Skip to main content

uor_foundation/
enforcement.rs

1// @generated by uor-crate from uor-ontology — do not edit manually
2
3//! Declarative enforcement types.
4//!
5//! This module contains the opaque witness types, declarative builders,
6//! the Term AST, and the v0.2.1 ergonomics surface (sealed `Grounded<T>`,
7//! the `Certify` trait, `PipelineFailure`, ring-op phantom wrappers,
8//! fragment markers, dispatch tables, and the `prelude` module).
9//!
10//! # Layers
11//!
12//! - **Layer 1** \[Opaque Witnesses\]: `Datum`, `Validated<T>`, `Derivation`,
13//!   `FreeRank` \[private fields, no public constructors\]
14//! - **Layer 2** \[Declarative Builders\]: `CompileUnitBuilder`,
15//!   `EffectDeclarationBuilder`, etc. \[produce `Validated<T>` on success\]
16//! - **Term AST**: `Term`, `TermArena`, `Binding`, `Assertion`, etc.
17//! - **v0.2.1 Ergonomics**: `OntologyTarget`, `GroundedShape`, `Grounded<T>`,
18//!   `Certify`, `PipelineFailure`, `RingOp<L>`, fragment markers,
19//!   `INHABITANCE_DISPATCH_TABLE`, and the `prelude` module.
20
21use crate::{
22    DecimalTranscendental, HostTypes, MetricAxis, PrimitiveOp, VerificationDomain, ViolationKind,
23    WittLevel,
24};
25use core::marker::PhantomData;
26
27/// Private sealed module preventing downstream implementations.
28/// Only `GroundedCoord` and `GroundedTuple<N>` implement `Sealed`.
29mod sealed {
30    /// Sealed trait. Not publicly implementable because this module is private.
31    pub trait Sealed {}
32    impl Sealed for super::GroundedCoord {}
33    impl<const N: usize> Sealed for super::GroundedTuple<N> {}
34}
35
36/// Internal level-tagged ring value. Width determined by the Witt level.
37/// Variants are emitted parametrically from `schema:WittLevel` individuals
38/// in the ontology; adding a new level to the ontology regenerates this enum.
39/// Not publicly constructible \[sealed within the crate\].
40#[derive(Debug, Clone, PartialEq, Eq)]
41#[allow(clippy::large_enum_variant, dead_code)]
42pub(crate) enum DatumInner {
43    /// W8: 8-bit ring Z/(2^8)Z.
44    W8([u8; 1]),
45    /// W16: 16-bit ring Z/(2^16)Z.
46    W16([u8; 2]),
47    /// W24: 24-bit ring Z/(2^24)Z.
48    W24([u8; 3]),
49    /// W32: 32-bit ring Z/(2^32)Z.
50    W32([u8; 4]),
51    /// W40: 40-bit ring Z/(2^40)Z.
52    W40([u8; 5]),
53    /// W48: 48-bit ring Z/(2^48)Z.
54    W48([u8; 6]),
55    /// W56: 56-bit ring Z/(2^56)Z.
56    W56([u8; 7]),
57    /// W64: 64-bit ring Z/(2^64)Z.
58    W64([u8; 8]),
59    /// W72: 72-bit ring Z/(2^72)Z.
60    W72([u8; 9]),
61    /// W80: 80-bit ring Z/(2^80)Z.
62    W80([u8; 10]),
63    /// W88: 88-bit ring Z/(2^88)Z.
64    W88([u8; 11]),
65    /// W96: 96-bit ring Z/(2^96)Z.
66    W96([u8; 12]),
67    /// W104: 104-bit ring Z/(2^104)Z.
68    W104([u8; 13]),
69    /// W112: 112-bit ring Z/(2^112)Z.
70    W112([u8; 14]),
71    /// W120: 120-bit ring Z/(2^120)Z.
72    W120([u8; 15]),
73    /// W128: 128-bit ring Z/(2^128)Z.
74    W128([u8; 16]),
75}
76
77/// A ring element at its minting Witt level.
78/// Cannot be constructed outside the `uor_foundation` crate.
79/// The only way to obtain a `Datum` is through reduction evaluation
80/// or the two-phase minting boundary (`validate_and_mint_coord` /
81/// `validate_and_mint_tuple`).
82/// # Examples
83/// ```no_run
84/// // A Datum is produced by reduction evaluation or the minting boundary —
85/// // you never construct one directly.
86/// fn inspect_datum(d: &uor_foundation::enforcement::Datum) {
87///     // Query its Witt level (W8 = 8-bit, W32 = 32-bit, etc.)
88///     let _level = d.level();
89///     // Datum width is determined by its level:
90///     //   W8 → 1 byte,  W16 → 2 bytes,  W24 → 3 bytes,  W32 → 4 bytes.
91///     let _bytes = d.as_bytes();
92/// }
93/// ```
94#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct Datum {
96    /// Level-tagged ring value \[sealed\].
97    inner: DatumInner,
98}
99
100impl Datum {
101    /// Returns the Witt level at which this datum was minted.
102    #[inline]
103    #[must_use]
104    pub const fn level(&self) -> WittLevel {
105        match self.inner {
106            DatumInner::W8(_) => WittLevel::W8,
107            DatumInner::W16(_) => WittLevel::W16,
108            DatumInner::W24(_) => WittLevel::new(24),
109            DatumInner::W32(_) => WittLevel::new(32),
110            DatumInner::W40(_) => WittLevel::new(40),
111            DatumInner::W48(_) => WittLevel::new(48),
112            DatumInner::W56(_) => WittLevel::new(56),
113            DatumInner::W64(_) => WittLevel::new(64),
114            DatumInner::W72(_) => WittLevel::new(72),
115            DatumInner::W80(_) => WittLevel::new(80),
116            DatumInner::W88(_) => WittLevel::new(88),
117            DatumInner::W96(_) => WittLevel::new(96),
118            DatumInner::W104(_) => WittLevel::new(104),
119            DatumInner::W112(_) => WittLevel::new(112),
120            DatumInner::W120(_) => WittLevel::new(120),
121            DatumInner::W128(_) => WittLevel::new(128),
122        }
123    }
124
125    /// Returns the raw byte representation of this datum.
126    #[inline]
127    #[must_use]
128    pub fn as_bytes(&self) -> &[u8] {
129        match &self.inner {
130            DatumInner::W8(b) => b,
131            DatumInner::W16(b) => b,
132            DatumInner::W24(b) => b,
133            DatumInner::W32(b) => b,
134            DatumInner::W40(b) => b,
135            DatumInner::W48(b) => b,
136            DatumInner::W56(b) => b,
137            DatumInner::W64(b) => b,
138            DatumInner::W72(b) => b,
139            DatumInner::W80(b) => b,
140            DatumInner::W88(b) => b,
141            DatumInner::W96(b) => b,
142            DatumInner::W104(b) => b,
143            DatumInner::W112(b) => b,
144            DatumInner::W120(b) => b,
145            DatumInner::W128(b) => b,
146        }
147    }
148}
149
150/// Internal level-tagged coordinate value for grounding intermediates.
151/// Variant set mirrors `DatumInner`: one per `schema:WittLevel`.
152#[derive(Debug, Clone, PartialEq, Eq)]
153#[allow(clippy::large_enum_variant, dead_code)]
154pub(crate) enum GroundedCoordInner {
155    /// W8: 8-bit coordinate.
156    W8([u8; 1]),
157    /// W16: 16-bit coordinate.
158    W16([u8; 2]),
159    /// W24: 24-bit coordinate.
160    W24([u8; 3]),
161    /// W32: 32-bit coordinate.
162    W32([u8; 4]),
163    /// W40: 40-bit coordinate.
164    W40([u8; 5]),
165    /// W48: 48-bit coordinate.
166    W48([u8; 6]),
167    /// W56: 56-bit coordinate.
168    W56([u8; 7]),
169    /// W64: 64-bit coordinate.
170    W64([u8; 8]),
171    /// W72: 72-bit coordinate.
172    W72([u8; 9]),
173    /// W80: 80-bit coordinate.
174    W80([u8; 10]),
175    /// W88: 88-bit coordinate.
176    W88([u8; 11]),
177    /// W96: 96-bit coordinate.
178    W96([u8; 12]),
179    /// W104: 104-bit coordinate.
180    W104([u8; 13]),
181    /// W112: 112-bit coordinate.
182    W112([u8; 14]),
183    /// W120: 120-bit coordinate.
184    W120([u8; 15]),
185    /// W128: 128-bit coordinate.
186    W128([u8; 16]),
187}
188
189/// A single grounded coordinate value.
190/// Not a `Datum` \[this is the narrow intermediate that a `Grounding`
191/// impl produces\]. The foundation validates and mints it into a `Datum`.
192/// Uses the same closed level-tagged family as `Datum`, ensuring that
193/// coordinate width matches the target Witt level.
194/// # Examples
195/// ```rust
196/// use uor_foundation::enforcement::GroundedCoord;
197///
198/// // W8: 8-bit ring Z/256Z — lightweight, exhaustive-verification baseline
199/// let byte_coord = GroundedCoord::w8(42);
200///
201/// // W16: 16-bit ring Z/65536Z — audio samples, small indices
202/// let short_coord = GroundedCoord::w16(1000);
203///
204/// // W32: 32-bit ring Z/2^32Z — pixel data, general-purpose integers
205/// let word_coord = GroundedCoord::w32(70_000);
206/// ```
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub struct GroundedCoord {
209    /// Level-tagged coordinate bytes.
210    pub(crate) inner: GroundedCoordInner,
211}
212
213impl GroundedCoord {
214    /// Construct a W8 coordinate from a `u8` value (little-endian).
215    #[inline]
216    #[must_use]
217    pub const fn w8(value: u8) -> Self {
218        Self {
219            inner: GroundedCoordInner::W8(value.to_le_bytes()),
220        }
221    }
222
223    /// Construct a W16 coordinate from a `u16` value (little-endian).
224    #[inline]
225    #[must_use]
226    pub const fn w16(value: u16) -> Self {
227        Self {
228            inner: GroundedCoordInner::W16(value.to_le_bytes()),
229        }
230    }
231
232    /// Construct a W24 coordinate from a `u32` value (little-endian).
233    #[inline]
234    #[must_use]
235    pub const fn w24(value: u32) -> Self {
236        let full = value.to_le_bytes();
237        let mut out = [0u8; 3];
238        let mut i = 0;
239        while i < 3 {
240            out[i] = full[i];
241            i += 1;
242        }
243        Self {
244            inner: GroundedCoordInner::W24(out),
245        }
246    }
247
248    /// Construct a W32 coordinate from a `u32` value (little-endian).
249    #[inline]
250    #[must_use]
251    pub const fn w32(value: u32) -> Self {
252        Self {
253            inner: GroundedCoordInner::W32(value.to_le_bytes()),
254        }
255    }
256
257    /// Construct a W40 coordinate from a `u64` value (little-endian).
258    #[inline]
259    #[must_use]
260    pub const fn w40(value: u64) -> Self {
261        let full = value.to_le_bytes();
262        let mut out = [0u8; 5];
263        let mut i = 0;
264        while i < 5 {
265            out[i] = full[i];
266            i += 1;
267        }
268        Self {
269            inner: GroundedCoordInner::W40(out),
270        }
271    }
272
273    /// Construct a W48 coordinate from a `u64` value (little-endian).
274    #[inline]
275    #[must_use]
276    pub const fn w48(value: u64) -> Self {
277        let full = value.to_le_bytes();
278        let mut out = [0u8; 6];
279        let mut i = 0;
280        while i < 6 {
281            out[i] = full[i];
282            i += 1;
283        }
284        Self {
285            inner: GroundedCoordInner::W48(out),
286        }
287    }
288
289    /// Construct a W56 coordinate from a `u64` value (little-endian).
290    #[inline]
291    #[must_use]
292    pub const fn w56(value: u64) -> Self {
293        let full = value.to_le_bytes();
294        let mut out = [0u8; 7];
295        let mut i = 0;
296        while i < 7 {
297            out[i] = full[i];
298            i += 1;
299        }
300        Self {
301            inner: GroundedCoordInner::W56(out),
302        }
303    }
304
305    /// Construct a W64 coordinate from a `u64` value (little-endian).
306    #[inline]
307    #[must_use]
308    pub const fn w64(value: u64) -> Self {
309        Self {
310            inner: GroundedCoordInner::W64(value.to_le_bytes()),
311        }
312    }
313
314    /// Construct a W72 coordinate from a `u128` value (little-endian).
315    #[inline]
316    #[must_use]
317    pub const fn w72(value: u128) -> Self {
318        let full = value.to_le_bytes();
319        let mut out = [0u8; 9];
320        let mut i = 0;
321        while i < 9 {
322            out[i] = full[i];
323            i += 1;
324        }
325        Self {
326            inner: GroundedCoordInner::W72(out),
327        }
328    }
329
330    /// Construct a W80 coordinate from a `u128` value (little-endian).
331    #[inline]
332    #[must_use]
333    pub const fn w80(value: u128) -> Self {
334        let full = value.to_le_bytes();
335        let mut out = [0u8; 10];
336        let mut i = 0;
337        while i < 10 {
338            out[i] = full[i];
339            i += 1;
340        }
341        Self {
342            inner: GroundedCoordInner::W80(out),
343        }
344    }
345
346    /// Construct a W88 coordinate from a `u128` value (little-endian).
347    #[inline]
348    #[must_use]
349    pub const fn w88(value: u128) -> Self {
350        let full = value.to_le_bytes();
351        let mut out = [0u8; 11];
352        let mut i = 0;
353        while i < 11 {
354            out[i] = full[i];
355            i += 1;
356        }
357        Self {
358            inner: GroundedCoordInner::W88(out),
359        }
360    }
361
362    /// Construct a W96 coordinate from a `u128` value (little-endian).
363    #[inline]
364    #[must_use]
365    pub const fn w96(value: u128) -> Self {
366        let full = value.to_le_bytes();
367        let mut out = [0u8; 12];
368        let mut i = 0;
369        while i < 12 {
370            out[i] = full[i];
371            i += 1;
372        }
373        Self {
374            inner: GroundedCoordInner::W96(out),
375        }
376    }
377
378    /// Construct a W104 coordinate from a `u128` value (little-endian).
379    #[inline]
380    #[must_use]
381    pub const fn w104(value: u128) -> Self {
382        let full = value.to_le_bytes();
383        let mut out = [0u8; 13];
384        let mut i = 0;
385        while i < 13 {
386            out[i] = full[i];
387            i += 1;
388        }
389        Self {
390            inner: GroundedCoordInner::W104(out),
391        }
392    }
393
394    /// Construct a W112 coordinate from a `u128` value (little-endian).
395    #[inline]
396    #[must_use]
397    pub const fn w112(value: u128) -> Self {
398        let full = value.to_le_bytes();
399        let mut out = [0u8; 14];
400        let mut i = 0;
401        while i < 14 {
402            out[i] = full[i];
403            i += 1;
404        }
405        Self {
406            inner: GroundedCoordInner::W112(out),
407        }
408    }
409
410    /// Construct a W120 coordinate from a `u128` value (little-endian).
411    #[inline]
412    #[must_use]
413    pub const fn w120(value: u128) -> Self {
414        let full = value.to_le_bytes();
415        let mut out = [0u8; 15];
416        let mut i = 0;
417        while i < 15 {
418            out[i] = full[i];
419            i += 1;
420        }
421        Self {
422            inner: GroundedCoordInner::W120(out),
423        }
424    }
425
426    /// Construct a W128 coordinate from a `u128` value (little-endian).
427    #[inline]
428    #[must_use]
429    pub const fn w128(value: u128) -> Self {
430        let full = value.to_le_bytes();
431        let mut out = [0u8; 16];
432        let mut i = 0;
433        while i < 16 {
434            out[i] = full[i];
435            i += 1;
436        }
437        Self {
438            inner: GroundedCoordInner::W128(out),
439        }
440    }
441}
442
443/// A grounded tuple: a fixed-size array of `GroundedCoord` values.
444/// Represents a structured type (e.g., the 8 coordinates of an E8
445/// lattice point). Not a `Datum` until the foundation validates and
446/// mints it. Stack-resident, no heap allocation.
447/// # Examples
448/// ```rust
449/// use uor_foundation::enforcement::{GroundedCoord, GroundedTuple};
450///
451/// // A 2D pixel: (red, green) at W8 (8-bit per channel)
452/// let pixel = GroundedTuple::new([
453///     GroundedCoord::w8(255), // red channel
454///     GroundedCoord::w8(128), // green channel
455/// ]);
456///
457/// // An E8 lattice point: 8 coordinates at W8
458/// let lattice_point = GroundedTuple::new([
459///     GroundedCoord::w8(2), GroundedCoord::w8(0),
460///     GroundedCoord::w8(0), GroundedCoord::w8(0),
461///     GroundedCoord::w8(0), GroundedCoord::w8(0),
462///     GroundedCoord::w8(0), GroundedCoord::w8(0),
463/// ]);
464/// ```
465#[derive(Debug, Clone, PartialEq, Eq)]
466pub struct GroundedTuple<const N: usize> {
467    /// The coordinate array.
468    pub(crate) coords: [GroundedCoord; N],
469}
470
471impl<const N: usize> GroundedTuple<N> {
472    /// Construct a tuple from a fixed-size array of coordinates.
473    #[inline]
474    #[must_use]
475    pub const fn new(coords: [GroundedCoord; N]) -> Self {
476        Self { coords }
477    }
478}
479
480/// Sealed marker trait for grounded intermediates.
481/// Implemented only for `GroundedCoord` and `GroundedTuple<N>`.
482/// Prism code cannot implement this \[the sealed module pattern
483/// prevents it\].
484pub trait GroundedValue: sealed::Sealed {}
485impl GroundedValue for GroundedCoord {}
486impl<const N: usize> GroundedValue for GroundedTuple<N> {}
487
488/// Target §3: sealed marker trait shared by all morphism kinds.
489/// `GroundingMapKind` (inbound) and `ProjectionMapKind` (outbound) both
490/// extend this trait; the four structural markers (`Total`, `Invertible`,
491/// `PreservesStructure`, `PreservesMetric`) are bounded on `MorphismKind`.
492pub trait MorphismKind: morphism_kind_sealed::Sealed {
493    /// The ontology IRI of this morphism kind.
494    const ONTOLOGY_IRI: &'static str;
495}
496
497/// v0.2.2 W4: sealed marker trait for the kind of a `Grounding` map.
498/// Implemented by exactly the `morphism:GroundingMap` individuals declared in
499/// the ontology; downstream cannot extend the kind set.
500pub trait GroundingMapKind: MorphismKind + grounding_map_kind_sealed::Sealed {}
501
502/// Target §3: sealed marker trait for the kind of a `Sinking` projection.
503/// Implemented by exactly the `morphism:ProjectionMap` individuals declared
504/// in the ontology; downstream cannot extend the kind set.
505pub trait ProjectionMapKind: MorphismKind + projection_map_kind_sealed::Sealed {}
506
507/// v0.2.2 W4: kinds whose image is total over the input domain
508/// (every input maps successfully).
509pub trait Total: MorphismKind {}
510
511/// v0.2.2 W4: kinds whose map is injective and admits an inverse on its image.
512pub trait Invertible: MorphismKind {}
513
514/// v0.2.2 W4: kinds whose map preserves the algebraic structure of the
515/// source domain (homomorphism-like).
516pub trait PreservesStructure: MorphismKind {}
517
518/// v0.2.2 W4: kinds whose map preserves the metric of the source domain
519/// (isometry-like).
520pub trait PreservesMetric: MorphismKind {}
521
522/// v0.2.2 W4: kind for raw byte ingestion. Total and invertible; preserves bit identity only.
523#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
524pub struct BinaryGroundingMap;
525
526/// v0.2.2 W4: kind for one-way digest functions (e.g., SHA-256). Total but not invertible; preserves no structure.
527#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
528pub struct DigestGroundingMap;
529
530/// v0.2.2 W4: kind for integer surface symbols. Total, invertible, structure-preserving.
531#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
532pub struct IntegerGroundingMap;
533
534/// v0.2.2 W4: kind for JSON host strings. Invertible on its image, structure-preserving.
535#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
536pub struct JsonGroundingMap;
537
538/// v0.2.2 W4: kind for UTF-8 host strings. Invertible on its image, structure-preserving.
539#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
540pub struct Utf8GroundingMap;
541
542/// Target §3: kind for raw byte projections. Total and invertible; preserves bit identity only.
543#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
544pub struct BinaryProjectionMap;
545
546/// Target §3: kind for fixed-size digests projected outward. Total but not invertible; preserves no structure.
547#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
548pub struct DigestProjectionMap;
549
550/// Target §3: kind for integer surface symbols projected outward. Invertible, structure-preserving.
551#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
552pub struct IntegerProjectionMap;
553
554/// Target §3: kind for JSON host strings projected outward. Invertible, structure-preserving.
555#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
556pub struct JsonProjectionMap;
557
558/// Target §3: kind for UTF-8 host strings projected outward. Invertible, structure-preserving.
559#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
560pub struct Utf8ProjectionMap;
561
562mod morphism_kind_sealed {
563    /// Private supertrait for MorphismKind. Not implementable outside this crate.
564    pub trait Sealed {}
565    impl Sealed for super::BinaryGroundingMap {}
566    impl Sealed for super::DigestGroundingMap {}
567    impl Sealed for super::IntegerGroundingMap {}
568    impl Sealed for super::JsonGroundingMap {}
569    impl Sealed for super::Utf8GroundingMap {}
570    impl Sealed for super::BinaryProjectionMap {}
571    impl Sealed for super::DigestProjectionMap {}
572    impl Sealed for super::IntegerProjectionMap {}
573    impl Sealed for super::JsonProjectionMap {}
574    impl Sealed for super::Utf8ProjectionMap {}
575}
576
577mod grounding_map_kind_sealed {
578    /// Private supertrait. Not implementable outside this crate.
579    pub trait Sealed {}
580    impl Sealed for super::BinaryGroundingMap {}
581    impl Sealed for super::DigestGroundingMap {}
582    impl Sealed for super::IntegerGroundingMap {}
583    impl Sealed for super::JsonGroundingMap {}
584    impl Sealed for super::Utf8GroundingMap {}
585}
586
587mod projection_map_kind_sealed {
588    /// Private supertrait. Not implementable outside this crate.
589    pub trait Sealed {}
590    impl Sealed for super::BinaryProjectionMap {}
591    impl Sealed for super::DigestProjectionMap {}
592    impl Sealed for super::IntegerProjectionMap {}
593    impl Sealed for super::JsonProjectionMap {}
594    impl Sealed for super::Utf8ProjectionMap {}
595}
596
597impl MorphismKind for BinaryGroundingMap {
598    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/BinaryGroundingMap";
599}
600
601impl MorphismKind for DigestGroundingMap {
602    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/DigestGroundingMap";
603}
604
605impl MorphismKind for IntegerGroundingMap {
606    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/IntegerGroundingMap";
607}
608
609impl MorphismKind for JsonGroundingMap {
610    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/JsonGroundingMap";
611}
612
613impl MorphismKind for Utf8GroundingMap {
614    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/Utf8GroundingMap";
615}
616
617impl MorphismKind for BinaryProjectionMap {
618    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/BinaryProjectionMap";
619}
620
621impl MorphismKind for DigestProjectionMap {
622    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/DigestProjectionMap";
623}
624
625impl MorphismKind for IntegerProjectionMap {
626    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/IntegerProjectionMap";
627}
628
629impl MorphismKind for JsonProjectionMap {
630    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/JsonProjectionMap";
631}
632
633impl MorphismKind for Utf8ProjectionMap {
634    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/Utf8ProjectionMap";
635}
636
637impl GroundingMapKind for BinaryGroundingMap {}
638impl GroundingMapKind for DigestGroundingMap {}
639impl GroundingMapKind for IntegerGroundingMap {}
640impl GroundingMapKind for JsonGroundingMap {}
641impl GroundingMapKind for Utf8GroundingMap {}
642
643impl ProjectionMapKind for BinaryProjectionMap {}
644impl ProjectionMapKind for DigestProjectionMap {}
645impl ProjectionMapKind for IntegerProjectionMap {}
646impl ProjectionMapKind for JsonProjectionMap {}
647impl ProjectionMapKind for Utf8ProjectionMap {}
648
649impl Total for IntegerGroundingMap {}
650impl Invertible for IntegerGroundingMap {}
651impl PreservesStructure for IntegerGroundingMap {}
652
653impl Invertible for Utf8GroundingMap {}
654impl PreservesStructure for Utf8GroundingMap {}
655
656impl Invertible for JsonGroundingMap {}
657impl PreservesStructure for JsonGroundingMap {}
658
659impl Total for DigestGroundingMap {}
660
661impl Total for BinaryGroundingMap {}
662impl Invertible for BinaryGroundingMap {}
663
664impl Invertible for IntegerProjectionMap {}
665impl PreservesStructure for IntegerProjectionMap {}
666
667impl Invertible for Utf8ProjectionMap {}
668impl PreservesStructure for Utf8ProjectionMap {}
669
670impl Invertible for JsonProjectionMap {}
671impl PreservesStructure for JsonProjectionMap {}
672
673impl Total for DigestProjectionMap {}
674
675impl Total for BinaryProjectionMap {}
676impl Invertible for BinaryProjectionMap {}
677
678/// Open trait for boundary crossing: external data to grounded intermediate.
679/// The foundation validates the returned value against the declared
680/// `GroundingShape` and mints it into a `Datum` if conformant.
681/// v0.2.2 W4 adds the `Map: GroundingMapKind` associated type — every impl
682/// must declare what *kind* of grounding map it is. Foundation operations
683/// that require structure preservation gate on `<G as Grounding>::Map: PreservesStructure`,
684/// and a digest-style impl is rejected at the call site.
685/// # Examples
686/// ```no_run
687/// use uor_foundation::enforcement::{
688///     Grounding, GroundedCoord, GroundingProgram, BinaryGroundingMap, combinators,
689/// };
690///
691/// /// Byte-passthrough grounding: reads the first byte of input as a W8 Datum.
692/// struct PassthroughGrounding;
693///
694/// impl Grounding for PassthroughGrounding {
695///     type Output = GroundedCoord;
696///     type Map = BinaryGroundingMap;
697///
698///     // Phase K: provide the combinator program; the type system verifies
699///     // at compile time that its marker tuple matches Self::Map via
700///     // GroundingProgram::from_primitive's MarkersImpliedBy<Map> bound.
701///     fn program(&self) -> GroundingProgram<GroundedCoord, BinaryGroundingMap> {
702///         GroundingProgram::from_primitive(combinators::read_bytes::<GroundedCoord>())
703///     }
704///     // Foundation supplies `ground()` via the sealed `GroundingExt`
705///     // extension trait — downstream implementers provide only `program()`.
706/// }
707/// ```
708pub trait Grounding {
709    /// The grounded intermediate type. Bounded by `GroundedValue`,
710    /// which is sealed \[only `GroundedCoord` and `GroundedTuple<N>`
711    /// are permitted\].
712    type Output: GroundedValue;
713
714    /// v0.2.2 W4: the kind of grounding map this impl is. Sealed to the
715    /// set of `morphism:GroundingMap` individuals declared in the
716    /// ontology. Every impl must declare the kind explicitly; if no kind
717    /// applies, use `BinaryGroundingMap` (the most permissive — total +
718    /// invertible, no structure preservation).
719    type Map: GroundingMapKind;
720
721    /// Phase K / W4 closure (target §4.3 + §9 criterion 1): the combinator
722    /// program that decomposes this grounding. The program's `Map` parameter
723    /// equals the impl's `Map` associated type, so the kind discriminator is
724    /// mechanically verifiable from the combinator decomposition — not a
725    /// promise. This is the only required method; `ground` is foundation-
726    /// supplied via `GroundingExt`.
727    fn program(&self) -> GroundingProgram<Self::Output, Self::Map>;
728}
729
730/// W4 closure (target §4.3 + §9 criterion 1): foundation-authored
731/// extension trait that supplies `ground()` for every `Grounding`
732/// impl. Downstream implementers provide only `program()`;
733/// the foundation runs it via the blanket `impl<G: Grounding>`
734/// below. The sealed supertrait prevents downstream from
735/// implementing `GroundingExt` directly — there is no second path.
736mod grounding_ext_sealed {
737    /// Private supertrait. Not implementable outside this crate.
738    pub trait Sealed {}
739    impl<G: super::Grounding> Sealed for G {}
740}
741
742/// Crate-internal bridge from `GroundingProgram` to `Option<Out>`.
743/// Blanket-impl'd for the two `GroundedValue` members
744/// (`GroundedCoord` and `GroundedTuple<N>`) so the `GroundingExt`
745/// blanket compiles for any output in the closed set.
746pub trait GroundingProgramRun<Out> {
747    /// Run the program on external bytes.
748    fn run_program(&self, external: &[u8]) -> Option<Out>;
749}
750
751impl<Map: GroundingMapKind> GroundingProgramRun<GroundedCoord>
752    for GroundingProgram<GroundedCoord, Map>
753{
754    #[inline]
755    fn run_program(&self, external: &[u8]) -> Option<GroundedCoord> {
756        self.run(external)
757    }
758}
759
760impl<const N: usize, Map: GroundingMapKind> GroundingProgramRun<GroundedTuple<N>>
761    for GroundingProgram<GroundedTuple<N>, Map>
762{
763    #[inline]
764    fn run_program(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
765        self.run(external)
766    }
767}
768
769/// Foundation-supplied `ground()` for every `Grounding` impl.
770/// The blanket `impl<G: Grounding> GroundingExt for G` below
771/// routes every call of `.ground(bytes)` through
772/// `self.program().run_program(bytes)`. Downstream cannot
773/// override this path: `GroundingExt` has a sealed supertrait
774/// and downstream cannot impl `GroundingExt` directly.
775pub trait GroundingExt: Grounding + grounding_ext_sealed::Sealed {
776    /// Map external bytes into a grounded value via this impl's combinator program.
777    /// Returns `None` when the combinator chain rejects the input (e.g. empty slice
778    /// for `ReadBytes`, malformed UTF-8 for `DecodeUtf8`).
779    fn ground(&self, external: &[u8]) -> Option<Self::Output>;
780}
781
782impl<G: Grounding> GroundingExt for G
783where
784    GroundingProgram<G::Output, G::Map>: GroundingProgramRun<G::Output>,
785{
786    #[inline]
787    fn ground(&self, external: &[u8]) -> Option<Self::Output> {
788        self.program().run_program(external)
789    }
790}
791
792/// Target §3 + §4.6: the foundation-owned operational contract for outbound
793/// boundary crossings. Dual of `Grounding`.
794/// A `Sinking` impl projects a `Grounded<Source>` value to a host-side
795/// `Output` through a specific `ProjectionMap` kind. The `&Grounded<Source>`
796/// input is structurally unforgeable (sealed per §2) — no raw data can be
797/// laundered through this contract. Downstream authors implement `Sinking`
798/// for their projection types; the foundation guarantees the input pedigree.
799/// # Examples
800/// ```no_run
801/// use uor_foundation::enforcement::{
802///     Grounded, Sinking, Utf8ProjectionMap, ConstrainedTypeInput,
803/// };
804///
805/// struct MyJsonSink;
806///
807/// impl Sinking for MyJsonSink {
808///     type Source = ConstrainedTypeInput;
809///     type ProjectionMap = Utf8ProjectionMap;
810///     type Output = String;
811///
812///     fn project(&self, grounded: &Grounded<ConstrainedTypeInput>) -> String {
813///         format!("{:?}", grounded.unit_address())
814///     }
815/// }
816/// ```
817pub trait Sinking {
818    /// The ring-side shape `T` carried by the `Grounded<T>` being projected.
819    /// Sealed via `GroundedShape` — downstream cannot forge an admissible Source.
820    type Source: GroundedShape;
821
822    /// The ontology-declared ProjectionMap kind this impl serves. Sealed to
823    /// the closed set of `morphism:ProjectionMap` individuals.
824    type ProjectionMap: ProjectionMapKind;
825
826    /// The host-side output type of this projection. Intentionally generic —
827    /// downstream chooses `String`, `Vec<u8>`, `serde_json::Value`, or any
828    /// host-appropriate carrier.
829    type Output;
830
831    /// Project a grounded ring value to the host output. The `&Grounded<Source>`
832    /// input is unforgeable (Grounded is sealed per §2) — no raw data can be
833    /// laundered through this contract.
834    fn project(&self, grounded: &Grounded<Self::Source>) -> Self::Output;
835}
836
837/// Target §4.6: extension trait tying `EmitEffect<H>` (ontology-declarative)
838/// to `Sinking` (Rust-operational). Emit-effect implementations carry a
839/// specific `Sinking` impl; the emit operation threads a sealed
840/// `Grounded<Source>` through the projection.
841pub trait EmitThrough<H: crate::HostTypes>: crate::bridge::boundary::EmitEffect<H> {
842    /// The `Sinking` implementation this emit-effect routes through.
843    type Sinking: Sinking;
844
845    /// Emit a grounded value through this effect's bound `Sinking`. The
846    /// input type is the sealed `Grounded<Source>` of the bound `Sinking`;
847    /// nothing else is admissible.
848    fn emit(
849        &self,
850        grounded: &Grounded<<Self::Sinking as Sinking>::Source>,
851    ) -> <Self::Sinking as Sinking>::Output;
852}
853
854/// v0.2.2 W13: sealed marker trait for the validation phase at which a
855/// `Validated<T, Phase>` was witnessed. Implemented only by `CompileTime`
856/// and `Runtime`; downstream cannot extend.
857pub trait ValidationPhase: validation_phase_sealed::Sealed {}
858
859mod validation_phase_sealed {
860    /// Private supertrait. Not implementable outside this crate.
861    pub trait Sealed {}
862    impl Sealed for super::CompileTime {}
863    impl Sealed for super::Runtime {}
864}
865
866/// v0.2.2 W13: marker for compile-time validated witnesses produced by
867/// `validate_const()` and usable in `const` contexts. Convertible to
868/// `Validated<T, Runtime>` via `From`.
869#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
870pub struct CompileTime;
871impl ValidationPhase for CompileTime {}
872
873/// v0.2.2 W13: marker for runtime-validated witnesses produced by
874/// `validate()`. The default phase of `Validated<T>` so v0.2.1 call
875/// sites continue to compile.
876#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
877pub struct Runtime;
878impl ValidationPhase for Runtime {}
879
880/// Proof that a value was produced by the conformance checker,
881/// not fabricated by Prism code.
882/// The inner value and `_sealed` field are private, so `Validated<T>`
883/// can only be constructed within this crate.
884/// v0.2.2 W13: parameterized by a `Phase: ValidationPhase` discriminator.
885/// `Validated<T, CompileTime>` was witnessed by `validate_const()` and is
886/// usable in const contexts. `Validated<T, Runtime>` (the default) was
887/// witnessed by `validate()`. A `CompileTime` witness is convertible to
888/// a `Runtime` witness via `From`.
889/// # Examples
890/// ```no_run
891/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
892/// use uor_foundation::{WittLevel, VerificationDomain};
893///
894/// // Validated<T> proves that a value passed conformance checking.
895/// // You cannot construct one directly — only builder validate() methods
896/// // and the minting boundary produce them.
897/// let terms = [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
898/// let domains = [VerificationDomain::Enumerative];
899///
900/// let validated = CompileUnitBuilder::new()
901///     .root_term(&terms)
902///     .witt_level_ceiling(WittLevel::W8)
903///     .thermodynamic_budget(1024)
904///     .target_domains(&domains)
905///     .result_type::<ConstrainedTypeInput>()
906///     .validate()
907///     .expect("all fields set");
908///
909/// // Access the inner value through the proof wrapper:
910/// let _compile_unit = validated.inner();
911/// ```
912#[derive(Debug, Clone, PartialEq, Eq)]
913pub struct Validated<T, Phase: ValidationPhase = Runtime> {
914    /// The validated inner value.
915    inner: T,
916    /// Phantom marker for the validation phase (`CompileTime` or `Runtime`).
917    _phase: PhantomData<Phase>,
918    /// Prevents external construction.
919    _sealed: (),
920}
921
922impl<T, Phase: ValidationPhase> Validated<T, Phase> {
923    /// Returns a reference to the validated inner value.
924    #[inline]
925    #[must_use]
926    pub const fn inner(&self) -> &T {
927        &self.inner
928    }
929
930    /// Creates a new `Validated<T, Phase>` wrapper. Only callable within the crate.
931    #[inline]
932    #[allow(dead_code)]
933    pub(crate) const fn new(inner: T) -> Self {
934        Self {
935            inner,
936            _phase: PhantomData,
937            _sealed: (),
938        }
939    }
940}
941
942/// v0.2.2 W13: a compile-time witness is usable wherever a runtime witness is required.
943impl<T> From<Validated<T, CompileTime>> for Validated<T, Runtime> {
944    #[inline]
945    fn from(value: Validated<T, CompileTime>) -> Self {
946        Self {
947            inner: value.inner,
948            _phase: PhantomData,
949            _sealed: (),
950        }
951    }
952}
953
954/// An opaque derivation trace that can only be extended by the rewrite engine.
955/// Records the rewrite-step count, the source `witt_level_bits`, and the
956/// parametric `content_fingerprint`. Private fields prevent external
957/// construction; produced exclusively by `Grounded::derivation()` so the
958/// verify path can re-derive the source certificate via
959/// `Derivation::replay() -> Trace -> verify_trace`.
960#[derive(Debug, Clone, PartialEq, Eq)]
961pub struct Derivation {
962    /// Number of rewrite steps in this derivation.
963    step_count: u32,
964    /// v0.2.2 T5: Witt level the source grounding was minted at. Carried
965    /// through replay so the verifier can reconstruct the certificate.
966    witt_level_bits: u16,
967    /// v0.2.2 T5: parametric content fingerprint of the source unit's
968    /// full state, computed at grounding time by the consumer-supplied
969    /// `Hasher`. Carried through replay so the verifier can reproduce
970    /// the source certificate via passthrough.
971    content_fingerprint: ContentFingerprint,
972}
973
974impl Derivation {
975    /// Returns the number of rewrite steps.
976    #[inline]
977    #[must_use]
978    pub const fn step_count(&self) -> u32 {
979        self.step_count
980    }
981
982    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
983    #[inline]
984    #[must_use]
985    pub const fn witt_level_bits(&self) -> u16 {
986        self.witt_level_bits
987    }
988
989    /// v0.2.2 T5: returns the parametric content fingerprint of the source
990    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
991    #[inline]
992    #[must_use]
993    pub const fn content_fingerprint(&self) -> ContentFingerprint {
994        self.content_fingerprint
995    }
996
997    /// Creates a new derivation. Only callable within the crate.
998    #[inline]
999    #[must_use]
1000    #[allow(dead_code)]
1001    pub(crate) const fn new(
1002        step_count: u32,
1003        witt_level_bits: u16,
1004        content_fingerprint: ContentFingerprint,
1005    ) -> Self {
1006        Self {
1007            step_count,
1008            witt_level_bits,
1009            content_fingerprint,
1010        }
1011    }
1012}
1013
1014/// An opaque free rank that can only be decremented by `PinningEffect`
1015/// and incremented by `UnbindingEffect` \[never by direct mutation\].
1016#[derive(Debug, Clone, PartialEq, Eq)]
1017pub struct FreeRank {
1018    /// Total site capacity at the Witt level.
1019    total: u32,
1020    /// Currently pinned sites.
1021    pinned: u32,
1022}
1023
1024impl FreeRank {
1025    /// Returns the total site capacity.
1026    #[inline]
1027    #[must_use]
1028    pub const fn total(&self) -> u32 {
1029        self.total
1030    }
1031
1032    /// Returns the number of currently pinned sites.
1033    #[inline]
1034    #[must_use]
1035    pub const fn pinned(&self) -> u32 {
1036        self.pinned
1037    }
1038
1039    /// Returns the number of remaining (unpinned) sites.
1040    #[inline]
1041    #[must_use]
1042    pub const fn remaining(&self) -> u32 {
1043        self.total - self.pinned
1044    }
1045
1046    /// Creates a new free rank. Only callable within the crate.
1047    #[inline]
1048    #[allow(dead_code)]
1049    pub(crate) const fn new(total: u32, pinned: u32) -> Self {
1050        Self { total, pinned }
1051    }
1052}
1053
1054/// v0.2.2 Phase A: sealed `H::Decimal`-backed newtype carrying the
1055/// `observable:LandauerCost` accumulator in `observable:Nats`.
1056/// Monotonic within a pipeline invocation. The UOR ring operates
1057/// at the Landauer temperature (β* = ln 2), so this observable is
1058/// a direct measure of irreversible bit-erasure performed.
1059/// Phase 9: parameterized over `H: HostTypes` so the underlying
1060/// decimal type tracks the host's chosen precision.
1061#[derive(Debug)]
1062pub struct LandauerBudget<H: HostTypes = crate::DefaultHostTypes> {
1063    /// Accumulated Landauer cost in nats. Non-negative, finite.
1064    nats: H::Decimal,
1065    /// Phantom marker pinning the host type.
1066    _phantom: core::marker::PhantomData<H>,
1067    /// Prevents external construction.
1068    _sealed: (),
1069}
1070
1071impl<H: HostTypes> LandauerBudget<H> {
1072    /// Returns the accumulated Landauer cost in nats.
1073    #[inline]
1074    #[must_use]
1075    pub const fn nats(&self) -> H::Decimal {
1076        self.nats
1077    }
1078
1079    /// Crate-internal constructor. Caller guarantees `nats` is
1080    /// non-negative and finite (i.e. not NaN, not infinite).
1081    #[inline]
1082    #[must_use]
1083    #[allow(dead_code)]
1084    pub(crate) const fn new(nats: H::Decimal) -> Self {
1085        Self {
1086            nats,
1087            _phantom: core::marker::PhantomData,
1088            _sealed: (),
1089        }
1090    }
1091
1092    /// Crate-internal constructor for the zero-cost initial budget.
1093    #[inline]
1094    #[must_use]
1095    #[allow(dead_code)]
1096    pub(crate) const fn zero() -> Self {
1097        Self {
1098            nats: H::EMPTY_DECIMAL,
1099            _phantom: core::marker::PhantomData,
1100            _sealed: (),
1101        }
1102    }
1103}
1104
1105impl<H: HostTypes> Copy for LandauerBudget<H> {}
1106impl<H: HostTypes> Clone for LandauerBudget<H> {
1107    #[inline]
1108    fn clone(&self) -> Self {
1109        *self
1110    }
1111}
1112impl<H: HostTypes> PartialEq for LandauerBudget<H> {
1113    #[inline]
1114    fn eq(&self, other: &Self) -> bool {
1115        self.nats == other.nats
1116    }
1117}
1118impl<H: HostTypes> Eq for LandauerBudget<H> {}
1119impl<H: HostTypes> PartialOrd for LandauerBudget<H> {
1120    #[inline]
1121    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1122        Some(self.cmp(other))
1123    }
1124}
1125impl<H: HostTypes> Ord for LandauerBudget<H> {
1126    #[inline]
1127    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1128        // Total order on H::Decimal with NaN excluded by construction.
1129        self.nats
1130            .partial_cmp(&other.nats)
1131            .unwrap_or(core::cmp::Ordering::Equal)
1132    }
1133}
1134impl<H: HostTypes> core::hash::Hash for LandauerBudget<H> {
1135    #[inline]
1136    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1137        // DecimalTranscendental::to_bits gives a stable u64 fingerprint
1138        // for any in-range Decimal value.
1139        self.nats.to_bits().hash(state);
1140    }
1141}
1142
1143/// v0.2.2 Phase A: foundation-internal deterministic two-clock value
1144/// carried by every `Grounded<T>` and `Certified<C>`. The two clocks are
1145/// `landauer_nats` (a `LandauerBudget` value backed by `observable:LandauerCost`)
1146/// and `rewrite_steps` (a `u64` backed by `derivation:stepCount` on
1147/// `derivation:TermMetrics`). Each clock is monotonic within a pipeline
1148/// invocation, content-deterministic, ontology-grounded, and binds to a
1149/// physical wall-clock lower bound through established physics (Landauer's
1150/// principle for nats; Margolus-Levitin for rewrite steps). Two clocks
1151/// because exactly two physical lower-bound theorems are grounded; adding
1152/// a third clock would require grounding a third physical theorem.
1153/// `PartialOrd` is component-wise: `a < b` iff every field of `a` is `<=`
1154/// the corresponding field of `b` and at least one is strictly `<`. Two
1155/// `UorTime` values from unrelated computations are genuinely incomparable,
1156/// so `UorTime` is `PartialOrd` but **not** `Ord`.
1157#[derive(Debug)]
1158pub struct UorTime<H: HostTypes = crate::DefaultHostTypes> {
1159    /// Landauer budget consumed, in `observable:Nats`.
1160    landauer_nats: LandauerBudget<H>,
1161    /// Total rewrite steps taken (`derivation:stepCount`).
1162    rewrite_steps: u64,
1163    /// Prevents external construction.
1164    _sealed: (),
1165}
1166
1167impl<H: HostTypes> UorTime<H> {
1168    /// Returns the Landauer budget consumed, in `observable:Nats`.
1169    /// Maps to `observable:LandauerCost`.
1170    #[inline]
1171    #[must_use]
1172    pub const fn landauer_nats(&self) -> LandauerBudget<H> {
1173        self.landauer_nats
1174    }
1175
1176    /// Returns the total rewrite steps taken.
1177    /// Maps to `derivation:stepCount` on `derivation:TermMetrics`.
1178    #[inline]
1179    #[must_use]
1180    pub const fn rewrite_steps(&self) -> u64 {
1181        self.rewrite_steps
1182    }
1183
1184    /// Crate-internal constructor. Reachable only from the pipeline at witness mint time.
1185    #[inline]
1186    #[must_use]
1187    #[allow(dead_code)]
1188    pub(crate) const fn new(landauer_nats: LandauerBudget<H>, rewrite_steps: u64) -> Self {
1189        Self {
1190            landauer_nats,
1191            rewrite_steps,
1192            _sealed: (),
1193        }
1194    }
1195
1196    /// Crate-internal constructor for the zero initial value.
1197    #[inline]
1198    #[must_use]
1199    #[allow(dead_code)]
1200    pub(crate) const fn zero() -> Self {
1201        Self {
1202            landauer_nats: LandauerBudget::<H>::zero(),
1203            rewrite_steps: 0,
1204            _sealed: (),
1205        }
1206    }
1207
1208    /// Returns the provable minimum wall-clock duration that the
1209    /// computation producing this witness could have taken under the
1210    /// given calibration. Returns `max(Landauer-bound, Margolus-Levitin-bound)`.
1211    /// The Landauer bound is `landauer_nats × k_B·T / thermal_power`.
1212    /// The Margolus-Levitin bound is `π·ℏ·rewrite_steps / (2·characteristic_energy)`.
1213    /// Pure arithmetic — no transcendentals, no state. Const-evaluable
1214    /// where the `UorTime` value is known at compile time.
1215    #[inline]
1216    #[must_use]
1217    pub fn min_wall_clock(&self, cal: &Calibration<H>) -> Nanos {
1218        // Landauer bound: nats × k_B·T / thermal_power = seconds.
1219        let landauer_seconds = self.landauer_nats.nats() * cal.k_b_t() / cal.thermal_power();
1220        // Margolus-Levitin bound: π·ℏ / (2·E) per orthogonal state transition.
1221        // π·ℏ ≈ 3.31194e-34 J·s; encoded as the f64 bit pattern of
1222        // `core::f64::consts::PI * 1.054_571_817e-34` so the constant is
1223        // representable across host Decimal types.
1224        let pi_times_h_bar =
1225            <H::Decimal as DecimalTranscendental>::from_bits(crate::PI_TIMES_H_BAR_BITS);
1226        let two = <H::Decimal as DecimalTranscendental>::from_u32(2);
1227        let ml_seconds_per_step = pi_times_h_bar / (two * cal.characteristic_energy());
1228        let steps = <H::Decimal as DecimalTranscendental>::from_u64(self.rewrite_steps);
1229        let ml_seconds = ml_seconds_per_step * steps;
1230        let max_seconds = if landauer_seconds > ml_seconds {
1231            landauer_seconds
1232        } else {
1233            ml_seconds
1234        };
1235        // Convert seconds to nanoseconds, saturate on overflow.
1236        let nanos_per_second =
1237            <H::Decimal as DecimalTranscendental>::from_bits(crate::NANOS_PER_SECOND_BITS);
1238        let nanos = max_seconds * nanos_per_second;
1239        Nanos {
1240            ns: <H::Decimal as DecimalTranscendental>::as_u64_saturating(nanos),
1241            _sealed: (),
1242        }
1243    }
1244}
1245
1246impl<H: HostTypes> Copy for UorTime<H> {}
1247impl<H: HostTypes> Clone for UorTime<H> {
1248    #[inline]
1249    fn clone(&self) -> Self {
1250        *self
1251    }
1252}
1253impl<H: HostTypes> PartialEq for UorTime<H> {
1254    #[inline]
1255    fn eq(&self, other: &Self) -> bool {
1256        self.landauer_nats == other.landauer_nats && self.rewrite_steps == other.rewrite_steps
1257    }
1258}
1259impl<H: HostTypes> Eq for UorTime<H> {}
1260impl<H: HostTypes> core::hash::Hash for UorTime<H> {
1261    #[inline]
1262    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1263        self.landauer_nats.hash(state);
1264        self.rewrite_steps.hash(state);
1265    }
1266}
1267impl<H: HostTypes> PartialOrd for UorTime<H> {
1268    #[inline]
1269    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1270        let l = self.landauer_nats.cmp(&other.landauer_nats);
1271        let r = self.rewrite_steps.cmp(&other.rewrite_steps);
1272        match (l, r) {
1273            (core::cmp::Ordering::Equal, core::cmp::Ordering::Equal) => {
1274                Some(core::cmp::Ordering::Equal)
1275            }
1276            (core::cmp::Ordering::Less, core::cmp::Ordering::Less)
1277            | (core::cmp::Ordering::Less, core::cmp::Ordering::Equal)
1278            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Less) => {
1279                Some(core::cmp::Ordering::Less)
1280            }
1281            (core::cmp::Ordering::Greater, core::cmp::Ordering::Greater)
1282            | (core::cmp::Ordering::Greater, core::cmp::Ordering::Equal)
1283            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Greater) => {
1284                Some(core::cmp::Ordering::Greater)
1285            }
1286            _ => None,
1287        }
1288    }
1289}
1290
1291/// v0.2.2 Phase A: sealed lower-bound carrier for wall-clock duration.
1292/// Produced only by `UorTime::min_wall_clock` and similar foundation
1293/// time conversions. The sealing guarantees that any `Nanos` value is
1294/// a provable physical bound, not a raw integer. Developers who need
1295/// the underlying `u64` call `.as_u64()`; the sealing prevents
1296/// accidentally passing a host-measured duration where the type system
1297/// expects "a provable minimum".
1298#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1299pub struct Nanos {
1300    /// The provable lower-bound duration in nanoseconds.
1301    ns: u64,
1302    /// Prevents external construction.
1303    _sealed: (),
1304}
1305
1306impl Nanos {
1307    /// Returns the underlying nanosecond count. The value is a provable
1308    /// physical lower bound under whatever calibration produced it.
1309    #[inline]
1310    #[must_use]
1311    pub const fn as_u64(self) -> u64 {
1312        self.ns
1313    }
1314}
1315
1316/// v0.2.2 Phase A: error returned by `Calibration::new` when the supplied
1317/// physical parameters fail plausibility validation.
1318#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1319pub enum CalibrationError {
1320    /// `k_b_t` was non-positive, NaN, or outside the known-universe
1321    /// temperature range (`1e-30 ≤ k_b_t ≤ 1e-15` joules).
1322    ThermalEnergy,
1323    /// `thermal_power` was non-positive, NaN, or above the thermodynamic maximum (`1e9` W).
1324    ThermalPower,
1325    /// `characteristic_energy` was non-positive, NaN, or above the
1326    /// k_B·T × Avogadro-class bound (`1e3` joules).
1327    CharacteristicEnergy,
1328}
1329
1330impl core::fmt::Display for CalibrationError {
1331    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1332        match self {
1333            Self::ThermalEnergy => {
1334                f.write_str("calibration k_b_t out of range (must be in [1e-30, 1e-15] joules)")
1335            }
1336            Self::ThermalPower => {
1337                f.write_str("calibration thermal_power out of range (must be > 0 and <= 1e9 W)")
1338            }
1339            Self::CharacteristicEnergy => f.write_str(
1340                "calibration characteristic_energy out of range (must be > 0 and <= 1e3 J)",
1341            ),
1342        }
1343    }
1344}
1345
1346impl core::error::Error for CalibrationError {}
1347
1348/// v0.2.2 Phase A: physical-substrate calibration for wall-clock binding.
1349/// Construction is open via [`Calibration::new`], but the fields are
1350/// private and validated for physical plausibility. Used to convert
1351/// `UorTime` to a provable wall-clock lower bound via
1352/// [`UorTime::min_wall_clock`].
1353/// **A `Calibration` is never passed into `pipeline::run`,
1354/// `resolver::*::certify`, `validate_const`, or any other foundation entry
1355/// point.** The foundation computes `UorTime` without physical
1356/// interpretation; the developer applies a `Calibration` after the fact.
1357#[derive(Debug)]
1358pub struct Calibration<H: HostTypes = crate::DefaultHostTypes> {
1359    /// Boltzmann constant times temperature, in joules.
1360    k_b_t: H::Decimal,
1361    /// Sustained dissipation in watts.
1362    thermal_power: H::Decimal,
1363    /// Mean energy above ground state, in joules.
1364    characteristic_energy: H::Decimal,
1365    /// Phantom marker pinning the host type.
1366    _phantom: core::marker::PhantomData<H>,
1367}
1368
1369impl<H: HostTypes> Copy for Calibration<H> {}
1370impl<H: HostTypes> Clone for Calibration<H> {
1371    #[inline]
1372    fn clone(&self) -> Self {
1373        *self
1374    }
1375}
1376impl<H: HostTypes> PartialEq for Calibration<H> {
1377    #[inline]
1378    fn eq(&self, other: &Self) -> bool {
1379        self.k_b_t == other.k_b_t
1380            && self.thermal_power == other.thermal_power
1381            && self.characteristic_energy == other.characteristic_energy
1382    }
1383}
1384
1385impl<H: HostTypes> Calibration<H> {
1386    /// Construct a calibration with physically plausible parameters.
1387    /// Validation: every parameter must be positive and finite. `k_b_t`
1388    /// must lie within the known-universe temperature range
1389    /// (`1e-30 <= k_b_t <= 1e-15` joules covers ~1 nK to ~1e8 K).
1390    /// `thermal_power` must be at most `1e9` W (gigawatt class — far above
1391    /// any plausible single-compute envelope). `characteristic_energy`
1392    /// must be at most `1e3` J (kilojoule class — astronomically generous).
1393    /// # Errors
1394    /// Returns `CalibrationError::InvalidThermalEnergy` when `k_b_t` is
1395    /// non-positive, NaN, or outside the temperature range.
1396    /// Returns `CalibrationError::InvalidThermalPower` when `thermal_power`
1397    /// is non-positive, NaN, or above the maximum.
1398    /// Returns `CalibrationError::InvalidCharacteristicEnergy` when
1399    /// `characteristic_energy` is non-positive, NaN, or above the maximum.
1400    /// # Example
1401    /// ```
1402    /// use uor_foundation::enforcement::Calibration;
1403    /// use uor_foundation::DefaultHostTypes;
1404    /// // X86 server-class envelope at room temperature.
1405    /// // k_B·T at 300 K = 4.14e-21 J; 85 W sustained TDP; ~1e-15 J/op.
1406    /// let cal = Calibration::<DefaultHostTypes>::new(4.14e-21, 85.0, 1.0e-15)
1407    ///     .expect("physically plausible server calibration");
1408    /// # let _ = cal;
1409    /// ```
1410    #[inline]
1411    pub fn new(
1412        k_b_t: H::Decimal,
1413        thermal_power: H::Decimal,
1414        characteristic_energy: H::Decimal,
1415    ) -> Result<Self, CalibrationError> {
1416        // Bit-pattern bounds for the validation envelope. Reading them
1417        // through `from_bits` lets the host's chosen Decimal precision
1418        // resolve the comparison without any hardcoded f64 in source.
1419        let zero = <H::Decimal as Default>::default();
1420        let kbt_lo =
1421            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_LO_BITS);
1422        let kbt_hi =
1423            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_HI_BITS);
1424        let tp_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1425            crate::CALIBRATION_THERMAL_POWER_HI_BITS,
1426        );
1427        let ce_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1428            crate::CALIBRATION_CHAR_ENERGY_HI_BITS,
1429        );
1430        // NaN identity: NaN != NaN. PartialEq is the defining bound.
1431        #[allow(clippy::eq_op)]
1432        let k_b_t_nan = k_b_t != k_b_t;
1433        if k_b_t_nan || k_b_t <= zero || k_b_t < kbt_lo || k_b_t > kbt_hi {
1434            return Err(CalibrationError::ThermalEnergy);
1435        }
1436        #[allow(clippy::eq_op)]
1437        let tp_nan = thermal_power != thermal_power;
1438        if tp_nan || thermal_power <= zero || thermal_power > tp_hi {
1439            return Err(CalibrationError::ThermalPower);
1440        }
1441        #[allow(clippy::eq_op)]
1442        let ce_nan = characteristic_energy != characteristic_energy;
1443        if ce_nan || characteristic_energy <= zero || characteristic_energy > ce_hi {
1444            return Err(CalibrationError::CharacteristicEnergy);
1445        }
1446        Ok(Self {
1447            k_b_t,
1448            thermal_power,
1449            characteristic_energy,
1450            _phantom: core::marker::PhantomData,
1451        })
1452    }
1453
1454    /// Returns the Boltzmann constant times temperature, in joules.
1455    #[inline]
1456    #[must_use]
1457    pub const fn k_b_t(&self) -> H::Decimal {
1458        self.k_b_t
1459    }
1460
1461    /// Returns the sustained thermal power dissipation, in watts.
1462    #[inline]
1463    #[must_use]
1464    pub const fn thermal_power(&self) -> H::Decimal {
1465        self.thermal_power
1466    }
1467
1468    /// Returns the characteristic energy above ground state, in joules.
1469    #[inline]
1470    #[must_use]
1471    pub const fn characteristic_energy(&self) -> H::Decimal {
1472        self.characteristic_energy
1473    }
1474
1475    /// v0.2.2 T5.5: zero sentinel. All three fields are 0.0 — physically
1476    /// meaningless but safely constructible. Used as the unreachable-branch
1477    /// placeholder in the const-context preset literals (`X86_SERVER`,
1478    /// `ARM_MOBILE`, `CORTEX_M_EMBEDDED`, `CONSERVATIVE_WORST_CASE`). The
1479    /// `meta/calibration_presets_valid` conformance check verifies the
1480    /// preset literals always succeed in `Calibration::new`, so this
1481    /// sentinel is never produced in practice. Do not use it directly;
1482    /// it is exposed only because Rust's const-eval needs a fallback for
1483    /// the impossible `Err` arm of the preset match.
1484    pub const ZERO_SENTINEL: Calibration<H> = Self {
1485        k_b_t: H::EMPTY_DECIMAL,
1486        thermal_power: H::EMPTY_DECIMAL,
1487        characteristic_energy: H::EMPTY_DECIMAL,
1488        _phantom: core::marker::PhantomData,
1489    };
1490}
1491
1492impl Calibration<crate::DefaultHostTypes> {
1493    /// Const constructor for the default-host (f64) path. Bypasses runtime validation; use only for the spec-shipped preset literals where the envelope is statically guaranteed. Parameter types are written as `<DefaultHostTypes as HostTypes>::Decimal` so no `: f64` annotation appears in the public-API surface — the host-type alias is the canonical name; downstream that swaps the host gets the matching decimal automatically.
1494    #[inline]
1495    #[must_use]
1496    pub(crate) const fn from_f64_unchecked(
1497        k_b_t: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1498        thermal_power: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1499        characteristic_energy: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1500    ) -> Self {
1501        Self {
1502            k_b_t,
1503            thermal_power,
1504            characteristic_energy,
1505            _phantom: core::marker::PhantomData,
1506        }
1507    }
1508}
1509
1510/// v0.2.2 Phase A: foundation-shipped preset calibrations covering common
1511/// substrates. The values are derived from published substrate thermals at
1512/// T=300 K (room temperature, where k_B·T ≈ 4.14e-21 J).
1513pub mod calibrations {
1514    use super::Calibration;
1515    use crate::DefaultHostTypes;
1516
1517    /// Server-class x86 (Xeon/EPYC sustained envelope).
1518    /// k_B·T = 4.14e-21 J (T = 300 K), thermal_power = 85 W (typical TDP),
1519    /// characteristic_energy = 1e-15 J/op (~1 fJ/op for modern CMOS).
1520    pub const X86_SERVER: Calibration<DefaultHostTypes> =
1521        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 85.0, 1.0e-15);
1522
1523    /// Mobile ARM SoC (Apple M-series, Snapdragon 8-series sustained envelope).
1524    /// k_B·T = 4.14e-21 J, thermal_power = 5 W, characteristic_energy = 1e-16 J/op.
1525    pub const ARM_MOBILE: Calibration<DefaultHostTypes> =
1526        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 5.0, 1.0e-16);
1527
1528    /// Cortex-M embedded (STM32/nRF52 at 80 MHz).
1529    /// k_B·T = 4.14e-21 J, thermal_power = 0.1 W, characteristic_energy = 1e-17 J/op.
1530    pub const CORTEX_M_EMBEDDED: Calibration<DefaultHostTypes> =
1531        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 0.1, 1.0e-17);
1532
1533    /// The tightest provable lower bound that requires no trust in the
1534    /// issuer's claimed substrate. Values are physically sound but maximally
1535    /// generous: k_B·T at 300 K floor, thermal_power at 1 GW (above any
1536    /// plausible single-compute envelope), characteristic_energy at 1 J
1537    /// (astronomically generous).
1538    /// Applying this calibration yields the smallest `Nanos` physically
1539    /// possible for the computation regardless of substrate claims.
1540    pub const CONSERVATIVE_WORST_CASE: Calibration<DefaultHostTypes> =
1541        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 1.0e9, 1.0);
1542}
1543
1544/// v0.2.2 Phase B (target §1.7): timing-policy carrier. Parametric over host tuning.
1545/// Supplies the preflight / runtime Nanos budgets (canonical values from
1546/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`) plus
1547/// the `Calibration` used to convert an input's a-priori `UorTime` estimate
1548/// into a Nanos lower bound for comparison against the budget.
1549/// The foundation-canonical default [`CanonicalTimingPolicy`] uses
1550/// `calibrations::CONSERVATIVE_WORST_CASE` (the tightest provable lower-bound
1551/// calibration) and the 10 ms budget from the ontology. Host code overrides by
1552/// implementing `TimingPolicy` on a marker struct and substituting at the
1553/// preflight-function call site.
1554pub trait TimingPolicy {
1555    /// Preflight Nanos budget. Inputs whose a-priori UorTime → min_wall_clock
1556    /// under `Self::CALIBRATION` exceeds this value are rejected at preflight.
1557    const PREFLIGHT_BUDGET_NS: u64;
1558    /// Runtime Nanos budget for post-admission reduction.
1559    const RUNTIME_BUDGET_NS: u64;
1560    /// Canonical Calibration used to convert a-priori UorTime estimates to Nanos.
1561    /// Phase 9: pinned to `Calibration<DefaultHostTypes>` because the trait's `const` slot can't carry a non-DefaultHost generic. Polymorphic consumers build a `Calibration<H>` at runtime via `Calibration::new`.
1562    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes>;
1563}
1564
1565/// v0.2.2 Phase B: foundation-canonical [`TimingPolicy`]. Budget values mirror
1566/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`; calibration
1567/// is `calibrations::CONSERVATIVE_WORST_CASE` so the Nanos lower bound from any
1568/// input UorTime is the tightest physically-defensible value.
1569#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1570pub struct CanonicalTimingPolicy;
1571
1572impl TimingPolicy for CanonicalTimingPolicy {
1573    const PREFLIGHT_BUDGET_NS: u64 = 10_000_000;
1574    const RUNTIME_BUDGET_NS: u64 = 10_000_000;
1575    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes> =
1576        &calibrations::CONSERVATIVE_WORST_CASE;
1577}
1578
1579/// Phase H (target §1.6): foundation-owned transcendental-arithmetic entry points.
1580/// Routes through the always-on `libm` dependency so every build — std, alloc,
1581/// and strict no_std — has access to `ln` / `exp` / `sqrt` for `xsd:decimal`
1582/// observables. Gating these behind an optional feature flag was considered and
1583/// rejected per target §1.6: an observable that exists in one build and not
1584/// another violates the foundation's "one surface" discipline.
1585/// Downstream code that needs transcendentals should call these wrappers —
1586/// they are the canonical entry point for the four observables target §3 enumerates
1587/// (`convergenceRate`, `residualEntropy`, `collapseAmplitude`, and `op:OA_5` pricing)
1588/// and for any future observable whose implementation admits transcendentals.
1589pub mod transcendentals {
1590    use crate::DecimalTranscendental;
1591
1592    /// Natural logarithm. Dispatches via `DecimalTranscendental::ln`; the foundation's f64 / f32 impls route through `libm::log` / `logf`.
1593    /// Returns `NaN` for `x <= 0.0`, preserving `libm`'s contract.
1594    #[inline]
1595    #[must_use]
1596    pub fn ln<D: DecimalTranscendental>(x: D) -> D {
1597        x.ln()
1598    }
1599
1600    /// Exponential `e^x`. Dispatches via `DecimalTranscendental::exp`.
1601    #[inline]
1602    #[must_use]
1603    pub fn exp<D: DecimalTranscendental>(x: D) -> D {
1604        x.exp()
1605    }
1606
1607    /// Square root. Dispatches via `DecimalTranscendental::sqrt`. Returns `NaN` for `x < 0.0`.
1608    #[inline]
1609    #[must_use]
1610    pub fn sqrt<D: DecimalTranscendental>(x: D) -> D {
1611        x.sqrt()
1612    }
1613
1614    /// Shannon entropy term `-p · ln(p)` in nats. Returns 0 for `p = 0` by
1615    /// continuous extension. Used by `observable:residualEntropy`.
1616    #[inline]
1617    #[must_use]
1618    pub fn entropy_term_nats<D: DecimalTranscendental>(p: D) -> D {
1619        let zero = <D as Default>::default();
1620        if p <= zero {
1621            zero
1622        } else {
1623            zero - p * p.ln()
1624        }
1625    }
1626}
1627
1628/// Fixed-capacity term list for `#![no_std]`. Indices into a `TermArena`.
1629#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1630pub struct TermList {
1631    /// Start index in the arena.
1632    pub start: u32,
1633    /// Number of terms in this list.
1634    pub len: u32,
1635}
1636
1637/// Stack-resident arena for `Term` trees.
1638/// Fixed capacity determined by the const generic `CAP`.
1639/// All `Term` child references are `u32` indices into this arena.
1640/// `#![no_std]`-safe: no heap allocation.
1641/// # Examples
1642/// ```rust
1643/// use uor_foundation::enforcement::{TermArena, Term, TermList};
1644/// use uor_foundation::{WittLevel, PrimitiveOp};
1645///
1646/// // Build the expression `add(3, 5)` bottom-up in an arena.
1647/// let mut arena = TermArena::<4>::new();
1648///
1649/// // Push leaves first:
1650/// let idx_3 = arena.push(uor_foundation::pipeline::literal_u64(3, WittLevel::W8));
1651/// let idx_5 = arena.push(uor_foundation::pipeline::literal_u64(5, WittLevel::W8));
1652///
1653/// // Push the application node, referencing the leaves by index:
1654/// let idx_add = arena.push(Term::Application {
1655///     operator: PrimitiveOp::Add,
1656///     args: TermList { start: idx_3.unwrap_or(0), len: 2 },
1657/// });
1658///
1659/// assert_eq!(arena.len(), 3);
1660/// // Retrieve a node by index:
1661/// let node = arena.get(idx_add.unwrap_or(0));
1662/// assert!(node.is_some());
1663/// ```
1664#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1665pub struct TermArena<const CAP: usize> {
1666    /// Node storage. `None` slots are unused.
1667    nodes: [Option<Term>; CAP],
1668    /// Number of allocated nodes.
1669    len: u32,
1670}
1671
1672impl<const CAP: usize> TermArena<CAP> {
1673    /// Creates an empty arena.
1674    #[inline]
1675    #[must_use]
1676    pub const fn new() -> Self {
1677        // v0.2.2 T4.5.a: const-stable on MSRV 1.70 via the `[None; CAP]`
1678        // initializer (Term is Copy as of T4.5.a, so Option<Term> is Copy).
1679        Self {
1680            nodes: [None; CAP],
1681            len: 0,
1682        }
1683    }
1684
1685    /// Push a term into the arena and return its index.
1686    /// # Errors
1687    /// Returns `None` if the arena is full.
1688    #[must_use]
1689    pub fn push(&mut self, term: Term) -> Option<u32> {
1690        let idx = self.len;
1691        if (idx as usize) >= CAP {
1692            return None;
1693        }
1694        self.nodes[idx as usize] = Some(term);
1695        self.len = idx + 1;
1696        Some(idx)
1697    }
1698
1699    /// Returns a reference to the term at `index`, or `None` if out of bounds.
1700    #[inline]
1701    #[must_use]
1702    pub fn get(&self, index: u32) -> Option<&Term> {
1703        self.nodes
1704            .get(index as usize)
1705            .and_then(|slot| slot.as_ref())
1706    }
1707
1708    /// Returns the number of allocated nodes.
1709    #[inline]
1710    #[must_use]
1711    pub const fn len(&self) -> u32 {
1712        self.len
1713    }
1714
1715    /// Returns `true` if the arena has no allocated nodes.
1716    #[inline]
1717    #[must_use]
1718    pub const fn is_empty(&self) -> bool {
1719        self.len == 0
1720    }
1721
1722    /// v0.2.2 T4.5.b: returns the populated prefix of the arena as a slice.
1723    /// Each entry is `Some(term)` for the populated indices `0..len()`;
1724    /// downstream consumers index into this slice via `TermList::start` and
1725    /// `TermList::len` to walk the children of an Application/Match node.
1726    #[inline]
1727    #[must_use]
1728    pub fn as_slice(&self) -> &[Option<Term>] {
1729        &self.nodes[..self.len as usize]
1730    }
1731
1732    /// Wiki ADR-022 D2: const constructor that copies a static term slice
1733    /// into the arena. Used by the `prism_model!` proc-macro to emit a
1734    /// `const ROUTE: TermArena<CAP> = TermArena::from_slice(ROUTE_SLICE)`
1735    /// declaration alongside the model — the `const ROUTE_SLICE` carrying
1736    /// the term tree, this `from_slice` wrapping it into the arena form
1737    /// [`crate::pipeline::run_route`] consumes.
1738    /// `CAP` MUST be at least `slice.len()`; if the slice exceeds the
1739    /// arena's capacity the trailing terms are silently dropped (the
1740    /// `prism_model!` macro emits an arena sized to fit the route's term
1741    /// count plus headroom, so this case is unreachable from the macro's
1742    /// output).
1743    #[inline]
1744    #[must_use]
1745    pub const fn from_slice(slice: &'static [Term]) -> Self {
1746        let mut nodes: [Option<Term>; CAP] = [None; CAP];
1747        let mut i = 0usize;
1748        while i < slice.len() && i < CAP {
1749            nodes[i] = Some(slice[i]);
1750            i += 1;
1751        }
1752        // Cap at min(slice.len(), CAP) so a too-large slice doesn't
1753        // overrun. The macro emits arena CAP >= slice.len() so the
1754        // truncation branch is unreachable in practice.
1755        #[allow(clippy::cast_possible_truncation)]
1756        let len = if slice.len() > CAP {
1757            CAP as u32
1758        } else {
1759            slice.len() as u32
1760        };
1761        Self { nodes, len }
1762    }
1763}
1764
1765impl<const CAP: usize> Default for TermArena<CAP> {
1766    fn default() -> Self {
1767        Self::new()
1768    }
1769}
1770
1771/// Concrete AST node for the UOR term language.
1772/// Mirrors the EBNF grammar productions. All child references are
1773/// indices into a `TermArena`, keeping the AST stack-resident and
1774/// `#![no_std]`-safe.
1775/// # Examples
1776/// ```rust
1777/// use uor_foundation::enforcement::{Term, TermList};
1778/// use uor_foundation::{WittLevel, PrimitiveOp};
1779///
1780/// // Literal: an integer value tagged with a Witt level.
1781/// let lit = uor_foundation::pipeline::literal_u64(42, WittLevel::W8);
1782///
1783/// // Application: an operation applied to arguments.
1784/// // `args` is a TermList { start, len } pointing into a TermArena.
1785/// let app = Term::Application {
1786///     operator: PrimitiveOp::Mul,
1787///     args: TermList { start: 0, len: 2 },
1788/// };
1789///
1790/// // Lift: canonical injection from a lower to a higher Witt level.
1791/// let lift = Term::Lift { operand_index: 0, target: WittLevel::new(32) };
1792///
1793/// // Project: canonical surjection from a higher to a lower level.
1794/// let proj = Term::Project { operand_index: 0, target: WittLevel::W8 };
1795/// ```
1796#[allow(clippy::large_enum_variant)]
1797#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1798pub enum Term {
1799    /// Integer literal with Witt level annotation. Per ADR-051 the value
1800    /// carrier is a `TermValue` byte sequence whose length matches the declared
1801    /// `level`'s byte width. Use `uor_foundation::pipeline::literal_u64(value, level)`
1802    /// to construct a literal from a `u64` value (the narrow form).
1803    Literal {
1804        /// The literal value as a byte sequence (ADR-051). Length equals
1805        /// `level.witt_length() / 8`. Wider widths (W128, W256, …) are
1806        /// natively representable without `Concat` composition.
1807        value: crate::pipeline::TermValue,
1808        /// The Witt level of this literal.
1809        level: WittLevel,
1810    },
1811    /// Variable reference by name index.
1812    Variable {
1813        /// Index into the name table.
1814        name_index: u32,
1815    },
1816    /// Operation application: operator applied to arguments.
1817    Application {
1818        /// The primitive operation to apply.
1819        operator: PrimitiveOp,
1820        /// Argument list (indices into arena).
1821        args: TermList,
1822    },
1823    /// Lift: canonical injection W_n to W_m (n < m, lossless).
1824    Lift {
1825        /// Index of the operand term in the arena.
1826        operand_index: u32,
1827        /// Target Witt level.
1828        target: WittLevel,
1829    },
1830    /// Project: canonical surjection W_m to W_n (m > n, lossy).
1831    Project {
1832        /// Index of the operand term in the arena.
1833        operand_index: u32,
1834        /// Target Witt level.
1835        target: WittLevel,
1836    },
1837    /// Match expression with pattern-result pairs.
1838    Match {
1839        /// Index of the scrutinee term in the arena.
1840        scrutinee_index: u32,
1841        /// Match arms (indices into arena).
1842        arms: TermList,
1843    },
1844    /// Bounded recursion with descent measure.
1845    Recurse {
1846        /// Index of the descent measure term.
1847        measure_index: u32,
1848        /// Index of the base case term.
1849        base_index: u32,
1850        /// Index of the recursive step term.
1851        step_index: u32,
1852    },
1853    /// Stream construction via unfold.
1854    Unfold {
1855        /// Index of the seed term.
1856        seed_index: u32,
1857        /// Index of the step function term.
1858        step_index: u32,
1859    },
1860    /// Try expression with failure recovery.
1861    Try {
1862        /// Index of the body term.
1863        body_index: u32,
1864        /// Index of the handler term.
1865        handler_index: u32,
1866    },
1867    /// Substitution-axis-realized verb projection (wiki ADR-029 + ADR-030).
1868    /// Delegates evaluation to the application's `AxisTuple` substitution-axis
1869    /// impl: the catamorphism evaluates the input subtree, dispatches the
1870    /// axis at `axis_index` to the kernel identified by `kernel_id`, and
1871    /// emits the kernel's output as the result. Emitted by
1872    /// `prism_model!` from the closure-body form `hash(input)` (ADR-026 G19,
1873    /// which lowers to AxisInvocation against the application's HashAxis).
1874    AxisInvocation {
1875        /// Position of the axis in the application's `AxisTuple`.
1876        axis_index: u32,
1877        /// Per-axis kernel id (the SDK macro emits per-method `KERNEL_*` consts).
1878        kernel_id: u32,
1879        /// Input subtree's arena index (single input — current axes are 1-arg).
1880        input_index: u32,
1881    },
1882    /// Field-access projection over a partition_product input (wiki
1883    /// ADR-033 G20). The catamorphism's fold-rule evaluates `source`
1884    /// and slices `[byte_offset .. byte_offset + byte_length]` from
1885    /// the resulting bytes. Emitted by `prism_model!` and `verb!`
1886    /// from the closure-body forms `<expr>.<index>` and
1887    /// `<expr>.<field_name>` (named-field access requires the
1888    /// `partition_product!` declaration to use the named-field form).
1889    /// Coproduct field-access is rejected at macro-expansion time.
1890    ProjectField {
1891        /// Arena index of the source expression's term tree.
1892        source_index: u32,
1893        /// Byte offset into the source's evaluated bytes (proc-
1894        /// macro-computed from factor MAX_BYTES).
1895        byte_offset: u32,
1896        /// Length of the projected slice in bytes.
1897        byte_length: u32,
1898    },
1899    /// Bounded search with structural early termination (wiki ADR-034).
1900    /// The catamorphism iterates `idx` from 0 up to (but excluding) the
1901    /// evaluated `domain_size`; for each iteration it evaluates
1902    /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to `idx`.
1903    /// On the first non-zero predicate result the fold emits the
1904    /// coproduct value `(0x01, idx_bytes)` and terminates iteration; if
1905    /// no `idx` admits, the fold emits `(0x00, idx-width zero bytes)`.
1906    /// Emitted by `prism_model!` and `verb!` from the closure-body
1907    /// form `first_admit(<DomainTy>, |idx| <pred>)` (ADR-026 G16; the
1908    /// lowering target shifted from `Term::Recurse` to `Term::FirstAdmit`
1909    /// per ADR-034's structural-search commitment).
1910    FirstAdmit {
1911        /// Arena index of the domain-cardinality term (typically a
1912        /// `Term::Literal` carrying `<DomainTy as ConstrainedTypeShape>::CYCLE_SIZE`).
1913        domain_size_index: u32,
1914        /// Arena index of the predicate body. Evaluation visits
1915        /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to the
1916        /// current candidate `idx`.
1917        predicate_index: u32,
1918    },
1919    /// ψ_1 (wiki ADR-035): nerve construction — Constraints → SimplicialComplex.
1920    /// Lowered from the closure-body form `nerve(<value_expr>)` (G21).
1921    /// Resolver-bound: consults the ResolverTuple's NerveResolver per ADR-036.
1922    Nerve {
1923        /// Arena index of the value-bytes operand (typically a
1924        /// `Term::Variable` for the route input or a `Term::ProjectField`).
1925        value_index: u32,
1926    },
1927    /// ψ_2 (wiki ADR-035): chain functor — SimplicialComplex → ChainComplex.
1928    /// Lowered from `chain_complex(<simplicial_expr>)` (G22).
1929    /// Resolver-bound: ChainComplexResolver per ADR-036.
1930    ChainComplex { simplicial_index: u32 },
1931    /// ψ_3 (wiki ADR-035): homology functor — ChainComplex → HomologyGroups.
1932    /// `H_k(C) = ker(∂_k) / im(∂_{k+1})`.
1933    /// Lowered from `homology_groups(<chain_expr>)` (G23).
1934    /// Resolver-bound: HomologyGroupResolver per ADR-036.
1935    HomologyGroups { chain_index: u32 },
1936    /// ψ_4 (wiki ADR-035): Betti-number extraction — HomologyGroups → BettiNumbers.
1937    /// Pure computation on resolved homology groups; no resolver consultation.
1938    /// Lowered from `betti(<homology_expr>)` (G24).
1939    Betti { homology_index: u32 },
1940    /// ψ_5 (wiki ADR-035): dualization functor — ChainComplex → CochainComplex.
1941    /// `C^k = Hom(C_k, R)`.
1942    /// Lowered from `cochain_complex(<chain_expr>)` (G25).
1943    /// Resolver-bound: CochainComplexResolver per ADR-036.
1944    CochainComplex { chain_index: u32 },
1945    /// ψ_6 (wiki ADR-035): cohomology functor — CochainComplex → CohomologyGroups.
1946    /// `H^k(C) = ker(δ^k) / im(δ^{k-1})`.
1947    /// Lowered from `cohomology_groups(<cochain_expr>)` (G26).
1948    /// Resolver-bound: CohomologyGroupResolver per ADR-036.
1949    CohomologyGroups { cochain_index: u32 },
1950    /// ψ_7 (wiki ADR-035): Kan-completion + Postnikov truncation —
1951    /// SimplicialComplex → PostnikovTower. The PostnikovResolver performs
1952    /// the Kan-completion internally; verb authors do not need to construct
1953    /// KanComplex values explicitly.
1954    /// Lowered from `postnikov_tower(<simplicial_expr>)` (G27).
1955    /// Resolver-bound: PostnikovResolver per ADR-036.
1956    PostnikovTower { simplicial_index: u32 },
1957    /// ψ_8 (wiki ADR-035): homotopy extraction — PostnikovTower → HomotopyGroups.
1958    /// π_k from each truncation stage.
1959    /// Lowered from `homotopy_groups(<postnikov_expr>)` (G28).
1960    /// Resolver-bound: HomotopyGroupResolver per ADR-036.
1961    HomotopyGroups { postnikov_index: u32 },
1962    /// ψ_9 (wiki ADR-035): k-invariant computation — HomotopyGroups → KInvariants.
1963    /// κ_k classifying the Postnikov tower.
1964    /// Lowered from `k_invariants(<homotopy_expr>)` (G29).
1965    /// Resolver-bound: KInvariantResolver per ADR-036.
1966    KInvariants { homotopy_index: u32 },
1967}
1968
1969/// Wiki ADR-024 verb-graph compile-time inlining: shift the arena-index
1970/// fields of `term` by `offset`. Used by [`inline_verb_fragment`] to
1971/// inline a verb's term-tree fragment into a host arena at compile time.
1972/// `Term::Variable`'s `name_index` is a binding-name reference (not an
1973/// arena index) and is preserved unchanged. `Term::Try`'s `handler_index`
1974/// is preserved unchanged when it equals `u32::MAX` (the default-
1975/// propagation sentinel per ADR-022 D3 G9).
1976#[must_use]
1977pub const fn shift_term(term: Term, offset: u32) -> Term {
1978    match term {
1979        Term::Literal { value, level } => Term::Literal { value, level },
1980        // name_index is a binding-name reference, not an arena index.
1981        Term::Variable { name_index } => Term::Variable { name_index },
1982        Term::Application { operator, args } => Term::Application {
1983            operator,
1984            args: TermList {
1985                start: args.start + offset,
1986                len: args.len,
1987            },
1988        },
1989        Term::Lift {
1990            operand_index,
1991            target,
1992        } => Term::Lift {
1993            operand_index: operand_index + offset,
1994            target,
1995        },
1996        Term::Project {
1997            operand_index,
1998            target,
1999        } => Term::Project {
2000            operand_index: operand_index + offset,
2001            target,
2002        },
2003        Term::Match {
2004            scrutinee_index,
2005            arms,
2006        } => Term::Match {
2007            scrutinee_index: scrutinee_index + offset,
2008            arms: TermList {
2009                start: arms.start + offset,
2010                len: arms.len,
2011            },
2012        },
2013        Term::Recurse {
2014            measure_index,
2015            base_index,
2016            step_index,
2017        } => Term::Recurse {
2018            measure_index: measure_index + offset,
2019            base_index: base_index + offset,
2020            step_index: step_index + offset,
2021        },
2022        Term::Unfold {
2023            seed_index,
2024            step_index,
2025        } => Term::Unfold {
2026            seed_index: seed_index + offset,
2027            step_index: step_index + offset,
2028        },
2029        Term::Try {
2030            body_index,
2031            handler_index,
2032        } => Term::Try {
2033            body_index: body_index + offset,
2034            handler_index: if handler_index == u32::MAX {
2035                u32::MAX
2036            } else {
2037                handler_index + offset
2038            },
2039        },
2040        Term::AxisInvocation {
2041            axis_index,
2042            kernel_id,
2043            input_index,
2044        } => Term::AxisInvocation {
2045            axis_index,
2046            kernel_id,
2047            input_index: input_index + offset,
2048        },
2049        Term::ProjectField {
2050            source_index,
2051            byte_offset,
2052            byte_length,
2053        } => Term::ProjectField {
2054            source_index: source_index + offset,
2055            byte_offset,
2056            byte_length,
2057        },
2058        Term::FirstAdmit {
2059            domain_size_index,
2060            predicate_index,
2061        } => Term::FirstAdmit {
2062            domain_size_index: domain_size_index + offset,
2063            predicate_index: predicate_index + offset,
2064        },
2065        Term::Nerve { value_index } => Term::Nerve {
2066            value_index: value_index + offset,
2067        },
2068        Term::ChainComplex { simplicial_index } => Term::ChainComplex {
2069            simplicial_index: simplicial_index + offset,
2070        },
2071        Term::HomologyGroups { chain_index } => Term::HomologyGroups {
2072            chain_index: chain_index + offset,
2073        },
2074        Term::Betti { homology_index } => Term::Betti {
2075            homology_index: homology_index + offset,
2076        },
2077        Term::CochainComplex { chain_index } => Term::CochainComplex {
2078            chain_index: chain_index + offset,
2079        },
2080        Term::CohomologyGroups { cochain_index } => Term::CohomologyGroups {
2081            cochain_index: cochain_index + offset,
2082        },
2083        Term::PostnikovTower { simplicial_index } => Term::PostnikovTower {
2084            simplicial_index: simplicial_index + offset,
2085        },
2086        Term::HomotopyGroups { postnikov_index } => Term::HomotopyGroups {
2087            postnikov_index: postnikov_index + offset,
2088        },
2089        Term::KInvariants { homotopy_index } => Term::KInvariants {
2090            homotopy_index: homotopy_index + offset,
2091        },
2092    }
2093}
2094
2095/// Wiki ADR-024 compile-time verb-fragment inlining helper.
2096/// Copies the verb `fragment` slice into `buf` starting at `len` while applying
2097/// two simultaneous transformations per term so the verb body becomes part of
2098/// the calling route's flat arena: Variable(0) substitution (the verb's `input`
2099/// parameter binds to the caller's argument expression by replacing each
2100/// `Variable { name_index: 0 }` with a copy of `buf[arg_root_idx]`), and arena-
2101/// index shifting (every non-Variable(0) term has its arena-index fields shifted
2102/// by `len` so internal references resolve correctly within the host).
2103/// The combined transformation realises ADR-024's compile-time inlining: the
2104/// verb body lands in the host arena with its `input` bound to the caller's
2105/// argument expression — verb-graph acyclicity is checked at const-eval time,
2106/// no `Term::VerbReference` variant or runtime depth guard is required.
2107/// # Panics
2108/// Panics at const-eval time if `len + fragment.len() > CAP` or if
2109/// `arg_root_idx as usize >= len`.
2110#[must_use]
2111pub const fn inline_verb_fragment<const CAP: usize>(
2112    mut buf: [Term; CAP],
2113    mut len: usize,
2114    fragment: &[Term],
2115    arg_root_idx: u32,
2116) -> ([Term; CAP], usize) {
2117    let offset = len as u32;
2118    // Capture a copy of the caller's argument root term; `Variable { name_index: 0 }`
2119    // occurrences in the fragment are replaced by this copy per ADR-024.
2120    let arg_root_term = buf[arg_root_idx as usize];
2121    let mut i = 0;
2122    while i < fragment.len() {
2123        let term = fragment[i];
2124        let new_term = match term {
2125            Term::Variable { name_index: 0 } => arg_root_term,
2126            other => shift_term(other, offset),
2127        };
2128        buf[len] = new_term;
2129        len += 1;
2130        i += 1;
2131    }
2132    (buf, len)
2133}
2134
2135/// A type declaration with constraint kinds.
2136#[derive(Debug, Clone, PartialEq, Eq)]
2137pub struct TypeDeclaration {
2138    /// Name index for this type.
2139    pub name_index: u32,
2140    /// Constraint terms (indices into arena).
2141    pub constraints: TermList,
2142}
2143
2144/// A named binding: `let name : Type = term`.
2145#[derive(Debug, Clone, PartialEq, Eq)]
2146pub struct Binding {
2147    /// Name index for this binding.
2148    pub name_index: u32,
2149    /// Index of the type declaration.
2150    pub type_index: u32,
2151    /// Index of the value term in the arena.
2152    pub value_index: u32,
2153    /// EBNF surface syntax (compile-time constant).
2154    pub surface: &'static str,
2155    /// FNV-1a content address (compile-time constant).
2156    pub content_address: u64,
2157}
2158
2159impl Binding {
2160    /// v0.2.2 Phase P.3: lift this binding to the `BindingEntry` shape consumed by
2161    /// `BindingsTable`. `address` is derived from `content_address` via
2162    /// `ContentAddress::from_u64_fingerprint`; `bytes` re-uses the `surface` slice.
2163    /// Content-deterministic; const-compatible since all fields are `'static`.
2164    #[inline]
2165    #[must_use]
2166    pub const fn to_binding_entry(&self) -> BindingEntry {
2167        BindingEntry {
2168            address: ContentAddress::from_u64_fingerprint(self.content_address),
2169            bytes: self.surface.as_bytes(),
2170        }
2171    }
2172}
2173
2174/// An assertion: `assert lhs = rhs`.
2175#[derive(Debug, Clone, PartialEq, Eq)]
2176pub struct Assertion {
2177    /// Index of the left-hand side term.
2178    pub lhs_index: u32,
2179    /// Index of the right-hand side term.
2180    pub rhs_index: u32,
2181    /// EBNF surface syntax (compile-time constant).
2182    pub surface: &'static str,
2183}
2184
2185/// Boundary source declaration: `source name : Type via grounding`.
2186#[derive(Debug, Clone, PartialEq, Eq)]
2187pub struct SourceDeclaration {
2188    /// Name index for the source.
2189    pub name_index: u32,
2190    /// Index of the type declaration.
2191    pub type_index: u32,
2192    /// Name index of the grounding map.
2193    pub grounding_name_index: u32,
2194}
2195
2196/// Boundary sink declaration: `sink name : Type via projection`.
2197#[derive(Debug, Clone, PartialEq, Eq)]
2198pub struct SinkDeclaration {
2199    /// Name index for the sink.
2200    pub name_index: u32,
2201    /// Index of the type declaration.
2202    pub type_index: u32,
2203    /// Name index of the projection map.
2204    pub projection_name_index: u32,
2205}
2206
2207/// Structured violation diagnostic carrying metadata from the
2208/// conformance namespace. Every field is machine-readable.
2209/// # Examples
2210/// ```rust
2211/// use uor_foundation::enforcement::ShapeViolation;
2212/// use uor_foundation::ViolationKind;
2213///
2214/// // ShapeViolation carries structured metadata from the ontology.
2215/// // Every field is machine-readable — IRIs, counts, and a typed kind.
2216/// let violation = ShapeViolation {
2217///     shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2218///     constraint_iri: "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2219///     property_iri: "https://uor.foundation/reduction/rootTerm",
2220///     expected_range: "https://uor.foundation/schema/Term",
2221///     min_count: 1,
2222///     max_count: 1,
2223///     kind: ViolationKind::Missing,
2224/// };
2225///
2226/// // Machine-readable for tooling (IDE plugins, CI pipelines):
2227/// assert_eq!(violation.kind, ViolationKind::Missing);
2228/// assert!(violation.shape_iri.ends_with("CompileUnitShape"));
2229/// assert_eq!(violation.min_count, 1);
2230/// ```
2231#[derive(Debug, Clone, PartialEq, Eq)]
2232pub struct ShapeViolation {
2233    /// IRI of the `conformance:Shape` that was validated against.
2234    pub shape_iri: &'static str,
2235    /// IRI of the specific `conformance:PropertyConstraint` that failed.
2236    pub constraint_iri: &'static str,
2237    /// IRI of the property that was missing or invalid.
2238    pub property_iri: &'static str,
2239    /// The expected range class IRI.
2240    pub expected_range: &'static str,
2241    /// Minimum cardinality from the constraint.
2242    pub min_count: u32,
2243    /// Maximum cardinality (0 = unbounded).
2244    pub max_count: u32,
2245    /// What went wrong.
2246    pub kind: ViolationKind,
2247}
2248
2249impl core::fmt::Display for ShapeViolation {
2250    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2251        write!(
2252            f,
2253            "shape violation: {} (constraint {}, property {}, kind {:?})",
2254            self.shape_iri, self.constraint_iri, self.property_iri, self.kind,
2255        )
2256    }
2257}
2258
2259impl core::error::Error for ShapeViolation {}
2260
2261impl ShapeViolation {
2262    /// Phase C.3: returns the shape IRI as a `&'static str` suitable for
2263    /// `const fn` panic messages. The IRI uniquely identifies the violated
2264    /// constraint in the conformance catalog.
2265    #[inline]
2266    #[must_use]
2267    pub const fn const_message(&self) -> &'static str {
2268        self.shape_iri
2269    }
2270}
2271
2272/// Builder for `CompileUnit` admission into the reduction pipeline.
2273/// Collects `rootTerm`, `wittLevelCeiling`, `thermodynamicBudget`,
2274/// and `targetDomains`. The `validate()` method checks structural
2275/// constraints (Tier 1) and value-dependent constraints (Tier 2).
2276/// # Examples
2277/// ```rust
2278/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
2279/// use uor_foundation::{WittLevel, VerificationDomain, ViolationKind};
2280///
2281/// // A CompileUnit packages a term graph for reduction admission.
2282/// // The builder enforces that all required fields are present.
2283/// let terms = [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
2284/// let domains = [VerificationDomain::Enumerative];
2285///
2286/// let unit = CompileUnitBuilder::new()
2287///     .root_term(&terms)
2288///     .witt_level_ceiling(WittLevel::W8)
2289///     .thermodynamic_budget(1024)
2290///     .target_domains(&domains)
2291///     .result_type::<ConstrainedTypeInput>()
2292///     .validate();
2293/// assert!(unit.is_ok());
2294///
2295/// // Omitting a required field produces a ShapeViolation
2296/// // with the exact conformance IRI that failed:
2297/// let err = CompileUnitBuilder::new()
2298///     .witt_level_ceiling(WittLevel::W8)
2299///     .thermodynamic_budget(1024)
2300///     .target_domains(&domains)
2301///     .result_type::<ConstrainedTypeInput>()
2302///     .validate();
2303/// assert!(err.is_err());
2304/// if let Err(violation) = err {
2305///     assert_eq!(violation.kind, ViolationKind::Missing);
2306///     assert!(violation.property_iri.contains("rootTerm"));
2307/// }
2308/// ```
2309#[derive(Debug, Clone)]
2310pub struct CompileUnitBuilder<'a> {
2311    /// The root term expression.
2312    root_term: Option<&'a [Term]>,
2313    /// v0.2.2 Phase H1: named bindings (`let name : Type = term` forms)
2314    /// declared by the compile unit. Stage 5 extracts these into a `BindingsTable`
2315    /// for grounding-aware and session resolvers; an empty slice declares no bindings.
2316    bindings: Option<&'a [Binding]>,
2317    /// The widest Witt level the computation may reference.
2318    witt_level_ceiling: Option<WittLevel>,
2319    /// Landauer-bounded energy budget.
2320    thermodynamic_budget: Option<u64>,
2321    /// Verification domains targeted.
2322    target_domains: Option<&'a [VerificationDomain]>,
2323    /// v0.2.2 T6.11: result-type IRI for ShapeMismatch detection.
2324    /// Set via `result_type::<T: ConstrainedTypeShape>()`. Required by
2325    /// `validate()` and `validate_compile_unit_const`. The pipeline checks
2326    /// `unit.result_type_iri() == T::IRI` at `pipeline::run` invocation
2327    /// time, returning `PipelineFailure::ShapeMismatch` on mismatch.
2328    result_type_iri: Option<&'static str>,
2329}
2330
2331/// A validated compile unit ready for reduction admission.
2332/// v0.2.2 Phase A (carrier widening): the lifetime parameter `'a` ties
2333/// the post-validation carrier to its builder's borrow. The `root_term`
2334/// and `target_domains` slices are retained through validation so
2335/// resolvers can inspect declared structure — previously these fields
2336/// were discarded at `validate()` and every resolver received a
2337/// 3-field scalar witness with no walkable structure.
2338/// Const-constructed compile units use the trivial specialization
2339/// `CompileUnit<'static>` — borrow-free and usable in const contexts.
2340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2341pub struct CompileUnit<'a> {
2342    /// The Witt level ceiling.
2343    level: WittLevel,
2344    /// The thermodynamic budget.
2345    budget: u64,
2346    /// v0.2.2 T6.11: result-type IRI. The pipeline matches this against
2347    /// the caller's `T::IRI` to detect shape mismatches.
2348    result_type_iri: &'static str,
2349    /// v0.2.2 Phase A: root term expression, retained from the builder.
2350    /// Stage 5 (extract bindings) and the grounding-aware resolver walk
2351    /// this slice. Empty slice for the trivial `CompileUnit<'static>`
2352    /// specialization produced by builders that don't carry a term AST.
2353    root_term: &'a [Term],
2354    /// v0.2.2 Phase H1: named bindings retained from the builder. Consumed by Stage 5
2355    /// (`bindings_from_unit`) to materialize the `BindingsTable` for grounding-aware,
2356    /// session, and superposition resolvers. Empty slice declares no bindings.
2357    bindings: &'a [Binding],
2358    /// v0.2.2 Phase A: verification domains targeted, retained from the builder.
2359    target_domains: &'a [VerificationDomain],
2360}
2361
2362impl<'a> CompileUnit<'a> {
2363    /// Returns the Witt level ceiling declared at validation time.
2364    #[inline]
2365    #[must_use]
2366    pub const fn witt_level(&self) -> WittLevel {
2367        self.level
2368    }
2369
2370    /// Returns the thermodynamic budget declared at validation time.
2371    #[inline]
2372    #[must_use]
2373    pub const fn thermodynamic_budget(&self) -> u64 {
2374        self.budget
2375    }
2376
2377    /// v0.2.2 T6.11: returns the result-type IRI declared at validation
2378    /// time. The pipeline matches this against the caller's `T::IRI` to
2379    /// detect shape mismatches.
2380    #[inline]
2381    #[must_use]
2382    pub const fn result_type_iri(&self) -> &'static str {
2383        self.result_type_iri
2384    }
2385
2386    /// v0.2.2 Phase A: returns the root term slice declared at validation time.
2387    /// Empty for builders that did not supply a term AST.
2388    #[inline]
2389    #[must_use]
2390    pub const fn root_term(&self) -> &'a [Term] {
2391        self.root_term
2392    }
2393
2394    /// v0.2.2 Phase H1: returns the named bindings declared at validation time.
2395    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the `BindingsTable`.
2396    /// Empty slice for compile units that declare no bindings.
2397    #[inline]
2398    #[must_use]
2399    pub const fn bindings(&self) -> &'a [Binding] {
2400        self.bindings
2401    }
2402
2403    /// v0.2.2 Phase A: returns the verification domains declared at validation time.
2404    #[inline]
2405    #[must_use]
2406    pub const fn target_domains(&self) -> &'a [VerificationDomain] {
2407        self.target_domains
2408    }
2409
2410    /// v0.2.2 Phase G / T2.8 + T6.11: const-constructible parts form used
2411    /// by `validate_compile_unit_const` — the const-fn path reads the
2412    /// builder's fields and packs them into the `Validated` result.
2413    /// v0.2.2 Phase H1: bindings slice is retained alongside root_term;
2414    /// empty slice declares no bindings.
2415    #[inline]
2416    #[must_use]
2417    pub(crate) const fn from_parts_const(
2418        level: WittLevel,
2419        budget: u64,
2420        result_type_iri: &'static str,
2421        root_term: &'a [Term],
2422        bindings: &'a [Binding],
2423        target_domains: &'a [VerificationDomain],
2424    ) -> Self {
2425        Self {
2426            level,
2427            budget,
2428            result_type_iri,
2429            root_term,
2430            bindings,
2431            target_domains,
2432        }
2433    }
2434}
2435
2436impl<'a> CompileUnitBuilder<'a> {
2437    /// Creates a new empty builder.
2438    #[must_use]
2439    pub const fn new() -> Self {
2440        Self {
2441            root_term: None,
2442            bindings: None,
2443            witt_level_ceiling: None,
2444            thermodynamic_budget: None,
2445            target_domains: None,
2446            result_type_iri: None,
2447        }
2448    }
2449
2450    /// Set the root term expression.
2451    #[must_use]
2452    pub const fn root_term(mut self, terms: &'a [Term]) -> Self {
2453        self.root_term = Some(terms);
2454        self
2455    }
2456
2457    /// v0.2.2 Phase H1: set the named bindings declared by this compile unit.
2458    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the
2459    /// `BindingsTable` for grounding-aware, session, and superposition resolvers.
2460    /// Omit for compile units without bindings; the default is the empty slice.
2461    #[must_use]
2462    pub const fn bindings(mut self, bindings: &'a [Binding]) -> Self {
2463        self.bindings = Some(bindings);
2464        self
2465    }
2466
2467    /// Set the Witt level ceiling.
2468    #[must_use]
2469    pub const fn witt_level_ceiling(mut self, level: WittLevel) -> Self {
2470        self.witt_level_ceiling = Some(level);
2471        self
2472    }
2473
2474    /// Set the thermodynamic budget.
2475    #[must_use]
2476    pub const fn thermodynamic_budget(mut self, budget: u64) -> Self {
2477        self.thermodynamic_budget = Some(budget);
2478        self
2479    }
2480
2481    /// Set the target verification domains.
2482    #[must_use]
2483    pub const fn target_domains(mut self, domains: &'a [VerificationDomain]) -> Self {
2484        self.target_domains = Some(domains);
2485        self
2486    }
2487
2488    /// v0.2.2 T6.11: set the result-type IRI from a `ConstrainedTypeShape`
2489    /// type parameter. The pipeline matches this against the caller's
2490    /// `T::IRI` at `pipeline::run` invocation time, returning
2491    /// `PipelineFailure::ShapeMismatch` on mismatch.
2492    /// Required: `validate()` and `validate_compile_unit_const` reject
2493    /// builders without a result type set.
2494    #[must_use]
2495    pub const fn result_type<T: crate::pipeline::ConstrainedTypeShape>(mut self) -> Self {
2496        self.result_type_iri = Some(T::IRI);
2497        self
2498    }
2499
2500    /// v0.2.2 T2.8: const-fn accessor exposing the stored Witt level
2501    /// ceiling (or `None` if unset). Used by `validate_compile_unit_const`.
2502    #[inline]
2503    #[must_use]
2504    pub const fn witt_level_option(&self) -> Option<WittLevel> {
2505        self.witt_level_ceiling
2506    }
2507
2508    /// v0.2.2 T2.8: const-fn accessor exposing the stored thermodynamic
2509    /// budget (or `None` if unset).
2510    #[inline]
2511    #[must_use]
2512    pub const fn budget_option(&self) -> Option<u64> {
2513        self.thermodynamic_budget
2514    }
2515
2516    /// v0.2.2 T6.13: const-fn accessor — `true` iff `root_term` is set.
2517    #[inline]
2518    #[must_use]
2519    pub const fn has_root_term_const(&self) -> bool {
2520        self.root_term.is_some()
2521    }
2522
2523    /// v0.2.2 T6.13: const-fn accessor — `true` iff `target_domains` is
2524    /// set and non-empty.
2525    #[inline]
2526    #[must_use]
2527    pub const fn has_target_domains_const(&self) -> bool {
2528        match self.target_domains {
2529            Some(d) => !d.is_empty(),
2530            None => false,
2531        }
2532    }
2533
2534    /// v0.2.2 T6.13: const-fn accessor exposing the stored result-type IRI
2535    /// (or `None` if unset). Used by `validate_compile_unit_const`.
2536    #[inline]
2537    #[must_use]
2538    pub const fn result_type_iri_const(&self) -> Option<&'static str> {
2539        self.result_type_iri
2540    }
2541
2542    /// v0.2.2 Phase A: const-fn accessor exposing the stored root-term slice,
2543    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2544    /// propagate the AST into the widened `CompileUnit<'a>` carrier.
2545    #[inline]
2546    #[must_use]
2547    pub const fn root_term_slice_const(&self) -> &'a [Term] {
2548        match self.root_term {
2549            Some(terms) => terms,
2550            None => &[],
2551        }
2552    }
2553
2554    /// v0.2.2 Phase H1: const-fn accessor exposing the stored bindings slice,
2555    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2556    /// propagate the bindings declaration into the widened `CompileUnit<'a>` carrier.
2557    #[inline]
2558    #[must_use]
2559    pub const fn bindings_slice_const(&self) -> &'a [Binding] {
2560        match self.bindings {
2561            Some(bindings) => bindings,
2562            None => &[],
2563        }
2564    }
2565
2566    /// v0.2.2 Phase A: const-fn accessor exposing the stored target-domains
2567    /// slice, or an empty slice if unset. Used by `validate_compile_unit_const`.
2568    #[inline]
2569    #[must_use]
2570    pub const fn target_domains_slice_const(&self) -> &'a [VerificationDomain] {
2571        match self.target_domains {
2572            Some(d) => d,
2573            None => &[],
2574        }
2575    }
2576
2577    /// Validate against `CompileUnitShape`.
2578    /// Tier 1: checks presence and cardinality of all required fields.
2579    /// Tier 2: checks budget solvency and level coherence.
2580    /// # Errors
2581    /// Returns `ShapeViolation` if any constraint is not satisfied.
2582    pub fn validate(self) -> Result<Validated<CompileUnit<'a>>, ShapeViolation> {
2583        let root_term = match self.root_term {
2584            Some(terms) => terms,
2585            None => {
2586                return Err(ShapeViolation {
2587                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2588                    constraint_iri:
2589                        "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2590                    property_iri: "https://uor.foundation/reduction/rootTerm",
2591                    expected_range: "https://uor.foundation/schema/Term",
2592                    min_count: 1,
2593                    max_count: 1,
2594                    kind: ViolationKind::Missing,
2595                })
2596            }
2597        };
2598        let level =
2599            match self.witt_level_ceiling {
2600                Some(l) => l,
2601                None => return Err(ShapeViolation {
2602                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2603                    constraint_iri:
2604                        "https://uor.foundation/conformance/compileUnit_unitWittLevel_constraint",
2605                    property_iri: "https://uor.foundation/reduction/unitWittLevel",
2606                    expected_range: "https://uor.foundation/schema/WittLevel",
2607                    min_count: 1,
2608                    max_count: 1,
2609                    kind: ViolationKind::Missing,
2610                }),
2611            };
2612        let budget = match self.thermodynamic_budget {
2613            Some(b) => b,
2614            None => return Err(ShapeViolation {
2615                shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2616                constraint_iri:
2617                    "https://uor.foundation/conformance/compileUnit_thermodynamicBudget_constraint",
2618                property_iri: "https://uor.foundation/reduction/thermodynamicBudget",
2619                expected_range: "http://www.w3.org/2001/XMLSchema#decimal",
2620                min_count: 1,
2621                max_count: 1,
2622                kind: ViolationKind::Missing,
2623            }),
2624        };
2625        let target_domains =
2626            match self.target_domains {
2627                Some(d) if !d.is_empty() => d,
2628                _ => return Err(ShapeViolation {
2629                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2630                    constraint_iri:
2631                        "https://uor.foundation/conformance/compileUnit_targetDomains_constraint",
2632                    property_iri: "https://uor.foundation/reduction/targetDomains",
2633                    expected_range: "https://uor.foundation/op/VerificationDomain",
2634                    min_count: 1,
2635                    max_count: 0,
2636                    kind: ViolationKind::Missing,
2637                }),
2638            };
2639        let result_type_iri = match self.result_type_iri {
2640            Some(iri) => iri,
2641            None => {
2642                return Err(ShapeViolation {
2643                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2644                    constraint_iri:
2645                        "https://uor.foundation/conformance/compileUnit_resultType_constraint",
2646                    property_iri: "https://uor.foundation/reduction/resultType",
2647                    expected_range: "https://uor.foundation/type/ConstrainedType",
2648                    min_count: 1,
2649                    max_count: 1,
2650                    kind: ViolationKind::Missing,
2651                })
2652            }
2653        };
2654        // v0.2.2 Phase H1: bindings is optional; absent declares no bindings.
2655        let bindings: &'a [Binding] = match self.bindings {
2656            Some(b) => b,
2657            None => &[],
2658        };
2659        Ok(Validated::new(CompileUnit {
2660            level,
2661            budget,
2662            result_type_iri,
2663            root_term,
2664            bindings,
2665            target_domains,
2666        }))
2667    }
2668}
2669
2670impl<'a> Default for CompileUnitBuilder<'a> {
2671    fn default() -> Self {
2672        Self::new()
2673    }
2674}
2675
2676/// Builder for `EffectDeclaration`. Validates against `EffectShape`.
2677#[derive(Debug, Clone)]
2678pub struct EffectDeclarationBuilder<'a> {
2679    /// The `name` field.
2680    name: Option<&'a str>,
2681    /// The `target_sites` field.
2682    target_sites: Option<&'a [u32]>,
2683    /// The `budget_delta` field.
2684    budget_delta: Option<i64>,
2685    /// The `commutes` field.
2686    commutes: Option<bool>,
2687}
2688
2689/// Declared effect validated against `EffectShape`.
2690#[derive(Debug, Clone, PartialEq, Eq)]
2691pub struct EffectDeclaration {
2692    /// Shape IRI this declaration was validated against.
2693    pub shape_iri: &'static str,
2694}
2695
2696impl EffectDeclaration {
2697    /// v0.2.2 Phase G: const-constructible empty form used by
2698    /// `validate_*_const` companion functions.
2699    #[inline]
2700    #[must_use]
2701    #[allow(dead_code)]
2702    pub(crate) const fn empty_const() -> Self {
2703        Self {
2704            shape_iri: "https://uor.foundation/conformance/EffectShape",
2705        }
2706    }
2707}
2708
2709impl<'a> EffectDeclarationBuilder<'a> {
2710    /// Creates a new empty builder.
2711    #[must_use]
2712    pub const fn new() -> Self {
2713        Self {
2714            name: None,
2715            target_sites: None,
2716            budget_delta: None,
2717            commutes: None,
2718        }
2719    }
2720
2721    /// Set the `name` field.
2722    #[must_use]
2723    pub const fn name(mut self, value: &'a str) -> Self {
2724        self.name = Some(value);
2725        self
2726    }
2727
2728    /// Set the `target_sites` field.
2729    #[must_use]
2730    pub const fn target_sites(mut self, value: &'a [u32]) -> Self {
2731        self.target_sites = Some(value);
2732        self
2733    }
2734
2735    /// Set the `budget_delta` field.
2736    #[must_use]
2737    pub const fn budget_delta(mut self, value: i64) -> Self {
2738        self.budget_delta = Some(value);
2739        self
2740    }
2741
2742    /// Set the `commutes` field.
2743    #[must_use]
2744    pub const fn commutes(mut self, value: bool) -> Self {
2745        self.commutes = Some(value);
2746        self
2747    }
2748
2749    /// Validate against `EffectShape`.
2750    /// # Errors
2751    /// Returns `ShapeViolation` if any required field is missing.
2752    pub fn validate(self) -> Result<Validated<EffectDeclaration>, ShapeViolation> {
2753        if self.name.is_none() {
2754            return Err(ShapeViolation {
2755                shape_iri: "https://uor.foundation/conformance/EffectShape",
2756                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2757                property_iri: "https://uor.foundation/conformance/name",
2758                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2759                min_count: 1,
2760                max_count: 1,
2761                kind: ViolationKind::Missing,
2762            });
2763        }
2764        if self.target_sites.is_none() {
2765            return Err(ShapeViolation {
2766                shape_iri: "https://uor.foundation/conformance/EffectShape",
2767                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2768                property_iri: "https://uor.foundation/conformance/target_sites",
2769                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2770                min_count: 1,
2771                max_count: 1,
2772                kind: ViolationKind::Missing,
2773            });
2774        }
2775        if self.budget_delta.is_none() {
2776            return Err(ShapeViolation {
2777                shape_iri: "https://uor.foundation/conformance/EffectShape",
2778                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2779                property_iri: "https://uor.foundation/conformance/budget_delta",
2780                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2781                min_count: 1,
2782                max_count: 1,
2783                kind: ViolationKind::Missing,
2784            });
2785        }
2786        if self.commutes.is_none() {
2787            return Err(ShapeViolation {
2788                shape_iri: "https://uor.foundation/conformance/EffectShape",
2789                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2790                property_iri: "https://uor.foundation/conformance/commutes",
2791                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2792                min_count: 1,
2793                max_count: 1,
2794                kind: ViolationKind::Missing,
2795            });
2796        }
2797        Ok(Validated::new(EffectDeclaration {
2798            shape_iri: "https://uor.foundation/conformance/EffectShape",
2799        }))
2800    }
2801
2802    /// Phase C.1: const-fn companion for `EffectDeclarationBuilder::validate`.
2803    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2804    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2805    /// # Errors
2806    /// Returns `ShapeViolation` if any required field is missing.
2807    pub const fn validate_const(
2808        &self,
2809    ) -> Result<Validated<EffectDeclaration, CompileTime>, ShapeViolation> {
2810        if self.name.is_none() {
2811            return Err(ShapeViolation {
2812                shape_iri: "https://uor.foundation/conformance/EffectShape",
2813                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2814                property_iri: "https://uor.foundation/conformance/name",
2815                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2816                min_count: 1,
2817                max_count: 1,
2818                kind: ViolationKind::Missing,
2819            });
2820        }
2821        if self.target_sites.is_none() {
2822            return Err(ShapeViolation {
2823                shape_iri: "https://uor.foundation/conformance/EffectShape",
2824                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2825                property_iri: "https://uor.foundation/conformance/target_sites",
2826                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2827                min_count: 1,
2828                max_count: 1,
2829                kind: ViolationKind::Missing,
2830            });
2831        }
2832        if self.budget_delta.is_none() {
2833            return Err(ShapeViolation {
2834                shape_iri: "https://uor.foundation/conformance/EffectShape",
2835                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2836                property_iri: "https://uor.foundation/conformance/budget_delta",
2837                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2838                min_count: 1,
2839                max_count: 1,
2840                kind: ViolationKind::Missing,
2841            });
2842        }
2843        if self.commutes.is_none() {
2844            return Err(ShapeViolation {
2845                shape_iri: "https://uor.foundation/conformance/EffectShape",
2846                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2847                property_iri: "https://uor.foundation/conformance/commutes",
2848                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2849                min_count: 1,
2850                max_count: 1,
2851                kind: ViolationKind::Missing,
2852            });
2853        }
2854        Ok(Validated::new(EffectDeclaration {
2855            shape_iri: "https://uor.foundation/conformance/EffectShape",
2856        }))
2857    }
2858}
2859
2860impl<'a> Default for EffectDeclarationBuilder<'a> {
2861    fn default() -> Self {
2862        Self::new()
2863    }
2864}
2865
2866/// Builder for `GroundingDeclaration`. Validates against `GroundingShape`.
2867#[derive(Debug, Clone)]
2868pub struct GroundingDeclarationBuilder<'a> {
2869    /// The `source_type` field.
2870    source_type: Option<&'a str>,
2871    /// The `ring_mapping` field.
2872    ring_mapping: Option<&'a str>,
2873    /// The `invertibility` field.
2874    invertibility: Option<bool>,
2875}
2876
2877/// Declared grounding validated against `GroundingShape`.
2878#[derive(Debug, Clone, PartialEq, Eq)]
2879pub struct GroundingDeclaration {
2880    /// Shape IRI this declaration was validated against.
2881    pub shape_iri: &'static str,
2882}
2883
2884impl GroundingDeclaration {
2885    /// v0.2.2 Phase G: const-constructible empty form used by
2886    /// `validate_*_const` companion functions.
2887    #[inline]
2888    #[must_use]
2889    #[allow(dead_code)]
2890    pub(crate) const fn empty_const() -> Self {
2891        Self {
2892            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2893        }
2894    }
2895}
2896
2897impl<'a> GroundingDeclarationBuilder<'a> {
2898    /// Creates a new empty builder.
2899    #[must_use]
2900    pub const fn new() -> Self {
2901        Self {
2902            source_type: None,
2903            ring_mapping: None,
2904            invertibility: None,
2905        }
2906    }
2907
2908    /// Set the `source_type` field.
2909    #[must_use]
2910    pub const fn source_type(mut self, value: &'a str) -> Self {
2911        self.source_type = Some(value);
2912        self
2913    }
2914
2915    /// Set the `ring_mapping` field.
2916    #[must_use]
2917    pub const fn ring_mapping(mut self, value: &'a str) -> Self {
2918        self.ring_mapping = Some(value);
2919        self
2920    }
2921
2922    /// Set the `invertibility` field.
2923    #[must_use]
2924    pub const fn invertibility(mut self, value: bool) -> Self {
2925        self.invertibility = Some(value);
2926        self
2927    }
2928
2929    /// Validate against `GroundingShape`.
2930    /// # Errors
2931    /// Returns `ShapeViolation` if any required field is missing.
2932    pub fn validate(self) -> Result<Validated<GroundingDeclaration>, ShapeViolation> {
2933        if self.source_type.is_none() {
2934            return Err(ShapeViolation {
2935                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2936                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2937                property_iri: "https://uor.foundation/conformance/source_type",
2938                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2939                min_count: 1,
2940                max_count: 1,
2941                kind: ViolationKind::Missing,
2942            });
2943        }
2944        if self.ring_mapping.is_none() {
2945            return Err(ShapeViolation {
2946                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2947                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2948                property_iri: "https://uor.foundation/conformance/ring_mapping",
2949                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2950                min_count: 1,
2951                max_count: 1,
2952                kind: ViolationKind::Missing,
2953            });
2954        }
2955        if self.invertibility.is_none() {
2956            return Err(ShapeViolation {
2957                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2958                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2959                property_iri: "https://uor.foundation/conformance/invertibility",
2960                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2961                min_count: 1,
2962                max_count: 1,
2963                kind: ViolationKind::Missing,
2964            });
2965        }
2966        Ok(Validated::new(GroundingDeclaration {
2967            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2968        }))
2969    }
2970
2971    /// Phase C.1: const-fn companion for `GroundingDeclarationBuilder::validate`.
2972    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2973    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2974    /// # Errors
2975    /// Returns `ShapeViolation` if any required field is missing.
2976    pub const fn validate_const(
2977        &self,
2978    ) -> Result<Validated<GroundingDeclaration, CompileTime>, ShapeViolation> {
2979        if self.source_type.is_none() {
2980            return Err(ShapeViolation {
2981                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2982                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2983                property_iri: "https://uor.foundation/conformance/source_type",
2984                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2985                min_count: 1,
2986                max_count: 1,
2987                kind: ViolationKind::Missing,
2988            });
2989        }
2990        if self.ring_mapping.is_none() {
2991            return Err(ShapeViolation {
2992                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2993                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2994                property_iri: "https://uor.foundation/conformance/ring_mapping",
2995                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2996                min_count: 1,
2997                max_count: 1,
2998                kind: ViolationKind::Missing,
2999            });
3000        }
3001        if self.invertibility.is_none() {
3002            return Err(ShapeViolation {
3003                shape_iri: "https://uor.foundation/conformance/GroundingShape",
3004                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
3005                property_iri: "https://uor.foundation/conformance/invertibility",
3006                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3007                min_count: 1,
3008                max_count: 1,
3009                kind: ViolationKind::Missing,
3010            });
3011        }
3012        Ok(Validated::new(GroundingDeclaration {
3013            shape_iri: "https://uor.foundation/conformance/GroundingShape",
3014        }))
3015    }
3016}
3017
3018impl<'a> Default for GroundingDeclarationBuilder<'a> {
3019    fn default() -> Self {
3020        Self::new()
3021    }
3022}
3023
3024/// Builder for `DispatchDeclaration`. Validates against `DispatchShape`.
3025#[derive(Debug, Clone)]
3026pub struct DispatchDeclarationBuilder<'a> {
3027    /// The `predicate` field.
3028    predicate: Option<&'a [Term]>,
3029    /// The `target_resolver` field.
3030    target_resolver: Option<&'a str>,
3031    /// The `priority` field.
3032    priority: Option<u32>,
3033}
3034
3035/// Declared dispatch rule validated against `DispatchShape`.
3036#[derive(Debug, Clone, PartialEq, Eq)]
3037pub struct DispatchDeclaration {
3038    /// Shape IRI this declaration was validated against.
3039    pub shape_iri: &'static str,
3040}
3041
3042impl DispatchDeclaration {
3043    /// v0.2.2 Phase G: const-constructible empty form used by
3044    /// `validate_*_const` companion functions.
3045    #[inline]
3046    #[must_use]
3047    #[allow(dead_code)]
3048    pub(crate) const fn empty_const() -> Self {
3049        Self {
3050            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3051        }
3052    }
3053}
3054
3055impl<'a> DispatchDeclarationBuilder<'a> {
3056    /// Creates a new empty builder.
3057    #[must_use]
3058    pub const fn new() -> Self {
3059        Self {
3060            predicate: None,
3061            target_resolver: None,
3062            priority: None,
3063        }
3064    }
3065
3066    /// Set the `predicate` field.
3067    #[must_use]
3068    pub const fn predicate(mut self, value: &'a [Term]) -> Self {
3069        self.predicate = Some(value);
3070        self
3071    }
3072
3073    /// Set the `target_resolver` field.
3074    #[must_use]
3075    pub const fn target_resolver(mut self, value: &'a str) -> Self {
3076        self.target_resolver = Some(value);
3077        self
3078    }
3079
3080    /// Set the `priority` field.
3081    #[must_use]
3082    pub const fn priority(mut self, value: u32) -> Self {
3083        self.priority = Some(value);
3084        self
3085    }
3086
3087    /// Validate against `DispatchShape`.
3088    /// # Errors
3089    /// Returns `ShapeViolation` if any required field is missing.
3090    pub fn validate(self) -> Result<Validated<DispatchDeclaration>, ShapeViolation> {
3091        if self.predicate.is_none() {
3092            return Err(ShapeViolation {
3093                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3094                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3095                property_iri: "https://uor.foundation/conformance/predicate",
3096                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3097                min_count: 1,
3098                max_count: 1,
3099                kind: ViolationKind::Missing,
3100            });
3101        }
3102        if self.target_resolver.is_none() {
3103            return Err(ShapeViolation {
3104                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3105                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3106                property_iri: "https://uor.foundation/conformance/target_resolver",
3107                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3108                min_count: 1,
3109                max_count: 1,
3110                kind: ViolationKind::Missing,
3111            });
3112        }
3113        if self.priority.is_none() {
3114            return Err(ShapeViolation {
3115                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3116                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3117                property_iri: "https://uor.foundation/conformance/priority",
3118                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3119                min_count: 1,
3120                max_count: 1,
3121                kind: ViolationKind::Missing,
3122            });
3123        }
3124        Ok(Validated::new(DispatchDeclaration {
3125            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3126        }))
3127    }
3128
3129    /// Phase C.1: const-fn companion for `DispatchDeclarationBuilder::validate`.
3130    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3131    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3132    /// # Errors
3133    /// Returns `ShapeViolation` if any required field is missing.
3134    pub const fn validate_const(
3135        &self,
3136    ) -> Result<Validated<DispatchDeclaration, CompileTime>, ShapeViolation> {
3137        if self.predicate.is_none() {
3138            return Err(ShapeViolation {
3139                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3140                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3141                property_iri: "https://uor.foundation/conformance/predicate",
3142                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3143                min_count: 1,
3144                max_count: 1,
3145                kind: ViolationKind::Missing,
3146            });
3147        }
3148        if self.target_resolver.is_none() {
3149            return Err(ShapeViolation {
3150                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3151                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3152                property_iri: "https://uor.foundation/conformance/target_resolver",
3153                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3154                min_count: 1,
3155                max_count: 1,
3156                kind: ViolationKind::Missing,
3157            });
3158        }
3159        if self.priority.is_none() {
3160            return Err(ShapeViolation {
3161                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3162                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3163                property_iri: "https://uor.foundation/conformance/priority",
3164                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3165                min_count: 1,
3166                max_count: 1,
3167                kind: ViolationKind::Missing,
3168            });
3169        }
3170        Ok(Validated::new(DispatchDeclaration {
3171            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3172        }))
3173    }
3174}
3175
3176impl<'a> Default for DispatchDeclarationBuilder<'a> {
3177    fn default() -> Self {
3178        Self::new()
3179    }
3180}
3181
3182/// Builder for `LeaseDeclaration`. Validates against `LeaseShape`.
3183#[derive(Debug, Clone)]
3184pub struct LeaseDeclarationBuilder<'a> {
3185    /// The `linear_site` field.
3186    linear_site: Option<u32>,
3187    /// The `scope` field.
3188    scope: Option<&'a str>,
3189}
3190
3191/// Declared lease validated against `LeaseShape`.
3192#[derive(Debug, Clone, PartialEq, Eq)]
3193pub struct LeaseDeclaration {
3194    /// Shape IRI this declaration was validated against.
3195    pub shape_iri: &'static str,
3196}
3197
3198impl LeaseDeclaration {
3199    /// v0.2.2 Phase G: const-constructible empty form used by
3200    /// `validate_*_const` companion functions.
3201    #[inline]
3202    #[must_use]
3203    #[allow(dead_code)]
3204    pub(crate) const fn empty_const() -> Self {
3205        Self {
3206            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3207        }
3208    }
3209}
3210
3211impl<'a> LeaseDeclarationBuilder<'a> {
3212    /// Creates a new empty builder.
3213    #[must_use]
3214    pub const fn new() -> Self {
3215        Self {
3216            linear_site: None,
3217            scope: None,
3218        }
3219    }
3220
3221    /// Set the `linear_site` field.
3222    #[must_use]
3223    pub const fn linear_site(mut self, value: u32) -> Self {
3224        self.linear_site = Some(value);
3225        self
3226    }
3227
3228    /// Set the `scope` field.
3229    #[must_use]
3230    pub const fn scope(mut self, value: &'a str) -> Self {
3231        self.scope = Some(value);
3232        self
3233    }
3234
3235    /// Validate against `LeaseShape`.
3236    /// # Errors
3237    /// Returns `ShapeViolation` if any required field is missing.
3238    pub fn validate(self) -> Result<Validated<LeaseDeclaration>, ShapeViolation> {
3239        if self.linear_site.is_none() {
3240            return Err(ShapeViolation {
3241                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3242                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3243                property_iri: "https://uor.foundation/conformance/linear_site",
3244                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3245                min_count: 1,
3246                max_count: 1,
3247                kind: ViolationKind::Missing,
3248            });
3249        }
3250        if self.scope.is_none() {
3251            return Err(ShapeViolation {
3252                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3253                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3254                property_iri: "https://uor.foundation/conformance/scope",
3255                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3256                min_count: 1,
3257                max_count: 1,
3258                kind: ViolationKind::Missing,
3259            });
3260        }
3261        Ok(Validated::new(LeaseDeclaration {
3262            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3263        }))
3264    }
3265
3266    /// Phase C.1: const-fn companion for `LeaseDeclarationBuilder::validate`.
3267    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3268    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3269    /// # Errors
3270    /// Returns `ShapeViolation` if any required field is missing.
3271    pub const fn validate_const(
3272        &self,
3273    ) -> Result<Validated<LeaseDeclaration, CompileTime>, ShapeViolation> {
3274        if self.linear_site.is_none() {
3275            return Err(ShapeViolation {
3276                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3277                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3278                property_iri: "https://uor.foundation/conformance/linear_site",
3279                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3280                min_count: 1,
3281                max_count: 1,
3282                kind: ViolationKind::Missing,
3283            });
3284        }
3285        if self.scope.is_none() {
3286            return Err(ShapeViolation {
3287                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3288                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3289                property_iri: "https://uor.foundation/conformance/scope",
3290                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3291                min_count: 1,
3292                max_count: 1,
3293                kind: ViolationKind::Missing,
3294            });
3295        }
3296        Ok(Validated::new(LeaseDeclaration {
3297            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3298        }))
3299    }
3300}
3301
3302impl<'a> Default for LeaseDeclarationBuilder<'a> {
3303    fn default() -> Self {
3304        Self::new()
3305    }
3306}
3307
3308/// Builder for `StreamDeclaration`. Validates against `StreamShape`.
3309#[derive(Debug, Clone)]
3310pub struct StreamDeclarationBuilder<'a> {
3311    /// The `seed` field.
3312    seed: Option<&'a [Term]>,
3313    /// The `step` field.
3314    step: Option<&'a [Term]>,
3315    /// The `productivity_witness` field.
3316    productivity_witness: Option<&'a str>,
3317}
3318
3319/// Declared stream validated against `StreamShape`.
3320#[derive(Debug, Clone, PartialEq, Eq)]
3321pub struct StreamDeclaration {
3322    /// Shape IRI this declaration was validated against.
3323    pub shape_iri: &'static str,
3324}
3325
3326impl StreamDeclaration {
3327    /// v0.2.2 Phase G: const-constructible empty form used by
3328    /// `validate_*_const` companion functions.
3329    #[inline]
3330    #[must_use]
3331    #[allow(dead_code)]
3332    pub(crate) const fn empty_const() -> Self {
3333        Self {
3334            shape_iri: "https://uor.foundation/conformance/StreamShape",
3335        }
3336    }
3337}
3338
3339impl<'a> StreamDeclarationBuilder<'a> {
3340    /// Creates a new empty builder.
3341    #[must_use]
3342    pub const fn new() -> Self {
3343        Self {
3344            seed: None,
3345            step: None,
3346            productivity_witness: None,
3347        }
3348    }
3349
3350    /// Set the `seed` field.
3351    #[must_use]
3352    pub const fn seed(mut self, value: &'a [Term]) -> Self {
3353        self.seed = Some(value);
3354        self
3355    }
3356
3357    /// Set the `step` field.
3358    #[must_use]
3359    pub const fn step(mut self, value: &'a [Term]) -> Self {
3360        self.step = Some(value);
3361        self
3362    }
3363
3364    /// Set the `productivity_witness` field.
3365    #[must_use]
3366    pub const fn productivity_witness(mut self, value: &'a str) -> Self {
3367        self.productivity_witness = Some(value);
3368        self
3369    }
3370
3371    /// Validate against `StreamShape`.
3372    /// # Errors
3373    /// Returns `ShapeViolation` if any required field is missing.
3374    pub fn validate(self) -> Result<Validated<StreamDeclaration>, ShapeViolation> {
3375        if self.seed.is_none() {
3376            return Err(ShapeViolation {
3377                shape_iri: "https://uor.foundation/conformance/StreamShape",
3378                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3379                property_iri: "https://uor.foundation/conformance/seed",
3380                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3381                min_count: 1,
3382                max_count: 1,
3383                kind: ViolationKind::Missing,
3384            });
3385        }
3386        if self.step.is_none() {
3387            return Err(ShapeViolation {
3388                shape_iri: "https://uor.foundation/conformance/StreamShape",
3389                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3390                property_iri: "https://uor.foundation/conformance/step",
3391                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3392                min_count: 1,
3393                max_count: 1,
3394                kind: ViolationKind::Missing,
3395            });
3396        }
3397        if self.productivity_witness.is_none() {
3398            return Err(ShapeViolation {
3399                shape_iri: "https://uor.foundation/conformance/StreamShape",
3400                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3401                property_iri: "https://uor.foundation/conformance/productivity_witness",
3402                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3403                min_count: 1,
3404                max_count: 1,
3405                kind: ViolationKind::Missing,
3406            });
3407        }
3408        Ok(Validated::new(StreamDeclaration {
3409            shape_iri: "https://uor.foundation/conformance/StreamShape",
3410        }))
3411    }
3412
3413    /// Phase C.1: const-fn companion for `StreamDeclarationBuilder::validate`.
3414    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3415    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3416    /// # Errors
3417    /// Returns `ShapeViolation` if any required field is missing.
3418    pub const fn validate_const(
3419        &self,
3420    ) -> Result<Validated<StreamDeclaration, CompileTime>, ShapeViolation> {
3421        if self.seed.is_none() {
3422            return Err(ShapeViolation {
3423                shape_iri: "https://uor.foundation/conformance/StreamShape",
3424                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3425                property_iri: "https://uor.foundation/conformance/seed",
3426                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3427                min_count: 1,
3428                max_count: 1,
3429                kind: ViolationKind::Missing,
3430            });
3431        }
3432        if self.step.is_none() {
3433            return Err(ShapeViolation {
3434                shape_iri: "https://uor.foundation/conformance/StreamShape",
3435                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3436                property_iri: "https://uor.foundation/conformance/step",
3437                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3438                min_count: 1,
3439                max_count: 1,
3440                kind: ViolationKind::Missing,
3441            });
3442        }
3443        if self.productivity_witness.is_none() {
3444            return Err(ShapeViolation {
3445                shape_iri: "https://uor.foundation/conformance/StreamShape",
3446                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3447                property_iri: "https://uor.foundation/conformance/productivity_witness",
3448                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3449                min_count: 1,
3450                max_count: 1,
3451                kind: ViolationKind::Missing,
3452            });
3453        }
3454        Ok(Validated::new(StreamDeclaration {
3455            shape_iri: "https://uor.foundation/conformance/StreamShape",
3456        }))
3457    }
3458}
3459
3460impl<'a> Default for StreamDeclarationBuilder<'a> {
3461    fn default() -> Self {
3462        Self::new()
3463    }
3464}
3465
3466/// Builder for `PredicateDeclaration`. Validates against `PredicateShape`.
3467#[derive(Debug, Clone)]
3468pub struct PredicateDeclarationBuilder<'a> {
3469    /// The `input_type` field.
3470    input_type: Option<&'a str>,
3471    /// The `evaluator` field.
3472    evaluator: Option<&'a [Term]>,
3473    /// The `termination_witness` field.
3474    termination_witness: Option<&'a str>,
3475}
3476
3477/// Declared predicate validated against `PredicateShape`.
3478#[derive(Debug, Clone, PartialEq, Eq)]
3479pub struct PredicateDeclaration {
3480    /// Shape IRI this declaration was validated against.
3481    pub shape_iri: &'static str,
3482}
3483
3484impl PredicateDeclaration {
3485    /// v0.2.2 Phase G: const-constructible empty form used by
3486    /// `validate_*_const` companion functions.
3487    #[inline]
3488    #[must_use]
3489    #[allow(dead_code)]
3490    pub(crate) const fn empty_const() -> Self {
3491        Self {
3492            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3493        }
3494    }
3495}
3496
3497impl<'a> PredicateDeclarationBuilder<'a> {
3498    /// Creates a new empty builder.
3499    #[must_use]
3500    pub const fn new() -> Self {
3501        Self {
3502            input_type: None,
3503            evaluator: None,
3504            termination_witness: None,
3505        }
3506    }
3507
3508    /// Set the `input_type` field.
3509    #[must_use]
3510    pub const fn input_type(mut self, value: &'a str) -> Self {
3511        self.input_type = Some(value);
3512        self
3513    }
3514
3515    /// Set the `evaluator` field.
3516    #[must_use]
3517    pub const fn evaluator(mut self, value: &'a [Term]) -> Self {
3518        self.evaluator = Some(value);
3519        self
3520    }
3521
3522    /// Set the `termination_witness` field.
3523    #[must_use]
3524    pub const fn termination_witness(mut self, value: &'a str) -> Self {
3525        self.termination_witness = Some(value);
3526        self
3527    }
3528
3529    /// Validate against `PredicateShape`.
3530    /// # Errors
3531    /// Returns `ShapeViolation` if any required field is missing.
3532    pub fn validate(self) -> Result<Validated<PredicateDeclaration>, ShapeViolation> {
3533        if self.input_type.is_none() {
3534            return Err(ShapeViolation {
3535                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3536                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3537                property_iri: "https://uor.foundation/conformance/input_type",
3538                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3539                min_count: 1,
3540                max_count: 1,
3541                kind: ViolationKind::Missing,
3542            });
3543        }
3544        if self.evaluator.is_none() {
3545            return Err(ShapeViolation {
3546                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3547                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3548                property_iri: "https://uor.foundation/conformance/evaluator",
3549                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3550                min_count: 1,
3551                max_count: 1,
3552                kind: ViolationKind::Missing,
3553            });
3554        }
3555        if self.termination_witness.is_none() {
3556            return Err(ShapeViolation {
3557                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3558                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3559                property_iri: "https://uor.foundation/conformance/termination_witness",
3560                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3561                min_count: 1,
3562                max_count: 1,
3563                kind: ViolationKind::Missing,
3564            });
3565        }
3566        Ok(Validated::new(PredicateDeclaration {
3567            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3568        }))
3569    }
3570
3571    /// Phase C.1: const-fn companion for `PredicateDeclarationBuilder::validate`.
3572    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3573    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3574    /// # Errors
3575    /// Returns `ShapeViolation` if any required field is missing.
3576    pub const fn validate_const(
3577        &self,
3578    ) -> Result<Validated<PredicateDeclaration, CompileTime>, ShapeViolation> {
3579        if self.input_type.is_none() {
3580            return Err(ShapeViolation {
3581                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3582                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3583                property_iri: "https://uor.foundation/conformance/input_type",
3584                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3585                min_count: 1,
3586                max_count: 1,
3587                kind: ViolationKind::Missing,
3588            });
3589        }
3590        if self.evaluator.is_none() {
3591            return Err(ShapeViolation {
3592                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3593                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3594                property_iri: "https://uor.foundation/conformance/evaluator",
3595                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3596                min_count: 1,
3597                max_count: 1,
3598                kind: ViolationKind::Missing,
3599            });
3600        }
3601        if self.termination_witness.is_none() {
3602            return Err(ShapeViolation {
3603                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3604                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3605                property_iri: "https://uor.foundation/conformance/termination_witness",
3606                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3607                min_count: 1,
3608                max_count: 1,
3609                kind: ViolationKind::Missing,
3610            });
3611        }
3612        Ok(Validated::new(PredicateDeclaration {
3613            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3614        }))
3615    }
3616}
3617
3618impl<'a> Default for PredicateDeclarationBuilder<'a> {
3619    fn default() -> Self {
3620        Self::new()
3621    }
3622}
3623
3624/// Builder for `ParallelDeclaration`. Validates against `ParallelShape`.
3625#[derive(Debug, Clone)]
3626pub struct ParallelDeclarationBuilder<'a> {
3627    /// The `site_partition` field.
3628    site_partition: Option<&'a [u32]>,
3629    /// The `disjointness_witness` field.
3630    disjointness_witness: Option<&'a str>,
3631}
3632
3633/// Declared parallel composition validated against `ParallelShape`.
3634#[derive(Debug, Clone, PartialEq, Eq)]
3635pub struct ParallelDeclaration {
3636    /// Shape IRI this declaration was validated against.
3637    pub shape_iri: &'static str,
3638}
3639
3640impl ParallelDeclaration {
3641    /// v0.2.2 Phase G: const-constructible empty form used by
3642    /// `validate_*_const` companion functions.
3643    #[inline]
3644    #[must_use]
3645    #[allow(dead_code)]
3646    pub(crate) const fn empty_const() -> Self {
3647        Self {
3648            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3649        }
3650    }
3651}
3652
3653impl<'a> ParallelDeclarationBuilder<'a> {
3654    /// Creates a new empty builder.
3655    #[must_use]
3656    pub const fn new() -> Self {
3657        Self {
3658            site_partition: None,
3659            disjointness_witness: None,
3660        }
3661    }
3662
3663    /// Set the `site_partition` field.
3664    #[must_use]
3665    pub const fn site_partition(mut self, value: &'a [u32]) -> Self {
3666        self.site_partition = Some(value);
3667        self
3668    }
3669
3670    /// Set the `disjointness_witness` field.
3671    #[must_use]
3672    pub const fn disjointness_witness(mut self, value: &'a str) -> Self {
3673        self.disjointness_witness = Some(value);
3674        self
3675    }
3676
3677    /// Validate against `ParallelShape`.
3678    /// # Errors
3679    /// Returns `ShapeViolation` if any required field is missing.
3680    pub fn validate(self) -> Result<Validated<ParallelDeclaration>, ShapeViolation> {
3681        if self.site_partition.is_none() {
3682            return Err(ShapeViolation {
3683                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3684                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3685                property_iri: "https://uor.foundation/conformance/site_partition",
3686                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3687                min_count: 1,
3688                max_count: 1,
3689                kind: ViolationKind::Missing,
3690            });
3691        }
3692        if self.disjointness_witness.is_none() {
3693            return Err(ShapeViolation {
3694                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3695                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3696                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3697                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3698                min_count: 1,
3699                max_count: 1,
3700                kind: ViolationKind::Missing,
3701            });
3702        }
3703        Ok(Validated::new(ParallelDeclaration {
3704            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3705        }))
3706    }
3707
3708    /// Phase C.1: const-fn companion for `ParallelDeclarationBuilder::validate`.
3709    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3710    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3711    /// # Errors
3712    /// Returns `ShapeViolation` if any required field is missing.
3713    pub const fn validate_const(
3714        &self,
3715    ) -> Result<Validated<ParallelDeclaration, CompileTime>, ShapeViolation> {
3716        if self.site_partition.is_none() {
3717            return Err(ShapeViolation {
3718                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3719                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3720                property_iri: "https://uor.foundation/conformance/site_partition",
3721                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3722                min_count: 1,
3723                max_count: 1,
3724                kind: ViolationKind::Missing,
3725            });
3726        }
3727        if self.disjointness_witness.is_none() {
3728            return Err(ShapeViolation {
3729                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3730                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3731                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3732                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3733                min_count: 1,
3734                max_count: 1,
3735                kind: ViolationKind::Missing,
3736            });
3737        }
3738        Ok(Validated::new(ParallelDeclaration {
3739            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3740        }))
3741    }
3742}
3743
3744impl<'a> Default for ParallelDeclarationBuilder<'a> {
3745    fn default() -> Self {
3746        Self::new()
3747    }
3748}
3749
3750impl<'a> ParallelDeclarationBuilder<'a> {
3751    /// v0.2.2 T2.7: const-fn accessor returning the length of the
3752    /// declared site partition (or 0 if unset).
3753    #[inline]
3754    #[must_use]
3755    pub const fn site_partition_len(&self) -> usize {
3756        match self.site_partition {
3757            Some(p) => p.len(),
3758            None => 0,
3759        }
3760    }
3761
3762    /// v0.2.2 Phase A: const-fn accessor returning the declared site-partition
3763    /// slice, or an empty slice if unset. Used by `validate_parallel_const`
3764    /// to propagate the partition into the widened `ParallelDeclaration<'a>`.
3765    #[inline]
3766    #[must_use]
3767    pub const fn site_partition_slice_const(&self) -> &'a [u32] {
3768        match self.site_partition {
3769            Some(p) => p,
3770            None => &[],
3771        }
3772    }
3773
3774    /// v0.2.2 Phase A: const-fn accessor returning the declared disjointness-witness
3775    /// IRI string, or an empty string if unset.
3776    #[inline]
3777    #[must_use]
3778    pub const fn disjointness_witness_const(&self) -> &'a str {
3779        match self.disjointness_witness {
3780            Some(s) => s,
3781            None => "",
3782        }
3783    }
3784}
3785
3786impl<'a> StreamDeclarationBuilder<'a> {
3787    /// v0.2.2 canonical: productivity bound is 1 if a `productivityWitness`
3788    /// IRI is declared (the stream attests termination via a `proof:Proof`
3789    /// individual), 0 otherwise. The witness's IRI points to the termination
3790    /// proof; downstream resolvers dereference it for detailed bound
3791    /// information. This two-level split (presence flag here, IRI dereference
3792    /// elsewhere) is the canonical foundation-level shape.
3793    #[inline]
3794    #[must_use]
3795    pub const fn productivity_bound_const(&self) -> u64 {
3796        match self.productivity_witness {
3797            Some(_) => 1,
3798            None => 0,
3799        }
3800    }
3801
3802    /// v0.2.2 Phase A: const-fn accessor returning the declared seed term slice,
3803    /// or an empty slice if unset.
3804    #[inline]
3805    #[must_use]
3806    pub const fn seed_slice_const(&self) -> &'a [Term] {
3807        match self.seed {
3808            Some(t) => t,
3809            None => &[],
3810        }
3811    }
3812
3813    /// v0.2.2 Phase A: const-fn accessor returning the declared step term slice,
3814    /// or an empty slice if unset.
3815    #[inline]
3816    #[must_use]
3817    pub const fn step_slice_const(&self) -> &'a [Term] {
3818        match self.step {
3819            Some(t) => t,
3820            None => &[],
3821        }
3822    }
3823
3824    /// v0.2.2 Phase A: const-fn accessor returning the declared productivity-witness
3825    /// IRI, or an empty string if unset.
3826    #[inline]
3827    #[must_use]
3828    pub const fn productivity_witness_const(&self) -> &'a str {
3829        match self.productivity_witness {
3830            Some(s) => s,
3831            None => "",
3832        }
3833    }
3834}
3835
3836/// Builder for declaring a new Witt level beyond W32.
3837/// Validates against `WittLevelShape`.
3838#[derive(Debug, Clone)]
3839pub struct WittLevelDeclarationBuilder {
3840    /// The declared bit width.
3841    bit_width: Option<u32>,
3842    /// The declared cycle size.
3843    cycle_size: Option<u128>,
3844    /// The predecessor level.
3845    predecessor: Option<WittLevel>,
3846}
3847
3848/// Validated Witt level declaration.
3849#[derive(Debug, Clone, PartialEq, Eq)]
3850pub struct WittLevelDeclaration {
3851    /// The declared bit width.
3852    pub bit_width: u32,
3853    /// The predecessor level.
3854    pub predecessor: WittLevel,
3855}
3856
3857impl WittLevelDeclarationBuilder {
3858    /// Creates a new empty builder.
3859    #[must_use]
3860    pub const fn new() -> Self {
3861        Self {
3862            bit_width: None,
3863            cycle_size: None,
3864            predecessor: None,
3865        }
3866    }
3867
3868    /// Set the declared bit width.
3869    #[must_use]
3870    pub const fn bit_width(mut self, w: u32) -> Self {
3871        self.bit_width = Some(w);
3872        self
3873    }
3874
3875    /// Set the declared cycle size.
3876    #[must_use]
3877    pub const fn cycle_size(mut self, s: u128) -> Self {
3878        self.cycle_size = Some(s);
3879        self
3880    }
3881
3882    /// Set the predecessor Witt level.
3883    #[must_use]
3884    pub const fn predecessor(mut self, level: WittLevel) -> Self {
3885        self.predecessor = Some(level);
3886        self
3887    }
3888
3889    /// Validate against `WittLevelShape`.
3890    /// # Errors
3891    /// Returns `ShapeViolation` if any required field is missing.
3892    pub fn validate(self) -> Result<Validated<WittLevelDeclaration>, ShapeViolation> {
3893        let bw = match self.bit_width {
3894            Some(w) => w,
3895            None => {
3896                return Err(ShapeViolation {
3897                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3898                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3899                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3900                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3901                    min_count: 1,
3902                    max_count: 1,
3903                    kind: ViolationKind::Missing,
3904                })
3905            }
3906        };
3907        let pred = match self.predecessor {
3908            Some(p) => p,
3909            None => {
3910                return Err(ShapeViolation {
3911                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3912                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3913                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3914                    expected_range: "https://uor.foundation/schema/WittLevel",
3915                    min_count: 1,
3916                    max_count: 1,
3917                    kind: ViolationKind::Missing,
3918                })
3919            }
3920        };
3921        Ok(Validated::new(WittLevelDeclaration {
3922            bit_width: bw,
3923            predecessor: pred,
3924        }))
3925    }
3926
3927    /// Phase C.1: const-fn companion for `WittLevelDeclarationBuilder::validate`.
3928    /// # Errors
3929    /// Returns `ShapeViolation` if any required field is missing.
3930    pub const fn validate_const(
3931        &self,
3932    ) -> Result<Validated<WittLevelDeclaration, CompileTime>, ShapeViolation> {
3933        let bw = match self.bit_width {
3934            Some(w) => w,
3935            None => {
3936                return Err(ShapeViolation {
3937                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3938                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3939                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3940                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3941                    min_count: 1,
3942                    max_count: 1,
3943                    kind: ViolationKind::Missing,
3944                })
3945            }
3946        };
3947        let pred = match self.predecessor {
3948            Some(p) => p,
3949            None => {
3950                return Err(ShapeViolation {
3951                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3952                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3953                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3954                    expected_range: "https://uor.foundation/schema/WittLevel",
3955                    min_count: 1,
3956                    max_count: 1,
3957                    kind: ViolationKind::Missing,
3958                })
3959            }
3960        };
3961        Ok(Validated::new(WittLevelDeclaration {
3962            bit_width: bw,
3963            predecessor: pred,
3964        }))
3965    }
3966}
3967
3968impl Default for WittLevelDeclarationBuilder {
3969    fn default() -> Self {
3970        Self::new()
3971    }
3972}
3973
3974/// Boundary session state tracker for the two-phase minting boundary.
3975/// Records crossing count and idempotency flag. Private fields
3976/// prevent external construction.
3977#[derive(Debug, Clone, PartialEq, Eq)]
3978pub struct BoundarySession {
3979    /// Total boundary crossings in this session.
3980    crossing_count: u32,
3981    /// Whether the boundary effect is idempotent.
3982    is_idempotent: bool,
3983}
3984
3985impl BoundarySession {
3986    /// Creates a new boundary session. Only callable within the crate.
3987    #[inline]
3988    #[allow(dead_code)]
3989    pub(crate) const fn new(is_idempotent: bool) -> Self {
3990        Self {
3991            crossing_count: 0,
3992            is_idempotent,
3993        }
3994    }
3995
3996    /// Returns the total boundary crossings.
3997    #[inline]
3998    #[must_use]
3999    pub const fn crossing_count(&self) -> u32 {
4000        self.crossing_count
4001    }
4002
4003    /// Returns whether the boundary effect is idempotent.
4004    #[inline]
4005    #[must_use]
4006    pub const fn is_idempotent(&self) -> bool {
4007        self.is_idempotent
4008    }
4009}
4010
4011/// Validate a scalar grounding intermediate against a `GroundingShape`
4012/// and mint it into a `Datum`. Only callable within `uor-foundation`.
4013/// # Errors
4014/// Returns `ShapeViolation` if the coordinate fails validation.
4015#[allow(dead_code)]
4016pub(crate) fn validate_and_mint_coord(
4017    grounded: GroundedCoord,
4018    shape: &Validated<GroundingDeclaration>,
4019    session: &mut BoundarySession,
4020) -> Result<Datum, ShapeViolation> {
4021    // The Validated<GroundingDeclaration> proves the shape was already
4022    // validated at builder time. The coordinate's level is guaranteed
4023    // correct by the closed GroundedCoordInner enum — the type system
4024    // enforces that only supported levels can be constructed.
4025    let _ = shape; // shape validation passed at builder time
4026    session.crossing_count += 1;
4027    let inner = match grounded.inner {
4028        GroundedCoordInner::W8(b) => DatumInner::W8(b),
4029        GroundedCoordInner::W16(b) => DatumInner::W16(b),
4030        GroundedCoordInner::W24(b) => DatumInner::W24(b),
4031        GroundedCoordInner::W32(b) => DatumInner::W32(b),
4032        GroundedCoordInner::W40(b) => DatumInner::W40(b),
4033        GroundedCoordInner::W48(b) => DatumInner::W48(b),
4034        GroundedCoordInner::W56(b) => DatumInner::W56(b),
4035        GroundedCoordInner::W64(b) => DatumInner::W64(b),
4036        GroundedCoordInner::W72(b) => DatumInner::W72(b),
4037        GroundedCoordInner::W80(b) => DatumInner::W80(b),
4038        GroundedCoordInner::W88(b) => DatumInner::W88(b),
4039        GroundedCoordInner::W96(b) => DatumInner::W96(b),
4040        GroundedCoordInner::W104(b) => DatumInner::W104(b),
4041        GroundedCoordInner::W112(b) => DatumInner::W112(b),
4042        GroundedCoordInner::W120(b) => DatumInner::W120(b),
4043        GroundedCoordInner::W128(b) => DatumInner::W128(b),
4044    };
4045    Ok(Datum { inner })
4046}
4047
4048/// Validate a tuple grounding intermediate and mint into a `Datum`.
4049/// Only callable within `uor-foundation`.
4050/// Mints the first coordinate of the tuple as the representative `Datum`.
4051/// Composite multi-coordinate `Datum` construction depends on the target
4052/// type's site decomposition, which is resolved during reduction evaluation.
4053/// # Errors
4054/// Returns `ShapeViolation` if the tuple is empty or fails validation.
4055#[allow(dead_code)]
4056pub(crate) fn validate_and_mint_tuple<const N: usize>(
4057    grounded: GroundedTuple<N>,
4058    shape: &Validated<GroundingDeclaration>,
4059    session: &mut BoundarySession,
4060) -> Result<Datum, ShapeViolation> {
4061    if N == 0 {
4062        return Err(ShapeViolation {
4063            shape_iri: shape.inner().shape_iri,
4064            constraint_iri: shape.inner().shape_iri,
4065            property_iri: "https://uor.foundation/conformance/groundingSourceType",
4066            expected_range: "https://uor.foundation/type/TypeDefinition",
4067            min_count: 1,
4068            max_count: 0,
4069            kind: ViolationKind::CardinalityViolation,
4070        });
4071    }
4072    // Mint the first coordinate as the representative Datum.
4073    // The full tuple is decomposed during reduction evaluation,
4074    // where each coordinate maps to a site in the constrained type.
4075    validate_and_mint_coord(grounded.coords[0].clone(), shape, session)
4076}
4077
4078/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Datum`.
4079/// Takes host bytes that have already passed the author's `Grounding` impl and
4080/// mints them into a sealed `Datum` at the supplied Witt level. The bytes are
4081/// decoded according to the level's byte width.
4082/// # Errors
4083/// Returns [`ShapeViolation`] if `bytes.len()` doesn't match the level's byte width
4084/// or if the level is unsupported.
4085pub fn mint_datum(level: crate::WittLevel, bytes: &[u8]) -> Result<Datum, ShapeViolation> {
4086    let expected_bytes = (level.witt_length() / 8) as usize;
4087    if bytes.len() != expected_bytes {
4088        return Err(ShapeViolation {
4089            shape_iri: "https://uor.foundation/u/Datum",
4090            constraint_iri: "https://uor.foundation/u/DatumByteWidth",
4091            property_iri: "https://uor.foundation/u/datumBytes",
4092            expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
4093            min_count: expected_bytes as u32,
4094            max_count: expected_bytes as u32,
4095            kind: crate::ViolationKind::CardinalityViolation,
4096        });
4097    }
4098    let inner = match level.witt_length() {
4099        8 => {
4100            let mut buf = [0u8; 1];
4101            let mut i = 0;
4102            while i < 1 {
4103                buf[i] = bytes[i];
4104                i += 1;
4105            }
4106            DatumInner::W8(buf)
4107        }
4108        16 => {
4109            let mut buf = [0u8; 2];
4110            let mut i = 0;
4111            while i < 2 {
4112                buf[i] = bytes[i];
4113                i += 1;
4114            }
4115            DatumInner::W16(buf)
4116        }
4117        24 => {
4118            let mut buf = [0u8; 3];
4119            let mut i = 0;
4120            while i < 3 {
4121                buf[i] = bytes[i];
4122                i += 1;
4123            }
4124            DatumInner::W24(buf)
4125        }
4126        32 => {
4127            let mut buf = [0u8; 4];
4128            let mut i = 0;
4129            while i < 4 {
4130                buf[i] = bytes[i];
4131                i += 1;
4132            }
4133            DatumInner::W32(buf)
4134        }
4135        40 => {
4136            let mut buf = [0u8; 5];
4137            let mut i = 0;
4138            while i < 5 {
4139                buf[i] = bytes[i];
4140                i += 1;
4141            }
4142            DatumInner::W40(buf)
4143        }
4144        48 => {
4145            let mut buf = [0u8; 6];
4146            let mut i = 0;
4147            while i < 6 {
4148                buf[i] = bytes[i];
4149                i += 1;
4150            }
4151            DatumInner::W48(buf)
4152        }
4153        56 => {
4154            let mut buf = [0u8; 7];
4155            let mut i = 0;
4156            while i < 7 {
4157                buf[i] = bytes[i];
4158                i += 1;
4159            }
4160            DatumInner::W56(buf)
4161        }
4162        64 => {
4163            let mut buf = [0u8; 8];
4164            let mut i = 0;
4165            while i < 8 {
4166                buf[i] = bytes[i];
4167                i += 1;
4168            }
4169            DatumInner::W64(buf)
4170        }
4171        72 => {
4172            let mut buf = [0u8; 9];
4173            let mut i = 0;
4174            while i < 9 {
4175                buf[i] = bytes[i];
4176                i += 1;
4177            }
4178            DatumInner::W72(buf)
4179        }
4180        80 => {
4181            let mut buf = [0u8; 10];
4182            let mut i = 0;
4183            while i < 10 {
4184                buf[i] = bytes[i];
4185                i += 1;
4186            }
4187            DatumInner::W80(buf)
4188        }
4189        88 => {
4190            let mut buf = [0u8; 11];
4191            let mut i = 0;
4192            while i < 11 {
4193                buf[i] = bytes[i];
4194                i += 1;
4195            }
4196            DatumInner::W88(buf)
4197        }
4198        96 => {
4199            let mut buf = [0u8; 12];
4200            let mut i = 0;
4201            while i < 12 {
4202                buf[i] = bytes[i];
4203                i += 1;
4204            }
4205            DatumInner::W96(buf)
4206        }
4207        104 => {
4208            let mut buf = [0u8; 13];
4209            let mut i = 0;
4210            while i < 13 {
4211                buf[i] = bytes[i];
4212                i += 1;
4213            }
4214            DatumInner::W104(buf)
4215        }
4216        112 => {
4217            let mut buf = [0u8; 14];
4218            let mut i = 0;
4219            while i < 14 {
4220                buf[i] = bytes[i];
4221                i += 1;
4222            }
4223            DatumInner::W112(buf)
4224        }
4225        120 => {
4226            let mut buf = [0u8; 15];
4227            let mut i = 0;
4228            while i < 15 {
4229                buf[i] = bytes[i];
4230                i += 1;
4231            }
4232            DatumInner::W120(buf)
4233        }
4234        128 => {
4235            let mut buf = [0u8; 16];
4236            let mut i = 0;
4237            while i < 16 {
4238                buf[i] = bytes[i];
4239                i += 1;
4240            }
4241            DatumInner::W128(buf)
4242        }
4243        _ => {
4244            return Err(ShapeViolation {
4245                shape_iri: "https://uor.foundation/u/Datum",
4246                constraint_iri: "https://uor.foundation/u/DatumLevel",
4247                property_iri: "https://uor.foundation/u/datumLevel",
4248                expected_range: "https://uor.foundation/schema/WittLevel",
4249                min_count: 1,
4250                max_count: 1,
4251                kind: crate::ViolationKind::ValueCheck,
4252            })
4253        }
4254    };
4255    Ok(Datum { inner })
4256}
4257
4258/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Triad<L>`.
4259/// Takes three coordinate values that satisfy the Triad shape constraint and
4260/// mints them into a sealed `Triad<L>` at the level marker `L`.
4261#[must_use]
4262pub const fn mint_triad<L>(stratum: u64, spectrum: u64, address: u64) -> Triad<L> {
4263    Triad::new(stratum, spectrum, address)
4264}
4265
4266/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Derivation`.
4267/// Takes the precursor's step count + Witt level + content fingerprint and mints
4268/// a sealed `Derivation` carrying the typed transition witness.
4269#[must_use]
4270pub const fn mint_derivation(
4271    step_count: u32,
4272    witt_level_bits: u16,
4273    content_fingerprint: ContentFingerprint,
4274) -> Derivation {
4275    Derivation::new(step_count, witt_level_bits, content_fingerprint)
4276}
4277
4278/// Wiki ADR-016 mint primitive: cross-crate construction surface for `FreeRank`.
4279/// Takes a natural-number rank witness (total site capacity at the Witt level plus
4280/// the number of currently pinned sites) and mints it into a sealed `FreeRank`.
4281#[must_use]
4282pub const fn mint_freerank(total: u32, pinned: u32) -> FreeRank {
4283    FreeRank::new(total, pinned)
4284}
4285
4286/// Evaluate a binary ring operation at compile time.
4287/// One helper is emitted per `schema:WittLevel` individual. The `uor!`
4288/// proc macro delegates to these helpers; it never performs ring
4289/// arithmetic itself.
4290/// # Examples
4291/// ```rust
4292/// use uor_foundation::enforcement::{const_ring_eval_w8, const_ring_eval_unary_w8};
4293/// use uor_foundation::PrimitiveOp;
4294///
4295/// // Ring arithmetic in Z/256Z: all operations wrap modulo 256.
4296///
4297/// // Addition wraps: 200 + 100 = 300 -> 300 - 256 = 44
4298/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Add, 200, 100), 44);
4299///
4300/// // Multiplication: 3 * 5 = 15 (no wrap needed)
4301/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Mul, 3, 5), 15);
4302///
4303/// // XOR: bitwise exclusive-or
4304/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Xor, 0b1010, 0b1100), 0b0110);
4305///
4306/// // Negation: neg(x) = 256 - x (additive inverse in Z/256Z)
4307/// assert_eq!(const_ring_eval_unary_w8(PrimitiveOp::Neg, 1), 255);
4308///
4309/// // The critical identity: neg(bnot(x)) = succ(x) for all x
4310/// let x = 42u8;
4311/// let lhs = const_ring_eval_unary_w8(PrimitiveOp::Neg,
4312///     const_ring_eval_unary_w8(PrimitiveOp::Bnot, x));
4313/// let rhs = const_ring_eval_unary_w8(PrimitiveOp::Succ, x);
4314/// assert_eq!(lhs, rhs);
4315/// ```
4316#[inline]
4317#[must_use]
4318#[allow(clippy::manual_checked_ops)]
4319pub const fn const_ring_eval_w8(op: PrimitiveOp, a: u8, b: u8) -> u8 {
4320    match op {
4321        PrimitiveOp::Add => a.wrapping_add(b),
4322        PrimitiveOp::Sub => a.wrapping_sub(b),
4323        PrimitiveOp::Mul => a.wrapping_mul(b),
4324        PrimitiveOp::Xor => a ^ b,
4325        PrimitiveOp::And => a & b,
4326        PrimitiveOp::Or => a | b,
4327        PrimitiveOp::Le => (a <= b) as u8,
4328        PrimitiveOp::Lt => (a < b) as u8,
4329        PrimitiveOp::Ge => (a >= b) as u8,
4330        PrimitiveOp::Gt => (a > b) as u8,
4331        PrimitiveOp::Concat => 0,
4332        PrimitiveOp::Div => {
4333            if b == 0 {
4334                0
4335            } else {
4336                a / b
4337            }
4338        }
4339        PrimitiveOp::Mod => {
4340            if b == 0 {
4341                0
4342            } else {
4343                a % b
4344            }
4345        }
4346        PrimitiveOp::Pow => const_pow_w8(a, b),
4347        _ => 0,
4348    }
4349}
4350
4351#[inline]
4352#[must_use]
4353pub const fn const_pow_w8(base: u8, exp: u8) -> u8 {
4354    let mut result: u8 = 1;
4355    let mut b: u8 = base;
4356    let mut e: u8 = exp;
4357    while e > 0 {
4358        if (e & 1) == 1 {
4359            result = result.wrapping_mul(b);
4360        }
4361        b = b.wrapping_mul(b);
4362        e >>= 1;
4363    }
4364    result
4365}
4366
4367#[inline]
4368#[must_use]
4369pub const fn const_ring_eval_unary_w8(op: PrimitiveOp, a: u8) -> u8 {
4370    match op {
4371        PrimitiveOp::Neg => 0u8.wrapping_sub(a),
4372        PrimitiveOp::Bnot => !a,
4373        PrimitiveOp::Succ => a.wrapping_add(1),
4374        PrimitiveOp::Pred => a.wrapping_sub(1),
4375        _ => 0,
4376    }
4377}
4378
4379#[inline]
4380#[must_use]
4381#[allow(clippy::manual_checked_ops)]
4382pub const fn const_ring_eval_w16(op: PrimitiveOp, a: u16, b: u16) -> u16 {
4383    match op {
4384        PrimitiveOp::Add => a.wrapping_add(b),
4385        PrimitiveOp::Sub => a.wrapping_sub(b),
4386        PrimitiveOp::Mul => a.wrapping_mul(b),
4387        PrimitiveOp::Xor => a ^ b,
4388        PrimitiveOp::And => a & b,
4389        PrimitiveOp::Or => a | b,
4390        PrimitiveOp::Le => (a <= b) as u16,
4391        PrimitiveOp::Lt => (a < b) as u16,
4392        PrimitiveOp::Ge => (a >= b) as u16,
4393        PrimitiveOp::Gt => (a > b) as u16,
4394        PrimitiveOp::Concat => 0,
4395        PrimitiveOp::Div => {
4396            if b == 0 {
4397                0
4398            } else {
4399                a / b
4400            }
4401        }
4402        PrimitiveOp::Mod => {
4403            if b == 0 {
4404                0
4405            } else {
4406                a % b
4407            }
4408        }
4409        PrimitiveOp::Pow => const_pow_w16(a, b),
4410        _ => 0,
4411    }
4412}
4413
4414#[inline]
4415#[must_use]
4416pub const fn const_pow_w16(base: u16, exp: u16) -> u16 {
4417    let mut result: u16 = 1;
4418    let mut b: u16 = base;
4419    let mut e: u16 = exp;
4420    while e > 0 {
4421        if (e & 1) == 1 {
4422            result = result.wrapping_mul(b);
4423        }
4424        b = b.wrapping_mul(b);
4425        e >>= 1;
4426    }
4427    result
4428}
4429
4430#[inline]
4431#[must_use]
4432pub const fn const_ring_eval_unary_w16(op: PrimitiveOp, a: u16) -> u16 {
4433    match op {
4434        PrimitiveOp::Neg => 0u16.wrapping_sub(a),
4435        PrimitiveOp::Bnot => !a,
4436        PrimitiveOp::Succ => a.wrapping_add(1),
4437        PrimitiveOp::Pred => a.wrapping_sub(1),
4438        _ => 0,
4439    }
4440}
4441
4442#[inline]
4443#[must_use]
4444#[allow(clippy::manual_checked_ops)]
4445pub const fn const_ring_eval_w24(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4446    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4447    match op {
4448        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4449        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4450        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4451        PrimitiveOp::Xor => (a ^ b) & MASK,
4452        PrimitiveOp::And => (a & b) & MASK,
4453        PrimitiveOp::Or => (a | b) & MASK,
4454        PrimitiveOp::Le => (a <= b) as u32,
4455        PrimitiveOp::Lt => (a < b) as u32,
4456        PrimitiveOp::Ge => (a >= b) as u32,
4457        PrimitiveOp::Gt => (a > b) as u32,
4458        PrimitiveOp::Concat => 0,
4459        PrimitiveOp::Div => {
4460            if b == 0 {
4461                0
4462            } else {
4463                (a / b) & MASK
4464            }
4465        }
4466        PrimitiveOp::Mod => {
4467            if b == 0 {
4468                0
4469            } else {
4470                (a % b) & MASK
4471            }
4472        }
4473        PrimitiveOp::Pow => (const_pow_w24(a, b)) & MASK,
4474        _ => 0,
4475    }
4476}
4477
4478#[inline]
4479#[must_use]
4480pub const fn const_pow_w24(base: u32, exp: u32) -> u32 {
4481    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4482    let mut result: u32 = 1;
4483    let mut b: u32 = (base) & MASK;
4484    let mut e: u32 = exp;
4485    while e > 0 {
4486        if (e & 1) == 1 {
4487            result = (result.wrapping_mul(b)) & MASK;
4488        }
4489        b = (b.wrapping_mul(b)) & MASK;
4490        e >>= 1;
4491    }
4492    result
4493}
4494
4495#[inline]
4496#[must_use]
4497pub const fn const_ring_eval_unary_w24(op: PrimitiveOp, a: u32) -> u32 {
4498    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4499    match op {
4500        PrimitiveOp::Neg => (0u32.wrapping_sub(a)) & MASK,
4501        PrimitiveOp::Bnot => (!a) & MASK,
4502        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4503        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4504        _ => 0,
4505    }
4506}
4507
4508#[inline]
4509#[must_use]
4510#[allow(clippy::manual_checked_ops)]
4511pub const fn const_ring_eval_w32(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4512    match op {
4513        PrimitiveOp::Add => a.wrapping_add(b),
4514        PrimitiveOp::Sub => a.wrapping_sub(b),
4515        PrimitiveOp::Mul => a.wrapping_mul(b),
4516        PrimitiveOp::Xor => a ^ b,
4517        PrimitiveOp::And => a & b,
4518        PrimitiveOp::Or => a | b,
4519        PrimitiveOp::Le => (a <= b) as u32,
4520        PrimitiveOp::Lt => (a < b) as u32,
4521        PrimitiveOp::Ge => (a >= b) as u32,
4522        PrimitiveOp::Gt => (a > b) as u32,
4523        PrimitiveOp::Concat => 0,
4524        PrimitiveOp::Div => {
4525            if b == 0 {
4526                0
4527            } else {
4528                a / b
4529            }
4530        }
4531        PrimitiveOp::Mod => {
4532            if b == 0 {
4533                0
4534            } else {
4535                a % b
4536            }
4537        }
4538        PrimitiveOp::Pow => const_pow_w32(a, b),
4539        _ => 0,
4540    }
4541}
4542
4543#[inline]
4544#[must_use]
4545pub const fn const_pow_w32(base: u32, exp: u32) -> u32 {
4546    let mut result: u32 = 1;
4547    let mut b: u32 = base;
4548    let mut e: u32 = exp;
4549    while e > 0 {
4550        if (e & 1) == 1 {
4551            result = result.wrapping_mul(b);
4552        }
4553        b = b.wrapping_mul(b);
4554        e >>= 1;
4555    }
4556    result
4557}
4558
4559#[inline]
4560#[must_use]
4561pub const fn const_ring_eval_unary_w32(op: PrimitiveOp, a: u32) -> u32 {
4562    match op {
4563        PrimitiveOp::Neg => 0u32.wrapping_sub(a),
4564        PrimitiveOp::Bnot => !a,
4565        PrimitiveOp::Succ => a.wrapping_add(1),
4566        PrimitiveOp::Pred => a.wrapping_sub(1),
4567        _ => 0,
4568    }
4569}
4570
4571#[inline]
4572#[must_use]
4573#[allow(clippy::manual_checked_ops)]
4574pub const fn const_ring_eval_w40(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4575    const MASK: u64 = u64::MAX >> (64 - 40);
4576    match op {
4577        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4578        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4579        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4580        PrimitiveOp::Xor => (a ^ b) & MASK,
4581        PrimitiveOp::And => (a & b) & MASK,
4582        PrimitiveOp::Or => (a | b) & MASK,
4583        PrimitiveOp::Le => (a <= b) as u64,
4584        PrimitiveOp::Lt => (a < b) as u64,
4585        PrimitiveOp::Ge => (a >= b) as u64,
4586        PrimitiveOp::Gt => (a > b) as u64,
4587        PrimitiveOp::Concat => 0,
4588        PrimitiveOp::Div => {
4589            if b == 0 {
4590                0
4591            } else {
4592                (a / b) & MASK
4593            }
4594        }
4595        PrimitiveOp::Mod => {
4596            if b == 0 {
4597                0
4598            } else {
4599                (a % b) & MASK
4600            }
4601        }
4602        PrimitiveOp::Pow => (const_pow_w40(a, b)) & MASK,
4603        _ => 0,
4604    }
4605}
4606
4607#[inline]
4608#[must_use]
4609pub const fn const_pow_w40(base: u64, exp: u64) -> u64 {
4610    const MASK: u64 = u64::MAX >> (64 - 40);
4611    let mut result: u64 = 1;
4612    let mut b: u64 = (base) & MASK;
4613    let mut e: u64 = exp;
4614    while e > 0 {
4615        if (e & 1) == 1 {
4616            result = (result.wrapping_mul(b)) & MASK;
4617        }
4618        b = (b.wrapping_mul(b)) & MASK;
4619        e >>= 1;
4620    }
4621    result
4622}
4623
4624#[inline]
4625#[must_use]
4626pub const fn const_ring_eval_unary_w40(op: PrimitiveOp, a: u64) -> u64 {
4627    const MASK: u64 = u64::MAX >> (64 - 40);
4628    match op {
4629        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4630        PrimitiveOp::Bnot => (!a) & MASK,
4631        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4632        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4633        _ => 0,
4634    }
4635}
4636
4637#[inline]
4638#[must_use]
4639#[allow(clippy::manual_checked_ops)]
4640pub const fn const_ring_eval_w48(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4641    const MASK: u64 = u64::MAX >> (64 - 48);
4642    match op {
4643        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4644        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4645        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4646        PrimitiveOp::Xor => (a ^ b) & MASK,
4647        PrimitiveOp::And => (a & b) & MASK,
4648        PrimitiveOp::Or => (a | b) & MASK,
4649        PrimitiveOp::Le => (a <= b) as u64,
4650        PrimitiveOp::Lt => (a < b) as u64,
4651        PrimitiveOp::Ge => (a >= b) as u64,
4652        PrimitiveOp::Gt => (a > b) as u64,
4653        PrimitiveOp::Concat => 0,
4654        PrimitiveOp::Div => {
4655            if b == 0 {
4656                0
4657            } else {
4658                (a / b) & MASK
4659            }
4660        }
4661        PrimitiveOp::Mod => {
4662            if b == 0 {
4663                0
4664            } else {
4665                (a % b) & MASK
4666            }
4667        }
4668        PrimitiveOp::Pow => (const_pow_w48(a, b)) & MASK,
4669        _ => 0,
4670    }
4671}
4672
4673#[inline]
4674#[must_use]
4675pub const fn const_pow_w48(base: u64, exp: u64) -> u64 {
4676    const MASK: u64 = u64::MAX >> (64 - 48);
4677    let mut result: u64 = 1;
4678    let mut b: u64 = (base) & MASK;
4679    let mut e: u64 = exp;
4680    while e > 0 {
4681        if (e & 1) == 1 {
4682            result = (result.wrapping_mul(b)) & MASK;
4683        }
4684        b = (b.wrapping_mul(b)) & MASK;
4685        e >>= 1;
4686    }
4687    result
4688}
4689
4690#[inline]
4691#[must_use]
4692pub const fn const_ring_eval_unary_w48(op: PrimitiveOp, a: u64) -> u64 {
4693    const MASK: u64 = u64::MAX >> (64 - 48);
4694    match op {
4695        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4696        PrimitiveOp::Bnot => (!a) & MASK,
4697        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4698        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4699        _ => 0,
4700    }
4701}
4702
4703#[inline]
4704#[must_use]
4705#[allow(clippy::manual_checked_ops)]
4706pub const fn const_ring_eval_w56(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4707    const MASK: u64 = u64::MAX >> (64 - 56);
4708    match op {
4709        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4710        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4711        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4712        PrimitiveOp::Xor => (a ^ b) & MASK,
4713        PrimitiveOp::And => (a & b) & MASK,
4714        PrimitiveOp::Or => (a | b) & MASK,
4715        PrimitiveOp::Le => (a <= b) as u64,
4716        PrimitiveOp::Lt => (a < b) as u64,
4717        PrimitiveOp::Ge => (a >= b) as u64,
4718        PrimitiveOp::Gt => (a > b) as u64,
4719        PrimitiveOp::Concat => 0,
4720        PrimitiveOp::Div => {
4721            if b == 0 {
4722                0
4723            } else {
4724                (a / b) & MASK
4725            }
4726        }
4727        PrimitiveOp::Mod => {
4728            if b == 0 {
4729                0
4730            } else {
4731                (a % b) & MASK
4732            }
4733        }
4734        PrimitiveOp::Pow => (const_pow_w56(a, b)) & MASK,
4735        _ => 0,
4736    }
4737}
4738
4739#[inline]
4740#[must_use]
4741pub const fn const_pow_w56(base: u64, exp: u64) -> u64 {
4742    const MASK: u64 = u64::MAX >> (64 - 56);
4743    let mut result: u64 = 1;
4744    let mut b: u64 = (base) & MASK;
4745    let mut e: u64 = exp;
4746    while e > 0 {
4747        if (e & 1) == 1 {
4748            result = (result.wrapping_mul(b)) & MASK;
4749        }
4750        b = (b.wrapping_mul(b)) & MASK;
4751        e >>= 1;
4752    }
4753    result
4754}
4755
4756#[inline]
4757#[must_use]
4758pub const fn const_ring_eval_unary_w56(op: PrimitiveOp, a: u64) -> u64 {
4759    const MASK: u64 = u64::MAX >> (64 - 56);
4760    match op {
4761        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4762        PrimitiveOp::Bnot => (!a) & MASK,
4763        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4764        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4765        _ => 0,
4766    }
4767}
4768
4769#[inline]
4770#[must_use]
4771#[allow(clippy::manual_checked_ops)]
4772pub const fn const_ring_eval_w64(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4773    match op {
4774        PrimitiveOp::Add => a.wrapping_add(b),
4775        PrimitiveOp::Sub => a.wrapping_sub(b),
4776        PrimitiveOp::Mul => a.wrapping_mul(b),
4777        PrimitiveOp::Xor => a ^ b,
4778        PrimitiveOp::And => a & b,
4779        PrimitiveOp::Or => a | b,
4780        PrimitiveOp::Le => (a <= b) as u64,
4781        PrimitiveOp::Lt => (a < b) as u64,
4782        PrimitiveOp::Ge => (a >= b) as u64,
4783        PrimitiveOp::Gt => (a > b) as u64,
4784        PrimitiveOp::Concat => 0,
4785        PrimitiveOp::Div => {
4786            if b == 0 {
4787                0
4788            } else {
4789                a / b
4790            }
4791        }
4792        PrimitiveOp::Mod => {
4793            if b == 0 {
4794                0
4795            } else {
4796                a % b
4797            }
4798        }
4799        PrimitiveOp::Pow => const_pow_w64(a, b),
4800        _ => 0,
4801    }
4802}
4803
4804#[inline]
4805#[must_use]
4806pub const fn const_pow_w64(base: u64, exp: u64) -> u64 {
4807    let mut result: u64 = 1;
4808    let mut b: u64 = base;
4809    let mut e: u64 = exp;
4810    while e > 0 {
4811        if (e & 1) == 1 {
4812            result = result.wrapping_mul(b);
4813        }
4814        b = b.wrapping_mul(b);
4815        e >>= 1;
4816    }
4817    result
4818}
4819
4820#[inline]
4821#[must_use]
4822pub const fn const_ring_eval_unary_w64(op: PrimitiveOp, a: u64) -> u64 {
4823    match op {
4824        PrimitiveOp::Neg => 0u64.wrapping_sub(a),
4825        PrimitiveOp::Bnot => !a,
4826        PrimitiveOp::Succ => a.wrapping_add(1),
4827        PrimitiveOp::Pred => a.wrapping_sub(1),
4828        _ => 0,
4829    }
4830}
4831
4832#[inline]
4833#[must_use]
4834#[allow(clippy::manual_checked_ops)]
4835pub const fn const_ring_eval_w72(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4836    const MASK: u128 = u128::MAX >> (128 - 72);
4837    match op {
4838        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4839        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4840        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4841        PrimitiveOp::Xor => (a ^ b) & MASK,
4842        PrimitiveOp::And => (a & b) & MASK,
4843        PrimitiveOp::Or => (a | b) & MASK,
4844        PrimitiveOp::Le => (a <= b) as u128,
4845        PrimitiveOp::Lt => (a < b) as u128,
4846        PrimitiveOp::Ge => (a >= b) as u128,
4847        PrimitiveOp::Gt => (a > b) as u128,
4848        PrimitiveOp::Concat => 0,
4849        PrimitiveOp::Div => {
4850            if b == 0 {
4851                0
4852            } else {
4853                (a / b) & MASK
4854            }
4855        }
4856        PrimitiveOp::Mod => {
4857            if b == 0 {
4858                0
4859            } else {
4860                (a % b) & MASK
4861            }
4862        }
4863        PrimitiveOp::Pow => (const_pow_w72(a, b)) & MASK,
4864        _ => 0,
4865    }
4866}
4867
4868#[inline]
4869#[must_use]
4870pub const fn const_pow_w72(base: u128, exp: u128) -> u128 {
4871    const MASK: u128 = u128::MAX >> (128 - 72);
4872    let mut result: u128 = 1;
4873    let mut b: u128 = (base) & MASK;
4874    let mut e: u128 = exp;
4875    while e > 0 {
4876        if (e & 1) == 1 {
4877            result = (result.wrapping_mul(b)) & MASK;
4878        }
4879        b = (b.wrapping_mul(b)) & MASK;
4880        e >>= 1;
4881    }
4882    result
4883}
4884
4885#[inline]
4886#[must_use]
4887pub const fn const_ring_eval_unary_w72(op: PrimitiveOp, a: u128) -> u128 {
4888    const MASK: u128 = u128::MAX >> (128 - 72);
4889    match op {
4890        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4891        PrimitiveOp::Bnot => (!a) & MASK,
4892        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4893        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4894        _ => 0,
4895    }
4896}
4897
4898#[inline]
4899#[must_use]
4900#[allow(clippy::manual_checked_ops)]
4901pub const fn const_ring_eval_w80(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4902    const MASK: u128 = u128::MAX >> (128 - 80);
4903    match op {
4904        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4905        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4906        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4907        PrimitiveOp::Xor => (a ^ b) & MASK,
4908        PrimitiveOp::And => (a & b) & MASK,
4909        PrimitiveOp::Or => (a | b) & MASK,
4910        PrimitiveOp::Le => (a <= b) as u128,
4911        PrimitiveOp::Lt => (a < b) as u128,
4912        PrimitiveOp::Ge => (a >= b) as u128,
4913        PrimitiveOp::Gt => (a > b) as u128,
4914        PrimitiveOp::Concat => 0,
4915        PrimitiveOp::Div => {
4916            if b == 0 {
4917                0
4918            } else {
4919                (a / b) & MASK
4920            }
4921        }
4922        PrimitiveOp::Mod => {
4923            if b == 0 {
4924                0
4925            } else {
4926                (a % b) & MASK
4927            }
4928        }
4929        PrimitiveOp::Pow => (const_pow_w80(a, b)) & MASK,
4930        _ => 0,
4931    }
4932}
4933
4934#[inline]
4935#[must_use]
4936pub const fn const_pow_w80(base: u128, exp: u128) -> u128 {
4937    const MASK: u128 = u128::MAX >> (128 - 80);
4938    let mut result: u128 = 1;
4939    let mut b: u128 = (base) & MASK;
4940    let mut e: u128 = exp;
4941    while e > 0 {
4942        if (e & 1) == 1 {
4943            result = (result.wrapping_mul(b)) & MASK;
4944        }
4945        b = (b.wrapping_mul(b)) & MASK;
4946        e >>= 1;
4947    }
4948    result
4949}
4950
4951#[inline]
4952#[must_use]
4953pub const fn const_ring_eval_unary_w80(op: PrimitiveOp, a: u128) -> u128 {
4954    const MASK: u128 = u128::MAX >> (128 - 80);
4955    match op {
4956        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4957        PrimitiveOp::Bnot => (!a) & MASK,
4958        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4959        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4960        _ => 0,
4961    }
4962}
4963
4964#[inline]
4965#[must_use]
4966#[allow(clippy::manual_checked_ops)]
4967pub const fn const_ring_eval_w88(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4968    const MASK: u128 = u128::MAX >> (128 - 88);
4969    match op {
4970        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4971        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4972        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4973        PrimitiveOp::Xor => (a ^ b) & MASK,
4974        PrimitiveOp::And => (a & b) & MASK,
4975        PrimitiveOp::Or => (a | b) & MASK,
4976        PrimitiveOp::Le => (a <= b) as u128,
4977        PrimitiveOp::Lt => (a < b) as u128,
4978        PrimitiveOp::Ge => (a >= b) as u128,
4979        PrimitiveOp::Gt => (a > b) as u128,
4980        PrimitiveOp::Concat => 0,
4981        PrimitiveOp::Div => {
4982            if b == 0 {
4983                0
4984            } else {
4985                (a / b) & MASK
4986            }
4987        }
4988        PrimitiveOp::Mod => {
4989            if b == 0 {
4990                0
4991            } else {
4992                (a % b) & MASK
4993            }
4994        }
4995        PrimitiveOp::Pow => (const_pow_w88(a, b)) & MASK,
4996        _ => 0,
4997    }
4998}
4999
5000#[inline]
5001#[must_use]
5002pub const fn const_pow_w88(base: u128, exp: u128) -> u128 {
5003    const MASK: u128 = u128::MAX >> (128 - 88);
5004    let mut result: u128 = 1;
5005    let mut b: u128 = (base) & MASK;
5006    let mut e: u128 = exp;
5007    while e > 0 {
5008        if (e & 1) == 1 {
5009            result = (result.wrapping_mul(b)) & MASK;
5010        }
5011        b = (b.wrapping_mul(b)) & MASK;
5012        e >>= 1;
5013    }
5014    result
5015}
5016
5017#[inline]
5018#[must_use]
5019pub const fn const_ring_eval_unary_w88(op: PrimitiveOp, a: u128) -> u128 {
5020    const MASK: u128 = u128::MAX >> (128 - 88);
5021    match op {
5022        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5023        PrimitiveOp::Bnot => (!a) & MASK,
5024        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5025        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5026        _ => 0,
5027    }
5028}
5029
5030#[inline]
5031#[must_use]
5032#[allow(clippy::manual_checked_ops)]
5033pub const fn const_ring_eval_w96(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5034    const MASK: u128 = u128::MAX >> (128 - 96);
5035    match op {
5036        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5037        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5038        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5039        PrimitiveOp::Xor => (a ^ b) & MASK,
5040        PrimitiveOp::And => (a & b) & MASK,
5041        PrimitiveOp::Or => (a | b) & MASK,
5042        PrimitiveOp::Le => (a <= b) as u128,
5043        PrimitiveOp::Lt => (a < b) as u128,
5044        PrimitiveOp::Ge => (a >= b) as u128,
5045        PrimitiveOp::Gt => (a > b) as u128,
5046        PrimitiveOp::Concat => 0,
5047        PrimitiveOp::Div => {
5048            if b == 0 {
5049                0
5050            } else {
5051                (a / b) & MASK
5052            }
5053        }
5054        PrimitiveOp::Mod => {
5055            if b == 0 {
5056                0
5057            } else {
5058                (a % b) & MASK
5059            }
5060        }
5061        PrimitiveOp::Pow => (const_pow_w96(a, b)) & MASK,
5062        _ => 0,
5063    }
5064}
5065
5066#[inline]
5067#[must_use]
5068pub const fn const_pow_w96(base: u128, exp: u128) -> u128 {
5069    const MASK: u128 = u128::MAX >> (128 - 96);
5070    let mut result: u128 = 1;
5071    let mut b: u128 = (base) & MASK;
5072    let mut e: u128 = exp;
5073    while e > 0 {
5074        if (e & 1) == 1 {
5075            result = (result.wrapping_mul(b)) & MASK;
5076        }
5077        b = (b.wrapping_mul(b)) & MASK;
5078        e >>= 1;
5079    }
5080    result
5081}
5082
5083#[inline]
5084#[must_use]
5085pub const fn const_ring_eval_unary_w96(op: PrimitiveOp, a: u128) -> u128 {
5086    const MASK: u128 = u128::MAX >> (128 - 96);
5087    match op {
5088        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5089        PrimitiveOp::Bnot => (!a) & MASK,
5090        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5091        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5092        _ => 0,
5093    }
5094}
5095
5096#[inline]
5097#[must_use]
5098#[allow(clippy::manual_checked_ops)]
5099pub const fn const_ring_eval_w104(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5100    const MASK: u128 = u128::MAX >> (128 - 104);
5101    match op {
5102        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5103        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5104        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5105        PrimitiveOp::Xor => (a ^ b) & MASK,
5106        PrimitiveOp::And => (a & b) & MASK,
5107        PrimitiveOp::Or => (a | b) & MASK,
5108        PrimitiveOp::Le => (a <= b) as u128,
5109        PrimitiveOp::Lt => (a < b) as u128,
5110        PrimitiveOp::Ge => (a >= b) as u128,
5111        PrimitiveOp::Gt => (a > b) as u128,
5112        PrimitiveOp::Concat => 0,
5113        PrimitiveOp::Div => {
5114            if b == 0 {
5115                0
5116            } else {
5117                (a / b) & MASK
5118            }
5119        }
5120        PrimitiveOp::Mod => {
5121            if b == 0 {
5122                0
5123            } else {
5124                (a % b) & MASK
5125            }
5126        }
5127        PrimitiveOp::Pow => (const_pow_w104(a, b)) & MASK,
5128        _ => 0,
5129    }
5130}
5131
5132#[inline]
5133#[must_use]
5134pub const fn const_pow_w104(base: u128, exp: u128) -> u128 {
5135    const MASK: u128 = u128::MAX >> (128 - 104);
5136    let mut result: u128 = 1;
5137    let mut b: u128 = (base) & MASK;
5138    let mut e: u128 = exp;
5139    while e > 0 {
5140        if (e & 1) == 1 {
5141            result = (result.wrapping_mul(b)) & MASK;
5142        }
5143        b = (b.wrapping_mul(b)) & MASK;
5144        e >>= 1;
5145    }
5146    result
5147}
5148
5149#[inline]
5150#[must_use]
5151pub const fn const_ring_eval_unary_w104(op: PrimitiveOp, a: u128) -> u128 {
5152    const MASK: u128 = u128::MAX >> (128 - 104);
5153    match op {
5154        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5155        PrimitiveOp::Bnot => (!a) & MASK,
5156        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5157        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5158        _ => 0,
5159    }
5160}
5161
5162#[inline]
5163#[must_use]
5164#[allow(clippy::manual_checked_ops)]
5165pub const fn const_ring_eval_w112(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5166    const MASK: u128 = u128::MAX >> (128 - 112);
5167    match op {
5168        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5169        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5170        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5171        PrimitiveOp::Xor => (a ^ b) & MASK,
5172        PrimitiveOp::And => (a & b) & MASK,
5173        PrimitiveOp::Or => (a | b) & MASK,
5174        PrimitiveOp::Le => (a <= b) as u128,
5175        PrimitiveOp::Lt => (a < b) as u128,
5176        PrimitiveOp::Ge => (a >= b) as u128,
5177        PrimitiveOp::Gt => (a > b) as u128,
5178        PrimitiveOp::Concat => 0,
5179        PrimitiveOp::Div => {
5180            if b == 0 {
5181                0
5182            } else {
5183                (a / b) & MASK
5184            }
5185        }
5186        PrimitiveOp::Mod => {
5187            if b == 0 {
5188                0
5189            } else {
5190                (a % b) & MASK
5191            }
5192        }
5193        PrimitiveOp::Pow => (const_pow_w112(a, b)) & MASK,
5194        _ => 0,
5195    }
5196}
5197
5198#[inline]
5199#[must_use]
5200pub const fn const_pow_w112(base: u128, exp: u128) -> u128 {
5201    const MASK: u128 = u128::MAX >> (128 - 112);
5202    let mut result: u128 = 1;
5203    let mut b: u128 = (base) & MASK;
5204    let mut e: u128 = exp;
5205    while e > 0 {
5206        if (e & 1) == 1 {
5207            result = (result.wrapping_mul(b)) & MASK;
5208        }
5209        b = (b.wrapping_mul(b)) & MASK;
5210        e >>= 1;
5211    }
5212    result
5213}
5214
5215#[inline]
5216#[must_use]
5217pub const fn const_ring_eval_unary_w112(op: PrimitiveOp, a: u128) -> u128 {
5218    const MASK: u128 = u128::MAX >> (128 - 112);
5219    match op {
5220        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5221        PrimitiveOp::Bnot => (!a) & MASK,
5222        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5223        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5224        _ => 0,
5225    }
5226}
5227
5228#[inline]
5229#[must_use]
5230#[allow(clippy::manual_checked_ops)]
5231pub const fn const_ring_eval_w120(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5232    const MASK: u128 = u128::MAX >> (128 - 120);
5233    match op {
5234        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5235        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5236        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5237        PrimitiveOp::Xor => (a ^ b) & MASK,
5238        PrimitiveOp::And => (a & b) & MASK,
5239        PrimitiveOp::Or => (a | b) & MASK,
5240        PrimitiveOp::Le => (a <= b) as u128,
5241        PrimitiveOp::Lt => (a < b) as u128,
5242        PrimitiveOp::Ge => (a >= b) as u128,
5243        PrimitiveOp::Gt => (a > b) as u128,
5244        PrimitiveOp::Concat => 0,
5245        PrimitiveOp::Div => {
5246            if b == 0 {
5247                0
5248            } else {
5249                (a / b) & MASK
5250            }
5251        }
5252        PrimitiveOp::Mod => {
5253            if b == 0 {
5254                0
5255            } else {
5256                (a % b) & MASK
5257            }
5258        }
5259        PrimitiveOp::Pow => (const_pow_w120(a, b)) & MASK,
5260        _ => 0,
5261    }
5262}
5263
5264#[inline]
5265#[must_use]
5266pub const fn const_pow_w120(base: u128, exp: u128) -> u128 {
5267    const MASK: u128 = u128::MAX >> (128 - 120);
5268    let mut result: u128 = 1;
5269    let mut b: u128 = (base) & MASK;
5270    let mut e: u128 = exp;
5271    while e > 0 {
5272        if (e & 1) == 1 {
5273            result = (result.wrapping_mul(b)) & MASK;
5274        }
5275        b = (b.wrapping_mul(b)) & MASK;
5276        e >>= 1;
5277    }
5278    result
5279}
5280
5281#[inline]
5282#[must_use]
5283pub const fn const_ring_eval_unary_w120(op: PrimitiveOp, a: u128) -> u128 {
5284    const MASK: u128 = u128::MAX >> (128 - 120);
5285    match op {
5286        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5287        PrimitiveOp::Bnot => (!a) & MASK,
5288        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5289        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5290        _ => 0,
5291    }
5292}
5293
5294#[inline]
5295#[must_use]
5296#[allow(clippy::manual_checked_ops)]
5297pub const fn const_ring_eval_w128(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5298    match op {
5299        PrimitiveOp::Add => a.wrapping_add(b),
5300        PrimitiveOp::Sub => a.wrapping_sub(b),
5301        PrimitiveOp::Mul => a.wrapping_mul(b),
5302        PrimitiveOp::Xor => a ^ b,
5303        PrimitiveOp::And => a & b,
5304        PrimitiveOp::Or => a | b,
5305        PrimitiveOp::Le => (a <= b) as u128,
5306        PrimitiveOp::Lt => (a < b) as u128,
5307        PrimitiveOp::Ge => (a >= b) as u128,
5308        PrimitiveOp::Gt => (a > b) as u128,
5309        PrimitiveOp::Concat => 0,
5310        PrimitiveOp::Div => {
5311            if b == 0 {
5312                0
5313            } else {
5314                a / b
5315            }
5316        }
5317        PrimitiveOp::Mod => {
5318            if b == 0 {
5319                0
5320            } else {
5321                a % b
5322            }
5323        }
5324        PrimitiveOp::Pow => const_pow_w128(a, b),
5325        _ => 0,
5326    }
5327}
5328
5329#[inline]
5330#[must_use]
5331pub const fn const_pow_w128(base: u128, exp: u128) -> u128 {
5332    let mut result: u128 = 1;
5333    let mut b: u128 = base;
5334    let mut e: u128 = exp;
5335    while e > 0 {
5336        if (e & 1) == 1 {
5337            result = result.wrapping_mul(b);
5338        }
5339        b = b.wrapping_mul(b);
5340        e >>= 1;
5341    }
5342    result
5343}
5344
5345#[inline]
5346#[must_use]
5347pub const fn const_ring_eval_unary_w128(op: PrimitiveOp, a: u128) -> u128 {
5348    match op {
5349        PrimitiveOp::Neg => 0u128.wrapping_sub(a),
5350        PrimitiveOp::Bnot => !a,
5351        PrimitiveOp::Succ => a.wrapping_add(1),
5352        PrimitiveOp::Pred => a.wrapping_sub(1),
5353        _ => 0,
5354    }
5355}
5356
5357/// v0.2.2 Phase C.3: foundation-internal generic backing for Witt
5358/// levels above W128. Holds an inline `[u64; N]` array with no heap
5359/// allocation, no global state, and `const fn` arithmetic throughout.
5360/// Constructors are `pub(crate)`; downstream cannot fabricate a `Limbs<N>`.
5361/// Multiplication is schoolbook-only at v0.2.2 Phase C.3; the Toom-Cook
5362/// framework with parametric splitting factor `R` ships in Phase C.4 via
5363/// the `resolver::multiplication::certify` resolver, which decides `R`
5364/// per call from a Landauer cost function constrained by stack budget.
5365#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5366pub struct Limbs<const N: usize> {
5367    /// Little-endian limbs: `words[0]` is the low 64 bits.
5368    words: [u64; N],
5369    /// Prevents external construction.
5370    _sealed: (),
5371}
5372
5373impl<const N: usize> Limbs<N> {
5374    /// Crate-internal constructor from a fixed-size limb array.
5375    #[inline]
5376    #[must_use]
5377    #[allow(dead_code)]
5378    pub(crate) const fn from_words(words: [u64; N]) -> Self {
5379        Self { words, _sealed: () }
5380    }
5381
5382    /// All-zeros constructor.
5383    #[inline]
5384    #[must_use]
5385    #[allow(dead_code)]
5386    pub(crate) const fn zero() -> Self {
5387        Self {
5388            words: [0u64; N],
5389            _sealed: (),
5390        }
5391    }
5392
5393    /// Returns a reference to the underlying limb array.
5394    #[inline]
5395    #[must_use]
5396    pub const fn words(&self) -> &[u64; N] {
5397        &self.words
5398    }
5399
5400    /// Wrapping addition mod 2^(64*N). Const-fn schoolbook with carry.
5401    #[inline]
5402    #[must_use]
5403    #[allow(dead_code)]
5404    pub(crate) const fn wrapping_add(self, other: Self) -> Self {
5405        let mut out = [0u64; N];
5406        let mut carry: u64 = 0;
5407        let mut i = 0;
5408        while i < N {
5409            let (s1, c1) = self.words[i].overflowing_add(other.words[i]);
5410            let (s2, c2) = s1.overflowing_add(carry);
5411            out[i] = s2;
5412            carry = (c1 as u64) | (c2 as u64);
5413            i += 1;
5414        }
5415        Self {
5416            words: out,
5417            _sealed: (),
5418        }
5419    }
5420
5421    /// Wrapping subtraction mod 2^(64*N). Const-fn schoolbook with borrow.
5422    #[inline]
5423    #[must_use]
5424    #[allow(dead_code)]
5425    pub(crate) const fn wrapping_sub(self, other: Self) -> Self {
5426        let mut out = [0u64; N];
5427        let mut borrow: u64 = 0;
5428        let mut i = 0;
5429        while i < N {
5430            let (d1, b1) = self.words[i].overflowing_sub(other.words[i]);
5431            let (d2, b2) = d1.overflowing_sub(borrow);
5432            out[i] = d2;
5433            borrow = (b1 as u64) | (b2 as u64);
5434            i += 1;
5435        }
5436        Self {
5437            words: out,
5438            _sealed: (),
5439        }
5440    }
5441
5442    /// Wrapping schoolbook multiplication mod 2^(64*N). The high N limbs of
5443    /// the 2N-limb full product are discarded (mod 2^bits truncation).
5444    /// v0.2.2 Phase C.3: schoolbook only. Phase C.4 adds the Toom-Cook
5445    /// framework with parametric R via `resolver::multiplication::certify`.
5446    #[inline]
5447    #[must_use]
5448    #[allow(dead_code)]
5449    pub(crate) const fn wrapping_mul(self, other: Self) -> Self {
5450        let mut out = [0u64; N];
5451        let mut i = 0;
5452        while i < N {
5453            let mut carry: u128 = 0;
5454            let mut j = 0;
5455            while j < N - i {
5456                let prod = (self.words[i] as u128) * (other.words[j] as u128)
5457                    + (out[i + j] as u128)
5458                    + carry;
5459                out[i + j] = prod as u64;
5460                carry = prod >> 64;
5461                j += 1;
5462            }
5463            i += 1;
5464        }
5465        Self {
5466            words: out,
5467            _sealed: (),
5468        }
5469    }
5470
5471    /// Bitwise XOR.
5472    #[inline]
5473    #[must_use]
5474    #[allow(dead_code)]
5475    pub(crate) const fn xor(self, other: Self) -> Self {
5476        let mut out = [0u64; N];
5477        let mut i = 0;
5478        while i < N {
5479            out[i] = self.words[i] ^ other.words[i];
5480            i += 1;
5481        }
5482        Self {
5483            words: out,
5484            _sealed: (),
5485        }
5486    }
5487
5488    /// Bitwise AND.
5489    #[inline]
5490    #[must_use]
5491    #[allow(dead_code)]
5492    pub(crate) const fn and(self, other: Self) -> Self {
5493        let mut out = [0u64; N];
5494        let mut i = 0;
5495        while i < N {
5496            out[i] = self.words[i] & other.words[i];
5497            i += 1;
5498        }
5499        Self {
5500            words: out,
5501            _sealed: (),
5502        }
5503    }
5504
5505    /// Bitwise OR.
5506    #[inline]
5507    #[must_use]
5508    #[allow(dead_code)]
5509    pub(crate) const fn or(self, other: Self) -> Self {
5510        let mut out = [0u64; N];
5511        let mut i = 0;
5512        while i < N {
5513            out[i] = self.words[i] | other.words[i];
5514            i += 1;
5515        }
5516        Self {
5517            words: out,
5518            _sealed: (),
5519        }
5520    }
5521
5522    /// Bitwise NOT.
5523    #[inline]
5524    #[must_use]
5525    #[allow(dead_code)]
5526    pub(crate) const fn not(self) -> Self {
5527        let mut out = [0u64; N];
5528        let mut i = 0;
5529        while i < N {
5530            out[i] = !self.words[i];
5531            i += 1;
5532        }
5533        Self {
5534            words: out,
5535            _sealed: (),
5536        }
5537    }
5538
5539    /// Mask the high bits of the value to keep only the low `bits` bits.
5540    /// Used at the arithmetic boundary for non-exact-fit Witt widths (e.g.,
5541    /// W160 over `Limbs<3>`: 64+64+32 bits = mask the upper 32 bits of words[2]).
5542    #[inline]
5543    #[must_use]
5544    #[allow(dead_code)]
5545    pub(crate) const fn mask_high_bits(self, bits: u32) -> Self {
5546        let mut out = self.words;
5547        let high_word_idx = (bits / 64) as usize;
5548        let low_bits_in_high_word = bits % 64;
5549        if low_bits_in_high_word != 0 && high_word_idx < N {
5550            let mask = (1u64 << low_bits_in_high_word) - 1;
5551            out[high_word_idx] &= mask;
5552            // Zero everything above the high word.
5553            let mut i = high_word_idx + 1;
5554            while i < N {
5555                out[i] = 0;
5556                i += 1;
5557            }
5558        } else if low_bits_in_high_word == 0 && high_word_idx < N {
5559            // bits is exactly a multiple of 64; zero everything from high_word_idx.
5560            let mut i = high_word_idx;
5561            while i < N {
5562                out[i] = 0;
5563                i += 1;
5564            }
5565        }
5566        Self {
5567            words: out,
5568            _sealed: (),
5569        }
5570    }
5571}
5572
5573/// Sealed marker trait identifying types produced by the foundation crate's
5574/// conformance/reduction pipeline. v0.2.1 bounds `Validated<T>` on this trait
5575/// so downstream crates cannot fabricate `Validated<UserType>` — user types
5576/// cannot impl `OntologyTarget` because the supertrait is private.
5577pub trait OntologyTarget: ontology_target_sealed::Sealed {}
5578
5579/// Sealed shim for `cert:GroundingCertificate`. Produced by GroundingAwareResolver.
5580#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5581pub struct GroundingCertificate {
5582    witt_bits: u16,
5583    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5584    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5585    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5586    /// are never equal even when leading bytes coincide.
5587    content_fingerprint: ContentFingerprint,
5588}
5589
5590impl GroundingCertificate {
5591    /// Returns the Witt level the certificate was issued for. Sourced
5592    /// from the pipeline's substrate hash output at minting time.
5593    #[inline]
5594    #[must_use]
5595    pub const fn witt_bits(&self) -> u16 {
5596        self.witt_bits
5597    }
5598
5599    /// v0.2.2 T5: returns the parametric content fingerprint of the
5600    /// source state, computed at mint time by the consumer-supplied
5601    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5602    /// certificates from different hashers are never equal because
5603    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5604    #[inline]
5605    #[must_use]
5606    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5607        self.content_fingerprint
5608    }
5609
5610    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5611    /// witt-bits value AND the parametric content fingerprint. Used by
5612    /// `pipeline::run` and `certify_*_const` to mint a certificate
5613    /// carrying the substrate-computed fingerprint of the source state.
5614    #[inline]
5615    #[must_use]
5616    #[allow(dead_code)]
5617    pub(crate) const fn with_level_and_fingerprint_const(
5618        witt_bits: u16,
5619        content_fingerprint: ContentFingerprint,
5620    ) -> Self {
5621        Self {
5622            witt_bits,
5623            content_fingerprint,
5624        }
5625    }
5626}
5627
5628/// Sealed shim for `cert:LiftChainCertificate`. Carries the v0.2.1 `target_level()` accessor populated from the pipeline's StageOutcome.
5629#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5630pub struct LiftChainCertificate {
5631    witt_bits: u16,
5632    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5633    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5634    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5635    /// are never equal even when leading bytes coincide.
5636    content_fingerprint: ContentFingerprint,
5637}
5638
5639impl LiftChainCertificate {
5640    /// Returns the Witt level the certificate was issued for. Sourced
5641    /// from the pipeline's substrate hash output at minting time.
5642    #[inline]
5643    #[must_use]
5644    pub const fn witt_bits(&self) -> u16 {
5645        self.witt_bits
5646    }
5647
5648    /// v0.2.2 T5: returns the parametric content fingerprint of the
5649    /// source state, computed at mint time by the consumer-supplied
5650    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5651    /// certificates from different hashers are never equal because
5652    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5653    #[inline]
5654    #[must_use]
5655    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5656        self.content_fingerprint
5657    }
5658
5659    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5660    /// witt-bits value AND the parametric content fingerprint. Used by
5661    /// `pipeline::run` and `certify_*_const` to mint a certificate
5662    /// carrying the substrate-computed fingerprint of the source state.
5663    #[inline]
5664    #[must_use]
5665    #[allow(dead_code)]
5666    pub(crate) const fn with_level_and_fingerprint_const(
5667        witt_bits: u16,
5668        content_fingerprint: ContentFingerprint,
5669    ) -> Self {
5670        Self {
5671            witt_bits,
5672            content_fingerprint,
5673        }
5674    }
5675}
5676
5677/// Sealed shim for `cert:InhabitanceCertificate` (v0.2.1).
5678#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5679pub struct InhabitanceCertificate {
5680    witt_bits: u16,
5681    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5682    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5683    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5684    /// are never equal even when leading bytes coincide.
5685    content_fingerprint: ContentFingerprint,
5686}
5687
5688impl InhabitanceCertificate {
5689    /// Returns the Witt level the certificate was issued for. Sourced
5690    /// from the pipeline's substrate hash output at minting time.
5691    #[inline]
5692    #[must_use]
5693    pub const fn witt_bits(&self) -> u16 {
5694        self.witt_bits
5695    }
5696
5697    /// v0.2.2 T5: returns the parametric content fingerprint of the
5698    /// source state, computed at mint time by the consumer-supplied
5699    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5700    /// certificates from different hashers are never equal because
5701    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5702    #[inline]
5703    #[must_use]
5704    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5705        self.content_fingerprint
5706    }
5707
5708    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5709    /// witt-bits value AND the parametric content fingerprint. Used by
5710    /// `pipeline::run` and `certify_*_const` to mint a certificate
5711    /// carrying the substrate-computed fingerprint of the source state.
5712    #[inline]
5713    #[must_use]
5714    #[allow(dead_code)]
5715    pub(crate) const fn with_level_and_fingerprint_const(
5716        witt_bits: u16,
5717        content_fingerprint: ContentFingerprint,
5718    ) -> Self {
5719        Self {
5720            witt_bits,
5721            content_fingerprint,
5722        }
5723    }
5724}
5725
5726/// Sealed shim for `cert:CompletenessCertificate`.
5727#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5728pub struct CompletenessCertificate {
5729    witt_bits: u16,
5730    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5731    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5732    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5733    /// are never equal even when leading bytes coincide.
5734    content_fingerprint: ContentFingerprint,
5735}
5736
5737impl CompletenessCertificate {
5738    /// Returns the Witt level the certificate was issued for. Sourced
5739    /// from the pipeline's substrate hash output at minting time.
5740    #[inline]
5741    #[must_use]
5742    pub const fn witt_bits(&self) -> u16 {
5743        self.witt_bits
5744    }
5745
5746    /// v0.2.2 T5: returns the parametric content fingerprint of the
5747    /// source state, computed at mint time by the consumer-supplied
5748    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5749    /// certificates from different hashers are never equal because
5750    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5751    #[inline]
5752    #[must_use]
5753    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5754        self.content_fingerprint
5755    }
5756
5757    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5758    /// witt-bits value AND the parametric content fingerprint. Used by
5759    /// `pipeline::run` and `certify_*_const` to mint a certificate
5760    /// carrying the substrate-computed fingerprint of the source state.
5761    #[inline]
5762    #[must_use]
5763    #[allow(dead_code)]
5764    pub(crate) const fn with_level_and_fingerprint_const(
5765        witt_bits: u16,
5766        content_fingerprint: ContentFingerprint,
5767    ) -> Self {
5768        Self {
5769            witt_bits,
5770            content_fingerprint,
5771        }
5772    }
5773}
5774
5775/// Sealed shim for `cert:MultiplicationCertificate` (v0.2.2 Phase C.4). Carries the cost-optimal Toom-Cook splitting factor R, the recursive sub-multiplication count, and the accumulated Landauer cost in nats.
5776#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5777pub struct MultiplicationCertificate {
5778    witt_bits: u16,
5779    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5780    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5781    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5782    /// are never equal even when leading bytes coincide.
5783    content_fingerprint: ContentFingerprint,
5784}
5785
5786impl MultiplicationCertificate {
5787    /// Returns the Witt level the certificate was issued for. Sourced
5788    /// from the pipeline's substrate hash output at minting time.
5789    #[inline]
5790    #[must_use]
5791    pub const fn witt_bits(&self) -> u16 {
5792        self.witt_bits
5793    }
5794
5795    /// v0.2.2 T5: returns the parametric content fingerprint of the
5796    /// source state, computed at mint time by the consumer-supplied
5797    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5798    /// certificates from different hashers are never equal because
5799    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5800    #[inline]
5801    #[must_use]
5802    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5803        self.content_fingerprint
5804    }
5805
5806    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5807    /// witt-bits value AND the parametric content fingerprint. Used by
5808    /// `pipeline::run` and `certify_*_const` to mint a certificate
5809    /// carrying the substrate-computed fingerprint of the source state.
5810    #[inline]
5811    #[must_use]
5812    #[allow(dead_code)]
5813    pub(crate) const fn with_level_and_fingerprint_const(
5814        witt_bits: u16,
5815        content_fingerprint: ContentFingerprint,
5816    ) -> Self {
5817        Self {
5818            witt_bits,
5819            content_fingerprint,
5820        }
5821    }
5822}
5823
5824/// Sealed shim for `cert:PartitionCertificate` (v0.2.2 Phase E). Attests the partition component classification of a Datum.
5825#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5826pub struct PartitionCertificate {
5827    witt_bits: u16,
5828    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5829    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5830    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5831    /// are never equal even when leading bytes coincide.
5832    content_fingerprint: ContentFingerprint,
5833}
5834
5835impl PartitionCertificate {
5836    /// Returns the Witt level the certificate was issued for. Sourced
5837    /// from the pipeline's substrate hash output at minting time.
5838    #[inline]
5839    #[must_use]
5840    pub const fn witt_bits(&self) -> u16 {
5841        self.witt_bits
5842    }
5843
5844    /// v0.2.2 T5: returns the parametric content fingerprint of the
5845    /// source state, computed at mint time by the consumer-supplied
5846    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5847    /// certificates from different hashers are never equal because
5848    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5849    #[inline]
5850    #[must_use]
5851    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5852        self.content_fingerprint
5853    }
5854
5855    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5856    /// witt-bits value AND the parametric content fingerprint. Used by
5857    /// `pipeline::run` and `certify_*_const` to mint a certificate
5858    /// carrying the substrate-computed fingerprint of the source state.
5859    #[inline]
5860    #[must_use]
5861    #[allow(dead_code)]
5862    pub(crate) const fn with_level_and_fingerprint_const(
5863        witt_bits: u16,
5864        content_fingerprint: ContentFingerprint,
5865    ) -> Self {
5866        Self {
5867            witt_bits,
5868            content_fingerprint,
5869        }
5870    }
5871}
5872
5873/// Sealed shim for `proof:ImpossibilityWitness`. Returned by completeness and grounding resolvers on failure.
5874#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5875pub struct GenericImpossibilityWitness {
5876    /// Optional theorem / invariant IRI identifying the failed identity.
5877    /// `None` for legacy call sites minting via `Default::default()`;
5878    /// `Some(iri)` when the witness is constructed via `for_identity`
5879    /// (Product/Coproduct Completion Amendment §2.3a).
5880    identity: Option<&'static str>,
5881}
5882
5883impl Default for GenericImpossibilityWitness {
5884    #[inline]
5885    fn default() -> Self {
5886        Self { identity: None }
5887    }
5888}
5889
5890impl GenericImpossibilityWitness {
5891    /// Construct a witness citing a specific theorem / invariant IRI.
5892    /// Introduced by the Product/Coproduct Completion Amendment §2.3a
5893    /// so mint primitives can emit typed failures against `op/*` theorems
5894    /// and `foundation/*` layout invariants.
5895    #[inline]
5896    #[must_use]
5897    pub const fn for_identity(identity: &'static str) -> Self {
5898        Self {
5899            identity: Some(identity),
5900        }
5901    }
5902
5903    /// Returns the theorem / invariant IRI this witness cites, if any.
5904    #[inline]
5905    #[must_use]
5906    pub const fn identity(&self) -> Option<&'static str> {
5907        self.identity
5908    }
5909}
5910
5911/// Sealed shim for `proof:InhabitanceImpossibilityWitness` (v0.2.1).
5912#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5913pub struct InhabitanceImpossibilityWitness {
5914    _private: (),
5915}
5916
5917/// Input shim for `type:ConstrainedType`. Used as `Certify::Input` for InhabitanceResolver, TowerCompletenessResolver, and IncrementalCompletenessResolver.
5918#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5919pub struct ConstrainedTypeInput {
5920    _private: (),
5921}
5922
5923impl core::fmt::Display for GenericImpossibilityWitness {
5924    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5925        match self.identity {
5926            Some(iri) => write!(f, "GenericImpossibilityWitness({iri})"),
5927            None => f.write_str("GenericImpossibilityWitness"),
5928        }
5929    }
5930}
5931impl core::error::Error for GenericImpossibilityWitness {}
5932
5933impl core::fmt::Display for InhabitanceImpossibilityWitness {
5934    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5935        f.write_str("InhabitanceImpossibilityWitness")
5936    }
5937}
5938impl core::error::Error for InhabitanceImpossibilityWitness {}
5939
5940impl LiftChainCertificate {
5941    /// Returns the Witt level the certificate was issued for.
5942    #[inline]
5943    #[must_use]
5944    pub const fn target_level(&self) -> WittLevel {
5945        WittLevel::new(self.witt_bits as u32)
5946    }
5947}
5948
5949impl InhabitanceCertificate {
5950    /// Returns the witness value tuple bytes when `verified` is true.
5951    /// The sealed shim returns `None`; real witnesses flow through the
5952    /// macro back-door path.
5953    #[inline]
5954    #[must_use]
5955    pub const fn witness(&self) -> Option<&'static [u8]> {
5956        None
5957    }
5958}
5959
5960pub(crate) mod ontology_target_sealed {
5961    /// Private supertrait. Not implementable outside this crate.
5962    pub trait Sealed {}
5963    impl Sealed for super::GroundingCertificate {}
5964    impl Sealed for super::LiftChainCertificate {}
5965    impl Sealed for super::InhabitanceCertificate {}
5966    impl Sealed for super::CompletenessCertificate {}
5967    impl Sealed for super::MultiplicationCertificate {}
5968    impl Sealed for super::PartitionCertificate {}
5969    impl Sealed for super::GenericImpossibilityWitness {}
5970    impl Sealed for super::InhabitanceImpossibilityWitness {}
5971    impl Sealed for super::ConstrainedTypeInput {}
5972    impl Sealed for super::PartitionProductWitness {}
5973    impl Sealed for super::PartitionCoproductWitness {}
5974    impl Sealed for super::CartesianProductWitness {}
5975    impl Sealed for super::CompileUnit<'_> {}
5976}
5977
5978impl OntologyTarget for GroundingCertificate {}
5979impl OntologyTarget for LiftChainCertificate {}
5980impl OntologyTarget for InhabitanceCertificate {}
5981impl OntologyTarget for CompletenessCertificate {}
5982impl OntologyTarget for MultiplicationCertificate {}
5983impl OntologyTarget for PartitionCertificate {}
5984impl OntologyTarget for GenericImpossibilityWitness {}
5985impl OntologyTarget for InhabitanceImpossibilityWitness {}
5986impl OntologyTarget for ConstrainedTypeInput {}
5987impl OntologyTarget for PartitionProductWitness {}
5988impl OntologyTarget for PartitionCoproductWitness {}
5989impl OntologyTarget for CartesianProductWitness {}
5990impl OntologyTarget for CompileUnit<'_> {}
5991
5992/// v0.2.2 W11: supporting evidence type for `CompletenessCertificate`.
5993/// Linked from the certificate via the `Certificate::Evidence` associated type.
5994#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5995pub struct CompletenessAuditTrail {
5996    _private: (),
5997}
5998
5999/// v0.2.2 W11: supporting evidence type for `LiftChainCertificate`.
6000#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6001pub struct ChainAuditTrail {
6002    _private: (),
6003}
6004
6005/// v0.2.2 W11: supporting evidence type for `GeodesicCertificate`.
6006#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6007pub struct GeodesicEvidenceBundle {
6008    _private: (),
6009}
6010
6011/// v0.2.2 W11: sealed carrier for `cert:TransformCertificate`.
6012/// Phase X.1: minted with a Witt level and content fingerprint so the
6013/// resolver whose `resolver:CertifyMapping` produces this class can fold
6014/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6015/// constructor matches every other `cert:Certificate` subclass.
6016#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6017pub struct TransformCertificate {
6018    witt_bits: u16,
6019    content_fingerprint: ContentFingerprint,
6020    _private: (),
6021}
6022
6023impl TransformCertificate {
6024    /// Phase X.1: content-addressed constructor. Mints a certificate
6025    /// carrying the Witt level and substrate-hasher fingerprint of the
6026    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6027    #[inline]
6028    #[must_use]
6029    #[allow(dead_code)]
6030    pub(crate) const fn with_level_and_fingerprint_const(
6031        witt_bits: u16,
6032        content_fingerprint: ContentFingerprint,
6033    ) -> Self {
6034        Self {
6035            witt_bits,
6036            content_fingerprint,
6037            _private: (),
6038        }
6039    }
6040
6041    /// Phase X.1: legacy zero-fingerprint constructor retained for
6042    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6043    #[inline]
6044    #[must_use]
6045    #[allow(dead_code)]
6046    pub(crate) const fn empty_const() -> Self {
6047        Self {
6048            witt_bits: 0,
6049            content_fingerprint: ContentFingerprint::zero(),
6050            _private: (),
6051        }
6052    }
6053
6054    /// Phase X.1: the Witt level at which this certificate was minted.
6055    #[inline]
6056    #[must_use]
6057    pub const fn witt_bits(&self) -> u16 {
6058        self.witt_bits
6059    }
6060
6061    /// Phase X.1: the content fingerprint of the resolver decision.
6062    #[inline]
6063    #[must_use]
6064    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6065        self.content_fingerprint
6066    }
6067}
6068
6069/// v0.2.2 W11: sealed carrier for `cert:IsometryCertificate`.
6070/// Phase X.1: minted with a Witt level and content fingerprint so the
6071/// resolver whose `resolver:CertifyMapping` produces this class can fold
6072/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6073/// constructor matches every other `cert:Certificate` subclass.
6074#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6075pub struct IsometryCertificate {
6076    witt_bits: u16,
6077    content_fingerprint: ContentFingerprint,
6078    _private: (),
6079}
6080
6081impl IsometryCertificate {
6082    /// Phase X.1: content-addressed constructor. Mints a certificate
6083    /// carrying the Witt level and substrate-hasher fingerprint of the
6084    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6085    #[inline]
6086    #[must_use]
6087    #[allow(dead_code)]
6088    pub(crate) const fn with_level_and_fingerprint_const(
6089        witt_bits: u16,
6090        content_fingerprint: ContentFingerprint,
6091    ) -> Self {
6092        Self {
6093            witt_bits,
6094            content_fingerprint,
6095            _private: (),
6096        }
6097    }
6098
6099    /// Phase X.1: legacy zero-fingerprint constructor retained for
6100    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6101    #[inline]
6102    #[must_use]
6103    #[allow(dead_code)]
6104    pub(crate) const fn empty_const() -> Self {
6105        Self {
6106            witt_bits: 0,
6107            content_fingerprint: ContentFingerprint::zero(),
6108            _private: (),
6109        }
6110    }
6111
6112    /// Phase X.1: the Witt level at which this certificate was minted.
6113    #[inline]
6114    #[must_use]
6115    pub const fn witt_bits(&self) -> u16 {
6116        self.witt_bits
6117    }
6118
6119    /// Phase X.1: the content fingerprint of the resolver decision.
6120    #[inline]
6121    #[must_use]
6122    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6123        self.content_fingerprint
6124    }
6125}
6126
6127/// v0.2.2 W11: sealed carrier for `cert:InvolutionCertificate`.
6128/// Phase X.1: minted with a Witt level and content fingerprint so the
6129/// resolver whose `resolver:CertifyMapping` produces this class can fold
6130/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6131/// constructor matches every other `cert:Certificate` subclass.
6132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6133pub struct InvolutionCertificate {
6134    witt_bits: u16,
6135    content_fingerprint: ContentFingerprint,
6136    _private: (),
6137}
6138
6139impl InvolutionCertificate {
6140    /// Phase X.1: content-addressed constructor. Mints a certificate
6141    /// carrying the Witt level and substrate-hasher fingerprint of the
6142    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6143    #[inline]
6144    #[must_use]
6145    #[allow(dead_code)]
6146    pub(crate) const fn with_level_and_fingerprint_const(
6147        witt_bits: u16,
6148        content_fingerprint: ContentFingerprint,
6149    ) -> Self {
6150        Self {
6151            witt_bits,
6152            content_fingerprint,
6153            _private: (),
6154        }
6155    }
6156
6157    /// Phase X.1: legacy zero-fingerprint constructor retained for
6158    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6159    #[inline]
6160    #[must_use]
6161    #[allow(dead_code)]
6162    pub(crate) const fn empty_const() -> Self {
6163        Self {
6164            witt_bits: 0,
6165            content_fingerprint: ContentFingerprint::zero(),
6166            _private: (),
6167        }
6168    }
6169
6170    /// Phase X.1: the Witt level at which this certificate was minted.
6171    #[inline]
6172    #[must_use]
6173    pub const fn witt_bits(&self) -> u16 {
6174        self.witt_bits
6175    }
6176
6177    /// Phase X.1: the content fingerprint of the resolver decision.
6178    #[inline]
6179    #[must_use]
6180    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6181        self.content_fingerprint
6182    }
6183}
6184
6185/// v0.2.2 W11: sealed carrier for `cert:GeodesicCertificate`.
6186/// Phase X.1: minted with a Witt level and content fingerprint so the
6187/// resolver whose `resolver:CertifyMapping` produces this class can fold
6188/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6189/// constructor matches every other `cert:Certificate` subclass.
6190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6191pub struct GeodesicCertificate {
6192    witt_bits: u16,
6193    content_fingerprint: ContentFingerprint,
6194    _private: (),
6195}
6196
6197impl GeodesicCertificate {
6198    /// Phase X.1: content-addressed constructor. Mints a certificate
6199    /// carrying the Witt level and substrate-hasher fingerprint of the
6200    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6201    #[inline]
6202    #[must_use]
6203    #[allow(dead_code)]
6204    pub(crate) const fn with_level_and_fingerprint_const(
6205        witt_bits: u16,
6206        content_fingerprint: ContentFingerprint,
6207    ) -> Self {
6208        Self {
6209            witt_bits,
6210            content_fingerprint,
6211            _private: (),
6212        }
6213    }
6214
6215    /// Phase X.1: legacy zero-fingerprint constructor retained for
6216    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6217    #[inline]
6218    #[must_use]
6219    #[allow(dead_code)]
6220    pub(crate) const fn empty_const() -> Self {
6221        Self {
6222            witt_bits: 0,
6223            content_fingerprint: ContentFingerprint::zero(),
6224            _private: (),
6225        }
6226    }
6227
6228    /// Phase X.1: the Witt level at which this certificate was minted.
6229    #[inline]
6230    #[must_use]
6231    pub const fn witt_bits(&self) -> u16 {
6232        self.witt_bits
6233    }
6234
6235    /// Phase X.1: the content fingerprint of the resolver decision.
6236    #[inline]
6237    #[must_use]
6238    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6239        self.content_fingerprint
6240    }
6241}
6242
6243/// v0.2.2 W11: sealed carrier for `cert:MeasurementCertificate`.
6244/// Phase X.1: minted with a Witt level and content fingerprint so the
6245/// resolver whose `resolver:CertifyMapping` produces this class can fold
6246/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6247/// constructor matches every other `cert:Certificate` subclass.
6248#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6249pub struct MeasurementCertificate {
6250    witt_bits: u16,
6251    content_fingerprint: ContentFingerprint,
6252    _private: (),
6253}
6254
6255impl MeasurementCertificate {
6256    /// Phase X.1: content-addressed constructor. Mints a certificate
6257    /// carrying the Witt level and substrate-hasher fingerprint of the
6258    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6259    #[inline]
6260    #[must_use]
6261    #[allow(dead_code)]
6262    pub(crate) const fn with_level_and_fingerprint_const(
6263        witt_bits: u16,
6264        content_fingerprint: ContentFingerprint,
6265    ) -> Self {
6266        Self {
6267            witt_bits,
6268            content_fingerprint,
6269            _private: (),
6270        }
6271    }
6272
6273    /// Phase X.1: legacy zero-fingerprint constructor retained for
6274    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6275    #[inline]
6276    #[must_use]
6277    #[allow(dead_code)]
6278    pub(crate) const fn empty_const() -> Self {
6279        Self {
6280            witt_bits: 0,
6281            content_fingerprint: ContentFingerprint::zero(),
6282            _private: (),
6283        }
6284    }
6285
6286    /// Phase X.1: the Witt level at which this certificate was minted.
6287    #[inline]
6288    #[must_use]
6289    pub const fn witt_bits(&self) -> u16 {
6290        self.witt_bits
6291    }
6292
6293    /// Phase X.1: the content fingerprint of the resolver decision.
6294    #[inline]
6295    #[must_use]
6296    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6297        self.content_fingerprint
6298    }
6299}
6300
6301/// v0.2.2 W11: sealed carrier for `cert:BornRuleVerification`.
6302/// Phase X.1: minted with a Witt level and content fingerprint so the
6303/// resolver whose `resolver:CertifyMapping` produces this class can fold
6304/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6305/// constructor matches every other `cert:Certificate` subclass.
6306#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6307pub struct BornRuleVerification {
6308    witt_bits: u16,
6309    content_fingerprint: ContentFingerprint,
6310    _private: (),
6311}
6312
6313impl BornRuleVerification {
6314    /// Phase X.1: content-addressed constructor. Mints a certificate
6315    /// carrying the Witt level and substrate-hasher fingerprint of the
6316    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6317    #[inline]
6318    #[must_use]
6319    #[allow(dead_code)]
6320    pub(crate) const fn with_level_and_fingerprint_const(
6321        witt_bits: u16,
6322        content_fingerprint: ContentFingerprint,
6323    ) -> Self {
6324        Self {
6325            witt_bits,
6326            content_fingerprint,
6327            _private: (),
6328        }
6329    }
6330
6331    /// Phase X.1: legacy zero-fingerprint constructor retained for
6332    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6333    #[inline]
6334    #[must_use]
6335    #[allow(dead_code)]
6336    pub(crate) const fn empty_const() -> Self {
6337        Self {
6338            witt_bits: 0,
6339            content_fingerprint: ContentFingerprint::zero(),
6340            _private: (),
6341        }
6342    }
6343
6344    /// Phase X.1: the Witt level at which this certificate was minted.
6345    #[inline]
6346    #[must_use]
6347    pub const fn witt_bits(&self) -> u16 {
6348        self.witt_bits
6349    }
6350
6351    /// Phase X.1: the content fingerprint of the resolver decision.
6352    #[inline]
6353    #[must_use]
6354    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6355        self.content_fingerprint
6356    }
6357}
6358
6359/// v0.2.2 W11: sealed marker trait for foundation-supplied certificate kinds.
6360/// Implemented by every `cert:Certificate` subclass via codegen; not
6361/// implementable outside this crate.
6362pub trait Certificate: certificate_sealed::Sealed {
6363    /// The ontology IRI of this certificate class.
6364    const IRI: &'static str;
6365    /// The structured evidence carried by this certificate (or `()` if none).
6366    type Evidence;
6367}
6368
6369pub(crate) mod certificate_sealed {
6370    /// Private supertrait. Not implementable outside this crate.
6371    pub trait Sealed {}
6372    impl Sealed for super::GroundingCertificate {}
6373    impl Sealed for super::LiftChainCertificate {}
6374    impl Sealed for super::InhabitanceCertificate {}
6375    impl Sealed for super::CompletenessCertificate {}
6376    impl Sealed for super::TransformCertificate {}
6377    impl Sealed for super::IsometryCertificate {}
6378    impl Sealed for super::InvolutionCertificate {}
6379    impl Sealed for super::GeodesicCertificate {}
6380    impl Sealed for super::MeasurementCertificate {}
6381    impl Sealed for super::BornRuleVerification {}
6382    impl Sealed for super::MultiplicationCertificate {}
6383    impl Sealed for super::PartitionCertificate {}
6384    impl Sealed for super::GenericImpossibilityWitness {}
6385    impl Sealed for super::InhabitanceImpossibilityWitness {}
6386    impl Sealed for super::PartitionProductWitness {}
6387    impl Sealed for super::PartitionCoproductWitness {}
6388    impl Sealed for super::CartesianProductWitness {}
6389}
6390
6391impl Certificate for GroundingCertificate {
6392    const IRI: &'static str = "https://uor.foundation/cert/GroundingCertificate";
6393    type Evidence = ();
6394}
6395
6396impl Certificate for LiftChainCertificate {
6397    const IRI: &'static str = "https://uor.foundation/cert/LiftChainCertificate";
6398    type Evidence = ChainAuditTrail;
6399}
6400
6401impl Certificate for InhabitanceCertificate {
6402    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceCertificate";
6403    type Evidence = ();
6404}
6405
6406impl Certificate for CompletenessCertificate {
6407    const IRI: &'static str = "https://uor.foundation/cert/CompletenessCertificate";
6408    type Evidence = CompletenessAuditTrail;
6409}
6410
6411impl Certificate for TransformCertificate {
6412    const IRI: &'static str = "https://uor.foundation/cert/TransformCertificate";
6413    type Evidence = ();
6414}
6415
6416impl Certificate for IsometryCertificate {
6417    const IRI: &'static str = "https://uor.foundation/cert/IsometryCertificate";
6418    type Evidence = ();
6419}
6420
6421impl Certificate for InvolutionCertificate {
6422    const IRI: &'static str = "https://uor.foundation/cert/InvolutionCertificate";
6423    type Evidence = ();
6424}
6425
6426impl Certificate for GeodesicCertificate {
6427    const IRI: &'static str = "https://uor.foundation/cert/GeodesicCertificate";
6428    type Evidence = GeodesicEvidenceBundle;
6429}
6430
6431impl Certificate for MeasurementCertificate {
6432    const IRI: &'static str = "https://uor.foundation/cert/MeasurementCertificate";
6433    type Evidence = ();
6434}
6435
6436impl Certificate for BornRuleVerification {
6437    const IRI: &'static str = "https://uor.foundation/cert/BornRuleVerification";
6438    type Evidence = ();
6439}
6440
6441impl Certificate for MultiplicationCertificate {
6442    const IRI: &'static str = "https://uor.foundation/cert/MultiplicationCertificate";
6443    type Evidence = MultiplicationEvidence;
6444}
6445
6446impl Certificate for PartitionCertificate {
6447    const IRI: &'static str = "https://uor.foundation/cert/PartitionCertificate";
6448    type Evidence = ();
6449}
6450
6451impl Certificate for GenericImpossibilityWitness {
6452    const IRI: &'static str = "https://uor.foundation/cert/GenericImpossibilityCertificate";
6453    type Evidence = ();
6454}
6455
6456impl Certificate for InhabitanceImpossibilityWitness {
6457    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceImpossibilityCertificate";
6458    type Evidence = ();
6459}
6460
6461/// Phase X.1: uniform mint interface over cert subclasses. Each
6462/// `Certificate` implementer that accepts `(witt_bits, ContentFingerprint)`
6463/// at construction time implements this trait. Lives inside a
6464/// `certify_const_mint` module so the symbol doesn't leak into top-level
6465/// documentation alongside `Certificate`.
6466pub(crate) mod certify_const_mint {
6467    use super::{Certificate, ContentFingerprint};
6468    pub trait MintWithLevelFingerprint: Certificate {
6469        fn mint_with_level_fingerprint(
6470            witt_bits: u16,
6471            content_fingerprint: ContentFingerprint,
6472        ) -> Self;
6473    }
6474    impl MintWithLevelFingerprint for super::GroundingCertificate {
6475        #[inline]
6476        fn mint_with_level_fingerprint(
6477            witt_bits: u16,
6478            content_fingerprint: ContentFingerprint,
6479        ) -> Self {
6480            super::GroundingCertificate::with_level_and_fingerprint_const(
6481                witt_bits,
6482                content_fingerprint,
6483            )
6484        }
6485    }
6486    impl MintWithLevelFingerprint for super::LiftChainCertificate {
6487        #[inline]
6488        fn mint_with_level_fingerprint(
6489            witt_bits: u16,
6490            content_fingerprint: ContentFingerprint,
6491        ) -> Self {
6492            super::LiftChainCertificate::with_level_and_fingerprint_const(
6493                witt_bits,
6494                content_fingerprint,
6495            )
6496        }
6497    }
6498    impl MintWithLevelFingerprint for super::InhabitanceCertificate {
6499        #[inline]
6500        fn mint_with_level_fingerprint(
6501            witt_bits: u16,
6502            content_fingerprint: ContentFingerprint,
6503        ) -> Self {
6504            super::InhabitanceCertificate::with_level_and_fingerprint_const(
6505                witt_bits,
6506                content_fingerprint,
6507            )
6508        }
6509    }
6510    impl MintWithLevelFingerprint for super::CompletenessCertificate {
6511        #[inline]
6512        fn mint_with_level_fingerprint(
6513            witt_bits: u16,
6514            content_fingerprint: ContentFingerprint,
6515        ) -> Self {
6516            super::CompletenessCertificate::with_level_and_fingerprint_const(
6517                witt_bits,
6518                content_fingerprint,
6519            )
6520        }
6521    }
6522    impl MintWithLevelFingerprint for super::MultiplicationCertificate {
6523        #[inline]
6524        fn mint_with_level_fingerprint(
6525            witt_bits: u16,
6526            content_fingerprint: ContentFingerprint,
6527        ) -> Self {
6528            super::MultiplicationCertificate::with_level_and_fingerprint_const(
6529                witt_bits,
6530                content_fingerprint,
6531            )
6532        }
6533    }
6534    impl MintWithLevelFingerprint for super::PartitionCertificate {
6535        #[inline]
6536        fn mint_with_level_fingerprint(
6537            witt_bits: u16,
6538            content_fingerprint: ContentFingerprint,
6539        ) -> Self {
6540            super::PartitionCertificate::with_level_and_fingerprint_const(
6541                witt_bits,
6542                content_fingerprint,
6543            )
6544        }
6545    }
6546    impl MintWithLevelFingerprint for super::TransformCertificate {
6547        #[inline]
6548        fn mint_with_level_fingerprint(
6549            witt_bits: u16,
6550            content_fingerprint: ContentFingerprint,
6551        ) -> Self {
6552            super::TransformCertificate::with_level_and_fingerprint_const(
6553                witt_bits,
6554                content_fingerprint,
6555            )
6556        }
6557    }
6558    impl MintWithLevelFingerprint for super::IsometryCertificate {
6559        #[inline]
6560        fn mint_with_level_fingerprint(
6561            witt_bits: u16,
6562            content_fingerprint: ContentFingerprint,
6563        ) -> Self {
6564            super::IsometryCertificate::with_level_and_fingerprint_const(
6565                witt_bits,
6566                content_fingerprint,
6567            )
6568        }
6569    }
6570    impl MintWithLevelFingerprint for super::InvolutionCertificate {
6571        #[inline]
6572        fn mint_with_level_fingerprint(
6573            witt_bits: u16,
6574            content_fingerprint: ContentFingerprint,
6575        ) -> Self {
6576            super::InvolutionCertificate::with_level_and_fingerprint_const(
6577                witt_bits,
6578                content_fingerprint,
6579            )
6580        }
6581    }
6582    impl MintWithLevelFingerprint for super::GeodesicCertificate {
6583        #[inline]
6584        fn mint_with_level_fingerprint(
6585            witt_bits: u16,
6586            content_fingerprint: ContentFingerprint,
6587        ) -> Self {
6588            super::GeodesicCertificate::with_level_and_fingerprint_const(
6589                witt_bits,
6590                content_fingerprint,
6591            )
6592        }
6593    }
6594    impl MintWithLevelFingerprint for super::MeasurementCertificate {
6595        #[inline]
6596        fn mint_with_level_fingerprint(
6597            witt_bits: u16,
6598            content_fingerprint: ContentFingerprint,
6599        ) -> Self {
6600            super::MeasurementCertificate::with_level_and_fingerprint_const(
6601                witt_bits,
6602                content_fingerprint,
6603            )
6604        }
6605    }
6606    impl MintWithLevelFingerprint for super::BornRuleVerification {
6607        #[inline]
6608        fn mint_with_level_fingerprint(
6609            witt_bits: u16,
6610            content_fingerprint: ContentFingerprint,
6611        ) -> Self {
6612            super::BornRuleVerification::with_level_and_fingerprint_const(
6613                witt_bits,
6614                content_fingerprint,
6615            )
6616        }
6617    }
6618}
6619
6620/// v0.2.2 W11: parametric carrier for any foundation-supplied certificate.
6621/// Replaces the v0.2.1 per-class shim duplication. The `Certificate` trait
6622/// is sealed and the `_private` field prevents external construction; only
6623/// the foundation's pipeline / resolver paths produce `Certified<C>` values.
6624#[derive(Debug, Clone)]
6625pub struct Certified<C: Certificate> {
6626    /// The certificate kind value carried by this wrapper.
6627    inner: C,
6628    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6629    uor_time: UorTime,
6630    /// Prevents external construction.
6631    _private: (),
6632}
6633
6634impl<C: Certificate> Certified<C> {
6635    /// Returns a reference to the carried certificate kind value.
6636    #[inline]
6637    #[must_use]
6638    pub const fn certificate(&self) -> &C {
6639        &self.inner
6640    }
6641
6642    /// Returns the ontology IRI of this certificate's kind.
6643    #[inline]
6644    #[must_use]
6645    pub const fn iri(&self) -> &'static str {
6646        C::IRI
6647    }
6648
6649    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6650    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
6651    /// `observable:LandauerCost`. Content-deterministic: same computation →
6652    /// same `UorTime`. Composable against wall-clock bounds via
6653    /// [`UorTime::min_wall_clock`] and a downstream-supplied `Calibration`.
6654    #[inline]
6655    #[must_use]
6656    pub const fn uor_time(&self) -> UorTime {
6657        self.uor_time
6658    }
6659
6660    /// Crate-internal constructor. Reachable only from the pipeline / resolver paths.
6661    /// The `uor_time` is computed deterministically from the certificate kind's `IRI`
6662    /// length: the rewrite-step count is the IRI byte length, and the Landauer cost
6663    /// is `rewrite_steps × ln 2` (the Landauer-temperature cost of traversing that
6664    /// many orthogonal states). Two `Certified<C>` values with the same `C` share the
6665    /// same `UorTime`, preserving content-determinism across pipeline invocations.
6666    #[inline]
6667    #[allow(dead_code)]
6668    pub(crate) const fn new(inner: C) -> Self {
6669        // IRI length is the deterministic proxy for the cert class's structural
6670        // complexity. Phase D threads real resolver-counted steps through.
6671        let steps = C::IRI.len() as u64;
6672        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
6673        let uor_time = UorTime::new(landauer, steps);
6674        Self {
6675            inner,
6676            uor_time,
6677            _private: (),
6678        }
6679    }
6680}
6681
6682/// v0.2.2 Phase C.4: call-site context consumed by the multiplication
6683/// resolver. Carries the stack budget (`linear:stackBudgetBytes`), the
6684/// const-eval regime, and the limb count of the operand's `Limbs<N>`
6685/// backing. The resolver picks the cost-optimal Toom-Cook splitting
6686/// factor R based on this context.
6687#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6688pub struct MulContext {
6689    /// Stack budget available at the call site, in bytes. Zero is
6690    /// inadmissible; the resolver returns an impossibility witness.
6691    pub stack_budget_bytes: u64,
6692    /// True if this call is in const-eval context. In const-eval, only
6693    /// R = 1 (schoolbook) is admissible because deeper recursion blows
6694    /// the const-eval depth limit.
6695    pub const_eval: bool,
6696    /// Number of 64-bit limbs in the operand's `Limbs<N>` backing.
6697    /// Schoolbook cost is proportional to `N^2`; Karatsuba cost is
6698    /// proportional to `3 · (N/2)^2`. For native-backed levels
6699    /// (W8..W128), pass the equivalent limb count.
6700    pub limb_count: usize,
6701}
6702
6703impl MulContext {
6704    /// Construct a new `MulContext` for the call site.
6705    #[inline]
6706    #[must_use]
6707    pub const fn new(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> Self {
6708        Self {
6709            stack_budget_bytes,
6710            const_eval,
6711            limb_count,
6712        }
6713    }
6714}
6715
6716/// v0.2.2 Phase C.4: evidence returned alongside a `MultiplicationCertificate`.
6717/// The certificate is a sealed handle; its evidence (chosen splitting factor,
6718/// sub-multiplication count, accumulated Landauer cost in nats) lives here.
6719#[derive(Debug, Clone, Copy, PartialEq)]
6720pub struct MultiplicationEvidence {
6721    splitting_factor: u32,
6722    sub_multiplication_count: u32,
6723    landauer_cost_nats_bits: u64,
6724}
6725
6726impl MultiplicationEvidence {
6727    /// The Toom-Cook splitting factor R chosen by the resolver.
6728    #[inline]
6729    #[must_use]
6730    pub const fn splitting_factor(&self) -> u32 {
6731        self.splitting_factor
6732    }
6733
6734    /// The recursive sub-multiplication count for one multiplication.
6735    #[inline]
6736    #[must_use]
6737    pub const fn sub_multiplication_count(&self) -> u32 {
6738        self.sub_multiplication_count
6739    }
6740
6741    /// Accumulated Landauer cost in nats, priced per `op:OA_5`. Returned as the IEEE-754 bit pattern; project to `H::Decimal` at use sites via `<H::Decimal as DecimalTranscendental>::from_bits(_)`.
6742    #[inline]
6743    #[must_use]
6744    pub const fn landauer_cost_nats_bits(&self) -> u64 {
6745        self.landauer_cost_nats_bits
6746    }
6747}
6748
6749impl MultiplicationCertificate {
6750    /// v0.2.2 T6.7: construct a `MultiplicationCertificate` with substrate-
6751    /// computed evidence. Crate-internal only; downstream obtains certificates
6752    /// via `resolver::multiplication::certify::<H>`.
6753    #[inline]
6754    #[must_use]
6755    pub(crate) fn with_evidence(
6756        splitting_factor: u32,
6757        sub_multiplication_count: u32,
6758        landauer_cost_nats_bits: u64,
6759        content_fingerprint: ContentFingerprint,
6760    ) -> Self {
6761        let _ = MultiplicationEvidence {
6762            splitting_factor,
6763            sub_multiplication_count,
6764            landauer_cost_nats_bits,
6765        };
6766        Self::with_level_and_fingerprint_const(32, content_fingerprint)
6767    }
6768}
6769
6770/// v0.2.2 Phase E: maximum simplicial dimension tracked by the
6771/// constraint-nerve Betti-numbers vector. The bound is 8 for the
6772/// currently-supported WittLevel set per the existing partition:FreeRank
6773/// capacity properties; the constant is `pub` (part of the public-API
6774/// snapshot) so future expansions require explicit review.
6775/// Wiki ADR-037: alias of [`crate::HostBounds::BETTI_DIMENSION_MAX`] via
6776/// [`crate::DefaultHostBounds`].
6777pub const MAX_BETTI_DIMENSION: usize =
6778    <crate::DefaultHostBounds as crate::HostBounds>::BETTI_DIMENSION_MAX;
6779
6780/// Sealed newtype for the grounding completion ratio σ ∈
6781/// [0.0, 1.0]. σ = 1 indicates the ground state; σ = 0 the
6782/// unbound state. Backs observable:GroundingSigma. Phase 9: parametric over
6783/// the host's `H::Decimal` precision.
6784#[derive(Debug)]
6785pub struct SigmaValue<H: HostTypes = crate::DefaultHostTypes> {
6786    value: H::Decimal,
6787    _phantom: core::marker::PhantomData<H>,
6788    _sealed: (),
6789}
6790
6791impl<H: HostTypes> Copy for SigmaValue<H> {}
6792impl<H: HostTypes> Clone for SigmaValue<H> {
6793    #[inline]
6794    fn clone(&self) -> Self {
6795        *self
6796    }
6797}
6798impl<H: HostTypes> PartialEq for SigmaValue<H> {
6799    #[inline]
6800    fn eq(&self, other: &Self) -> bool {
6801        self.value == other.value
6802    }
6803}
6804
6805impl<H: HostTypes> SigmaValue<H> {
6806    /// Returns the stored σ value in the range [0.0, 1.0].
6807    #[inline]
6808    #[must_use]
6809    pub const fn value(&self) -> H::Decimal {
6810        self.value
6811    }
6812
6813    /// Crate-internal constructor. Caller guarantees `value` is in
6814    /// the closed range [0.0, 1.0] and is not NaN.
6815    #[inline]
6816    #[must_use]
6817    #[allow(dead_code)]
6818    pub(crate) const fn new_unchecked(value: H::Decimal) -> Self {
6819        Self {
6820            value,
6821            _phantom: core::marker::PhantomData,
6822            _sealed: (),
6823        }
6824    }
6825}
6826
6827/// Phase A.3: sealed stratum coordinate (the v₂ valuation of a `Datum` at level `L`).
6828/// Backs `schema:stratum`. The value is non-negative and bounded by `L`'s `bit_width`
6829/// per the ontology's `nonNegativeInteger` range. Constructed only by foundation code
6830/// at grounding time; no public constructor — the `Stratum<W8>` / `Stratum<W16>` / ...
6831/// type family is closed under the WittLevel individual set.
6832#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6833pub struct Stratum<L> {
6834    value: u32,
6835    _level: PhantomData<L>,
6836    _sealed: (),
6837}
6838
6839impl<L> Stratum<L> {
6840    /// Returns the raw v₂ valuation as a `u32`. The value is bounded by `L`'s bit_width.
6841    #[inline]
6842    #[must_use]
6843    pub const fn as_u32(&self) -> u32 {
6844        self.value
6845    }
6846
6847    /// Crate-internal constructor. Reachable only from grounding-time minting.
6848    #[inline]
6849    #[must_use]
6850    #[allow(dead_code)]
6851    pub(crate) const fn new(value: u32) -> Self {
6852        Self {
6853            value,
6854            _level: PhantomData,
6855            _sealed: (),
6856        }
6857    }
6858}
6859
6860/// Phase A.4: sealed carrier for `observable:d_delta_metric` (metric incompatibility).
6861#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6862pub struct DDeltaMetric {
6863    value: i64,
6864    _sealed: (),
6865}
6866
6867impl DDeltaMetric {
6868    /// Returns the signed incompatibility magnitude (ring distance minus Hamming distance).
6869    #[inline]
6870    #[must_use]
6871    pub const fn as_i64(&self) -> i64 {
6872        self.value
6873    }
6874
6875    /// Crate-internal constructor.
6876    #[inline]
6877    #[must_use]
6878    #[allow(dead_code)]
6879    pub(crate) const fn new(value: i64) -> Self {
6880        Self { value, _sealed: () }
6881    }
6882}
6883
6884/// Phase A.4: sealed carrier for `observable:euler_metric` (Euler characteristic).
6885#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6886pub struct EulerMetric {
6887    value: i64,
6888    _sealed: (),
6889}
6890
6891impl EulerMetric {
6892    /// Returns the Euler characteristic χ of the constraint nerve.
6893    #[inline]
6894    #[must_use]
6895    pub const fn as_i64(&self) -> i64 {
6896        self.value
6897    }
6898
6899    /// Crate-internal constructor.
6900    #[inline]
6901    #[must_use]
6902    #[allow(dead_code)]
6903    pub(crate) const fn new(value: i64) -> Self {
6904        Self { value, _sealed: () }
6905    }
6906}
6907
6908/// Phase A.4: sealed carrier for `observable:residual_metric` (free-site count r).
6909#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6910pub struct ResidualMetric {
6911    value: u32,
6912    _sealed: (),
6913}
6914
6915impl ResidualMetric {
6916    /// Returns the free-site count r at grounding time.
6917    #[inline]
6918    #[must_use]
6919    pub const fn as_u32(&self) -> u32 {
6920        self.value
6921    }
6922
6923    /// Crate-internal constructor.
6924    #[inline]
6925    #[must_use]
6926    #[allow(dead_code)]
6927    pub(crate) const fn new(value: u32) -> Self {
6928        Self { value, _sealed: () }
6929    }
6930}
6931
6932/// Phase A.4: sealed carrier for `observable:betti_metric` (Betti-number vector).
6933/// Fixed-capacity `[u32; MAX_BETTI_DIMENSION]` backing; no heap.
6934#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6935pub struct BettiMetric {
6936    values: [u32; MAX_BETTI_DIMENSION],
6937    _sealed: (),
6938}
6939
6940impl BettiMetric {
6941    /// Returns the Betti-number vector as a fixed-size array reference.
6942    #[inline]
6943    #[must_use]
6944    pub const fn as_array(&self) -> &[u32; MAX_BETTI_DIMENSION] {
6945        &self.values
6946    }
6947
6948    /// Returns the individual Betti number βₖ for dimension k.
6949    /// Returns 0 when k >= MAX_BETTI_DIMENSION.
6950    #[inline]
6951    #[must_use]
6952    pub const fn beta(&self, k: usize) -> u32 {
6953        if k < MAX_BETTI_DIMENSION {
6954            self.values[k]
6955        } else {
6956            0
6957        }
6958    }
6959
6960    /// Crate-internal constructor.
6961    #[inline]
6962    #[must_use]
6963    #[allow(dead_code)]
6964    pub(crate) const fn new(values: [u32; MAX_BETTI_DIMENSION]) -> Self {
6965        Self {
6966            values,
6967            _sealed: (),
6968        }
6969    }
6970}
6971
6972/// Maximum site count of the Jacobian row per Datum at any supported
6973/// WittLevel. Sourced from the partition:FreeRank capacity bound.
6974/// v0.2.2 T2.6 (cleanup): reduced from 64 to 8 to keep `Grounded` under
6975/// the 256-byte size budget enforced by `phantom_tag::grounded_sealed_field_count_unchanged`.
6976/// 8 matches `MAX_BETTI_DIMENSION` and is sufficient for the v0.2.2 partition rank set.
6977/// Wiki ADR-037: alias of [`crate::HostBounds::JACOBIAN_SITES_MAX`] via
6978/// [`crate::DefaultHostBounds`].
6979pub const JACOBIAN_MAX_SITES: usize =
6980    <crate::DefaultHostBounds as crate::HostBounds>::JACOBIAN_SITES_MAX;
6981
6982/// v0.2.2 Phase E: sealed Jacobian row carrier, parametric over the
6983/// WittLevel marker. Fixed-size `[i64; JACOBIAN_MAX_SITES]` backing; no
6984/// heap. The row records the per-site partial derivative of the ring
6985/// operation that produced the Datum. Backs observable:JacobianObservable.
6986#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6987pub struct JacobianMetric<L> {
6988    entries: [i64; JACOBIAN_MAX_SITES],
6989    len: u16,
6990    _level: PhantomData<L>,
6991    _sealed: (),
6992}
6993
6994impl<L> JacobianMetric<L> {
6995    /// Construct a zeroed Jacobian row with the given active length.
6996    #[inline]
6997    #[must_use]
6998    #[allow(dead_code)]
6999    pub(crate) const fn zero(len: u16) -> Self {
7000        Self {
7001            entries: [0i64; JACOBIAN_MAX_SITES],
7002            len,
7003            _level: PhantomData,
7004            _sealed: (),
7005        }
7006    }
7007
7008    /// v0.2.2 T2.6 (cleanup): crate-internal constructor used by the
7009    /// BaseMetric accessor on `Grounded` to return a `JacobianMetric`
7010    /// backed by stored field values.
7011    #[inline]
7012    #[must_use]
7013    #[allow(dead_code)]
7014    pub(crate) const fn from_entries(entries: [i64; JACOBIAN_MAX_SITES], len: u16) -> Self {
7015        Self {
7016            entries,
7017            len,
7018            _level: PhantomData,
7019            _sealed: (),
7020        }
7021    }
7022
7023    /// Access the Jacobian row entries.
7024    #[inline]
7025    #[must_use]
7026    pub const fn entries(&self) -> &[i64; JACOBIAN_MAX_SITES] {
7027        &self.entries
7028    }
7029
7030    /// Number of active sites (the row's logical length).
7031    #[inline]
7032    #[must_use]
7033    pub const fn len(&self) -> u16 {
7034        self.len
7035    }
7036
7037    /// Whether the Jacobian row is empty.
7038    #[inline]
7039    #[must_use]
7040    pub const fn is_empty(&self) -> bool {
7041        self.len == 0
7042    }
7043}
7044
7045/// v0.2.2 Phase E: sealed Partition component classification.
7046/// Closed enumeration mirroring the partition:PartitionComponent
7047/// ontology class.
7048#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7049#[non_exhaustive]
7050pub enum PartitionComponent {
7051    /// The irreducible component.
7052    Irreducible,
7053    /// The reducible component.
7054    Reducible,
7055    /// The unit component.
7056    Units,
7057    /// The exterior component.
7058    Exterior,
7059}
7060
7061/// Sealed marker trait identifying type:ConstrainedType subclasses that may
7062/// appear as the parameter of `Grounded<T>`.
7063/// Per wiki ADR-027, the seal is the same `__sdk_seal::Sealed` supertrait
7064/// foundation uses for `FoundationClosed`, `PrismModel`, and
7065/// `IntoBindingValue`: only foundation and the SDK shape macros emit
7066/// impls. The foundation-sanctioned identity output `ConstrainedTypeInput`
7067/// retains its direct impl; application authors declaring custom Output
7068/// shapes invoke the `output_shape!` SDK macro, which emits
7069/// `__sdk_seal::Sealed`, `GroundedShape`, `IntoBindingValue`, and
7070/// `ConstrainedTypeShape` together.
7071pub trait GroundedShape: crate::pipeline::__sdk_seal::Sealed {}
7072impl GroundedShape for ConstrainedTypeInput {}
7073
7074/// v0.2.2 T4.2: sealed content-addressed handle.
7075/// Wraps a 128-bit identity used for `BindingsTable` lookups and as a
7076/// compact identity handle for `Grounded` values. The underlying `u128`
7077/// is visible via `as_u128()` for interop. Distinct from
7078/// `ContentFingerprint` (the parametric-width fingerprint computed by
7079/// the substrate `Hasher` — see T5.C3.d below): `ContentAddress` is a
7080/// fixed 16-byte sortable handle, while `ContentFingerprint` is the full
7081/// substrate-computed identity that round-trips through `verify_trace`.
7082#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7083pub struct ContentAddress {
7084    raw: u128,
7085    _sealed: (),
7086}
7087
7088impl ContentAddress {
7089    /// The zero content address. Used as the "unset" placeholder in
7090    /// `BindingsTable` lookups, the default state of an uninitialised
7091    /// `Grounded::unit_address`, and the initial seed of replay folds.
7092    #[inline]
7093    #[must_use]
7094    pub const fn zero() -> Self {
7095        Self {
7096            raw: 0,
7097            _sealed: (),
7098        }
7099    }
7100
7101    /// Returns the underlying 128-bit content hash.
7102    #[inline]
7103    #[must_use]
7104    pub const fn as_u128(&self) -> u128 {
7105        self.raw
7106    }
7107
7108    /// Whether this content address is the zero handle.
7109    #[inline]
7110    #[must_use]
7111    pub const fn is_zero(&self) -> bool {
7112        self.raw == 0
7113    }
7114
7115    /// v0.2.2 T5.C1: public ctor. Promoted from `pub(crate)` in T5 so
7116    /// downstream tests can construct deterministic `ContentAddress` values
7117    /// for fixture data without going through the foundation pipeline.
7118    #[inline]
7119    #[must_use]
7120    pub const fn from_u128(raw: u128) -> Self {
7121        Self { raw, _sealed: () }
7122    }
7123
7124    /// v0.2.2 Phase P.3: construct a `ContentAddress` from a `u64` FNV-1a fingerprint
7125    /// by right-padding the value into the 128-bit address space. Used by
7126    /// `Binding::to_binding_entry` to bridge the `Binding.content_address: u64`
7127    /// carrier to the `BindingEntry.address: ContentAddress` (`u128`-backed) shape.
7128    /// The lift is `raw = (fingerprint as u128) << 64` — upper 64 bits carry the
7129    /// FNV-1a value; lower 64 bits are zero. Content-deterministic; round-trips via
7130    /// `ContentAddress::as_u128() >> 64` back to the original `u64`.
7131    #[inline]
7132    #[must_use]
7133    pub const fn from_u64_fingerprint(fingerprint: u64) -> Self {
7134        Self {
7135            raw: (fingerprint as u128) << 64,
7136            _sealed: (),
7137        }
7138    }
7139}
7140
7141impl Default for ContentAddress {
7142    #[inline]
7143    fn default() -> Self {
7144        Self::zero()
7145    }
7146}
7147
7148/// Trace wire-format identifier. Per the wiki's ADR-018, wire-format
7149/// identifiers are explicitly carved out of the `HostBounds` rule because
7150/// cross-implementation interop requires a single shared format identifier.
7151/// Increment when the layout changes (event ordering, trailing fields,
7152/// primitive-op discriminant table, certificate-kind discriminant table).
7153/// Pinned by the `rust/trace_byte_layout_pinned` conformance validator.
7154pub const TRACE_REPLAY_FORMAT_VERSION: u16 = 9;
7155
7156/// v0.2.2 T5: pluggable content hasher with parametric output width.
7157/// The foundation does not ship an implementation. Downstream substrate
7158/// consumers (PRISM, application crates) supply their own `Hasher` impl
7159/// — BLAKE3, SHA-256, SHA-512, BLAKE2b, SipHash 2-4, FNV-1a, or any
7160/// other byte-stream hash whose output width satisfies the foundation's
7161/// derived collision-bound minimum.
7162/// # Foundation recommendation
7163/// The foundation **recommends BLAKE3** as the default substrate hash for
7164/// production deployments. BLAKE3 is fast, well-audited, has no known
7165/// cryptographic weaknesses, supports parallel and SIMD-accelerated
7166/// implementations, and has a flexible output length. PRISM ships a BLAKE3
7167/// `Hasher` impl as its production substrate; application crates should
7168/// use it unless they have a specific reason to deviate.
7169/// The recommendation is non-binding: any conforming `Hasher` impl works
7170/// with the foundation's pipeline and verify path. The foundation never
7171/// invokes a hash function itself, so the choice is fully a downstream
7172/// decision.
7173/// # Architecture
7174/// The architectural shape mirrors `Calibration`: the foundation defines
7175/// the abstract quantity (`ContentFingerprint`) and the substitution point
7176/// (`Hasher`); downstream provides the concrete substrate AND chooses the
7177/// output width within the foundation's correctness budget.
7178/// # Required laws
7179/// 1. **Width-in-budget**: `OUTPUT_BYTES` must be in
7180///    `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]` where `FP_MAX`
7181///    is the const-generic carrying `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
7182///    Enforced at codegen time via a `const _: () = assert!(...)` block
7183///    emitted inside every `pipeline::run::<T, _, H>` body.
7184/// 2. **Determinism**: identical byte sequences produce bit-identical outputs
7185///    across program runs, builds, target architectures, and rustc versions.
7186/// 3. **Sensitivity**: hashing two byte sequences that differ in any byte
7187///    produces two distinct outputs with probability bounded by the hasher's
7188///    documented collision rate.
7189/// 4. **No interior mutability**: `fold_byte` consumes `self` and returns a
7190///    new state. Impls that depend on hidden mutable state violate the contract.
7191/// # Example
7192/// ```
7193/// use uor_foundation::enforcement::Hasher;
7194/// /// Minimal 128-bit (16-byte) FNV-1a substrate — two 64-bit lanes.
7195/// #[derive(Clone, Copy)]
7196/// pub struct Fnv1a16 { a: u64, b: u64 }
7197/// impl Hasher for Fnv1a16 {
7198///     const OUTPUT_BYTES: usize = 16;
7199///     fn initial() -> Self {
7200///         Self { a: 0xcbf29ce484222325, b: 0x84222325cbf29ce4 }
7201///     }
7202///     fn fold_byte(mut self, x: u8) -> Self {
7203///         self.a ^= x as u64;
7204///         self.a = self.a.wrapping_mul(0x100000001b3);
7205///         self.b ^= (x as u64).rotate_left(8);
7206///         self.b = self.b.wrapping_mul(0x100000001b3);
7207///         self
7208///     }
7209///     fn finalize(self) -> [u8; 32] {
7210///         let mut buf = [0u8; 32];
7211///         buf[..8].copy_from_slice(&self.a.to_be_bytes());
7212///         buf[8..16].copy_from_slice(&self.b.to_be_bytes());
7213///         buf
7214///     }
7215/// }
7216/// ```
7217/// Above, `Hasher` is reached through its default const-generic
7218/// `<FP_MAX = 32>`, which is the `DefaultHostBounds::FINGERPRINT_MAX_BYTES`
7219/// value. Applications that select a different `HostBounds` impl write
7220/// `impl Hasher<{<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES}> for MyHasher`.
7221pub trait Hasher<const FP_MAX: usize = 32> {
7222    /// Active output width in bytes. Must lie within the bounds
7223    /// the application's selected `HostBounds` declares —
7224    /// `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]`.
7225    const OUTPUT_BYTES: usize;
7226
7227    /// Initial hasher state.
7228    fn initial() -> Self;
7229
7230    /// Fold a single byte into the running state.
7231    #[must_use]
7232    fn fold_byte(self, b: u8) -> Self;
7233
7234    /// Fold a slice of bytes (default impl: byte-by-byte).
7235    #[inline]
7236    #[must_use]
7237    fn fold_bytes(mut self, bytes: &[u8]) -> Self
7238    where
7239        Self: Sized,
7240    {
7241        let mut i = 0;
7242        while i < bytes.len() {
7243            self = self.fold_byte(bytes[i]);
7244            i += 1;
7245        }
7246        self
7247    }
7248
7249    /// Finalize into the canonical max-width buffer of `FP_MAX` bytes.
7250    /// Bytes `0..OUTPUT_BYTES` carry the hash result; bytes
7251    /// `OUTPUT_BYTES..FP_MAX` MUST be zero.
7252    fn finalize(self) -> [u8; FP_MAX];
7253}
7254
7255/// ADR-030 adapter: wrap any [`Hasher`] impl as an
7256/// [`crate::pipeline::AxisExtension`]. The lone supported kernel id
7257/// is [`HashAxis::KERNEL_HASH`] = 0, which folds the input bytes
7258/// through the wrapped Hasher and writes the first `OUTPUT_BYTES`
7259/// digest bytes to the caller-provided buffer.
7260#[derive(Debug, Clone, Copy)]
7261pub struct HashAxis<H: Hasher>(core::marker::PhantomData<H>);
7262
7263impl<H: Hasher> HashAxis<H> {
7264    /// Canonical kernel id for the hash operation. The closure-body
7265    /// grammar G19 form `hash(input)` lowers to
7266    /// `Term::AxisInvocation { axis_index: 0, kernel_id: HashAxis::KERNEL_HASH, input_index }`.
7267    pub const KERNEL_HASH: u32 = 0;
7268}
7269
7270impl<H: Hasher> crate::pipeline::__sdk_seal::Sealed for HashAxis<H> {}
7271impl<H: Hasher> crate::pipeline::SubstrateTermBody for HashAxis<H> {
7272    fn body_arena() -> &'static [Term] {
7273        &[]
7274    }
7275}
7276impl<H: Hasher> crate::pipeline::AxisExtension for HashAxis<H> {
7277    const AXIS_ADDRESS: &'static str = "https://uor.foundation/axis/HashAxis";
7278    const MAX_OUTPUT_BYTES: usize = <H as Hasher>::OUTPUT_BYTES;
7279    fn dispatch_kernel(
7280        kernel_id: u32,
7281        input: &[u8],
7282        out: &mut [u8],
7283    ) -> Result<usize, ShapeViolation> {
7284        if kernel_id != Self::KERNEL_HASH {
7285            return Err(ShapeViolation {
7286                shape_iri: "https://uor.foundation/axis/HashAxis",
7287                constraint_iri: "https://uor.foundation/axis/HashAxis/kernelId",
7288                property_iri: "https://uor.foundation/axis/kernelId",
7289                expected_range: "https://uor.foundation/axis/HashAxis/KERNEL_HASH",
7290                min_count: 0,
7291                max_count: 1,
7292                kind: crate::ViolationKind::ValueCheck,
7293            });
7294        }
7295        let mut hasher = <H as Hasher>::initial();
7296        hasher = hasher.fold_bytes(input);
7297        let digest = hasher.finalize();
7298        let n = <H as Hasher>::OUTPUT_BYTES.min(out.len()).min(digest.len());
7299        let mut i = 0;
7300        while i < n {
7301            out[i] = digest[i];
7302            i += 1;
7303        }
7304        Ok(n)
7305    }
7306}
7307
7308/// Sealed parametric content fingerprint.
7309/// Wraps a fixed-capacity byte buffer of `FP_MAX` bytes plus the
7310/// active width in bytes. `FP_MAX` is the const-generic that carries
7311/// the application's selected `HostBounds::FINGERPRINT_MAX_BYTES`
7312/// (default = 32, matching `DefaultHostBounds`). The active width
7313/// is set by the producing `Hasher::OUTPUT_BYTES` and recorded so
7314/// downstream can distinguish "this is a 128-bit fingerprint" from
7315/// "this is a 256-bit fingerprint" without inspecting trailing zeros.
7316/// Equality is bit-equality on the full buffer + width tag, so two
7317/// fingerprints from different hashers (different widths) are never
7318/// equal even if their leading bytes happen to coincide. This prevents
7319/// silent collisions when downstream consumers mix substrate hashers.
7320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7321pub struct ContentFingerprint<const FP_MAX: usize = 32> {
7322    bytes: [u8; FP_MAX],
7323    width_bytes: u8,
7324    _sealed: (),
7325}
7326
7327impl<const FP_MAX: usize> ContentFingerprint<FP_MAX> {
7328    /// Crate-internal zero placeholder. Used internally as the
7329    /// `Trace::empty()` field initializer and the `Default` impl. Not
7330    /// publicly constructible; downstream that needs a `ContentFingerprint`
7331    /// constructs one via `Hasher::finalize()` followed by `from_buffer()`.
7332    #[inline]
7333    #[must_use]
7334    #[allow(dead_code)]
7335    pub(crate) const fn zero() -> Self {
7336        Self {
7337            bytes: [0u8; FP_MAX],
7338            width_bytes: 0,
7339            _sealed: (),
7340        }
7341    }
7342
7343    /// Whether this fingerprint is the all-zero placeholder.
7344    #[inline]
7345    #[must_use]
7346    pub const fn is_zero(&self) -> bool {
7347        self.width_bytes == 0
7348    }
7349
7350    /// Active width in bytes (set by the producing hasher).
7351    #[inline]
7352    #[must_use]
7353    pub const fn width_bytes(&self) -> u8 {
7354        self.width_bytes
7355    }
7356
7357    /// Active width in bits (`width_bytes * 8`).
7358    #[inline]
7359    #[must_use]
7360    pub const fn width_bits(&self) -> u16 {
7361        (self.width_bytes as u16) * 8
7362    }
7363
7364    /// The full buffer. Bytes `0..width_bytes` are the hash; bytes
7365    /// `width_bytes..FP_MAX` are zero.
7366    #[inline]
7367    #[must_use]
7368    pub const fn as_bytes(&self) -> &[u8; FP_MAX] {
7369        &self.bytes
7370    }
7371
7372    /// Construct a fingerprint from a hasher's finalize buffer + width tag.
7373    /// Production paths reach this via `pipeline::run::<T, _, H>`; test
7374    /// paths via the `__test_helpers` back-door.
7375    #[inline]
7376    #[must_use]
7377    pub const fn from_buffer(bytes: [u8; FP_MAX], width_bytes: u8) -> Self {
7378        Self {
7379            bytes,
7380            width_bytes,
7381            _sealed: (),
7382        }
7383    }
7384}
7385
7386impl<const FP_MAX: usize> Default for ContentFingerprint<FP_MAX> {
7387    #[inline]
7388    fn default() -> Self {
7389        Self::zero()
7390    }
7391}
7392
7393/// v0.2.2 T5: stable u8 discriminant for `PrimitiveOp`. Locked to the
7394/// codegen output order; do not reorder `PrimitiveOp` variants without
7395/// bumping `TRACE_REPLAY_FORMAT_VERSION`. Folded into the canonical byte
7396/// layout of every `TraceEvent` so substrate hashers produce stable
7397/// fingerprints across builds.
7398#[inline]
7399#[must_use]
7400pub const fn primitive_op_discriminant(op: crate::PrimitiveOp) -> u8 {
7401    match op {
7402        crate::PrimitiveOp::Neg => 0,
7403        crate::PrimitiveOp::Bnot => 1,
7404        crate::PrimitiveOp::Succ => 2,
7405        crate::PrimitiveOp::Pred => 3,
7406        crate::PrimitiveOp::Add => 4,
7407        crate::PrimitiveOp::Sub => 5,
7408        crate::PrimitiveOp::Mul => 6,
7409        crate::PrimitiveOp::Xor => 7,
7410        crate::PrimitiveOp::And => 8,
7411        crate::PrimitiveOp::Or => 9,
7412        // ADR-013/TR-08 substrate amendment: byte-level ops 10..15.
7413        crate::PrimitiveOp::Le => 10,
7414        crate::PrimitiveOp::Lt => 11,
7415        crate::PrimitiveOp::Ge => 12,
7416        crate::PrimitiveOp::Gt => 13,
7417        crate::PrimitiveOp::Concat => 14,
7418        // ADR-053 substrate amendment: ring-axis arithmetic completion.
7419        crate::PrimitiveOp::Div => 15,
7420        crate::PrimitiveOp::Mod => 16,
7421        crate::PrimitiveOp::Pow => 17,
7422    }
7423}
7424
7425/// v0.2.2 T5: stable u8 discriminant tag distinguishing the certificate
7426/// kinds the foundation pipeline mints. Folded into the trailing byte of
7427/// every canonical digest so two certificates over the same source unit
7428/// but of different kinds produce distinct fingerprints. Locked at v0.2.2;
7429/// reordering or inserting variants requires bumping
7430/// `TRACE_REPLAY_FORMAT_VERSION`.
7431#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7432#[non_exhaustive]
7433pub enum CertificateKind {
7434    /// Cert minted by `pipeline::run` and `run_const` (retained for
7435    /// `run_grounding_aware`).
7436    Grounding,
7437    /// Cert minted by `certify_tower_completeness_const`.
7438    TowerCompleteness,
7439    /// Cert minted by `certify_incremental_completeness_const`.
7440    IncrementalCompleteness,
7441    /// Cert minted by `certify_inhabitance_const` / `run_inhabitance`.
7442    Inhabitance,
7443    /// Cert minted by `certify_multiplication_const`.
7444    Multiplication,
7445    /// Cert minted by `resolver::two_sat_decider::certify`.
7446    TwoSat,
7447    /// Cert minted by `resolver::horn_sat_decider::certify`.
7448    HornSat,
7449    /// Cert minted by `resolver::residual_verdict::certify`.
7450    ResidualVerdict,
7451    /// Cert minted by `resolver::canonical_form::certify`.
7452    CanonicalForm,
7453    /// Cert minted by `resolver::type_synthesis::certify`.
7454    TypeSynthesis,
7455    /// Cert minted by `resolver::homotopy::certify`.
7456    Homotopy,
7457    /// Cert minted by `resolver::monodromy::certify`.
7458    Monodromy,
7459    /// Cert minted by `resolver::moduli::certify`.
7460    Moduli,
7461    /// Cert minted by `resolver::jacobian_guided::certify`.
7462    JacobianGuided,
7463    /// Cert minted by `resolver::evaluation::certify`.
7464    Evaluation,
7465    /// Cert minted by `resolver::session::certify`.
7466    Session,
7467    /// Cert minted by `resolver::superposition::certify`.
7468    Superposition,
7469    /// Cert minted by `resolver::measurement::certify`.
7470    Measurement,
7471    /// Cert minted by `resolver::witt_level_resolver::certify`.
7472    WittLevel,
7473    /// Cert minted by `resolver::dihedral_factorization::certify`.
7474    DihedralFactorization,
7475    /// Cert minted by `resolver::completeness::certify`.
7476    Completeness,
7477    /// Cert minted by `resolver::geodesic_validator::certify`.
7478    GeodesicValidator,
7479}
7480
7481/// v0.2.2 T5: stable u8 discriminant for `CertificateKind`. Folded into
7482/// the trailing byte of canonical digests via the `*Digest` types so two
7483/// distinct certificate kinds over the same source unit produce distinct
7484/// fingerprints. Locked at v0.2.2.
7485#[inline]
7486#[must_use]
7487pub const fn certificate_kind_discriminant(kind: CertificateKind) -> u8 {
7488    match kind {
7489        CertificateKind::Grounding => 1,
7490        CertificateKind::TowerCompleteness => 2,
7491        CertificateKind::IncrementalCompleteness => 3,
7492        CertificateKind::Inhabitance => 4,
7493        CertificateKind::Multiplication => 5,
7494        CertificateKind::TwoSat => 6,
7495        CertificateKind::HornSat => 7,
7496        CertificateKind::ResidualVerdict => 8,
7497        CertificateKind::CanonicalForm => 9,
7498        CertificateKind::TypeSynthesis => 10,
7499        CertificateKind::Homotopy => 11,
7500        CertificateKind::Monodromy => 12,
7501        CertificateKind::Moduli => 13,
7502        CertificateKind::JacobianGuided => 14,
7503        CertificateKind::Evaluation => 15,
7504        CertificateKind::Session => 16,
7505        CertificateKind::Superposition => 17,
7506        CertificateKind::Measurement => 18,
7507        CertificateKind::WittLevel => 19,
7508        CertificateKind::DihedralFactorization => 20,
7509        CertificateKind::Completeness => 21,
7510        CertificateKind::GeodesicValidator => 22,
7511    }
7512}
7513
7514/// v0.2.2 T5: fold a `ConstraintRef` into a `Hasher` via the canonical
7515/// byte layout. Each variant emits a discriminant byte (1..=9) followed by
7516/// its payload bytes in big-endian order. Locked at v0.2.2; reordering
7517/// variants requires bumping `TRACE_REPLAY_FORMAT_VERSION`.
7518/// Used by `pipeline::run`, `run_const`, and the four `certify_*` entry
7519/// points to fold a unit's constraint set into the substrate fingerprint.
7520pub fn fold_constraint_ref<H: Hasher>(mut hasher: H, c: &crate::pipeline::ConstraintRef) -> H {
7521    use crate::pipeline::ConstraintRef as C;
7522    match c {
7523        C::Residue { modulus, residue } => {
7524            hasher = hasher.fold_byte(1);
7525            hasher = hasher.fold_bytes(&modulus.to_be_bytes());
7526            hasher = hasher.fold_bytes(&residue.to_be_bytes());
7527        }
7528        C::Hamming { bound } => {
7529            hasher = hasher.fold_byte(2);
7530            hasher = hasher.fold_bytes(&bound.to_be_bytes());
7531        }
7532        C::Depth { min, max } => {
7533            hasher = hasher.fold_byte(3);
7534            hasher = hasher.fold_bytes(&min.to_be_bytes());
7535            hasher = hasher.fold_bytes(&max.to_be_bytes());
7536        }
7537        C::Carry { site } => {
7538            hasher = hasher.fold_byte(4);
7539            hasher = hasher.fold_bytes(&site.to_be_bytes());
7540        }
7541        C::Site { position } => {
7542            hasher = hasher.fold_byte(5);
7543            hasher = hasher.fold_bytes(&position.to_be_bytes());
7544        }
7545        C::Affine {
7546            coefficients,
7547            coefficient_count,
7548            bias,
7549        } => {
7550            hasher = hasher.fold_byte(6);
7551            hasher = hasher.fold_bytes(&coefficient_count.to_be_bytes());
7552            let count = *coefficient_count as usize;
7553            let mut i = 0;
7554            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
7555                hasher = hasher.fold_bytes(&coefficients[i].to_be_bytes());
7556                i += 1;
7557            }
7558            hasher = hasher.fold_bytes(&bias.to_be_bytes());
7559        }
7560        C::SatClauses { clauses, num_vars } => {
7561            hasher = hasher.fold_byte(7);
7562            hasher = hasher.fold_bytes(&num_vars.to_be_bytes());
7563            hasher = hasher.fold_bytes(&(clauses.len() as u32).to_be_bytes());
7564            let mut i = 0;
7565            while i < clauses.len() {
7566                let clause = clauses[i];
7567                hasher = hasher.fold_bytes(&(clause.len() as u32).to_be_bytes());
7568                let mut j = 0;
7569                while j < clause.len() {
7570                    let (var, neg) = clause[j];
7571                    hasher = hasher.fold_bytes(&var.to_be_bytes());
7572                    hasher = hasher.fold_byte(if neg { 1 } else { 0 });
7573                    j += 1;
7574                }
7575                i += 1;
7576            }
7577        }
7578        C::Bound {
7579            observable_iri,
7580            bound_shape_iri,
7581            args_repr,
7582        } => {
7583            hasher = hasher.fold_byte(8);
7584            hasher = hasher.fold_bytes(observable_iri.as_bytes());
7585            hasher = hasher.fold_byte(0);
7586            hasher = hasher.fold_bytes(bound_shape_iri.as_bytes());
7587            hasher = hasher.fold_byte(0);
7588            hasher = hasher.fold_bytes(args_repr.as_bytes());
7589            hasher = hasher.fold_byte(0);
7590        }
7591        C::Conjunction {
7592            conjuncts,
7593            conjunct_count,
7594        } => {
7595            hasher = hasher.fold_byte(9);
7596            hasher = hasher.fold_bytes(&conjunct_count.to_be_bytes());
7597            let count = *conjunct_count as usize;
7598            let mut i = 0;
7599            while i < count && i < crate::pipeline::CONJUNCTION_MAX_TERMS {
7600                let lifted = conjuncts[i].into_constraint();
7601                hasher = fold_constraint_ref(hasher, &lifted);
7602                i += 1;
7603            }
7604        }
7605    }
7606    hasher
7607}
7608
7609/// v0.2.2 T5: fold the canonical CompileUnit byte layout into a `Hasher`.
7610/// Layout: `level_bits (2 BE) || budget (8 BE) || iri bytes || 0x00 ||
7611/// site_count (8 BE) || for each constraint: fold_constraint_ref ||
7612/// certificate_kind_discriminant (1 byte trailing)`.
7613/// Locked at v0.2.2 by the `rust/trace_byte_layout_pinned` conformance
7614/// validator. Used by `pipeline::run`, `run_const`, and the four
7615/// `certify_*` entry points.
7616pub fn fold_unit_digest<H: Hasher>(
7617    mut hasher: H,
7618    level_bits: u16,
7619    budget: u64,
7620    iri: &str,
7621    site_count: usize,
7622    constraints: &[crate::pipeline::ConstraintRef],
7623    kind: CertificateKind,
7624) -> H {
7625    hasher = hasher.fold_bytes(&level_bits.to_be_bytes());
7626    hasher = hasher.fold_bytes(&budget.to_be_bytes());
7627    hasher = hasher.fold_bytes(iri.as_bytes());
7628    hasher = hasher.fold_byte(0);
7629    hasher = hasher.fold_bytes(&(site_count as u64).to_be_bytes());
7630    let mut i = 0;
7631    while i < constraints.len() {
7632        hasher = fold_constraint_ref(hasher, &constraints[i]);
7633        i += 1;
7634    }
7635    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7636    hasher
7637}
7638
7639/// v0.2.2 T5: fold the canonical ParallelDeclaration byte layout into a `Hasher`.
7640/// Layout: `site_count (8 BE) || iri bytes || 0x00 || decl_site_count (8 BE) ||
7641/// for each constraint: fold_constraint_ref || certificate_kind_discriminant`.
7642pub fn fold_parallel_digest<H: Hasher>(
7643    mut hasher: H,
7644    decl_site_count: u64,
7645    iri: &str,
7646    type_site_count: usize,
7647    constraints: &[crate::pipeline::ConstraintRef],
7648    kind: CertificateKind,
7649) -> H {
7650    hasher = hasher.fold_bytes(&decl_site_count.to_be_bytes());
7651    hasher = hasher.fold_bytes(iri.as_bytes());
7652    hasher = hasher.fold_byte(0);
7653    hasher = hasher.fold_bytes(&(type_site_count as u64).to_be_bytes());
7654    let mut i = 0;
7655    while i < constraints.len() {
7656        hasher = fold_constraint_ref(hasher, &constraints[i]);
7657        i += 1;
7658    }
7659    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7660    hasher
7661}
7662
7663/// v0.2.2 T5: fold the canonical StreamDeclaration byte layout into a `Hasher`.
7664pub fn fold_stream_digest<H: Hasher>(
7665    mut hasher: H,
7666    productivity_bound: u64,
7667    iri: &str,
7668    constraints: &[crate::pipeline::ConstraintRef],
7669    kind: CertificateKind,
7670) -> H {
7671    hasher = hasher.fold_bytes(&productivity_bound.to_be_bytes());
7672    hasher = hasher.fold_bytes(iri.as_bytes());
7673    hasher = hasher.fold_byte(0);
7674    let mut i = 0;
7675    while i < constraints.len() {
7676        hasher = fold_constraint_ref(hasher, &constraints[i]);
7677        i += 1;
7678    }
7679    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7680    hasher
7681}
7682
7683/// v0.2.2 T5: fold the canonical InteractionDeclaration byte layout into a `Hasher`.
7684pub fn fold_interaction_digest<H: Hasher>(
7685    mut hasher: H,
7686    convergence_seed: u64,
7687    iri: &str,
7688    constraints: &[crate::pipeline::ConstraintRef],
7689    kind: CertificateKind,
7690) -> H {
7691    hasher = hasher.fold_bytes(&convergence_seed.to_be_bytes());
7692    hasher = hasher.fold_bytes(iri.as_bytes());
7693    hasher = hasher.fold_byte(0);
7694    let mut i = 0;
7695    while i < constraints.len() {
7696        hasher = fold_constraint_ref(hasher, &constraints[i]);
7697        i += 1;
7698    }
7699    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7700    hasher
7701}
7702
7703/// v0.2.2 Phase J primitive: `reduction:ReductionStep` / `recursion:BoundedRecursion`.
7704/// Content-deterministic reduction signature: `(witt_bits, constraint_count, satisfiable_bit)`.
7705pub(crate) fn primitive_terminal_reduction<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7706    witt_bits: u16,
7707) -> Result<(u16, u32, u8), PipelineFailure> {
7708    let outcome = crate::pipeline::run_reduction_stages::<T>(witt_bits)?;
7709    let satisfiable_bit: u8 = if outcome.satisfiable { 1 } else { 0 };
7710    Ok((
7711        outcome.witt_bits,
7712        T::CONSTRAINTS.len() as u32,
7713        satisfiable_bit,
7714    ))
7715}
7716
7717/// v0.2.2 Phase J: fold the TerminalReduction triple into the hasher.
7718pub(crate) fn fold_terminal_reduction<H: Hasher>(
7719    mut hasher: H,
7720    witt_bits: u16,
7721    constraint_count: u32,
7722    satisfiable_bit: u8,
7723) -> H {
7724    hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
7725    hasher = hasher.fold_bytes(&constraint_count.to_be_bytes());
7726    hasher = hasher.fold_byte(satisfiable_bit);
7727    hasher
7728}
7729
7730/// Phase X.4: `resolver:CechNerve` / `homology:ChainComplex`.
7731/// Computes the content-deterministic Betti tuple `[b_0, b_1, b_2, 0, .., 0]`
7732/// from the 2-complex constraint-nerve over `T::CONSTRAINTS`:
7733/// vertices = constraints, 1-simplices = pairs of constraints with intersecting
7734/// site support, 2-simplices = triples of constraints with a common site.
7735/// `b_k = dim ker(∂_k) - dim im(∂_{k+1})` for k ∈ {0,1,2}; `b_3..b_7 = 0`.
7736/// Ranks of the boundary operators ∂_1, ∂_2 are computed over ℤ/p (p prime,
7737/// `NERVE_RANK_MOD_P = 1_000_000_007`) by `integer_matrix_rank`. Nerve boundary
7738/// matrices have ±1/0 entries and are totally unimodular, so rank over ℤ/p
7739/// equals rank over ℚ equals rank over ℤ for any prime p not dividing a minor.
7740/// Phase 1a (orphan-closure): inputs larger than `NERVE_CONSTRAINTS_CAP = 8`
7741/// constraints or `NERVE_SITES_CAP = 8` sites return
7742/// `Err(GenericImpossibilityWitness::for_identity("NERVE_CAPACITY_EXCEEDED"))`
7743/// rather than silently truncating — truncation produced Betti numbers for a
7744/// differently-shaped complex than the caller asked about. Callers propagate
7745/// the witness via `?` (pattern mirrored on `primitive_terminal_reduction`).
7746/// # Errors
7747/// Returns `NERVE_CAPACITY_EXCEEDED` when either cap is exceeded.
7748pub fn primitive_simplicial_nerve_betti<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7749) -> Result<[u32; MAX_BETTI_DIMENSION], GenericImpossibilityWitness> {
7750    let k_all = T::CONSTRAINTS.len();
7751    if k_all > NERVE_CONSTRAINTS_CAP {
7752        return Err(GenericImpossibilityWitness::for_identity(
7753            "NERVE_CAPACITY_EXCEEDED",
7754        ));
7755    }
7756    let s_all = T::SITE_COUNT;
7757    if s_all > NERVE_SITES_CAP {
7758        return Err(GenericImpossibilityWitness::for_identity(
7759            "NERVE_CAPACITY_EXCEEDED",
7760        ));
7761    }
7762    let n_constraints = k_all;
7763    let n_sites = s_all;
7764    let mut out = [0u32; MAX_BETTI_DIMENSION];
7765    if n_constraints == 0 {
7766        out[0] = 1;
7767        return Ok(out);
7768    }
7769    // Compute site-support bitmask per constraint (bit `s` set iff constraint touches site `s`).
7770    let mut support = [0u16; NERVE_CONSTRAINTS_CAP];
7771    let mut c = 0;
7772    while c < n_constraints {
7773        support[c] = constraint_site_support_mask::<T>(c, n_sites);
7774        c += 1;
7775    }
7776    // Enumerate 1-simplices: pairs (i,j) with i<j and support[i] & support[j] != 0.
7777    // Index in c1_pairs_lo/hi corresponds to the column in ∂_1 / row in ∂_2.
7778    let mut c1_pairs_lo = [0u8; NERVE_C1_MAX];
7779    let mut c1_pairs_hi = [0u8; NERVE_C1_MAX];
7780    let mut n_c1: usize = 0;
7781    let mut i = 0;
7782    while i < n_constraints {
7783        let mut j = i + 1;
7784        while j < n_constraints {
7785            if (support[i] & support[j]) != 0 && n_c1 < NERVE_C1_MAX {
7786                c1_pairs_lo[n_c1] = i as u8;
7787                c1_pairs_hi[n_c1] = j as u8;
7788                n_c1 += 1;
7789            }
7790            j += 1;
7791        }
7792        i += 1;
7793    }
7794    // Enumerate 2-simplices: triples (i,j,k) with i<j<k and support[i] & support[j] & support[k] != 0.
7795    let mut c2_i = [0u8; NERVE_C2_MAX];
7796    let mut c2_j = [0u8; NERVE_C2_MAX];
7797    let mut c2_k = [0u8; NERVE_C2_MAX];
7798    let mut n_c2: usize = 0;
7799    let mut i2 = 0;
7800    while i2 < n_constraints {
7801        let mut j2 = i2 + 1;
7802        while j2 < n_constraints {
7803            let mut k2 = j2 + 1;
7804            while k2 < n_constraints {
7805                if (support[i2] & support[j2] & support[k2]) != 0 && n_c2 < NERVE_C2_MAX {
7806                    c2_i[n_c2] = i2 as u8;
7807                    c2_j[n_c2] = j2 as u8;
7808                    c2_k[n_c2] = k2 as u8;
7809                    n_c2 += 1;
7810                }
7811                k2 += 1;
7812            }
7813            j2 += 1;
7814        }
7815        i2 += 1;
7816    }
7817    // Build ∂_1: rows = n_constraints (vertices of the nerve), cols = n_c1.
7818    // Convention: ∂(c_i, c_j) = c_j - c_i for i < j.
7819    let mut partial_1 = [[0i64; NERVE_C1_MAX]; NERVE_CONSTRAINTS_CAP];
7820    let mut e = 0;
7821    while e < n_c1 {
7822        let lo = c1_pairs_lo[e] as usize;
7823        let hi = c1_pairs_hi[e] as usize;
7824        partial_1[lo][e] = NERVE_RANK_MOD_P - 1; // -1 mod p
7825        partial_1[hi][e] = 1;
7826        e += 1;
7827    }
7828    let rank_1 = integer_matrix_rank::<NERVE_CONSTRAINTS_CAP, NERVE_C1_MAX>(
7829        &mut partial_1,
7830        n_constraints,
7831        n_c1,
7832    );
7833    // Build ∂_2: rows = n_c1, cols = n_c2.
7834    // Convention: ∂(c_i, c_j, c_k) = (c_j, c_k) - (c_i, c_k) + (c_i, c_j).
7835    let mut partial_2 = [[0i64; NERVE_C2_MAX]; NERVE_C1_MAX];
7836    let mut t = 0;
7837    while t < n_c2 {
7838        let ti = c2_i[t];
7839        let tj = c2_j[t];
7840        let tk = c2_k[t];
7841        let idx_jk = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, tj, tk);
7842        let idx_ik = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tk);
7843        let idx_ij = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tj);
7844        if idx_jk < NERVE_C1_MAX {
7845            partial_2[idx_jk][t] = 1;
7846        }
7847        if idx_ik < NERVE_C1_MAX {
7848            partial_2[idx_ik][t] = NERVE_RANK_MOD_P - 1;
7849        }
7850        if idx_ij < NERVE_C1_MAX {
7851            partial_2[idx_ij][t] = 1;
7852        }
7853        t += 1;
7854    }
7855    let rank_2 = integer_matrix_rank::<NERVE_C1_MAX, NERVE_C2_MAX>(&mut partial_2, n_c1, n_c2);
7856    // b_0 = |C_0| - rank(∂_1). Always ≥ 1 because partial_1 has at least one all-zero row.
7857    let b0 = (n_constraints - rank_1) as u32;
7858    // b_1 = (|C_1| - rank(∂_1)) - rank(∂_2).
7859    let cycles_1 = n_c1.saturating_sub(rank_1);
7860    let b1 = cycles_1.saturating_sub(rank_2) as u32;
7861    // b_2 = |C_2| - rank(∂_2) (the complex is 2-dimensional; no ∂_3).
7862    let b2 = n_c2.saturating_sub(rank_2) as u32;
7863    out[0] = if b0 == 0 { 1 } else { b0 };
7864    if MAX_BETTI_DIMENSION > 1 {
7865        out[1] = b1;
7866    }
7867    if MAX_BETTI_DIMENSION > 2 {
7868        out[2] = b2;
7869    }
7870    Ok(out)
7871}
7872
7873/// Phase X.4: cap on the number of constraints considered by the nerve
7874/// primitive. Phase 1a (orphan-closure): inputs exceeding this cap are
7875/// rejected via `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
7876/// Wiki ADR-037: alias of [`crate::HostBounds::NERVE_CONSTRAINTS_MAX`] via
7877/// [`crate::DefaultHostBounds`].
7878pub const NERVE_CONSTRAINTS_CAP: usize =
7879    <crate::DefaultHostBounds as crate::HostBounds>::NERVE_CONSTRAINTS_MAX;
7880
7881/// Phase X.4: cap on site-support bitmask width (matches `u16` storage).
7882/// Phase 1a (orphan-closure): inputs exceeding this cap are rejected via
7883/// `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
7884/// Wiki ADR-037: alias of [`crate::HostBounds::NERVE_SITES_MAX`] via
7885/// [`crate::DefaultHostBounds`].
7886pub const NERVE_SITES_CAP: usize = <crate::DefaultHostBounds as crate::HostBounds>::NERVE_SITES_MAX;
7887
7888/// Phase X.4: maximum number of 1-simplices = C(NERVE_CONSTRAINTS_CAP, 2) = 28.
7889pub const NERVE_C1_MAX: usize = 28;
7890
7891/// Phase X.4: maximum number of 2-simplices = C(NERVE_CONSTRAINTS_CAP, 3) = 56.
7892pub const NERVE_C2_MAX: usize = 56;
7893
7894/// Phase X.4: prime modulus for nerve boundary-matrix rank computation.
7895/// Chosen so `(i64 * i64) mod p` never overflows (`p² < 2⁶³`). Nerve boundary
7896/// matrices have entries in {-1, 0, 1}; rank over ℤ/p equals rank over ℚ.
7897pub(crate) const NERVE_RANK_MOD_P: i64 = 1_000_000_007;
7898
7899/// Phase X.4: per-constraint site-support bitmask. Returns bit `s` set iff
7900/// constraint `c` in `T::CONSTRAINTS` touches site index `s` (`s < n_sites`).
7901/// `Affine { coefficients, .. }` returns the bitmask of sites whose
7902/// coefficient is non-zero — the natural "site support" of the affine
7903/// relation. Remaining non-site-local variants (Residue, Hamming, Depth,
7904/// Bound, Conjunction, SatClauses) return an all-ones mask over `n_sites`.
7905pub(crate) const fn constraint_site_support_mask<
7906    T: crate::pipeline::ConstrainedTypeShape + ?Sized,
7907>(
7908    c: usize,
7909    n_sites: usize,
7910) -> u16 {
7911    let all_mask: u16 = if n_sites == 0 {
7912        0
7913    } else {
7914        (1u16 << n_sites) - 1
7915    };
7916    match &T::CONSTRAINTS[c] {
7917        crate::pipeline::ConstraintRef::Site { position } => {
7918            if n_sites == 0 {
7919                0
7920            } else {
7921                1u16 << (*position as usize % n_sites)
7922            }
7923        }
7924        crate::pipeline::ConstraintRef::Carry { site } => {
7925            if n_sites == 0 {
7926                0
7927            } else {
7928                1u16 << (*site as usize % n_sites)
7929            }
7930        }
7931        crate::pipeline::ConstraintRef::Affine {
7932            coefficients,
7933            coefficient_count,
7934            ..
7935        } => {
7936            if n_sites == 0 {
7937                0
7938            } else {
7939                let mut mask: u16 = 0;
7940                let count = *coefficient_count as usize;
7941                let mut i = 0;
7942                while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS && i < n_sites {
7943                    if coefficients[i] != 0 {
7944                        mask |= 1u16 << i;
7945                    }
7946                    i += 1;
7947                }
7948                if mask == 0 {
7949                    all_mask
7950                } else {
7951                    mask
7952                }
7953            }
7954        }
7955        _ => all_mask,
7956    }
7957}
7958
7959/// Phase X.4: find the column index of the 1-simplex (lo, hi) in the enumerated
7960/// pair list. Returns `NERVE_C1_MAX` (sentinel = not found) when absent.
7961pub(crate) const fn find_pair_index(
7962    lo_arr: &[u8; NERVE_C1_MAX],
7963    hi_arr: &[u8; NERVE_C1_MAX],
7964    n_c1: usize,
7965    lo: u8,
7966    hi: u8,
7967) -> usize {
7968    let mut i = 0;
7969    while i < n_c1 {
7970        if lo_arr[i] == lo && hi_arr[i] == hi {
7971            return i;
7972        }
7973        i += 1;
7974    }
7975    NERVE_C1_MAX
7976}
7977
7978/// Phase X.4: rank of an integer matrix over ℤ/`NERVE_RANK_MOD_P` via modular
7979/// Gaussian elimination. Entries are reduced mod p and elimination uses
7980/// Fermat-inverse pivot normalization. For ±1/0 boundary matrices this
7981/// coincides with rank over ℤ.
7982pub(crate) const fn integer_matrix_rank<const R: usize, const C: usize>(
7983    matrix: &mut [[i64; C]; R],
7984    rows: usize,
7985    cols: usize,
7986) -> usize {
7987    let p = NERVE_RANK_MOD_P;
7988    // Reduce all entries into [0, p).
7989    let mut r = 0;
7990    while r < rows {
7991        let mut c = 0;
7992        while c < cols {
7993            let v = matrix[r][c] % p;
7994            matrix[r][c] = if v < 0 { v + p } else { v };
7995            c += 1;
7996        }
7997        r += 1;
7998    }
7999    let mut rank: usize = 0;
8000    let mut col: usize = 0;
8001    while col < cols && rank < rows {
8002        // Find a pivot row in column `col`, starting at `rank`.
8003        let mut pivot_row = rank;
8004        while pivot_row < rows && matrix[pivot_row][col] == 0 {
8005            pivot_row += 1;
8006        }
8007        if pivot_row == rows {
8008            col += 1;
8009            continue;
8010        }
8011        // Swap into position.
8012        if pivot_row != rank {
8013            let mut k = 0;
8014            while k < cols {
8015                let tmp = matrix[rank][k];
8016                matrix[rank][k] = matrix[pivot_row][k];
8017                matrix[pivot_row][k] = tmp;
8018                k += 1;
8019            }
8020        }
8021        // Normalize pivot row to have leading 1.
8022        let pivot = matrix[rank][col];
8023        let pivot_inv = mod_pow(pivot, p - 2, p);
8024        let mut k = 0;
8025        while k < cols {
8026            matrix[rank][k] = (matrix[rank][k] * pivot_inv) % p;
8027            k += 1;
8028        }
8029        // Eliminate the column entry from every other row.
8030        let mut r2 = 0;
8031        while r2 < rows {
8032            if r2 != rank {
8033                let factor = matrix[r2][col];
8034                if factor != 0 {
8035                    let mut kk = 0;
8036                    while kk < cols {
8037                        let sub = (matrix[rank][kk] * factor) % p;
8038                        let mut v = matrix[r2][kk] - sub;
8039                        v %= p;
8040                        if v < 0 {
8041                            v += p;
8042                        }
8043                        matrix[r2][kk] = v;
8044                        kk += 1;
8045                    }
8046                }
8047            }
8048            r2 += 1;
8049        }
8050        rank += 1;
8051        col += 1;
8052    }
8053    rank
8054}
8055
8056/// Phase X.4: modular exponentiation `base^exp mod p`, const-fn. Used by
8057/// `integer_matrix_rank` via Fermat's little theorem for modular inverses.
8058pub(crate) const fn mod_pow(base: i64, exp: i64, p: i64) -> i64 {
8059    let mut result: i64 = 1;
8060    let mut b = ((base % p) + p) % p;
8061    let mut e = exp;
8062    while e > 0 {
8063        if e & 1 == 1 {
8064            result = (result * b) % p;
8065        }
8066        b = (b * b) % p;
8067        e >>= 1;
8068    }
8069    result
8070}
8071
8072/// v0.2.2 Phase J: fold the Betti tuple into the hasher.
8073pub(crate) fn fold_betti_tuple<H: Hasher>(mut hasher: H, betti: &[u32; MAX_BETTI_DIMENSION]) -> H {
8074    let mut i = 0;
8075    while i < MAX_BETTI_DIMENSION {
8076        hasher = hasher.fold_bytes(&betti[i].to_be_bytes());
8077        i += 1;
8078    }
8079    hasher
8080}
8081
8082/// v0.2.2 Phase J: Euler characteristic `χ = Σ(-1)^k b_k` from the Betti tuple.
8083#[must_use]
8084pub(crate) fn primitive_euler_characteristic(betti: &[u32; MAX_BETTI_DIMENSION]) -> i64 {
8085    let mut chi: i64 = 0;
8086    let mut k = 0;
8087    while k < MAX_BETTI_DIMENSION {
8088        let term = betti[k] as i64;
8089        if k % 2 == 0 {
8090            chi += term;
8091        } else {
8092            chi -= term;
8093        }
8094        k += 1;
8095    }
8096    chi
8097}
8098
8099/// v0.2.2 Phase J primitive: `op:DihedralGroup` / `op:D_7`.
8100/// Returns `(orbit_size, representative)` under D_{2^n} acting on `T::SITE_COUNT`.
8101/// `orbit_size = 2n` when n ≥ 2, 2 when n == 1, 1 when n == 0 (group identity only).
8102/// `representative` is the lexicographically-minimal element of the orbit of
8103/// site 0 under D_{2n}: rotations `r^k → k mod n` and reflections `s·r^k → (n - k) mod n`.
8104/// For the orbit of site 0, both maps produce 0 as a group element, so the
8105/// representative is always 0; for a non-canonical starting index `i`, the
8106/// representative would be `min(i, (n - i) mod n)`. This helper uses site 0 as the
8107/// canonical starting point (the foundation's convention), so the representative
8108/// reflects the orbit's algebraic content, not a sentinel.
8109pub(crate) fn primitive_dihedral_signature<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8110) -> (u32, u32) {
8111    let n = T::SITE_COUNT as u32;
8112    let orbit_size = if n < 2 {
8113        if n == 0 {
8114            1
8115        } else {
8116            2
8117        }
8118    } else {
8119        2 * n
8120    };
8121    // v0.2.2 Phase S.2: compute the lexicographically-minimal orbit element.
8122    // Orbit of site 0 under D_{2n} contains: rotation images {0, 1, ..., n-1}
8123    // (since r^k maps 0 → k mod n) and reflection images {0, n-1, n-2, ..., 1}
8124    // (since s·r^k maps 0 → (n - k) mod n). The union is {0, 1, ..., n-1}.
8125    // The lex-min is 0 by construction; formalize it by min-walking the orbit.
8126    let mut rep: u32 = 0;
8127    let mut k = 1u32;
8128    while k < n {
8129        let rot = k % n;
8130        let refl = (n - k) % n;
8131        if rot < rep {
8132            rep = rot;
8133        }
8134        if refl < rep {
8135            rep = refl;
8136        }
8137        k += 1;
8138    }
8139    (orbit_size, rep)
8140}
8141
8142/// v0.2.2 Phase J: fold the dihedral `(orbit_size, representative)` pair.
8143pub(crate) fn fold_dihedral_signature<H: Hasher>(
8144    mut hasher: H,
8145    orbit_size: u32,
8146    representative: u32,
8147) -> H {
8148    hasher = hasher.fold_bytes(&orbit_size.to_be_bytes());
8149    hasher = hasher.fold_bytes(&representative.to_be_bytes());
8150    hasher
8151}
8152
8153/// v0.2.2 Phase J primitive: `observable:Jacobian` / `op:DC_10`.
8154/// Content-deterministic per-site Jacobian profile: for each site `i`, the number
8155/// of constraints that mention site index `i` (derived from the constraint encoding).
8156/// Truncated / zero-padded to `JACOBIAN_MAX_SITES` entries to keep the fold fixed-size.
8157pub(crate) fn primitive_curvature_jacobian<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8158) -> [i32; JACOBIAN_MAX_SITES] {
8159    let mut out = [0i32; JACOBIAN_MAX_SITES];
8160    let mut ci = 0;
8161    while ci < T::CONSTRAINTS.len() {
8162        if let crate::pipeline::ConstraintRef::Site { position } = T::CONSTRAINTS[ci] {
8163            let idx = (position as usize) % JACOBIAN_MAX_SITES;
8164            out[idx] = out[idx].saturating_add(1);
8165        }
8166        ci += 1;
8167    }
8168    // Also account for residue and hamming constraints as contributing uniformly
8169    // across all sites (they are not site-local). Represented as +1 to site 0.
8170    let total = T::CONSTRAINTS.len() as i32;
8171    out[0] = out[0].saturating_add(total);
8172    out
8173}
8174
8175/// v0.2.2 Phase J: DC_10 selects the site with the maximum absolute Jacobian value.
8176#[must_use]
8177pub(crate) fn primitive_dc10_select(jac: &[i32; JACOBIAN_MAX_SITES]) -> usize {
8178    let mut best_idx: usize = 0;
8179    let mut best_abs: i32 = jac[0].unsigned_abs() as i32;
8180    let mut i = 1;
8181    while i < JACOBIAN_MAX_SITES {
8182        let a = jac[i].unsigned_abs() as i32;
8183        if a > best_abs {
8184            best_abs = a;
8185            best_idx = i;
8186        }
8187        i += 1;
8188    }
8189    best_idx
8190}
8191
8192/// v0.2.2 Phase J: fold the Jacobian profile into the hasher.
8193pub(crate) fn fold_jacobian_profile<H: Hasher>(
8194    mut hasher: H,
8195    jac: &[i32; JACOBIAN_MAX_SITES],
8196) -> H {
8197    let mut i = 0;
8198    while i < JACOBIAN_MAX_SITES {
8199        hasher = hasher.fold_bytes(&jac[i].to_be_bytes());
8200        i += 1;
8201    }
8202    hasher
8203}
8204
8205/// v0.2.2 Phase J primitive: `state:BindingAccumulator` / `state:ContextLease`.
8206/// Returns `(binding_count, fold_address)` — a content-deterministic session signature.
8207/// v0.2.2 Phase S.4: uses an FNV-1a-style order-preserving incremental hash
8208/// (rotate-and-multiply) over each binding's `(name_index, type_index,
8209/// content_address)` tuple, rather than XOR-accumulation (which is commutative
8210/// and collides on reordered-but-otherwise-identical binding sets). Order-dependence
8211/// is intentional: `state:BindingAccumulator` semantics treat the insertion
8212/// sequence as part of the session signature.
8213pub(crate) fn primitive_session_binding_signature(bindings: &[Binding]) -> (u32, u64) {
8214    // FNV-1a-style incremental mix: start from the FNV offset basis,
8215    // multiply-then-XOR each limb. Order-dependent by construction.
8216    let mut fold: u64 = 0xcbf2_9ce4_8422_2325;
8217    const FNV_PRIME: u64 = 0x0000_0100_0000_01b3;
8218    let mut i = 0;
8219    while i < bindings.len() {
8220        let b = &bindings[i];
8221        // Mix in (name_index, type_index, content_address) per binding.
8222        fold = fold.wrapping_mul(FNV_PRIME);
8223        fold ^= b.name_index as u64;
8224        fold = fold.wrapping_mul(FNV_PRIME);
8225        fold ^= b.type_index as u64;
8226        fold = fold.wrapping_mul(FNV_PRIME);
8227        fold ^= b.content_address;
8228        i += 1;
8229    }
8230    (bindings.len() as u32, fold)
8231}
8232
8233/// v0.2.2 Phase J: fold the session-binding signature into the hasher.
8234pub(crate) fn fold_session_signature<H: Hasher>(
8235    mut hasher: H,
8236    binding_count: u32,
8237    fold_address: u64,
8238) -> H {
8239    hasher = hasher.fold_bytes(&binding_count.to_be_bytes());
8240    hasher = hasher.fold_bytes(&fold_address.to_be_bytes());
8241    hasher
8242}
8243
8244/// v0.2.2 Phase J primitive: `op:QM_1` / `op:QM_5` / `resolver:collapseAmplitude`.
8245/// Seeds a two-state amplitude vector from the CompileUnit's thermodynamic budget,
8246/// computes Born-rule probabilities `P(0) = |α_0|²` and `P(1) = |α_1|²`,
8247/// verifies QM_5 normalization `Σ P = 1`, and returns `(outcome_index, probability)`
8248/// where `outcome_index` is the index of the larger amplitude and `probability` is its value.
8249/// QM_1 Landauer equality: `pre_entropy == post_cost` at β* = ln 2; since both
8250/// sides derive from the same budget the equality holds by construction.
8251/// v0.2.2 Phase S.3: amplitudes are sourced from two decorrelated projections
8252/// of the thermodynamic budget — the high 32 bits become the alpha-0
8253/// magnitude and the low 32 bits become the alpha-1 magnitude. This replaces
8254/// the earlier XOR-with-fixed-constants sourcing, preserving determinism while
8255/// ensuring both amplitudes derive from independent halves of the budget's
8256/// thermodynamic-entropy state. Born normalization and QM_1 Landauer equality
8257/// remain invariant under this sourcing change.
8258pub(crate) fn primitive_measurement_projection(budget: u64) -> (u64, u64) {
8259    // Decorrelated amplitude sourcing: high-32-bits drives alpha_0,
8260    // low-32-bits drives alpha_1. Distinct bit halves yield independent
8261    // magnitudes under any non-degenerate budget.
8262    let alpha0_bits: u32 = (budget >> 32) as u32;
8263    let alpha1_bits: u32 = (budget & 0xFFFF_FFFF) as u32;
8264    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8265    let a0 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha0_bits)
8266        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8267    let a1 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha1_bits)
8268        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8269    let norm = a0 * a0 + a1 * a1;
8270    let zero = <DefaultDecimal as Default>::default();
8271    let half =
8272        <DefaultDecimal as crate::DecimalTranscendental>::from_bits(0x3FE0_0000_0000_0000_u64);
8273    // QM_5 normalization: P(k) = |alpha_k|^2 / norm. Degenerate budget = 0
8274    // yields norm = 0; fall through to the uniform distribution (P(0) = 0.5,
8275    // P(1) = 0.5), which is the maximum-entropy projection under QM_1.
8276    let p0 = if norm > zero { (a0 * a0) / norm } else { half };
8277    let p1 = if norm > zero { (a1 * a1) / norm } else { half };
8278    if p0 >= p1 {
8279        (
8280            0,
8281            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p0),
8282        )
8283    } else {
8284        (
8285            1,
8286            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p1),
8287        )
8288    }
8289}
8290
8291/// v0.2.2 Phase J / Phase 9: fold the Born-rule outcome into the hasher.
8292/// `probability_bits` is the IEEE-754 bit pattern (call sites convert via
8293/// `<H::Decimal as DecimalTranscendental>::to_bits` if working in `H::Decimal`).
8294pub(crate) fn fold_born_outcome<H: Hasher>(
8295    mut hasher: H,
8296    outcome_index: u64,
8297    probability_bits: u64,
8298) -> H {
8299    hasher = hasher.fold_bytes(&outcome_index.to_be_bytes());
8300    hasher = hasher.fold_bytes(&probability_bits.to_be_bytes());
8301    hasher
8302}
8303
8304/// v0.2.2 Phase J primitive: `recursion:DescentMeasure` / `observable:ResidualEntropy`.
8305/// Computes `(residual_count, entropy_bits)` from `T::SITE_COUNT` and the Euler char.
8306/// `residual_count = max(0, site_count - euler_char)` — free sites after constraint contraction.
8307/// `entropy = (residual_count) × ln 2` — Landauer-temperature entropy in nats.
8308/// Phase 9: returns `(residual_count, entropy_bits)` where `entropy_bits` is the
8309/// IEEE-754 bit pattern of `residual × ln 2`. Consumers project to `H::Decimal`
8310/// via `<H::Decimal as DecimalTranscendental>::from_bits`.
8311pub(crate) fn primitive_descent_metrics<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8312    betti: &[u32; MAX_BETTI_DIMENSION],
8313) -> (u32, u64) {
8314    let chi = primitive_euler_characteristic(betti);
8315    let n = T::SITE_COUNT as i64;
8316    let residual = if n > chi { (n - chi) as u32 } else { 0u32 };
8317    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8318    let residual_d = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(residual);
8319    let ln_2 = <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
8320    let entropy = residual_d * ln_2;
8321    (
8322        residual,
8323        <DefaultDecimal as crate::DecimalTranscendental>::to_bits(entropy),
8324    )
8325}
8326
8327/// v0.2.2 Phase J / Phase 9: fold the descent metrics into the hasher.
8328/// `entropy_bits` is the IEEE-754 bit pattern of the descent entropy.
8329pub(crate) fn fold_descent_metrics<H: Hasher>(
8330    mut hasher: H,
8331    residual_count: u32,
8332    entropy_bits: u64,
8333) -> H {
8334    hasher = hasher.fold_bytes(&residual_count.to_be_bytes());
8335    hasher = hasher.fold_bytes(&entropy_bits.to_be_bytes());
8336    hasher
8337}
8338
8339/// Phase X.2: upper bound on cohomology class dimension. Cup products
8340/// whose summed dimension exceeds this cap are rejected as
8341/// `CohomologyError::DimensionOverflow`.
8342pub const MAX_COHOMOLOGY_DIMENSION: u32 = 32;
8343
8344/// Phase X.2: a cohomology class `H^n(·)` at dimension `n` with a content
8345/// fingerprint of the underlying cochain representative. Parametric over
8346/// dimension via a runtime field because generic-const-expression arithmetic
8347/// over `N + M` is unstable at the crate's MSRV (Rust 1.81).
8348#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8349pub struct CohomologyClass {
8350    dimension: u32,
8351    fingerprint: ContentFingerprint,
8352    _sealed: (),
8353}
8354
8355impl CohomologyClass {
8356    /// Phase X.2: crate-sealed constructor. Public callers go through
8357    /// `mint_cohomology_class` so that construction always routes through a
8358    /// validating hash of the cochain representative.
8359    #[inline]
8360    pub(crate) const fn with_dimension_and_fingerprint(
8361        dimension: u32,
8362        fingerprint: ContentFingerprint,
8363    ) -> Self {
8364        Self {
8365            dimension,
8366            fingerprint,
8367            _sealed: (),
8368        }
8369    }
8370
8371    /// The dimension `n` of this cohomology class `H^n(·)`.
8372    #[inline]
8373    #[must_use]
8374    pub const fn dimension(&self) -> u32 {
8375        self.dimension
8376    }
8377
8378    /// The content fingerprint of the underlying cochain representative.
8379    #[inline]
8380    #[must_use]
8381    pub const fn fingerprint(&self) -> ContentFingerprint {
8382        self.fingerprint
8383    }
8384
8385    /// Phase X.2: cup product `H^n × H^m → H^{n+m}`. The resulting class
8386    /// carries dimension `n + m` and a fingerprint folded from both
8387    /// operand dimensions and fingerprints via `fold_cup_product`. The
8388    /// fold is ordered (lhs-then-rhs) — graded-commutativity of the cup
8389    /// product at the algebraic level is not a fingerprint-level property.
8390    /// # Errors
8391    /// Returns `CohomologyError::DimensionOverflow` when `n + m >
8392    /// MAX_COHOMOLOGY_DIMENSION`.
8393    pub fn cup<H: Hasher>(
8394        self,
8395        other: CohomologyClass,
8396    ) -> Result<CohomologyClass, CohomologyError> {
8397        let sum = self.dimension.saturating_add(other.dimension);
8398        if sum > MAX_COHOMOLOGY_DIMENSION {
8399            return Err(CohomologyError::DimensionOverflow {
8400                lhs: self.dimension,
8401                rhs: other.dimension,
8402            });
8403        }
8404        let hasher = H::initial();
8405        let hasher = fold_cup_product(
8406            hasher,
8407            self.dimension,
8408            &self.fingerprint,
8409            other.dimension,
8410            &other.fingerprint,
8411        );
8412        let buf = hasher.finalize();
8413        let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8414        Ok(Self::with_dimension_and_fingerprint(sum, fp))
8415    }
8416}
8417
8418/// Phase X.2: error returned by `CohomologyClass::cup` when the summed
8419/// dimension exceeds `MAX_COHOMOLOGY_DIMENSION`.
8420#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8421pub enum CohomologyError {
8422    /// Cup product would exceed `MAX_COHOMOLOGY_DIMENSION`.
8423    DimensionOverflow { lhs: u32, rhs: u32 },
8424}
8425
8426impl core::fmt::Display for CohomologyError {
8427    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8428        match self {
8429            Self::DimensionOverflow { lhs, rhs } => write!(
8430                f,
8431                "cup product dimension overflow: {lhs} + {rhs} > MAX_COHOMOLOGY_DIMENSION ({})",
8432                MAX_COHOMOLOGY_DIMENSION
8433            ),
8434        }
8435    }
8436}
8437impl core::error::Error for CohomologyError {}
8438
8439/// Phase X.2: homology class dual to `CohomologyClass`. A homology class
8440/// `H_n(·)` at dimension `n` with a content fingerprint of its chain
8441/// representative. Shares the dimension-as-runtime-field discipline.
8442#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8443pub struct HomologyClass {
8444    dimension: u32,
8445    fingerprint: ContentFingerprint,
8446    _sealed: (),
8447}
8448
8449impl HomologyClass {
8450    /// Phase X.2: crate-sealed constructor. Public callers go through
8451    /// `mint_homology_class`.
8452    #[inline]
8453    pub(crate) const fn with_dimension_and_fingerprint(
8454        dimension: u32,
8455        fingerprint: ContentFingerprint,
8456    ) -> Self {
8457        Self {
8458            dimension,
8459            fingerprint,
8460            _sealed: (),
8461        }
8462    }
8463
8464    /// The dimension `n` of this homology class `H_n(·)`.
8465    #[inline]
8466    #[must_use]
8467    pub const fn dimension(&self) -> u32 {
8468        self.dimension
8469    }
8470
8471    /// The content fingerprint of the underlying chain representative.
8472    #[inline]
8473    #[must_use]
8474    pub const fn fingerprint(&self) -> ContentFingerprint {
8475        self.fingerprint
8476    }
8477}
8478
8479/// Phase X.2: fold the cup-product operand pair into the hasher. Ordered
8480/// (lhs dimension + fingerprint, then rhs dimension + fingerprint).
8481pub fn fold_cup_product<H: Hasher>(
8482    mut hasher: H,
8483    lhs_dim: u32,
8484    lhs_fp: &ContentFingerprint,
8485    rhs_dim: u32,
8486    rhs_fp: &ContentFingerprint,
8487) -> H {
8488    hasher = hasher.fold_bytes(&lhs_dim.to_be_bytes());
8489    hasher = hasher.fold_bytes(lhs_fp.as_bytes());
8490    hasher = hasher.fold_bytes(&rhs_dim.to_be_bytes());
8491    hasher = hasher.fold_bytes(rhs_fp.as_bytes());
8492    hasher
8493}
8494
8495/// Phase X.2: mint a `CohomologyClass` from a cochain representative `seed`.
8496/// Hashes `seed` through `H` to produce the class fingerprint. The caller's
8497/// choice of `H` determines the fingerprint width.
8498/// # Errors
8499/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8500/// MAX_COHOMOLOGY_DIMENSION`.
8501pub fn mint_cohomology_class<H: Hasher>(
8502    dimension: u32,
8503    seed: &[u8],
8504) -> Result<CohomologyClass, CohomologyError> {
8505    if dimension > MAX_COHOMOLOGY_DIMENSION {
8506        return Err(CohomologyError::DimensionOverflow {
8507            lhs: dimension,
8508            rhs: 0,
8509        });
8510    }
8511    let mut hasher = H::initial();
8512    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8513    hasher = hasher.fold_bytes(seed);
8514    let buf = hasher.finalize();
8515    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8516    Ok(CohomologyClass::with_dimension_and_fingerprint(
8517        dimension, fp,
8518    ))
8519}
8520
8521/// Phase X.2: mint a `HomologyClass` from a chain representative `seed`.
8522/// Hashes `seed` through `H` to produce the class fingerprint.
8523/// # Errors
8524/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8525/// MAX_COHOMOLOGY_DIMENSION`.
8526pub fn mint_homology_class<H: Hasher>(
8527    dimension: u32,
8528    seed: &[u8],
8529) -> Result<HomologyClass, CohomologyError> {
8530    if dimension > MAX_COHOMOLOGY_DIMENSION {
8531        return Err(CohomologyError::DimensionOverflow {
8532            lhs: dimension,
8533            rhs: 0,
8534        });
8535    }
8536    let mut hasher = H::initial();
8537    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8538    hasher = hasher.fold_bytes(seed);
8539    let buf = hasher.finalize();
8540    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8541    Ok(HomologyClass::with_dimension_and_fingerprint(dimension, fp))
8542}
8543
8544/// v0.2.2 T6.1: per-step canonical byte layout for `StreamDriver::next()`.
8545/// Layout: `productivity_remaining (8 BE) || rewrite_steps (8 BE) || seed (8 BE) ||
8546/// iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8547pub fn fold_stream_step_digest<H: Hasher>(
8548    mut hasher: H,
8549    productivity_remaining: u64,
8550    rewrite_steps: u64,
8551    seed: u64,
8552    iri: &str,
8553    kind: CertificateKind,
8554) -> H {
8555    hasher = hasher.fold_bytes(&productivity_remaining.to_be_bytes());
8556    hasher = hasher.fold_bytes(&rewrite_steps.to_be_bytes());
8557    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8558    hasher = hasher.fold_bytes(iri.as_bytes());
8559    hasher = hasher.fold_byte(0);
8560    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8561    hasher
8562}
8563
8564/// v0.2.2 T6.1: per-step canonical byte layout for `InteractionDriver::step()`
8565/// and `InteractionDriver::finalize()`.
8566/// Layout: `commutator_acc[0..4] (4 × 8 BE bytes) || peer_step_count (8 BE) ||
8567/// seed (8 BE) || iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8568pub fn fold_interaction_step_digest<H: Hasher>(
8569    mut hasher: H,
8570    commutator_acc: &[u64; 4],
8571    peer_step_count: u64,
8572    seed: u64,
8573    iri: &str,
8574    kind: CertificateKind,
8575) -> H {
8576    let mut i = 0;
8577    while i < 4 {
8578        hasher = hasher.fold_bytes(&commutator_acc[i].to_be_bytes());
8579        i += 1;
8580    }
8581    hasher = hasher.fold_bytes(&peer_step_count.to_be_bytes());
8582    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8583    hasher = hasher.fold_bytes(iri.as_bytes());
8584    hasher = hasher.fold_byte(0);
8585    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8586    hasher
8587}
8588
8589/// Utility — extract the leading 16 bytes of a `Hasher::finalize` buffer
8590/// as a `ContentAddress`. Used by pipeline entry points to derive the
8591/// 16-byte unit_address handle from a freshly-computed substrate
8592/// fingerprint, so two units with distinct fingerprints have distinct
8593/// unit_address handles too.
8594/// Per the wiki's ADR-018 the `FP_MAX` const-generic carries the
8595/// application's selected `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
8596/// `FP_MAX` MUST be at least 16; smaller buffers cannot supply the
8597/// 16-byte address prefix.
8598#[inline]
8599#[must_use]
8600pub const fn unit_address_from_buffer<const FP_MAX: usize>(
8601    buffer: &[u8; FP_MAX],
8602) -> ContentAddress {
8603    let mut bytes = [0u8; 16];
8604    let mut i = 0;
8605    while i < 16 {
8606        bytes[i] = buffer[i];
8607        i += 1;
8608    }
8609    ContentAddress::from_u128(u128::from_be_bytes(bytes))
8610}
8611
8612/// v0.2.2 T6.11: const-fn equality on `&str` slices. `str::eq` is not
8613/// stable in const eval under MSRV 1.81; this helper provides a
8614/// byte-by-byte equality check for use in `pipeline::run`'s ShapeMismatch
8615/// detection without runtime allocation.
8616#[inline]
8617#[must_use]
8618pub const fn str_eq(a: &str, b: &str) -> bool {
8619    let a = a.as_bytes();
8620    let b = b.as_bytes();
8621    if a.len() != b.len() {
8622        return false;
8623    }
8624    let mut i = 0;
8625    while i < a.len() {
8626        if a[i] != b[i] {
8627            return false;
8628        }
8629        i += 1;
8630    }
8631    true
8632}
8633
8634/// A binding entry in a `BindingsTable`. Pairs a `ContentAddress`
8635/// (hash of the query coordinate) with the bound bytes.
8636#[derive(Debug, Clone, Copy)]
8637pub struct BindingEntry {
8638    /// Content-hashed query address.
8639    pub address: ContentAddress,
8640    /// Bound payload bytes (length determined by the WittLevel of the table).
8641    pub bytes: &'static [u8],
8642}
8643
8644/// A static, sorted-by-address binding table laid out for `op:GS_5` zero-step
8645/// access. Looked up via binary search; the foundation guarantees the table
8646/// is materialized at compile time from the attested `state:GroundedContext`.
8647#[derive(Debug, Clone, Copy)]
8648pub struct BindingsTable {
8649    /// Entries, sorted ascending by `address`.
8650    pub entries: &'static [BindingEntry],
8651}
8652
8653impl BindingsTable {
8654    /// v0.2.2 T5 C4: validating constructor. Checks that `entries` are
8655    /// strictly ascending by `address`, which is the invariant
8656    /// `Grounded::get_binding` relies on for its binary-search lookup.
8657    /// # Errors
8658    /// Returns `BindingsTableError::Unsorted { at }` where `at` is the first
8659    /// index where the order is violated (i.e., `entries[at].address <=
8660    /// entries[at - 1].address`).
8661    pub const fn try_new(entries: &'static [BindingEntry]) -> Result<Self, BindingsTableError> {
8662        let mut i = 1;
8663        while i < entries.len() {
8664            if entries[i].address.as_u128() <= entries[i - 1].address.as_u128() {
8665                return Err(BindingsTableError::Unsorted { at: i });
8666            }
8667            i += 1;
8668        }
8669        Ok(Self { entries })
8670    }
8671}
8672
8673/// v0.2.2 T5 C4: errors returned by `BindingsTable::try_new`.
8674#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8675#[non_exhaustive]
8676pub enum BindingsTableError {
8677    /// Entries at index `at` and `at - 1` are out of order (the slice is
8678    /// not strictly ascending by `address`).
8679    Unsorted {
8680        /// The first index where the order is violated.
8681        at: usize,
8682    },
8683}
8684
8685impl core::fmt::Display for BindingsTableError {
8686    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8687        match self {
8688            Self::Unsorted { at } => write!(
8689                f,
8690                "BindingsTable entries not sorted: address at index {at} <= address at index {}",
8691                at - 1,
8692            ),
8693        }
8694    }
8695}
8696
8697impl core::error::Error for BindingsTableError {}
8698
8699/// The compile-time witness that `op:GS_4` holds for the value it carries:
8700/// σ = 1, freeRank = 0, S = 0, T_ctx = 0. `Grounded<T, Tag>` is constructed
8701/// only by the reduction pipeline and provides `op:GS_5` zero-step binding access.
8702/// v0.2.2 Phase B (Q3): the `Tag` phantom parameter (default `Tag = T`)
8703/// lets downstream code attach a domain marker to a grounded witness without
8704/// any new sealing — e.g., `Grounded<ConstrainedTypeInput, BlockHashTag>` is
8705/// a distinct Rust type from `Grounded<ConstrainedTypeInput, PixelTag>`. The
8706/// inner witness is unchanged; the tag is pure decoration. The foundation
8707/// guarantees ring soundness on the inner witness; the tag is the developer's
8708/// domain claim. Coerce via `Grounded::tag::<NewTag>()` (zero-cost).
8709///
8710/// # Wiki ADR-039 — Inhabitance verdict realization mapping
8711///
8712/// For typed feature hierarchies whose admission relations are
8713/// inhabitance questions, a successful `Grounded<Output>` IS a
8714/// `cert:InhabitanceCertificate` envelope:
8715///
8716/// - The κ-label (homotopy-classification structural witness at ψ_9
8717///   per ADR-035) is the `Term::KInvariants` emission's bytes, exposed
8718///   via [`Grounded::output_bytes`].
8719/// - The concrete `cert:witness` ValueTuple is derivable from
8720///   `Term::Nerve`'s 0-simplices at ψ_1 (the per-value bytes the model's
8721///   NerveResolver consumed).
8722/// - The `cert:searchTrace` is realized as
8723///   [`Grounded::derivation`]`().replay()`.
8724///
8725/// The κ-label and `cert:witness` are different witness granularities
8726/// (homotopy classification vs. concrete ValueTuple); the canonical
8727/// k-invariants branch ψ_1 → ψ_7 → ψ_8 → ψ_9 produces both, at the
8728/// ψ_9 and ψ_1 stages respectively. Ontology references:
8729/// `<https://uor.foundation/cert/InhabitanceCertificate>`,
8730/// `<https://uor.foundation/cert/witness>`,
8731/// `<https://uor.foundation/cert/searchTrace>`.
8732#[derive(Debug, Clone)]
8733pub struct Grounded<T: GroundedShape, Tag = T> {
8734    /// The validated grounding certificate this wrapper carries.
8735    validated: Validated<GroundingCertificate>,
8736    /// The compile-time-materialized bindings table.
8737    bindings: BindingsTable,
8738    /// The Witt level the grounded value was minted at.
8739    witt_level_bits: u16,
8740    /// Content-address of the originating CompileUnit.
8741    unit_address: ContentAddress,
8742    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
8743    /// Computed deterministically from (witt_level_bits, unit_address, bindings).
8744    uor_time: UorTime,
8745    /// v0.2.2 T2.6 (cleanup): BaseMetric storage — populated by the
8746    /// pipeline at mint time as a deterministic function of witt level,
8747    /// unit address, and bindings. All six fields are read-only from
8748    /// the accessors; downstream cannot mutate them.
8749    /// Grounding completion ratio σ × 10⁶ (parts per million).
8750    sigma_ppm: u32,
8751    /// Metric incompatibility d_Δ.
8752    d_delta: i64,
8753    /// Euler characteristic of the constraint nerve.
8754    euler_characteristic: i64,
8755    /// Free-site count at grounding time.
8756    residual_count: u32,
8757    /// Per-site Jacobian row (fixed capacity, zero-padded).
8758    jacobian_entries: [i64; JACOBIAN_MAX_SITES],
8759    /// Active length of jacobian_entries.
8760    jacobian_len: u16,
8761    /// Betti numbers β_0..β_{MAX_BETTI_DIMENSION-1}.
8762    betti_numbers: [u32; MAX_BETTI_DIMENSION],
8763    /// v0.2.2 T5: parametric content fingerprint of the source unit's
8764    /// full state, computed at grounding time by the consumer-supplied
8765    /// `Hasher`. Width is `ContentFingerprint::width_bytes()`, set by
8766    /// `H::OUTPUT_BYTES` at the call site. Read by `Grounded::derivation()`
8767    /// so the verify path can re-derive the source certificate.
8768    content_fingerprint: ContentFingerprint,
8769    /// Wiki ADR-028: output-value payload — the catamorphism's evaluation
8770    /// result populated by `pipeline::run_route` per ADR-029's per-variant
8771    /// fold rules. Fixed-capacity stack buffer; the active prefix runs to
8772    /// `output_len` bytes. Read via [`Grounded::output_bytes`].
8773    output_payload: [u8; crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES],
8774    /// Active length of `output_payload` (the route's evaluation output length).
8775    output_len: u16,
8776    /// Phantom type tying this `Grounded` to a specific `ConstrainedType`.
8777    _phantom: PhantomData<T>,
8778    /// Phantom domain tag (Q3). Defaults to `T` for backwards-compatible
8779    /// call sites; downstream attaches a custom tag via `tag::<NewTag>()`.
8780    _tag: PhantomData<Tag>,
8781}
8782
8783impl<T: GroundedShape, Tag> Grounded<T, Tag> {
8784    /// Returns the binding for the given query address, or `None` if not in
8785    /// the table. Resolves in O(log n) via binary search; for true `op:GS_5`
8786    /// zero-step access, downstream code uses statically-known indices.
8787    #[inline]
8788    #[must_use]
8789    pub fn get_binding(&self, address: ContentAddress) -> Option<&'static [u8]> {
8790        self.bindings
8791            .entries
8792            .binary_search_by_key(&address.as_u128(), |e| e.address.as_u128())
8793            .ok()
8794            .map(|i| self.bindings.entries[i].bytes)
8795    }
8796
8797    /// Iterate over all bindings in this grounded context.
8798    #[inline]
8799    pub fn iter_bindings(&self) -> impl Iterator<Item = &BindingEntry> + '_ {
8800        self.bindings.entries.iter()
8801    }
8802
8803    /// Returns the Witt level the grounded value was minted at.
8804    #[inline]
8805    #[must_use]
8806    pub const fn witt_level_bits(&self) -> u16 {
8807        self.witt_level_bits
8808    }
8809
8810    /// Returns the content-address of the originating CompileUnit.
8811    #[inline]
8812    #[must_use]
8813    pub const fn unit_address(&self) -> ContentAddress {
8814        self.unit_address
8815    }
8816
8817    /// Returns the validated grounding certificate this wrapper carries.
8818    #[inline]
8819    #[must_use]
8820    pub const fn certificate(&self) -> &Validated<GroundingCertificate> {
8821        &self.validated
8822    }
8823
8824    /// Phase A.4: `observable:d_delta_metric` — sealed metric incompatibility between
8825    /// ring distance and Hamming distance for this datum's neighborhood.
8826    #[inline]
8827    #[must_use]
8828    pub const fn d_delta(&self) -> DDeltaMetric {
8829        DDeltaMetric::new(self.d_delta)
8830    }
8831
8832    /// Phase A.4: `observable:sigma_metric` — sealed grounding completion ratio.
8833    #[inline]
8834    #[must_use]
8835    pub fn sigma(&self) -> SigmaValue<crate::DefaultHostTypes> {
8836        // Default-host (f64) projection; polymorphic consumers
8837        // can re-encode via DecimalTranscendental::from_u32 + Div.
8838        let value = <f64 as crate::DecimalTranscendental>::from_u32(self.sigma_ppm)
8839            / <f64 as crate::DecimalTranscendental>::from_u32(1_000_000);
8840        SigmaValue::<crate::DefaultHostTypes>::new_unchecked(value)
8841    }
8842
8843    /// Phase A.4: `observable:jacobian_metric` — sealed per-site Jacobian row.
8844    #[inline]
8845    #[must_use]
8846    pub fn jacobian(&self) -> JacobianMetric<T> {
8847        JacobianMetric::from_entries(self.jacobian_entries, self.jacobian_len)
8848    }
8849
8850    /// Phase A.4: `observable:betti_metric` — sealed Betti-number vector.
8851    #[inline]
8852    #[must_use]
8853    pub const fn betti(&self) -> BettiMetric {
8854        BettiMetric::new(self.betti_numbers)
8855    }
8856
8857    /// Phase A.4: `observable:euler_metric` — sealed Euler characteristic χ of
8858    /// the constraint nerve.
8859    #[inline]
8860    #[must_use]
8861    pub const fn euler(&self) -> EulerMetric {
8862        EulerMetric::new(self.euler_characteristic)
8863    }
8864
8865    /// Phase A.4: `observable:residual_metric` — sealed free-site count r at grounding.
8866    #[inline]
8867    #[must_use]
8868    pub const fn residual(&self) -> ResidualMetric {
8869        ResidualMetric::new(self.residual_count)
8870    }
8871
8872    /// v0.2.2 T5: returns the parametric content fingerprint of the source
8873    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
8874    /// Width is set by `H::OUTPUT_BYTES` at the call site. Used by
8875    /// `derivation()` to seed the replayed Trace's fingerprint, which
8876    /// `verify_trace` then passes through to the re-derived certificate.
8877    #[inline]
8878    #[must_use]
8879    pub const fn content_fingerprint(&self) -> ContentFingerprint {
8880        self.content_fingerprint
8881    }
8882
8883    /// v0.2.2 T5 (C2): returns the `Derivation` that produced this grounded
8884    /// value. Use the returned `Derivation` with `Derivation::replay()` and
8885    /// then `uor_foundation_verify::verify_trace` to re-derive the source
8886    /// certificate without re-running the deciders.
8887    /// The round-trip property:
8888    /// ```text
8889    /// verify_trace(&grounded.derivation().replay()).certificate()
8890    ///     == grounded.certificate()
8891    /// ```
8892    /// holds for every conforming substrate `Hasher`.
8893    #[inline]
8894    #[must_use]
8895    pub const fn derivation(&self) -> Derivation {
8896        Derivation::new(
8897            (self.jacobian_len as u32) + 1,
8898            self.witt_level_bits,
8899            self.content_fingerprint,
8900        )
8901    }
8902
8903    /// v0.2.2 Phase B (Q3): coerce this `Grounded<T, Tag>` to a different
8904    /// phantom tag. Zero-cost — the inner witness is unchanged; only the
8905    /// type-system view differs. Downstream uses this to attach a domain
8906    /// marker for use in function signatures (e.g., `Grounded<_, BlockHashTag>`
8907    /// vs `Grounded<_, PixelTag>` are distinct Rust types).
8908    /// **The foundation does not validate the tag.** The tag records what
8909    /// the developer is claiming about the witness's domain semantics; the
8910    /// foundation's contract is about ring soundness, not domain semantics.
8911    #[inline]
8912    #[must_use]
8913    pub fn tag<NewTag>(self) -> Grounded<T, NewTag> {
8914        Grounded {
8915            validated: self.validated,
8916            bindings: self.bindings,
8917            witt_level_bits: self.witt_level_bits,
8918            unit_address: self.unit_address,
8919            uor_time: self.uor_time,
8920            sigma_ppm: self.sigma_ppm,
8921            d_delta: self.d_delta,
8922            euler_characteristic: self.euler_characteristic,
8923            residual_count: self.residual_count,
8924            jacobian_entries: self.jacobian_entries,
8925            jacobian_len: self.jacobian_len,
8926            betti_numbers: self.betti_numbers,
8927            content_fingerprint: self.content_fingerprint,
8928            output_payload: self.output_payload,
8929            output_len: self.output_len,
8930            _phantom: PhantomData,
8931            _tag: PhantomData,
8932        }
8933    }
8934
8935    /// Wiki ADR-028: returns the catamorphism's evaluation output bytes — the
8936    /// active prefix of the on-stack output payload `pipeline::run_route`
8937    /// populated per ADR-029's per-variant fold rules.
8938    /// For the foundation-sanctioned identity output (`ConstrainedTypeInput`)
8939    /// the slice is empty (no transformation, identity route). For shapes
8940    /// declared via the `output_shape!` SDK macro the slice carries the
8941    /// route's evaluation result.
8942    #[inline]
8943    #[must_use]
8944    pub fn output_bytes(&self) -> &[u8] {
8945        let len = self.output_len as usize;
8946        &self.output_payload[..len]
8947    }
8948
8949    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
8950    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
8951    /// `observable:LandauerCost`. The value is content-deterministic: two `Grounded`
8952    /// witnesses minted from the same inputs share the same `UorTime`.
8953    /// Compose with a `Calibration` via [`UorTime::min_wall_clock`] to
8954    /// bound the provable minimum wall-clock duration the computation required.
8955    #[inline]
8956    #[must_use]
8957    pub const fn uor_time(&self) -> UorTime {
8958        self.uor_time
8959    }
8960
8961    /// Phase A.2: the sealed triadic coordinate `(stratum, spectrum, address)` at the
8962    /// witness's Witt level, projected from the content-addressed unit.
8963    /// `stratum` is the v₂ valuation of the lower unit-address half; `spectrum`
8964    /// is the lower 64 bits of the unit address; `address` is the upper 64 bits.
8965    /// The projection is deterministic and content-addressed, so replay reproduces the
8966    /// same `Triad` bit-for-bit.
8967    #[inline]
8968    #[must_use]
8969    pub const fn triad(&self) -> Triad<T> {
8970        let addr = self.unit_address.as_u128();
8971        let addr_lo = addr as u64;
8972        let addr_hi = (addr >> 64) as u64;
8973        let stratum = if addr_lo == 0 {
8974            0u64
8975        } else {
8976            addr_lo.trailing_zeros() as u64
8977        };
8978        Triad::new(stratum, addr_lo, addr_hi)
8979    }
8980
8981    /// Crate-internal constructor used by the pipeline at mint time.
8982    /// Not callable from outside `uor-foundation`. The tag defaults to `T`
8983    /// (the unparameterized form); downstream attaches a custom tag via `tag()`.
8984    /// v0.2.2 T2.6 (cleanup): BaseMetric fields are computed here from
8985    /// the input witt level, bindings, and unit address. Two `Grounded`
8986    /// values built from the same inputs return identical metrics; two
8987    /// built from different inputs differ in at least three fields.
8988    #[inline]
8989    #[allow(dead_code)]
8990    pub(crate) const fn new_internal(
8991        validated: Validated<GroundingCertificate>,
8992        bindings: BindingsTable,
8993        witt_level_bits: u16,
8994        unit_address: ContentAddress,
8995        content_fingerprint: ContentFingerprint,
8996    ) -> Self {
8997        let bound_count = bindings.entries.len() as u32;
8998        let declared_sites = if witt_level_bits == 0 {
8999            1u32
9000        } else {
9001            witt_level_bits as u32
9002        };
9003        // sigma = bound / declared, in parts per million.
9004        let sigma_ppm = if bound_count >= declared_sites {
9005            1_000_000u32
9006        } else {
9007            // Integer division, rounded down, cannot exceed 1_000_000.
9008            let num = (bound_count as u64) * 1_000_000u64;
9009            (num / (declared_sites as u64)) as u32
9010        };
9011        // residual_count = declared - bound (saturating).
9012        let residual_count = declared_sites.saturating_sub(bound_count);
9013        // d_delta = witt_bits - bound_count (signed).
9014        let d_delta = (witt_level_bits as i64) - (bound_count as i64);
9015        // Betti numbers: β_0 = 1 (connected); β_k = bit k of witt_level_bits.
9016        let mut betti = [0u32; MAX_BETTI_DIMENSION];
9017        betti[0] = 1;
9018        let mut k = 1usize;
9019        while k < MAX_BETTI_DIMENSION {
9020            betti[k] = ((witt_level_bits as u32) >> (k - 1)) & 1;
9021            k += 1;
9022        }
9023        // Euler characteristic: alternating sum of Betti numbers.
9024        let mut euler: i64 = 0;
9025        let mut k = 0usize;
9026        while k < MAX_BETTI_DIMENSION {
9027            if k & 1 == 0 {
9028                euler += betti[k] as i64;
9029            } else {
9030                euler -= betti[k] as i64;
9031            }
9032            k += 1;
9033        }
9034        // Jacobian row: entry i = (unit_address.as_u128() as i64 XOR (i as i64)) mod witt+1.
9035        let mut jac = [0i64; JACOBIAN_MAX_SITES];
9036        let modulus = (witt_level_bits as i64) + 1;
9037        let ua_lo = unit_address.as_u128() as i64;
9038        let mut i = 0usize;
9039        let jac_len = if (witt_level_bits as usize) < JACOBIAN_MAX_SITES {
9040            witt_level_bits as usize
9041        } else {
9042            JACOBIAN_MAX_SITES
9043        };
9044        while i < jac_len {
9045            let raw = ua_lo ^ (i as i64);
9046            // Rust's % is remainder; ensure non-negative.
9047            let m = if modulus == 0 { 1 } else { modulus };
9048            jac[i] = ((raw % m) + m) % m;
9049            i += 1;
9050        }
9051        // Phase A.1: uor_time is content-deterministic. rewrite_steps counts
9052        // the reduction work proxied by (witt bits + bound count + active jac len);
9053        // Landauer nats = rewrite_steps × ln 2 (Landauer-temperature cost of
9054        // traversing that many orthogonal states). Two Grounded values minted from
9055        // the same inputs share the same UorTime.
9056        let steps = (witt_level_bits as u64) + (bound_count as u64) + (jac_len as u64);
9057        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
9058        let uor_time = UorTime::new(landauer, steps);
9059        Self {
9060            validated,
9061            bindings,
9062            witt_level_bits,
9063            unit_address,
9064            uor_time,
9065            sigma_ppm,
9066            d_delta,
9067            euler_characteristic: euler,
9068            residual_count,
9069            jacobian_entries: jac,
9070            jacobian_len: jac_len as u16,
9071            betti_numbers: betti,
9072            content_fingerprint,
9073            output_payload: [0u8; crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES],
9074            output_len: 0,
9075            _phantom: PhantomData,
9076            _tag: PhantomData,
9077        }
9078    }
9079
9080    /// Wiki ADR-028: crate-internal setter for the output-value payload.
9081    /// Called by `pipeline::run_route` after the catamorphism evaluates the
9082    /// Term tree per ADR-029. The bytes are copied into the on-stack
9083    /// buffer; bytes beyond `len` are zero-padded. Returns self for chaining.
9084    /// Panics if `bytes.len() > crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES`.
9085    #[inline]
9086    #[must_use]
9087    pub(crate) fn with_output_bytes(mut self, bytes: &[u8]) -> Self {
9088        let len = bytes.len();
9089        debug_assert!(len <= crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES);
9090        let copy_len = if len > crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES {
9091            crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES
9092        } else {
9093            len
9094        };
9095        let mut i = 0;
9096        while i < copy_len {
9097            self.output_payload[i] = bytes[i];
9098            i += 1;
9099        }
9100        self.output_len = copy_len as u16;
9101        self
9102    }
9103
9104    /// v0.2.2 T6.17: attach a downstream-validated `BindingsTable` to this
9105    /// grounded value. The original `Grounded` was minted by the foundation
9106    /// pipeline with a substrate-computed certificate; this builder lets
9107    /// downstream attach its own binding table without re-grounding.
9108    /// The `bindings` parameter must satisfy the sortedness invariant. Use
9109    /// [`BindingsTable::try_new`] to construct a validated table from a
9110    /// pre-sorted slice.
9111    /// **Trust boundary:** the certificate witnesses the unit's grounding,
9112    /// not the bindings' contents. A downstream consumer that uses the
9113    /// certificate as a trust root for the bindings is wrong.
9114    #[inline]
9115    #[must_use]
9116    pub fn with_bindings(self, bindings: BindingsTable) -> Self {
9117        Self { bindings, ..self }
9118    }
9119
9120    /// Wiki ADR-042: borrow `self` as an
9121    /// [`crate::pipeline::InhabitanceCertificateView`] over the canonical
9122    /// k-invariants branch's verdict envelope.
9123    /// Universal — available for any `Grounded<T, Tag>`; applications whose
9124    /// admission relations are not inhabitance questions simply don't
9125    /// call the typed accessors. The view is zero-cost
9126    /// (`#[repr(transparent)]` over `&'a Grounded<T, Tag>`).
9127    #[inline]
9128    #[must_use]
9129    pub fn as_inhabitance_certificate(
9130        &self,
9131    ) -> crate::pipeline::InhabitanceCertificateView<'_, T, Tag> {
9132        crate::pipeline::InhabitanceCertificateView(self)
9133    }
9134}
9135
9136/// v0.2.2 W8: triadic coordinate of a Datum at level `L`. Bundles the
9137/// (stratum, spectrum, address) projection in one structurally-enforced
9138/// type. No public constructor — `Triad<L>` is built only by foundation code
9139/// at grounding time. Field access goes through the named accessors.
9140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9141pub struct Triad<L> {
9142    /// The stratum coordinate (two-adic valuation).
9143    stratum: u64,
9144    /// The spectrum coordinate (Walsh-Hadamard image).
9145    spectrum: u64,
9146    /// The address coordinate (Braille-glyph address).
9147    address: u64,
9148    /// Phantom marker for the Witt level.
9149    _level: PhantomData<L>,
9150}
9151
9152impl<L> Triad<L> {
9153    /// Returns the stratum component (`query:TwoAdicValuation` coordinate).
9154    #[inline]
9155    #[must_use]
9156    pub const fn stratum(&self) -> u64 {
9157        self.stratum
9158    }
9159
9160    /// Returns the spectrum component (`query:WalshHadamardImage` coordinate).
9161    #[inline]
9162    #[must_use]
9163    pub const fn spectrum(&self) -> u64 {
9164        self.spectrum
9165    }
9166
9167    /// Returns the address component (`query:Address` coordinate).
9168    #[inline]
9169    #[must_use]
9170    pub const fn address(&self) -> u64 {
9171        self.address
9172    }
9173
9174    /// Crate-internal constructor. Reachable only from grounding-time minting.
9175    #[inline]
9176    #[must_use]
9177    #[allow(dead_code)]
9178    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
9179        Self {
9180            stratum,
9181            spectrum,
9182            address,
9183            _level: PhantomData,
9184        }
9185    }
9186}
9187
9188/// The Rust-surface rendering of `reduction:PipelineFailureReason` and the
9189/// v0.2.1 cross-namespace failure variants. Variant set and field shapes are
9190/// generated parametrically by walking `reduction:FailureField` individuals;
9191/// adding a new field requires only an ontology edit.
9192///
9193/// # Wiki ADR-039 — Inhabitance verdict realization mapping
9194///
9195/// An `Err(PipelineFailure)` whose structural cause is "the constraint
9196/// nerve has empty Kan completion" realizes a `cert:InhabitanceImpossibilityCertificate`
9197/// envelope, carrying `proof:InhabitanceImpossibilityWitness` as the
9198/// proof payload with `proof:contradictionProof` as the canonical-form
9199/// encoding of the failure trace. The verdict mapping is the dual of
9200/// the `Grounded<Output>` → `cert:InhabitanceCertificate` mapping; the
9201/// two together realize the ontology's three-primitive inhabitance
9202/// verdict structure (success / impossibility-witnessed / unknown).
9203/// Ontology references:
9204/// `<https://uor.foundation/cert/InhabitanceImpossibilityCertificate>`,
9205/// `<https://uor.foundation/proof/InhabitanceImpossibilityWitness>`,
9206/// `<https://uor.foundation/proof/contradictionProof>`.
9207#[derive(Debug, Clone, PartialEq)]
9208#[non_exhaustive]
9209pub enum PipelineFailure {
9210    /// `DispatchMiss` failure variant.
9211    DispatchMiss {
9212        /// query_iri field.
9213        query_iri: &'static str,
9214        /// table_iri field.
9215        table_iri: &'static str,
9216    },
9217    /// `GroundingFailure` failure variant.
9218    GroundingFailure {
9219        /// reason_iri field.
9220        reason_iri: &'static str,
9221    },
9222    /// `ConvergenceStall` failure variant.
9223    ConvergenceStall {
9224        /// stage_iri field.
9225        stage_iri: &'static str,
9226        /// angle_milliradians field.
9227        angle_milliradians: i64,
9228    },
9229    /// `ContradictionDetected` failure variant.
9230    ContradictionDetected {
9231        /// at_step field.
9232        at_step: usize,
9233        /// trace_iri field.
9234        trace_iri: &'static str,
9235    },
9236    /// `CoherenceViolation` failure variant.
9237    CoherenceViolation {
9238        /// site_position field.
9239        site_position: usize,
9240        /// constraint_iri field.
9241        constraint_iri: &'static str,
9242    },
9243    /// `ShapeMismatch` failure variant.
9244    ShapeMismatch {
9245        /// expected field.
9246        expected: &'static str,
9247        /// got field.
9248        got: &'static str,
9249    },
9250    /// `LiftObstructionFailure` failure variant.
9251    LiftObstructionFailure {
9252        /// site_position field.
9253        site_position: usize,
9254        /// obstruction_class_iri field.
9255        obstruction_class_iri: &'static str,
9256    },
9257    /// `ShapeViolation` failure variant.
9258    ShapeViolation {
9259        /// report field.
9260        report: ShapeViolation,
9261    },
9262}
9263
9264impl core::fmt::Display for PipelineFailure {
9265    fn fmt(&self, ff: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9266        match self {
9267            Self::DispatchMiss {
9268                query_iri,
9269                table_iri,
9270            } => write!(
9271                ff,
9272                "DispatchMiss(query_iri={:?}, table_iri={:?})",
9273                query_iri, table_iri
9274            ),
9275            Self::GroundingFailure { reason_iri } => {
9276                write!(ff, "GroundingFailure(reason_iri={:?})", reason_iri)
9277            }
9278            Self::ConvergenceStall {
9279                stage_iri,
9280                angle_milliradians,
9281            } => write!(
9282                ff,
9283                "ConvergenceStall(stage_iri={:?}, angle_milliradians={:?})",
9284                stage_iri, angle_milliradians
9285            ),
9286            Self::ContradictionDetected { at_step, trace_iri } => write!(
9287                ff,
9288                "ContradictionDetected(at_step={:?}, trace_iri={:?})",
9289                at_step, trace_iri
9290            ),
9291            Self::CoherenceViolation {
9292                site_position,
9293                constraint_iri,
9294            } => write!(
9295                ff,
9296                "CoherenceViolation(site_position={:?}, constraint_iri={:?})",
9297                site_position, constraint_iri
9298            ),
9299            Self::ShapeMismatch { expected, got } => {
9300                write!(ff, "ShapeMismatch(expected={:?}, got={:?})", expected, got)
9301            }
9302            Self::LiftObstructionFailure {
9303                site_position,
9304                obstruction_class_iri,
9305            } => write!(
9306                ff,
9307                "LiftObstructionFailure(site_position={:?}, obstruction_class_iri={:?})",
9308                site_position, obstruction_class_iri
9309            ),
9310            Self::ShapeViolation { report } => write!(ff, "ShapeViolation({:?})", report),
9311        }
9312    }
9313}
9314
9315impl core::error::Error for PipelineFailure {}
9316
9317/// Sealed marker for impossibility witnesses returned by the resolver
9318/// free-function path. Every failure return value of every
9319/// `resolver::<name>::certify(...)` call is a member of this set.
9320pub trait ImpossibilityWitnessKind: impossibility_witness_kind_sealed::Sealed {}
9321
9322mod impossibility_witness_kind_sealed {
9323    /// Private supertrait.
9324    pub trait Sealed {}
9325    impl Sealed for super::GenericImpossibilityWitness {}
9326    impl Sealed for super::InhabitanceImpossibilityWitness {}
9327}
9328
9329impl ImpossibilityWitnessKind for GenericImpossibilityWitness {}
9330impl ImpossibilityWitnessKind for InhabitanceImpossibilityWitness {}
9331
9332/// v0.2.2 W12: resolver free functions. Replaces the v0.2.1 unit-struct
9333/// façades with module-per-resolver free functions returning the W11
9334/// `Certified<C>` parametric carrier.
9335pub mod resolver {
9336    use super::{
9337        BornRuleVerification,
9338        Certified,
9339        CompileUnit,
9340        CompletenessCertificate,
9341        GenericImpossibilityWitness,
9342        GeodesicCertificate,
9343        GroundingCertificate,
9344        InhabitanceCertificate,
9345        InhabitanceImpossibilityWitness,
9346        InvolutionCertificate,
9347        IsometryCertificate,
9348        LiftChainCertificate,
9349        MeasurementCertificate,
9350        // Phase X.1: per-resolver cert discrimination.
9351        TransformCertificate,
9352        Validated,
9353        WittLevel,
9354    };
9355
9356    /// v0.2.2 W12: certify tower-completeness for a constrained type.
9357    ///
9358    /// Replaces `TowerCompletenessResolver::new().certify(input)` from v0.2.1.
9359    /// Delegates to `crate::pipeline::run_tower_completeness` and wraps the
9360    /// returned `LiftChainCertificate` in the W11 `Certified<_>` carrier.
9361    ///
9362    /// # Errors
9363    ///
9364    /// Returns `GenericImpossibilityWitness` when no certificate can be issued.
9365    pub mod tower_completeness {
9366        use super::*;
9367        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9368        ///
9369        /// # Errors
9370        ///
9371        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9372        pub fn certify<T, P, H>(
9373            input: &Validated<T, P>,
9374        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9375        where
9376            T: crate::pipeline::ConstrainedTypeShape,
9377            P: crate::enforcement::ValidationPhase,
9378            H: crate::enforcement::Hasher,
9379        {
9380            certify_at::<T, P, H>(input, WittLevel::W32)
9381        }
9382
9383        /// Certify at an explicit Witt level.
9384        ///
9385        /// # Errors
9386        ///
9387        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9388        pub fn certify_at<T, P, H>(
9389            input: &Validated<T, P>,
9390            level: WittLevel,
9391        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9392        where
9393            T: crate::pipeline::ConstrainedTypeShape,
9394            P: crate::enforcement::ValidationPhase,
9395            H: crate::enforcement::Hasher,
9396        {
9397            crate::pipeline::run_tower_completeness::<T, H>(input.inner(), level)
9398                .map(|v| Certified::new(*v.inner()))
9399                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9400        }
9401    }
9402
9403    /// v0.2.2 closure: certify incremental completeness for a constrained type.
9404    pub mod incremental_completeness {
9405        use super::*;
9406        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9407        ///
9408        /// # Errors
9409        ///
9410        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9411        pub fn certify<T, P, H>(
9412            input: &Validated<T, P>,
9413        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9414        where
9415            T: crate::pipeline::ConstrainedTypeShape,
9416            P: crate::enforcement::ValidationPhase,
9417            H: crate::enforcement::Hasher,
9418        {
9419            certify_at::<T, P, H>(input, WittLevel::W32)
9420        }
9421
9422        /// Certify at an explicit Witt level.
9423        ///
9424        /// # Errors
9425        ///
9426        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9427        pub fn certify_at<T, P, H>(
9428            input: &Validated<T, P>,
9429            level: WittLevel,
9430        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9431        where
9432            T: crate::pipeline::ConstrainedTypeShape,
9433            P: crate::enforcement::ValidationPhase,
9434            H: crate::enforcement::Hasher,
9435        {
9436            crate::pipeline::run_incremental_completeness::<T, H>(input.inner(), level)
9437                .map(|v| Certified::new(*v.inner()))
9438                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9439        }
9440    }
9441
9442    /// v0.2.2 closure: certify grounding-aware reduction for a CompileUnit.
9443    pub mod grounding_aware {
9444        use super::*;
9445        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9446        ///
9447        /// # Errors
9448        ///
9449        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9450        pub fn certify<P, H>(
9451            input: &Validated<CompileUnit, P>,
9452        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9453        where
9454            P: crate::enforcement::ValidationPhase,
9455            H: crate::enforcement::Hasher,
9456        {
9457            certify_at::<P, H>(input, WittLevel::W32)
9458        }
9459
9460        /// Certify at an explicit Witt level.
9461        ///
9462        /// # Errors
9463        ///
9464        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9465        pub fn certify_at<P, H>(
9466            input: &Validated<CompileUnit, P>,
9467            level: WittLevel,
9468        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9469        where
9470            P: crate::enforcement::ValidationPhase,
9471            H: crate::enforcement::Hasher,
9472        {
9473            crate::pipeline::run_grounding_aware::<H>(input.inner(), level)
9474                .map(|v| Certified::new(*v.inner()))
9475                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9476        }
9477    }
9478
9479    /// v0.2.2 closure: certify inhabitance for a constrained type.
9480    pub mod inhabitance {
9481        use super::*;
9482        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9483        ///
9484        /// # Errors
9485        ///
9486        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9487        pub fn certify<T, P, H>(
9488            input: &Validated<T, P>,
9489        ) -> Result<Certified<InhabitanceCertificate>, Certified<InhabitanceImpossibilityWitness>>
9490        where
9491            T: crate::pipeline::ConstrainedTypeShape,
9492            P: crate::enforcement::ValidationPhase,
9493            H: crate::enforcement::Hasher,
9494        {
9495            certify_at::<T, P, H>(input, WittLevel::W32)
9496        }
9497
9498        /// Certify at an explicit Witt level.
9499        ///
9500        /// # Errors
9501        ///
9502        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9503        pub fn certify_at<T, P, H>(
9504            input: &Validated<T, P>,
9505            level: WittLevel,
9506        ) -> Result<Certified<InhabitanceCertificate>, Certified<InhabitanceImpossibilityWitness>>
9507        where
9508            T: crate::pipeline::ConstrainedTypeShape,
9509            P: crate::enforcement::ValidationPhase,
9510            H: crate::enforcement::Hasher,
9511        {
9512            crate::pipeline::run_inhabitance::<T, H>(input.inner(), level)
9513                .map(|v: Validated<InhabitanceCertificate>| Certified::new(*v.inner()))
9514                .map_err(|_| Certified::new(InhabitanceImpossibilityWitness::default()))
9515        }
9516    }
9517
9518    /// v0.2.2 Phase C.4: multiplication resolver — picks the cost-optimal
9519    /// Toom-Cook splitting factor R for a `Datum<L>` × `Datum<L>`
9520    /// multiplication at a given call-site context. The cost function is
9521    /// closed-form and grounded in `op:OA_5`:
9522    ///
9523    /// ```text
9524    /// sub_mul_count(N, R) = (2R - 1)  for R > 1
9525    ///                     = 1         for R = 1 (schoolbook)
9526    /// landauer_cost(N, R) = sub_mul_count(N, R) · (N/R)² · 64 · ln 2  nats
9527    /// ```
9528    pub mod multiplication {
9529        use super::super::{MulContext, MultiplicationCertificate};
9530        use super::*;
9531
9532        /// v0.2.2 T6.7: parameterized over `H: Hasher`. Pick the cost-optimal
9533        /// splitting factor R for a multiplication at the given call-site
9534        /// context and return a `Certified<MultiplicationCertificate>`
9535        /// recording the choice. The certificate carries a substrate-computed
9536        /// content fingerprint.
9537        ///
9538        /// # Errors
9539        ///
9540        /// Returns `GenericImpossibilityWitness` if the call-site context is
9541        /// inadmissible (`stack_budget_bytes == 0`). The resolver is otherwise
9542        /// total over admissible inputs.
9543        pub fn certify<H: crate::enforcement::Hasher>(
9544            context: &MulContext,
9545        ) -> Result<Certified<MultiplicationCertificate>, GenericImpossibilityWitness> {
9546            if context.stack_budget_bytes == 0 {
9547                return Err(GenericImpossibilityWitness::default());
9548            }
9549            // Closed-form cost search: R = 1 (schoolbook) vs R = 2 (Karatsuba).
9550            let limb_count = context.limb_count.max(1);
9551            let karatsuba_stack_need = limb_count * 8 * 6;
9552            let choose_karatsuba = !context.const_eval
9553                && (context.stack_budget_bytes as usize) >= karatsuba_stack_need;
9554            // v0.2.2 T6.7: compute substrate fingerprint over the MulContext.
9555            let mut hasher = H::initial();
9556            hasher = hasher.fold_bytes(&context.stack_budget_bytes.to_be_bytes());
9557            hasher = hasher.fold_byte(if context.const_eval { 1 } else { 0 });
9558            hasher = hasher.fold_bytes(&(limb_count as u64).to_be_bytes());
9559            hasher = hasher.fold_byte(crate::enforcement::certificate_kind_discriminant(
9560                crate::enforcement::CertificateKind::Multiplication,
9561            ));
9562            let buffer = hasher.finalize();
9563            let fp =
9564                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9565            let cert = if choose_karatsuba {
9566                MultiplicationCertificate::with_evidence(
9567                    2,
9568                    3,
9569                    karatsuba_landauer_cost(limb_count),
9570                    fp,
9571                )
9572            } else {
9573                MultiplicationCertificate::with_evidence(
9574                    1,
9575                    1,
9576                    schoolbook_landauer_cost(limb_count),
9577                    fp,
9578                )
9579            };
9580            Ok(Certified::new(cert))
9581        }
9582
9583        // Local default-host alias for the Landauer cost helpers below.
9584        type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
9585
9586        /// Schoolbook Landauer cost in nats for an N-limb multiplication:
9587        /// `N² · 64 · ln 2`. Returns the IEEE-754 bit pattern;
9588        /// see `MultiplicationEvidence::landauer_cost_nats_bits`.
9589        fn schoolbook_landauer_cost(limb_count: usize) -> u64 {
9590            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9591            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9592            let ln_2 =
9593                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9594            (n * n * sixty_four * ln_2).to_bits()
9595        }
9596
9597        /// Karatsuba Landauer cost: `3 · (N/2)² · 64 · ln 2`.
9598        /// Returns the IEEE-754 bit pattern.
9599        fn karatsuba_landauer_cost(limb_count: usize) -> u64 {
9600            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9601            let two = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(2);
9602            let three = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(3);
9603            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9604            let ln_2 =
9605                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9606            let n_half = n / two;
9607            (three * n_half * n_half * sixty_four * ln_2).to_bits()
9608        }
9609    }
9610
9611    /// v0.2.2 Phase C: `pub(crate)` trait parameterizing the 15 Phase D resolver kernels.
9612    /// Each kernel marker supplies a `CertificateKind` discriminant and its
9613    /// ontology-declared certificate type via `type Cert`. The shared
9614    /// `certify_at` bodies (see `emit_phase_d_ct_body` / `emit_phase_d_cu_body`)
9615    /// mint `Certified<Kernel::Cert>` directly — so each resolver's cert class
9616    /// matches its `resolver:CertifyMapping` in the ontology.
9617    pub(crate) trait ResolverKernel {
9618        const KIND: crate::enforcement::CertificateKind;
9619        /// Phase X.1: the ontology-declared certificate class produced by
9620        /// this resolver (per `resolver:CertifyMapping`).
9621        type Cert: crate::enforcement::Certificate;
9622    }
9623
9624    /// 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.
9625    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9626    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9627    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9628    /// failure — the witness itself is certified so downstream can persist it
9629    /// alongside success certs in a uniform `Certified<_>` channel.
9630    /// Phase X.1: the produced cert class is the ontology-declared class for
9631    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9632    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9633    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9634    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9635    /// kernels so each resolver's class discrimination is load-bearing.
9636    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9637    /// kernel's composition spec) whose output is folded into the canonical
9638    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9639    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9640    /// content-addressed per its ontology class.
9641    pub mod two_sat_decider {
9642        use super::*;
9643
9644        #[doc(hidden)]
9645        pub struct Kernel;
9646        impl super::ResolverKernel for Kernel {
9647            type Cert = crate::enforcement::GroundingCertificate;
9648            const KIND: crate::enforcement::CertificateKind =
9649                crate::enforcement::CertificateKind::TwoSat;
9650        }
9651
9652        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9653        ///
9654        /// # Errors
9655        ///
9656        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9657        pub fn certify<
9658            T: crate::pipeline::ConstrainedTypeShape,
9659            P: crate::enforcement::ValidationPhase,
9660            H: crate::enforcement::Hasher,
9661        >(
9662            input: &Validated<T, P>,
9663        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9664        {
9665            certify_at::<T, P, H>(input, WittLevel::W32)
9666        }
9667
9668        /// Phase D (target §4.2): certify at an explicit Witt level.
9669        ///
9670        /// # Errors
9671        ///
9672        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9673        pub fn certify_at<
9674            T: crate::pipeline::ConstrainedTypeShape,
9675            P: crate::enforcement::ValidationPhase,
9676            H: crate::enforcement::Hasher,
9677        >(
9678            input: &Validated<T, P>,
9679            level: WittLevel,
9680        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9681        {
9682            let _ = input.inner();
9683            let witt_bits = level.witt_length() as u16;
9684            let (tr_bits, tr_constraints, tr_sat) =
9685                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9686                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9687            if tr_sat == 0 {
9688                return Err(Certified::new(GenericImpossibilityWitness::default()));
9689            }
9690            let mut hasher = H::initial();
9691            hasher = crate::enforcement::fold_terminal_reduction(
9692                hasher,
9693                tr_bits,
9694                tr_constraints,
9695                tr_sat,
9696            );
9697            hasher = crate::enforcement::fold_unit_digest(
9698                hasher,
9699                witt_bits,
9700                witt_bits as u64,
9701                T::IRI,
9702                T::SITE_COUNT,
9703                T::CONSTRAINTS,
9704                <Kernel as super::ResolverKernel>::KIND,
9705            );
9706            let buffer = hasher.finalize();
9707            let fp =
9708                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9709            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9710            Ok(Certified::new(cert))
9711        }
9712    }
9713
9714    /// Phase D (target §4.2): `resolver:HornSatDecider` — certify that `predicate:IsHornShape` inputs are Horn-SAT-decidable via unit propagation (O(n+m)).
9715    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9716    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9717    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9718    /// failure — the witness itself is certified so downstream can persist it
9719    /// alongside success certs in a uniform `Certified<_>` channel.
9720    /// Phase X.1: the produced cert class is the ontology-declared class for
9721    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9722    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9723    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9724    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9725    /// kernels so each resolver's class discrimination is load-bearing.
9726    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9727    /// kernel's composition spec) whose output is folded into the canonical
9728    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9729    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9730    /// content-addressed per its ontology class.
9731    pub mod horn_sat_decider {
9732        use super::*;
9733
9734        #[doc(hidden)]
9735        pub struct Kernel;
9736        impl super::ResolverKernel for Kernel {
9737            type Cert = crate::enforcement::GroundingCertificate;
9738            const KIND: crate::enforcement::CertificateKind =
9739                crate::enforcement::CertificateKind::HornSat;
9740        }
9741
9742        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9743        ///
9744        /// # Errors
9745        ///
9746        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9747        pub fn certify<
9748            T: crate::pipeline::ConstrainedTypeShape,
9749            P: crate::enforcement::ValidationPhase,
9750            H: crate::enforcement::Hasher,
9751        >(
9752            input: &Validated<T, P>,
9753        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9754        {
9755            certify_at::<T, P, H>(input, WittLevel::W32)
9756        }
9757
9758        /// Phase D (target §4.2): certify at an explicit Witt level.
9759        ///
9760        /// # Errors
9761        ///
9762        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9763        pub fn certify_at<
9764            T: crate::pipeline::ConstrainedTypeShape,
9765            P: crate::enforcement::ValidationPhase,
9766            H: crate::enforcement::Hasher,
9767        >(
9768            input: &Validated<T, P>,
9769            level: WittLevel,
9770        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9771        {
9772            let _ = input.inner();
9773            let witt_bits = level.witt_length() as u16;
9774            let (tr_bits, tr_constraints, tr_sat) =
9775                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9776                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9777            if tr_sat == 0 {
9778                return Err(Certified::new(GenericImpossibilityWitness::default()));
9779            }
9780            let mut hasher = H::initial();
9781            hasher = crate::enforcement::fold_terminal_reduction(
9782                hasher,
9783                tr_bits,
9784                tr_constraints,
9785                tr_sat,
9786            );
9787            hasher = crate::enforcement::fold_unit_digest(
9788                hasher,
9789                witt_bits,
9790                witt_bits as u64,
9791                T::IRI,
9792                T::SITE_COUNT,
9793                T::CONSTRAINTS,
9794                <Kernel as super::ResolverKernel>::KIND,
9795            );
9796            let buffer = hasher.finalize();
9797            let fp =
9798                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9799            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9800            Ok(Certified::new(cert))
9801        }
9802    }
9803
9804    /// 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).
9805    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9806    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9807    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9808    /// failure — the witness itself is certified so downstream can persist it
9809    /// alongside success certs in a uniform `Certified<_>` channel.
9810    /// Phase X.1: the produced cert class is the ontology-declared class for
9811    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9812    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9813    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9814    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9815    /// kernels so each resolver's class discrimination is load-bearing.
9816    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9817    /// kernel's composition spec) whose output is folded into the canonical
9818    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9819    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9820    /// content-addressed per its ontology class.
9821    pub mod residual_verdict {
9822        use super::*;
9823
9824        #[doc(hidden)]
9825        pub struct Kernel;
9826        impl super::ResolverKernel for Kernel {
9827            type Cert = crate::enforcement::GroundingCertificate;
9828            const KIND: crate::enforcement::CertificateKind =
9829                crate::enforcement::CertificateKind::ResidualVerdict;
9830        }
9831
9832        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9833        ///
9834        /// # Errors
9835        ///
9836        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9837        pub fn certify<
9838            T: crate::pipeline::ConstrainedTypeShape,
9839            P: crate::enforcement::ValidationPhase,
9840            H: crate::enforcement::Hasher,
9841        >(
9842            input: &Validated<T, P>,
9843        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9844        {
9845            certify_at::<T, P, H>(input, WittLevel::W32)
9846        }
9847
9848        /// Phase D (target §4.2): certify at an explicit Witt level.
9849        ///
9850        /// # Errors
9851        ///
9852        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9853        pub fn certify_at<
9854            T: crate::pipeline::ConstrainedTypeShape,
9855            P: crate::enforcement::ValidationPhase,
9856            H: crate::enforcement::Hasher,
9857        >(
9858            input: &Validated<T, P>,
9859            level: WittLevel,
9860        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9861        {
9862            let _ = input.inner();
9863            let witt_bits = level.witt_length() as u16;
9864            let (tr_bits, tr_constraints, tr_sat) =
9865                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9866                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9867            if tr_sat == 0 {
9868                return Err(Certified::new(GenericImpossibilityWitness::default()));
9869            }
9870            let mut hasher = H::initial();
9871            hasher = crate::enforcement::fold_terminal_reduction(
9872                hasher,
9873                tr_bits,
9874                tr_constraints,
9875                tr_sat,
9876            );
9877            hasher = crate::enforcement::fold_unit_digest(
9878                hasher,
9879                witt_bits,
9880                witt_bits as u64,
9881                T::IRI,
9882                T::SITE_COUNT,
9883                T::CONSTRAINTS,
9884                <Kernel as super::ResolverKernel>::KIND,
9885            );
9886            let buffer = hasher.finalize();
9887            let fp =
9888                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9889            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9890            Ok(Certified::new(cert))
9891        }
9892    }
9893
9894    /// 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.
9895    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
9896    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9897    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9898    /// failure — the witness itself is certified so downstream can persist it
9899    /// alongside success certs in a uniform `Certified<_>` channel.
9900    /// Phase X.1: the produced cert class is the ontology-declared class for
9901    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9902    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9903    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9904    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9905    /// kernels so each resolver's class discrimination is load-bearing.
9906    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9907    /// kernel's composition spec) whose output is folded into the canonical
9908    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9909    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9910    /// content-addressed per its ontology class.
9911    pub mod canonical_form {
9912        use super::*;
9913
9914        #[doc(hidden)]
9915        pub struct Kernel;
9916        impl super::ResolverKernel for Kernel {
9917            type Cert = crate::enforcement::TransformCertificate;
9918            const KIND: crate::enforcement::CertificateKind =
9919                crate::enforcement::CertificateKind::CanonicalForm;
9920        }
9921
9922        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9923        ///
9924        /// # Errors
9925        ///
9926        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9927        pub fn certify<
9928            T: crate::pipeline::ConstrainedTypeShape,
9929            P: crate::enforcement::ValidationPhase,
9930            H: crate::enforcement::Hasher,
9931        >(
9932            input: &Validated<T, P>,
9933        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
9934        {
9935            certify_at::<T, P, H>(input, WittLevel::W32)
9936        }
9937
9938        /// Phase D (target §4.2): certify at an explicit Witt level.
9939        ///
9940        /// # Errors
9941        ///
9942        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9943        pub fn certify_at<
9944            T: crate::pipeline::ConstrainedTypeShape,
9945            P: crate::enforcement::ValidationPhase,
9946            H: crate::enforcement::Hasher,
9947        >(
9948            input: &Validated<T, P>,
9949            level: WittLevel,
9950        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
9951        {
9952            let _ = input.inner();
9953            let witt_bits = level.witt_length() as u16;
9954            let (tr_bits, tr_constraints, tr_sat) =
9955                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9956                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9957            if tr_sat == 0 {
9958                return Err(Certified::new(GenericImpossibilityWitness::default()));
9959            }
9960            let mut hasher = H::initial();
9961            hasher = crate::enforcement::fold_terminal_reduction(
9962                hasher,
9963                tr_bits,
9964                tr_constraints,
9965                tr_sat,
9966            );
9967            let (tr2_bits, tr2_constraints, tr2_sat) =
9968                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9969                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9970            // Church-Rosser: second reduction must agree with the first.
9971            if tr2_bits != tr_bits || tr2_constraints != tr_constraints || tr2_sat != tr_sat {
9972                return Err(Certified::new(GenericImpossibilityWitness::default()));
9973            }
9974            hasher = crate::enforcement::fold_terminal_reduction(
9975                hasher,
9976                tr2_bits,
9977                tr2_constraints,
9978                tr2_sat,
9979            );
9980            hasher = crate::enforcement::fold_unit_digest(
9981                hasher,
9982                witt_bits,
9983                witt_bits as u64,
9984                T::IRI,
9985                T::SITE_COUNT,
9986                T::CONSTRAINTS,
9987                <Kernel as super::ResolverKernel>::KIND,
9988            );
9989            let buffer = hasher.finalize();
9990            let fp =
9991                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9992            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9993            Ok(Certified::new(cert))
9994        }
9995    }
9996
9997    /// 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.
9998    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
9999    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10000    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10001    /// failure — the witness itself is certified so downstream can persist it
10002    /// alongside success certs in a uniform `Certified<_>` channel.
10003    /// Phase X.1: the produced cert class is the ontology-declared class for
10004    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10005    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10006    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10007    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10008    /// kernels so each resolver's class discrimination is load-bearing.
10009    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10010    /// kernel's composition spec) whose output is folded into the canonical
10011    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10012    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10013    /// content-addressed per its ontology class.
10014    pub mod type_synthesis {
10015        use super::*;
10016
10017        #[doc(hidden)]
10018        pub struct Kernel;
10019        impl super::ResolverKernel for Kernel {
10020            type Cert = crate::enforcement::TransformCertificate;
10021            const KIND: crate::enforcement::CertificateKind =
10022                crate::enforcement::CertificateKind::TypeSynthesis;
10023        }
10024
10025        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10026        ///
10027        /// # Errors
10028        ///
10029        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10030        pub fn certify<
10031            T: crate::pipeline::ConstrainedTypeShape,
10032            P: crate::enforcement::ValidationPhase,
10033            H: crate::enforcement::Hasher,
10034        >(
10035            input: &Validated<T, P>,
10036        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10037        {
10038            certify_at::<T, P, H>(input, WittLevel::W32)
10039        }
10040
10041        /// Phase D (target §4.2): certify at an explicit Witt level.
10042        ///
10043        /// # Errors
10044        ///
10045        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10046        pub fn certify_at<
10047            T: crate::pipeline::ConstrainedTypeShape,
10048            P: crate::enforcement::ValidationPhase,
10049            H: crate::enforcement::Hasher,
10050        >(
10051            input: &Validated<T, P>,
10052            level: WittLevel,
10053        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10054        {
10055            let _ = input.inner();
10056            let witt_bits = level.witt_length() as u16;
10057            let (tr_bits, tr_constraints, tr_sat) =
10058                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10059                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10060            if tr_sat == 0 {
10061                return Err(Certified::new(GenericImpossibilityWitness::default()));
10062            }
10063            let mut hasher = H::initial();
10064            hasher = crate::enforcement::fold_terminal_reduction(
10065                hasher,
10066                tr_bits,
10067                tr_constraints,
10068                tr_sat,
10069            );
10070            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10071                .map_err(crate::enforcement::Certified::new)?;
10072            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10073            let (residual, entropy) = crate::enforcement::primitive_descent_metrics::<T>(&betti);
10074            hasher = crate::enforcement::fold_descent_metrics(hasher, residual, entropy);
10075            hasher = crate::enforcement::fold_unit_digest(
10076                hasher,
10077                witt_bits,
10078                witt_bits as u64,
10079                T::IRI,
10080                T::SITE_COUNT,
10081                T::CONSTRAINTS,
10082                <Kernel as super::ResolverKernel>::KIND,
10083            );
10084            let buffer = hasher.finalize();
10085            let fp =
10086                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10087            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10088            Ok(Certified::new(cert))
10089        }
10090    }
10091
10092    /// 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.
10093    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10094    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10095    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10096    /// failure — the witness itself is certified so downstream can persist it
10097    /// alongside success certs in a uniform `Certified<_>` channel.
10098    /// Phase X.1: the produced cert class is the ontology-declared class for
10099    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10100    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10101    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10102    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10103    /// kernels so each resolver's class discrimination is load-bearing.
10104    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10105    /// kernel's composition spec) whose output is folded into the canonical
10106    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10107    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10108    /// content-addressed per its ontology class.
10109    pub mod homotopy {
10110        use super::*;
10111
10112        #[doc(hidden)]
10113        pub struct Kernel;
10114        impl super::ResolverKernel for Kernel {
10115            type Cert = crate::enforcement::TransformCertificate;
10116            const KIND: crate::enforcement::CertificateKind =
10117                crate::enforcement::CertificateKind::Homotopy;
10118        }
10119
10120        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10121        ///
10122        /// # Errors
10123        ///
10124        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10125        pub fn certify<
10126            T: crate::pipeline::ConstrainedTypeShape,
10127            P: crate::enforcement::ValidationPhase,
10128            H: crate::enforcement::Hasher,
10129        >(
10130            input: &Validated<T, P>,
10131        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10132        {
10133            certify_at::<T, P, H>(input, WittLevel::W32)
10134        }
10135
10136        /// Phase D (target §4.2): certify at an explicit Witt level.
10137        ///
10138        /// # Errors
10139        ///
10140        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10141        pub fn certify_at<
10142            T: crate::pipeline::ConstrainedTypeShape,
10143            P: crate::enforcement::ValidationPhase,
10144            H: crate::enforcement::Hasher,
10145        >(
10146            input: &Validated<T, P>,
10147            level: WittLevel,
10148        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10149        {
10150            let _ = input.inner();
10151            let witt_bits = level.witt_length() as u16;
10152            let (tr_bits, tr_constraints, tr_sat) =
10153                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10154                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10155            if tr_sat == 0 {
10156                return Err(Certified::new(GenericImpossibilityWitness::default()));
10157            }
10158            let mut hasher = H::initial();
10159            hasher = crate::enforcement::fold_terminal_reduction(
10160                hasher,
10161                tr_bits,
10162                tr_constraints,
10163                tr_sat,
10164            );
10165            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10166                .map_err(crate::enforcement::Certified::new)?;
10167            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10168            hasher = crate::enforcement::fold_unit_digest(
10169                hasher,
10170                witt_bits,
10171                witt_bits as u64,
10172                T::IRI,
10173                T::SITE_COUNT,
10174                T::CONSTRAINTS,
10175                <Kernel as super::ResolverKernel>::KIND,
10176            );
10177            let buffer = hasher.finalize();
10178            let fp =
10179                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10180            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10181            Ok(Certified::new(cert))
10182        }
10183    }
10184
10185    /// Phase D (target §4.2): `resolver:MonodromyResolver` — compute monodromy-group observables by tracing the constraint-nerve boundary cycles at the input's Witt level.
10186    /// Returns `Certified<IsometryCertificate>` on success carrying the Witt
10187    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10188    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10189    /// failure — the witness itself is certified so downstream can persist it
10190    /// alongside success certs in a uniform `Certified<_>` channel.
10191    /// Phase X.1: the produced cert class is the ontology-declared class for
10192    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10193    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10194    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10195    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10196    /// kernels so each resolver's class discrimination is load-bearing.
10197    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10198    /// kernel's composition spec) whose output is folded into the canonical
10199    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10200    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10201    /// content-addressed per its ontology class.
10202    pub mod monodromy {
10203        use super::*;
10204
10205        #[doc(hidden)]
10206        pub struct Kernel;
10207        impl super::ResolverKernel for Kernel {
10208            type Cert = crate::enforcement::IsometryCertificate;
10209            const KIND: crate::enforcement::CertificateKind =
10210                crate::enforcement::CertificateKind::Monodromy;
10211        }
10212
10213        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10214        ///
10215        /// # Errors
10216        ///
10217        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10218        pub fn certify<
10219            T: crate::pipeline::ConstrainedTypeShape,
10220            P: crate::enforcement::ValidationPhase,
10221            H: crate::enforcement::Hasher,
10222        >(
10223            input: &Validated<T, P>,
10224        ) -> Result<Certified<IsometryCertificate>, Certified<GenericImpossibilityWitness>>
10225        {
10226            certify_at::<T, P, H>(input, WittLevel::W32)
10227        }
10228
10229        /// Phase D (target §4.2): certify at an explicit Witt level.
10230        ///
10231        /// # Errors
10232        ///
10233        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10234        pub fn certify_at<
10235            T: crate::pipeline::ConstrainedTypeShape,
10236            P: crate::enforcement::ValidationPhase,
10237            H: crate::enforcement::Hasher,
10238        >(
10239            input: &Validated<T, P>,
10240            level: WittLevel,
10241        ) -> Result<Certified<IsometryCertificate>, Certified<GenericImpossibilityWitness>>
10242        {
10243            let _ = input.inner();
10244            let witt_bits = level.witt_length() as u16;
10245            let (tr_bits, tr_constraints, tr_sat) =
10246                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10247                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10248            if tr_sat == 0 {
10249                return Err(Certified::new(GenericImpossibilityWitness::default()));
10250            }
10251            let mut hasher = H::initial();
10252            hasher = crate::enforcement::fold_terminal_reduction(
10253                hasher,
10254                tr_bits,
10255                tr_constraints,
10256                tr_sat,
10257            );
10258            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10259                .map_err(crate::enforcement::Certified::new)?;
10260            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10261            let (orbit_size, representative) =
10262                crate::enforcement::primitive_dihedral_signature::<T>();
10263            hasher =
10264                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
10265            hasher = crate::enforcement::fold_unit_digest(
10266                hasher,
10267                witt_bits,
10268                witt_bits as u64,
10269                T::IRI,
10270                T::SITE_COUNT,
10271                T::CONSTRAINTS,
10272                <Kernel as super::ResolverKernel>::KIND,
10273            );
10274            let buffer = hasher.finalize();
10275            let fp =
10276                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10277            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10278            Ok(Certified::new(cert))
10279        }
10280    }
10281
10282    /// Phase D (target §4.2): `resolver:ModuliResolver` — compute the local moduli-space structure at a `CompleteType`: DeformationComplex, HolonomyStratum, tangent/obstruction dimensions.
10283    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10284    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10285    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10286    /// failure — the witness itself is certified so downstream can persist it
10287    /// alongside success certs in a uniform `Certified<_>` channel.
10288    /// Phase X.1: the produced cert class is the ontology-declared class for
10289    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10290    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10291    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10292    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10293    /// kernels so each resolver's class discrimination is load-bearing.
10294    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10295    /// kernel's composition spec) whose output is folded into the canonical
10296    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10297    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10298    /// content-addressed per its ontology class.
10299    pub mod moduli {
10300        use super::*;
10301
10302        #[doc(hidden)]
10303        pub struct Kernel;
10304        impl super::ResolverKernel for Kernel {
10305            type Cert = crate::enforcement::TransformCertificate;
10306            const KIND: crate::enforcement::CertificateKind =
10307                crate::enforcement::CertificateKind::Moduli;
10308        }
10309
10310        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10311        ///
10312        /// # Errors
10313        ///
10314        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10315        pub fn certify<
10316            T: crate::pipeline::ConstrainedTypeShape,
10317            P: crate::enforcement::ValidationPhase,
10318            H: crate::enforcement::Hasher,
10319        >(
10320            input: &Validated<T, P>,
10321        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10322        {
10323            certify_at::<T, P, H>(input, WittLevel::W32)
10324        }
10325
10326        /// Phase D (target §4.2): certify at an explicit Witt level.
10327        ///
10328        /// # Errors
10329        ///
10330        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10331        pub fn certify_at<
10332            T: crate::pipeline::ConstrainedTypeShape,
10333            P: crate::enforcement::ValidationPhase,
10334            H: crate::enforcement::Hasher,
10335        >(
10336            input: &Validated<T, P>,
10337            level: WittLevel,
10338        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10339        {
10340            let _ = input.inner();
10341            let witt_bits = level.witt_length() as u16;
10342            let (tr_bits, tr_constraints, tr_sat) =
10343                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10344                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10345            if tr_sat == 0 {
10346                return Err(Certified::new(GenericImpossibilityWitness::default()));
10347            }
10348            let mut hasher = H::initial();
10349            hasher = crate::enforcement::fold_terminal_reduction(
10350                hasher,
10351                tr_bits,
10352                tr_constraints,
10353                tr_sat,
10354            );
10355            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10356                .map_err(crate::enforcement::Certified::new)?;
10357            let automorphisms: u32 = betti[0];
10358            let deformations: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 1 {
10359                betti[1]
10360            } else {
10361                0
10362            };
10363            let obstructions: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 2 {
10364                betti[2]
10365            } else {
10366                0
10367            };
10368            hasher = hasher.fold_bytes(&automorphisms.to_be_bytes());
10369            hasher = hasher.fold_bytes(&deformations.to_be_bytes());
10370            hasher = hasher.fold_bytes(&obstructions.to_be_bytes());
10371            hasher = crate::enforcement::fold_unit_digest(
10372                hasher,
10373                witt_bits,
10374                witt_bits as u64,
10375                T::IRI,
10376                T::SITE_COUNT,
10377                T::CONSTRAINTS,
10378                <Kernel as super::ResolverKernel>::KIND,
10379            );
10380            let buffer = hasher.finalize();
10381            let fp =
10382                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10383            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10384            Ok(Certified::new(cert))
10385        }
10386    }
10387
10388    /// 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.
10389    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10390    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10391    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10392    /// failure — the witness itself is certified so downstream can persist it
10393    /// alongside success certs in a uniform `Certified<_>` channel.
10394    /// Phase X.1: the produced cert class is the ontology-declared class for
10395    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10396    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10397    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10398    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10399    /// kernels so each resolver's class discrimination is load-bearing.
10400    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10401    /// kernel's composition spec) whose output is folded into the canonical
10402    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10403    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10404    /// content-addressed per its ontology class.
10405    pub mod jacobian_guided {
10406        use super::*;
10407
10408        #[doc(hidden)]
10409        pub struct Kernel;
10410        impl super::ResolverKernel for Kernel {
10411            type Cert = crate::enforcement::GroundingCertificate;
10412            const KIND: crate::enforcement::CertificateKind =
10413                crate::enforcement::CertificateKind::JacobianGuided;
10414        }
10415
10416        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10417        ///
10418        /// # Errors
10419        ///
10420        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10421        pub fn certify<
10422            T: crate::pipeline::ConstrainedTypeShape,
10423            P: crate::enforcement::ValidationPhase,
10424            H: crate::enforcement::Hasher,
10425        >(
10426            input: &Validated<T, P>,
10427        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10428        {
10429            certify_at::<T, P, H>(input, WittLevel::W32)
10430        }
10431
10432        /// Phase D (target §4.2): certify at an explicit Witt level.
10433        ///
10434        /// # Errors
10435        ///
10436        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10437        pub fn certify_at<
10438            T: crate::pipeline::ConstrainedTypeShape,
10439            P: crate::enforcement::ValidationPhase,
10440            H: crate::enforcement::Hasher,
10441        >(
10442            input: &Validated<T, P>,
10443            level: WittLevel,
10444        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10445        {
10446            let _ = input.inner();
10447            let witt_bits = level.witt_length() as u16;
10448            let (tr_bits, tr_constraints, tr_sat) =
10449                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10450                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10451            if tr_sat == 0 {
10452                return Err(Certified::new(GenericImpossibilityWitness::default()));
10453            }
10454            let mut hasher = H::initial();
10455            hasher = crate::enforcement::fold_terminal_reduction(
10456                hasher,
10457                tr_bits,
10458                tr_constraints,
10459                tr_sat,
10460            );
10461            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
10462            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
10463            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
10464            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
10465            hasher = crate::enforcement::fold_unit_digest(
10466                hasher,
10467                witt_bits,
10468                witt_bits as u64,
10469                T::IRI,
10470                T::SITE_COUNT,
10471                T::CONSTRAINTS,
10472                <Kernel as super::ResolverKernel>::KIND,
10473            );
10474            let buffer = hasher.finalize();
10475            let fp =
10476                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10477            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10478            Ok(Certified::new(cert))
10479        }
10480    }
10481
10482    /// 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.
10483    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10484    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10485    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10486    /// failure — the witness itself is certified so downstream can persist it
10487    /// alongside success certs in a uniform `Certified<_>` channel.
10488    /// Phase X.1: the produced cert class is the ontology-declared class for
10489    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10490    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10491    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10492    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10493    /// kernels so each resolver's class discrimination is load-bearing.
10494    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10495    /// kernel's composition spec) whose output is folded into the canonical
10496    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10497    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10498    /// content-addressed per its ontology class.
10499    pub mod evaluation {
10500        use super::*;
10501
10502        #[doc(hidden)]
10503        pub struct Kernel;
10504        impl super::ResolverKernel for Kernel {
10505            type Cert = crate::enforcement::GroundingCertificate;
10506            const KIND: crate::enforcement::CertificateKind =
10507                crate::enforcement::CertificateKind::Evaluation;
10508        }
10509
10510        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10511        ///
10512        /// # Errors
10513        ///
10514        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10515        pub fn certify<
10516            T: crate::pipeline::ConstrainedTypeShape,
10517            P: crate::enforcement::ValidationPhase,
10518            H: crate::enforcement::Hasher,
10519        >(
10520            input: &Validated<T, P>,
10521        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10522        {
10523            certify_at::<T, P, H>(input, WittLevel::W32)
10524        }
10525
10526        /// Phase D (target §4.2): certify at an explicit Witt level.
10527        ///
10528        /// # Errors
10529        ///
10530        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10531        pub fn certify_at<
10532            T: crate::pipeline::ConstrainedTypeShape,
10533            P: crate::enforcement::ValidationPhase,
10534            H: crate::enforcement::Hasher,
10535        >(
10536            input: &Validated<T, P>,
10537            level: WittLevel,
10538        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10539        {
10540            let _ = input.inner();
10541            let witt_bits = level.witt_length() as u16;
10542            let (tr_bits, tr_constraints, tr_sat) =
10543                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10544                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10545            if tr_sat == 0 {
10546                return Err(Certified::new(GenericImpossibilityWitness::default()));
10547            }
10548            let mut hasher = H::initial();
10549            hasher = crate::enforcement::fold_terminal_reduction(
10550                hasher,
10551                tr_bits,
10552                tr_constraints,
10553                tr_sat,
10554            );
10555            hasher = crate::enforcement::fold_unit_digest(
10556                hasher,
10557                witt_bits,
10558                witt_bits as u64,
10559                T::IRI,
10560                T::SITE_COUNT,
10561                T::CONSTRAINTS,
10562                <Kernel as super::ResolverKernel>::KIND,
10563            );
10564            let buffer = hasher.finalize();
10565            let fp =
10566                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10567            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10568            Ok(Certified::new(cert))
10569        }
10570    }
10571
10572    /// 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.
10573    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10574    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10575    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10576    /// failure — the witness itself is certified so downstream can persist it
10577    /// alongside success certs in a uniform `Certified<_>` channel.
10578    /// Phase X.1: the produced cert class is the ontology-declared class for
10579    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10580    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10581    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10582    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10583    /// kernels so each resolver's class discrimination is load-bearing.
10584    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10585    /// kernel's composition spec) whose output is folded into the canonical
10586    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10587    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10588    /// content-addressed per its ontology class.
10589    pub mod session {
10590        use super::*;
10591
10592        #[doc(hidden)]
10593        pub struct Kernel;
10594        impl super::ResolverKernel for Kernel {
10595            type Cert = crate::enforcement::GroundingCertificate;
10596            const KIND: crate::enforcement::CertificateKind =
10597                crate::enforcement::CertificateKind::Session;
10598        }
10599
10600        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10601        ///
10602        /// # Errors
10603        ///
10604        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10605        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10606            input: &Validated<CompileUnit, P>,
10607        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10608        {
10609            certify_at::<P, H>(input, WittLevel::W32)
10610        }
10611
10612        /// Phase D (target §4.2): certify at an explicit Witt level.
10613        ///
10614        /// # Errors
10615        ///
10616        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10617        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10618            input: &Validated<CompileUnit, P>,
10619            level: WittLevel,
10620        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10621        {
10622            let unit = input.inner();
10623            let witt_bits = level.witt_length() as u16;
10624            let budget = unit.thermodynamic_budget();
10625            let result_type_iri = unit.result_type_iri();
10626            let mut hasher = H::initial();
10627            let (binding_count, fold_addr) =
10628                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10629            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10630            hasher = crate::enforcement::fold_unit_digest(
10631                hasher,
10632                witt_bits,
10633                budget,
10634                result_type_iri,
10635                0usize,
10636                &[],
10637                <Kernel as super::ResolverKernel>::KIND,
10638            );
10639            let buffer = hasher.finalize();
10640            let fp =
10641                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10642            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10643            Ok(Certified::new(cert))
10644        }
10645    }
10646
10647    /// 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).
10648    /// Returns `Certified<BornRuleVerification>` on success carrying the Witt
10649    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10650    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10651    /// failure — the witness itself is certified so downstream can persist it
10652    /// alongside success certs in a uniform `Certified<_>` channel.
10653    /// Phase X.1: the produced cert class is the ontology-declared class for
10654    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10655    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10656    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10657    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10658    /// kernels so each resolver's class discrimination is load-bearing.
10659    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10660    /// kernel's composition spec) whose output is folded into the canonical
10661    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10662    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10663    /// content-addressed per its ontology class.
10664    pub mod superposition {
10665        use super::*;
10666
10667        #[doc(hidden)]
10668        pub struct Kernel;
10669        impl super::ResolverKernel for Kernel {
10670            type Cert = crate::enforcement::BornRuleVerification;
10671            const KIND: crate::enforcement::CertificateKind =
10672                crate::enforcement::CertificateKind::Superposition;
10673        }
10674
10675        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10676        ///
10677        /// # Errors
10678        ///
10679        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10680        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10681            input: &Validated<CompileUnit, P>,
10682        ) -> Result<Certified<BornRuleVerification>, Certified<GenericImpossibilityWitness>>
10683        {
10684            certify_at::<P, H>(input, WittLevel::W32)
10685        }
10686
10687        /// Phase D (target §4.2): certify at an explicit Witt level.
10688        ///
10689        /// # Errors
10690        ///
10691        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10692        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10693            input: &Validated<CompileUnit, P>,
10694            level: WittLevel,
10695        ) -> Result<Certified<BornRuleVerification>, Certified<GenericImpossibilityWitness>>
10696        {
10697            let unit = input.inner();
10698            let witt_bits = level.witt_length() as u16;
10699            let budget = unit.thermodynamic_budget();
10700            let result_type_iri = unit.result_type_iri();
10701            let mut hasher = H::initial();
10702            let (binding_count, fold_addr) =
10703                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10704            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10705            let (outcome_index, probability) =
10706                crate::enforcement::primitive_measurement_projection(budget);
10707            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10708            hasher = crate::enforcement::fold_unit_digest(
10709                hasher,
10710                witt_bits,
10711                budget,
10712                result_type_iri,
10713                0usize,
10714                &[],
10715                <Kernel as super::ResolverKernel>::KIND,
10716            );
10717            let buffer = hasher.finalize();
10718            let fp =
10719                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10720            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10721            Ok(Certified::new(cert))
10722        }
10723    }
10724
10725    /// Phase D (target §4.2): `resolver:MeasurementResolver` — resolve a `trace:MeasurementEvent` against the von Neumann-Landauer bridge (QM_1): `preCollapseEntropy = postCollapseLandauerCost` at β* = ln 2.
10726    /// Returns `Certified<MeasurementCertificate>` on success carrying the Witt
10727    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10728    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10729    /// failure — the witness itself is certified so downstream can persist it
10730    /// alongside success certs in a uniform `Certified<_>` channel.
10731    /// Phase X.1: the produced cert class is the ontology-declared class for
10732    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10733    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10734    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10735    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10736    /// kernels so each resolver's class discrimination is load-bearing.
10737    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10738    /// kernel's composition spec) whose output is folded into the canonical
10739    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10740    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10741    /// content-addressed per its ontology class.
10742    pub mod measurement {
10743        use super::*;
10744
10745        #[doc(hidden)]
10746        pub struct Kernel;
10747        impl super::ResolverKernel for Kernel {
10748            type Cert = crate::enforcement::MeasurementCertificate;
10749            const KIND: crate::enforcement::CertificateKind =
10750                crate::enforcement::CertificateKind::Measurement;
10751        }
10752
10753        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10754        ///
10755        /// # Errors
10756        ///
10757        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10758        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10759            input: &Validated<CompileUnit, P>,
10760        ) -> Result<Certified<MeasurementCertificate>, Certified<GenericImpossibilityWitness>>
10761        {
10762            certify_at::<P, H>(input, WittLevel::W32)
10763        }
10764
10765        /// Phase D (target §4.2): certify at an explicit Witt level.
10766        ///
10767        /// # Errors
10768        ///
10769        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10770        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10771            input: &Validated<CompileUnit, P>,
10772            level: WittLevel,
10773        ) -> Result<Certified<MeasurementCertificate>, Certified<GenericImpossibilityWitness>>
10774        {
10775            let unit = input.inner();
10776            let witt_bits = level.witt_length() as u16;
10777            let budget = unit.thermodynamic_budget();
10778            let result_type_iri = unit.result_type_iri();
10779            let mut hasher = H::initial();
10780            let (outcome_index, probability) =
10781                crate::enforcement::primitive_measurement_projection(budget);
10782            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10783            hasher = crate::enforcement::fold_unit_digest(
10784                hasher,
10785                witt_bits,
10786                budget,
10787                result_type_iri,
10788                0usize,
10789                &[],
10790                <Kernel as super::ResolverKernel>::KIND,
10791            );
10792            let buffer = hasher.finalize();
10793            let fp =
10794                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10795            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10796            Ok(Certified::new(cert))
10797        }
10798    }
10799
10800    /// 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.
10801    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10802    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10803    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10804    /// failure — the witness itself is certified so downstream can persist it
10805    /// alongside success certs in a uniform `Certified<_>` channel.
10806    /// Phase X.1: the produced cert class is the ontology-declared class for
10807    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10808    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10809    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10810    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10811    /// kernels so each resolver's class discrimination is load-bearing.
10812    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10813    /// kernel's composition spec) whose output is folded into the canonical
10814    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10815    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10816    /// content-addressed per its ontology class.
10817    pub mod witt_level_resolver {
10818        use super::*;
10819
10820        #[doc(hidden)]
10821        pub struct Kernel;
10822        impl super::ResolverKernel for Kernel {
10823            type Cert = crate::enforcement::GroundingCertificate;
10824            const KIND: crate::enforcement::CertificateKind =
10825                crate::enforcement::CertificateKind::WittLevel;
10826        }
10827
10828        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10829        ///
10830        /// # Errors
10831        ///
10832        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10833        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10834            input: &Validated<CompileUnit, P>,
10835        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10836        {
10837            certify_at::<P, H>(input, WittLevel::W32)
10838        }
10839
10840        /// Phase D (target §4.2): certify at an explicit Witt level.
10841        ///
10842        /// # Errors
10843        ///
10844        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10845        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10846            input: &Validated<CompileUnit, P>,
10847            level: WittLevel,
10848        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10849        {
10850            let unit = input.inner();
10851            let witt_bits = level.witt_length() as u16;
10852            let budget = unit.thermodynamic_budget();
10853            let result_type_iri = unit.result_type_iri();
10854            let mut hasher = H::initial();
10855            hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
10856            let declared_level_bits = unit.witt_level().witt_length() as u16;
10857            hasher = hasher.fold_bytes(&declared_level_bits.to_be_bytes());
10858            hasher = crate::enforcement::fold_unit_digest(
10859                hasher,
10860                witt_bits,
10861                budget,
10862                result_type_iri,
10863                0usize,
10864                &[],
10865                <Kernel as super::ResolverKernel>::KIND,
10866            );
10867            let buffer = hasher.finalize();
10868            let fp =
10869                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10870            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10871            Ok(Certified::new(cert))
10872        }
10873    }
10874
10875    /// Phase D (target §4.2): `resolver:DihedralFactorizationResolver` — run the dihedral factorization decider on a `ConstrainedType`'s carrier, producing a cert over the factor structure.
10876    /// Returns `Certified<InvolutionCertificate>` on success carrying the Witt
10877    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10878    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10879    /// failure — the witness itself is certified so downstream can persist it
10880    /// alongside success certs in a uniform `Certified<_>` channel.
10881    /// Phase X.1: the produced cert class is the ontology-declared class for
10882    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10883    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10884    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10885    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10886    /// kernels so each resolver's class discrimination is load-bearing.
10887    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10888    /// kernel's composition spec) whose output is folded into the canonical
10889    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10890    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10891    /// content-addressed per its ontology class.
10892    pub mod dihedral_factorization {
10893        use super::*;
10894
10895        #[doc(hidden)]
10896        pub struct Kernel;
10897        impl super::ResolverKernel for Kernel {
10898            type Cert = crate::enforcement::InvolutionCertificate;
10899            const KIND: crate::enforcement::CertificateKind =
10900                crate::enforcement::CertificateKind::DihedralFactorization;
10901        }
10902
10903        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10904        ///
10905        /// # Errors
10906        ///
10907        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10908        pub fn certify<
10909            T: crate::pipeline::ConstrainedTypeShape,
10910            P: crate::enforcement::ValidationPhase,
10911            H: crate::enforcement::Hasher,
10912        >(
10913            input: &Validated<T, P>,
10914        ) -> Result<Certified<InvolutionCertificate>, Certified<GenericImpossibilityWitness>>
10915        {
10916            certify_at::<T, P, H>(input, WittLevel::W32)
10917        }
10918
10919        /// Phase D (target §4.2): certify at an explicit Witt level.
10920        ///
10921        /// # Errors
10922        ///
10923        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10924        pub fn certify_at<
10925            T: crate::pipeline::ConstrainedTypeShape,
10926            P: crate::enforcement::ValidationPhase,
10927            H: crate::enforcement::Hasher,
10928        >(
10929            input: &Validated<T, P>,
10930            level: WittLevel,
10931        ) -> Result<Certified<InvolutionCertificate>, Certified<GenericImpossibilityWitness>>
10932        {
10933            let _ = input.inner();
10934            let witt_bits = level.witt_length() as u16;
10935            let (tr_bits, tr_constraints, tr_sat) =
10936                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10937                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10938            if tr_sat == 0 {
10939                return Err(Certified::new(GenericImpossibilityWitness::default()));
10940            }
10941            let mut hasher = H::initial();
10942            hasher = crate::enforcement::fold_terminal_reduction(
10943                hasher,
10944                tr_bits,
10945                tr_constraints,
10946                tr_sat,
10947            );
10948            let (orbit_size, representative) =
10949                crate::enforcement::primitive_dihedral_signature::<T>();
10950            hasher =
10951                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
10952            hasher = crate::enforcement::fold_unit_digest(
10953                hasher,
10954                witt_bits,
10955                witt_bits as u64,
10956                T::IRI,
10957                T::SITE_COUNT,
10958                T::CONSTRAINTS,
10959                <Kernel as super::ResolverKernel>::KIND,
10960            );
10961            let buffer = hasher.finalize();
10962            let fp =
10963                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10964            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10965            Ok(Certified::new(cert))
10966        }
10967    }
10968
10969    /// 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.
10970    /// Returns `Certified<CompletenessCertificate>` on success carrying the Witt
10971    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10972    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10973    /// failure — the witness itself is certified so downstream can persist it
10974    /// alongside success certs in a uniform `Certified<_>` channel.
10975    /// Phase X.1: the produced cert class is the ontology-declared class for
10976    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10977    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10978    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10979    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10980    /// kernels so each resolver's class discrimination is load-bearing.
10981    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10982    /// kernel's composition spec) whose output is folded into the canonical
10983    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10984    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10985    /// content-addressed per its ontology class.
10986    pub mod completeness {
10987        use super::*;
10988
10989        #[doc(hidden)]
10990        pub struct Kernel;
10991        impl super::ResolverKernel for Kernel {
10992            type Cert = crate::enforcement::CompletenessCertificate;
10993            const KIND: crate::enforcement::CertificateKind =
10994                crate::enforcement::CertificateKind::Completeness;
10995        }
10996
10997        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10998        ///
10999        /// # Errors
11000        ///
11001        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11002        pub fn certify<
11003            T: crate::pipeline::ConstrainedTypeShape,
11004            P: crate::enforcement::ValidationPhase,
11005            H: crate::enforcement::Hasher,
11006        >(
11007            input: &Validated<T, P>,
11008        ) -> Result<Certified<CompletenessCertificate>, Certified<GenericImpossibilityWitness>>
11009        {
11010            certify_at::<T, P, H>(input, WittLevel::W32)
11011        }
11012
11013        /// Phase D (target §4.2): certify at an explicit Witt level.
11014        ///
11015        /// # Errors
11016        ///
11017        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11018        pub fn certify_at<
11019            T: crate::pipeline::ConstrainedTypeShape,
11020            P: crate::enforcement::ValidationPhase,
11021            H: crate::enforcement::Hasher,
11022        >(
11023            input: &Validated<T, P>,
11024            level: WittLevel,
11025        ) -> Result<Certified<CompletenessCertificate>, Certified<GenericImpossibilityWitness>>
11026        {
11027            let _ = input.inner();
11028            let witt_bits = level.witt_length() as u16;
11029            let (tr_bits, tr_constraints, tr_sat) =
11030                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11031                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11032            if tr_sat == 0 {
11033                return Err(Certified::new(GenericImpossibilityWitness::default()));
11034            }
11035            let mut hasher = H::initial();
11036            hasher = crate::enforcement::fold_terminal_reduction(
11037                hasher,
11038                tr_bits,
11039                tr_constraints,
11040                tr_sat,
11041            );
11042            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
11043                .map_err(crate::enforcement::Certified::new)?;
11044            let chi = crate::enforcement::primitive_euler_characteristic(&betti);
11045            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
11046            hasher = hasher.fold_bytes(&chi.to_be_bytes());
11047            hasher = crate::enforcement::fold_unit_digest(
11048                hasher,
11049                witt_bits,
11050                witt_bits as u64,
11051                T::IRI,
11052                T::SITE_COUNT,
11053                T::CONSTRAINTS,
11054                <Kernel as super::ResolverKernel>::KIND,
11055            );
11056            let buffer = hasher.finalize();
11057            let fp =
11058                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11059            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11060            Ok(Certified::new(cert))
11061        }
11062    }
11063
11064    /// 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.
11065    /// Returns `Certified<GeodesicCertificate>` on success carrying the Witt
11066    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11067    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11068    /// failure — the witness itself is certified so downstream can persist it
11069    /// alongside success certs in a uniform `Certified<_>` channel.
11070    /// Phase X.1: the produced cert class is the ontology-declared class for
11071    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11072    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11073    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11074    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11075    /// kernels so each resolver's class discrimination is load-bearing.
11076    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11077    /// kernel's composition spec) whose output is folded into the canonical
11078    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11079    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11080    /// content-addressed per its ontology class.
11081    pub mod geodesic_validator {
11082        use super::*;
11083
11084        #[doc(hidden)]
11085        pub struct Kernel;
11086        impl super::ResolverKernel for Kernel {
11087            type Cert = crate::enforcement::GeodesicCertificate;
11088            const KIND: crate::enforcement::CertificateKind =
11089                crate::enforcement::CertificateKind::GeodesicValidator;
11090        }
11091
11092        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11093        ///
11094        /// # Errors
11095        ///
11096        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11097        pub fn certify<
11098            T: crate::pipeline::ConstrainedTypeShape,
11099            P: crate::enforcement::ValidationPhase,
11100            H: crate::enforcement::Hasher,
11101        >(
11102            input: &Validated<T, P>,
11103        ) -> Result<Certified<GeodesicCertificate>, Certified<GenericImpossibilityWitness>>
11104        {
11105            certify_at::<T, P, H>(input, WittLevel::W32)
11106        }
11107
11108        /// Phase D (target §4.2): certify at an explicit Witt level.
11109        ///
11110        /// # Errors
11111        ///
11112        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11113        pub fn certify_at<
11114            T: crate::pipeline::ConstrainedTypeShape,
11115            P: crate::enforcement::ValidationPhase,
11116            H: crate::enforcement::Hasher,
11117        >(
11118            input: &Validated<T, P>,
11119            level: WittLevel,
11120        ) -> Result<Certified<GeodesicCertificate>, Certified<GenericImpossibilityWitness>>
11121        {
11122            let _ = input.inner();
11123            let witt_bits = level.witt_length() as u16;
11124            let (tr_bits, tr_constraints, tr_sat) =
11125                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11126                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11127            if tr_sat == 0 {
11128                return Err(Certified::new(GenericImpossibilityWitness::default()));
11129            }
11130            let mut hasher = H::initial();
11131            hasher = crate::enforcement::fold_terminal_reduction(
11132                hasher,
11133                tr_bits,
11134                tr_constraints,
11135                tr_sat,
11136            );
11137            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
11138            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
11139            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
11140            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
11141            hasher = crate::enforcement::fold_unit_digest(
11142                hasher,
11143                witt_bits,
11144                witt_bits as u64,
11145                T::IRI,
11146                T::SITE_COUNT,
11147                T::CONSTRAINTS,
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 as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11154            Ok(Certified::new(cert))
11155        }
11156    }
11157}
11158
11159/// v0.2.2 phantom-typed ring operation surface. Each phantom struct binds a
11160/// `WittLevel` at the type level so consumers can write
11161/// `Mul::<W8>::apply(a, b)` for compile-time level-checked arithmetic.
11162pub trait RingOp<L> {
11163    /// Operand type at this level.
11164    type Operand;
11165    /// Apply this binary ring op.
11166    fn apply(a: Self::Operand, b: Self::Operand) -> Self::Operand;
11167}
11168
11169/// v0.2.2 W3: unary phantom-typed ring operation surface. Mirrors `RingOp`
11170/// for arity-1 operations (`Neg`, `BNot`, `Succ`) so consumers can write
11171/// `Neg::<W8>::apply(a)` for compile-time level-checked unary arithmetic.
11172pub trait UnaryRingOp<L> {
11173    /// Operand type at this level.
11174    type Operand;
11175    /// Apply this unary ring op.
11176    fn apply(a: Self::Operand) -> Self::Operand;
11177}
11178
11179/// Multiplicative ring op. phantom-typed at level `L`.
11180#[derive(Debug, Default, Clone, Copy)]
11181pub struct Mul<L>(PhantomData<L>);
11182
11183/// Additive ring op. phantom-typed at level `L`.
11184#[derive(Debug, Default, Clone, Copy)]
11185pub struct Add<L>(PhantomData<L>);
11186
11187/// Subtractive ring op. phantom-typed at level `L`.
11188#[derive(Debug, Default, Clone, Copy)]
11189pub struct Sub<L>(PhantomData<L>);
11190
11191/// Bitwise XOR ring op. phantom-typed at level `L`.
11192#[derive(Debug, Default, Clone, Copy)]
11193pub struct Xor<L>(PhantomData<L>);
11194
11195/// Bitwise AND ring op. phantom-typed at level `L`.
11196#[derive(Debug, Default, Clone, Copy)]
11197pub struct And<L>(PhantomData<L>);
11198
11199/// Bitwise OR ring op. phantom-typed at level `L`.
11200#[derive(Debug, Default, Clone, Copy)]
11201pub struct Or<L>(PhantomData<L>);
11202
11203/// Ring negation (the canonical involution: x → -x). Phantom-typed at level `L` (v0.2.2 W3).
11204#[derive(Debug, Default, Clone, Copy)]
11205pub struct Neg<L>(PhantomData<L>);
11206
11207/// Bitwise NOT (the Hamming involution: x → (2^n - 1) XOR x). Phantom-typed at level `L` (v0.2.2 W3).
11208#[derive(Debug, Default, Clone, Copy)]
11209pub struct BNot<L>(PhantomData<L>);
11210
11211/// Successor (= Neg ∘ BNot per the critical composition law). Phantom-typed at level `L` (v0.2.2 W3).
11212#[derive(Debug, Default, Clone, Copy)]
11213pub struct Succ<L>(PhantomData<L>);
11214
11215/// W8 marker — 8-bit Witt level reified at the type level.
11216#[derive(Debug, Default, Clone, Copy)]
11217pub struct W8;
11218
11219/// W16 marker — 16-bit Witt level reified at the type level.
11220#[derive(Debug, Default, Clone, Copy)]
11221pub struct W16;
11222
11223/// W24 marker — 24-bit Witt level reified at the type level.
11224#[derive(Debug, Default, Clone, Copy)]
11225pub struct W24;
11226
11227/// W32 marker — 32-bit Witt level reified at the type level.
11228#[derive(Debug, Default, Clone, Copy)]
11229pub struct W32;
11230
11231/// W40 marker — 40-bit Witt level reified at the type level.
11232#[derive(Debug, Default, Clone, Copy)]
11233pub struct W40;
11234
11235/// W48 marker — 48-bit Witt level reified at the type level.
11236#[derive(Debug, Default, Clone, Copy)]
11237pub struct W48;
11238
11239/// W56 marker — 56-bit Witt level reified at the type level.
11240#[derive(Debug, Default, Clone, Copy)]
11241pub struct W56;
11242
11243/// W64 marker — 64-bit Witt level reified at the type level.
11244#[derive(Debug, Default, Clone, Copy)]
11245pub struct W64;
11246
11247/// W72 marker — 72-bit Witt level reified at the type level.
11248#[derive(Debug, Default, Clone, Copy)]
11249pub struct W72;
11250
11251/// W80 marker — 80-bit Witt level reified at the type level.
11252#[derive(Debug, Default, Clone, Copy)]
11253pub struct W80;
11254
11255/// W88 marker — 88-bit Witt level reified at the type level.
11256#[derive(Debug, Default, Clone, Copy)]
11257pub struct W88;
11258
11259/// W96 marker — 96-bit Witt level reified at the type level.
11260#[derive(Debug, Default, Clone, Copy)]
11261pub struct W96;
11262
11263/// W104 marker — 104-bit Witt level reified at the type level.
11264#[derive(Debug, Default, Clone, Copy)]
11265pub struct W104;
11266
11267/// W112 marker — 112-bit Witt level reified at the type level.
11268#[derive(Debug, Default, Clone, Copy)]
11269pub struct W112;
11270
11271/// W120 marker — 120-bit Witt level reified at the type level.
11272#[derive(Debug, Default, Clone, Copy)]
11273pub struct W120;
11274
11275/// W128 marker — 128-bit Witt level reified at the type level.
11276#[derive(Debug, Default, Clone, Copy)]
11277pub struct W128;
11278
11279impl RingOp<W8> for Mul<W8> {
11280    type Operand = u8;
11281    #[inline]
11282    fn apply(a: u8, b: u8) -> u8 {
11283        const_ring_eval_w8(PrimitiveOp::Mul, a, b)
11284    }
11285}
11286
11287impl RingOp<W8> for Add<W8> {
11288    type Operand = u8;
11289    #[inline]
11290    fn apply(a: u8, b: u8) -> u8 {
11291        const_ring_eval_w8(PrimitiveOp::Add, a, b)
11292    }
11293}
11294
11295impl RingOp<W8> for Sub<W8> {
11296    type Operand = u8;
11297    #[inline]
11298    fn apply(a: u8, b: u8) -> u8 {
11299        const_ring_eval_w8(PrimitiveOp::Sub, a, b)
11300    }
11301}
11302
11303impl RingOp<W8> for Xor<W8> {
11304    type Operand = u8;
11305    #[inline]
11306    fn apply(a: u8, b: u8) -> u8 {
11307        const_ring_eval_w8(PrimitiveOp::Xor, a, b)
11308    }
11309}
11310
11311impl RingOp<W8> for And<W8> {
11312    type Operand = u8;
11313    #[inline]
11314    fn apply(a: u8, b: u8) -> u8 {
11315        const_ring_eval_w8(PrimitiveOp::And, a, b)
11316    }
11317}
11318
11319impl RingOp<W8> for Or<W8> {
11320    type Operand = u8;
11321    #[inline]
11322    fn apply(a: u8, b: u8) -> u8 {
11323        const_ring_eval_w8(PrimitiveOp::Or, a, b)
11324    }
11325}
11326
11327impl RingOp<W16> for Mul<W16> {
11328    type Operand = u16;
11329    #[inline]
11330    fn apply(a: u16, b: u16) -> u16 {
11331        const_ring_eval_w16(PrimitiveOp::Mul, a, b)
11332    }
11333}
11334
11335impl RingOp<W16> for Add<W16> {
11336    type Operand = u16;
11337    #[inline]
11338    fn apply(a: u16, b: u16) -> u16 {
11339        const_ring_eval_w16(PrimitiveOp::Add, a, b)
11340    }
11341}
11342
11343impl RingOp<W16> for Sub<W16> {
11344    type Operand = u16;
11345    #[inline]
11346    fn apply(a: u16, b: u16) -> u16 {
11347        const_ring_eval_w16(PrimitiveOp::Sub, a, b)
11348    }
11349}
11350
11351impl RingOp<W16> for Xor<W16> {
11352    type Operand = u16;
11353    #[inline]
11354    fn apply(a: u16, b: u16) -> u16 {
11355        const_ring_eval_w16(PrimitiveOp::Xor, a, b)
11356    }
11357}
11358
11359impl RingOp<W16> for And<W16> {
11360    type Operand = u16;
11361    #[inline]
11362    fn apply(a: u16, b: u16) -> u16 {
11363        const_ring_eval_w16(PrimitiveOp::And, a, b)
11364    }
11365}
11366
11367impl RingOp<W16> for Or<W16> {
11368    type Operand = u16;
11369    #[inline]
11370    fn apply(a: u16, b: u16) -> u16 {
11371        const_ring_eval_w16(PrimitiveOp::Or, a, b)
11372    }
11373}
11374
11375impl RingOp<W24> for Mul<W24> {
11376    type Operand = u32;
11377    #[inline]
11378    fn apply(a: u32, b: u32) -> u32 {
11379        const_ring_eval_w24(PrimitiveOp::Mul, a, b)
11380    }
11381}
11382
11383impl RingOp<W24> for Add<W24> {
11384    type Operand = u32;
11385    #[inline]
11386    fn apply(a: u32, b: u32) -> u32 {
11387        const_ring_eval_w24(PrimitiveOp::Add, a, b)
11388    }
11389}
11390
11391impl RingOp<W24> for Sub<W24> {
11392    type Operand = u32;
11393    #[inline]
11394    fn apply(a: u32, b: u32) -> u32 {
11395        const_ring_eval_w24(PrimitiveOp::Sub, a, b)
11396    }
11397}
11398
11399impl RingOp<W24> for Xor<W24> {
11400    type Operand = u32;
11401    #[inline]
11402    fn apply(a: u32, b: u32) -> u32 {
11403        const_ring_eval_w24(PrimitiveOp::Xor, a, b)
11404    }
11405}
11406
11407impl RingOp<W24> for And<W24> {
11408    type Operand = u32;
11409    #[inline]
11410    fn apply(a: u32, b: u32) -> u32 {
11411        const_ring_eval_w24(PrimitiveOp::And, a, b)
11412    }
11413}
11414
11415impl RingOp<W24> for Or<W24> {
11416    type Operand = u32;
11417    #[inline]
11418    fn apply(a: u32, b: u32) -> u32 {
11419        const_ring_eval_w24(PrimitiveOp::Or, a, b)
11420    }
11421}
11422
11423impl RingOp<W32> for Mul<W32> {
11424    type Operand = u32;
11425    #[inline]
11426    fn apply(a: u32, b: u32) -> u32 {
11427        const_ring_eval_w32(PrimitiveOp::Mul, a, b)
11428    }
11429}
11430
11431impl RingOp<W32> for Add<W32> {
11432    type Operand = u32;
11433    #[inline]
11434    fn apply(a: u32, b: u32) -> u32 {
11435        const_ring_eval_w32(PrimitiveOp::Add, a, b)
11436    }
11437}
11438
11439impl RingOp<W32> for Sub<W32> {
11440    type Operand = u32;
11441    #[inline]
11442    fn apply(a: u32, b: u32) -> u32 {
11443        const_ring_eval_w32(PrimitiveOp::Sub, a, b)
11444    }
11445}
11446
11447impl RingOp<W32> for Xor<W32> {
11448    type Operand = u32;
11449    #[inline]
11450    fn apply(a: u32, b: u32) -> u32 {
11451        const_ring_eval_w32(PrimitiveOp::Xor, a, b)
11452    }
11453}
11454
11455impl RingOp<W32> for And<W32> {
11456    type Operand = u32;
11457    #[inline]
11458    fn apply(a: u32, b: u32) -> u32 {
11459        const_ring_eval_w32(PrimitiveOp::And, a, b)
11460    }
11461}
11462
11463impl RingOp<W32> for Or<W32> {
11464    type Operand = u32;
11465    #[inline]
11466    fn apply(a: u32, b: u32) -> u32 {
11467        const_ring_eval_w32(PrimitiveOp::Or, a, b)
11468    }
11469}
11470
11471impl RingOp<W40> for Mul<W40> {
11472    type Operand = u64;
11473    #[inline]
11474    fn apply(a: u64, b: u64) -> u64 {
11475        const_ring_eval_w40(PrimitiveOp::Mul, a, b)
11476    }
11477}
11478
11479impl RingOp<W40> for Add<W40> {
11480    type Operand = u64;
11481    #[inline]
11482    fn apply(a: u64, b: u64) -> u64 {
11483        const_ring_eval_w40(PrimitiveOp::Add, a, b)
11484    }
11485}
11486
11487impl RingOp<W40> for Sub<W40> {
11488    type Operand = u64;
11489    #[inline]
11490    fn apply(a: u64, b: u64) -> u64 {
11491        const_ring_eval_w40(PrimitiveOp::Sub, a, b)
11492    }
11493}
11494
11495impl RingOp<W40> for Xor<W40> {
11496    type Operand = u64;
11497    #[inline]
11498    fn apply(a: u64, b: u64) -> u64 {
11499        const_ring_eval_w40(PrimitiveOp::Xor, a, b)
11500    }
11501}
11502
11503impl RingOp<W40> for And<W40> {
11504    type Operand = u64;
11505    #[inline]
11506    fn apply(a: u64, b: u64) -> u64 {
11507        const_ring_eval_w40(PrimitiveOp::And, a, b)
11508    }
11509}
11510
11511impl RingOp<W40> for Or<W40> {
11512    type Operand = u64;
11513    #[inline]
11514    fn apply(a: u64, b: u64) -> u64 {
11515        const_ring_eval_w40(PrimitiveOp::Or, a, b)
11516    }
11517}
11518
11519impl RingOp<W48> for Mul<W48> {
11520    type Operand = u64;
11521    #[inline]
11522    fn apply(a: u64, b: u64) -> u64 {
11523        const_ring_eval_w48(PrimitiveOp::Mul, a, b)
11524    }
11525}
11526
11527impl RingOp<W48> for Add<W48> {
11528    type Operand = u64;
11529    #[inline]
11530    fn apply(a: u64, b: u64) -> u64 {
11531        const_ring_eval_w48(PrimitiveOp::Add, a, b)
11532    }
11533}
11534
11535impl RingOp<W48> for Sub<W48> {
11536    type Operand = u64;
11537    #[inline]
11538    fn apply(a: u64, b: u64) -> u64 {
11539        const_ring_eval_w48(PrimitiveOp::Sub, a, b)
11540    }
11541}
11542
11543impl RingOp<W48> for Xor<W48> {
11544    type Operand = u64;
11545    #[inline]
11546    fn apply(a: u64, b: u64) -> u64 {
11547        const_ring_eval_w48(PrimitiveOp::Xor, a, b)
11548    }
11549}
11550
11551impl RingOp<W48> for And<W48> {
11552    type Operand = u64;
11553    #[inline]
11554    fn apply(a: u64, b: u64) -> u64 {
11555        const_ring_eval_w48(PrimitiveOp::And, a, b)
11556    }
11557}
11558
11559impl RingOp<W48> for Or<W48> {
11560    type Operand = u64;
11561    #[inline]
11562    fn apply(a: u64, b: u64) -> u64 {
11563        const_ring_eval_w48(PrimitiveOp::Or, a, b)
11564    }
11565}
11566
11567impl RingOp<W56> for Mul<W56> {
11568    type Operand = u64;
11569    #[inline]
11570    fn apply(a: u64, b: u64) -> u64 {
11571        const_ring_eval_w56(PrimitiveOp::Mul, a, b)
11572    }
11573}
11574
11575impl RingOp<W56> for Add<W56> {
11576    type Operand = u64;
11577    #[inline]
11578    fn apply(a: u64, b: u64) -> u64 {
11579        const_ring_eval_w56(PrimitiveOp::Add, a, b)
11580    }
11581}
11582
11583impl RingOp<W56> for Sub<W56> {
11584    type Operand = u64;
11585    #[inline]
11586    fn apply(a: u64, b: u64) -> u64 {
11587        const_ring_eval_w56(PrimitiveOp::Sub, a, b)
11588    }
11589}
11590
11591impl RingOp<W56> for Xor<W56> {
11592    type Operand = u64;
11593    #[inline]
11594    fn apply(a: u64, b: u64) -> u64 {
11595        const_ring_eval_w56(PrimitiveOp::Xor, a, b)
11596    }
11597}
11598
11599impl RingOp<W56> for And<W56> {
11600    type Operand = u64;
11601    #[inline]
11602    fn apply(a: u64, b: u64) -> u64 {
11603        const_ring_eval_w56(PrimitiveOp::And, a, b)
11604    }
11605}
11606
11607impl RingOp<W56> for Or<W56> {
11608    type Operand = u64;
11609    #[inline]
11610    fn apply(a: u64, b: u64) -> u64 {
11611        const_ring_eval_w56(PrimitiveOp::Or, a, b)
11612    }
11613}
11614
11615impl RingOp<W64> for Mul<W64> {
11616    type Operand = u64;
11617    #[inline]
11618    fn apply(a: u64, b: u64) -> u64 {
11619        const_ring_eval_w64(PrimitiveOp::Mul, a, b)
11620    }
11621}
11622
11623impl RingOp<W64> for Add<W64> {
11624    type Operand = u64;
11625    #[inline]
11626    fn apply(a: u64, b: u64) -> u64 {
11627        const_ring_eval_w64(PrimitiveOp::Add, a, b)
11628    }
11629}
11630
11631impl RingOp<W64> for Sub<W64> {
11632    type Operand = u64;
11633    #[inline]
11634    fn apply(a: u64, b: u64) -> u64 {
11635        const_ring_eval_w64(PrimitiveOp::Sub, a, b)
11636    }
11637}
11638
11639impl RingOp<W64> for Xor<W64> {
11640    type Operand = u64;
11641    #[inline]
11642    fn apply(a: u64, b: u64) -> u64 {
11643        const_ring_eval_w64(PrimitiveOp::Xor, a, b)
11644    }
11645}
11646
11647impl RingOp<W64> for And<W64> {
11648    type Operand = u64;
11649    #[inline]
11650    fn apply(a: u64, b: u64) -> u64 {
11651        const_ring_eval_w64(PrimitiveOp::And, a, b)
11652    }
11653}
11654
11655impl RingOp<W64> for Or<W64> {
11656    type Operand = u64;
11657    #[inline]
11658    fn apply(a: u64, b: u64) -> u64 {
11659        const_ring_eval_w64(PrimitiveOp::Or, a, b)
11660    }
11661}
11662
11663impl RingOp<W72> for Mul<W72> {
11664    type Operand = u128;
11665    #[inline]
11666    fn apply(a: u128, b: u128) -> u128 {
11667        const_ring_eval_w72(PrimitiveOp::Mul, a, b)
11668    }
11669}
11670
11671impl RingOp<W72> for Add<W72> {
11672    type Operand = u128;
11673    #[inline]
11674    fn apply(a: u128, b: u128) -> u128 {
11675        const_ring_eval_w72(PrimitiveOp::Add, a, b)
11676    }
11677}
11678
11679impl RingOp<W72> for Sub<W72> {
11680    type Operand = u128;
11681    #[inline]
11682    fn apply(a: u128, b: u128) -> u128 {
11683        const_ring_eval_w72(PrimitiveOp::Sub, a, b)
11684    }
11685}
11686
11687impl RingOp<W72> for Xor<W72> {
11688    type Operand = u128;
11689    #[inline]
11690    fn apply(a: u128, b: u128) -> u128 {
11691        const_ring_eval_w72(PrimitiveOp::Xor, a, b)
11692    }
11693}
11694
11695impl RingOp<W72> for And<W72> {
11696    type Operand = u128;
11697    #[inline]
11698    fn apply(a: u128, b: u128) -> u128 {
11699        const_ring_eval_w72(PrimitiveOp::And, a, b)
11700    }
11701}
11702
11703impl RingOp<W72> for Or<W72> {
11704    type Operand = u128;
11705    #[inline]
11706    fn apply(a: u128, b: u128) -> u128 {
11707        const_ring_eval_w72(PrimitiveOp::Or, a, b)
11708    }
11709}
11710
11711impl RingOp<W80> for Mul<W80> {
11712    type Operand = u128;
11713    #[inline]
11714    fn apply(a: u128, b: u128) -> u128 {
11715        const_ring_eval_w80(PrimitiveOp::Mul, a, b)
11716    }
11717}
11718
11719impl RingOp<W80> for Add<W80> {
11720    type Operand = u128;
11721    #[inline]
11722    fn apply(a: u128, b: u128) -> u128 {
11723        const_ring_eval_w80(PrimitiveOp::Add, a, b)
11724    }
11725}
11726
11727impl RingOp<W80> for Sub<W80> {
11728    type Operand = u128;
11729    #[inline]
11730    fn apply(a: u128, b: u128) -> u128 {
11731        const_ring_eval_w80(PrimitiveOp::Sub, a, b)
11732    }
11733}
11734
11735impl RingOp<W80> for Xor<W80> {
11736    type Operand = u128;
11737    #[inline]
11738    fn apply(a: u128, b: u128) -> u128 {
11739        const_ring_eval_w80(PrimitiveOp::Xor, a, b)
11740    }
11741}
11742
11743impl RingOp<W80> for And<W80> {
11744    type Operand = u128;
11745    #[inline]
11746    fn apply(a: u128, b: u128) -> u128 {
11747        const_ring_eval_w80(PrimitiveOp::And, a, b)
11748    }
11749}
11750
11751impl RingOp<W80> for Or<W80> {
11752    type Operand = u128;
11753    #[inline]
11754    fn apply(a: u128, b: u128) -> u128 {
11755        const_ring_eval_w80(PrimitiveOp::Or, a, b)
11756    }
11757}
11758
11759impl RingOp<W88> for Mul<W88> {
11760    type Operand = u128;
11761    #[inline]
11762    fn apply(a: u128, b: u128) -> u128 {
11763        const_ring_eval_w88(PrimitiveOp::Mul, a, b)
11764    }
11765}
11766
11767impl RingOp<W88> for Add<W88> {
11768    type Operand = u128;
11769    #[inline]
11770    fn apply(a: u128, b: u128) -> u128 {
11771        const_ring_eval_w88(PrimitiveOp::Add, a, b)
11772    }
11773}
11774
11775impl RingOp<W88> for Sub<W88> {
11776    type Operand = u128;
11777    #[inline]
11778    fn apply(a: u128, b: u128) -> u128 {
11779        const_ring_eval_w88(PrimitiveOp::Sub, a, b)
11780    }
11781}
11782
11783impl RingOp<W88> for Xor<W88> {
11784    type Operand = u128;
11785    #[inline]
11786    fn apply(a: u128, b: u128) -> u128 {
11787        const_ring_eval_w88(PrimitiveOp::Xor, a, b)
11788    }
11789}
11790
11791impl RingOp<W88> for And<W88> {
11792    type Operand = u128;
11793    #[inline]
11794    fn apply(a: u128, b: u128) -> u128 {
11795        const_ring_eval_w88(PrimitiveOp::And, a, b)
11796    }
11797}
11798
11799impl RingOp<W88> for Or<W88> {
11800    type Operand = u128;
11801    #[inline]
11802    fn apply(a: u128, b: u128) -> u128 {
11803        const_ring_eval_w88(PrimitiveOp::Or, a, b)
11804    }
11805}
11806
11807impl RingOp<W96> for Mul<W96> {
11808    type Operand = u128;
11809    #[inline]
11810    fn apply(a: u128, b: u128) -> u128 {
11811        const_ring_eval_w96(PrimitiveOp::Mul, a, b)
11812    }
11813}
11814
11815impl RingOp<W96> for Add<W96> {
11816    type Operand = u128;
11817    #[inline]
11818    fn apply(a: u128, b: u128) -> u128 {
11819        const_ring_eval_w96(PrimitiveOp::Add, a, b)
11820    }
11821}
11822
11823impl RingOp<W96> for Sub<W96> {
11824    type Operand = u128;
11825    #[inline]
11826    fn apply(a: u128, b: u128) -> u128 {
11827        const_ring_eval_w96(PrimitiveOp::Sub, a, b)
11828    }
11829}
11830
11831impl RingOp<W96> for Xor<W96> {
11832    type Operand = u128;
11833    #[inline]
11834    fn apply(a: u128, b: u128) -> u128 {
11835        const_ring_eval_w96(PrimitiveOp::Xor, a, b)
11836    }
11837}
11838
11839impl RingOp<W96> for And<W96> {
11840    type Operand = u128;
11841    #[inline]
11842    fn apply(a: u128, b: u128) -> u128 {
11843        const_ring_eval_w96(PrimitiveOp::And, a, b)
11844    }
11845}
11846
11847impl RingOp<W96> for Or<W96> {
11848    type Operand = u128;
11849    #[inline]
11850    fn apply(a: u128, b: u128) -> u128 {
11851        const_ring_eval_w96(PrimitiveOp::Or, a, b)
11852    }
11853}
11854
11855impl RingOp<W104> for Mul<W104> {
11856    type Operand = u128;
11857    #[inline]
11858    fn apply(a: u128, b: u128) -> u128 {
11859        const_ring_eval_w104(PrimitiveOp::Mul, a, b)
11860    }
11861}
11862
11863impl RingOp<W104> for Add<W104> {
11864    type Operand = u128;
11865    #[inline]
11866    fn apply(a: u128, b: u128) -> u128 {
11867        const_ring_eval_w104(PrimitiveOp::Add, a, b)
11868    }
11869}
11870
11871impl RingOp<W104> for Sub<W104> {
11872    type Operand = u128;
11873    #[inline]
11874    fn apply(a: u128, b: u128) -> u128 {
11875        const_ring_eval_w104(PrimitiveOp::Sub, a, b)
11876    }
11877}
11878
11879impl RingOp<W104> for Xor<W104> {
11880    type Operand = u128;
11881    #[inline]
11882    fn apply(a: u128, b: u128) -> u128 {
11883        const_ring_eval_w104(PrimitiveOp::Xor, a, b)
11884    }
11885}
11886
11887impl RingOp<W104> for And<W104> {
11888    type Operand = u128;
11889    #[inline]
11890    fn apply(a: u128, b: u128) -> u128 {
11891        const_ring_eval_w104(PrimitiveOp::And, a, b)
11892    }
11893}
11894
11895impl RingOp<W104> for Or<W104> {
11896    type Operand = u128;
11897    #[inline]
11898    fn apply(a: u128, b: u128) -> u128 {
11899        const_ring_eval_w104(PrimitiveOp::Or, a, b)
11900    }
11901}
11902
11903impl RingOp<W112> for Mul<W112> {
11904    type Operand = u128;
11905    #[inline]
11906    fn apply(a: u128, b: u128) -> u128 {
11907        const_ring_eval_w112(PrimitiveOp::Mul, a, b)
11908    }
11909}
11910
11911impl RingOp<W112> for Add<W112> {
11912    type Operand = u128;
11913    #[inline]
11914    fn apply(a: u128, b: u128) -> u128 {
11915        const_ring_eval_w112(PrimitiveOp::Add, a, b)
11916    }
11917}
11918
11919impl RingOp<W112> for Sub<W112> {
11920    type Operand = u128;
11921    #[inline]
11922    fn apply(a: u128, b: u128) -> u128 {
11923        const_ring_eval_w112(PrimitiveOp::Sub, a, b)
11924    }
11925}
11926
11927impl RingOp<W112> for Xor<W112> {
11928    type Operand = u128;
11929    #[inline]
11930    fn apply(a: u128, b: u128) -> u128 {
11931        const_ring_eval_w112(PrimitiveOp::Xor, a, b)
11932    }
11933}
11934
11935impl RingOp<W112> for And<W112> {
11936    type Operand = u128;
11937    #[inline]
11938    fn apply(a: u128, b: u128) -> u128 {
11939        const_ring_eval_w112(PrimitiveOp::And, a, b)
11940    }
11941}
11942
11943impl RingOp<W112> for Or<W112> {
11944    type Operand = u128;
11945    #[inline]
11946    fn apply(a: u128, b: u128) -> u128 {
11947        const_ring_eval_w112(PrimitiveOp::Or, a, b)
11948    }
11949}
11950
11951impl RingOp<W120> for Mul<W120> {
11952    type Operand = u128;
11953    #[inline]
11954    fn apply(a: u128, b: u128) -> u128 {
11955        const_ring_eval_w120(PrimitiveOp::Mul, a, b)
11956    }
11957}
11958
11959impl RingOp<W120> for Add<W120> {
11960    type Operand = u128;
11961    #[inline]
11962    fn apply(a: u128, b: u128) -> u128 {
11963        const_ring_eval_w120(PrimitiveOp::Add, a, b)
11964    }
11965}
11966
11967impl RingOp<W120> for Sub<W120> {
11968    type Operand = u128;
11969    #[inline]
11970    fn apply(a: u128, b: u128) -> u128 {
11971        const_ring_eval_w120(PrimitiveOp::Sub, a, b)
11972    }
11973}
11974
11975impl RingOp<W120> for Xor<W120> {
11976    type Operand = u128;
11977    #[inline]
11978    fn apply(a: u128, b: u128) -> u128 {
11979        const_ring_eval_w120(PrimitiveOp::Xor, a, b)
11980    }
11981}
11982
11983impl RingOp<W120> for And<W120> {
11984    type Operand = u128;
11985    #[inline]
11986    fn apply(a: u128, b: u128) -> u128 {
11987        const_ring_eval_w120(PrimitiveOp::And, a, b)
11988    }
11989}
11990
11991impl RingOp<W120> for Or<W120> {
11992    type Operand = u128;
11993    #[inline]
11994    fn apply(a: u128, b: u128) -> u128 {
11995        const_ring_eval_w120(PrimitiveOp::Or, a, b)
11996    }
11997}
11998
11999impl RingOp<W128> for Mul<W128> {
12000    type Operand = u128;
12001    #[inline]
12002    fn apply(a: u128, b: u128) -> u128 {
12003        const_ring_eval_w128(PrimitiveOp::Mul, a, b)
12004    }
12005}
12006
12007impl RingOp<W128> for Add<W128> {
12008    type Operand = u128;
12009    #[inline]
12010    fn apply(a: u128, b: u128) -> u128 {
12011        const_ring_eval_w128(PrimitiveOp::Add, a, b)
12012    }
12013}
12014
12015impl RingOp<W128> for Sub<W128> {
12016    type Operand = u128;
12017    #[inline]
12018    fn apply(a: u128, b: u128) -> u128 {
12019        const_ring_eval_w128(PrimitiveOp::Sub, a, b)
12020    }
12021}
12022
12023impl RingOp<W128> for Xor<W128> {
12024    type Operand = u128;
12025    #[inline]
12026    fn apply(a: u128, b: u128) -> u128 {
12027        const_ring_eval_w128(PrimitiveOp::Xor, a, b)
12028    }
12029}
12030
12031impl RingOp<W128> for And<W128> {
12032    type Operand = u128;
12033    #[inline]
12034    fn apply(a: u128, b: u128) -> u128 {
12035        const_ring_eval_w128(PrimitiveOp::And, a, b)
12036    }
12037}
12038
12039impl RingOp<W128> for Or<W128> {
12040    type Operand = u128;
12041    #[inline]
12042    fn apply(a: u128, b: u128) -> u128 {
12043        const_ring_eval_w128(PrimitiveOp::Or, a, b)
12044    }
12045}
12046
12047impl UnaryRingOp<W8> for Neg<W8> {
12048    type Operand = u8;
12049    #[inline]
12050    fn apply(a: u8) -> u8 {
12051        const_ring_eval_w8(PrimitiveOp::Sub, 0, a)
12052    }
12053}
12054
12055impl UnaryRingOp<W8> for BNot<W8> {
12056    type Operand = u8;
12057    #[inline]
12058    fn apply(a: u8) -> u8 {
12059        const_ring_eval_w8(PrimitiveOp::Xor, a, u8::MAX)
12060    }
12061}
12062
12063impl UnaryRingOp<W8> for Succ<W8> {
12064    type Operand = u8;
12065    #[inline]
12066    fn apply(a: u8) -> u8 {
12067        <Neg<W8> as UnaryRingOp<W8>>::apply(<BNot<W8> as UnaryRingOp<W8>>::apply(a))
12068    }
12069}
12070
12071impl UnaryRingOp<W16> for Neg<W16> {
12072    type Operand = u16;
12073    #[inline]
12074    fn apply(a: u16) -> u16 {
12075        const_ring_eval_w16(PrimitiveOp::Sub, 0, a)
12076    }
12077}
12078
12079impl UnaryRingOp<W16> for BNot<W16> {
12080    type Operand = u16;
12081    #[inline]
12082    fn apply(a: u16) -> u16 {
12083        const_ring_eval_w16(PrimitiveOp::Xor, a, u16::MAX)
12084    }
12085}
12086
12087impl UnaryRingOp<W16> for Succ<W16> {
12088    type Operand = u16;
12089    #[inline]
12090    fn apply(a: u16) -> u16 {
12091        <Neg<W16> as UnaryRingOp<W16>>::apply(<BNot<W16> as UnaryRingOp<W16>>::apply(a))
12092    }
12093}
12094
12095impl UnaryRingOp<W24> for Neg<W24> {
12096    type Operand = u32;
12097    #[inline]
12098    fn apply(a: u32) -> u32 {
12099        const_ring_eval_w24(PrimitiveOp::Sub, 0, a)
12100    }
12101}
12102
12103impl UnaryRingOp<W24> for BNot<W24> {
12104    type Operand = u32;
12105    #[inline]
12106    fn apply(a: u32) -> u32 {
12107        const_ring_eval_w24(PrimitiveOp::Xor, a, 0x00FF_FFFFu32)
12108    }
12109}
12110
12111impl UnaryRingOp<W24> for Succ<W24> {
12112    type Operand = u32;
12113    #[inline]
12114    fn apply(a: u32) -> u32 {
12115        <Neg<W24> as UnaryRingOp<W24>>::apply(<BNot<W24> as UnaryRingOp<W24>>::apply(a))
12116    }
12117}
12118
12119impl UnaryRingOp<W32> for Neg<W32> {
12120    type Operand = u32;
12121    #[inline]
12122    fn apply(a: u32) -> u32 {
12123        const_ring_eval_w32(PrimitiveOp::Sub, 0, a)
12124    }
12125}
12126
12127impl UnaryRingOp<W32> for BNot<W32> {
12128    type Operand = u32;
12129    #[inline]
12130    fn apply(a: u32) -> u32 {
12131        const_ring_eval_w32(PrimitiveOp::Xor, a, u32::MAX)
12132    }
12133}
12134
12135impl UnaryRingOp<W32> for Succ<W32> {
12136    type Operand = u32;
12137    #[inline]
12138    fn apply(a: u32) -> u32 {
12139        <Neg<W32> as UnaryRingOp<W32>>::apply(<BNot<W32> as UnaryRingOp<W32>>::apply(a))
12140    }
12141}
12142
12143impl UnaryRingOp<W40> for Neg<W40> {
12144    type Operand = u64;
12145    #[inline]
12146    fn apply(a: u64) -> u64 {
12147        const_ring_eval_w40(PrimitiveOp::Sub, 0, a)
12148    }
12149}
12150
12151impl UnaryRingOp<W40> for BNot<W40> {
12152    type Operand = u64;
12153    #[inline]
12154    fn apply(a: u64) -> u64 {
12155        const_ring_eval_w40(PrimitiveOp::Xor, a, 0x0000_00FF_FFFF_FFFFu64)
12156    }
12157}
12158
12159impl UnaryRingOp<W40> for Succ<W40> {
12160    type Operand = u64;
12161    #[inline]
12162    fn apply(a: u64) -> u64 {
12163        <Neg<W40> as UnaryRingOp<W40>>::apply(<BNot<W40> as UnaryRingOp<W40>>::apply(a))
12164    }
12165}
12166
12167impl UnaryRingOp<W48> for Neg<W48> {
12168    type Operand = u64;
12169    #[inline]
12170    fn apply(a: u64) -> u64 {
12171        const_ring_eval_w48(PrimitiveOp::Sub, 0, a)
12172    }
12173}
12174
12175impl UnaryRingOp<W48> for BNot<W48> {
12176    type Operand = u64;
12177    #[inline]
12178    fn apply(a: u64) -> u64 {
12179        const_ring_eval_w48(PrimitiveOp::Xor, a, 0x0000_FFFF_FFFF_FFFFu64)
12180    }
12181}
12182
12183impl UnaryRingOp<W48> for Succ<W48> {
12184    type Operand = u64;
12185    #[inline]
12186    fn apply(a: u64) -> u64 {
12187        <Neg<W48> as UnaryRingOp<W48>>::apply(<BNot<W48> as UnaryRingOp<W48>>::apply(a))
12188    }
12189}
12190
12191impl UnaryRingOp<W56> for Neg<W56> {
12192    type Operand = u64;
12193    #[inline]
12194    fn apply(a: u64) -> u64 {
12195        const_ring_eval_w56(PrimitiveOp::Sub, 0, a)
12196    }
12197}
12198
12199impl UnaryRingOp<W56> for BNot<W56> {
12200    type Operand = u64;
12201    #[inline]
12202    fn apply(a: u64) -> u64 {
12203        const_ring_eval_w56(PrimitiveOp::Xor, a, 0x00FF_FFFF_FFFF_FFFFu64)
12204    }
12205}
12206
12207impl UnaryRingOp<W56> for Succ<W56> {
12208    type Operand = u64;
12209    #[inline]
12210    fn apply(a: u64) -> u64 {
12211        <Neg<W56> as UnaryRingOp<W56>>::apply(<BNot<W56> as UnaryRingOp<W56>>::apply(a))
12212    }
12213}
12214
12215impl UnaryRingOp<W64> for Neg<W64> {
12216    type Operand = u64;
12217    #[inline]
12218    fn apply(a: u64) -> u64 {
12219        const_ring_eval_w64(PrimitiveOp::Sub, 0, a)
12220    }
12221}
12222
12223impl UnaryRingOp<W64> for BNot<W64> {
12224    type Operand = u64;
12225    #[inline]
12226    fn apply(a: u64) -> u64 {
12227        const_ring_eval_w64(PrimitiveOp::Xor, a, u64::MAX)
12228    }
12229}
12230
12231impl UnaryRingOp<W64> for Succ<W64> {
12232    type Operand = u64;
12233    #[inline]
12234    fn apply(a: u64) -> u64 {
12235        <Neg<W64> as UnaryRingOp<W64>>::apply(<BNot<W64> as UnaryRingOp<W64>>::apply(a))
12236    }
12237}
12238
12239impl UnaryRingOp<W72> for Neg<W72> {
12240    type Operand = u128;
12241    #[inline]
12242    fn apply(a: u128) -> u128 {
12243        const_ring_eval_w72(PrimitiveOp::Sub, 0, a)
12244    }
12245}
12246
12247impl UnaryRingOp<W72> for BNot<W72> {
12248    type Operand = u128;
12249    #[inline]
12250    fn apply(a: u128) -> u128 {
12251        const_ring_eval_w72(PrimitiveOp::Xor, a, u128::MAX >> (128 - 72))
12252    }
12253}
12254
12255impl UnaryRingOp<W72> for Succ<W72> {
12256    type Operand = u128;
12257    #[inline]
12258    fn apply(a: u128) -> u128 {
12259        <Neg<W72> as UnaryRingOp<W72>>::apply(<BNot<W72> as UnaryRingOp<W72>>::apply(a))
12260    }
12261}
12262
12263impl UnaryRingOp<W80> for Neg<W80> {
12264    type Operand = u128;
12265    #[inline]
12266    fn apply(a: u128) -> u128 {
12267        const_ring_eval_w80(PrimitiveOp::Sub, 0, a)
12268    }
12269}
12270
12271impl UnaryRingOp<W80> for BNot<W80> {
12272    type Operand = u128;
12273    #[inline]
12274    fn apply(a: u128) -> u128 {
12275        const_ring_eval_w80(PrimitiveOp::Xor, a, u128::MAX >> (128 - 80))
12276    }
12277}
12278
12279impl UnaryRingOp<W80> for Succ<W80> {
12280    type Operand = u128;
12281    #[inline]
12282    fn apply(a: u128) -> u128 {
12283        <Neg<W80> as UnaryRingOp<W80>>::apply(<BNot<W80> as UnaryRingOp<W80>>::apply(a))
12284    }
12285}
12286
12287impl UnaryRingOp<W88> for Neg<W88> {
12288    type Operand = u128;
12289    #[inline]
12290    fn apply(a: u128) -> u128 {
12291        const_ring_eval_w88(PrimitiveOp::Sub, 0, a)
12292    }
12293}
12294
12295impl UnaryRingOp<W88> for BNot<W88> {
12296    type Operand = u128;
12297    #[inline]
12298    fn apply(a: u128) -> u128 {
12299        const_ring_eval_w88(PrimitiveOp::Xor, a, u128::MAX >> (128 - 88))
12300    }
12301}
12302
12303impl UnaryRingOp<W88> for Succ<W88> {
12304    type Operand = u128;
12305    #[inline]
12306    fn apply(a: u128) -> u128 {
12307        <Neg<W88> as UnaryRingOp<W88>>::apply(<BNot<W88> as UnaryRingOp<W88>>::apply(a))
12308    }
12309}
12310
12311impl UnaryRingOp<W96> for Neg<W96> {
12312    type Operand = u128;
12313    #[inline]
12314    fn apply(a: u128) -> u128 {
12315        const_ring_eval_w96(PrimitiveOp::Sub, 0, a)
12316    }
12317}
12318
12319impl UnaryRingOp<W96> for BNot<W96> {
12320    type Operand = u128;
12321    #[inline]
12322    fn apply(a: u128) -> u128 {
12323        const_ring_eval_w96(PrimitiveOp::Xor, a, u128::MAX >> (128 - 96))
12324    }
12325}
12326
12327impl UnaryRingOp<W96> for Succ<W96> {
12328    type Operand = u128;
12329    #[inline]
12330    fn apply(a: u128) -> u128 {
12331        <Neg<W96> as UnaryRingOp<W96>>::apply(<BNot<W96> as UnaryRingOp<W96>>::apply(a))
12332    }
12333}
12334
12335impl UnaryRingOp<W104> for Neg<W104> {
12336    type Operand = u128;
12337    #[inline]
12338    fn apply(a: u128) -> u128 {
12339        const_ring_eval_w104(PrimitiveOp::Sub, 0, a)
12340    }
12341}
12342
12343impl UnaryRingOp<W104> for BNot<W104> {
12344    type Operand = u128;
12345    #[inline]
12346    fn apply(a: u128) -> u128 {
12347        const_ring_eval_w104(PrimitiveOp::Xor, a, u128::MAX >> (128 - 104))
12348    }
12349}
12350
12351impl UnaryRingOp<W104> for Succ<W104> {
12352    type Operand = u128;
12353    #[inline]
12354    fn apply(a: u128) -> u128 {
12355        <Neg<W104> as UnaryRingOp<W104>>::apply(<BNot<W104> as UnaryRingOp<W104>>::apply(a))
12356    }
12357}
12358
12359impl UnaryRingOp<W112> for Neg<W112> {
12360    type Operand = u128;
12361    #[inline]
12362    fn apply(a: u128) -> u128 {
12363        const_ring_eval_w112(PrimitiveOp::Sub, 0, a)
12364    }
12365}
12366
12367impl UnaryRingOp<W112> for BNot<W112> {
12368    type Operand = u128;
12369    #[inline]
12370    fn apply(a: u128) -> u128 {
12371        const_ring_eval_w112(PrimitiveOp::Xor, a, u128::MAX >> (128 - 112))
12372    }
12373}
12374
12375impl UnaryRingOp<W112> for Succ<W112> {
12376    type Operand = u128;
12377    #[inline]
12378    fn apply(a: u128) -> u128 {
12379        <Neg<W112> as UnaryRingOp<W112>>::apply(<BNot<W112> as UnaryRingOp<W112>>::apply(a))
12380    }
12381}
12382
12383impl UnaryRingOp<W120> for Neg<W120> {
12384    type Operand = u128;
12385    #[inline]
12386    fn apply(a: u128) -> u128 {
12387        const_ring_eval_w120(PrimitiveOp::Sub, 0, a)
12388    }
12389}
12390
12391impl UnaryRingOp<W120> for BNot<W120> {
12392    type Operand = u128;
12393    #[inline]
12394    fn apply(a: u128) -> u128 {
12395        const_ring_eval_w120(PrimitiveOp::Xor, a, u128::MAX >> (128 - 120))
12396    }
12397}
12398
12399impl UnaryRingOp<W120> for Succ<W120> {
12400    type Operand = u128;
12401    #[inline]
12402    fn apply(a: u128) -> u128 {
12403        <Neg<W120> as UnaryRingOp<W120>>::apply(<BNot<W120> as UnaryRingOp<W120>>::apply(a))
12404    }
12405}
12406
12407impl UnaryRingOp<W128> for Neg<W128> {
12408    type Operand = u128;
12409    #[inline]
12410    fn apply(a: u128) -> u128 {
12411        const_ring_eval_w128(PrimitiveOp::Sub, 0, a)
12412    }
12413}
12414
12415impl UnaryRingOp<W128> for BNot<W128> {
12416    type Operand = u128;
12417    #[inline]
12418    fn apply(a: u128) -> u128 {
12419        const_ring_eval_w128(PrimitiveOp::Xor, a, u128::MAX)
12420    }
12421}
12422
12423impl UnaryRingOp<W128> for Succ<W128> {
12424    type Operand = u128;
12425    #[inline]
12426    fn apply(a: u128) -> u128 {
12427        <Neg<W128> as UnaryRingOp<W128>>::apply(<BNot<W128> as UnaryRingOp<W128>>::apply(a))
12428    }
12429}
12430
12431/// Sealed marker for well-formed level embedding pairs (`(From, To)` with
12432/// `From <= To`). v0.2.2 W3.
12433pub trait ValidLevelEmbedding: valid_level_embedding_sealed::Sealed {}
12434
12435mod valid_level_embedding_sealed {
12436    /// Private supertrait. Not implementable outside this crate.
12437    pub trait Sealed {}
12438    impl Sealed for (super::W8, super::W8) {}
12439    impl Sealed for (super::W8, super::W16) {}
12440    impl Sealed for (super::W8, super::W24) {}
12441    impl Sealed for (super::W8, super::W32) {}
12442    impl Sealed for (super::W8, super::W40) {}
12443    impl Sealed for (super::W8, super::W48) {}
12444    impl Sealed for (super::W8, super::W56) {}
12445    impl Sealed for (super::W8, super::W64) {}
12446    impl Sealed for (super::W8, super::W72) {}
12447    impl Sealed for (super::W8, super::W80) {}
12448    impl Sealed for (super::W8, super::W88) {}
12449    impl Sealed for (super::W8, super::W96) {}
12450    impl Sealed for (super::W8, super::W104) {}
12451    impl Sealed for (super::W8, super::W112) {}
12452    impl Sealed for (super::W8, super::W120) {}
12453    impl Sealed for (super::W8, super::W128) {}
12454    impl Sealed for (super::W16, super::W16) {}
12455    impl Sealed for (super::W16, super::W24) {}
12456    impl Sealed for (super::W16, super::W32) {}
12457    impl Sealed for (super::W16, super::W40) {}
12458    impl Sealed for (super::W16, super::W48) {}
12459    impl Sealed for (super::W16, super::W56) {}
12460    impl Sealed for (super::W16, super::W64) {}
12461    impl Sealed for (super::W16, super::W72) {}
12462    impl Sealed for (super::W16, super::W80) {}
12463    impl Sealed for (super::W16, super::W88) {}
12464    impl Sealed for (super::W16, super::W96) {}
12465    impl Sealed for (super::W16, super::W104) {}
12466    impl Sealed for (super::W16, super::W112) {}
12467    impl Sealed for (super::W16, super::W120) {}
12468    impl Sealed for (super::W16, super::W128) {}
12469    impl Sealed for (super::W24, super::W24) {}
12470    impl Sealed for (super::W24, super::W32) {}
12471    impl Sealed for (super::W24, super::W40) {}
12472    impl Sealed for (super::W24, super::W48) {}
12473    impl Sealed for (super::W24, super::W56) {}
12474    impl Sealed for (super::W24, super::W64) {}
12475    impl Sealed for (super::W24, super::W72) {}
12476    impl Sealed for (super::W24, super::W80) {}
12477    impl Sealed for (super::W24, super::W88) {}
12478    impl Sealed for (super::W24, super::W96) {}
12479    impl Sealed for (super::W24, super::W104) {}
12480    impl Sealed for (super::W24, super::W112) {}
12481    impl Sealed for (super::W24, super::W120) {}
12482    impl Sealed for (super::W24, super::W128) {}
12483    impl Sealed for (super::W32, super::W32) {}
12484    impl Sealed for (super::W32, super::W40) {}
12485    impl Sealed for (super::W32, super::W48) {}
12486    impl Sealed for (super::W32, super::W56) {}
12487    impl Sealed for (super::W32, super::W64) {}
12488    impl Sealed for (super::W32, super::W72) {}
12489    impl Sealed for (super::W32, super::W80) {}
12490    impl Sealed for (super::W32, super::W88) {}
12491    impl Sealed for (super::W32, super::W96) {}
12492    impl Sealed for (super::W32, super::W104) {}
12493    impl Sealed for (super::W32, super::W112) {}
12494    impl Sealed for (super::W32, super::W120) {}
12495    impl Sealed for (super::W32, super::W128) {}
12496    impl Sealed for (super::W40, super::W40) {}
12497    impl Sealed for (super::W40, super::W48) {}
12498    impl Sealed for (super::W40, super::W56) {}
12499    impl Sealed for (super::W40, super::W64) {}
12500    impl Sealed for (super::W40, super::W72) {}
12501    impl Sealed for (super::W40, super::W80) {}
12502    impl Sealed for (super::W40, super::W88) {}
12503    impl Sealed for (super::W40, super::W96) {}
12504    impl Sealed for (super::W40, super::W104) {}
12505    impl Sealed for (super::W40, super::W112) {}
12506    impl Sealed for (super::W40, super::W120) {}
12507    impl Sealed for (super::W40, super::W128) {}
12508    impl Sealed for (super::W48, super::W48) {}
12509    impl Sealed for (super::W48, super::W56) {}
12510    impl Sealed for (super::W48, super::W64) {}
12511    impl Sealed for (super::W48, super::W72) {}
12512    impl Sealed for (super::W48, super::W80) {}
12513    impl Sealed for (super::W48, super::W88) {}
12514    impl Sealed for (super::W48, super::W96) {}
12515    impl Sealed for (super::W48, super::W104) {}
12516    impl Sealed for (super::W48, super::W112) {}
12517    impl Sealed for (super::W48, super::W120) {}
12518    impl Sealed for (super::W48, super::W128) {}
12519    impl Sealed for (super::W56, super::W56) {}
12520    impl Sealed for (super::W56, super::W64) {}
12521    impl Sealed for (super::W56, super::W72) {}
12522    impl Sealed for (super::W56, super::W80) {}
12523    impl Sealed for (super::W56, super::W88) {}
12524    impl Sealed for (super::W56, super::W96) {}
12525    impl Sealed for (super::W56, super::W104) {}
12526    impl Sealed for (super::W56, super::W112) {}
12527    impl Sealed for (super::W56, super::W120) {}
12528    impl Sealed for (super::W56, super::W128) {}
12529    impl Sealed for (super::W64, super::W64) {}
12530    impl Sealed for (super::W64, super::W72) {}
12531    impl Sealed for (super::W64, super::W80) {}
12532    impl Sealed for (super::W64, super::W88) {}
12533    impl Sealed for (super::W64, super::W96) {}
12534    impl Sealed for (super::W64, super::W104) {}
12535    impl Sealed for (super::W64, super::W112) {}
12536    impl Sealed for (super::W64, super::W120) {}
12537    impl Sealed for (super::W64, super::W128) {}
12538    impl Sealed for (super::W72, super::W72) {}
12539    impl Sealed for (super::W72, super::W80) {}
12540    impl Sealed for (super::W72, super::W88) {}
12541    impl Sealed for (super::W72, super::W96) {}
12542    impl Sealed for (super::W72, super::W104) {}
12543    impl Sealed for (super::W72, super::W112) {}
12544    impl Sealed for (super::W72, super::W120) {}
12545    impl Sealed for (super::W72, super::W128) {}
12546    impl Sealed for (super::W80, super::W80) {}
12547    impl Sealed for (super::W80, super::W88) {}
12548    impl Sealed for (super::W80, super::W96) {}
12549    impl Sealed for (super::W80, super::W104) {}
12550    impl Sealed for (super::W80, super::W112) {}
12551    impl Sealed for (super::W80, super::W120) {}
12552    impl Sealed for (super::W80, super::W128) {}
12553    impl Sealed for (super::W88, super::W88) {}
12554    impl Sealed for (super::W88, super::W96) {}
12555    impl Sealed for (super::W88, super::W104) {}
12556    impl Sealed for (super::W88, super::W112) {}
12557    impl Sealed for (super::W88, super::W120) {}
12558    impl Sealed for (super::W88, super::W128) {}
12559    impl Sealed for (super::W96, super::W96) {}
12560    impl Sealed for (super::W96, super::W104) {}
12561    impl Sealed for (super::W96, super::W112) {}
12562    impl Sealed for (super::W96, super::W120) {}
12563    impl Sealed for (super::W96, super::W128) {}
12564    impl Sealed for (super::W104, super::W104) {}
12565    impl Sealed for (super::W104, super::W112) {}
12566    impl Sealed for (super::W104, super::W120) {}
12567    impl Sealed for (super::W104, super::W128) {}
12568    impl Sealed for (super::W112, super::W112) {}
12569    impl Sealed for (super::W112, super::W120) {}
12570    impl Sealed for (super::W112, super::W128) {}
12571    impl Sealed for (super::W120, super::W120) {}
12572    impl Sealed for (super::W120, super::W128) {}
12573    impl Sealed for (super::W128, super::W128) {}
12574}
12575
12576impl ValidLevelEmbedding for (W8, W8) {}
12577impl ValidLevelEmbedding for (W8, W16) {}
12578impl ValidLevelEmbedding for (W8, W24) {}
12579impl ValidLevelEmbedding for (W8, W32) {}
12580impl ValidLevelEmbedding for (W8, W40) {}
12581impl ValidLevelEmbedding for (W8, W48) {}
12582impl ValidLevelEmbedding for (W8, W56) {}
12583impl ValidLevelEmbedding for (W8, W64) {}
12584impl ValidLevelEmbedding for (W8, W72) {}
12585impl ValidLevelEmbedding for (W8, W80) {}
12586impl ValidLevelEmbedding for (W8, W88) {}
12587impl ValidLevelEmbedding for (W8, W96) {}
12588impl ValidLevelEmbedding for (W8, W104) {}
12589impl ValidLevelEmbedding for (W8, W112) {}
12590impl ValidLevelEmbedding for (W8, W120) {}
12591impl ValidLevelEmbedding for (W8, W128) {}
12592impl ValidLevelEmbedding for (W16, W16) {}
12593impl ValidLevelEmbedding for (W16, W24) {}
12594impl ValidLevelEmbedding for (W16, W32) {}
12595impl ValidLevelEmbedding for (W16, W40) {}
12596impl ValidLevelEmbedding for (W16, W48) {}
12597impl ValidLevelEmbedding for (W16, W56) {}
12598impl ValidLevelEmbedding for (W16, W64) {}
12599impl ValidLevelEmbedding for (W16, W72) {}
12600impl ValidLevelEmbedding for (W16, W80) {}
12601impl ValidLevelEmbedding for (W16, W88) {}
12602impl ValidLevelEmbedding for (W16, W96) {}
12603impl ValidLevelEmbedding for (W16, W104) {}
12604impl ValidLevelEmbedding for (W16, W112) {}
12605impl ValidLevelEmbedding for (W16, W120) {}
12606impl ValidLevelEmbedding for (W16, W128) {}
12607impl ValidLevelEmbedding for (W24, W24) {}
12608impl ValidLevelEmbedding for (W24, W32) {}
12609impl ValidLevelEmbedding for (W24, W40) {}
12610impl ValidLevelEmbedding for (W24, W48) {}
12611impl ValidLevelEmbedding for (W24, W56) {}
12612impl ValidLevelEmbedding for (W24, W64) {}
12613impl ValidLevelEmbedding for (W24, W72) {}
12614impl ValidLevelEmbedding for (W24, W80) {}
12615impl ValidLevelEmbedding for (W24, W88) {}
12616impl ValidLevelEmbedding for (W24, W96) {}
12617impl ValidLevelEmbedding for (W24, W104) {}
12618impl ValidLevelEmbedding for (W24, W112) {}
12619impl ValidLevelEmbedding for (W24, W120) {}
12620impl ValidLevelEmbedding for (W24, W128) {}
12621impl ValidLevelEmbedding for (W32, W32) {}
12622impl ValidLevelEmbedding for (W32, W40) {}
12623impl ValidLevelEmbedding for (W32, W48) {}
12624impl ValidLevelEmbedding for (W32, W56) {}
12625impl ValidLevelEmbedding for (W32, W64) {}
12626impl ValidLevelEmbedding for (W32, W72) {}
12627impl ValidLevelEmbedding for (W32, W80) {}
12628impl ValidLevelEmbedding for (W32, W88) {}
12629impl ValidLevelEmbedding for (W32, W96) {}
12630impl ValidLevelEmbedding for (W32, W104) {}
12631impl ValidLevelEmbedding for (W32, W112) {}
12632impl ValidLevelEmbedding for (W32, W120) {}
12633impl ValidLevelEmbedding for (W32, W128) {}
12634impl ValidLevelEmbedding for (W40, W40) {}
12635impl ValidLevelEmbedding for (W40, W48) {}
12636impl ValidLevelEmbedding for (W40, W56) {}
12637impl ValidLevelEmbedding for (W40, W64) {}
12638impl ValidLevelEmbedding for (W40, W72) {}
12639impl ValidLevelEmbedding for (W40, W80) {}
12640impl ValidLevelEmbedding for (W40, W88) {}
12641impl ValidLevelEmbedding for (W40, W96) {}
12642impl ValidLevelEmbedding for (W40, W104) {}
12643impl ValidLevelEmbedding for (W40, W112) {}
12644impl ValidLevelEmbedding for (W40, W120) {}
12645impl ValidLevelEmbedding for (W40, W128) {}
12646impl ValidLevelEmbedding for (W48, W48) {}
12647impl ValidLevelEmbedding for (W48, W56) {}
12648impl ValidLevelEmbedding for (W48, W64) {}
12649impl ValidLevelEmbedding for (W48, W72) {}
12650impl ValidLevelEmbedding for (W48, W80) {}
12651impl ValidLevelEmbedding for (W48, W88) {}
12652impl ValidLevelEmbedding for (W48, W96) {}
12653impl ValidLevelEmbedding for (W48, W104) {}
12654impl ValidLevelEmbedding for (W48, W112) {}
12655impl ValidLevelEmbedding for (W48, W120) {}
12656impl ValidLevelEmbedding for (W48, W128) {}
12657impl ValidLevelEmbedding for (W56, W56) {}
12658impl ValidLevelEmbedding for (W56, W64) {}
12659impl ValidLevelEmbedding for (W56, W72) {}
12660impl ValidLevelEmbedding for (W56, W80) {}
12661impl ValidLevelEmbedding for (W56, W88) {}
12662impl ValidLevelEmbedding for (W56, W96) {}
12663impl ValidLevelEmbedding for (W56, W104) {}
12664impl ValidLevelEmbedding for (W56, W112) {}
12665impl ValidLevelEmbedding for (W56, W120) {}
12666impl ValidLevelEmbedding for (W56, W128) {}
12667impl ValidLevelEmbedding for (W64, W64) {}
12668impl ValidLevelEmbedding for (W64, W72) {}
12669impl ValidLevelEmbedding for (W64, W80) {}
12670impl ValidLevelEmbedding for (W64, W88) {}
12671impl ValidLevelEmbedding for (W64, W96) {}
12672impl ValidLevelEmbedding for (W64, W104) {}
12673impl ValidLevelEmbedding for (W64, W112) {}
12674impl ValidLevelEmbedding for (W64, W120) {}
12675impl ValidLevelEmbedding for (W64, W128) {}
12676impl ValidLevelEmbedding for (W72, W72) {}
12677impl ValidLevelEmbedding for (W72, W80) {}
12678impl ValidLevelEmbedding for (W72, W88) {}
12679impl ValidLevelEmbedding for (W72, W96) {}
12680impl ValidLevelEmbedding for (W72, W104) {}
12681impl ValidLevelEmbedding for (W72, W112) {}
12682impl ValidLevelEmbedding for (W72, W120) {}
12683impl ValidLevelEmbedding for (W72, W128) {}
12684impl ValidLevelEmbedding for (W80, W80) {}
12685impl ValidLevelEmbedding for (W80, W88) {}
12686impl ValidLevelEmbedding for (W80, W96) {}
12687impl ValidLevelEmbedding for (W80, W104) {}
12688impl ValidLevelEmbedding for (W80, W112) {}
12689impl ValidLevelEmbedding for (W80, W120) {}
12690impl ValidLevelEmbedding for (W80, W128) {}
12691impl ValidLevelEmbedding for (W88, W88) {}
12692impl ValidLevelEmbedding for (W88, W96) {}
12693impl ValidLevelEmbedding for (W88, W104) {}
12694impl ValidLevelEmbedding for (W88, W112) {}
12695impl ValidLevelEmbedding for (W88, W120) {}
12696impl ValidLevelEmbedding for (W88, W128) {}
12697impl ValidLevelEmbedding for (W96, W96) {}
12698impl ValidLevelEmbedding for (W96, W104) {}
12699impl ValidLevelEmbedding for (W96, W112) {}
12700impl ValidLevelEmbedding for (W96, W120) {}
12701impl ValidLevelEmbedding for (W96, W128) {}
12702impl ValidLevelEmbedding for (W104, W104) {}
12703impl ValidLevelEmbedding for (W104, W112) {}
12704impl ValidLevelEmbedding for (W104, W120) {}
12705impl ValidLevelEmbedding for (W104, W128) {}
12706impl ValidLevelEmbedding for (W112, W112) {}
12707impl ValidLevelEmbedding for (W112, W120) {}
12708impl ValidLevelEmbedding for (W112, W128) {}
12709impl ValidLevelEmbedding for (W120, W120) {}
12710impl ValidLevelEmbedding for (W120, W128) {}
12711impl ValidLevelEmbedding for (W128, W128) {}
12712
12713/// v0.2.2 W3: phantom-typed level embedding `Embed<From, To>` for the
12714/// canonical injection ι : R_From → R_To when `From <= To`.
12715/// Implementations exist only for sealed `(From, To)` pairs in the
12716/// `ValidLevelEmbedding` trait, so attempting an unsupported direction
12717/// (e.g., `Embed<W32, W8>`) fails at compile time.
12718#[derive(Debug, Default, Clone, Copy)]
12719pub struct Embed<From, To>(PhantomData<(From, To)>);
12720
12721impl Embed<W8, W8> {
12722    /// Embed a `u8` value at W8 into a `u8` value at W8.
12723    #[inline]
12724    #[must_use]
12725    pub const fn apply(value: u8) -> u8 {
12726        value
12727    }
12728}
12729
12730impl Embed<W8, W16> {
12731    /// Embed a `u8` value at W8 into a `u16` value at W16.
12732    #[inline]
12733    #[must_use]
12734    pub const fn apply(value: u8) -> u16 {
12735        value as u16
12736    }
12737}
12738
12739impl Embed<W8, W24> {
12740    /// Embed a `u8` value at W8 into a `u32` value at W24.
12741    #[inline]
12742    #[must_use]
12743    pub const fn apply(value: u8) -> u32 {
12744        value as u32
12745    }
12746}
12747
12748impl Embed<W8, W32> {
12749    /// Embed a `u8` value at W8 into a `u32` value at W32.
12750    #[inline]
12751    #[must_use]
12752    pub const fn apply(value: u8) -> u32 {
12753        value as u32
12754    }
12755}
12756
12757impl Embed<W8, W40> {
12758    /// Embed a `u8` value at W8 into a `u64` value at W40.
12759    #[inline]
12760    #[must_use]
12761    pub const fn apply(value: u8) -> u64 {
12762        value as u64
12763    }
12764}
12765
12766impl Embed<W8, W48> {
12767    /// Embed a `u8` value at W8 into a `u64` value at W48.
12768    #[inline]
12769    #[must_use]
12770    pub const fn apply(value: u8) -> u64 {
12771        value as u64
12772    }
12773}
12774
12775impl Embed<W8, W56> {
12776    /// Embed a `u8` value at W8 into a `u64` value at W56.
12777    #[inline]
12778    #[must_use]
12779    pub const fn apply(value: u8) -> u64 {
12780        value as u64
12781    }
12782}
12783
12784impl Embed<W8, W64> {
12785    /// Embed a `u8` value at W8 into a `u64` value at W64.
12786    #[inline]
12787    #[must_use]
12788    pub const fn apply(value: u8) -> u64 {
12789        value as u64
12790    }
12791}
12792
12793impl Embed<W8, W72> {
12794    /// Embed a `u8` value at W8 into a `u128` value at W72.
12795    #[inline]
12796    #[must_use]
12797    pub const fn apply(value: u8) -> u128 {
12798        value as u128
12799    }
12800}
12801
12802impl Embed<W8, W80> {
12803    /// Embed a `u8` value at W8 into a `u128` value at W80.
12804    #[inline]
12805    #[must_use]
12806    pub const fn apply(value: u8) -> u128 {
12807        value as u128
12808    }
12809}
12810
12811impl Embed<W8, W88> {
12812    /// Embed a `u8` value at W8 into a `u128` value at W88.
12813    #[inline]
12814    #[must_use]
12815    pub const fn apply(value: u8) -> u128 {
12816        value as u128
12817    }
12818}
12819
12820impl Embed<W8, W96> {
12821    /// Embed a `u8` value at W8 into a `u128` value at W96.
12822    #[inline]
12823    #[must_use]
12824    pub const fn apply(value: u8) -> u128 {
12825        value as u128
12826    }
12827}
12828
12829impl Embed<W8, W104> {
12830    /// Embed a `u8` value at W8 into a `u128` value at W104.
12831    #[inline]
12832    #[must_use]
12833    pub const fn apply(value: u8) -> u128 {
12834        value as u128
12835    }
12836}
12837
12838impl Embed<W8, W112> {
12839    /// Embed a `u8` value at W8 into a `u128` value at W112.
12840    #[inline]
12841    #[must_use]
12842    pub const fn apply(value: u8) -> u128 {
12843        value as u128
12844    }
12845}
12846
12847impl Embed<W8, W120> {
12848    /// Embed a `u8` value at W8 into a `u128` value at W120.
12849    #[inline]
12850    #[must_use]
12851    pub const fn apply(value: u8) -> u128 {
12852        value as u128
12853    }
12854}
12855
12856impl Embed<W8, W128> {
12857    /// Embed a `u8` value at W8 into a `u128` value at W128.
12858    #[inline]
12859    #[must_use]
12860    pub const fn apply(value: u8) -> u128 {
12861        value as u128
12862    }
12863}
12864
12865impl Embed<W16, W16> {
12866    /// Embed a `u16` value at W16 into a `u16` value at W16.
12867    #[inline]
12868    #[must_use]
12869    pub const fn apply(value: u16) -> u16 {
12870        value
12871    }
12872}
12873
12874impl Embed<W16, W24> {
12875    /// Embed a `u16` value at W16 into a `u32` value at W24.
12876    #[inline]
12877    #[must_use]
12878    pub const fn apply(value: u16) -> u32 {
12879        value as u32
12880    }
12881}
12882
12883impl Embed<W16, W32> {
12884    /// Embed a `u16` value at W16 into a `u32` value at W32.
12885    #[inline]
12886    #[must_use]
12887    pub const fn apply(value: u16) -> u32 {
12888        value as u32
12889    }
12890}
12891
12892impl Embed<W16, W40> {
12893    /// Embed a `u16` value at W16 into a `u64` value at W40.
12894    #[inline]
12895    #[must_use]
12896    pub const fn apply(value: u16) -> u64 {
12897        value as u64
12898    }
12899}
12900
12901impl Embed<W16, W48> {
12902    /// Embed a `u16` value at W16 into a `u64` value at W48.
12903    #[inline]
12904    #[must_use]
12905    pub const fn apply(value: u16) -> u64 {
12906        value as u64
12907    }
12908}
12909
12910impl Embed<W16, W56> {
12911    /// Embed a `u16` value at W16 into a `u64` value at W56.
12912    #[inline]
12913    #[must_use]
12914    pub const fn apply(value: u16) -> u64 {
12915        value as u64
12916    }
12917}
12918
12919impl Embed<W16, W64> {
12920    /// Embed a `u16` value at W16 into a `u64` value at W64.
12921    #[inline]
12922    #[must_use]
12923    pub const fn apply(value: u16) -> u64 {
12924        value as u64
12925    }
12926}
12927
12928impl Embed<W16, W72> {
12929    /// Embed a `u16` value at W16 into a `u128` value at W72.
12930    #[inline]
12931    #[must_use]
12932    pub const fn apply(value: u16) -> u128 {
12933        value as u128
12934    }
12935}
12936
12937impl Embed<W16, W80> {
12938    /// Embed a `u16` value at W16 into a `u128` value at W80.
12939    #[inline]
12940    #[must_use]
12941    pub const fn apply(value: u16) -> u128 {
12942        value as u128
12943    }
12944}
12945
12946impl Embed<W16, W88> {
12947    /// Embed a `u16` value at W16 into a `u128` value at W88.
12948    #[inline]
12949    #[must_use]
12950    pub const fn apply(value: u16) -> u128 {
12951        value as u128
12952    }
12953}
12954
12955impl Embed<W16, W96> {
12956    /// Embed a `u16` value at W16 into a `u128` value at W96.
12957    #[inline]
12958    #[must_use]
12959    pub const fn apply(value: u16) -> u128 {
12960        value as u128
12961    }
12962}
12963
12964impl Embed<W16, W104> {
12965    /// Embed a `u16` value at W16 into a `u128` value at W104.
12966    #[inline]
12967    #[must_use]
12968    pub const fn apply(value: u16) -> u128 {
12969        value as u128
12970    }
12971}
12972
12973impl Embed<W16, W112> {
12974    /// Embed a `u16` value at W16 into a `u128` value at W112.
12975    #[inline]
12976    #[must_use]
12977    pub const fn apply(value: u16) -> u128 {
12978        value as u128
12979    }
12980}
12981
12982impl Embed<W16, W120> {
12983    /// Embed a `u16` value at W16 into a `u128` value at W120.
12984    #[inline]
12985    #[must_use]
12986    pub const fn apply(value: u16) -> u128 {
12987        value as u128
12988    }
12989}
12990
12991impl Embed<W16, W128> {
12992    /// Embed a `u16` value at W16 into a `u128` value at W128.
12993    #[inline]
12994    #[must_use]
12995    pub const fn apply(value: u16) -> u128 {
12996        value as u128
12997    }
12998}
12999
13000impl Embed<W24, W24> {
13001    /// Embed a `u32` value at W24 into a `u32` value at W24.
13002    #[inline]
13003    #[must_use]
13004    pub const fn apply(value: u32) -> u32 {
13005        value
13006    }
13007}
13008
13009impl Embed<W24, W32> {
13010    /// Embed a `u32` value at W24 into a `u32` value at W32.
13011    #[inline]
13012    #[must_use]
13013    pub const fn apply(value: u32) -> u32 {
13014        value
13015    }
13016}
13017
13018impl Embed<W24, W40> {
13019    /// Embed a `u32` value at W24 into a `u64` value at W40.
13020    #[inline]
13021    #[must_use]
13022    pub const fn apply(value: u32) -> u64 {
13023        value as u64
13024    }
13025}
13026
13027impl Embed<W24, W48> {
13028    /// Embed a `u32` value at W24 into a `u64` value at W48.
13029    #[inline]
13030    #[must_use]
13031    pub const fn apply(value: u32) -> u64 {
13032        value as u64
13033    }
13034}
13035
13036impl Embed<W24, W56> {
13037    /// Embed a `u32` value at W24 into a `u64` value at W56.
13038    #[inline]
13039    #[must_use]
13040    pub const fn apply(value: u32) -> u64 {
13041        value as u64
13042    }
13043}
13044
13045impl Embed<W24, W64> {
13046    /// Embed a `u32` value at W24 into a `u64` value at W64.
13047    #[inline]
13048    #[must_use]
13049    pub const fn apply(value: u32) -> u64 {
13050        value as u64
13051    }
13052}
13053
13054impl Embed<W24, W72> {
13055    /// Embed a `u32` value at W24 into a `u128` value at W72.
13056    #[inline]
13057    #[must_use]
13058    pub const fn apply(value: u32) -> u128 {
13059        value as u128
13060    }
13061}
13062
13063impl Embed<W24, W80> {
13064    /// Embed a `u32` value at W24 into a `u128` value at W80.
13065    #[inline]
13066    #[must_use]
13067    pub const fn apply(value: u32) -> u128 {
13068        value as u128
13069    }
13070}
13071
13072impl Embed<W24, W88> {
13073    /// Embed a `u32` value at W24 into a `u128` value at W88.
13074    #[inline]
13075    #[must_use]
13076    pub const fn apply(value: u32) -> u128 {
13077        value as u128
13078    }
13079}
13080
13081impl Embed<W24, W96> {
13082    /// Embed a `u32` value at W24 into a `u128` value at W96.
13083    #[inline]
13084    #[must_use]
13085    pub const fn apply(value: u32) -> u128 {
13086        value as u128
13087    }
13088}
13089
13090impl Embed<W24, W104> {
13091    /// Embed a `u32` value at W24 into a `u128` value at W104.
13092    #[inline]
13093    #[must_use]
13094    pub const fn apply(value: u32) -> u128 {
13095        value as u128
13096    }
13097}
13098
13099impl Embed<W24, W112> {
13100    /// Embed a `u32` value at W24 into a `u128` value at W112.
13101    #[inline]
13102    #[must_use]
13103    pub const fn apply(value: u32) -> u128 {
13104        value as u128
13105    }
13106}
13107
13108impl Embed<W24, W120> {
13109    /// Embed a `u32` value at W24 into a `u128` value at W120.
13110    #[inline]
13111    #[must_use]
13112    pub const fn apply(value: u32) -> u128 {
13113        value as u128
13114    }
13115}
13116
13117impl Embed<W24, W128> {
13118    /// Embed a `u32` value at W24 into a `u128` value at W128.
13119    #[inline]
13120    #[must_use]
13121    pub const fn apply(value: u32) -> u128 {
13122        value as u128
13123    }
13124}
13125
13126impl Embed<W32, W32> {
13127    /// Embed a `u32` value at W32 into a `u32` value at W32.
13128    #[inline]
13129    #[must_use]
13130    pub const fn apply(value: u32) -> u32 {
13131        value
13132    }
13133}
13134
13135impl Embed<W32, W40> {
13136    /// Embed a `u32` value at W32 into a `u64` value at W40.
13137    #[inline]
13138    #[must_use]
13139    pub const fn apply(value: u32) -> u64 {
13140        value as u64
13141    }
13142}
13143
13144impl Embed<W32, W48> {
13145    /// Embed a `u32` value at W32 into a `u64` value at W48.
13146    #[inline]
13147    #[must_use]
13148    pub const fn apply(value: u32) -> u64 {
13149        value as u64
13150    }
13151}
13152
13153impl Embed<W32, W56> {
13154    /// Embed a `u32` value at W32 into a `u64` value at W56.
13155    #[inline]
13156    #[must_use]
13157    pub const fn apply(value: u32) -> u64 {
13158        value as u64
13159    }
13160}
13161
13162impl Embed<W32, W64> {
13163    /// Embed a `u32` value at W32 into a `u64` value at W64.
13164    #[inline]
13165    #[must_use]
13166    pub const fn apply(value: u32) -> u64 {
13167        value as u64
13168    }
13169}
13170
13171impl Embed<W32, W72> {
13172    /// Embed a `u32` value at W32 into a `u128` value at W72.
13173    #[inline]
13174    #[must_use]
13175    pub const fn apply(value: u32) -> u128 {
13176        value as u128
13177    }
13178}
13179
13180impl Embed<W32, W80> {
13181    /// Embed a `u32` value at W32 into a `u128` value at W80.
13182    #[inline]
13183    #[must_use]
13184    pub const fn apply(value: u32) -> u128 {
13185        value as u128
13186    }
13187}
13188
13189impl Embed<W32, W88> {
13190    /// Embed a `u32` value at W32 into a `u128` value at W88.
13191    #[inline]
13192    #[must_use]
13193    pub const fn apply(value: u32) -> u128 {
13194        value as u128
13195    }
13196}
13197
13198impl Embed<W32, W96> {
13199    /// Embed a `u32` value at W32 into a `u128` value at W96.
13200    #[inline]
13201    #[must_use]
13202    pub const fn apply(value: u32) -> u128 {
13203        value as u128
13204    }
13205}
13206
13207impl Embed<W32, W104> {
13208    /// Embed a `u32` value at W32 into a `u128` value at W104.
13209    #[inline]
13210    #[must_use]
13211    pub const fn apply(value: u32) -> u128 {
13212        value as u128
13213    }
13214}
13215
13216impl Embed<W32, W112> {
13217    /// Embed a `u32` value at W32 into a `u128` value at W112.
13218    #[inline]
13219    #[must_use]
13220    pub const fn apply(value: u32) -> u128 {
13221        value as u128
13222    }
13223}
13224
13225impl Embed<W32, W120> {
13226    /// Embed a `u32` value at W32 into a `u128` value at W120.
13227    #[inline]
13228    #[must_use]
13229    pub const fn apply(value: u32) -> u128 {
13230        value as u128
13231    }
13232}
13233
13234impl Embed<W32, W128> {
13235    /// Embed a `u32` value at W32 into a `u128` value at W128.
13236    #[inline]
13237    #[must_use]
13238    pub const fn apply(value: u32) -> u128 {
13239        value as u128
13240    }
13241}
13242
13243impl Embed<W40, W40> {
13244    /// Embed a `u64` value at W40 into a `u64` value at W40.
13245    #[inline]
13246    #[must_use]
13247    pub const fn apply(value: u64) -> u64 {
13248        value
13249    }
13250}
13251
13252impl Embed<W40, W48> {
13253    /// Embed a `u64` value at W40 into a `u64` value at W48.
13254    #[inline]
13255    #[must_use]
13256    pub const fn apply(value: u64) -> u64 {
13257        value
13258    }
13259}
13260
13261impl Embed<W40, W56> {
13262    /// Embed a `u64` value at W40 into a `u64` value at W56.
13263    #[inline]
13264    #[must_use]
13265    pub const fn apply(value: u64) -> u64 {
13266        value
13267    }
13268}
13269
13270impl Embed<W40, W64> {
13271    /// Embed a `u64` value at W40 into a `u64` value at W64.
13272    #[inline]
13273    #[must_use]
13274    pub const fn apply(value: u64) -> u64 {
13275        value
13276    }
13277}
13278
13279impl Embed<W40, W72> {
13280    /// Embed a `u64` value at W40 into a `u128` value at W72.
13281    #[inline]
13282    #[must_use]
13283    pub const fn apply(value: u64) -> u128 {
13284        value as u128
13285    }
13286}
13287
13288impl Embed<W40, W80> {
13289    /// Embed a `u64` value at W40 into a `u128` value at W80.
13290    #[inline]
13291    #[must_use]
13292    pub const fn apply(value: u64) -> u128 {
13293        value as u128
13294    }
13295}
13296
13297impl Embed<W40, W88> {
13298    /// Embed a `u64` value at W40 into a `u128` value at W88.
13299    #[inline]
13300    #[must_use]
13301    pub const fn apply(value: u64) -> u128 {
13302        value as u128
13303    }
13304}
13305
13306impl Embed<W40, W96> {
13307    /// Embed a `u64` value at W40 into a `u128` value at W96.
13308    #[inline]
13309    #[must_use]
13310    pub const fn apply(value: u64) -> u128 {
13311        value as u128
13312    }
13313}
13314
13315impl Embed<W40, W104> {
13316    /// Embed a `u64` value at W40 into a `u128` value at W104.
13317    #[inline]
13318    #[must_use]
13319    pub const fn apply(value: u64) -> u128 {
13320        value as u128
13321    }
13322}
13323
13324impl Embed<W40, W112> {
13325    /// Embed a `u64` value at W40 into a `u128` value at W112.
13326    #[inline]
13327    #[must_use]
13328    pub const fn apply(value: u64) -> u128 {
13329        value as u128
13330    }
13331}
13332
13333impl Embed<W40, W120> {
13334    /// Embed a `u64` value at W40 into a `u128` value at W120.
13335    #[inline]
13336    #[must_use]
13337    pub const fn apply(value: u64) -> u128 {
13338        value as u128
13339    }
13340}
13341
13342impl Embed<W40, W128> {
13343    /// Embed a `u64` value at W40 into a `u128` value at W128.
13344    #[inline]
13345    #[must_use]
13346    pub const fn apply(value: u64) -> u128 {
13347        value as u128
13348    }
13349}
13350
13351impl Embed<W48, W48> {
13352    /// Embed a `u64` value at W48 into a `u64` value at W48.
13353    #[inline]
13354    #[must_use]
13355    pub const fn apply(value: u64) -> u64 {
13356        value
13357    }
13358}
13359
13360impl Embed<W48, W56> {
13361    /// Embed a `u64` value at W48 into a `u64` value at W56.
13362    #[inline]
13363    #[must_use]
13364    pub const fn apply(value: u64) -> u64 {
13365        value
13366    }
13367}
13368
13369impl Embed<W48, W64> {
13370    /// Embed a `u64` value at W48 into a `u64` value at W64.
13371    #[inline]
13372    #[must_use]
13373    pub const fn apply(value: u64) -> u64 {
13374        value
13375    }
13376}
13377
13378impl Embed<W48, W72> {
13379    /// Embed a `u64` value at W48 into a `u128` value at W72.
13380    #[inline]
13381    #[must_use]
13382    pub const fn apply(value: u64) -> u128 {
13383        value as u128
13384    }
13385}
13386
13387impl Embed<W48, W80> {
13388    /// Embed a `u64` value at W48 into a `u128` value at W80.
13389    #[inline]
13390    #[must_use]
13391    pub const fn apply(value: u64) -> u128 {
13392        value as u128
13393    }
13394}
13395
13396impl Embed<W48, W88> {
13397    /// Embed a `u64` value at W48 into a `u128` value at W88.
13398    #[inline]
13399    #[must_use]
13400    pub const fn apply(value: u64) -> u128 {
13401        value as u128
13402    }
13403}
13404
13405impl Embed<W48, W96> {
13406    /// Embed a `u64` value at W48 into a `u128` value at W96.
13407    #[inline]
13408    #[must_use]
13409    pub const fn apply(value: u64) -> u128 {
13410        value as u128
13411    }
13412}
13413
13414impl Embed<W48, W104> {
13415    /// Embed a `u64` value at W48 into a `u128` value at W104.
13416    #[inline]
13417    #[must_use]
13418    pub const fn apply(value: u64) -> u128 {
13419        value as u128
13420    }
13421}
13422
13423impl Embed<W48, W112> {
13424    /// Embed a `u64` value at W48 into a `u128` value at W112.
13425    #[inline]
13426    #[must_use]
13427    pub const fn apply(value: u64) -> u128 {
13428        value as u128
13429    }
13430}
13431
13432impl Embed<W48, W120> {
13433    /// Embed a `u64` value at W48 into a `u128` value at W120.
13434    #[inline]
13435    #[must_use]
13436    pub const fn apply(value: u64) -> u128 {
13437        value as u128
13438    }
13439}
13440
13441impl Embed<W48, W128> {
13442    /// Embed a `u64` value at W48 into a `u128` value at W128.
13443    #[inline]
13444    #[must_use]
13445    pub const fn apply(value: u64) -> u128 {
13446        value as u128
13447    }
13448}
13449
13450impl Embed<W56, W56> {
13451    /// Embed a `u64` value at W56 into a `u64` value at W56.
13452    #[inline]
13453    #[must_use]
13454    pub const fn apply(value: u64) -> u64 {
13455        value
13456    }
13457}
13458
13459impl Embed<W56, W64> {
13460    /// Embed a `u64` value at W56 into a `u64` value at W64.
13461    #[inline]
13462    #[must_use]
13463    pub const fn apply(value: u64) -> u64 {
13464        value
13465    }
13466}
13467
13468impl Embed<W56, W72> {
13469    /// Embed a `u64` value at W56 into a `u128` value at W72.
13470    #[inline]
13471    #[must_use]
13472    pub const fn apply(value: u64) -> u128 {
13473        value as u128
13474    }
13475}
13476
13477impl Embed<W56, W80> {
13478    /// Embed a `u64` value at W56 into a `u128` value at W80.
13479    #[inline]
13480    #[must_use]
13481    pub const fn apply(value: u64) -> u128 {
13482        value as u128
13483    }
13484}
13485
13486impl Embed<W56, W88> {
13487    /// Embed a `u64` value at W56 into a `u128` value at W88.
13488    #[inline]
13489    #[must_use]
13490    pub const fn apply(value: u64) -> u128 {
13491        value as u128
13492    }
13493}
13494
13495impl Embed<W56, W96> {
13496    /// Embed a `u64` value at W56 into a `u128` value at W96.
13497    #[inline]
13498    #[must_use]
13499    pub const fn apply(value: u64) -> u128 {
13500        value as u128
13501    }
13502}
13503
13504impl Embed<W56, W104> {
13505    /// Embed a `u64` value at W56 into a `u128` value at W104.
13506    #[inline]
13507    #[must_use]
13508    pub const fn apply(value: u64) -> u128 {
13509        value as u128
13510    }
13511}
13512
13513impl Embed<W56, W112> {
13514    /// Embed a `u64` value at W56 into a `u128` value at W112.
13515    #[inline]
13516    #[must_use]
13517    pub const fn apply(value: u64) -> u128 {
13518        value as u128
13519    }
13520}
13521
13522impl Embed<W56, W120> {
13523    /// Embed a `u64` value at W56 into a `u128` value at W120.
13524    #[inline]
13525    #[must_use]
13526    pub const fn apply(value: u64) -> u128 {
13527        value as u128
13528    }
13529}
13530
13531impl Embed<W56, W128> {
13532    /// Embed a `u64` value at W56 into a `u128` value at W128.
13533    #[inline]
13534    #[must_use]
13535    pub const fn apply(value: u64) -> u128 {
13536        value as u128
13537    }
13538}
13539
13540impl Embed<W64, W64> {
13541    /// Embed a `u64` value at W64 into a `u64` value at W64.
13542    #[inline]
13543    #[must_use]
13544    pub const fn apply(value: u64) -> u64 {
13545        value
13546    }
13547}
13548
13549impl Embed<W64, W72> {
13550    /// Embed a `u64` value at W64 into a `u128` value at W72.
13551    #[inline]
13552    #[must_use]
13553    pub const fn apply(value: u64) -> u128 {
13554        value as u128
13555    }
13556}
13557
13558impl Embed<W64, W80> {
13559    /// Embed a `u64` value at W64 into a `u128` value at W80.
13560    #[inline]
13561    #[must_use]
13562    pub const fn apply(value: u64) -> u128 {
13563        value as u128
13564    }
13565}
13566
13567impl Embed<W64, W88> {
13568    /// Embed a `u64` value at W64 into a `u128` value at W88.
13569    #[inline]
13570    #[must_use]
13571    pub const fn apply(value: u64) -> u128 {
13572        value as u128
13573    }
13574}
13575
13576impl Embed<W64, W96> {
13577    /// Embed a `u64` value at W64 into a `u128` value at W96.
13578    #[inline]
13579    #[must_use]
13580    pub const fn apply(value: u64) -> u128 {
13581        value as u128
13582    }
13583}
13584
13585impl Embed<W64, W104> {
13586    /// Embed a `u64` value at W64 into a `u128` value at W104.
13587    #[inline]
13588    #[must_use]
13589    pub const fn apply(value: u64) -> u128 {
13590        value as u128
13591    }
13592}
13593
13594impl Embed<W64, W112> {
13595    /// Embed a `u64` value at W64 into a `u128` value at W112.
13596    #[inline]
13597    #[must_use]
13598    pub const fn apply(value: u64) -> u128 {
13599        value as u128
13600    }
13601}
13602
13603impl Embed<W64, W120> {
13604    /// Embed a `u64` value at W64 into a `u128` value at W120.
13605    #[inline]
13606    #[must_use]
13607    pub const fn apply(value: u64) -> u128 {
13608        value as u128
13609    }
13610}
13611
13612impl Embed<W64, W128> {
13613    /// Embed a `u64` value at W64 into a `u128` value at W128.
13614    #[inline]
13615    #[must_use]
13616    pub const fn apply(value: u64) -> u128 {
13617        value as u128
13618    }
13619}
13620
13621impl Embed<W72, W72> {
13622    /// Embed a `u128` value at W72 into a `u128` value at W72.
13623    #[inline]
13624    #[must_use]
13625    pub const fn apply(value: u128) -> u128 {
13626        value
13627    }
13628}
13629
13630impl Embed<W72, W80> {
13631    /// Embed a `u128` value at W72 into a `u128` value at W80.
13632    #[inline]
13633    #[must_use]
13634    pub const fn apply(value: u128) -> u128 {
13635        value
13636    }
13637}
13638
13639impl Embed<W72, W88> {
13640    /// Embed a `u128` value at W72 into a `u128` value at W88.
13641    #[inline]
13642    #[must_use]
13643    pub const fn apply(value: u128) -> u128 {
13644        value
13645    }
13646}
13647
13648impl Embed<W72, W96> {
13649    /// Embed a `u128` value at W72 into a `u128` value at W96.
13650    #[inline]
13651    #[must_use]
13652    pub const fn apply(value: u128) -> u128 {
13653        value
13654    }
13655}
13656
13657impl Embed<W72, W104> {
13658    /// Embed a `u128` value at W72 into a `u128` value at W104.
13659    #[inline]
13660    #[must_use]
13661    pub const fn apply(value: u128) -> u128 {
13662        value
13663    }
13664}
13665
13666impl Embed<W72, W112> {
13667    /// Embed a `u128` value at W72 into a `u128` value at W112.
13668    #[inline]
13669    #[must_use]
13670    pub const fn apply(value: u128) -> u128 {
13671        value
13672    }
13673}
13674
13675impl Embed<W72, W120> {
13676    /// Embed a `u128` value at W72 into a `u128` value at W120.
13677    #[inline]
13678    #[must_use]
13679    pub const fn apply(value: u128) -> u128 {
13680        value
13681    }
13682}
13683
13684impl Embed<W72, W128> {
13685    /// Embed a `u128` value at W72 into a `u128` value at W128.
13686    #[inline]
13687    #[must_use]
13688    pub const fn apply(value: u128) -> u128 {
13689        value
13690    }
13691}
13692
13693impl Embed<W80, W80> {
13694    /// Embed a `u128` value at W80 into a `u128` value at W80.
13695    #[inline]
13696    #[must_use]
13697    pub const fn apply(value: u128) -> u128 {
13698        value
13699    }
13700}
13701
13702impl Embed<W80, W88> {
13703    /// Embed a `u128` value at W80 into a `u128` value at W88.
13704    #[inline]
13705    #[must_use]
13706    pub const fn apply(value: u128) -> u128 {
13707        value
13708    }
13709}
13710
13711impl Embed<W80, W96> {
13712    /// Embed a `u128` value at W80 into a `u128` value at W96.
13713    #[inline]
13714    #[must_use]
13715    pub const fn apply(value: u128) -> u128 {
13716        value
13717    }
13718}
13719
13720impl Embed<W80, W104> {
13721    /// Embed a `u128` value at W80 into a `u128` value at W104.
13722    #[inline]
13723    #[must_use]
13724    pub const fn apply(value: u128) -> u128 {
13725        value
13726    }
13727}
13728
13729impl Embed<W80, W112> {
13730    /// Embed a `u128` value at W80 into a `u128` value at W112.
13731    #[inline]
13732    #[must_use]
13733    pub const fn apply(value: u128) -> u128 {
13734        value
13735    }
13736}
13737
13738impl Embed<W80, W120> {
13739    /// Embed a `u128` value at W80 into a `u128` value at W120.
13740    #[inline]
13741    #[must_use]
13742    pub const fn apply(value: u128) -> u128 {
13743        value
13744    }
13745}
13746
13747impl Embed<W80, W128> {
13748    /// Embed a `u128` value at W80 into a `u128` value at W128.
13749    #[inline]
13750    #[must_use]
13751    pub const fn apply(value: u128) -> u128 {
13752        value
13753    }
13754}
13755
13756impl Embed<W88, W88> {
13757    /// Embed a `u128` value at W88 into a `u128` value at W88.
13758    #[inline]
13759    #[must_use]
13760    pub const fn apply(value: u128) -> u128 {
13761        value
13762    }
13763}
13764
13765impl Embed<W88, W96> {
13766    /// Embed a `u128` value at W88 into a `u128` value at W96.
13767    #[inline]
13768    #[must_use]
13769    pub const fn apply(value: u128) -> u128 {
13770        value
13771    }
13772}
13773
13774impl Embed<W88, W104> {
13775    /// Embed a `u128` value at W88 into a `u128` value at W104.
13776    #[inline]
13777    #[must_use]
13778    pub const fn apply(value: u128) -> u128 {
13779        value
13780    }
13781}
13782
13783impl Embed<W88, W112> {
13784    /// Embed a `u128` value at W88 into a `u128` value at W112.
13785    #[inline]
13786    #[must_use]
13787    pub const fn apply(value: u128) -> u128 {
13788        value
13789    }
13790}
13791
13792impl Embed<W88, W120> {
13793    /// Embed a `u128` value at W88 into a `u128` value at W120.
13794    #[inline]
13795    #[must_use]
13796    pub const fn apply(value: u128) -> u128 {
13797        value
13798    }
13799}
13800
13801impl Embed<W88, W128> {
13802    /// Embed a `u128` value at W88 into a `u128` value at W128.
13803    #[inline]
13804    #[must_use]
13805    pub const fn apply(value: u128) -> u128 {
13806        value
13807    }
13808}
13809
13810impl Embed<W96, W96> {
13811    /// Embed a `u128` value at W96 into a `u128` value at W96.
13812    #[inline]
13813    #[must_use]
13814    pub const fn apply(value: u128) -> u128 {
13815        value
13816    }
13817}
13818
13819impl Embed<W96, W104> {
13820    /// Embed a `u128` value at W96 into a `u128` value at W104.
13821    #[inline]
13822    #[must_use]
13823    pub const fn apply(value: u128) -> u128 {
13824        value
13825    }
13826}
13827
13828impl Embed<W96, W112> {
13829    /// Embed a `u128` value at W96 into a `u128` value at W112.
13830    #[inline]
13831    #[must_use]
13832    pub const fn apply(value: u128) -> u128 {
13833        value
13834    }
13835}
13836
13837impl Embed<W96, W120> {
13838    /// Embed a `u128` value at W96 into a `u128` value at W120.
13839    #[inline]
13840    #[must_use]
13841    pub const fn apply(value: u128) -> u128 {
13842        value
13843    }
13844}
13845
13846impl Embed<W96, W128> {
13847    /// Embed a `u128` value at W96 into a `u128` value at W128.
13848    #[inline]
13849    #[must_use]
13850    pub const fn apply(value: u128) -> u128 {
13851        value
13852    }
13853}
13854
13855impl Embed<W104, W104> {
13856    /// Embed a `u128` value at W104 into a `u128` value at W104.
13857    #[inline]
13858    #[must_use]
13859    pub const fn apply(value: u128) -> u128 {
13860        value
13861    }
13862}
13863
13864impl Embed<W104, W112> {
13865    /// Embed a `u128` value at W104 into a `u128` value at W112.
13866    #[inline]
13867    #[must_use]
13868    pub const fn apply(value: u128) -> u128 {
13869        value
13870    }
13871}
13872
13873impl Embed<W104, W120> {
13874    /// Embed a `u128` value at W104 into a `u128` value at W120.
13875    #[inline]
13876    #[must_use]
13877    pub const fn apply(value: u128) -> u128 {
13878        value
13879    }
13880}
13881
13882impl Embed<W104, W128> {
13883    /// Embed a `u128` value at W104 into a `u128` value at W128.
13884    #[inline]
13885    #[must_use]
13886    pub const fn apply(value: u128) -> u128 {
13887        value
13888    }
13889}
13890
13891impl Embed<W112, W112> {
13892    /// Embed a `u128` value at W112 into a `u128` value at W112.
13893    #[inline]
13894    #[must_use]
13895    pub const fn apply(value: u128) -> u128 {
13896        value
13897    }
13898}
13899
13900impl Embed<W112, W120> {
13901    /// Embed a `u128` value at W112 into a `u128` value at W120.
13902    #[inline]
13903    #[must_use]
13904    pub const fn apply(value: u128) -> u128 {
13905        value
13906    }
13907}
13908
13909impl Embed<W112, W128> {
13910    /// Embed a `u128` value at W112 into a `u128` value at W128.
13911    #[inline]
13912    #[must_use]
13913    pub const fn apply(value: u128) -> u128 {
13914        value
13915    }
13916}
13917
13918impl Embed<W120, W120> {
13919    /// Embed a `u128` value at W120 into a `u128` value at W120.
13920    #[inline]
13921    #[must_use]
13922    pub const fn apply(value: u128) -> u128 {
13923        value
13924    }
13925}
13926
13927impl Embed<W120, W128> {
13928    /// Embed a `u128` value at W120 into a `u128` value at W128.
13929    #[inline]
13930    #[must_use]
13931    pub const fn apply(value: u128) -> u128 {
13932        value
13933    }
13934}
13935
13936impl Embed<W128, W128> {
13937    /// Embed a `u128` value at W128 into a `u128` value at W128.
13938    #[inline]
13939    #[must_use]
13940    pub const fn apply(value: u128) -> u128 {
13941        value
13942    }
13943}
13944
13945/// v0.2.2 Phase C.3: marker structs for Limbs-backed Witt levels.
13946/// Each level binds a const-generic `Limbs<N>` width at the type level.
13947/// W160 marker — 160-bit Witt level, Limbs-backed.
13948#[derive(Debug, Default, Clone, Copy)]
13949pub struct W160;
13950
13951/// W192 marker — 192-bit Witt level, Limbs-backed.
13952#[derive(Debug, Default, Clone, Copy)]
13953pub struct W192;
13954
13955/// W224 marker — 224-bit Witt level, Limbs-backed.
13956#[derive(Debug, Default, Clone, Copy)]
13957pub struct W224;
13958
13959/// W256 marker — 256-bit Witt level, Limbs-backed.
13960#[derive(Debug, Default, Clone, Copy)]
13961pub struct W256;
13962
13963/// W384 marker — 384-bit Witt level, Limbs-backed.
13964#[derive(Debug, Default, Clone, Copy)]
13965pub struct W384;
13966
13967/// W448 marker — 448-bit Witt level, Limbs-backed.
13968#[derive(Debug, Default, Clone, Copy)]
13969pub struct W448;
13970
13971/// W512 marker — 512-bit Witt level, Limbs-backed.
13972#[derive(Debug, Default, Clone, Copy)]
13973pub struct W512;
13974
13975/// W520 marker — 520-bit Witt level, Limbs-backed.
13976#[derive(Debug, Default, Clone, Copy)]
13977pub struct W520;
13978
13979/// W528 marker — 528-bit Witt level, Limbs-backed.
13980#[derive(Debug, Default, Clone, Copy)]
13981pub struct W528;
13982
13983/// W1024 marker — 1024-bit Witt level, Limbs-backed.
13984#[derive(Debug, Default, Clone, Copy)]
13985pub struct W1024;
13986
13987/// W2048 marker — 2048-bit Witt level, Limbs-backed.
13988#[derive(Debug, Default, Clone, Copy)]
13989pub struct W2048;
13990
13991/// W4096 marker — 4096-bit Witt level, Limbs-backed.
13992#[derive(Debug, Default, Clone, Copy)]
13993pub struct W4096;
13994
13995/// W8192 marker — 8192-bit Witt level, Limbs-backed.
13996#[derive(Debug, Default, Clone, Copy)]
13997pub struct W8192;
13998
13999/// W12288 marker — 12288-bit Witt level, Limbs-backed.
14000#[derive(Debug, Default, Clone, Copy)]
14001pub struct W12288;
14002
14003/// W16384 marker — 16384-bit Witt level, Limbs-backed.
14004#[derive(Debug, Default, Clone, Copy)]
14005pub struct W16384;
14006
14007/// W32768 marker — 32768-bit Witt level, Limbs-backed.
14008#[derive(Debug, Default, Clone, Copy)]
14009pub struct W32768;
14010
14011impl RingOp<W160> for Mul<W160> {
14012    type Operand = Limbs<3>;
14013    #[inline]
14014    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14015        a.wrapping_mul(b).mask_high_bits(160)
14016    }
14017}
14018
14019impl RingOp<W160> for Add<W160> {
14020    type Operand = Limbs<3>;
14021    #[inline]
14022    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14023        a.wrapping_add(b).mask_high_bits(160)
14024    }
14025}
14026
14027impl RingOp<W160> for Sub<W160> {
14028    type Operand = Limbs<3>;
14029    #[inline]
14030    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14031        a.wrapping_sub(b).mask_high_bits(160)
14032    }
14033}
14034
14035impl RingOp<W160> for Xor<W160> {
14036    type Operand = Limbs<3>;
14037    #[inline]
14038    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14039        a.xor(b).mask_high_bits(160)
14040    }
14041}
14042
14043impl RingOp<W160> for And<W160> {
14044    type Operand = Limbs<3>;
14045    #[inline]
14046    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14047        a.and(b).mask_high_bits(160)
14048    }
14049}
14050
14051impl RingOp<W160> for Or<W160> {
14052    type Operand = Limbs<3>;
14053    #[inline]
14054    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14055        a.or(b).mask_high_bits(160)
14056    }
14057}
14058
14059impl UnaryRingOp<W160> for Neg<W160> {
14060    type Operand = Limbs<3>;
14061    #[inline]
14062    fn apply(a: Limbs<3>) -> Limbs<3> {
14063        (Limbs::<3>::zero().wrapping_sub(a)).mask_high_bits(160)
14064    }
14065}
14066
14067impl UnaryRingOp<W160> for BNot<W160> {
14068    type Operand = Limbs<3>;
14069    #[inline]
14070    fn apply(a: Limbs<3>) -> Limbs<3> {
14071        (a.not()).mask_high_bits(160)
14072    }
14073}
14074
14075impl UnaryRingOp<W160> for Succ<W160> {
14076    type Operand = Limbs<3>;
14077    #[inline]
14078    fn apply(a: Limbs<3>) -> Limbs<3> {
14079        (a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))).mask_high_bits(160)
14080    }
14081}
14082
14083impl RingOp<W192> for Mul<W192> {
14084    type Operand = Limbs<3>;
14085    #[inline]
14086    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14087        a.wrapping_mul(b)
14088    }
14089}
14090
14091impl RingOp<W192> for Add<W192> {
14092    type Operand = Limbs<3>;
14093    #[inline]
14094    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14095        a.wrapping_add(b)
14096    }
14097}
14098
14099impl RingOp<W192> for Sub<W192> {
14100    type Operand = Limbs<3>;
14101    #[inline]
14102    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14103        a.wrapping_sub(b)
14104    }
14105}
14106
14107impl RingOp<W192> for Xor<W192> {
14108    type Operand = Limbs<3>;
14109    #[inline]
14110    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14111        a.xor(b)
14112    }
14113}
14114
14115impl RingOp<W192> for And<W192> {
14116    type Operand = Limbs<3>;
14117    #[inline]
14118    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14119        a.and(b)
14120    }
14121}
14122
14123impl RingOp<W192> for Or<W192> {
14124    type Operand = Limbs<3>;
14125    #[inline]
14126    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14127        a.or(b)
14128    }
14129}
14130
14131impl UnaryRingOp<W192> for Neg<W192> {
14132    type Operand = Limbs<3>;
14133    #[inline]
14134    fn apply(a: Limbs<3>) -> Limbs<3> {
14135        Limbs::<3>::zero().wrapping_sub(a)
14136    }
14137}
14138
14139impl UnaryRingOp<W192> for BNot<W192> {
14140    type Operand = Limbs<3>;
14141    #[inline]
14142    fn apply(a: Limbs<3>) -> Limbs<3> {
14143        a.not()
14144    }
14145}
14146
14147impl UnaryRingOp<W192> for Succ<W192> {
14148    type Operand = Limbs<3>;
14149    #[inline]
14150    fn apply(a: Limbs<3>) -> Limbs<3> {
14151        a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))
14152    }
14153}
14154
14155impl RingOp<W224> for Mul<W224> {
14156    type Operand = Limbs<4>;
14157    #[inline]
14158    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14159        a.wrapping_mul(b).mask_high_bits(224)
14160    }
14161}
14162
14163impl RingOp<W224> for Add<W224> {
14164    type Operand = Limbs<4>;
14165    #[inline]
14166    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14167        a.wrapping_add(b).mask_high_bits(224)
14168    }
14169}
14170
14171impl RingOp<W224> for Sub<W224> {
14172    type Operand = Limbs<4>;
14173    #[inline]
14174    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14175        a.wrapping_sub(b).mask_high_bits(224)
14176    }
14177}
14178
14179impl RingOp<W224> for Xor<W224> {
14180    type Operand = Limbs<4>;
14181    #[inline]
14182    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14183        a.xor(b).mask_high_bits(224)
14184    }
14185}
14186
14187impl RingOp<W224> for And<W224> {
14188    type Operand = Limbs<4>;
14189    #[inline]
14190    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14191        a.and(b).mask_high_bits(224)
14192    }
14193}
14194
14195impl RingOp<W224> for Or<W224> {
14196    type Operand = Limbs<4>;
14197    #[inline]
14198    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14199        a.or(b).mask_high_bits(224)
14200    }
14201}
14202
14203impl UnaryRingOp<W224> for Neg<W224> {
14204    type Operand = Limbs<4>;
14205    #[inline]
14206    fn apply(a: Limbs<4>) -> Limbs<4> {
14207        (Limbs::<4>::zero().wrapping_sub(a)).mask_high_bits(224)
14208    }
14209}
14210
14211impl UnaryRingOp<W224> for BNot<W224> {
14212    type Operand = Limbs<4>;
14213    #[inline]
14214    fn apply(a: Limbs<4>) -> Limbs<4> {
14215        (a.not()).mask_high_bits(224)
14216    }
14217}
14218
14219impl UnaryRingOp<W224> for Succ<W224> {
14220    type Operand = Limbs<4>;
14221    #[inline]
14222    fn apply(a: Limbs<4>) -> Limbs<4> {
14223        (a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))).mask_high_bits(224)
14224    }
14225}
14226
14227impl RingOp<W256> for Mul<W256> {
14228    type Operand = Limbs<4>;
14229    #[inline]
14230    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14231        a.wrapping_mul(b)
14232    }
14233}
14234
14235impl RingOp<W256> for Add<W256> {
14236    type Operand = Limbs<4>;
14237    #[inline]
14238    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14239        a.wrapping_add(b)
14240    }
14241}
14242
14243impl RingOp<W256> for Sub<W256> {
14244    type Operand = Limbs<4>;
14245    #[inline]
14246    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14247        a.wrapping_sub(b)
14248    }
14249}
14250
14251impl RingOp<W256> for Xor<W256> {
14252    type Operand = Limbs<4>;
14253    #[inline]
14254    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14255        a.xor(b)
14256    }
14257}
14258
14259impl RingOp<W256> for And<W256> {
14260    type Operand = Limbs<4>;
14261    #[inline]
14262    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14263        a.and(b)
14264    }
14265}
14266
14267impl RingOp<W256> for Or<W256> {
14268    type Operand = Limbs<4>;
14269    #[inline]
14270    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14271        a.or(b)
14272    }
14273}
14274
14275impl UnaryRingOp<W256> for Neg<W256> {
14276    type Operand = Limbs<4>;
14277    #[inline]
14278    fn apply(a: Limbs<4>) -> Limbs<4> {
14279        Limbs::<4>::zero().wrapping_sub(a)
14280    }
14281}
14282
14283impl UnaryRingOp<W256> for BNot<W256> {
14284    type Operand = Limbs<4>;
14285    #[inline]
14286    fn apply(a: Limbs<4>) -> Limbs<4> {
14287        a.not()
14288    }
14289}
14290
14291impl UnaryRingOp<W256> for Succ<W256> {
14292    type Operand = Limbs<4>;
14293    #[inline]
14294    fn apply(a: Limbs<4>) -> Limbs<4> {
14295        a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))
14296    }
14297}
14298
14299impl RingOp<W384> for Mul<W384> {
14300    type Operand = Limbs<6>;
14301    #[inline]
14302    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14303        a.wrapping_mul(b)
14304    }
14305}
14306
14307impl RingOp<W384> for Add<W384> {
14308    type Operand = Limbs<6>;
14309    #[inline]
14310    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14311        a.wrapping_add(b)
14312    }
14313}
14314
14315impl RingOp<W384> for Sub<W384> {
14316    type Operand = Limbs<6>;
14317    #[inline]
14318    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14319        a.wrapping_sub(b)
14320    }
14321}
14322
14323impl RingOp<W384> for Xor<W384> {
14324    type Operand = Limbs<6>;
14325    #[inline]
14326    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14327        a.xor(b)
14328    }
14329}
14330
14331impl RingOp<W384> for And<W384> {
14332    type Operand = Limbs<6>;
14333    #[inline]
14334    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14335        a.and(b)
14336    }
14337}
14338
14339impl RingOp<W384> for Or<W384> {
14340    type Operand = Limbs<6>;
14341    #[inline]
14342    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14343        a.or(b)
14344    }
14345}
14346
14347impl UnaryRingOp<W384> for Neg<W384> {
14348    type Operand = Limbs<6>;
14349    #[inline]
14350    fn apply(a: Limbs<6>) -> Limbs<6> {
14351        Limbs::<6>::zero().wrapping_sub(a)
14352    }
14353}
14354
14355impl UnaryRingOp<W384> for BNot<W384> {
14356    type Operand = Limbs<6>;
14357    #[inline]
14358    fn apply(a: Limbs<6>) -> Limbs<6> {
14359        a.not()
14360    }
14361}
14362
14363impl UnaryRingOp<W384> for Succ<W384> {
14364    type Operand = Limbs<6>;
14365    #[inline]
14366    fn apply(a: Limbs<6>) -> Limbs<6> {
14367        a.wrapping_add(Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64]))
14368    }
14369}
14370
14371impl RingOp<W448> for Mul<W448> {
14372    type Operand = Limbs<7>;
14373    #[inline]
14374    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14375        a.wrapping_mul(b)
14376    }
14377}
14378
14379impl RingOp<W448> for Add<W448> {
14380    type Operand = Limbs<7>;
14381    #[inline]
14382    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14383        a.wrapping_add(b)
14384    }
14385}
14386
14387impl RingOp<W448> for Sub<W448> {
14388    type Operand = Limbs<7>;
14389    #[inline]
14390    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14391        a.wrapping_sub(b)
14392    }
14393}
14394
14395impl RingOp<W448> for Xor<W448> {
14396    type Operand = Limbs<7>;
14397    #[inline]
14398    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14399        a.xor(b)
14400    }
14401}
14402
14403impl RingOp<W448> for And<W448> {
14404    type Operand = Limbs<7>;
14405    #[inline]
14406    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14407        a.and(b)
14408    }
14409}
14410
14411impl RingOp<W448> for Or<W448> {
14412    type Operand = Limbs<7>;
14413    #[inline]
14414    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14415        a.or(b)
14416    }
14417}
14418
14419impl UnaryRingOp<W448> for Neg<W448> {
14420    type Operand = Limbs<7>;
14421    #[inline]
14422    fn apply(a: Limbs<7>) -> Limbs<7> {
14423        Limbs::<7>::zero().wrapping_sub(a)
14424    }
14425}
14426
14427impl UnaryRingOp<W448> for BNot<W448> {
14428    type Operand = Limbs<7>;
14429    #[inline]
14430    fn apply(a: Limbs<7>) -> Limbs<7> {
14431        a.not()
14432    }
14433}
14434
14435impl UnaryRingOp<W448> for Succ<W448> {
14436    type Operand = Limbs<7>;
14437    #[inline]
14438    fn apply(a: Limbs<7>) -> Limbs<7> {
14439        a.wrapping_add(Limbs::<7>::from_words([
14440            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14441        ]))
14442    }
14443}
14444
14445impl RingOp<W512> for Mul<W512> {
14446    type Operand = Limbs<8>;
14447    #[inline]
14448    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14449        a.wrapping_mul(b)
14450    }
14451}
14452
14453impl RingOp<W512> for Add<W512> {
14454    type Operand = Limbs<8>;
14455    #[inline]
14456    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14457        a.wrapping_add(b)
14458    }
14459}
14460
14461impl RingOp<W512> for Sub<W512> {
14462    type Operand = Limbs<8>;
14463    #[inline]
14464    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14465        a.wrapping_sub(b)
14466    }
14467}
14468
14469impl RingOp<W512> for Xor<W512> {
14470    type Operand = Limbs<8>;
14471    #[inline]
14472    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14473        a.xor(b)
14474    }
14475}
14476
14477impl RingOp<W512> for And<W512> {
14478    type Operand = Limbs<8>;
14479    #[inline]
14480    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14481        a.and(b)
14482    }
14483}
14484
14485impl RingOp<W512> for Or<W512> {
14486    type Operand = Limbs<8>;
14487    #[inline]
14488    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14489        a.or(b)
14490    }
14491}
14492
14493impl UnaryRingOp<W512> for Neg<W512> {
14494    type Operand = Limbs<8>;
14495    #[inline]
14496    fn apply(a: Limbs<8>) -> Limbs<8> {
14497        Limbs::<8>::zero().wrapping_sub(a)
14498    }
14499}
14500
14501impl UnaryRingOp<W512> for BNot<W512> {
14502    type Operand = Limbs<8>;
14503    #[inline]
14504    fn apply(a: Limbs<8>) -> Limbs<8> {
14505        a.not()
14506    }
14507}
14508
14509impl UnaryRingOp<W512> for Succ<W512> {
14510    type Operand = Limbs<8>;
14511    #[inline]
14512    fn apply(a: Limbs<8>) -> Limbs<8> {
14513        a.wrapping_add(Limbs::<8>::from_words([
14514            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14515        ]))
14516    }
14517}
14518
14519impl RingOp<W520> for Mul<W520> {
14520    type Operand = Limbs<9>;
14521    #[inline]
14522    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14523        a.wrapping_mul(b).mask_high_bits(520)
14524    }
14525}
14526
14527impl RingOp<W520> for Add<W520> {
14528    type Operand = Limbs<9>;
14529    #[inline]
14530    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14531        a.wrapping_add(b).mask_high_bits(520)
14532    }
14533}
14534
14535impl RingOp<W520> for Sub<W520> {
14536    type Operand = Limbs<9>;
14537    #[inline]
14538    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14539        a.wrapping_sub(b).mask_high_bits(520)
14540    }
14541}
14542
14543impl RingOp<W520> for Xor<W520> {
14544    type Operand = Limbs<9>;
14545    #[inline]
14546    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14547        a.xor(b).mask_high_bits(520)
14548    }
14549}
14550
14551impl RingOp<W520> for And<W520> {
14552    type Operand = Limbs<9>;
14553    #[inline]
14554    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14555        a.and(b).mask_high_bits(520)
14556    }
14557}
14558
14559impl RingOp<W520> for Or<W520> {
14560    type Operand = Limbs<9>;
14561    #[inline]
14562    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14563        a.or(b).mask_high_bits(520)
14564    }
14565}
14566
14567impl UnaryRingOp<W520> for Neg<W520> {
14568    type Operand = Limbs<9>;
14569    #[inline]
14570    fn apply(a: Limbs<9>) -> Limbs<9> {
14571        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(520)
14572    }
14573}
14574
14575impl UnaryRingOp<W520> for BNot<W520> {
14576    type Operand = Limbs<9>;
14577    #[inline]
14578    fn apply(a: Limbs<9>) -> Limbs<9> {
14579        (a.not()).mask_high_bits(520)
14580    }
14581}
14582
14583impl UnaryRingOp<W520> for Succ<W520> {
14584    type Operand = Limbs<9>;
14585    #[inline]
14586    fn apply(a: Limbs<9>) -> Limbs<9> {
14587        (a.wrapping_add(Limbs::<9>::from_words([
14588            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14589        ])))
14590        .mask_high_bits(520)
14591    }
14592}
14593
14594impl RingOp<W528> for Mul<W528> {
14595    type Operand = Limbs<9>;
14596    #[inline]
14597    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14598        a.wrapping_mul(b).mask_high_bits(528)
14599    }
14600}
14601
14602impl RingOp<W528> for Add<W528> {
14603    type Operand = Limbs<9>;
14604    #[inline]
14605    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14606        a.wrapping_add(b).mask_high_bits(528)
14607    }
14608}
14609
14610impl RingOp<W528> for Sub<W528> {
14611    type Operand = Limbs<9>;
14612    #[inline]
14613    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14614        a.wrapping_sub(b).mask_high_bits(528)
14615    }
14616}
14617
14618impl RingOp<W528> for Xor<W528> {
14619    type Operand = Limbs<9>;
14620    #[inline]
14621    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14622        a.xor(b).mask_high_bits(528)
14623    }
14624}
14625
14626impl RingOp<W528> for And<W528> {
14627    type Operand = Limbs<9>;
14628    #[inline]
14629    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14630        a.and(b).mask_high_bits(528)
14631    }
14632}
14633
14634impl RingOp<W528> for Or<W528> {
14635    type Operand = Limbs<9>;
14636    #[inline]
14637    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14638        a.or(b).mask_high_bits(528)
14639    }
14640}
14641
14642impl UnaryRingOp<W528> for Neg<W528> {
14643    type Operand = Limbs<9>;
14644    #[inline]
14645    fn apply(a: Limbs<9>) -> Limbs<9> {
14646        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(528)
14647    }
14648}
14649
14650impl UnaryRingOp<W528> for BNot<W528> {
14651    type Operand = Limbs<9>;
14652    #[inline]
14653    fn apply(a: Limbs<9>) -> Limbs<9> {
14654        (a.not()).mask_high_bits(528)
14655    }
14656}
14657
14658impl UnaryRingOp<W528> for Succ<W528> {
14659    type Operand = Limbs<9>;
14660    #[inline]
14661    fn apply(a: Limbs<9>) -> Limbs<9> {
14662        (a.wrapping_add(Limbs::<9>::from_words([
14663            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14664        ])))
14665        .mask_high_bits(528)
14666    }
14667}
14668
14669impl RingOp<W1024> for Mul<W1024> {
14670    type Operand = Limbs<16>;
14671    #[inline]
14672    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14673        a.wrapping_mul(b)
14674    }
14675}
14676
14677impl RingOp<W1024> for Add<W1024> {
14678    type Operand = Limbs<16>;
14679    #[inline]
14680    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14681        a.wrapping_add(b)
14682    }
14683}
14684
14685impl RingOp<W1024> for Sub<W1024> {
14686    type Operand = Limbs<16>;
14687    #[inline]
14688    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14689        a.wrapping_sub(b)
14690    }
14691}
14692
14693impl RingOp<W1024> for Xor<W1024> {
14694    type Operand = Limbs<16>;
14695    #[inline]
14696    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14697        a.xor(b)
14698    }
14699}
14700
14701impl RingOp<W1024> for And<W1024> {
14702    type Operand = Limbs<16>;
14703    #[inline]
14704    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14705        a.and(b)
14706    }
14707}
14708
14709impl RingOp<W1024> for Or<W1024> {
14710    type Operand = Limbs<16>;
14711    #[inline]
14712    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14713        a.or(b)
14714    }
14715}
14716
14717impl UnaryRingOp<W1024> for Neg<W1024> {
14718    type Operand = Limbs<16>;
14719    #[inline]
14720    fn apply(a: Limbs<16>) -> Limbs<16> {
14721        Limbs::<16>::zero().wrapping_sub(a)
14722    }
14723}
14724
14725impl UnaryRingOp<W1024> for BNot<W1024> {
14726    type Operand = Limbs<16>;
14727    #[inline]
14728    fn apply(a: Limbs<16>) -> Limbs<16> {
14729        a.not()
14730    }
14731}
14732
14733impl UnaryRingOp<W1024> for Succ<W1024> {
14734    type Operand = Limbs<16>;
14735    #[inline]
14736    fn apply(a: Limbs<16>) -> Limbs<16> {
14737        a.wrapping_add(Limbs::<16>::from_words([
14738            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14739            0u64, 0u64,
14740        ]))
14741    }
14742}
14743
14744impl RingOp<W2048> for Mul<W2048> {
14745    type Operand = Limbs<32>;
14746    #[inline]
14747    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14748        a.wrapping_mul(b)
14749    }
14750}
14751
14752impl RingOp<W2048> for Add<W2048> {
14753    type Operand = Limbs<32>;
14754    #[inline]
14755    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14756        a.wrapping_add(b)
14757    }
14758}
14759
14760impl RingOp<W2048> for Sub<W2048> {
14761    type Operand = Limbs<32>;
14762    #[inline]
14763    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14764        a.wrapping_sub(b)
14765    }
14766}
14767
14768impl RingOp<W2048> for Xor<W2048> {
14769    type Operand = Limbs<32>;
14770    #[inline]
14771    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14772        a.xor(b)
14773    }
14774}
14775
14776impl RingOp<W2048> for And<W2048> {
14777    type Operand = Limbs<32>;
14778    #[inline]
14779    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14780        a.and(b)
14781    }
14782}
14783
14784impl RingOp<W2048> for Or<W2048> {
14785    type Operand = Limbs<32>;
14786    #[inline]
14787    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14788        a.or(b)
14789    }
14790}
14791
14792impl UnaryRingOp<W2048> for Neg<W2048> {
14793    type Operand = Limbs<32>;
14794    #[inline]
14795    fn apply(a: Limbs<32>) -> Limbs<32> {
14796        Limbs::<32>::zero().wrapping_sub(a)
14797    }
14798}
14799
14800impl UnaryRingOp<W2048> for BNot<W2048> {
14801    type Operand = Limbs<32>;
14802    #[inline]
14803    fn apply(a: Limbs<32>) -> Limbs<32> {
14804        a.not()
14805    }
14806}
14807
14808impl UnaryRingOp<W2048> for Succ<W2048> {
14809    type Operand = Limbs<32>;
14810    #[inline]
14811    fn apply(a: Limbs<32>) -> Limbs<32> {
14812        a.wrapping_add(Limbs::<32>::from_words([
14813            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14814            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14815            0u64, 0u64, 0u64, 0u64,
14816        ]))
14817    }
14818}
14819
14820impl RingOp<W4096> for Mul<W4096> {
14821    type Operand = Limbs<64>;
14822    #[inline]
14823    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14824        a.wrapping_mul(b)
14825    }
14826}
14827
14828impl RingOp<W4096> for Add<W4096> {
14829    type Operand = Limbs<64>;
14830    #[inline]
14831    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14832        a.wrapping_add(b)
14833    }
14834}
14835
14836impl RingOp<W4096> for Sub<W4096> {
14837    type Operand = Limbs<64>;
14838    #[inline]
14839    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14840        a.wrapping_sub(b)
14841    }
14842}
14843
14844impl RingOp<W4096> for Xor<W4096> {
14845    type Operand = Limbs<64>;
14846    #[inline]
14847    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14848        a.xor(b)
14849    }
14850}
14851
14852impl RingOp<W4096> for And<W4096> {
14853    type Operand = Limbs<64>;
14854    #[inline]
14855    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14856        a.and(b)
14857    }
14858}
14859
14860impl RingOp<W4096> for Or<W4096> {
14861    type Operand = Limbs<64>;
14862    #[inline]
14863    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14864        a.or(b)
14865    }
14866}
14867
14868impl UnaryRingOp<W4096> for Neg<W4096> {
14869    type Operand = Limbs<64>;
14870    #[inline]
14871    fn apply(a: Limbs<64>) -> Limbs<64> {
14872        Limbs::<64>::zero().wrapping_sub(a)
14873    }
14874}
14875
14876impl UnaryRingOp<W4096> for BNot<W4096> {
14877    type Operand = Limbs<64>;
14878    #[inline]
14879    fn apply(a: Limbs<64>) -> Limbs<64> {
14880        a.not()
14881    }
14882}
14883
14884impl UnaryRingOp<W4096> for Succ<W4096> {
14885    type Operand = Limbs<64>;
14886    #[inline]
14887    fn apply(a: Limbs<64>) -> Limbs<64> {
14888        a.wrapping_add(Limbs::<64>::from_words([
14889            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14890            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14891            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14892            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14893            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14894        ]))
14895    }
14896}
14897
14898impl RingOp<W8192> for Mul<W8192> {
14899    type Operand = Limbs<128>;
14900    #[inline]
14901    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14902        a.wrapping_mul(b)
14903    }
14904}
14905
14906impl RingOp<W8192> for Add<W8192> {
14907    type Operand = Limbs<128>;
14908    #[inline]
14909    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14910        a.wrapping_add(b)
14911    }
14912}
14913
14914impl RingOp<W8192> for Sub<W8192> {
14915    type Operand = Limbs<128>;
14916    #[inline]
14917    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14918        a.wrapping_sub(b)
14919    }
14920}
14921
14922impl RingOp<W8192> for Xor<W8192> {
14923    type Operand = Limbs<128>;
14924    #[inline]
14925    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14926        a.xor(b)
14927    }
14928}
14929
14930impl RingOp<W8192> for And<W8192> {
14931    type Operand = Limbs<128>;
14932    #[inline]
14933    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14934        a.and(b)
14935    }
14936}
14937
14938impl RingOp<W8192> for Or<W8192> {
14939    type Operand = Limbs<128>;
14940    #[inline]
14941    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14942        a.or(b)
14943    }
14944}
14945
14946impl UnaryRingOp<W8192> for Neg<W8192> {
14947    type Operand = Limbs<128>;
14948    #[inline]
14949    fn apply(a: Limbs<128>) -> Limbs<128> {
14950        Limbs::<128>::zero().wrapping_sub(a)
14951    }
14952}
14953
14954impl UnaryRingOp<W8192> for BNot<W8192> {
14955    type Operand = Limbs<128>;
14956    #[inline]
14957    fn apply(a: Limbs<128>) -> Limbs<128> {
14958        a.not()
14959    }
14960}
14961
14962impl UnaryRingOp<W8192> for Succ<W8192> {
14963    type Operand = Limbs<128>;
14964    #[inline]
14965    fn apply(a: Limbs<128>) -> Limbs<128> {
14966        a.wrapping_add(Limbs::<128>::from_words([
14967            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14968            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14969            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14970            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14971            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14972            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14973            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14974            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14975            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14976            0u64, 0u64,
14977        ]))
14978    }
14979}
14980
14981impl RingOp<W12288> for Mul<W12288> {
14982    type Operand = Limbs<192>;
14983    #[inline]
14984    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
14985        a.wrapping_mul(b)
14986    }
14987}
14988
14989impl RingOp<W12288> for Add<W12288> {
14990    type Operand = Limbs<192>;
14991    #[inline]
14992    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
14993        a.wrapping_add(b)
14994    }
14995}
14996
14997impl RingOp<W12288> for Sub<W12288> {
14998    type Operand = Limbs<192>;
14999    #[inline]
15000    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15001        a.wrapping_sub(b)
15002    }
15003}
15004
15005impl RingOp<W12288> for Xor<W12288> {
15006    type Operand = Limbs<192>;
15007    #[inline]
15008    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15009        a.xor(b)
15010    }
15011}
15012
15013impl RingOp<W12288> for And<W12288> {
15014    type Operand = Limbs<192>;
15015    #[inline]
15016    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15017        a.and(b)
15018    }
15019}
15020
15021impl RingOp<W12288> for Or<W12288> {
15022    type Operand = Limbs<192>;
15023    #[inline]
15024    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15025        a.or(b)
15026    }
15027}
15028
15029impl UnaryRingOp<W12288> for Neg<W12288> {
15030    type Operand = Limbs<192>;
15031    #[inline]
15032    fn apply(a: Limbs<192>) -> Limbs<192> {
15033        Limbs::<192>::zero().wrapping_sub(a)
15034    }
15035}
15036
15037impl UnaryRingOp<W12288> for BNot<W12288> {
15038    type Operand = Limbs<192>;
15039    #[inline]
15040    fn apply(a: Limbs<192>) -> Limbs<192> {
15041        a.not()
15042    }
15043}
15044
15045impl UnaryRingOp<W12288> for Succ<W12288> {
15046    type Operand = Limbs<192>;
15047    #[inline]
15048    fn apply(a: Limbs<192>) -> Limbs<192> {
15049        a.wrapping_add(Limbs::<192>::from_words([
15050            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15051            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15052            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15053            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15054            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15055            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15056            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15057            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15058            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15059            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15060            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15061            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15062            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15063            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15064        ]))
15065    }
15066}
15067
15068impl RingOp<W16384> for Mul<W16384> {
15069    type Operand = Limbs<256>;
15070    #[inline]
15071    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15072        a.wrapping_mul(b)
15073    }
15074}
15075
15076impl RingOp<W16384> for Add<W16384> {
15077    type Operand = Limbs<256>;
15078    #[inline]
15079    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15080        a.wrapping_add(b)
15081    }
15082}
15083
15084impl RingOp<W16384> for Sub<W16384> {
15085    type Operand = Limbs<256>;
15086    #[inline]
15087    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15088        a.wrapping_sub(b)
15089    }
15090}
15091
15092impl RingOp<W16384> for Xor<W16384> {
15093    type Operand = Limbs<256>;
15094    #[inline]
15095    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15096        a.xor(b)
15097    }
15098}
15099
15100impl RingOp<W16384> for And<W16384> {
15101    type Operand = Limbs<256>;
15102    #[inline]
15103    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15104        a.and(b)
15105    }
15106}
15107
15108impl RingOp<W16384> for Or<W16384> {
15109    type Operand = Limbs<256>;
15110    #[inline]
15111    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15112        a.or(b)
15113    }
15114}
15115
15116impl UnaryRingOp<W16384> for Neg<W16384> {
15117    type Operand = Limbs<256>;
15118    #[inline]
15119    fn apply(a: Limbs<256>) -> Limbs<256> {
15120        Limbs::<256>::zero().wrapping_sub(a)
15121    }
15122}
15123
15124impl UnaryRingOp<W16384> for BNot<W16384> {
15125    type Operand = Limbs<256>;
15126    #[inline]
15127    fn apply(a: Limbs<256>) -> Limbs<256> {
15128        a.not()
15129    }
15130}
15131
15132impl UnaryRingOp<W16384> for Succ<W16384> {
15133    type Operand = Limbs<256>;
15134    #[inline]
15135    fn apply(a: Limbs<256>) -> Limbs<256> {
15136        a.wrapping_add(Limbs::<256>::from_words([
15137            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15138            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15139            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15140            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15141            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15142            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15143            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15144            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15145            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15146            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15147            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15148            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15149            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15150            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15151            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15152            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15153            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15154            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15155            0u64, 0u64, 0u64, 0u64,
15156        ]))
15157    }
15158}
15159
15160impl RingOp<W32768> for Mul<W32768> {
15161    type Operand = Limbs<512>;
15162    #[inline]
15163    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15164        a.wrapping_mul(b)
15165    }
15166}
15167
15168impl RingOp<W32768> for Add<W32768> {
15169    type Operand = Limbs<512>;
15170    #[inline]
15171    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15172        a.wrapping_add(b)
15173    }
15174}
15175
15176impl RingOp<W32768> for Sub<W32768> {
15177    type Operand = Limbs<512>;
15178    #[inline]
15179    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15180        a.wrapping_sub(b)
15181    }
15182}
15183
15184impl RingOp<W32768> for Xor<W32768> {
15185    type Operand = Limbs<512>;
15186    #[inline]
15187    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15188        a.xor(b)
15189    }
15190}
15191
15192impl RingOp<W32768> for And<W32768> {
15193    type Operand = Limbs<512>;
15194    #[inline]
15195    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15196        a.and(b)
15197    }
15198}
15199
15200impl RingOp<W32768> for Or<W32768> {
15201    type Operand = Limbs<512>;
15202    #[inline]
15203    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15204        a.or(b)
15205    }
15206}
15207
15208impl UnaryRingOp<W32768> for Neg<W32768> {
15209    type Operand = Limbs<512>;
15210    #[inline]
15211    fn apply(a: Limbs<512>) -> Limbs<512> {
15212        Limbs::<512>::zero().wrapping_sub(a)
15213    }
15214}
15215
15216impl UnaryRingOp<W32768> for BNot<W32768> {
15217    type Operand = Limbs<512>;
15218    #[inline]
15219    fn apply(a: Limbs<512>) -> Limbs<512> {
15220        a.not()
15221    }
15222}
15223
15224impl UnaryRingOp<W32768> for Succ<W32768> {
15225    type Operand = Limbs<512>;
15226    #[inline]
15227    fn apply(a: Limbs<512>) -> Limbs<512> {
15228        a.wrapping_add(Limbs::<512>::from_words([
15229            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15230            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15231            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15232            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15233            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15234            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15235            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15236            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15237            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15238            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15239            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15240            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15241            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15242            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15243            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15244            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15245            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15246            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15247            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15248            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15249            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15250            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15251            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15252            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15253            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15254            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15255            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15256            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15257            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15258            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15259            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15260            0u64, 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,
15266        ]))
15267    }
15268}
15269
15270/// Phase L.2 (target §4.5): `const_ring_eval_w{n}` helpers for Limbs-backed
15271/// Witt levels. Each helper runs a `PrimitiveOp` over two `Limbs<N>` operands
15272/// and applies the level's bit-width mask to the result.
15273/// These helpers are always const-fn; whether `rustc` can complete a specific
15274/// compile-time evaluation within the developer's budget is a function of the
15275/// invocation (see target §4.5 Q2 practicality table).
15276#[inline]
15277#[must_use]
15278pub const fn const_ring_eval_w160(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15279    let raw = match op {
15280        PrimitiveOp::Add => a.wrapping_add(b),
15281        PrimitiveOp::Sub => a.wrapping_sub(b),
15282        PrimitiveOp::Mul => a.wrapping_mul(b),
15283        PrimitiveOp::And => a.and(b),
15284        PrimitiveOp::Or => a.or(b),
15285        PrimitiveOp::Xor => a.xor(b),
15286        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15287        PrimitiveOp::Bnot => a.not(),
15288        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15289        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15290        PrimitiveOp::Le => {
15291            if limbs_le_3(a, b) {
15292                limbs_one_3()
15293            } else {
15294                Limbs::<3>::zero()
15295            }
15296        }
15297        PrimitiveOp::Lt => {
15298            if limbs_lt_3(a, b) {
15299                limbs_one_3()
15300            } else {
15301                Limbs::<3>::zero()
15302            }
15303        }
15304        PrimitiveOp::Ge => {
15305            if limbs_le_3(b, a) {
15306                limbs_one_3()
15307            } else {
15308                Limbs::<3>::zero()
15309            }
15310        }
15311        PrimitiveOp::Gt => {
15312            if limbs_lt_3(b, a) {
15313                limbs_one_3()
15314            } else {
15315                Limbs::<3>::zero()
15316            }
15317        }
15318        PrimitiveOp::Concat => Limbs::<3>::zero(),
15319        PrimitiveOp::Div => {
15320            if limbs_is_zero_3(b) {
15321                Limbs::<3>::zero()
15322            } else {
15323                limbs_div_3(a, b)
15324            }
15325        }
15326        PrimitiveOp::Mod => {
15327            if limbs_is_zero_3(b) {
15328                Limbs::<3>::zero()
15329            } else {
15330                limbs_mod_3(a, b)
15331            }
15332        }
15333        PrimitiveOp::Pow => limbs_pow_3(a, b),
15334    };
15335    raw.mask_high_bits(160)
15336}
15337
15338#[inline]
15339#[must_use]
15340pub const fn const_ring_eval_w192(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15341    match op {
15342        PrimitiveOp::Add => a.wrapping_add(b),
15343        PrimitiveOp::Sub => a.wrapping_sub(b),
15344        PrimitiveOp::Mul => a.wrapping_mul(b),
15345        PrimitiveOp::And => a.and(b),
15346        PrimitiveOp::Or => a.or(b),
15347        PrimitiveOp::Xor => a.xor(b),
15348        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15349        PrimitiveOp::Bnot => a.not(),
15350        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15351        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15352        PrimitiveOp::Le => {
15353            if limbs_le_3(a, b) {
15354                limbs_one_3()
15355            } else {
15356                Limbs::<3>::zero()
15357            }
15358        }
15359        PrimitiveOp::Lt => {
15360            if limbs_lt_3(a, b) {
15361                limbs_one_3()
15362            } else {
15363                Limbs::<3>::zero()
15364            }
15365        }
15366        PrimitiveOp::Ge => {
15367            if limbs_le_3(b, a) {
15368                limbs_one_3()
15369            } else {
15370                Limbs::<3>::zero()
15371            }
15372        }
15373        PrimitiveOp::Gt => {
15374            if limbs_lt_3(b, a) {
15375                limbs_one_3()
15376            } else {
15377                Limbs::<3>::zero()
15378            }
15379        }
15380        PrimitiveOp::Concat => Limbs::<3>::zero(),
15381        PrimitiveOp::Div => {
15382            if limbs_is_zero_3(b) {
15383                Limbs::<3>::zero()
15384            } else {
15385                limbs_div_3(a, b)
15386            }
15387        }
15388        PrimitiveOp::Mod => {
15389            if limbs_is_zero_3(b) {
15390                Limbs::<3>::zero()
15391            } else {
15392                limbs_mod_3(a, b)
15393            }
15394        }
15395        PrimitiveOp::Pow => limbs_pow_3(a, b),
15396    }
15397}
15398
15399#[inline]
15400#[must_use]
15401pub const fn const_ring_eval_w224(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15402    let raw = match op {
15403        PrimitiveOp::Add => a.wrapping_add(b),
15404        PrimitiveOp::Sub => a.wrapping_sub(b),
15405        PrimitiveOp::Mul => a.wrapping_mul(b),
15406        PrimitiveOp::And => a.and(b),
15407        PrimitiveOp::Or => a.or(b),
15408        PrimitiveOp::Xor => a.xor(b),
15409        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15410        PrimitiveOp::Bnot => a.not(),
15411        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15412        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15413        PrimitiveOp::Le => {
15414            if limbs_le_4(a, b) {
15415                limbs_one_4()
15416            } else {
15417                Limbs::<4>::zero()
15418            }
15419        }
15420        PrimitiveOp::Lt => {
15421            if limbs_lt_4(a, b) {
15422                limbs_one_4()
15423            } else {
15424                Limbs::<4>::zero()
15425            }
15426        }
15427        PrimitiveOp::Ge => {
15428            if limbs_le_4(b, a) {
15429                limbs_one_4()
15430            } else {
15431                Limbs::<4>::zero()
15432            }
15433        }
15434        PrimitiveOp::Gt => {
15435            if limbs_lt_4(b, a) {
15436                limbs_one_4()
15437            } else {
15438                Limbs::<4>::zero()
15439            }
15440        }
15441        PrimitiveOp::Concat => Limbs::<4>::zero(),
15442        PrimitiveOp::Div => {
15443            if limbs_is_zero_4(b) {
15444                Limbs::<4>::zero()
15445            } else {
15446                limbs_div_4(a, b)
15447            }
15448        }
15449        PrimitiveOp::Mod => {
15450            if limbs_is_zero_4(b) {
15451                Limbs::<4>::zero()
15452            } else {
15453                limbs_mod_4(a, b)
15454            }
15455        }
15456        PrimitiveOp::Pow => limbs_pow_4(a, b),
15457    };
15458    raw.mask_high_bits(224)
15459}
15460
15461#[inline]
15462#[must_use]
15463pub const fn const_ring_eval_w256(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15464    match op {
15465        PrimitiveOp::Add => a.wrapping_add(b),
15466        PrimitiveOp::Sub => a.wrapping_sub(b),
15467        PrimitiveOp::Mul => a.wrapping_mul(b),
15468        PrimitiveOp::And => a.and(b),
15469        PrimitiveOp::Or => a.or(b),
15470        PrimitiveOp::Xor => a.xor(b),
15471        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15472        PrimitiveOp::Bnot => a.not(),
15473        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15474        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15475        PrimitiveOp::Le => {
15476            if limbs_le_4(a, b) {
15477                limbs_one_4()
15478            } else {
15479                Limbs::<4>::zero()
15480            }
15481        }
15482        PrimitiveOp::Lt => {
15483            if limbs_lt_4(a, b) {
15484                limbs_one_4()
15485            } else {
15486                Limbs::<4>::zero()
15487            }
15488        }
15489        PrimitiveOp::Ge => {
15490            if limbs_le_4(b, a) {
15491                limbs_one_4()
15492            } else {
15493                Limbs::<4>::zero()
15494            }
15495        }
15496        PrimitiveOp::Gt => {
15497            if limbs_lt_4(b, a) {
15498                limbs_one_4()
15499            } else {
15500                Limbs::<4>::zero()
15501            }
15502        }
15503        PrimitiveOp::Concat => Limbs::<4>::zero(),
15504        PrimitiveOp::Div => {
15505            if limbs_is_zero_4(b) {
15506                Limbs::<4>::zero()
15507            } else {
15508                limbs_div_4(a, b)
15509            }
15510        }
15511        PrimitiveOp::Mod => {
15512            if limbs_is_zero_4(b) {
15513                Limbs::<4>::zero()
15514            } else {
15515                limbs_mod_4(a, b)
15516            }
15517        }
15518        PrimitiveOp::Pow => limbs_pow_4(a, b),
15519    }
15520}
15521
15522#[inline]
15523#[must_use]
15524pub const fn const_ring_eval_w384(op: PrimitiveOp, a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
15525    match op {
15526        PrimitiveOp::Add => a.wrapping_add(b),
15527        PrimitiveOp::Sub => a.wrapping_sub(b),
15528        PrimitiveOp::Mul => a.wrapping_mul(b),
15529        PrimitiveOp::And => a.and(b),
15530        PrimitiveOp::Or => a.or(b),
15531        PrimitiveOp::Xor => a.xor(b),
15532        PrimitiveOp::Neg => Limbs::<6>::zero().wrapping_sub(a),
15533        PrimitiveOp::Bnot => a.not(),
15534        PrimitiveOp::Succ => a.wrapping_add(limbs_one_6()),
15535        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_6()),
15536        PrimitiveOp::Le => {
15537            if limbs_le_6(a, b) {
15538                limbs_one_6()
15539            } else {
15540                Limbs::<6>::zero()
15541            }
15542        }
15543        PrimitiveOp::Lt => {
15544            if limbs_lt_6(a, b) {
15545                limbs_one_6()
15546            } else {
15547                Limbs::<6>::zero()
15548            }
15549        }
15550        PrimitiveOp::Ge => {
15551            if limbs_le_6(b, a) {
15552                limbs_one_6()
15553            } else {
15554                Limbs::<6>::zero()
15555            }
15556        }
15557        PrimitiveOp::Gt => {
15558            if limbs_lt_6(b, a) {
15559                limbs_one_6()
15560            } else {
15561                Limbs::<6>::zero()
15562            }
15563        }
15564        PrimitiveOp::Concat => Limbs::<6>::zero(),
15565        PrimitiveOp::Div => {
15566            if limbs_is_zero_6(b) {
15567                Limbs::<6>::zero()
15568            } else {
15569                limbs_div_6(a, b)
15570            }
15571        }
15572        PrimitiveOp::Mod => {
15573            if limbs_is_zero_6(b) {
15574                Limbs::<6>::zero()
15575            } else {
15576                limbs_mod_6(a, b)
15577            }
15578        }
15579        PrimitiveOp::Pow => limbs_pow_6(a, b),
15580    }
15581}
15582
15583#[inline]
15584#[must_use]
15585pub const fn const_ring_eval_w448(op: PrimitiveOp, a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
15586    match op {
15587        PrimitiveOp::Add => a.wrapping_add(b),
15588        PrimitiveOp::Sub => a.wrapping_sub(b),
15589        PrimitiveOp::Mul => a.wrapping_mul(b),
15590        PrimitiveOp::And => a.and(b),
15591        PrimitiveOp::Or => a.or(b),
15592        PrimitiveOp::Xor => a.xor(b),
15593        PrimitiveOp::Neg => Limbs::<7>::zero().wrapping_sub(a),
15594        PrimitiveOp::Bnot => a.not(),
15595        PrimitiveOp::Succ => a.wrapping_add(limbs_one_7()),
15596        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_7()),
15597        PrimitiveOp::Le => {
15598            if limbs_le_7(a, b) {
15599                limbs_one_7()
15600            } else {
15601                Limbs::<7>::zero()
15602            }
15603        }
15604        PrimitiveOp::Lt => {
15605            if limbs_lt_7(a, b) {
15606                limbs_one_7()
15607            } else {
15608                Limbs::<7>::zero()
15609            }
15610        }
15611        PrimitiveOp::Ge => {
15612            if limbs_le_7(b, a) {
15613                limbs_one_7()
15614            } else {
15615                Limbs::<7>::zero()
15616            }
15617        }
15618        PrimitiveOp::Gt => {
15619            if limbs_lt_7(b, a) {
15620                limbs_one_7()
15621            } else {
15622                Limbs::<7>::zero()
15623            }
15624        }
15625        PrimitiveOp::Concat => Limbs::<7>::zero(),
15626        PrimitiveOp::Div => {
15627            if limbs_is_zero_7(b) {
15628                Limbs::<7>::zero()
15629            } else {
15630                limbs_div_7(a, b)
15631            }
15632        }
15633        PrimitiveOp::Mod => {
15634            if limbs_is_zero_7(b) {
15635                Limbs::<7>::zero()
15636            } else {
15637                limbs_mod_7(a, b)
15638            }
15639        }
15640        PrimitiveOp::Pow => limbs_pow_7(a, b),
15641    }
15642}
15643
15644#[inline]
15645#[must_use]
15646pub const fn const_ring_eval_w512(op: PrimitiveOp, a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
15647    match op {
15648        PrimitiveOp::Add => a.wrapping_add(b),
15649        PrimitiveOp::Sub => a.wrapping_sub(b),
15650        PrimitiveOp::Mul => a.wrapping_mul(b),
15651        PrimitiveOp::And => a.and(b),
15652        PrimitiveOp::Or => a.or(b),
15653        PrimitiveOp::Xor => a.xor(b),
15654        PrimitiveOp::Neg => Limbs::<8>::zero().wrapping_sub(a),
15655        PrimitiveOp::Bnot => a.not(),
15656        PrimitiveOp::Succ => a.wrapping_add(limbs_one_8()),
15657        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_8()),
15658        PrimitiveOp::Le => {
15659            if limbs_le_8(a, b) {
15660                limbs_one_8()
15661            } else {
15662                Limbs::<8>::zero()
15663            }
15664        }
15665        PrimitiveOp::Lt => {
15666            if limbs_lt_8(a, b) {
15667                limbs_one_8()
15668            } else {
15669                Limbs::<8>::zero()
15670            }
15671        }
15672        PrimitiveOp::Ge => {
15673            if limbs_le_8(b, a) {
15674                limbs_one_8()
15675            } else {
15676                Limbs::<8>::zero()
15677            }
15678        }
15679        PrimitiveOp::Gt => {
15680            if limbs_lt_8(b, a) {
15681                limbs_one_8()
15682            } else {
15683                Limbs::<8>::zero()
15684            }
15685        }
15686        PrimitiveOp::Concat => Limbs::<8>::zero(),
15687        PrimitiveOp::Div => {
15688            if limbs_is_zero_8(b) {
15689                Limbs::<8>::zero()
15690            } else {
15691                limbs_div_8(a, b)
15692            }
15693        }
15694        PrimitiveOp::Mod => {
15695            if limbs_is_zero_8(b) {
15696                Limbs::<8>::zero()
15697            } else {
15698                limbs_mod_8(a, b)
15699            }
15700        }
15701        PrimitiveOp::Pow => limbs_pow_8(a, b),
15702    }
15703}
15704
15705#[inline]
15706#[must_use]
15707pub const fn const_ring_eval_w520(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
15708    let raw = match op {
15709        PrimitiveOp::Add => a.wrapping_add(b),
15710        PrimitiveOp::Sub => a.wrapping_sub(b),
15711        PrimitiveOp::Mul => a.wrapping_mul(b),
15712        PrimitiveOp::And => a.and(b),
15713        PrimitiveOp::Or => a.or(b),
15714        PrimitiveOp::Xor => a.xor(b),
15715        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
15716        PrimitiveOp::Bnot => a.not(),
15717        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
15718        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
15719        PrimitiveOp::Le => {
15720            if limbs_le_9(a, b) {
15721                limbs_one_9()
15722            } else {
15723                Limbs::<9>::zero()
15724            }
15725        }
15726        PrimitiveOp::Lt => {
15727            if limbs_lt_9(a, b) {
15728                limbs_one_9()
15729            } else {
15730                Limbs::<9>::zero()
15731            }
15732        }
15733        PrimitiveOp::Ge => {
15734            if limbs_le_9(b, a) {
15735                limbs_one_9()
15736            } else {
15737                Limbs::<9>::zero()
15738            }
15739        }
15740        PrimitiveOp::Gt => {
15741            if limbs_lt_9(b, a) {
15742                limbs_one_9()
15743            } else {
15744                Limbs::<9>::zero()
15745            }
15746        }
15747        PrimitiveOp::Concat => Limbs::<9>::zero(),
15748        PrimitiveOp::Div => {
15749            if limbs_is_zero_9(b) {
15750                Limbs::<9>::zero()
15751            } else {
15752                limbs_div_9(a, b)
15753            }
15754        }
15755        PrimitiveOp::Mod => {
15756            if limbs_is_zero_9(b) {
15757                Limbs::<9>::zero()
15758            } else {
15759                limbs_mod_9(a, b)
15760            }
15761        }
15762        PrimitiveOp::Pow => limbs_pow_9(a, b),
15763    };
15764    raw.mask_high_bits(520)
15765}
15766
15767#[inline]
15768#[must_use]
15769pub const fn const_ring_eval_w528(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
15770    let raw = match op {
15771        PrimitiveOp::Add => a.wrapping_add(b),
15772        PrimitiveOp::Sub => a.wrapping_sub(b),
15773        PrimitiveOp::Mul => a.wrapping_mul(b),
15774        PrimitiveOp::And => a.and(b),
15775        PrimitiveOp::Or => a.or(b),
15776        PrimitiveOp::Xor => a.xor(b),
15777        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
15778        PrimitiveOp::Bnot => a.not(),
15779        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
15780        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
15781        PrimitiveOp::Le => {
15782            if limbs_le_9(a, b) {
15783                limbs_one_9()
15784            } else {
15785                Limbs::<9>::zero()
15786            }
15787        }
15788        PrimitiveOp::Lt => {
15789            if limbs_lt_9(a, b) {
15790                limbs_one_9()
15791            } else {
15792                Limbs::<9>::zero()
15793            }
15794        }
15795        PrimitiveOp::Ge => {
15796            if limbs_le_9(b, a) {
15797                limbs_one_9()
15798            } else {
15799                Limbs::<9>::zero()
15800            }
15801        }
15802        PrimitiveOp::Gt => {
15803            if limbs_lt_9(b, a) {
15804                limbs_one_9()
15805            } else {
15806                Limbs::<9>::zero()
15807            }
15808        }
15809        PrimitiveOp::Concat => Limbs::<9>::zero(),
15810        PrimitiveOp::Div => {
15811            if limbs_is_zero_9(b) {
15812                Limbs::<9>::zero()
15813            } else {
15814                limbs_div_9(a, b)
15815            }
15816        }
15817        PrimitiveOp::Mod => {
15818            if limbs_is_zero_9(b) {
15819                Limbs::<9>::zero()
15820            } else {
15821                limbs_mod_9(a, b)
15822            }
15823        }
15824        PrimitiveOp::Pow => limbs_pow_9(a, b),
15825    };
15826    raw.mask_high_bits(528)
15827}
15828
15829#[inline]
15830#[must_use]
15831pub const fn const_ring_eval_w1024(op: PrimitiveOp, a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
15832    match op {
15833        PrimitiveOp::Add => a.wrapping_add(b),
15834        PrimitiveOp::Sub => a.wrapping_sub(b),
15835        PrimitiveOp::Mul => a.wrapping_mul(b),
15836        PrimitiveOp::And => a.and(b),
15837        PrimitiveOp::Or => a.or(b),
15838        PrimitiveOp::Xor => a.xor(b),
15839        PrimitiveOp::Neg => Limbs::<16>::zero().wrapping_sub(a),
15840        PrimitiveOp::Bnot => a.not(),
15841        PrimitiveOp::Succ => a.wrapping_add(limbs_one_16()),
15842        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_16()),
15843        PrimitiveOp::Le => {
15844            if limbs_le_16(a, b) {
15845                limbs_one_16()
15846            } else {
15847                Limbs::<16>::zero()
15848            }
15849        }
15850        PrimitiveOp::Lt => {
15851            if limbs_lt_16(a, b) {
15852                limbs_one_16()
15853            } else {
15854                Limbs::<16>::zero()
15855            }
15856        }
15857        PrimitiveOp::Ge => {
15858            if limbs_le_16(b, a) {
15859                limbs_one_16()
15860            } else {
15861                Limbs::<16>::zero()
15862            }
15863        }
15864        PrimitiveOp::Gt => {
15865            if limbs_lt_16(b, a) {
15866                limbs_one_16()
15867            } else {
15868                Limbs::<16>::zero()
15869            }
15870        }
15871        PrimitiveOp::Concat => Limbs::<16>::zero(),
15872        PrimitiveOp::Div => {
15873            if limbs_is_zero_16(b) {
15874                Limbs::<16>::zero()
15875            } else {
15876                limbs_div_16(a, b)
15877            }
15878        }
15879        PrimitiveOp::Mod => {
15880            if limbs_is_zero_16(b) {
15881                Limbs::<16>::zero()
15882            } else {
15883                limbs_mod_16(a, b)
15884            }
15885        }
15886        PrimitiveOp::Pow => limbs_pow_16(a, b),
15887    }
15888}
15889
15890#[inline]
15891#[must_use]
15892pub const fn const_ring_eval_w2048(op: PrimitiveOp, a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15893    match op {
15894        PrimitiveOp::Add => a.wrapping_add(b),
15895        PrimitiveOp::Sub => a.wrapping_sub(b),
15896        PrimitiveOp::Mul => a.wrapping_mul(b),
15897        PrimitiveOp::And => a.and(b),
15898        PrimitiveOp::Or => a.or(b),
15899        PrimitiveOp::Xor => a.xor(b),
15900        PrimitiveOp::Neg => Limbs::<32>::zero().wrapping_sub(a),
15901        PrimitiveOp::Bnot => a.not(),
15902        PrimitiveOp::Succ => a.wrapping_add(limbs_one_32()),
15903        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_32()),
15904        PrimitiveOp::Le => {
15905            if limbs_le_32(a, b) {
15906                limbs_one_32()
15907            } else {
15908                Limbs::<32>::zero()
15909            }
15910        }
15911        PrimitiveOp::Lt => {
15912            if limbs_lt_32(a, b) {
15913                limbs_one_32()
15914            } else {
15915                Limbs::<32>::zero()
15916            }
15917        }
15918        PrimitiveOp::Ge => {
15919            if limbs_le_32(b, a) {
15920                limbs_one_32()
15921            } else {
15922                Limbs::<32>::zero()
15923            }
15924        }
15925        PrimitiveOp::Gt => {
15926            if limbs_lt_32(b, a) {
15927                limbs_one_32()
15928            } else {
15929                Limbs::<32>::zero()
15930            }
15931        }
15932        PrimitiveOp::Concat => Limbs::<32>::zero(),
15933        PrimitiveOp::Div => {
15934            if limbs_is_zero_32(b) {
15935                Limbs::<32>::zero()
15936            } else {
15937                limbs_div_32(a, b)
15938            }
15939        }
15940        PrimitiveOp::Mod => {
15941            if limbs_is_zero_32(b) {
15942                Limbs::<32>::zero()
15943            } else {
15944                limbs_mod_32(a, b)
15945            }
15946        }
15947        PrimitiveOp::Pow => limbs_pow_32(a, b),
15948    }
15949}
15950
15951#[inline]
15952#[must_use]
15953pub const fn const_ring_eval_w4096(op: PrimitiveOp, a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15954    match op {
15955        PrimitiveOp::Add => a.wrapping_add(b),
15956        PrimitiveOp::Sub => a.wrapping_sub(b),
15957        PrimitiveOp::Mul => a.wrapping_mul(b),
15958        PrimitiveOp::And => a.and(b),
15959        PrimitiveOp::Or => a.or(b),
15960        PrimitiveOp::Xor => a.xor(b),
15961        PrimitiveOp::Neg => Limbs::<64>::zero().wrapping_sub(a),
15962        PrimitiveOp::Bnot => a.not(),
15963        PrimitiveOp::Succ => a.wrapping_add(limbs_one_64()),
15964        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_64()),
15965        PrimitiveOp::Le => {
15966            if limbs_le_64(a, b) {
15967                limbs_one_64()
15968            } else {
15969                Limbs::<64>::zero()
15970            }
15971        }
15972        PrimitiveOp::Lt => {
15973            if limbs_lt_64(a, b) {
15974                limbs_one_64()
15975            } else {
15976                Limbs::<64>::zero()
15977            }
15978        }
15979        PrimitiveOp::Ge => {
15980            if limbs_le_64(b, a) {
15981                limbs_one_64()
15982            } else {
15983                Limbs::<64>::zero()
15984            }
15985        }
15986        PrimitiveOp::Gt => {
15987            if limbs_lt_64(b, a) {
15988                limbs_one_64()
15989            } else {
15990                Limbs::<64>::zero()
15991            }
15992        }
15993        PrimitiveOp::Concat => Limbs::<64>::zero(),
15994        PrimitiveOp::Div => {
15995            if limbs_is_zero_64(b) {
15996                Limbs::<64>::zero()
15997            } else {
15998                limbs_div_64(a, b)
15999            }
16000        }
16001        PrimitiveOp::Mod => {
16002            if limbs_is_zero_64(b) {
16003                Limbs::<64>::zero()
16004            } else {
16005                limbs_mod_64(a, b)
16006            }
16007        }
16008        PrimitiveOp::Pow => limbs_pow_64(a, b),
16009    }
16010}
16011
16012#[inline]
16013#[must_use]
16014pub const fn const_ring_eval_w8192(op: PrimitiveOp, a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
16015    match op {
16016        PrimitiveOp::Add => a.wrapping_add(b),
16017        PrimitiveOp::Sub => a.wrapping_sub(b),
16018        PrimitiveOp::Mul => a.wrapping_mul(b),
16019        PrimitiveOp::And => a.and(b),
16020        PrimitiveOp::Or => a.or(b),
16021        PrimitiveOp::Xor => a.xor(b),
16022        PrimitiveOp::Neg => Limbs::<128>::zero().wrapping_sub(a),
16023        PrimitiveOp::Bnot => a.not(),
16024        PrimitiveOp::Succ => a.wrapping_add(limbs_one_128()),
16025        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_128()),
16026        PrimitiveOp::Le => {
16027            if limbs_le_128(a, b) {
16028                limbs_one_128()
16029            } else {
16030                Limbs::<128>::zero()
16031            }
16032        }
16033        PrimitiveOp::Lt => {
16034            if limbs_lt_128(a, b) {
16035                limbs_one_128()
16036            } else {
16037                Limbs::<128>::zero()
16038            }
16039        }
16040        PrimitiveOp::Ge => {
16041            if limbs_le_128(b, a) {
16042                limbs_one_128()
16043            } else {
16044                Limbs::<128>::zero()
16045            }
16046        }
16047        PrimitiveOp::Gt => {
16048            if limbs_lt_128(b, a) {
16049                limbs_one_128()
16050            } else {
16051                Limbs::<128>::zero()
16052            }
16053        }
16054        PrimitiveOp::Concat => Limbs::<128>::zero(),
16055        PrimitiveOp::Div => {
16056            if limbs_is_zero_128(b) {
16057                Limbs::<128>::zero()
16058            } else {
16059                limbs_div_128(a, b)
16060            }
16061        }
16062        PrimitiveOp::Mod => {
16063            if limbs_is_zero_128(b) {
16064                Limbs::<128>::zero()
16065            } else {
16066                limbs_mod_128(a, b)
16067            }
16068        }
16069        PrimitiveOp::Pow => limbs_pow_128(a, b),
16070    }
16071}
16072
16073#[inline]
16074#[must_use]
16075pub const fn const_ring_eval_w12288(op: PrimitiveOp, a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
16076    match op {
16077        PrimitiveOp::Add => a.wrapping_add(b),
16078        PrimitiveOp::Sub => a.wrapping_sub(b),
16079        PrimitiveOp::Mul => a.wrapping_mul(b),
16080        PrimitiveOp::And => a.and(b),
16081        PrimitiveOp::Or => a.or(b),
16082        PrimitiveOp::Xor => a.xor(b),
16083        PrimitiveOp::Neg => Limbs::<192>::zero().wrapping_sub(a),
16084        PrimitiveOp::Bnot => a.not(),
16085        PrimitiveOp::Succ => a.wrapping_add(limbs_one_192()),
16086        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_192()),
16087        PrimitiveOp::Le => {
16088            if limbs_le_192(a, b) {
16089                limbs_one_192()
16090            } else {
16091                Limbs::<192>::zero()
16092            }
16093        }
16094        PrimitiveOp::Lt => {
16095            if limbs_lt_192(a, b) {
16096                limbs_one_192()
16097            } else {
16098                Limbs::<192>::zero()
16099            }
16100        }
16101        PrimitiveOp::Ge => {
16102            if limbs_le_192(b, a) {
16103                limbs_one_192()
16104            } else {
16105                Limbs::<192>::zero()
16106            }
16107        }
16108        PrimitiveOp::Gt => {
16109            if limbs_lt_192(b, a) {
16110                limbs_one_192()
16111            } else {
16112                Limbs::<192>::zero()
16113            }
16114        }
16115        PrimitiveOp::Concat => Limbs::<192>::zero(),
16116        PrimitiveOp::Div => {
16117            if limbs_is_zero_192(b) {
16118                Limbs::<192>::zero()
16119            } else {
16120                limbs_div_192(a, b)
16121            }
16122        }
16123        PrimitiveOp::Mod => {
16124            if limbs_is_zero_192(b) {
16125                Limbs::<192>::zero()
16126            } else {
16127                limbs_mod_192(a, b)
16128            }
16129        }
16130        PrimitiveOp::Pow => limbs_pow_192(a, b),
16131    }
16132}
16133
16134#[inline]
16135#[must_use]
16136pub const fn const_ring_eval_w16384(op: PrimitiveOp, a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
16137    match op {
16138        PrimitiveOp::Add => a.wrapping_add(b),
16139        PrimitiveOp::Sub => a.wrapping_sub(b),
16140        PrimitiveOp::Mul => a.wrapping_mul(b),
16141        PrimitiveOp::And => a.and(b),
16142        PrimitiveOp::Or => a.or(b),
16143        PrimitiveOp::Xor => a.xor(b),
16144        PrimitiveOp::Neg => Limbs::<256>::zero().wrapping_sub(a),
16145        PrimitiveOp::Bnot => a.not(),
16146        PrimitiveOp::Succ => a.wrapping_add(limbs_one_256()),
16147        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_256()),
16148        PrimitiveOp::Le => {
16149            if limbs_le_256(a, b) {
16150                limbs_one_256()
16151            } else {
16152                Limbs::<256>::zero()
16153            }
16154        }
16155        PrimitiveOp::Lt => {
16156            if limbs_lt_256(a, b) {
16157                limbs_one_256()
16158            } else {
16159                Limbs::<256>::zero()
16160            }
16161        }
16162        PrimitiveOp::Ge => {
16163            if limbs_le_256(b, a) {
16164                limbs_one_256()
16165            } else {
16166                Limbs::<256>::zero()
16167            }
16168        }
16169        PrimitiveOp::Gt => {
16170            if limbs_lt_256(b, a) {
16171                limbs_one_256()
16172            } else {
16173                Limbs::<256>::zero()
16174            }
16175        }
16176        PrimitiveOp::Concat => Limbs::<256>::zero(),
16177        PrimitiveOp::Div => {
16178            if limbs_is_zero_256(b) {
16179                Limbs::<256>::zero()
16180            } else {
16181                limbs_div_256(a, b)
16182            }
16183        }
16184        PrimitiveOp::Mod => {
16185            if limbs_is_zero_256(b) {
16186                Limbs::<256>::zero()
16187            } else {
16188                limbs_mod_256(a, b)
16189            }
16190        }
16191        PrimitiveOp::Pow => limbs_pow_256(a, b),
16192    }
16193}
16194
16195#[inline]
16196#[must_use]
16197pub const fn const_ring_eval_w32768(op: PrimitiveOp, a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
16198    match op {
16199        PrimitiveOp::Add => a.wrapping_add(b),
16200        PrimitiveOp::Sub => a.wrapping_sub(b),
16201        PrimitiveOp::Mul => a.wrapping_mul(b),
16202        PrimitiveOp::And => a.and(b),
16203        PrimitiveOp::Or => a.or(b),
16204        PrimitiveOp::Xor => a.xor(b),
16205        PrimitiveOp::Neg => Limbs::<512>::zero().wrapping_sub(a),
16206        PrimitiveOp::Bnot => a.not(),
16207        PrimitiveOp::Succ => a.wrapping_add(limbs_one_512()),
16208        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_512()),
16209        PrimitiveOp::Le => {
16210            if limbs_le_512(a, b) {
16211                limbs_one_512()
16212            } else {
16213                Limbs::<512>::zero()
16214            }
16215        }
16216        PrimitiveOp::Lt => {
16217            if limbs_lt_512(a, b) {
16218                limbs_one_512()
16219            } else {
16220                Limbs::<512>::zero()
16221            }
16222        }
16223        PrimitiveOp::Ge => {
16224            if limbs_le_512(b, a) {
16225                limbs_one_512()
16226            } else {
16227                Limbs::<512>::zero()
16228            }
16229        }
16230        PrimitiveOp::Gt => {
16231            if limbs_lt_512(b, a) {
16232                limbs_one_512()
16233            } else {
16234                Limbs::<512>::zero()
16235            }
16236        }
16237        PrimitiveOp::Concat => Limbs::<512>::zero(),
16238        PrimitiveOp::Div => {
16239            if limbs_is_zero_512(b) {
16240                Limbs::<512>::zero()
16241            } else {
16242                limbs_div_512(a, b)
16243            }
16244        }
16245        PrimitiveOp::Mod => {
16246            if limbs_is_zero_512(b) {
16247                Limbs::<512>::zero()
16248            } else {
16249                limbs_mod_512(a, b)
16250            }
16251        }
16252        PrimitiveOp::Pow => limbs_pow_512(a, b),
16253    }
16254}
16255
16256/// Phase L.2: one-constant helpers for `Limbs<N>::from_words([1, 0, ...])`.
16257#[inline]
16258#[must_use]
16259const fn limbs_one_3() -> Limbs<3> {
16260    Limbs::<3>::from_words([1u64, 0u64, 0u64])
16261}
16262
16263#[inline]
16264#[must_use]
16265const fn limbs_one_4() -> Limbs<4> {
16266    Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64])
16267}
16268
16269#[inline]
16270#[must_use]
16271const fn limbs_one_6() -> Limbs<6> {
16272    Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16273}
16274
16275#[inline]
16276#[must_use]
16277const fn limbs_one_7() -> Limbs<7> {
16278    Limbs::<7>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16279}
16280
16281#[inline]
16282#[must_use]
16283const fn limbs_one_8() -> Limbs<8> {
16284    Limbs::<8>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16285}
16286
16287#[inline]
16288#[must_use]
16289const fn limbs_one_9() -> Limbs<9> {
16290    Limbs::<9>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16291}
16292
16293#[inline]
16294#[must_use]
16295const fn limbs_one_16() -> Limbs<16> {
16296    Limbs::<16>::from_words([
16297        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16298        0u64,
16299    ])
16300}
16301
16302#[inline]
16303#[must_use]
16304const fn limbs_one_32() -> Limbs<32> {
16305    Limbs::<32>::from_words([
16306        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16307        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16308        0u64, 0u64,
16309    ])
16310}
16311
16312#[inline]
16313#[must_use]
16314const fn limbs_one_64() -> Limbs<64> {
16315    Limbs::<64>::from_words([
16316        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16317        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16318        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16319        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16320        0u64, 0u64, 0u64, 0u64,
16321    ])
16322}
16323
16324#[inline]
16325#[must_use]
16326const fn limbs_one_128() -> Limbs<128> {
16327    Limbs::<128>::from_words([
16328        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16329        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16330        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16331        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16332        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16333        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16334        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16335        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16336        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16337    ])
16338}
16339
16340#[inline]
16341#[must_use]
16342const fn limbs_one_192() -> Limbs<192> {
16343    Limbs::<192>::from_words([
16344        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16345        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16346        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16347        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16348        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16349        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16350        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16351        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16352        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16353        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16354        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16355        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16356        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16357    ])
16358}
16359
16360#[inline]
16361#[must_use]
16362const fn limbs_one_256() -> Limbs<256> {
16363    Limbs::<256>::from_words([
16364        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16365        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16366        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16367        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16368        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16369        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16370        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16371        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16372        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16373        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16374        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16375        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16376        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16377        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16378        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16379        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16380        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16381        0u64,
16382    ])
16383}
16384
16385#[inline]
16386#[must_use]
16387const fn limbs_one_512() -> Limbs<512> {
16388    Limbs::<512>::from_words([
16389        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16390        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16391        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16392        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16393        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16394        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16395        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16396        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16397        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16398        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16399        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16400        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16401        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16402        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16403        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16404        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16405        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16406        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16407        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16408        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16409        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16410        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16411        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16412        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16413        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16414        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16415        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16416        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16417        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16418        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16419        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16420        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16421        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16422        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16423        0u64, 0u64,
16424    ])
16425}
16426
16427/// ADR-013/TR-08: const-fn limb comparisons used by `const_ring_eval_w{n}`
16428/// to lift the comparison primitives to 0/1-valued ring indicators.
16429#[inline]
16430#[must_use]
16431const fn limbs_lt_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16432    let aw = a.words();
16433    let bw = b.words();
16434    let mut i = 3;
16435    while i > 0 {
16436        i -= 1;
16437        if aw[i] < bw[i] {
16438            return true;
16439        }
16440        if aw[i] > bw[i] {
16441            return false;
16442        }
16443    }
16444    false
16445}
16446
16447#[inline]
16448#[must_use]
16449const fn limbs_le_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16450    let aw = a.words();
16451    let bw = b.words();
16452    let mut i = 3;
16453    while i > 0 {
16454        i -= 1;
16455        if aw[i] < bw[i] {
16456            return true;
16457        }
16458        if aw[i] > bw[i] {
16459            return false;
16460        }
16461    }
16462    true
16463}
16464
16465#[inline]
16466#[must_use]
16467const fn limbs_lt_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16468    let aw = a.words();
16469    let bw = b.words();
16470    let mut i = 4;
16471    while i > 0 {
16472        i -= 1;
16473        if aw[i] < bw[i] {
16474            return true;
16475        }
16476        if aw[i] > bw[i] {
16477            return false;
16478        }
16479    }
16480    false
16481}
16482
16483#[inline]
16484#[must_use]
16485const fn limbs_le_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16486    let aw = a.words();
16487    let bw = b.words();
16488    let mut i = 4;
16489    while i > 0 {
16490        i -= 1;
16491        if aw[i] < bw[i] {
16492            return true;
16493        }
16494        if aw[i] > bw[i] {
16495            return false;
16496        }
16497    }
16498    true
16499}
16500
16501#[inline]
16502#[must_use]
16503const fn limbs_lt_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16504    let aw = a.words();
16505    let bw = b.words();
16506    let mut i = 6;
16507    while i > 0 {
16508        i -= 1;
16509        if aw[i] < bw[i] {
16510            return true;
16511        }
16512        if aw[i] > bw[i] {
16513            return false;
16514        }
16515    }
16516    false
16517}
16518
16519#[inline]
16520#[must_use]
16521const fn limbs_le_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16522    let aw = a.words();
16523    let bw = b.words();
16524    let mut i = 6;
16525    while i > 0 {
16526        i -= 1;
16527        if aw[i] < bw[i] {
16528            return true;
16529        }
16530        if aw[i] > bw[i] {
16531            return false;
16532        }
16533    }
16534    true
16535}
16536
16537#[inline]
16538#[must_use]
16539const fn limbs_lt_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16540    let aw = a.words();
16541    let bw = b.words();
16542    let mut i = 7;
16543    while i > 0 {
16544        i -= 1;
16545        if aw[i] < bw[i] {
16546            return true;
16547        }
16548        if aw[i] > bw[i] {
16549            return false;
16550        }
16551    }
16552    false
16553}
16554
16555#[inline]
16556#[must_use]
16557const fn limbs_le_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16558    let aw = a.words();
16559    let bw = b.words();
16560    let mut i = 7;
16561    while i > 0 {
16562        i -= 1;
16563        if aw[i] < bw[i] {
16564            return true;
16565        }
16566        if aw[i] > bw[i] {
16567            return false;
16568        }
16569    }
16570    true
16571}
16572
16573#[inline]
16574#[must_use]
16575const fn limbs_lt_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16576    let aw = a.words();
16577    let bw = b.words();
16578    let mut i = 8;
16579    while i > 0 {
16580        i -= 1;
16581        if aw[i] < bw[i] {
16582            return true;
16583        }
16584        if aw[i] > bw[i] {
16585            return false;
16586        }
16587    }
16588    false
16589}
16590
16591#[inline]
16592#[must_use]
16593const fn limbs_le_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16594    let aw = a.words();
16595    let bw = b.words();
16596    let mut i = 8;
16597    while i > 0 {
16598        i -= 1;
16599        if aw[i] < bw[i] {
16600            return true;
16601        }
16602        if aw[i] > bw[i] {
16603            return false;
16604        }
16605    }
16606    true
16607}
16608
16609#[inline]
16610#[must_use]
16611const fn limbs_lt_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16612    let aw = a.words();
16613    let bw = b.words();
16614    let mut i = 9;
16615    while i > 0 {
16616        i -= 1;
16617        if aw[i] < bw[i] {
16618            return true;
16619        }
16620        if aw[i] > bw[i] {
16621            return false;
16622        }
16623    }
16624    false
16625}
16626
16627#[inline]
16628#[must_use]
16629const fn limbs_le_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16630    let aw = a.words();
16631    let bw = b.words();
16632    let mut i = 9;
16633    while i > 0 {
16634        i -= 1;
16635        if aw[i] < bw[i] {
16636            return true;
16637        }
16638        if aw[i] > bw[i] {
16639            return false;
16640        }
16641    }
16642    true
16643}
16644
16645#[inline]
16646#[must_use]
16647const fn limbs_lt_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16648    let aw = a.words();
16649    let bw = b.words();
16650    let mut i = 16;
16651    while i > 0 {
16652        i -= 1;
16653        if aw[i] < bw[i] {
16654            return true;
16655        }
16656        if aw[i] > bw[i] {
16657            return false;
16658        }
16659    }
16660    false
16661}
16662
16663#[inline]
16664#[must_use]
16665const fn limbs_le_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16666    let aw = a.words();
16667    let bw = b.words();
16668    let mut i = 16;
16669    while i > 0 {
16670        i -= 1;
16671        if aw[i] < bw[i] {
16672            return true;
16673        }
16674        if aw[i] > bw[i] {
16675            return false;
16676        }
16677    }
16678    true
16679}
16680
16681#[inline]
16682#[must_use]
16683const fn limbs_lt_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16684    let aw = a.words();
16685    let bw = b.words();
16686    let mut i = 32;
16687    while i > 0 {
16688        i -= 1;
16689        if aw[i] < bw[i] {
16690            return true;
16691        }
16692        if aw[i] > bw[i] {
16693            return false;
16694        }
16695    }
16696    false
16697}
16698
16699#[inline]
16700#[must_use]
16701const fn limbs_le_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16702    let aw = a.words();
16703    let bw = b.words();
16704    let mut i = 32;
16705    while i > 0 {
16706        i -= 1;
16707        if aw[i] < bw[i] {
16708            return true;
16709        }
16710        if aw[i] > bw[i] {
16711            return false;
16712        }
16713    }
16714    true
16715}
16716
16717#[inline]
16718#[must_use]
16719const fn limbs_lt_64(a: Limbs<64>, b: Limbs<64>) -> bool {
16720    let aw = a.words();
16721    let bw = b.words();
16722    let mut i = 64;
16723    while i > 0 {
16724        i -= 1;
16725        if aw[i] < bw[i] {
16726            return true;
16727        }
16728        if aw[i] > bw[i] {
16729            return false;
16730        }
16731    }
16732    false
16733}
16734
16735#[inline]
16736#[must_use]
16737const fn limbs_le_64(a: Limbs<64>, b: Limbs<64>) -> bool {
16738    let aw = a.words();
16739    let bw = b.words();
16740    let mut i = 64;
16741    while i > 0 {
16742        i -= 1;
16743        if aw[i] < bw[i] {
16744            return true;
16745        }
16746        if aw[i] > bw[i] {
16747            return false;
16748        }
16749    }
16750    true
16751}
16752
16753#[inline]
16754#[must_use]
16755const fn limbs_lt_128(a: Limbs<128>, b: Limbs<128>) -> bool {
16756    let aw = a.words();
16757    let bw = b.words();
16758    let mut i = 128;
16759    while i > 0 {
16760        i -= 1;
16761        if aw[i] < bw[i] {
16762            return true;
16763        }
16764        if aw[i] > bw[i] {
16765            return false;
16766        }
16767    }
16768    false
16769}
16770
16771#[inline]
16772#[must_use]
16773const fn limbs_le_128(a: Limbs<128>, b: Limbs<128>) -> bool {
16774    let aw = a.words();
16775    let bw = b.words();
16776    let mut i = 128;
16777    while i > 0 {
16778        i -= 1;
16779        if aw[i] < bw[i] {
16780            return true;
16781        }
16782        if aw[i] > bw[i] {
16783            return false;
16784        }
16785    }
16786    true
16787}
16788
16789#[inline]
16790#[must_use]
16791const fn limbs_lt_192(a: Limbs<192>, b: Limbs<192>) -> bool {
16792    let aw = a.words();
16793    let bw = b.words();
16794    let mut i = 192;
16795    while i > 0 {
16796        i -= 1;
16797        if aw[i] < bw[i] {
16798            return true;
16799        }
16800        if aw[i] > bw[i] {
16801            return false;
16802        }
16803    }
16804    false
16805}
16806
16807#[inline]
16808#[must_use]
16809const fn limbs_le_192(a: Limbs<192>, b: Limbs<192>) -> bool {
16810    let aw = a.words();
16811    let bw = b.words();
16812    let mut i = 192;
16813    while i > 0 {
16814        i -= 1;
16815        if aw[i] < bw[i] {
16816            return true;
16817        }
16818        if aw[i] > bw[i] {
16819            return false;
16820        }
16821    }
16822    true
16823}
16824
16825#[inline]
16826#[must_use]
16827const fn limbs_lt_256(a: Limbs<256>, b: Limbs<256>) -> bool {
16828    let aw = a.words();
16829    let bw = b.words();
16830    let mut i = 256;
16831    while i > 0 {
16832        i -= 1;
16833        if aw[i] < bw[i] {
16834            return true;
16835        }
16836        if aw[i] > bw[i] {
16837            return false;
16838        }
16839    }
16840    false
16841}
16842
16843#[inline]
16844#[must_use]
16845const fn limbs_le_256(a: Limbs<256>, b: Limbs<256>) -> bool {
16846    let aw = a.words();
16847    let bw = b.words();
16848    let mut i = 256;
16849    while i > 0 {
16850        i -= 1;
16851        if aw[i] < bw[i] {
16852            return true;
16853        }
16854        if aw[i] > bw[i] {
16855            return false;
16856        }
16857    }
16858    true
16859}
16860
16861#[inline]
16862#[must_use]
16863const fn limbs_lt_512(a: Limbs<512>, b: Limbs<512>) -> bool {
16864    let aw = a.words();
16865    let bw = b.words();
16866    let mut i = 512;
16867    while i > 0 {
16868        i -= 1;
16869        if aw[i] < bw[i] {
16870            return true;
16871        }
16872        if aw[i] > bw[i] {
16873            return false;
16874        }
16875    }
16876    false
16877}
16878
16879#[inline]
16880#[must_use]
16881const fn limbs_le_512(a: Limbs<512>, b: Limbs<512>) -> bool {
16882    let aw = a.words();
16883    let bw = b.words();
16884    let mut i = 512;
16885    while i > 0 {
16886        i -= 1;
16887        if aw[i] < bw[i] {
16888            return true;
16889        }
16890        if aw[i] > bw[i] {
16891            return false;
16892        }
16893    }
16894    true
16895}
16896
16897/// ADR-053: zero-check, binary-long-division, and square-and-multiply
16898/// helpers used by the const-fn `Div`/`Mod`/`Pow` arms of `const_ring_eval_w{n}`.
16899#[inline]
16900#[must_use]
16901const fn limbs_is_zero_3(a: Limbs<3>) -> bool {
16902    let aw = a.words();
16903    let mut i = 0usize;
16904    while i < 3 {
16905        if aw[i] != 0 {
16906            return false;
16907        }
16908        i += 1;
16909    }
16910    true
16911}
16912
16913#[inline]
16914#[must_use]
16915const fn limbs_shl1_3(a: Limbs<3>) -> Limbs<3> {
16916    let aw = a.words();
16917    let mut out = [0u64; 3];
16918    let mut carry: u64 = 0;
16919    let mut i = 0usize;
16920    while i < 3 {
16921        let v = aw[i];
16922        out[i] = (v << 1) | carry;
16923        carry = v >> 63;
16924        i += 1;
16925    }
16926    Limbs::<3>::from_words(out)
16927}
16928
16929#[inline]
16930#[must_use]
16931const fn limbs_set_bit0_3(a: Limbs<3>) -> Limbs<3> {
16932    let aw = a.words();
16933    let mut out = [0u64; 3];
16934    let mut i = 0usize;
16935    while i < 3 {
16936        out[i] = aw[i];
16937        i += 1;
16938    }
16939    out[0] |= 1u64;
16940    Limbs::<3>::from_words(out)
16941}
16942
16943#[inline]
16944#[must_use]
16945const fn limbs_bit_msb_3(a: Limbs<3>, msb_index: usize) -> u64 {
16946    let aw = a.words();
16947    let total_bits = 3 * 64;
16948    let lsb_index = total_bits - 1 - msb_index;
16949    let word = lsb_index / 64;
16950    let bit = lsb_index % 64;
16951    (aw[word] >> bit) & 1u64
16952}
16953
16954#[inline]
16955#[must_use]
16956const fn limbs_divmod_3(a: Limbs<3>, b: Limbs<3>) -> (Limbs<3>, Limbs<3>) {
16957    let mut q = Limbs::<3>::zero();
16958    let mut r = Limbs::<3>::zero();
16959    let total_bits = 3 * 64;
16960    let mut i = 0usize;
16961    while i < total_bits {
16962        r = limbs_shl1_3(r);
16963        if limbs_bit_msb_3(a, i) == 1 {
16964            r = limbs_set_bit0_3(r);
16965        }
16966        if limbs_le_3(b, r) {
16967            r = r.wrapping_sub(b);
16968            q = limbs_shl1_3(q);
16969            q = limbs_set_bit0_3(q);
16970        } else {
16971            q = limbs_shl1_3(q);
16972        }
16973        i += 1;
16974    }
16975    (q, r)
16976}
16977
16978#[inline]
16979#[must_use]
16980const fn limbs_div_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
16981    let (q, _) = limbs_divmod_3(a, b);
16982    q
16983}
16984
16985#[inline]
16986#[must_use]
16987const fn limbs_mod_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
16988    let (_, r) = limbs_divmod_3(a, b);
16989    r
16990}
16991
16992#[inline]
16993#[must_use]
16994const fn limbs_pow_3(base: Limbs<3>, exp: Limbs<3>) -> Limbs<3> {
16995    let mut result = limbs_one_3();
16996    let mut b = base;
16997    let ew = exp.words();
16998    let mut word = 0usize;
16999    while word < 3 {
17000        let mut bit = 0u32;
17001        while bit < 64 {
17002            if ((ew[word] >> bit) & 1u64) == 1u64 {
17003                result = result.wrapping_mul(b);
17004            }
17005            b = b.wrapping_mul(b);
17006            bit += 1;
17007        }
17008        word += 1;
17009    }
17010    result
17011}
17012
17013#[inline]
17014#[must_use]
17015const fn limbs_is_zero_4(a: Limbs<4>) -> bool {
17016    let aw = a.words();
17017    let mut i = 0usize;
17018    while i < 4 {
17019        if aw[i] != 0 {
17020            return false;
17021        }
17022        i += 1;
17023    }
17024    true
17025}
17026
17027#[inline]
17028#[must_use]
17029const fn limbs_shl1_4(a: Limbs<4>) -> Limbs<4> {
17030    let aw = a.words();
17031    let mut out = [0u64; 4];
17032    let mut carry: u64 = 0;
17033    let mut i = 0usize;
17034    while i < 4 {
17035        let v = aw[i];
17036        out[i] = (v << 1) | carry;
17037        carry = v >> 63;
17038        i += 1;
17039    }
17040    Limbs::<4>::from_words(out)
17041}
17042
17043#[inline]
17044#[must_use]
17045const fn limbs_set_bit0_4(a: Limbs<4>) -> Limbs<4> {
17046    let aw = a.words();
17047    let mut out = [0u64; 4];
17048    let mut i = 0usize;
17049    while i < 4 {
17050        out[i] = aw[i];
17051        i += 1;
17052    }
17053    out[0] |= 1u64;
17054    Limbs::<4>::from_words(out)
17055}
17056
17057#[inline]
17058#[must_use]
17059const fn limbs_bit_msb_4(a: Limbs<4>, msb_index: usize) -> u64 {
17060    let aw = a.words();
17061    let total_bits = 4 * 64;
17062    let lsb_index = total_bits - 1 - msb_index;
17063    let word = lsb_index / 64;
17064    let bit = lsb_index % 64;
17065    (aw[word] >> bit) & 1u64
17066}
17067
17068#[inline]
17069#[must_use]
17070const fn limbs_divmod_4(a: Limbs<4>, b: Limbs<4>) -> (Limbs<4>, Limbs<4>) {
17071    let mut q = Limbs::<4>::zero();
17072    let mut r = Limbs::<4>::zero();
17073    let total_bits = 4 * 64;
17074    let mut i = 0usize;
17075    while i < total_bits {
17076        r = limbs_shl1_4(r);
17077        if limbs_bit_msb_4(a, i) == 1 {
17078            r = limbs_set_bit0_4(r);
17079        }
17080        if limbs_le_4(b, r) {
17081            r = r.wrapping_sub(b);
17082            q = limbs_shl1_4(q);
17083            q = limbs_set_bit0_4(q);
17084        } else {
17085            q = limbs_shl1_4(q);
17086        }
17087        i += 1;
17088    }
17089    (q, r)
17090}
17091
17092#[inline]
17093#[must_use]
17094const fn limbs_div_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17095    let (q, _) = limbs_divmod_4(a, b);
17096    q
17097}
17098
17099#[inline]
17100#[must_use]
17101const fn limbs_mod_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17102    let (_, r) = limbs_divmod_4(a, b);
17103    r
17104}
17105
17106#[inline]
17107#[must_use]
17108const fn limbs_pow_4(base: Limbs<4>, exp: Limbs<4>) -> Limbs<4> {
17109    let mut result = limbs_one_4();
17110    let mut b = base;
17111    let ew = exp.words();
17112    let mut word = 0usize;
17113    while word < 4 {
17114        let mut bit = 0u32;
17115        while bit < 64 {
17116            if ((ew[word] >> bit) & 1u64) == 1u64 {
17117                result = result.wrapping_mul(b);
17118            }
17119            b = b.wrapping_mul(b);
17120            bit += 1;
17121        }
17122        word += 1;
17123    }
17124    result
17125}
17126
17127#[inline]
17128#[must_use]
17129const fn limbs_is_zero_6(a: Limbs<6>) -> bool {
17130    let aw = a.words();
17131    let mut i = 0usize;
17132    while i < 6 {
17133        if aw[i] != 0 {
17134            return false;
17135        }
17136        i += 1;
17137    }
17138    true
17139}
17140
17141#[inline]
17142#[must_use]
17143const fn limbs_shl1_6(a: Limbs<6>) -> Limbs<6> {
17144    let aw = a.words();
17145    let mut out = [0u64; 6];
17146    let mut carry: u64 = 0;
17147    let mut i = 0usize;
17148    while i < 6 {
17149        let v = aw[i];
17150        out[i] = (v << 1) | carry;
17151        carry = v >> 63;
17152        i += 1;
17153    }
17154    Limbs::<6>::from_words(out)
17155}
17156
17157#[inline]
17158#[must_use]
17159const fn limbs_set_bit0_6(a: Limbs<6>) -> Limbs<6> {
17160    let aw = a.words();
17161    let mut out = [0u64; 6];
17162    let mut i = 0usize;
17163    while i < 6 {
17164        out[i] = aw[i];
17165        i += 1;
17166    }
17167    out[0] |= 1u64;
17168    Limbs::<6>::from_words(out)
17169}
17170
17171#[inline]
17172#[must_use]
17173const fn limbs_bit_msb_6(a: Limbs<6>, msb_index: usize) -> u64 {
17174    let aw = a.words();
17175    let total_bits = 6 * 64;
17176    let lsb_index = total_bits - 1 - msb_index;
17177    let word = lsb_index / 64;
17178    let bit = lsb_index % 64;
17179    (aw[word] >> bit) & 1u64
17180}
17181
17182#[inline]
17183#[must_use]
17184const fn limbs_divmod_6(a: Limbs<6>, b: Limbs<6>) -> (Limbs<6>, Limbs<6>) {
17185    let mut q = Limbs::<6>::zero();
17186    let mut r = Limbs::<6>::zero();
17187    let total_bits = 6 * 64;
17188    let mut i = 0usize;
17189    while i < total_bits {
17190        r = limbs_shl1_6(r);
17191        if limbs_bit_msb_6(a, i) == 1 {
17192            r = limbs_set_bit0_6(r);
17193        }
17194        if limbs_le_6(b, r) {
17195            r = r.wrapping_sub(b);
17196            q = limbs_shl1_6(q);
17197            q = limbs_set_bit0_6(q);
17198        } else {
17199            q = limbs_shl1_6(q);
17200        }
17201        i += 1;
17202    }
17203    (q, r)
17204}
17205
17206#[inline]
17207#[must_use]
17208const fn limbs_div_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17209    let (q, _) = limbs_divmod_6(a, b);
17210    q
17211}
17212
17213#[inline]
17214#[must_use]
17215const fn limbs_mod_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17216    let (_, r) = limbs_divmod_6(a, b);
17217    r
17218}
17219
17220#[inline]
17221#[must_use]
17222const fn limbs_pow_6(base: Limbs<6>, exp: Limbs<6>) -> Limbs<6> {
17223    let mut result = limbs_one_6();
17224    let mut b = base;
17225    let ew = exp.words();
17226    let mut word = 0usize;
17227    while word < 6 {
17228        let mut bit = 0u32;
17229        while bit < 64 {
17230            if ((ew[word] >> bit) & 1u64) == 1u64 {
17231                result = result.wrapping_mul(b);
17232            }
17233            b = b.wrapping_mul(b);
17234            bit += 1;
17235        }
17236        word += 1;
17237    }
17238    result
17239}
17240
17241#[inline]
17242#[must_use]
17243const fn limbs_is_zero_7(a: Limbs<7>) -> bool {
17244    let aw = a.words();
17245    let mut i = 0usize;
17246    while i < 7 {
17247        if aw[i] != 0 {
17248            return false;
17249        }
17250        i += 1;
17251    }
17252    true
17253}
17254
17255#[inline]
17256#[must_use]
17257const fn limbs_shl1_7(a: Limbs<7>) -> Limbs<7> {
17258    let aw = a.words();
17259    let mut out = [0u64; 7];
17260    let mut carry: u64 = 0;
17261    let mut i = 0usize;
17262    while i < 7 {
17263        let v = aw[i];
17264        out[i] = (v << 1) | carry;
17265        carry = v >> 63;
17266        i += 1;
17267    }
17268    Limbs::<7>::from_words(out)
17269}
17270
17271#[inline]
17272#[must_use]
17273const fn limbs_set_bit0_7(a: Limbs<7>) -> Limbs<7> {
17274    let aw = a.words();
17275    let mut out = [0u64; 7];
17276    let mut i = 0usize;
17277    while i < 7 {
17278        out[i] = aw[i];
17279        i += 1;
17280    }
17281    out[0] |= 1u64;
17282    Limbs::<7>::from_words(out)
17283}
17284
17285#[inline]
17286#[must_use]
17287const fn limbs_bit_msb_7(a: Limbs<7>, msb_index: usize) -> u64 {
17288    let aw = a.words();
17289    let total_bits = 7 * 64;
17290    let lsb_index = total_bits - 1 - msb_index;
17291    let word = lsb_index / 64;
17292    let bit = lsb_index % 64;
17293    (aw[word] >> bit) & 1u64
17294}
17295
17296#[inline]
17297#[must_use]
17298const fn limbs_divmod_7(a: Limbs<7>, b: Limbs<7>) -> (Limbs<7>, Limbs<7>) {
17299    let mut q = Limbs::<7>::zero();
17300    let mut r = Limbs::<7>::zero();
17301    let total_bits = 7 * 64;
17302    let mut i = 0usize;
17303    while i < total_bits {
17304        r = limbs_shl1_7(r);
17305        if limbs_bit_msb_7(a, i) == 1 {
17306            r = limbs_set_bit0_7(r);
17307        }
17308        if limbs_le_7(b, r) {
17309            r = r.wrapping_sub(b);
17310            q = limbs_shl1_7(q);
17311            q = limbs_set_bit0_7(q);
17312        } else {
17313            q = limbs_shl1_7(q);
17314        }
17315        i += 1;
17316    }
17317    (q, r)
17318}
17319
17320#[inline]
17321#[must_use]
17322const fn limbs_div_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17323    let (q, _) = limbs_divmod_7(a, b);
17324    q
17325}
17326
17327#[inline]
17328#[must_use]
17329const fn limbs_mod_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17330    let (_, r) = limbs_divmod_7(a, b);
17331    r
17332}
17333
17334#[inline]
17335#[must_use]
17336const fn limbs_pow_7(base: Limbs<7>, exp: Limbs<7>) -> Limbs<7> {
17337    let mut result = limbs_one_7();
17338    let mut b = base;
17339    let ew = exp.words();
17340    let mut word = 0usize;
17341    while word < 7 {
17342        let mut bit = 0u32;
17343        while bit < 64 {
17344            if ((ew[word] >> bit) & 1u64) == 1u64 {
17345                result = result.wrapping_mul(b);
17346            }
17347            b = b.wrapping_mul(b);
17348            bit += 1;
17349        }
17350        word += 1;
17351    }
17352    result
17353}
17354
17355#[inline]
17356#[must_use]
17357const fn limbs_is_zero_8(a: Limbs<8>) -> bool {
17358    let aw = a.words();
17359    let mut i = 0usize;
17360    while i < 8 {
17361        if aw[i] != 0 {
17362            return false;
17363        }
17364        i += 1;
17365    }
17366    true
17367}
17368
17369#[inline]
17370#[must_use]
17371const fn limbs_shl1_8(a: Limbs<8>) -> Limbs<8> {
17372    let aw = a.words();
17373    let mut out = [0u64; 8];
17374    let mut carry: u64 = 0;
17375    let mut i = 0usize;
17376    while i < 8 {
17377        let v = aw[i];
17378        out[i] = (v << 1) | carry;
17379        carry = v >> 63;
17380        i += 1;
17381    }
17382    Limbs::<8>::from_words(out)
17383}
17384
17385#[inline]
17386#[must_use]
17387const fn limbs_set_bit0_8(a: Limbs<8>) -> Limbs<8> {
17388    let aw = a.words();
17389    let mut out = [0u64; 8];
17390    let mut i = 0usize;
17391    while i < 8 {
17392        out[i] = aw[i];
17393        i += 1;
17394    }
17395    out[0] |= 1u64;
17396    Limbs::<8>::from_words(out)
17397}
17398
17399#[inline]
17400#[must_use]
17401const fn limbs_bit_msb_8(a: Limbs<8>, msb_index: usize) -> u64 {
17402    let aw = a.words();
17403    let total_bits = 8 * 64;
17404    let lsb_index = total_bits - 1 - msb_index;
17405    let word = lsb_index / 64;
17406    let bit = lsb_index % 64;
17407    (aw[word] >> bit) & 1u64
17408}
17409
17410#[inline]
17411#[must_use]
17412const fn limbs_divmod_8(a: Limbs<8>, b: Limbs<8>) -> (Limbs<8>, Limbs<8>) {
17413    let mut q = Limbs::<8>::zero();
17414    let mut r = Limbs::<8>::zero();
17415    let total_bits = 8 * 64;
17416    let mut i = 0usize;
17417    while i < total_bits {
17418        r = limbs_shl1_8(r);
17419        if limbs_bit_msb_8(a, i) == 1 {
17420            r = limbs_set_bit0_8(r);
17421        }
17422        if limbs_le_8(b, r) {
17423            r = r.wrapping_sub(b);
17424            q = limbs_shl1_8(q);
17425            q = limbs_set_bit0_8(q);
17426        } else {
17427            q = limbs_shl1_8(q);
17428        }
17429        i += 1;
17430    }
17431    (q, r)
17432}
17433
17434#[inline]
17435#[must_use]
17436const fn limbs_div_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17437    let (q, _) = limbs_divmod_8(a, b);
17438    q
17439}
17440
17441#[inline]
17442#[must_use]
17443const fn limbs_mod_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17444    let (_, r) = limbs_divmod_8(a, b);
17445    r
17446}
17447
17448#[inline]
17449#[must_use]
17450const fn limbs_pow_8(base: Limbs<8>, exp: Limbs<8>) -> Limbs<8> {
17451    let mut result = limbs_one_8();
17452    let mut b = base;
17453    let ew = exp.words();
17454    let mut word = 0usize;
17455    while word < 8 {
17456        let mut bit = 0u32;
17457        while bit < 64 {
17458            if ((ew[word] >> bit) & 1u64) == 1u64 {
17459                result = result.wrapping_mul(b);
17460            }
17461            b = b.wrapping_mul(b);
17462            bit += 1;
17463        }
17464        word += 1;
17465    }
17466    result
17467}
17468
17469#[inline]
17470#[must_use]
17471const fn limbs_is_zero_9(a: Limbs<9>) -> bool {
17472    let aw = a.words();
17473    let mut i = 0usize;
17474    while i < 9 {
17475        if aw[i] != 0 {
17476            return false;
17477        }
17478        i += 1;
17479    }
17480    true
17481}
17482
17483#[inline]
17484#[must_use]
17485const fn limbs_shl1_9(a: Limbs<9>) -> Limbs<9> {
17486    let aw = a.words();
17487    let mut out = [0u64; 9];
17488    let mut carry: u64 = 0;
17489    let mut i = 0usize;
17490    while i < 9 {
17491        let v = aw[i];
17492        out[i] = (v << 1) | carry;
17493        carry = v >> 63;
17494        i += 1;
17495    }
17496    Limbs::<9>::from_words(out)
17497}
17498
17499#[inline]
17500#[must_use]
17501const fn limbs_set_bit0_9(a: Limbs<9>) -> Limbs<9> {
17502    let aw = a.words();
17503    let mut out = [0u64; 9];
17504    let mut i = 0usize;
17505    while i < 9 {
17506        out[i] = aw[i];
17507        i += 1;
17508    }
17509    out[0] |= 1u64;
17510    Limbs::<9>::from_words(out)
17511}
17512
17513#[inline]
17514#[must_use]
17515const fn limbs_bit_msb_9(a: Limbs<9>, msb_index: usize) -> u64 {
17516    let aw = a.words();
17517    let total_bits = 9 * 64;
17518    let lsb_index = total_bits - 1 - msb_index;
17519    let word = lsb_index / 64;
17520    let bit = lsb_index % 64;
17521    (aw[word] >> bit) & 1u64
17522}
17523
17524#[inline]
17525#[must_use]
17526const fn limbs_divmod_9(a: Limbs<9>, b: Limbs<9>) -> (Limbs<9>, Limbs<9>) {
17527    let mut q = Limbs::<9>::zero();
17528    let mut r = Limbs::<9>::zero();
17529    let total_bits = 9 * 64;
17530    let mut i = 0usize;
17531    while i < total_bits {
17532        r = limbs_shl1_9(r);
17533        if limbs_bit_msb_9(a, i) == 1 {
17534            r = limbs_set_bit0_9(r);
17535        }
17536        if limbs_le_9(b, r) {
17537            r = r.wrapping_sub(b);
17538            q = limbs_shl1_9(q);
17539            q = limbs_set_bit0_9(q);
17540        } else {
17541            q = limbs_shl1_9(q);
17542        }
17543        i += 1;
17544    }
17545    (q, r)
17546}
17547
17548#[inline]
17549#[must_use]
17550const fn limbs_div_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17551    let (q, _) = limbs_divmod_9(a, b);
17552    q
17553}
17554
17555#[inline]
17556#[must_use]
17557const fn limbs_mod_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17558    let (_, r) = limbs_divmod_9(a, b);
17559    r
17560}
17561
17562#[inline]
17563#[must_use]
17564const fn limbs_pow_9(base: Limbs<9>, exp: Limbs<9>) -> Limbs<9> {
17565    let mut result = limbs_one_9();
17566    let mut b = base;
17567    let ew = exp.words();
17568    let mut word = 0usize;
17569    while word < 9 {
17570        let mut bit = 0u32;
17571        while bit < 64 {
17572            if ((ew[word] >> bit) & 1u64) == 1u64 {
17573                result = result.wrapping_mul(b);
17574            }
17575            b = b.wrapping_mul(b);
17576            bit += 1;
17577        }
17578        word += 1;
17579    }
17580    result
17581}
17582
17583#[inline]
17584#[must_use]
17585const fn limbs_is_zero_16(a: Limbs<16>) -> bool {
17586    let aw = a.words();
17587    let mut i = 0usize;
17588    while i < 16 {
17589        if aw[i] != 0 {
17590            return false;
17591        }
17592        i += 1;
17593    }
17594    true
17595}
17596
17597#[inline]
17598#[must_use]
17599const fn limbs_shl1_16(a: Limbs<16>) -> Limbs<16> {
17600    let aw = a.words();
17601    let mut out = [0u64; 16];
17602    let mut carry: u64 = 0;
17603    let mut i = 0usize;
17604    while i < 16 {
17605        let v = aw[i];
17606        out[i] = (v << 1) | carry;
17607        carry = v >> 63;
17608        i += 1;
17609    }
17610    Limbs::<16>::from_words(out)
17611}
17612
17613#[inline]
17614#[must_use]
17615const fn limbs_set_bit0_16(a: Limbs<16>) -> Limbs<16> {
17616    let aw = a.words();
17617    let mut out = [0u64; 16];
17618    let mut i = 0usize;
17619    while i < 16 {
17620        out[i] = aw[i];
17621        i += 1;
17622    }
17623    out[0] |= 1u64;
17624    Limbs::<16>::from_words(out)
17625}
17626
17627#[inline]
17628#[must_use]
17629const fn limbs_bit_msb_16(a: Limbs<16>, msb_index: usize) -> u64 {
17630    let aw = a.words();
17631    let total_bits = 16 * 64;
17632    let lsb_index = total_bits - 1 - msb_index;
17633    let word = lsb_index / 64;
17634    let bit = lsb_index % 64;
17635    (aw[word] >> bit) & 1u64
17636}
17637
17638#[inline]
17639#[must_use]
17640const fn limbs_divmod_16(a: Limbs<16>, b: Limbs<16>) -> (Limbs<16>, Limbs<16>) {
17641    let mut q = Limbs::<16>::zero();
17642    let mut r = Limbs::<16>::zero();
17643    let total_bits = 16 * 64;
17644    let mut i = 0usize;
17645    while i < total_bits {
17646        r = limbs_shl1_16(r);
17647        if limbs_bit_msb_16(a, i) == 1 {
17648            r = limbs_set_bit0_16(r);
17649        }
17650        if limbs_le_16(b, r) {
17651            r = r.wrapping_sub(b);
17652            q = limbs_shl1_16(q);
17653            q = limbs_set_bit0_16(q);
17654        } else {
17655            q = limbs_shl1_16(q);
17656        }
17657        i += 1;
17658    }
17659    (q, r)
17660}
17661
17662#[inline]
17663#[must_use]
17664const fn limbs_div_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17665    let (q, _) = limbs_divmod_16(a, b);
17666    q
17667}
17668
17669#[inline]
17670#[must_use]
17671const fn limbs_mod_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17672    let (_, r) = limbs_divmod_16(a, b);
17673    r
17674}
17675
17676#[inline]
17677#[must_use]
17678const fn limbs_pow_16(base: Limbs<16>, exp: Limbs<16>) -> Limbs<16> {
17679    let mut result = limbs_one_16();
17680    let mut b = base;
17681    let ew = exp.words();
17682    let mut word = 0usize;
17683    while word < 16 {
17684        let mut bit = 0u32;
17685        while bit < 64 {
17686            if ((ew[word] >> bit) & 1u64) == 1u64 {
17687                result = result.wrapping_mul(b);
17688            }
17689            b = b.wrapping_mul(b);
17690            bit += 1;
17691        }
17692        word += 1;
17693    }
17694    result
17695}
17696
17697#[inline]
17698#[must_use]
17699const fn limbs_is_zero_32(a: Limbs<32>) -> bool {
17700    let aw = a.words();
17701    let mut i = 0usize;
17702    while i < 32 {
17703        if aw[i] != 0 {
17704            return false;
17705        }
17706        i += 1;
17707    }
17708    true
17709}
17710
17711#[inline]
17712#[must_use]
17713const fn limbs_shl1_32(a: Limbs<32>) -> Limbs<32> {
17714    let aw = a.words();
17715    let mut out = [0u64; 32];
17716    let mut carry: u64 = 0;
17717    let mut i = 0usize;
17718    while i < 32 {
17719        let v = aw[i];
17720        out[i] = (v << 1) | carry;
17721        carry = v >> 63;
17722        i += 1;
17723    }
17724    Limbs::<32>::from_words(out)
17725}
17726
17727#[inline]
17728#[must_use]
17729const fn limbs_set_bit0_32(a: Limbs<32>) -> Limbs<32> {
17730    let aw = a.words();
17731    let mut out = [0u64; 32];
17732    let mut i = 0usize;
17733    while i < 32 {
17734        out[i] = aw[i];
17735        i += 1;
17736    }
17737    out[0] |= 1u64;
17738    Limbs::<32>::from_words(out)
17739}
17740
17741#[inline]
17742#[must_use]
17743const fn limbs_bit_msb_32(a: Limbs<32>, msb_index: usize) -> u64 {
17744    let aw = a.words();
17745    let total_bits = 32 * 64;
17746    let lsb_index = total_bits - 1 - msb_index;
17747    let word = lsb_index / 64;
17748    let bit = lsb_index % 64;
17749    (aw[word] >> bit) & 1u64
17750}
17751
17752#[inline]
17753#[must_use]
17754const fn limbs_divmod_32(a: Limbs<32>, b: Limbs<32>) -> (Limbs<32>, Limbs<32>) {
17755    let mut q = Limbs::<32>::zero();
17756    let mut r = Limbs::<32>::zero();
17757    let total_bits = 32 * 64;
17758    let mut i = 0usize;
17759    while i < total_bits {
17760        r = limbs_shl1_32(r);
17761        if limbs_bit_msb_32(a, i) == 1 {
17762            r = limbs_set_bit0_32(r);
17763        }
17764        if limbs_le_32(b, r) {
17765            r = r.wrapping_sub(b);
17766            q = limbs_shl1_32(q);
17767            q = limbs_set_bit0_32(q);
17768        } else {
17769            q = limbs_shl1_32(q);
17770        }
17771        i += 1;
17772    }
17773    (q, r)
17774}
17775
17776#[inline]
17777#[must_use]
17778const fn limbs_div_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
17779    let (q, _) = limbs_divmod_32(a, b);
17780    q
17781}
17782
17783#[inline]
17784#[must_use]
17785const fn limbs_mod_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
17786    let (_, r) = limbs_divmod_32(a, b);
17787    r
17788}
17789
17790#[inline]
17791#[must_use]
17792const fn limbs_pow_32(base: Limbs<32>, exp: Limbs<32>) -> Limbs<32> {
17793    let mut result = limbs_one_32();
17794    let mut b = base;
17795    let ew = exp.words();
17796    let mut word = 0usize;
17797    while word < 32 {
17798        let mut bit = 0u32;
17799        while bit < 64 {
17800            if ((ew[word] >> bit) & 1u64) == 1u64 {
17801                result = result.wrapping_mul(b);
17802            }
17803            b = b.wrapping_mul(b);
17804            bit += 1;
17805        }
17806        word += 1;
17807    }
17808    result
17809}
17810
17811#[inline]
17812#[must_use]
17813const fn limbs_is_zero_64(a: Limbs<64>) -> bool {
17814    let aw = a.words();
17815    let mut i = 0usize;
17816    while i < 64 {
17817        if aw[i] != 0 {
17818            return false;
17819        }
17820        i += 1;
17821    }
17822    true
17823}
17824
17825#[inline]
17826#[must_use]
17827const fn limbs_shl1_64(a: Limbs<64>) -> Limbs<64> {
17828    let aw = a.words();
17829    let mut out = [0u64; 64];
17830    let mut carry: u64 = 0;
17831    let mut i = 0usize;
17832    while i < 64 {
17833        let v = aw[i];
17834        out[i] = (v << 1) | carry;
17835        carry = v >> 63;
17836        i += 1;
17837    }
17838    Limbs::<64>::from_words(out)
17839}
17840
17841#[inline]
17842#[must_use]
17843const fn limbs_set_bit0_64(a: Limbs<64>) -> Limbs<64> {
17844    let aw = a.words();
17845    let mut out = [0u64; 64];
17846    let mut i = 0usize;
17847    while i < 64 {
17848        out[i] = aw[i];
17849        i += 1;
17850    }
17851    out[0] |= 1u64;
17852    Limbs::<64>::from_words(out)
17853}
17854
17855#[inline]
17856#[must_use]
17857const fn limbs_bit_msb_64(a: Limbs<64>, msb_index: usize) -> u64 {
17858    let aw = a.words();
17859    let total_bits = 64 * 64;
17860    let lsb_index = total_bits - 1 - msb_index;
17861    let word = lsb_index / 64;
17862    let bit = lsb_index % 64;
17863    (aw[word] >> bit) & 1u64
17864}
17865
17866#[inline]
17867#[must_use]
17868const fn limbs_divmod_64(a: Limbs<64>, b: Limbs<64>) -> (Limbs<64>, Limbs<64>) {
17869    let mut q = Limbs::<64>::zero();
17870    let mut r = Limbs::<64>::zero();
17871    let total_bits = 64 * 64;
17872    let mut i = 0usize;
17873    while i < total_bits {
17874        r = limbs_shl1_64(r);
17875        if limbs_bit_msb_64(a, i) == 1 {
17876            r = limbs_set_bit0_64(r);
17877        }
17878        if limbs_le_64(b, r) {
17879            r = r.wrapping_sub(b);
17880            q = limbs_shl1_64(q);
17881            q = limbs_set_bit0_64(q);
17882        } else {
17883            q = limbs_shl1_64(q);
17884        }
17885        i += 1;
17886    }
17887    (q, r)
17888}
17889
17890#[inline]
17891#[must_use]
17892const fn limbs_div_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
17893    let (q, _) = limbs_divmod_64(a, b);
17894    q
17895}
17896
17897#[inline]
17898#[must_use]
17899const fn limbs_mod_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
17900    let (_, r) = limbs_divmod_64(a, b);
17901    r
17902}
17903
17904#[inline]
17905#[must_use]
17906const fn limbs_pow_64(base: Limbs<64>, exp: Limbs<64>) -> Limbs<64> {
17907    let mut result = limbs_one_64();
17908    let mut b = base;
17909    let ew = exp.words();
17910    let mut word = 0usize;
17911    while word < 64 {
17912        let mut bit = 0u32;
17913        while bit < 64 {
17914            if ((ew[word] >> bit) & 1u64) == 1u64 {
17915                result = result.wrapping_mul(b);
17916            }
17917            b = b.wrapping_mul(b);
17918            bit += 1;
17919        }
17920        word += 1;
17921    }
17922    result
17923}
17924
17925#[inline]
17926#[must_use]
17927const fn limbs_is_zero_128(a: Limbs<128>) -> bool {
17928    let aw = a.words();
17929    let mut i = 0usize;
17930    while i < 128 {
17931        if aw[i] != 0 {
17932            return false;
17933        }
17934        i += 1;
17935    }
17936    true
17937}
17938
17939#[inline]
17940#[must_use]
17941const fn limbs_shl1_128(a: Limbs<128>) -> Limbs<128> {
17942    let aw = a.words();
17943    let mut out = [0u64; 128];
17944    let mut carry: u64 = 0;
17945    let mut i = 0usize;
17946    while i < 128 {
17947        let v = aw[i];
17948        out[i] = (v << 1) | carry;
17949        carry = v >> 63;
17950        i += 1;
17951    }
17952    Limbs::<128>::from_words(out)
17953}
17954
17955#[inline]
17956#[must_use]
17957const fn limbs_set_bit0_128(a: Limbs<128>) -> Limbs<128> {
17958    let aw = a.words();
17959    let mut out = [0u64; 128];
17960    let mut i = 0usize;
17961    while i < 128 {
17962        out[i] = aw[i];
17963        i += 1;
17964    }
17965    out[0] |= 1u64;
17966    Limbs::<128>::from_words(out)
17967}
17968
17969#[inline]
17970#[must_use]
17971const fn limbs_bit_msb_128(a: Limbs<128>, msb_index: usize) -> u64 {
17972    let aw = a.words();
17973    let total_bits = 128 * 64;
17974    let lsb_index = total_bits - 1 - msb_index;
17975    let word = lsb_index / 64;
17976    let bit = lsb_index % 64;
17977    (aw[word] >> bit) & 1u64
17978}
17979
17980#[inline]
17981#[must_use]
17982const fn limbs_divmod_128(a: Limbs<128>, b: Limbs<128>) -> (Limbs<128>, Limbs<128>) {
17983    let mut q = Limbs::<128>::zero();
17984    let mut r = Limbs::<128>::zero();
17985    let total_bits = 128 * 64;
17986    let mut i = 0usize;
17987    while i < total_bits {
17988        r = limbs_shl1_128(r);
17989        if limbs_bit_msb_128(a, i) == 1 {
17990            r = limbs_set_bit0_128(r);
17991        }
17992        if limbs_le_128(b, r) {
17993            r = r.wrapping_sub(b);
17994            q = limbs_shl1_128(q);
17995            q = limbs_set_bit0_128(q);
17996        } else {
17997            q = limbs_shl1_128(q);
17998        }
17999        i += 1;
18000    }
18001    (q, r)
18002}
18003
18004#[inline]
18005#[must_use]
18006const fn limbs_div_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18007    let (q, _) = limbs_divmod_128(a, b);
18008    q
18009}
18010
18011#[inline]
18012#[must_use]
18013const fn limbs_mod_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18014    let (_, r) = limbs_divmod_128(a, b);
18015    r
18016}
18017
18018#[inline]
18019#[must_use]
18020const fn limbs_pow_128(base: Limbs<128>, exp: Limbs<128>) -> Limbs<128> {
18021    let mut result = limbs_one_128();
18022    let mut b = base;
18023    let ew = exp.words();
18024    let mut word = 0usize;
18025    while word < 128 {
18026        let mut bit = 0u32;
18027        while bit < 64 {
18028            if ((ew[word] >> bit) & 1u64) == 1u64 {
18029                result = result.wrapping_mul(b);
18030            }
18031            b = b.wrapping_mul(b);
18032            bit += 1;
18033        }
18034        word += 1;
18035    }
18036    result
18037}
18038
18039#[inline]
18040#[must_use]
18041const fn limbs_is_zero_192(a: Limbs<192>) -> bool {
18042    let aw = a.words();
18043    let mut i = 0usize;
18044    while i < 192 {
18045        if aw[i] != 0 {
18046            return false;
18047        }
18048        i += 1;
18049    }
18050    true
18051}
18052
18053#[inline]
18054#[must_use]
18055const fn limbs_shl1_192(a: Limbs<192>) -> Limbs<192> {
18056    let aw = a.words();
18057    let mut out = [0u64; 192];
18058    let mut carry: u64 = 0;
18059    let mut i = 0usize;
18060    while i < 192 {
18061        let v = aw[i];
18062        out[i] = (v << 1) | carry;
18063        carry = v >> 63;
18064        i += 1;
18065    }
18066    Limbs::<192>::from_words(out)
18067}
18068
18069#[inline]
18070#[must_use]
18071const fn limbs_set_bit0_192(a: Limbs<192>) -> Limbs<192> {
18072    let aw = a.words();
18073    let mut out = [0u64; 192];
18074    let mut i = 0usize;
18075    while i < 192 {
18076        out[i] = aw[i];
18077        i += 1;
18078    }
18079    out[0] |= 1u64;
18080    Limbs::<192>::from_words(out)
18081}
18082
18083#[inline]
18084#[must_use]
18085const fn limbs_bit_msb_192(a: Limbs<192>, msb_index: usize) -> u64 {
18086    let aw = a.words();
18087    let total_bits = 192 * 64;
18088    let lsb_index = total_bits - 1 - msb_index;
18089    let word = lsb_index / 64;
18090    let bit = lsb_index % 64;
18091    (aw[word] >> bit) & 1u64
18092}
18093
18094#[inline]
18095#[must_use]
18096const fn limbs_divmod_192(a: Limbs<192>, b: Limbs<192>) -> (Limbs<192>, Limbs<192>) {
18097    let mut q = Limbs::<192>::zero();
18098    let mut r = Limbs::<192>::zero();
18099    let total_bits = 192 * 64;
18100    let mut i = 0usize;
18101    while i < total_bits {
18102        r = limbs_shl1_192(r);
18103        if limbs_bit_msb_192(a, i) == 1 {
18104            r = limbs_set_bit0_192(r);
18105        }
18106        if limbs_le_192(b, r) {
18107            r = r.wrapping_sub(b);
18108            q = limbs_shl1_192(q);
18109            q = limbs_set_bit0_192(q);
18110        } else {
18111            q = limbs_shl1_192(q);
18112        }
18113        i += 1;
18114    }
18115    (q, r)
18116}
18117
18118#[inline]
18119#[must_use]
18120const fn limbs_div_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18121    let (q, _) = limbs_divmod_192(a, b);
18122    q
18123}
18124
18125#[inline]
18126#[must_use]
18127const fn limbs_mod_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18128    let (_, r) = limbs_divmod_192(a, b);
18129    r
18130}
18131
18132#[inline]
18133#[must_use]
18134const fn limbs_pow_192(base: Limbs<192>, exp: Limbs<192>) -> Limbs<192> {
18135    let mut result = limbs_one_192();
18136    let mut b = base;
18137    let ew = exp.words();
18138    let mut word = 0usize;
18139    while word < 192 {
18140        let mut bit = 0u32;
18141        while bit < 64 {
18142            if ((ew[word] >> bit) & 1u64) == 1u64 {
18143                result = result.wrapping_mul(b);
18144            }
18145            b = b.wrapping_mul(b);
18146            bit += 1;
18147        }
18148        word += 1;
18149    }
18150    result
18151}
18152
18153#[inline]
18154#[must_use]
18155const fn limbs_is_zero_256(a: Limbs<256>) -> bool {
18156    let aw = a.words();
18157    let mut i = 0usize;
18158    while i < 256 {
18159        if aw[i] != 0 {
18160            return false;
18161        }
18162        i += 1;
18163    }
18164    true
18165}
18166
18167#[inline]
18168#[must_use]
18169const fn limbs_shl1_256(a: Limbs<256>) -> Limbs<256> {
18170    let aw = a.words();
18171    let mut out = [0u64; 256];
18172    let mut carry: u64 = 0;
18173    let mut i = 0usize;
18174    while i < 256 {
18175        let v = aw[i];
18176        out[i] = (v << 1) | carry;
18177        carry = v >> 63;
18178        i += 1;
18179    }
18180    Limbs::<256>::from_words(out)
18181}
18182
18183#[inline]
18184#[must_use]
18185const fn limbs_set_bit0_256(a: Limbs<256>) -> Limbs<256> {
18186    let aw = a.words();
18187    let mut out = [0u64; 256];
18188    let mut i = 0usize;
18189    while i < 256 {
18190        out[i] = aw[i];
18191        i += 1;
18192    }
18193    out[0] |= 1u64;
18194    Limbs::<256>::from_words(out)
18195}
18196
18197#[inline]
18198#[must_use]
18199const fn limbs_bit_msb_256(a: Limbs<256>, msb_index: usize) -> u64 {
18200    let aw = a.words();
18201    let total_bits = 256 * 64;
18202    let lsb_index = total_bits - 1 - msb_index;
18203    let word = lsb_index / 64;
18204    let bit = lsb_index % 64;
18205    (aw[word] >> bit) & 1u64
18206}
18207
18208#[inline]
18209#[must_use]
18210const fn limbs_divmod_256(a: Limbs<256>, b: Limbs<256>) -> (Limbs<256>, Limbs<256>) {
18211    let mut q = Limbs::<256>::zero();
18212    let mut r = Limbs::<256>::zero();
18213    let total_bits = 256 * 64;
18214    let mut i = 0usize;
18215    while i < total_bits {
18216        r = limbs_shl1_256(r);
18217        if limbs_bit_msb_256(a, i) == 1 {
18218            r = limbs_set_bit0_256(r);
18219        }
18220        if limbs_le_256(b, r) {
18221            r = r.wrapping_sub(b);
18222            q = limbs_shl1_256(q);
18223            q = limbs_set_bit0_256(q);
18224        } else {
18225            q = limbs_shl1_256(q);
18226        }
18227        i += 1;
18228    }
18229    (q, r)
18230}
18231
18232#[inline]
18233#[must_use]
18234const fn limbs_div_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18235    let (q, _) = limbs_divmod_256(a, b);
18236    q
18237}
18238
18239#[inline]
18240#[must_use]
18241const fn limbs_mod_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18242    let (_, r) = limbs_divmod_256(a, b);
18243    r
18244}
18245
18246#[inline]
18247#[must_use]
18248const fn limbs_pow_256(base: Limbs<256>, exp: Limbs<256>) -> Limbs<256> {
18249    let mut result = limbs_one_256();
18250    let mut b = base;
18251    let ew = exp.words();
18252    let mut word = 0usize;
18253    while word < 256 {
18254        let mut bit = 0u32;
18255        while bit < 64 {
18256            if ((ew[word] >> bit) & 1u64) == 1u64 {
18257                result = result.wrapping_mul(b);
18258            }
18259            b = b.wrapping_mul(b);
18260            bit += 1;
18261        }
18262        word += 1;
18263    }
18264    result
18265}
18266
18267#[inline]
18268#[must_use]
18269const fn limbs_is_zero_512(a: Limbs<512>) -> bool {
18270    let aw = a.words();
18271    let mut i = 0usize;
18272    while i < 512 {
18273        if aw[i] != 0 {
18274            return false;
18275        }
18276        i += 1;
18277    }
18278    true
18279}
18280
18281#[inline]
18282#[must_use]
18283const fn limbs_shl1_512(a: Limbs<512>) -> Limbs<512> {
18284    let aw = a.words();
18285    let mut out = [0u64; 512];
18286    let mut carry: u64 = 0;
18287    let mut i = 0usize;
18288    while i < 512 {
18289        let v = aw[i];
18290        out[i] = (v << 1) | carry;
18291        carry = v >> 63;
18292        i += 1;
18293    }
18294    Limbs::<512>::from_words(out)
18295}
18296
18297#[inline]
18298#[must_use]
18299const fn limbs_set_bit0_512(a: Limbs<512>) -> Limbs<512> {
18300    let aw = a.words();
18301    let mut out = [0u64; 512];
18302    let mut i = 0usize;
18303    while i < 512 {
18304        out[i] = aw[i];
18305        i += 1;
18306    }
18307    out[0] |= 1u64;
18308    Limbs::<512>::from_words(out)
18309}
18310
18311#[inline]
18312#[must_use]
18313const fn limbs_bit_msb_512(a: Limbs<512>, msb_index: usize) -> u64 {
18314    let aw = a.words();
18315    let total_bits = 512 * 64;
18316    let lsb_index = total_bits - 1 - msb_index;
18317    let word = lsb_index / 64;
18318    let bit = lsb_index % 64;
18319    (aw[word] >> bit) & 1u64
18320}
18321
18322#[inline]
18323#[must_use]
18324const fn limbs_divmod_512(a: Limbs<512>, b: Limbs<512>) -> (Limbs<512>, Limbs<512>) {
18325    let mut q = Limbs::<512>::zero();
18326    let mut r = Limbs::<512>::zero();
18327    let total_bits = 512 * 64;
18328    let mut i = 0usize;
18329    while i < total_bits {
18330        r = limbs_shl1_512(r);
18331        if limbs_bit_msb_512(a, i) == 1 {
18332            r = limbs_set_bit0_512(r);
18333        }
18334        if limbs_le_512(b, r) {
18335            r = r.wrapping_sub(b);
18336            q = limbs_shl1_512(q);
18337            q = limbs_set_bit0_512(q);
18338        } else {
18339            q = limbs_shl1_512(q);
18340        }
18341        i += 1;
18342    }
18343    (q, r)
18344}
18345
18346#[inline]
18347#[must_use]
18348const fn limbs_div_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18349    let (q, _) = limbs_divmod_512(a, b);
18350    q
18351}
18352
18353#[inline]
18354#[must_use]
18355const fn limbs_mod_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18356    let (_, r) = limbs_divmod_512(a, b);
18357    r
18358}
18359
18360#[inline]
18361#[must_use]
18362const fn limbs_pow_512(base: Limbs<512>, exp: Limbs<512>) -> Limbs<512> {
18363    let mut result = limbs_one_512();
18364    let mut b = base;
18365    let ew = exp.words();
18366    let mut word = 0usize;
18367    while word < 512 {
18368        let mut bit = 0u32;
18369        while bit < 64 {
18370            if ((ew[word] >> bit) & 1u64) == 1u64 {
18371                result = result.wrapping_mul(b);
18372            }
18373            b = b.wrapping_mul(b);
18374            bit += 1;
18375        }
18376        word += 1;
18377    }
18378    result
18379}
18380
18381/// Sealed marker trait for fragment classifiers (Is2SatShape, IsHornShape,
18382/// IsResidualFragment) emitted parametrically from the predicate individuals
18383/// referenced by `predicate:InhabitanceDispatchTable`.
18384pub trait FragmentMarker: fragment_sealed::Sealed {}
18385
18386mod fragment_sealed {
18387    /// Private supertrait.
18388    pub trait Sealed {}
18389    impl Sealed for super::Is2SatShape {}
18390    impl Sealed for super::IsHornShape {}
18391    impl Sealed for super::IsResidualFragment {}
18392}
18393
18394/// Fragment marker for `predicate:Is2SatShape`. Zero-sized.
18395#[derive(Debug, Default, Clone, Copy)]
18396pub struct Is2SatShape;
18397impl FragmentMarker for Is2SatShape {}
18398
18399/// Fragment marker for `predicate:IsHornShape`. Zero-sized.
18400#[derive(Debug, Default, Clone, Copy)]
18401pub struct IsHornShape;
18402impl FragmentMarker for IsHornShape {}
18403
18404/// Fragment marker for `predicate:IsResidualFragment`. Zero-sized.
18405#[derive(Debug, Default, Clone, Copy)]
18406pub struct IsResidualFragment;
18407impl FragmentMarker for IsResidualFragment {}
18408
18409/// A single dispatch rule entry pairing a predicate IRI, a target resolver
18410/// name, and an evaluation priority.
18411#[derive(Debug, Clone, Copy)]
18412pub struct DispatchRule {
18413    /// IRI of the predicate that selects this rule.
18414    pub predicate_iri: &'static str,
18415    /// IRI of the target resolver class invoked when the predicate holds.
18416    pub target_resolver_iri: &'static str,
18417    /// Evaluation order; lower values evaluate first.
18418    pub priority: u32,
18419}
18420
18421/// A static dispatch table — an ordered slice of `DispatchRule` entries.
18422pub type DispatchTable = &'static [DispatchRule];
18423
18424/// v0.2.1 dispatch table generated from `predicate:InhabitanceDispatchTable`.
18425pub const INHABITANCE_DISPATCH_TABLE: DispatchTable = &[
18426    DispatchRule {
18427        predicate_iri: "https://uor.foundation/predicate/Is2SatShape",
18428        target_resolver_iri: "https://uor.foundation/resolver/TwoSatDecider",
18429        priority: 0,
18430    },
18431    DispatchRule {
18432        predicate_iri: "https://uor.foundation/predicate/IsHornShape",
18433        target_resolver_iri: "https://uor.foundation/resolver/HornSatDecider",
18434        priority: 1,
18435    },
18436    DispatchRule {
18437        predicate_iri: "https://uor.foundation/predicate/IsResidualFragment",
18438        target_resolver_iri: "https://uor.foundation/resolver/ResidualVerdictResolver",
18439        priority: 2,
18440    },
18441];
18442
18443/// v0.2.1 `Deref` impl for `Validated<T: OntologyTarget>` so consumers can call
18444/// certificate methods directly: `cert.target_level()` rather than
18445/// `cert.inner().target_level()`. The bound `T: OntologyTarget` keeps the
18446/// auto-deref scoped to foundation-produced types.
18447impl<T: OntologyTarget> core::ops::Deref for Validated<T> {
18448    type Target = T;
18449    #[inline]
18450    fn deref(&self) -> &T {
18451        &self.inner
18452    }
18453}
18454
18455mod bound_constraint_sealed {
18456    /// Sealed supertrait for the closed Observable catalogue.
18457    pub trait ObservableSealed {}
18458    /// Sealed supertrait for the closed BoundShape catalogue.
18459    pub trait BoundShapeSealed {}
18460}
18461
18462/// Sealed marker trait identifying the closed catalogue of observables
18463/// admissible in BoundConstraint. Implemented by unit structs emitted
18464/// below per `observable:Observable` subclass referenced by a
18465/// BoundConstraint kind individual.
18466pub trait Observable: bound_constraint_sealed::ObservableSealed {
18467    /// Ontology IRI of this observable class.
18468    const IRI: &'static str;
18469}
18470
18471/// Sealed marker trait identifying the closed catalogue of bound shapes.
18472/// Exactly six individuals: EqualBound, LessEqBound, GreaterEqBound,
18473/// RangeContainBound, ResidueClassBound, AffineEqualBound.
18474pub trait BoundShape: bound_constraint_sealed::BoundShapeSealed {
18475    /// Ontology IRI of this bound shape individual.
18476    const IRI: &'static str;
18477}
18478
18479/// Observes a Datum's value modulo a configurable modulus.
18480#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18481pub struct ValueModObservable;
18482impl bound_constraint_sealed::ObservableSealed for ValueModObservable {}
18483impl Observable for ValueModObservable {
18484    const IRI: &'static str = "https://uor.foundation/observable/ValueModObservable";
18485}
18486
18487/// Distance between two ring elements under the Hamming metric.
18488#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18489pub struct HammingMetric;
18490impl bound_constraint_sealed::ObservableSealed for HammingMetric {}
18491impl Observable for HammingMetric {
18492    const IRI: &'static str = "https://uor.foundation/observable/HammingMetric";
18493}
18494
18495/// Observes the derivation depth of a Datum.
18496#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18497pub struct DerivationDepthObservable;
18498impl bound_constraint_sealed::ObservableSealed for DerivationDepthObservable {}
18499impl Observable for DerivationDepthObservable {
18500    const IRI: &'static str = "https://uor.foundation/derivation/DerivationDepthObservable";
18501}
18502
18503/// Observes the carry depth of a Datum in the W₂ tower.
18504#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18505pub struct CarryDepthObservable;
18506impl bound_constraint_sealed::ObservableSealed for CarryDepthObservable {}
18507impl Observable for CarryDepthObservable {
18508    const IRI: &'static str = "https://uor.foundation/carry/CarryDepthObservable";
18509}
18510
18511/// Observes the free-rank of the partition associated with a Datum.
18512#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18513pub struct FreeRankObservable;
18514impl bound_constraint_sealed::ObservableSealed for FreeRankObservable {}
18515impl Observable for FreeRankObservable {
18516    const IRI: &'static str = "https://uor.foundation/partition/FreeRankObservable";
18517}
18518
18519/// Predicate form: `observable(datum) == target`.
18520#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18521pub struct EqualBound;
18522impl bound_constraint_sealed::BoundShapeSealed for EqualBound {}
18523impl BoundShape for EqualBound {
18524    const IRI: &'static str = "https://uor.foundation/type/EqualBound";
18525}
18526
18527/// Predicate form: `observable(datum) <= bound`.
18528#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18529pub struct LessEqBound;
18530impl bound_constraint_sealed::BoundShapeSealed for LessEqBound {}
18531impl BoundShape for LessEqBound {
18532    const IRI: &'static str = "https://uor.foundation/type/LessEqBound";
18533}
18534
18535/// Predicate form: `observable(datum) >= bound`.
18536#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18537pub struct GreaterEqBound;
18538impl bound_constraint_sealed::BoundShapeSealed for GreaterEqBound {}
18539impl BoundShape for GreaterEqBound {
18540    const IRI: &'static str = "https://uor.foundation/type/GreaterEqBound";
18541}
18542
18543/// Predicate form: `lo <= observable(datum) <= hi`.
18544#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18545pub struct RangeContainBound;
18546impl bound_constraint_sealed::BoundShapeSealed for RangeContainBound {}
18547impl BoundShape for RangeContainBound {
18548    const IRI: &'static str = "https://uor.foundation/type/RangeContainBound";
18549}
18550
18551/// Predicate form: `observable(datum) ≡ residue (mod modulus)`.
18552#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18553pub struct ResidueClassBound;
18554impl bound_constraint_sealed::BoundShapeSealed for ResidueClassBound {}
18555impl BoundShape for ResidueClassBound {
18556    const IRI: &'static str = "https://uor.foundation/type/ResidueClassBound";
18557}
18558
18559/// Predicate form: `observable(datum) == offset + affine combination`.
18560#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18561pub struct AffineEqualBound;
18562impl bound_constraint_sealed::BoundShapeSealed for AffineEqualBound {}
18563impl BoundShape for AffineEqualBound {
18564    const IRI: &'static str = "https://uor.foundation/type/AffineEqualBound";
18565}
18566
18567/// Parameter value type for `BoundConstraint` arguments.
18568/// Sealed enum over the closed set of primitive kinds the bound-shape
18569/// catalogue requires. No heap, no `String`.
18570#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18571pub enum BoundArgValue {
18572    /// Unsigned 64-bit integer.
18573    U64(u64),
18574    /// Signed 64-bit integer.
18575    I64(i64),
18576    /// Fixed 32-byte content-addressed value.
18577    Bytes32([u8; 32]),
18578}
18579
18580/// Fixed-size arguments carrier for a `BoundConstraint`.
18581/// Holds up to eight `(name, value)` pairs inline. The closed
18582/// bound-shape catalogue requires at most three parameters per kind;
18583/// the extra slots are reserved for future kind additions without
18584/// changing the carrier layout.
18585#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18586pub struct BoundArguments {
18587    entries: [Option<BoundArgEntry>; 8],
18588}
18589
18590/// A single named parameter in a `BoundArguments` table.
18591#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18592pub struct BoundArgEntry {
18593    /// Parameter name (a `&'static str` intentional over heap-owned).
18594    pub name: &'static str,
18595    /// Parameter value.
18596    pub value: BoundArgValue,
18597}
18598
18599impl BoundArguments {
18600    /// Construct an empty argument table.
18601    #[inline]
18602    #[must_use]
18603    pub const fn empty() -> Self {
18604        Self { entries: [None; 8] }
18605    }
18606
18607    /// Construct a table with a single `(name, value)` pair.
18608    #[inline]
18609    #[must_use]
18610    pub const fn single(name: &'static str, value: BoundArgValue) -> Self {
18611        let mut entries = [None; 8];
18612        entries[0] = Some(BoundArgEntry { name, value });
18613        Self { entries }
18614    }
18615
18616    /// Construct a table with two `(name, value)` pairs.
18617    #[inline]
18618    #[must_use]
18619    pub const fn pair(
18620        first: (&'static str, BoundArgValue),
18621        second: (&'static str, BoundArgValue),
18622    ) -> Self {
18623        let mut entries = [None; 8];
18624        entries[0] = Some(BoundArgEntry {
18625            name: first.0,
18626            value: first.1,
18627        });
18628        entries[1] = Some(BoundArgEntry {
18629            name: second.0,
18630            value: second.1,
18631        });
18632        Self { entries }
18633    }
18634
18635    /// Access the stored entries.
18636    #[inline]
18637    #[must_use]
18638    pub const fn entries(&self) -> &[Option<BoundArgEntry>; 8] {
18639        &self.entries
18640    }
18641}
18642
18643/// Parametric constraint carrier (v0.2.2 Phase D).
18644/// Generic over `O: Observable` and `B: BoundShape`. The seven
18645/// legacy constraint kinds are preserved as type aliases over this
18646/// carrier; see `ResidueConstraint`, `HammingConstraint`, etc. below.
18647#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18648pub struct BoundConstraint<O: Observable, B: BoundShape> {
18649    observable: O,
18650    bound: B,
18651    args: BoundArguments,
18652    _sealed: (),
18653}
18654
18655impl<O: Observable, B: BoundShape> BoundConstraint<O, B> {
18656    /// Crate-internal constructor. Downstream obtains values through
18657    /// the per-type-alias `pub const fn new` constructors.
18658    #[inline]
18659    #[must_use]
18660    pub(crate) const fn from_parts(observable: O, bound: B, args: BoundArguments) -> Self {
18661        Self {
18662            observable,
18663            bound,
18664            args,
18665            _sealed: (),
18666        }
18667    }
18668
18669    /// Access the bound observable.
18670    #[inline]
18671    #[must_use]
18672    pub const fn observable(&self) -> &O {
18673        &self.observable
18674    }
18675
18676    /// Access the bound shape.
18677    #[inline]
18678    #[must_use]
18679    pub const fn bound(&self) -> &B {
18680        &self.bound
18681    }
18682
18683    /// Access the bound arguments.
18684    #[inline]
18685    #[must_use]
18686    pub const fn args(&self) -> &BoundArguments {
18687        &self.args
18688    }
18689}
18690
18691/// Parametric conjunction of `BoundConstraint` kinds (v0.2.2 Phase D).
18692/// Replaces the v0.2.1 `CompositeConstraint` enumeration; the legacy
18693/// name survives as the type alias `CompositeConstraint<N>` below.
18694#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18695pub struct Conjunction<const N: usize> {
18696    len: usize,
18697    _sealed: (),
18698}
18699
18700impl<const N: usize> Conjunction<N> {
18701    /// Construct a new Conjunction with `len` conjuncts.
18702    #[inline]
18703    #[must_use]
18704    pub const fn new(len: usize) -> Self {
18705        Self { len, _sealed: () }
18706    }
18707
18708    /// The number of conjuncts in this Conjunction.
18709    #[inline]
18710    #[must_use]
18711    pub const fn len(&self) -> usize {
18712        self.len
18713    }
18714
18715    /// Whether the Conjunction is empty.
18716    #[inline]
18717    #[must_use]
18718    pub const fn is_empty(&self) -> bool {
18719        self.len == 0
18720    }
18721}
18722
18723/// v0.2.1 legacy type alias: a `BoundConstraint` kind asserting
18724/// residue-class membership (`value mod m == r`).
18725pub type ResidueConstraint = BoundConstraint<ValueModObservable, ResidueClassBound>;
18726
18727impl ResidueConstraint {
18728    /// Construct a residue constraint with the given modulus and residue.
18729    #[inline]
18730    #[must_use]
18731    pub const fn new(modulus: u64, residue: u64) -> Self {
18732        let args = BoundArguments::pair(
18733            ("modulus", BoundArgValue::U64(modulus)),
18734            ("residue", BoundArgValue::U64(residue)),
18735        );
18736        BoundConstraint::from_parts(ValueModObservable, ResidueClassBound, args)
18737    }
18738}
18739
18740/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18741/// Hamming weight of the Datum (`weight <= bound`).
18742pub type HammingConstraint = BoundConstraint<HammingMetric, LessEqBound>;
18743
18744impl HammingConstraint {
18745    /// Construct a Hamming constraint with the given upper bound.
18746    #[inline]
18747    #[must_use]
18748    pub const fn new(bound: u64) -> Self {
18749        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
18750        BoundConstraint::from_parts(HammingMetric, LessEqBound, args)
18751    }
18752}
18753
18754/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18755/// derivation depth of the Datum.
18756pub type DepthConstraint = BoundConstraint<DerivationDepthObservable, LessEqBound>;
18757
18758impl DepthConstraint {
18759    /// Construct a depth constraint with min and max depths.
18760    #[inline]
18761    #[must_use]
18762    pub const fn new(min_depth: u64, max_depth: u64) -> Self {
18763        let args = BoundArguments::pair(
18764            ("min_depth", BoundArgValue::U64(min_depth)),
18765            ("max_depth", BoundArgValue::U64(max_depth)),
18766        );
18767        BoundConstraint::from_parts(DerivationDepthObservable, LessEqBound, args)
18768    }
18769}
18770
18771/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18772/// carry depth of the Datum in the W₂ tower.
18773pub type CarryConstraint = BoundConstraint<CarryDepthObservable, LessEqBound>;
18774
18775impl CarryConstraint {
18776    /// Construct a carry constraint with the given upper bound.
18777    #[inline]
18778    #[must_use]
18779    pub const fn new(bound: u64) -> Self {
18780        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
18781        BoundConstraint::from_parts(CarryDepthObservable, LessEqBound, args)
18782    }
18783}
18784
18785/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning a
18786/// single site coordinate.
18787pub type SiteConstraint = BoundConstraint<FreeRankObservable, LessEqBound>;
18788
18789impl SiteConstraint {
18790    /// Construct a site constraint with the given site index.
18791    #[inline]
18792    #[must_use]
18793    pub const fn new(site_index: u64) -> Self {
18794        let args = BoundArguments::single("site_index", BoundArgValue::U64(site_index));
18795        BoundConstraint::from_parts(FreeRankObservable, LessEqBound, args)
18796    }
18797}
18798
18799/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning an
18800/// affine relationship on the Datum's value projection.
18801pub type AffineConstraint = BoundConstraint<ValueModObservable, AffineEqualBound>;
18802
18803impl AffineConstraint {
18804    /// Construct an affine constraint with the given offset.
18805    #[inline]
18806    #[must_use]
18807    pub const fn new(offset: u64) -> Self {
18808        let args = BoundArguments::single("offset", BoundArgValue::U64(offset));
18809        BoundConstraint::from_parts(ValueModObservable, AffineEqualBound, args)
18810    }
18811}
18812
18813/// v0.2.1 legacy type alias: a `Conjunction` over `N` BoundConstraint
18814/// kinds (`CompositeConstraint<3>` = 3-way conjunction).
18815pub type CompositeConstraint<const N: usize> = Conjunction<N>;
18816
18817/// v0.2.2 Phase E: sealed query handle.
18818#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18819pub struct Query {
18820    address: ContentAddress,
18821    _sealed: (),
18822}
18823
18824impl Query {
18825    /// Returns the content-hashed query address.
18826    #[inline]
18827    #[must_use]
18828    pub const fn address(&self) -> ContentAddress {
18829        self.address
18830    }
18831
18832    /// Crate-internal constructor.
18833    #[inline]
18834    #[must_use]
18835    #[allow(dead_code)]
18836    pub(crate) const fn new(address: ContentAddress) -> Self {
18837        Self {
18838            address,
18839            _sealed: (),
18840        }
18841    }
18842}
18843
18844/// v0.2.2 Phase E: typed query coordinate parametric over WittLevel.
18845#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18846pub struct Coordinate<L> {
18847    stratum: u64,
18848    spectrum: u64,
18849    address: u64,
18850    _level: PhantomData<L>,
18851    _sealed: (),
18852}
18853
18854impl<L> Coordinate<L> {
18855    /// Returns the stratum coordinate.
18856    #[inline]
18857    #[must_use]
18858    pub const fn stratum(&self) -> u64 {
18859        self.stratum
18860    }
18861
18862    /// Returns the spectrum coordinate.
18863    #[inline]
18864    #[must_use]
18865    pub const fn spectrum(&self) -> u64 {
18866        self.spectrum
18867    }
18868
18869    /// Returns the address coordinate.
18870    #[inline]
18871    #[must_use]
18872    pub const fn address(&self) -> u64 {
18873        self.address
18874    }
18875
18876    /// Crate-internal constructor.
18877    #[inline]
18878    #[must_use]
18879    #[allow(dead_code)]
18880    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
18881        Self {
18882            stratum,
18883            spectrum,
18884            address,
18885            _level: PhantomData,
18886            _sealed: (),
18887        }
18888    }
18889}
18890
18891/// v0.2.2 Phase E: sealed binding query handle.
18892#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18893pub struct BindingQuery {
18894    address: ContentAddress,
18895    _sealed: (),
18896}
18897
18898impl BindingQuery {
18899    /// Returns the content-hashed binding query address.
18900    #[inline]
18901    #[must_use]
18902    pub const fn address(&self) -> ContentAddress {
18903        self.address
18904    }
18905
18906    /// Crate-internal constructor.
18907    #[inline]
18908    #[must_use]
18909    #[allow(dead_code)]
18910    pub(crate) const fn new(address: ContentAddress) -> Self {
18911        Self {
18912            address,
18913            _sealed: (),
18914        }
18915    }
18916}
18917
18918/// v0.2.2 Phase E: sealed Partition handle over the bridge:partition
18919/// component classification produced during grounding.
18920#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18921pub struct Partition {
18922    component: PartitionComponent,
18923    _sealed: (),
18924}
18925
18926impl Partition {
18927    /// Returns the component classification.
18928    #[inline]
18929    #[must_use]
18930    pub const fn component(&self) -> PartitionComponent {
18931        self.component
18932    }
18933
18934    /// Crate-internal constructor.
18935    #[inline]
18936    #[must_use]
18937    #[allow(dead_code)]
18938    pub(crate) const fn new(component: PartitionComponent) -> Self {
18939        Self {
18940            component,
18941            _sealed: (),
18942        }
18943    }
18944}
18945
18946/// v0.2.2 Phase E: a single event in a derivation Trace.
18947/// Fixed-size event; content-addressed so Trace replays are stable
18948/// across builds. The verifier in `uor-foundation-verify` (Phase H)
18949/// reconstructs the witness chain by walking a `Trace` iterator.
18950#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18951pub struct TraceEvent {
18952    /// Step index in the derivation.
18953    step_index: u32,
18954    /// Primitive op applied at this step.
18955    op: PrimitiveOp,
18956    /// Content-hashed target address the op produced.
18957    target: ContentAddress,
18958    /// Sealing marker.
18959    _sealed: (),
18960}
18961
18962impl TraceEvent {
18963    /// Returns the step index.
18964    #[inline]
18965    #[must_use]
18966    pub const fn step_index(&self) -> u32 {
18967        self.step_index
18968    }
18969
18970    /// Returns the primitive op applied at this step.
18971    #[inline]
18972    #[must_use]
18973    pub const fn op(&self) -> PrimitiveOp {
18974        self.op
18975    }
18976
18977    /// Returns the content-hashed target address.
18978    #[inline]
18979    #[must_use]
18980    pub const fn target(&self) -> ContentAddress {
18981        self.target
18982    }
18983
18984    /// Crate-internal constructor.
18985    #[inline]
18986    #[must_use]
18987    #[allow(dead_code)]
18988    pub(crate) const fn new(step_index: u32, op: PrimitiveOp, target: ContentAddress) -> Self {
18989        Self {
18990            step_index,
18991            op,
18992            target,
18993            _sealed: (),
18994        }
18995    }
18996}
18997
18998/// Fixed-capacity derivation trace. Holds up to `TR_MAX` events inline;
18999/// no heap. Produced by `Derivation::replay()` and consumed by
19000/// `uor-foundation-verify`. `TR_MAX` is the const-generic that carries
19001/// the application's selected `<MyBounds as HostBounds>::TRACE_MAX_EVENTS`;
19002/// the default const-generic resolves to `DefaultHostBounds`'s 256.
19003/// Carries `witt_level_bits` and `content_fingerprint` so `verify_trace`
19004/// can reconstruct the source `GroundingCertificate` via structural-
19005/// validation + fingerprint passthrough (no hash recomputation).
19006#[derive(Debug, Clone, Copy)]
19007pub struct Trace<const TR_MAX: usize = 256> {
19008    events: [Option<TraceEvent>; TR_MAX],
19009    len: u16,
19010    /// Witt level the source grounding was minted at, packed
19011    /// by `Derivation::replay` from the parent `Grounded::witt_level_bits`.
19012    /// `verify_trace` reads this back to populate the certificate.
19013    witt_level_bits: u16,
19014    /// Parametric content fingerprint of the source unit's full state,
19015    /// computed at grounding time by the consumer-supplied `Hasher` and
19016    /// packed in by `Derivation::replay`. `verify_trace` passes it through
19017    /// unchanged. The fingerprint's `FP_MAX` follows the application's
19018    /// selected `<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES`; this
19019    /// field uses the default-bound `ContentFingerprint`.
19020    content_fingerprint: ContentFingerprint,
19021    _sealed: (),
19022}
19023
19024impl<const TR_MAX: usize> Trace<TR_MAX> {
19025    /// An empty Trace.
19026    #[inline]
19027    #[must_use]
19028    pub const fn empty() -> Self {
19029        Self {
19030            events: [None; TR_MAX],
19031            len: 0,
19032            witt_level_bits: 0,
19033            content_fingerprint: ContentFingerprint::zero(),
19034            _sealed: (),
19035        }
19036    }
19037
19038    /// Crate-internal ctor for `Derivation::replay()` only.
19039    /// Bypasses validation because `replay()` constructs events from
19040    /// foundation-guaranteed-valid state (monotonic, contiguous, non-zero
19041    /// seed). No public path reaches this constructor; downstream uses the
19042    /// validating `try_from_events` instead.
19043    #[inline]
19044    #[must_use]
19045    #[allow(dead_code)]
19046    pub(crate) const fn from_replay_events_const(
19047        events: [Option<TraceEvent>; TR_MAX],
19048        len: u16,
19049        witt_level_bits: u16,
19050        content_fingerprint: ContentFingerprint,
19051    ) -> Self {
19052        Self {
19053            events,
19054            len,
19055            witt_level_bits,
19056            content_fingerprint,
19057            _sealed: (),
19058        }
19059    }
19060
19061    /// Number of events recorded.
19062    #[inline]
19063    #[must_use]
19064    pub const fn len(&self) -> u16 {
19065        self.len
19066    }
19067
19068    /// Whether the Trace is empty.
19069    #[inline]
19070    #[must_use]
19071    pub const fn is_empty(&self) -> bool {
19072        self.len == 0
19073    }
19074
19075    /// Access the event at the given index, or `None` if out of range.
19076    #[inline]
19077    #[must_use]
19078    pub fn event(&self, index: usize) -> Option<&TraceEvent> {
19079        self.events.get(index).and_then(|e| e.as_ref())
19080    }
19081
19082    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
19083    /// Carried through replay so `verify_trace` can populate the certificate.
19084    #[inline]
19085    #[must_use]
19086    pub const fn witt_level_bits(&self) -> u16 {
19087        self.witt_level_bits
19088    }
19089
19090    /// v0.2.2 T5: returns the parametric content fingerprint of the source
19091    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
19092    /// `verify_trace` passes this through unchanged into the re-derived
19093    /// certificate, upholding the round-trip property.
19094    #[inline]
19095    #[must_use]
19096    pub const fn content_fingerprint(&self) -> ContentFingerprint {
19097        self.content_fingerprint
19098    }
19099
19100    /// Validating constructor. Checks every invariant the verify path
19101    /// relies on: events are contiguous from index 0, no event has a zero
19102    /// target, and the slice fits within `TR_MAX` events.
19103    /// # Errors
19104    /// - `ReplayError::EmptyTrace` if `events.is_empty()`.
19105    /// - `ReplayError::CapacityExceeded { declared, provided }` if the
19106    ///   slice exceeds `TR_MAX`.
19107    /// - `ReplayError::OutOfOrderEvent { index }` if the event at `index`
19108    ///   has a `step_index` not equal to `index` (strict contiguity).
19109    /// - `ReplayError::ZeroTarget { index }` if any event carries a zero
19110    ///   `ContentAddress` target.
19111    pub fn try_from_events(
19112        events: &[TraceEvent],
19113        witt_level_bits: u16,
19114        content_fingerprint: ContentFingerprint,
19115    ) -> Result<Self, ReplayError> {
19116        if events.is_empty() {
19117            return Err(ReplayError::EmptyTrace);
19118        }
19119        if events.len() > TR_MAX {
19120            return Err(ReplayError::CapacityExceeded {
19121                declared: TR_MAX as u16,
19122                provided: events.len() as u32,
19123            });
19124        }
19125        let mut i = 0usize;
19126        while i < events.len() {
19127            let e = &events[i];
19128            if e.step_index() as usize != i {
19129                return Err(ReplayError::OutOfOrderEvent { index: i });
19130            }
19131            if e.target().is_zero() {
19132                return Err(ReplayError::ZeroTarget { index: i });
19133            }
19134            i += 1;
19135        }
19136        let mut arr = [None; TR_MAX];
19137        let mut j = 0usize;
19138        while j < events.len() {
19139            arr[j] = Some(events[j]);
19140            j += 1;
19141        }
19142        Ok(Self {
19143            events: arr,
19144            len: events.len() as u16,
19145            witt_level_bits,
19146            content_fingerprint,
19147            _sealed: (),
19148        })
19149    }
19150}
19151
19152impl<const TR_MAX: usize> Default for Trace<TR_MAX> {
19153    #[inline]
19154    fn default() -> Self {
19155        Self::empty()
19156    }
19157}
19158
19159/// v0.2.2 Phase E / T2.6: `Derivation::replay()` produces a content-addressed
19160/// Trace the verifier can re-walk without invoking the deciders. The trace
19161/// length matches the derivation's `step_count()`, and each event's
19162/// `step_index` reflects its position in the derivation.
19163impl Derivation {
19164    /// Replay this derivation as a fixed-size `Trace<TR_MAX>` whose length matches
19165    /// `self.step_count()` (capped at the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19166    /// Callers either annotate the binding (`let trace: Trace = ...;` picks
19167    /// `DefaultHostBounds`'s 256) or use turbofish (`derivation.replay::<1024>()`).
19168    /// # Example
19169    /// ```no_run
19170    /// use uor_foundation::enforcement::{
19171    ///     replay, CompileUnitBuilder, ConstrainedTypeInput, Grounded, Term, Trace,
19172    /// };
19173    /// use uor_foundation::pipeline::run;
19174    /// use uor_foundation::{VerificationDomain, WittLevel};
19175    /// # use uor_foundation::enforcement::Hasher;
19176    /// # struct H; impl Hasher for H {
19177    /// #     const OUTPUT_BYTES: usize = 16;
19178    /// #     fn initial() -> Self { Self }
19179    /// #     fn fold_byte(self, _: u8) -> Self { self }
19180    /// #     fn finalize(self) -> [u8; 32] { [0; 32] } }
19181    /// static TERMS: &[Term] = &[uor_foundation::pipeline::literal_u64(7, WittLevel::W8)];
19182    /// static DOMS: &[VerificationDomain] = &[VerificationDomain::Enumerative];
19183    /// let unit = CompileUnitBuilder::new()
19184    ///     .root_term(TERMS).witt_level_ceiling(WittLevel::W32)
19185    ///     .thermodynamic_budget(1024).target_domains(DOMS)
19186    ///     .result_type::<ConstrainedTypeInput>()
19187    ///     .validate().expect("unit well-formed");
19188    /// let grounded: Grounded<ConstrainedTypeInput> =
19189    ///     run::<ConstrainedTypeInput, _, H>(unit).expect("grounds");
19190    /// // Replay → round-trip verification. The trace's event-count
19191    /// // capacity comes from the application's `HostBounds`; here the
19192    /// // type-annotated binding inherits `DefaultHostBounds`'s 256.
19193    /// let trace: Trace = grounded.derivation().replay();
19194    /// let recert = replay::certify_from_trace(&trace).expect("valid trace");
19195    /// assert_eq!(recert.certificate().content_fingerprint(),
19196    ///            grounded.content_fingerprint());
19197    /// ```
19198    #[inline]
19199    #[must_use]
19200    pub fn replay<const TR_MAX: usize>(&self) -> Trace<TR_MAX> {
19201        let steps = self.step_count() as usize;
19202        let len = if steps > TR_MAX { TR_MAX } else { steps };
19203        let mut events = [None; TR_MAX];
19204        // Seed targets from the leading 8 bytes of the source
19205        // `content_fingerprint` (substrate-computed). Combined with `| 1` so
19206        // the first event's target is guaranteed nonzero even when the
19207        // leading bytes are all zero, and XOR with `(i + 1)` keeps the
19208        // sequence non-degenerate.
19209        let fp = self.content_fingerprint.as_bytes();
19210        let seed =
19211            u64::from_be_bytes([fp[0], fp[1], fp[2], fp[3], fp[4], fp[5], fp[6], fp[7]]) as u128;
19212        let nonzero_seed = seed | 1u128;
19213        let mut i = 0usize;
19214        while i < len {
19215            let target_raw = nonzero_seed ^ ((i as u128) + 1u128);
19216            events[i] = Some(TraceEvent::new(
19217                i as u32,
19218                crate::PrimitiveOp::Add,
19219                ContentAddress::from_u128(target_raw),
19220            ));
19221            i += 1;
19222        }
19223        // Pack the source `witt_level_bits` and `content_fingerprint`
19224        // into the Trace so `verify_trace` can reproduce the source certificate
19225        // via passthrough. The fingerprint was computed at grounding time by the
19226        // consumer-supplied Hasher and stored on the parent Grounded; the
19227        // Derivation accessor read it through.
19228        Trace::from_replay_events_const(
19229            events,
19230            len as u16,
19231            self.witt_level_bits,
19232            self.content_fingerprint,
19233        )
19234    }
19235}
19236
19237/// v0.2.2 T5: errors emitted by the trace-replay re-derivation path.
19238#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19239#[non_exhaustive]
19240pub enum ReplayError {
19241    /// The trace was empty; nothing to replay.
19242    EmptyTrace,
19243    /// Event at `index` has a non-monotonic step_index.
19244    OutOfOrderEvent {
19245        /// The event index that was out of order.
19246        index: usize,
19247    },
19248    /// Event at `index` carries a zero ContentAddress (forbidden in well-formed traces).
19249    ZeroTarget {
19250        /// The event index that carried a zero target.
19251        index: usize,
19252    },
19253    /// v0.2.2 T5.8: event step indices do not form a contiguous sequence
19254    /// `[0, 1, ..., len-1]`. Replaces the misleadingly-named v0.2.1
19255    /// `LengthMismatch` variant. The trace has the right number of
19256    /// events, but their step indices skip values (e.g., `[0, 2, 5]`
19257    /// with `len = 3`).
19258    NonContiguousSteps {
19259        /// The trace's declared length (number of events).
19260        declared: u16,
19261        /// The largest step_index observed in the event sequence.
19262        /// Always strictly greater than `declared - 1` when this
19263        /// variant fires.
19264        last_step: u32,
19265    },
19266    /// A caller attempted to construct a `Trace<TR_MAX>` whose event count
19267    /// exceeds `TR_MAX` (the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19268    /// Distinct from `NonContiguousSteps` because the recovery is different
19269    /// (truncate vs. close gaps). Returned by `Trace::try_from_events`,
19270    /// never by `verify_trace` (the verifier reads from an existing `Trace`
19271    /// whose capacity is already enforced by the type's storage).
19272    CapacityExceeded {
19273        /// The trace's hard capacity (`TR_MAX`).
19274        declared: u16,
19275        /// The actual event count the caller attempted to pack in.
19276        provided: u32,
19277    },
19278}
19279
19280impl core::fmt::Display for ReplayError {
19281    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19282        match self {
19283            Self::EmptyTrace => f.write_str("trace was empty; nothing to replay"),
19284            Self::OutOfOrderEvent { index } => write!(
19285                f,
19286                "event at index {index} has out-of-order step index",
19287            ),
19288            Self::ZeroTarget { index } => write!(
19289                f,
19290                "event at index {index} has a zero ContentAddress target",
19291            ),
19292            Self::NonContiguousSteps { declared, last_step } => write!(
19293                f,
19294                "trace declares {declared} events but step indices skip values \
19295                 (last step {last_step})",
19296            ),
19297            Self::CapacityExceeded { declared, provided } => write!(
19298                f,
19299                "trace capacity exceeded: tried to pack {provided} events into a buffer of {declared}",
19300            ),
19301        }
19302    }
19303}
19304
19305impl core::error::Error for ReplayError {}
19306
19307/// v0.2.2 T5: trace-replay re-derivation module.
19308/// The foundation owns the certificate-construction boundary; the
19309/// `uor-foundation-verify` crate is a thin facade that delegates to
19310/// `replay::certify_from_trace`. This preserves sealing discipline:
19311/// `Certified::new` stays `pub(crate)` and no external crate can mint a
19312/// certificate.
19313pub mod replay {
19314    use super::{Certified, GroundingCertificate, ReplayError, Trace};
19315
19316    /// Re-derive the `Certified<GroundingCertificate>` that the foundation
19317    /// grounding path produced for the source unit.
19318    /// Validates the trace's structural invariants (monotonic, contiguous
19319    /// step indices; no zero targets; no None slots in the populated
19320    /// prefix) and re-packages the trace's stored `ContentFingerprint` and
19321    /// `witt_level_bits` into a fresh certificate. The verifier does NOT
19322    /// invoke a hash function: the fingerprint is *data carried by the
19323    /// Trace*, computed at mint time by the consumer-supplied `Hasher` and
19324    /// passed through unchanged.
19325    /// # Round-trip property
19326    /// For every `Grounded<T>` produced by `pipeline::run::<T, _, H>` with
19327    /// a conforming substrate `H: Hasher`:
19328    /// ```text
19329    /// verify_trace(&grounded.derivation().replay()).certificate()
19330    ///     == grounded.certificate()
19331    /// ```
19332    /// holds bit-identically. The contract is orthogonal to the substrate
19333    /// hasher choice and to the chosen `OUTPUT_BYTES` width.
19334    /// # Errors
19335    /// Returns:
19336    /// - `ReplayError::EmptyTrace` if `trace.is_empty()`.
19337    /// - `ReplayError::OutOfOrderEvent { index }` if step indices are not
19338    ///   strictly monotonic at position `index`.
19339    /// - `ReplayError::ZeroTarget { index }` if any event carries
19340    ///   `ContentAddress::zero()`.
19341    /// - `ReplayError::NonContiguousSteps { declared, last_step }` if
19342    ///   the event step indices skip values.
19343    pub fn certify_from_trace<const TR_MAX: usize>(
19344        trace: &Trace<TR_MAX>,
19345    ) -> Result<Certified<GroundingCertificate>, ReplayError> {
19346        let len = trace.len() as usize;
19347        if len == 0 {
19348            return Err(ReplayError::EmptyTrace);
19349        }
19350        // Structural validation: monotonic step indices, contiguous from 0,
19351        // no zero targets, no None slots in the populated prefix.
19352        let mut last_step: i64 = -1;
19353        let mut max_step_index: u32 = 0;
19354        let mut i = 0usize;
19355        while i < len {
19356            let event = match trace.event(i) {
19357                Some(e) => e,
19358                None => return Err(ReplayError::OutOfOrderEvent { index: i }),
19359            };
19360            let step_index = event.step_index();
19361            if (step_index as i64) <= last_step {
19362                return Err(ReplayError::OutOfOrderEvent { index: i });
19363            }
19364            if event.target().is_zero() {
19365                return Err(ReplayError::ZeroTarget { index: i });
19366            }
19367            if step_index > max_step_index {
19368                max_step_index = step_index;
19369            }
19370            last_step = step_index as i64;
19371            i += 1;
19372        }
19373        if (max_step_index as u16).saturating_add(1) != trace.len() {
19374            return Err(ReplayError::NonContiguousSteps {
19375                declared: trace.len(),
19376                last_step: max_step_index,
19377            });
19378        }
19379        // v0.2.2 T5: fingerprint passthrough. The trace was minted by the
19380        // foundation pipeline with a `ContentFingerprint` already computed by
19381        // the consumer-supplied `Hasher`. The verifier does not invoke any
19382        // hash function; it copies the fingerprint through unchanged. The
19383        // round-trip property holds by construction. v0.2.2 T6.5: the
19384        // FingerprintMissing variant is removed because under T6.3 / T6.10,
19385        // no public path can produce a Trace with a zero fingerprint.
19386        Ok(Certified::new(
19387            GroundingCertificate::with_level_and_fingerprint_const(
19388                trace.witt_level_bits(),
19389                trace.content_fingerprint(),
19390            ),
19391        ))
19392    }
19393}
19394
19395/// v0.2.2 Phase E: sealed builder for an InteractionDeclaration.
19396/// Validates the peer protocol, convergence predicate, and
19397/// commutator state class required by `conformance:InteractionShape`.
19398/// Phase F wires the full `InteractionDriver` on top of this builder.
19399#[derive(Debug, Clone, Copy, Default)]
19400pub struct InteractionDeclarationBuilder {
19401    peer_protocol: Option<u128>,
19402    convergence_predicate: Option<u128>,
19403    commutator_state_class: Option<u128>,
19404}
19405
19406impl InteractionDeclarationBuilder {
19407    /// Construct a new builder.
19408    #[inline]
19409    #[must_use]
19410    pub const fn new() -> Self {
19411        Self {
19412            peer_protocol: None,
19413            convergence_predicate: None,
19414            commutator_state_class: None,
19415        }
19416    }
19417
19418    /// Set the peer protocol content address.
19419    #[inline]
19420    #[must_use]
19421    pub const fn peer_protocol(mut self, address: u128) -> Self {
19422        self.peer_protocol = Some(address);
19423        self
19424    }
19425
19426    /// Set the convergence predicate content address.
19427    #[inline]
19428    #[must_use]
19429    pub const fn convergence_predicate(mut self, address: u128) -> Self {
19430        self.convergence_predicate = Some(address);
19431        self
19432    }
19433
19434    /// Set the commutator state class content address.
19435    #[inline]
19436    #[must_use]
19437    pub const fn commutator_state_class(mut self, address: u128) -> Self {
19438        self.commutator_state_class = Some(address);
19439        self
19440    }
19441
19442    /// Phase E.6: validate against `conformance:InteractionShape`.
19443    /// # Errors
19444    /// Returns `ShapeViolation` if any of the three required fields is missing.
19445    pub fn validate(&self) -> Result<Validated<InteractionShape>, ShapeViolation> {
19446        self.validate_common().map(|_| {
19447            Validated::new(InteractionShape {
19448                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19449            })
19450        })
19451    }
19452
19453    /// Phase E.6 + C.1: const-fn companion.
19454    /// # Errors
19455    /// Returns `ShapeViolation` if any required field is missing.
19456    pub const fn validate_const(
19457        &self,
19458    ) -> Result<Validated<InteractionShape, CompileTime>, ShapeViolation> {
19459        if self.peer_protocol.is_none() {
19460            return Err(ShapeViolation {
19461                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19462                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19463                property_iri: "https://uor.foundation/interaction/peerProtocol",
19464                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19465                min_count: 1,
19466                max_count: 1,
19467                kind: ViolationKind::Missing,
19468            });
19469        }
19470        if self.convergence_predicate.is_none() {
19471            return Err(ShapeViolation {
19472                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19473                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19474                property_iri: "https://uor.foundation/interaction/convergencePredicate",
19475                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19476                min_count: 1,
19477                max_count: 1,
19478                kind: ViolationKind::Missing,
19479            });
19480        }
19481        if self.commutator_state_class.is_none() {
19482            return Err(ShapeViolation {
19483                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19484                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19485                property_iri: "https://uor.foundation/interaction/commutatorStateClass",
19486                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19487                min_count: 1,
19488                max_count: 1,
19489                kind: ViolationKind::Missing,
19490            });
19491        }
19492        Ok(Validated::new(InteractionShape {
19493            shape_iri: "https://uor.foundation/conformance/InteractionShape",
19494        }))
19495    }
19496
19497    fn validate_common(&self) -> Result<(), ShapeViolation> {
19498        self.validate_const().map(|_| ())
19499    }
19500}
19501
19502/// Phase E.6: validated InteractionDeclaration per `conformance:InteractionShape`.
19503#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19504pub struct InteractionShape {
19505    /// Shape IRI this declaration was validated against.
19506    pub shape_iri: &'static str,
19507}
19508
19509/// Phase E.5 (target §7.4): observability subscribe API.
19510/// When the `observability` feature is enabled, downstream may call
19511/// `subscribe_trace_events` with a handler closure that receives each
19512/// `TraceEvent` as the pipeline emits it. When the feature is off, this
19513/// function is entirely absent from the public API.
19514#[cfg(feature = "observability")]
19515pub fn subscribe_trace_events<F>(handler: F) -> ObservabilitySubscription<F>
19516where
19517    F: FnMut(&TraceEvent),
19518{
19519    ObservabilitySubscription {
19520        handler,
19521        _sealed: (),
19522    }
19523}
19524
19525#[cfg(feature = "observability")]
19526/// Phase E.5: sealed subscription handle returned by `subscribe_trace_events`.
19527#[cfg(feature = "observability")]
19528pub struct ObservabilitySubscription<F: FnMut(&TraceEvent)> {
19529    handler: F,
19530    _sealed: (),
19531}
19532
19533#[cfg(feature = "observability")]
19534impl<F: FnMut(&TraceEvent)> ObservabilitySubscription<F> {
19535    /// Dispatch a TraceEvent through the subscribed handler.
19536    pub fn emit(&mut self, event: &TraceEvent) {
19537        (self.handler)(event);
19538    }
19539}
19540
19541/// Phase F.2 (target §4.7): closed enumeration of the six constraint kinds.
19542/// `type-decl` bodies enumerate exactly these six kinds per `uor_term.ebnf`'s
19543/// `constraint-decl` production. `CompositeConstraint` — the implicit shape of
19544/// a multi-decl body — has no syntactic constructor and is therefore not a
19545/// variant of this enum.
19546#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19547#[non_exhaustive]
19548pub enum ConstraintKind {
19549    /// `type:ResidueConstraint` — value is congruent to `r (mod m)`.
19550    Residue,
19551    /// `type:CarryConstraint` — bounded carry depth.
19552    Carry,
19553    /// `type:DepthConstraint` — bounded derivation depth.
19554    Depth,
19555    /// `type:HammingConstraint` — bounded Hamming distance from a reference.
19556    Hamming,
19557    /// `type:SiteConstraint` — per-site cardinality or containment.
19558    Site,
19559    /// `type:AffineConstraint` — linear inequality over site values.
19560    Affine,
19561}
19562
19563/// Phase F.3 (target §4.7 carry): sealed per-ring-op carry profile.
19564#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19565pub struct CarryProfile {
19566    chain_length: u32,
19567    max_depth: u32,
19568    _sealed: (),
19569}
19570
19571impl CarryProfile {
19572    /// Length of the longest carry chain observed.
19573    #[inline]
19574    #[must_use]
19575    pub const fn chain_length(&self) -> u32 {
19576        self.chain_length
19577    }
19578
19579    /// Maximum carry depth across the op.
19580    #[inline]
19581    #[must_use]
19582    pub const fn max_depth(&self) -> u32 {
19583        self.max_depth
19584    }
19585
19586    /// Crate-internal constructor.
19587    #[inline]
19588    #[must_use]
19589    #[allow(dead_code)]
19590    pub(crate) const fn new(chain_length: u32, max_depth: u32) -> Self {
19591        Self {
19592            chain_length,
19593            max_depth,
19594            _sealed: (),
19595        }
19596    }
19597}
19598
19599/// Phase F.3 (target §4.7 carry): sealed carry-event witness — records the ring op
19600/// and two `Datum<L>` witt widths involved.
19601#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19602pub struct CarryEvent {
19603    left_bits: u16,
19604    right_bits: u16,
19605    _sealed: (),
19606}
19607
19608impl CarryEvent {
19609    /// Witt bit-width of the left operand.
19610    #[inline]
19611    #[must_use]
19612    pub const fn left_bits(&self) -> u16 {
19613        self.left_bits
19614    }
19615
19616    /// Witt bit-width of the right operand.
19617    #[inline]
19618    #[must_use]
19619    pub const fn right_bits(&self) -> u16 {
19620        self.right_bits
19621    }
19622
19623    /// Crate-internal constructor.
19624    #[inline]
19625    #[must_use]
19626    #[allow(dead_code)]
19627    pub(crate) const fn new(left_bits: u16, right_bits: u16) -> Self {
19628        Self {
19629            left_bits,
19630            right_bits,
19631            _sealed: (),
19632        }
19633    }
19634}
19635
19636/// Phase F.3 (target §4.7 convergence): sealed convergence-level witness at `L`.
19637#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19638pub struct ConvergenceLevel<L> {
19639    valuation: u32,
19640    _level: PhantomData<L>,
19641    _sealed: (),
19642}
19643
19644impl<L> ConvergenceLevel<L> {
19645    /// The v₂ valuation of the datum at this convergence level.
19646    #[inline]
19647    #[must_use]
19648    pub const fn valuation(&self) -> u32 {
19649        self.valuation
19650    }
19651
19652    /// Crate-internal constructor.
19653    #[inline]
19654    #[must_use]
19655    #[allow(dead_code)]
19656    pub(crate) const fn new(valuation: u32) -> Self {
19657        Self {
19658            valuation,
19659            _level: PhantomData,
19660            _sealed: (),
19661        }
19662    }
19663}
19664
19665/// Phase F.3 (target §4.7 division): sealed enum over the four normed division
19666/// algebras from Cayley-Dickson. No other admissible algebra exists (Hurwitz's theorem).
19667#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19668#[non_exhaustive]
19669pub enum DivisionAlgebraWitness {
19670    /// Real numbers ℝ (dimension 1).
19671    Real,
19672    /// Complex numbers ℂ (dimension 2).
19673    Complex,
19674    /// Quaternions ℍ (dimension 4, non-commutative).
19675    Quaternion,
19676    /// Octonions 𝕆 (dimension 8, non-commutative, non-associative).
19677    Octonion,
19678}
19679
19680/// Phase F.3 (target §4.7 monoidal): sealed monoidal-product witness.
19681#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19682pub struct MonoidalProduct<L, R> {
19683    _left: PhantomData<L>,
19684    _right: PhantomData<R>,
19685    _sealed: (),
19686}
19687
19688impl<L, R> MonoidalProduct<L, R> {
19689    /// Crate-internal constructor.
19690    #[inline]
19691    #[must_use]
19692    #[allow(dead_code)]
19693    pub(crate) const fn new() -> Self {
19694        Self {
19695            _left: PhantomData,
19696            _right: PhantomData,
19697            _sealed: (),
19698        }
19699    }
19700}
19701
19702/// Phase F.3 (target §4.7 monoidal): sealed monoidal-unit witness at `L`.
19703#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19704pub struct MonoidalUnit<L> {
19705    _level: PhantomData<L>,
19706    _sealed: (),
19707}
19708
19709impl<L> MonoidalUnit<L> {
19710    /// Crate-internal constructor.
19711    #[inline]
19712    #[must_use]
19713    #[allow(dead_code)]
19714    pub(crate) const fn new() -> Self {
19715        Self {
19716            _level: PhantomData,
19717            _sealed: (),
19718        }
19719    }
19720}
19721
19722/// Phase F.1 (target §4.7 operad): sealed operad-composition witness.
19723/// Every `type-app` form in the term grammar materializes a fresh `OperadComposition`
19724/// carrying the outer/inner type IRIs and composed site count, per `operad:` ontology.
19725#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19726pub struct OperadComposition {
19727    outer_type_iri: &'static str,
19728    inner_type_iri: &'static str,
19729    composed_site_count: u32,
19730    _sealed: (),
19731}
19732
19733impl OperadComposition {
19734    /// IRI of the outer `type:TypeDefinition`.
19735    #[inline]
19736    #[must_use]
19737    pub const fn outer_type_iri(&self) -> &'static str {
19738        self.outer_type_iri
19739    }
19740
19741    /// IRI of the inner `type:TypeDefinition`.
19742    #[inline]
19743    #[must_use]
19744    pub const fn inner_type_iri(&self) -> &'static str {
19745        self.inner_type_iri
19746    }
19747
19748    /// Site count of the composed type.
19749    #[inline]
19750    #[must_use]
19751    pub const fn composed_site_count(&self) -> u32 {
19752        self.composed_site_count
19753    }
19754
19755    /// Crate-internal constructor.
19756    #[inline]
19757    #[must_use]
19758    #[allow(dead_code)]
19759    pub(crate) const fn new(
19760        outer_type_iri: &'static str,
19761        inner_type_iri: &'static str,
19762        composed_site_count: u32,
19763    ) -> Self {
19764        Self {
19765            outer_type_iri,
19766            inner_type_iri,
19767            composed_site_count,
19768            _sealed: (),
19769        }
19770    }
19771}
19772
19773/// Phase F.3 (target §4.7 recursion): maximum depth of the recursion trace
19774/// witness. Bounded by the declared descent budget at builder-validate time;
19775/// the constant is a size-budget cap matching other foundation arenas.
19776/// Wiki ADR-037: alias of [`crate::HostBounds::RECURSION_TRACE_DEPTH_MAX`] via
19777/// [`crate::DefaultHostBounds`].
19778pub const RECURSION_TRACE_MAX_DEPTH: usize =
19779    <crate::DefaultHostBounds as crate::HostBounds>::RECURSION_TRACE_DEPTH_MAX;
19780
19781/// Phase F.3 (target §4.7 recursion): sealed recursion trace with fixed-capacity
19782/// descent-measure sequence.
19783#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19784pub struct RecursionTrace {
19785    depth: u32,
19786    measure: [u32; RECURSION_TRACE_MAX_DEPTH],
19787    _sealed: (),
19788}
19789
19790impl RecursionTrace {
19791    /// Number of recursive descents in this trace.
19792    #[inline]
19793    #[must_use]
19794    pub const fn depth(&self) -> u32 {
19795        self.depth
19796    }
19797
19798    /// Descent-measure sequence.
19799    #[inline]
19800    #[must_use]
19801    pub const fn measure(&self) -> &[u32; RECURSION_TRACE_MAX_DEPTH] {
19802        &self.measure
19803    }
19804
19805    /// Crate-internal constructor.
19806    #[inline]
19807    #[must_use]
19808    #[allow(dead_code)]
19809    pub(crate) const fn new(depth: u32, measure: [u32; RECURSION_TRACE_MAX_DEPTH]) -> Self {
19810        Self {
19811            depth,
19812            measure,
19813            _sealed: (),
19814        }
19815    }
19816}
19817
19818/// Phase F.3 (target §4.7 region): sealed address-region witness.
19819#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19820pub struct AddressRegion {
19821    base: u128,
19822    extent: u64,
19823    _sealed: (),
19824}
19825
19826impl AddressRegion {
19827    /// Base address of the region.
19828    #[inline]
19829    #[must_use]
19830    pub const fn base(&self) -> u128 {
19831        self.base
19832    }
19833
19834    /// Extent (number of addressable cells).
19835    #[inline]
19836    #[must_use]
19837    pub const fn extent(&self) -> u64 {
19838        self.extent
19839    }
19840
19841    /// Crate-internal constructor.
19842    #[inline]
19843    #[must_use]
19844    #[allow(dead_code)]
19845    pub(crate) const fn new(base: u128, extent: u64) -> Self {
19846        Self {
19847            base,
19848            extent,
19849            _sealed: (),
19850        }
19851    }
19852}
19853
19854/// Phase F.3 (target §4.7 linear): sealed linear-resource budget.
19855#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19856pub struct LinearBudget {
19857    sites_remaining: u64,
19858    _sealed: (),
19859}
19860
19861impl LinearBudget {
19862    /// Number of linear sites still available for allocation.
19863    #[inline]
19864    #[must_use]
19865    pub const fn sites_remaining(&self) -> u64 {
19866        self.sites_remaining
19867    }
19868
19869    /// Crate-internal constructor.
19870    #[inline]
19871    #[must_use]
19872    #[allow(dead_code)]
19873    pub(crate) const fn new(sites_remaining: u64) -> Self {
19874        Self {
19875            sites_remaining,
19876            _sealed: (),
19877        }
19878    }
19879}
19880
19881/// Phase F.3 (target §4.7 linear): sealed lease-allocation witness.
19882#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19883pub struct LeaseAllocation {
19884    site_count: u32,
19885    scope_hash: u128,
19886    _sealed: (),
19887}
19888
19889impl LeaseAllocation {
19890    /// Number of linear sites taken by this allocation.
19891    #[inline]
19892    #[must_use]
19893    pub const fn site_count(&self) -> u32 {
19894        self.site_count
19895    }
19896
19897    /// Content-hash of the lease scope identifier.
19898    #[inline]
19899    #[must_use]
19900    pub const fn scope_hash(&self) -> u128 {
19901        self.scope_hash
19902    }
19903
19904    /// Crate-internal constructor.
19905    #[inline]
19906    #[must_use]
19907    #[allow(dead_code)]
19908    pub(crate) const fn new(site_count: u32, scope_hash: u128) -> Self {
19909        Self {
19910            site_count,
19911            scope_hash,
19912            _sealed: (),
19913        }
19914    }
19915}
19916
19917/// v0.2.2 Phase J: zero-sized token identifying the `Total` marker.
19918#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19919pub struct TotalMarker;
19920
19921/// v0.2.2 Phase J: zero-sized token identifying the `Invertible` marker.
19922#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19923pub struct InvertibleMarker;
19924
19925/// v0.2.2 Phase J: zero-sized token identifying the `PreservesStructure` marker.
19926#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19927pub struct PreservesStructureMarker;
19928
19929mod marker_tuple_sealed {
19930    /// Private supertrait. Not implementable outside this crate.
19931    pub trait Sealed {}
19932}
19933
19934/// v0.2.2 Phase J: sealed marker-tuple trait. Implemented exhaustively by
19935/// the closed catalogue of six admissible marker tuples in canonical order
19936/// (Total, Invertible, PreservesStructure). Downstream cannot add new
19937/// marker tuples; the seal anchors Phase J's compile-time correctness claim.
19938pub trait MarkerTuple: marker_tuple_sealed::Sealed {}
19939
19940impl marker_tuple_sealed::Sealed for () {}
19941impl MarkerTuple for () {}
19942impl marker_tuple_sealed::Sealed for (TotalMarker,) {}
19943impl MarkerTuple for (TotalMarker,) {}
19944impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker) {}
19945impl MarkerTuple for (TotalMarker, InvertibleMarker) {}
19946impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
19947impl MarkerTuple for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
19948impl marker_tuple_sealed::Sealed for (InvertibleMarker,) {}
19949impl MarkerTuple for (InvertibleMarker,) {}
19950impl marker_tuple_sealed::Sealed for (InvertibleMarker, PreservesStructureMarker) {}
19951impl MarkerTuple for (InvertibleMarker, PreservesStructureMarker) {}
19952
19953/// v0.2.2 Phase J: type-level set intersection of two marker tuples.
19954/// Implemented exhaustively for every ordered pair in the closed catalogue.
19955/// Composition combinators (`then`, `and_then`) use this trait to compute
19956/// the output marker tuple of a composed primitive as the intersection of
19957/// its two inputs' tuples. Because the catalogue is closed, the result is
19958/// always another tuple in the catalogue — no open-world hazards.
19959pub trait MarkerIntersection<Other: MarkerTuple>: MarkerTuple {
19960    /// The intersection of `Self` and `Other` in the closed catalogue.
19961    type Output: MarkerTuple;
19962}
19963
19964impl MarkerIntersection<()> for () {
19965    type Output = ();
19966}
19967impl MarkerIntersection<(TotalMarker,)> for () {
19968    type Output = ();
19969}
19970impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for () {
19971    type Output = ();
19972}
19973impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)> for () {
19974    type Output = ();
19975}
19976impl MarkerIntersection<(InvertibleMarker,)> for () {
19977    type Output = ();
19978}
19979impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for () {
19980    type Output = ();
19981}
19982impl MarkerIntersection<()> for (TotalMarker,) {
19983    type Output = ();
19984}
19985impl MarkerIntersection<(TotalMarker,)> for (TotalMarker,) {
19986    type Output = (TotalMarker,);
19987}
19988impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker,) {
19989    type Output = (TotalMarker,);
19990}
19991impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
19992    for (TotalMarker,)
19993{
19994    type Output = (TotalMarker,);
19995}
19996impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker,) {
19997    type Output = ();
19998}
19999impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (TotalMarker,) {
20000    type Output = ();
20001}
20002impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker) {
20003    type Output = ();
20004}
20005impl MarkerIntersection<(TotalMarker,)> for (TotalMarker, InvertibleMarker) {
20006    type Output = (TotalMarker,);
20007}
20008impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker, InvertibleMarker) {
20009    type Output = (TotalMarker, InvertibleMarker);
20010}
20011impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20012    for (TotalMarker, InvertibleMarker)
20013{
20014    type Output = (TotalMarker, InvertibleMarker);
20015}
20016impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker, InvertibleMarker) {
20017    type Output = (InvertibleMarker,);
20018}
20019impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20020    for (TotalMarker, InvertibleMarker)
20021{
20022    type Output = (InvertibleMarker,);
20023}
20024impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {
20025    type Output = ();
20026}
20027impl MarkerIntersection<(TotalMarker,)>
20028    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20029{
20030    type Output = (TotalMarker,);
20031}
20032impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20033    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20034{
20035    type Output = (TotalMarker, InvertibleMarker);
20036}
20037impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20038    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20039{
20040    type Output = (TotalMarker, InvertibleMarker, PreservesStructureMarker);
20041}
20042impl MarkerIntersection<(InvertibleMarker,)>
20043    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20044{
20045    type Output = (InvertibleMarker,);
20046}
20047impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20048    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20049{
20050    type Output = (InvertibleMarker, PreservesStructureMarker);
20051}
20052impl MarkerIntersection<()> for (InvertibleMarker,) {
20053    type Output = ();
20054}
20055impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker,) {
20056    type Output = ();
20057}
20058impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (InvertibleMarker,) {
20059    type Output = (InvertibleMarker,);
20060}
20061impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20062    for (InvertibleMarker,)
20063{
20064    type Output = (InvertibleMarker,);
20065}
20066impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker,) {
20067    type Output = (InvertibleMarker,);
20068}
20069impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (InvertibleMarker,) {
20070    type Output = (InvertibleMarker,);
20071}
20072impl MarkerIntersection<()> for (InvertibleMarker, PreservesStructureMarker) {
20073    type Output = ();
20074}
20075impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20076    type Output = ();
20077}
20078impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20079    for (InvertibleMarker, PreservesStructureMarker)
20080{
20081    type Output = (InvertibleMarker,);
20082}
20083impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20084    for (InvertibleMarker, PreservesStructureMarker)
20085{
20086    type Output = (InvertibleMarker, PreservesStructureMarker);
20087}
20088impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20089    type Output = (InvertibleMarker,);
20090}
20091impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20092    for (InvertibleMarker, PreservesStructureMarker)
20093{
20094    type Output = (InvertibleMarker, PreservesStructureMarker);
20095}
20096
20097/// v0.2.2 Phase J: compile-time check that a combinator's marker tuple
20098/// carries every property declared by the `GroundingMapKind` a program
20099/// claims. Implemented exhaustively by codegen for every valid `(tuple,
20100/// map)` pair; absent impls reject the mismatched declaration at the
20101/// `GroundingProgram::from_primitive` call site.
20102pub trait MarkersImpliedBy<Map: GroundingMapKind>: MarkerTuple {}
20103
20104/// v0.2.2 Phase J: bitmask encoding of a combinator's marker set.
20105/// Bit 0 = Total, bit 1 = Invertible, bit 2 = PreservesStructure.
20106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20107pub struct MarkerBits(u8);
20108
20109impl MarkerBits {
20110    /// The `Total` marker bit.
20111    pub const TOTAL: Self = Self(1);
20112    /// The `Invertible` marker bit.
20113    pub const INVERTIBLE: Self = Self(2);
20114    /// The `PreservesStructure` marker bit.
20115    pub const PRESERVES_STRUCTURE: Self = Self(4);
20116    /// An empty marker set.
20117    pub const NONE: Self = Self(0);
20118
20119    /// Construct a marker bitmask from raw u8.
20120    #[inline]
20121    #[must_use]
20122    pub const fn from_u8(bits: u8) -> Self {
20123        Self(bits)
20124    }
20125
20126    /// Access the raw bitmask.
20127    #[inline]
20128    #[must_use]
20129    pub const fn as_u8(&self) -> u8 {
20130        self.0
20131    }
20132
20133    /// Bitwise OR of two marker bitmasks.
20134    #[inline]
20135    #[must_use]
20136    pub const fn union(self, other: Self) -> Self {
20137        Self(self.0 | other.0)
20138    }
20139
20140    /// Bitwise AND of two marker bitmasks (marker intersection).
20141    #[inline]
20142    #[must_use]
20143    pub const fn intersection(self, other: Self) -> Self {
20144        Self(self.0 & other.0)
20145    }
20146
20147    /// Whether this set contains all marker bits of `other`.
20148    #[inline]
20149    #[must_use]
20150    pub const fn contains(&self, other: Self) -> bool {
20151        (self.0 & other.0) == other.0
20152    }
20153}
20154
20155/// v0.2.2 Phase J: closed catalogue of grounding primitives.
20156/// Exactly 12 operations — read_bytes, interpret_le_integer,
20157/// interpret_be_integer, digest, decode_utf8, decode_json, select_field,
20158/// select_index, const_value, then, map_err, and_then. Adding a new
20159/// primitive is an ontology+grammar+codegen edit, not a Rust patch.
20160#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20161#[non_exhaustive]
20162pub enum GroundingPrimitiveOp {
20163    /// Read a fixed-size byte slice from the input.
20164    ReadBytes,
20165    /// Interpret bytes as a little-endian integer at the target WittLevel.
20166    InterpretLeInteger,
20167    /// Interpret bytes as a big-endian integer.
20168    InterpretBeInteger,
20169    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`.
20170    /// # Scope
20171    /// `interpret_leaf_op` returns the first byte of the blake3 32-byte digest.
20172    /// The full digest is produced by `Datum<W256>` composition of 32 `Digest` leaves —
20173    /// the leaf-level output is the single-byte projection.
20174    Digest,
20175    /// Decode UTF-8 bytes; rejects malformed input.
20176    /// # Scope
20177    /// Only single-byte ASCII (`b < 0x80`) is decoded by `interpret_leaf_op`.
20178    /// Multi-byte UTF-8 is not decoded by this leaf; multi-byte sequences traverse the
20179    /// foundation via `GroundedTuple<N>` composition of single-byte leaves.
20180    DecodeUtf8,
20181    /// Decode JSON bytes; rejects malformed input.
20182    /// # Scope
20183    /// Only the leading byte of a JSON number scalar (`-` or ASCII digit) is parsed
20184    /// by `interpret_leaf_op`. Structured JSON values (objects, arrays, strings,
20185    /// multi-byte numbers) are not parsed by this leaf.
20186    DecodeJson,
20187    /// Select a field from a structured value.
20188    SelectField,
20189    /// Select an indexed element.
20190    SelectIndex,
20191    /// Inject a foundation-known constant.
20192    /// # Scope
20193    /// `interpret_leaf_op` returns `GroundedCoord::w8(0)` — the foundation-canonical
20194    /// zero constant. Non-zero constants are materialized through the const-fn frontier
20195    /// (`validate_const` paths) rather than through this leaf.
20196    ConstValue,
20197    /// Compose two combinators sequentially.
20198    Then,
20199    /// Map the error variant of a fallible combinator.
20200    MapErr,
20201    /// Conditional composition (and_then).
20202    AndThen,
20203}
20204
20205/// Max depth of a composed op chain retained inline inside
20206/// `GroundingPrimitive`. Depth-2 composites (`Then(leaf, leaf)`,
20207/// `AndThen(leaf, leaf)`) are the exercised shape today; 8 gives headroom
20208/// for nested composition while keeping `Copy` and `no_std` without alloc.
20209/// Wiki ADR-037: alias of [`crate::HostBounds::OP_CHAIN_DEPTH_MAX`] via
20210/// [`crate::DefaultHostBounds`].
20211pub const MAX_OP_CHAIN_DEPTH: usize =
20212    <crate::DefaultHostBounds as crate::HostBounds>::OP_CHAIN_DEPTH_MAX;
20213
20214/// v0.2.2 Phase J: a single grounding primitive parametric over its output
20215/// type `Out` and its type-level marker tuple `Markers`.
20216/// Constructed only by the 12 enumerated combinator functions below;
20217/// downstream cannot construct one directly. The `Markers` parameter
20218/// defaults to `()` for backwards-compatible call sites, but each
20219/// combinator returns a specific tuple — see `combinators::digest` etc.
20220/// For leaf primitives `chain_len == 0`. For `Then`/`AndThen`/`MapErr`
20221/// composites, `chain[..chain_len as usize]` is the linearized post-order
20222/// sequence of leaf primitive ops the interpreter walks.
20223#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20224pub struct GroundingPrimitive<Out, Markers: MarkerTuple = ()> {
20225    op: GroundingPrimitiveOp,
20226    markers: MarkerBits,
20227    chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20228    chain_len: u8,
20229    _out: PhantomData<Out>,
20230    _markers: PhantomData<Markers>,
20231    _sealed: (),
20232}
20233
20234impl<Out, Markers: MarkerTuple> GroundingPrimitive<Out, Markers> {
20235    /// Access the primitive op.
20236    #[inline]
20237    #[must_use]
20238    pub const fn op(&self) -> GroundingPrimitiveOp {
20239        self.op
20240    }
20241
20242    /// Access the runtime marker bitmask (mirrors the type-level tuple).
20243    #[inline]
20244    #[must_use]
20245    pub const fn markers(&self) -> MarkerBits {
20246        self.markers
20247    }
20248
20249    /// Access the recorded composition chain. Empty for leaf primitives;
20250    /// the post-order leaf-op sequence for `Then`/`AndThen`/`MapErr`.
20251    #[inline]
20252    #[must_use]
20253    pub fn chain(&self) -> &[GroundingPrimitiveOp] {
20254        &self.chain[..self.chain_len as usize]
20255    }
20256
20257    /// Crate-internal constructor for a leaf primitive (no recorded chain).
20258    /// The type-level `Markers` tuple is selected via turbofish at call
20259    /// sites inside the combinator functions.
20260    #[inline]
20261    #[must_use]
20262    #[allow(dead_code)]
20263    pub(crate) const fn from_parts(op: GroundingPrimitiveOp, markers: MarkerBits) -> Self {
20264        Self {
20265            op,
20266            markers,
20267            chain: [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH],
20268            chain_len: 0,
20269            _out: PhantomData,
20270            _markers: PhantomData,
20271            _sealed: (),
20272        }
20273    }
20274
20275    /// Crate-internal constructor for a composite primitive. Stores
20276    /// `chain[..chain_len]` inline; accessors expose only the prefix.
20277    #[inline]
20278    #[must_use]
20279    #[allow(dead_code)]
20280    pub(crate) const fn from_parts_with_chain(
20281        op: GroundingPrimitiveOp,
20282        markers: MarkerBits,
20283        chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20284        chain_len: u8,
20285    ) -> Self {
20286        Self {
20287            op,
20288            markers,
20289            chain,
20290            chain_len,
20291            _out: PhantomData,
20292            _markers: PhantomData,
20293            _sealed: (),
20294        }
20295    }
20296}
20297
20298/// v0.2.2 Phase J: closed 12-combinator surface for building grounding
20299/// programs. See `GroundingProgram` for composition. Each leaf combinator
20300/// returns a `GroundingPrimitive<Out, M>` carrying a specific marker tuple;
20301/// the type parameter is what `GroundingProgram::from_primitive`'s
20302/// `MarkersImpliedBy<Map>` bound checks at compile time.
20303pub mod combinators {
20304    use super::{
20305        GroundingPrimitive, GroundingPrimitiveOp, InvertibleMarker, MarkerBits, MarkerIntersection,
20306        MarkerTuple, PreservesStructureMarker, TotalMarker, MAX_OP_CHAIN_DEPTH,
20307    };
20308
20309    /// Build the post-order leaf-op chain for a sequential composite:
20310    /// `first.chain ++ [first.op] ++ second.chain ++ [second.op]`.
20311    /// Saturated to `MAX_OP_CHAIN_DEPTH`.
20312    fn compose_chain<A, B, MA: MarkerTuple, MB: MarkerTuple>(
20313        first: &GroundingPrimitive<A, MA>,
20314        second: &GroundingPrimitive<B, MB>,
20315    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20316        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20317        let mut len: usize = 0;
20318        for &op in first.chain() {
20319            if len >= MAX_OP_CHAIN_DEPTH {
20320                return (chain, len as u8);
20321            }
20322            chain[len] = op;
20323            len += 1;
20324        }
20325        if len < MAX_OP_CHAIN_DEPTH {
20326            chain[len] = first.op();
20327            len += 1;
20328        }
20329        for &op in second.chain() {
20330            if len >= MAX_OP_CHAIN_DEPTH {
20331                return (chain, len as u8);
20332            }
20333            chain[len] = op;
20334            len += 1;
20335        }
20336        if len < MAX_OP_CHAIN_DEPTH {
20337            chain[len] = second.op();
20338            len += 1;
20339        }
20340        (chain, len as u8)
20341    }
20342
20343    /// Build the chain for `map_err(first)`: `first.chain ++ [first.op]`.
20344    fn map_err_chain<A, M: MarkerTuple>(
20345        first: &GroundingPrimitive<A, M>,
20346    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20347        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20348        let mut len: usize = 0;
20349        for &op in first.chain() {
20350            if len >= MAX_OP_CHAIN_DEPTH {
20351                return (chain, len as u8);
20352            }
20353            chain[len] = op;
20354            len += 1;
20355        }
20356        if len < MAX_OP_CHAIN_DEPTH {
20357            chain[len] = first.op();
20358            len += 1;
20359        }
20360        (chain, len as u8)
20361    }
20362
20363    /// Read a fixed-size byte slice from the input. `(Total, Invertible)`.
20364    #[inline]
20365    #[must_use]
20366    pub const fn read_bytes<Out>() -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker)> {
20367        GroundingPrimitive::from_parts(
20368            GroundingPrimitiveOp::ReadBytes,
20369            MarkerBits::TOTAL.union(MarkerBits::INVERTIBLE),
20370        )
20371    }
20372
20373    /// Interpret bytes as a little-endian integer at the target WittLevel.
20374    #[inline]
20375    #[must_use]
20376    pub const fn interpret_le_integer<Out>(
20377    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20378        GroundingPrimitive::from_parts(
20379            GroundingPrimitiveOp::InterpretLeInteger,
20380            MarkerBits::TOTAL
20381                .union(MarkerBits::INVERTIBLE)
20382                .union(MarkerBits::PRESERVES_STRUCTURE),
20383        )
20384    }
20385
20386    /// Interpret bytes as a big-endian integer.
20387    #[inline]
20388    #[must_use]
20389    pub const fn interpret_be_integer<Out>(
20390    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20391        GroundingPrimitive::from_parts(
20392            GroundingPrimitiveOp::InterpretBeInteger,
20393            MarkerBits::TOTAL
20394                .union(MarkerBits::INVERTIBLE)
20395                .union(MarkerBits::PRESERVES_STRUCTURE),
20396        )
20397    }
20398
20399    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`. `(Total,)` only.
20400    #[inline]
20401    #[must_use]
20402    pub const fn digest<Out>() -> GroundingPrimitive<Out, (TotalMarker,)> {
20403        GroundingPrimitive::from_parts(GroundingPrimitiveOp::Digest, MarkerBits::TOTAL)
20404    }
20405
20406    /// Decode UTF-8 bytes. `(Invertible, PreservesStructure)` — not Total.
20407    #[inline]
20408    #[must_use]
20409    pub const fn decode_utf8<Out>(
20410    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20411        GroundingPrimitive::from_parts(
20412            GroundingPrimitiveOp::DecodeUtf8,
20413            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20414        )
20415    }
20416
20417    /// Decode JSON bytes. `(Invertible, PreservesStructure)` — not Total.
20418    #[inline]
20419    #[must_use]
20420    pub const fn decode_json<Out>(
20421    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20422        GroundingPrimitive::from_parts(
20423            GroundingPrimitiveOp::DecodeJson,
20424            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20425        )
20426    }
20427
20428    /// Select a field from a structured value. `(Invertible,)` — not Total.
20429    #[inline]
20430    #[must_use]
20431    pub const fn select_field<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20432        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectField, MarkerBits::INVERTIBLE)
20433    }
20434
20435    /// Select an indexed element. `(Invertible,)` — not Total.
20436    #[inline]
20437    #[must_use]
20438    pub const fn select_index<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20439        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectIndex, MarkerBits::INVERTIBLE)
20440    }
20441
20442    /// Inject a foundation-known constant. `(Total, Invertible, PreservesStructure)`.
20443    #[inline]
20444    #[must_use]
20445    pub const fn const_value<Out>(
20446    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20447        GroundingPrimitive::from_parts(
20448            GroundingPrimitiveOp::ConstValue,
20449            MarkerBits::TOTAL
20450                .union(MarkerBits::INVERTIBLE)
20451                .union(MarkerBits::PRESERVES_STRUCTURE),
20452        )
20453    }
20454
20455    /// Compose two combinators sequentially. Markers are intersected at
20456    /// the type level via the `MarkerIntersection` trait. The recorded
20457    /// leaf-op chain lets the foundation's interpreter walk the operands
20458    /// at runtime.
20459    #[inline]
20460    #[must_use]
20461    pub fn then<A, B, MA, MB>(
20462        first: GroundingPrimitive<A, MA>,
20463        second: GroundingPrimitive<B, MB>,
20464    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20465    where
20466        MA: MarkerTuple + MarkerIntersection<MB>,
20467        MB: MarkerTuple,
20468    {
20469        let (chain, chain_len) = compose_chain(&first, &second);
20470        GroundingPrimitive::from_parts_with_chain(
20471            GroundingPrimitiveOp::Then,
20472            first.markers().intersection(second.markers()),
20473            chain,
20474            chain_len,
20475        )
20476    }
20477
20478    /// Map an error variant of a fallible combinator. Marker tuple
20479    /// is preserved. The operand's op is recorded so the interpreter's
20480    /// `MapErr` arm can forward the success value.
20481    #[inline]
20482    #[must_use]
20483    pub fn map_err<A, M: MarkerTuple>(first: GroundingPrimitive<A, M>) -> GroundingPrimitive<A, M> {
20484        let (chain, chain_len) = map_err_chain(&first);
20485        GroundingPrimitive::from_parts_with_chain(
20486            GroundingPrimitiveOp::MapErr,
20487            first.markers(),
20488            chain,
20489            chain_len,
20490        )
20491    }
20492
20493    /// Conditional composition (and_then). Markers are intersected; the
20494    /// recorded chain mirrors `then` so the interpreter walks operands.
20495    #[inline]
20496    #[must_use]
20497    pub fn and_then<A, B, MA, MB>(
20498        first: GroundingPrimitive<A, MA>,
20499        second: GroundingPrimitive<B, MB>,
20500    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20501    where
20502        MA: MarkerTuple + MarkerIntersection<MB>,
20503        MB: MarkerTuple,
20504    {
20505        let (chain, chain_len) = compose_chain(&first, &second);
20506        GroundingPrimitive::from_parts_with_chain(
20507            GroundingPrimitiveOp::AndThen,
20508            first.markers().intersection(second.markers()),
20509            chain,
20510            chain_len,
20511        )
20512    }
20513}
20514
20515/// v0.2.2 Phase J: sealed grounding program.
20516/// A composition of combinators with a statically tracked marker tuple.
20517/// Constructed only via `GroundingProgram::from_primitive`, which requires
20518/// via the `MarkersImpliedBy<Map>` trait bound that the primitive's marker
20519/// tuple carries every property declared by `Map: GroundingMapKind`.
20520#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20521pub struct GroundingProgram<Out, Map: GroundingMapKind> {
20522    primitive: GroundingPrimitive<Out>,
20523    _map: PhantomData<Map>,
20524    _sealed: (),
20525}
20526
20527impl<Out, Map: GroundingMapKind> GroundingProgram<Out, Map> {
20528    /// Foundation-verified constructor. Accepts a primitive whose marker
20529    /// tuple satisfies `MarkersImpliedBy<Map>`. Programs built from
20530    /// combinators whose marker tuple lacks a property `Map` requires are
20531    /// rejected at compile time — this is Phase J's marquee correctness
20532    /// claim: misdeclarations fail to compile.
20533    /// # Example: valid program
20534    /// ```
20535    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20536    /// let prog: GroundingProgram<u64, IntegerGroundingMap> =
20537    ///     GroundingProgram::from_primitive(combinators::interpret_le_integer::<u64>());
20538    /// let _ = prog;
20539    /// ```
20540    /// # Example: rejected misdeclaration
20541    /// ```compile_fail
20542    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20543    /// // digest returns (TotalMarker,) which does NOT satisfy
20544    /// // MarkersImpliedBy<IntegerGroundingMap> — the line below fails to compile.
20545    /// let prog: GroundingProgram<[u8; 32], IntegerGroundingMap> =
20546    ///     GroundingProgram::from_primitive(combinators::digest::<[u8; 32]>());
20547    /// let _ = prog;
20548    /// ```
20549    #[inline]
20550    #[must_use]
20551    pub fn from_primitive<Markers>(primitive: GroundingPrimitive<Out, Markers>) -> Self
20552    where
20553        Markers: MarkerTuple + MarkersImpliedBy<Map>,
20554    {
20555        // Preserve the composition chain so the interpreter can walk
20556        // operands of Then/AndThen/MapErr composites.
20557        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20558        let src = primitive.chain();
20559        let mut i = 0;
20560        while i < src.len() && i < MAX_OP_CHAIN_DEPTH {
20561            chain[i] = src[i];
20562            i += 1;
20563        }
20564        let erased = GroundingPrimitive::<Out, ()>::from_parts_with_chain(
20565            primitive.op(),
20566            primitive.markers(),
20567            chain,
20568            i as u8,
20569        );
20570        Self {
20571            primitive: erased,
20572            _map: PhantomData,
20573            _sealed: (),
20574        }
20575    }
20576
20577    /// Access the underlying primitive (erased marker tuple).
20578    #[inline]
20579    #[must_use]
20580    pub const fn primitive(&self) -> &GroundingPrimitive<Out> {
20581        &self.primitive
20582    }
20583}
20584
20585/// Phase K (target §4.3 / §9 criterion 1): foundation-supplied interpreter for
20586/// grounding programs whose `Out` is `GroundedCoord`. Handles every op in
20587/// the closed 12-combinator catalogue: leaf ops (`ReadBytes`,
20588/// `InterpretLeInteger`, `InterpretBeInteger`, `Digest`, `DecodeUtf8`,
20589/// `DecodeJson`, `ConstValue`, `SelectField`, `SelectIndex`) call
20590/// `interpret_leaf_op` directly; composition ops (`Then`, `AndThen`,
20591/// `MapErr`) walk the chain recorded in the primitive and thread
20592/// `external` through each leaf step. The interpreter surfaces
20593/// `GroundedCoord::w8(byte)` values; richer outputs compose through
20594/// combinator chains producing `GroundedTuple<N>`. No `ground()`
20595/// override exists after W4 closure — downstream provides only
20596/// `program()`, and `GroundingExt::ground` is foundation-authored.
20597impl<Map: GroundingMapKind> GroundingProgram<GroundedCoord, Map> {
20598    /// Run this program on external bytes, producing a `GroundedCoord`.
20599    /// Returns `None` if the input is malformed/undersized for the
20600    /// program's op chain.
20601    #[inline]
20602    #[must_use]
20603    pub fn run(&self, external: &[u8]) -> Option<GroundedCoord> {
20604        match self.primitive.op() {
20605            GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20606                let chain = self.primitive.chain();
20607                if chain.is_empty() {
20608                    return None;
20609                }
20610                let mut last: Option<GroundedCoord> = None;
20611                for &op in chain {
20612                    match interpret_leaf_op(op, external) {
20613                        Some(c) => last = Some(c),
20614                        None => return None,
20615                    }
20616                }
20617                last
20618            }
20619            GroundingPrimitiveOp::MapErr => self
20620                .primitive
20621                .chain()
20622                .first()
20623                .and_then(|&op| interpret_leaf_op(op, external)),
20624            leaf => interpret_leaf_op(leaf, external),
20625        }
20626    }
20627}
20628
20629/// W4 closure (target §4.3 + §9 criterion 1): foundation-supplied
20630/// interpreter for programs producing `GroundedTuple<N>`. Splits
20631/// `external` into `N` equal windows and runs the same dispatch
20632/// that `GroundingProgram<GroundedCoord, Map>::run` performs on
20633/// each window. Returns `None` if `N == 0`, the input is empty,
20634/// the input length isn't divisible by `N`, or any window fails.
20635impl<const N: usize, Map: GroundingMapKind> GroundingProgram<GroundedTuple<N>, Map> {
20636    /// Run this program on external bytes, producing a `GroundedTuple<N>`.
20637    #[inline]
20638    #[must_use]
20639    pub fn run(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
20640        if N == 0 || external.is_empty() || external.len() % N != 0 {
20641            return None;
20642        }
20643        let window = external.len() / N;
20644        let mut coords: [GroundedCoord; N] = [const { GroundedCoord::w8(0) }; N];
20645        let mut i = 0usize;
20646        while i < N {
20647            let start = i * window;
20648            let end = start + window;
20649            let sub = &external[start..end];
20650            // Walk this window through the same leaf/composition
20651            // dispatch as the GroundedCoord interpreter above. A
20652            // helper that runs the chain is reused via the same
20653            // primitive accessors.
20654            let outcome = match self.primitive.op() {
20655                GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20656                    let chain = self.primitive.chain();
20657                    if chain.is_empty() {
20658                        return None;
20659                    }
20660                    let mut last: Option<GroundedCoord> = None;
20661                    for &op in chain {
20662                        match interpret_leaf_op(op, sub) {
20663                            Some(c) => last = Some(c),
20664                            None => return None,
20665                        }
20666                    }
20667                    last
20668                }
20669                GroundingPrimitiveOp::MapErr => self
20670                    .primitive
20671                    .chain()
20672                    .first()
20673                    .and_then(|&op| interpret_leaf_op(op, sub)),
20674                leaf => interpret_leaf_op(leaf, sub),
20675            };
20676            match outcome {
20677                Some(c) => {
20678                    coords[i] = c;
20679                }
20680                None => {
20681                    return None;
20682                }
20683            }
20684            i += 1;
20685        }
20686        Some(GroundedTuple::new(coords))
20687    }
20688}
20689
20690/// Foundation-canonical leaf-op interpreter. Called directly by
20691/// `GroundingProgram::run` for leaf primitives and step-by-step for
20692/// composition ops.
20693#[inline]
20694fn interpret_leaf_op(op: GroundingPrimitiveOp, external: &[u8]) -> Option<GroundedCoord> {
20695    match op {
20696        GroundingPrimitiveOp::ReadBytes | GroundingPrimitiveOp::InterpretLeInteger => {
20697            external.first().map(|&b| GroundedCoord::w8(b))
20698        }
20699        GroundingPrimitiveOp::InterpretBeInteger => external.last().map(|&b| GroundedCoord::w8(b)),
20700        GroundingPrimitiveOp::Digest => {
20701            // Foundation-canonical digest: first byte as `GroundedCoord` —
20702            // the full 32-byte digest requires a Datum<W256> sink that does
20703            // not fit in `GroundedCoord`. Downstream that needs the full
20704            // digest composes a richer program via Then/AndThen chains over
20705            // the 12 closed combinators — no `ground()` override exists after
20706            // W4 closure.
20707            external.first().map(|&b| GroundedCoord::w8(b))
20708        }
20709        GroundingPrimitiveOp::DecodeUtf8 => {
20710            // ASCII single-byte path — the canonical v0.2.2 semantics for
20711            // `Grounding::ground` over `GroundedCoord` outputs. Multi-byte
20712            // UTF-8 sequences are out of scope for w8-sized leaves; a richer
20713            // structured output composes via combinator chains into
20714            // `GroundedTuple<N>`.
20715            match external.first() {
20716                Some(&b) if b < 0x80 => Some(GroundedCoord::w8(b)),
20717                _ => None,
20718            }
20719        }
20720        GroundingPrimitiveOp::DecodeJson => {
20721            // Accept JSON number scalars (leading `-` or ASCII digit).
20722            match external.first() {
20723                Some(&b) if b == b'-' || b.is_ascii_digit() => Some(GroundedCoord::w8(b)),
20724                _ => None,
20725            }
20726        }
20727        GroundingPrimitiveOp::ConstValue => Some(GroundedCoord::w8(0)),
20728        GroundingPrimitiveOp::SelectField | GroundingPrimitiveOp::SelectIndex => {
20729            // Selector ops are composition-only in normal use; if invoked
20730            // directly, forward the first byte as a GroundedCoord.
20731            external.first().map(|&b| GroundedCoord::w8(b))
20732        }
20733        GroundingPrimitiveOp::Then
20734        | GroundingPrimitiveOp::AndThen
20735        | GroundingPrimitiveOp::MapErr => {
20736            // Composite ops are dispatched by `run()` through the chain;
20737            // they never reach the leaf interpreter.
20738            None
20739        }
20740    }
20741}
20742
20743/// v0.2.2 Phase J: MarkersImpliedBy impls for the closed catalogue of valid
20744/// (marker tuple, GroundingMapKind) pairs. These are the compile-time
20745/// witnesses the foundation accepts; every absent pair is a rejection.
20746impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker,) {}
20747impl MarkersImpliedBy<BinaryGroundingMap> for (TotalMarker, InvertibleMarker) {}
20748impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker, InvertibleMarker) {}
20749impl MarkersImpliedBy<BinaryGroundingMap>
20750    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20751{
20752}
20753impl MarkersImpliedBy<DigestGroundingMap>
20754    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20755{
20756}
20757impl MarkersImpliedBy<IntegerGroundingMap>
20758    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20759{
20760}
20761impl MarkersImpliedBy<JsonGroundingMap>
20762    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20763{
20764}
20765impl MarkersImpliedBy<Utf8GroundingMap>
20766    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20767{
20768}
20769impl MarkersImpliedBy<JsonGroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
20770impl MarkersImpliedBy<Utf8GroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
20771
20772/// v0.2.2 T2.5: foundation-private test-only back-door module.
20773/// Exposes crate-internal constructors for `Trace`, `TraceEvent`, and
20774/// `MulContext` to the `uor-foundation-test-helpers` workspace member, which
20775/// re-exports them under stable test-only names. Not part of the public API.
20776#[doc(hidden)]
20777pub mod __test_helpers {
20778    use super::{ContentAddress, ContentFingerprint, MulContext, Trace, TraceEvent, Validated};
20779
20780    /// Test-only ctor: build a Trace from a slice of events with a
20781    /// `ContentFingerprint::zero()` placeholder. Tests that need a non-zero
20782    /// fingerprint use `trace_with_fingerprint` instead. Parametric in
20783    /// `TR_MAX` per the wiki's ADR-018; callers pick the trace event-count
20784    /// ceiling from their selected `HostBounds`.
20785    #[must_use]
20786    pub fn trace_from_events<const TR_MAX: usize>(events: &[TraceEvent]) -> Trace<TR_MAX> {
20787        trace_with_fingerprint(events, 0, ContentFingerprint::zero())
20788    }
20789
20790    /// Test-only ctor that takes an explicit `witt_level_bits` and
20791    /// `ContentFingerprint`. Used by round-trip tests that need to verify
20792    /// the verify-trace fingerprint passthrough invariant.
20793    #[must_use]
20794    pub fn trace_with_fingerprint<const TR_MAX: usize>(
20795        events: &[TraceEvent],
20796        witt_level_bits: u16,
20797        content_fingerprint: ContentFingerprint,
20798    ) -> Trace<TR_MAX> {
20799        let mut arr = [None; TR_MAX];
20800        let n = events.len().min(TR_MAX);
20801        let mut i = 0;
20802        while i < n {
20803            arr[i] = Some(events[i]);
20804            i += 1;
20805        }
20806        // The test-helpers back-door uses the foundation-private
20807        // `from_replay_events_const` to build malformed fixtures for error-path
20808        // tests. Downstream code uses `Trace::try_from_events` (validating).
20809        Trace::from_replay_events_const(arr, n as u16, witt_level_bits, content_fingerprint)
20810    }
20811
20812    /// Test-only ctor: build a TraceEvent.
20813    #[must_use]
20814    pub fn trace_event(step_index: u32, target: u128) -> TraceEvent {
20815        TraceEvent::new(
20816            step_index,
20817            crate::PrimitiveOp::Add,
20818            ContentAddress::from_u128(target),
20819        )
20820    }
20821
20822    /// Test-only ctor: build a MulContext.
20823    #[must_use]
20824    pub fn mul_context(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> MulContext {
20825        MulContext::new(stack_budget_bytes, const_eval, limb_count)
20826    }
20827
20828    /// Test-only ctor: wrap any T in a Runtime-phase Validated. Used by
20829    /// integration tests to construct `Validated<Decl, P>` values that
20830    /// the public API otherwise can't construct directly.
20831    #[must_use]
20832    pub fn validated_runtime<T>(inner: T) -> Validated<T> {
20833        Validated::new(inner)
20834    }
20835}
20836
20837/// Tolerance for entropy equality checks in the Product/Coproduct
20838/// Completion Amendment mint primitives. Returns an absolute-error bound
20839/// scaled to the magnitude of `expected`, so PT_4 / ST_2 / CPT_5
20840/// verifications are robust to floating-point rounding accumulated through
20841/// Künneth products and componentwise sums. The default-host (f64) backing
20842/// is hidden behind the `DefaultDecimal` alias so the function signature
20843/// reads as host-typed; downstream that swaps `H::Decimal` reaches the
20844/// same surface via the alias rebind.
20845type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
20846
20847#[inline]
20848const fn pc_entropy_tolerance(expected: DefaultDecimal) -> DefaultDecimal {
20849    let magnitude = if expected < 0.0 { -expected } else { expected };
20850    let scale = if magnitude > 1.0 { magnitude } else { 1.0 };
20851    1024.0 * <DefaultDecimal>::EPSILON * scale
20852}
20853
20854/// Validate an entropy value before participating in additivity checks.
20855/// Rejects NaN, ±∞, and negative values — the foundation's
20856/// `primitive_descent_metrics` produces `residual × LN_2` with
20857/// `residual: u32`, so valid entropies are non-negative finite Decimals.
20858#[inline]
20859fn pc_entropy_input_is_valid(value: DefaultDecimal) -> bool {
20860    value.is_finite() && value >= 0.0
20861}
20862
20863/// Check that `actual` matches `expected` within tolerance and that both
20864/// inputs are valid entropy values. Returns `false` if either input is
20865/// non-finite, negative, or differs from `expected` by more than
20866/// `pc_entropy_tolerance(expected)`.
20867#[inline]
20868fn pc_entropy_additivity_holds(actual: DefaultDecimal, expected: DefaultDecimal) -> bool {
20869    if !pc_entropy_input_is_valid(actual) || !pc_entropy_input_is_valid(expected) {
20870        return false;
20871    }
20872    let diff = actual - expected;
20873    let diff_abs = if diff < 0.0 { -diff } else { diff };
20874    diff_abs <= pc_entropy_tolerance(expected)
20875}
20876
20877/// Evidence bundle for `PartitionProductWitness`. Carries the PT_1 / PT_3 /
20878/// PT_4 input values used at mint time. Derives `PartialEq` only because
20879/// `f64` entropy fields exclude `Eq` / `Hash`; this is the auditing surface,
20880/// not a hash-map key.
20881#[derive(Debug, Clone, Copy, PartialEq)]
20882pub struct PartitionProductEvidence {
20883    /// Left operand `siteBudget` (data sites only, PT_1 input).
20884    pub left_site_budget: u16,
20885    /// Right operand `siteBudget`.
20886    pub right_site_budget: u16,
20887    /// Left operand `SITE_COUNT` (layout width, layout-invariant input).
20888    pub left_total_site_count: u16,
20889    /// Right operand `SITE_COUNT`.
20890    pub right_total_site_count: u16,
20891    /// Left operand Euler characteristic (PT_3 input).
20892    pub left_euler: i32,
20893    /// Right operand Euler characteristic.
20894    pub right_euler: i32,
20895    /// Left operand entropy in nats (PT_4 input).
20896    pub left_entropy_nats_bits: u64,
20897    /// Right operand entropy in nats.
20898    pub right_entropy_nats_bits: u64,
20899    /// Fingerprint of the source witness the evidence belongs to.
20900    pub source_witness_fingerprint: ContentFingerprint,
20901}
20902
20903/// Evidence bundle for `PartitionCoproductWitness`. Carries the
20904/// ST_1 / ST_2 / ST_9 / ST_10 input values used at mint time.
20905#[derive(Debug, Clone, Copy, PartialEq)]
20906pub struct PartitionCoproductEvidence {
20907    pub left_site_budget: u16,
20908    pub right_site_budget: u16,
20909    pub left_total_site_count: u16,
20910    pub right_total_site_count: u16,
20911    pub left_euler: i32,
20912    pub right_euler: i32,
20913    pub left_entropy_nats_bits: u64,
20914    pub right_entropy_nats_bits: u64,
20915    pub left_betti: [u32; MAX_BETTI_DIMENSION],
20916    pub right_betti: [u32; MAX_BETTI_DIMENSION],
20917    pub source_witness_fingerprint: ContentFingerprint,
20918}
20919
20920/// Evidence bundle for `CartesianProductWitness`. Carries the
20921/// CPT_1 / CPT_3 / CPT_4 / CPT_5 input values used at mint time, plus
20922/// `combined_entropy_nats` — the CartesianProductWitness itself does not
20923/// store entropy (see §1a), so the evidence sidecar preserves the
20924/// verification target value for re-audit.
20925#[derive(Debug, Clone, Copy, PartialEq)]
20926pub struct CartesianProductEvidence {
20927    pub left_site_budget: u16,
20928    pub right_site_budget: u16,
20929    pub left_total_site_count: u16,
20930    pub right_total_site_count: u16,
20931    pub left_euler: i32,
20932    pub right_euler: i32,
20933    pub left_betti: [u32; MAX_BETTI_DIMENSION],
20934    pub right_betti: [u32; MAX_BETTI_DIMENSION],
20935    pub left_entropy_nats_bits: u64,
20936    pub right_entropy_nats_bits: u64,
20937    pub combined_entropy_nats_bits: u64,
20938    pub source_witness_fingerprint: ContentFingerprint,
20939}
20940
20941/// Inputs to `PartitionProductWitness::mint_verified`. Mirrors the
20942/// underlying primitive's parameter list; each field is supplied by the
20943/// caller (typically a `product_shape!` macro expansion or a manual
20944/// construction following the amendment's Gap 2 pattern). Derives
20945/// `PartialEq` only because of the `f64` entropy fields.
20946#[derive(Debug, Clone, Copy, PartialEq)]
20947pub struct PartitionProductMintInputs {
20948    pub witt_bits: u16,
20949    pub left_fingerprint: ContentFingerprint,
20950    pub right_fingerprint: ContentFingerprint,
20951    pub left_site_budget: u16,
20952    pub right_site_budget: u16,
20953    pub left_total_site_count: u16,
20954    pub right_total_site_count: u16,
20955    pub left_euler: i32,
20956    pub right_euler: i32,
20957    pub left_entropy_nats_bits: u64,
20958    pub right_entropy_nats_bits: u64,
20959    pub combined_site_budget: u16,
20960    pub combined_site_count: u16,
20961    pub combined_euler: i32,
20962    pub combined_entropy_nats_bits: u64,
20963    pub combined_fingerprint: ContentFingerprint,
20964}
20965
20966/// Inputs to `PartitionCoproductWitness::mint_verified`. Adds three
20967/// structural fields beyond the other two MintInputs: the combined
20968/// constraint array, the boundary index between L and R regions, and the
20969/// tag site layout index. These feed `validate_coproduct_structure` at
20970/// mint time so ST_6 / ST_7 / ST_8 are verified numerically rather than
20971/// trusted from the caller.
20972/// Derives `Debug`, `Clone`, `Copy` only — no `PartialEq`. `ConstraintRef`
20973/// does not implement `PartialEq`, so deriving equality on a struct with a
20974/// `&[ConstraintRef]` field would not compile. MintInputs is not used as
20975/// an equality target in practice; downstream consumers compare the minted
20976/// witness (which derives `Eq` + `Hash`) instead.
20977#[derive(Debug, Clone, Copy)]
20978pub struct PartitionCoproductMintInputs {
20979    pub witt_bits: u16,
20980    pub left_fingerprint: ContentFingerprint,
20981    pub right_fingerprint: ContentFingerprint,
20982    pub left_site_budget: u16,
20983    pub right_site_budget: u16,
20984    pub left_total_site_count: u16,
20985    pub right_total_site_count: u16,
20986    pub left_euler: i32,
20987    pub right_euler: i32,
20988    pub left_entropy_nats_bits: u64,
20989    pub right_entropy_nats_bits: u64,
20990    pub left_betti: [u32; MAX_BETTI_DIMENSION],
20991    pub right_betti: [u32; MAX_BETTI_DIMENSION],
20992    pub combined_site_budget: u16,
20993    pub combined_site_count: u16,
20994    pub combined_euler: i32,
20995    pub combined_entropy_nats_bits: u64,
20996    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
20997    pub combined_fingerprint: ContentFingerprint,
20998    pub combined_constraints: &'static [crate::pipeline::ConstraintRef],
20999    pub left_constraint_count: usize,
21000    pub tag_site: u16,
21001}
21002
21003/// Inputs to `CartesianProductWitness::mint_verified`. Matches the
21004/// CartesianProduct mint primitive's parameter list.
21005#[derive(Debug, Clone, Copy, PartialEq)]
21006pub struct CartesianProductMintInputs {
21007    pub witt_bits: u16,
21008    pub left_fingerprint: ContentFingerprint,
21009    pub right_fingerprint: ContentFingerprint,
21010    pub left_site_budget: u16,
21011    pub right_site_budget: u16,
21012    pub left_total_site_count: u16,
21013    pub right_total_site_count: u16,
21014    pub left_euler: i32,
21015    pub right_euler: i32,
21016    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21017    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21018    pub left_entropy_nats_bits: u64,
21019    pub right_entropy_nats_bits: u64,
21020    pub combined_site_budget: u16,
21021    pub combined_site_count: u16,
21022    pub combined_euler: i32,
21023    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21024    pub combined_entropy_nats_bits: u64,
21025    pub combined_fingerprint: ContentFingerprint,
21026}
21027
21028/// Sealed PartitionProduct witness — content-addressed assertion that a
21029/// partition decomposes as `PartitionProduct(left, right)` per PT_2a.
21030/// Minting is gated on PT_1, PT_3, PT_4, and the foundation
21031/// `ProductLayoutWidth` invariant being verified against component
21032/// shapes. Existence of an instance is the attestation — there is no
21033/// partial or unverified form.
21034#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21035pub struct PartitionProductWitness {
21036    witt_bits: u16,
21037    content_fingerprint: ContentFingerprint,
21038    left_fingerprint: ContentFingerprint,
21039    right_fingerprint: ContentFingerprint,
21040    combined_site_budget: u16,
21041    combined_site_count: u16,
21042}
21043
21044impl PartitionProductWitness {
21045    /// Witt level at which the witness was minted.
21046    #[inline]
21047    #[must_use]
21048    pub const fn witt_bits(&self) -> u16 {
21049        self.witt_bits
21050    }
21051    /// Content fingerprint of the combined (A × B) shape.
21052    #[inline]
21053    #[must_use]
21054    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21055        self.content_fingerprint
21056    }
21057    /// Content fingerprint of the left factor A.
21058    #[inline]
21059    #[must_use]
21060    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21061        self.left_fingerprint
21062    }
21063    /// Content fingerprint of the right factor B.
21064    #[inline]
21065    #[must_use]
21066    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21067        self.right_fingerprint
21068    }
21069    /// `siteBudget(A × B)` per PT_1.
21070    #[inline]
21071    #[must_use]
21072    pub const fn combined_site_budget(&self) -> u16 {
21073        self.combined_site_budget
21074    }
21075    /// `SITE_COUNT(A × B)` — the foundation layout width.
21076    #[inline]
21077    #[must_use]
21078    pub const fn combined_site_count(&self) -> u16 {
21079        self.combined_site_count
21080    }
21081    /// Crate-internal mint entry. Only the verified mint primitive may call this.
21082    #[inline]
21083    #[must_use]
21084    #[allow(clippy::too_many_arguments)]
21085    pub(crate) const fn with_level_fingerprints_and_sites(
21086        witt_bits: u16,
21087        content_fingerprint: ContentFingerprint,
21088        left_fingerprint: ContentFingerprint,
21089        right_fingerprint: ContentFingerprint,
21090        combined_site_budget: u16,
21091        combined_site_count: u16,
21092    ) -> Self {
21093        Self {
21094            witt_bits,
21095            content_fingerprint,
21096            left_fingerprint,
21097            right_fingerprint,
21098            combined_site_budget,
21099            combined_site_count,
21100        }
21101    }
21102}
21103
21104/// Sealed PartitionCoproduct witness — content-addressed assertion that a
21105/// partition decomposes as `PartitionCoproduct(left, right)` per PT_2b.
21106/// Minting verifies ST_1, ST_2, ST_6, ST_7, ST_8, ST_9, ST_10, the
21107/// foundation `CoproductLayoutWidth` invariant, and — for ST_6/ST_7/ST_8 —
21108/// walks the supplied constraint array through `validate_coproduct_structure`.
21109#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21110pub struct PartitionCoproductWitness {
21111    witt_bits: u16,
21112    content_fingerprint: ContentFingerprint,
21113    left_fingerprint: ContentFingerprint,
21114    right_fingerprint: ContentFingerprint,
21115    combined_site_budget: u16,
21116    combined_site_count: u16,
21117    tag_site_index: u16,
21118}
21119
21120impl PartitionCoproductWitness {
21121    #[inline]
21122    #[must_use]
21123    pub const fn witt_bits(&self) -> u16 {
21124        self.witt_bits
21125    }
21126    #[inline]
21127    #[must_use]
21128    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21129        self.content_fingerprint
21130    }
21131    #[inline]
21132    #[must_use]
21133    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21134        self.left_fingerprint
21135    }
21136    #[inline]
21137    #[must_use]
21138    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21139        self.right_fingerprint
21140    }
21141    /// `siteBudget(A + B)` per ST_1 = max(siteBudget(A), siteBudget(B)).
21142    #[inline]
21143    #[must_use]
21144    pub const fn combined_site_budget(&self) -> u16 {
21145        self.combined_site_budget
21146    }
21147    /// `SITE_COUNT(A + B)` — the foundation layout width including the new tag site.
21148    #[inline]
21149    #[must_use]
21150    pub const fn combined_site_count(&self) -> u16 {
21151        self.combined_site_count
21152    }
21153    /// Index of the tag site in the layout convention of §4b'.
21154    /// Equals `max(SITE_COUNT(A), SITE_COUNT(B))`.
21155    #[inline]
21156    #[must_use]
21157    pub const fn tag_site_index(&self) -> u16 {
21158        self.tag_site_index
21159    }
21160    #[inline]
21161    #[must_use]
21162    #[allow(clippy::too_many_arguments)]
21163    pub(crate) const fn with_level_fingerprints_sites_and_tag(
21164        witt_bits: u16,
21165        content_fingerprint: ContentFingerprint,
21166        left_fingerprint: ContentFingerprint,
21167        right_fingerprint: ContentFingerprint,
21168        combined_site_budget: u16,
21169        combined_site_count: u16,
21170        tag_site_index: u16,
21171    ) -> Self {
21172        Self {
21173            witt_bits,
21174            content_fingerprint,
21175            left_fingerprint,
21176            right_fingerprint,
21177            combined_site_budget,
21178            combined_site_count,
21179            tag_site_index,
21180        }
21181    }
21182}
21183
21184/// Sealed CartesianPartitionProduct witness — content-addressed
21185/// assertion that a shape is `CartesianPartitionProduct(left, right)`
21186/// per CPT_2a. Minting verifies CPT_1, CPT_3, CPT_4, CPT_5, and the
21187/// foundation `CartesianLayoutWidth` invariant. The witness stores
21188/// a snapshot of the combined topological invariants (χ, Betti profile)
21189/// because the construction is axiomatic at the invariant level per §3c.
21190/// Entropy is not stored here (f64 has no Eq/Hash); use the paired
21191/// `CartesianProductEvidence` for entropy re-audit.
21192#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21193pub struct CartesianProductWitness {
21194    witt_bits: u16,
21195    content_fingerprint: ContentFingerprint,
21196    left_fingerprint: ContentFingerprint,
21197    right_fingerprint: ContentFingerprint,
21198    combined_site_budget: u16,
21199    combined_site_count: u16,
21200    combined_euler: i32,
21201    combined_betti: [u32; MAX_BETTI_DIMENSION],
21202}
21203
21204impl CartesianProductWitness {
21205    #[inline]
21206    #[must_use]
21207    pub const fn witt_bits(&self) -> u16 {
21208        self.witt_bits
21209    }
21210    #[inline]
21211    #[must_use]
21212    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21213        self.content_fingerprint
21214    }
21215    #[inline]
21216    #[must_use]
21217    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21218        self.left_fingerprint
21219    }
21220    #[inline]
21221    #[must_use]
21222    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21223        self.right_fingerprint
21224    }
21225    #[inline]
21226    #[must_use]
21227    pub const fn combined_site_budget(&self) -> u16 {
21228        self.combined_site_budget
21229    }
21230    #[inline]
21231    #[must_use]
21232    pub const fn combined_site_count(&self) -> u16 {
21233        self.combined_site_count
21234    }
21235    #[inline]
21236    #[must_use]
21237    pub const fn combined_euler(&self) -> i32 {
21238        self.combined_euler
21239    }
21240    #[inline]
21241    #[must_use]
21242    pub const fn combined_betti(&self) -> [u32; MAX_BETTI_DIMENSION] {
21243        self.combined_betti
21244    }
21245    #[inline]
21246    #[must_use]
21247    #[allow(clippy::too_many_arguments)]
21248    pub(crate) const fn with_level_fingerprints_and_invariants(
21249        witt_bits: u16,
21250        content_fingerprint: ContentFingerprint,
21251        left_fingerprint: ContentFingerprint,
21252        right_fingerprint: ContentFingerprint,
21253        combined_site_budget: u16,
21254        combined_site_count: u16,
21255        combined_euler: i32,
21256        combined_betti: [u32; MAX_BETTI_DIMENSION],
21257    ) -> Self {
21258        Self {
21259            witt_bits,
21260            content_fingerprint,
21261            left_fingerprint,
21262            right_fingerprint,
21263            combined_site_budget,
21264            combined_site_count,
21265            combined_euler,
21266            combined_betti,
21267        }
21268    }
21269}
21270
21271impl Certificate for PartitionProductWitness {
21272    const IRI: &'static str = "https://uor.foundation/partition/PartitionProduct";
21273    type Evidence = PartitionProductEvidence;
21274}
21275
21276impl Certificate for PartitionCoproductWitness {
21277    const IRI: &'static str = "https://uor.foundation/partition/PartitionCoproduct";
21278    type Evidence = PartitionCoproductEvidence;
21279}
21280
21281impl Certificate for CartesianProductWitness {
21282    const IRI: &'static str = "https://uor.foundation/partition/CartesianPartitionProduct";
21283    type Evidence = CartesianProductEvidence;
21284}
21285
21286impl core::fmt::Display for PartitionProductWitness {
21287    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21288        f.write_str("PartitionProductWitness")
21289    }
21290}
21291impl core::error::Error for PartitionProductWitness {}
21292
21293impl core::fmt::Display for PartitionCoproductWitness {
21294    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21295        f.write_str("PartitionCoproductWitness")
21296    }
21297}
21298impl core::error::Error for PartitionCoproductWitness {}
21299
21300impl core::fmt::Display for CartesianProductWitness {
21301    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21302        f.write_str("CartesianProductWitness")
21303    }
21304}
21305impl core::error::Error for CartesianProductWitness {}
21306
21307/// Sealed mint path for certificates that require multi-theorem verification
21308/// before minting. Introduced by the Product/Coproduct Completion Amendment
21309/// §1c; distinct from `MintWithLevelFingerprint` (which is the generic
21310/// partial-mint path for sealed shims). `VerifiedMint` implementors are
21311/// the three partition-algebra witnesses, each routing through a
21312/// foundation-internal mint primitive that verifies the relevant theorems.
21313/// The trait is public so external callers can invoke `mint_verified`
21314/// directly, but the `Certificate` supertrait's `certificate_sealed::Sealed`
21315/// bound keeps the implementor set closed to this crate.
21316pub trait VerifiedMint: Certificate {
21317    /// Caller-supplied input bundle — one `*MintInputs` struct per witness.
21318    type Inputs;
21319    /// Failure kind — always `GenericImpossibilityWitness` citing the
21320    /// specific op-namespace theorem or foundation-namespace layout
21321    /// invariant that was violated.
21322    type Error;
21323    /// Verify the theorems and invariants against `inputs`, then mint a
21324    /// witness or return a typed impossibility witness.
21325    /// # Errors
21326    /// Returns a `GenericImpossibilityWitness::for_identity(iri)` when any
21327    /// of the gated theorems or foundation invariants fails. The IRI
21328    /// identifies exactly which identity failed — `op/PT_*`, `op/ST_*`,
21329    /// `op/CPT_*`, or `foundation/*LayoutWidth` / `foundation/CoproductTagEncoding`.
21330    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error>
21331    where
21332        Self: Sized;
21333}
21334
21335/// Recursive classifier used by `validate_coproduct_structure`. Inspects
21336/// one `ConstraintRef`, tallies tag-pinner sightings via mutable references,
21337/// and recurses into `Conjunction` conjuncts up to `max_depth` levels. See
21338/// plan §A4 for the depth bound rationale.
21339#[allow(clippy::too_many_arguments)]
21340fn pc_classify_constraint(
21341    c: &crate::pipeline::ConstraintRef,
21342    in_left_region: bool,
21343    tag_site: u16,
21344    max_depth: u32,
21345    left_pins: &mut u32,
21346    right_pins: &mut u32,
21347    left_bias_ok: &mut bool,
21348    right_bias_ok: &mut bool,
21349) -> Result<(), GenericImpossibilityWitness> {
21350    match c {
21351        crate::pipeline::ConstraintRef::Site { position } => {
21352            if (*position as u16) >= tag_site {
21353                return Err(GenericImpossibilityWitness::for_identity(
21354                    "https://uor.foundation/op/ST_6",
21355                ));
21356            }
21357        }
21358        crate::pipeline::ConstraintRef::Carry { site } => {
21359            if (*site as u16) >= tag_site {
21360                return Err(GenericImpossibilityWitness::for_identity(
21361                    "https://uor.foundation/op/ST_6",
21362                ));
21363            }
21364        }
21365        crate::pipeline::ConstraintRef::Affine {
21366            coefficients,
21367            coefficient_count,
21368            bias,
21369        } => {
21370            let count = *coefficient_count as usize;
21371            let mut nonzero_count: u32 = 0;
21372            let mut nonzero_index: usize = 0;
21373            let mut max_nonzero_index: usize = 0;
21374            let mut i: usize = 0;
21375            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
21376                if coefficients[i] != 0 {
21377                    nonzero_count = nonzero_count.saturating_add(1);
21378                    nonzero_index = i;
21379                    if i > max_nonzero_index {
21380                        max_nonzero_index = i;
21381                    }
21382                }
21383                i += 1;
21384            }
21385            let touches_tag_site = nonzero_count > 0 && (max_nonzero_index as u16) >= tag_site;
21386            let is_canonical_tag_pinner = nonzero_count == 1
21387                && (nonzero_index as u16) == tag_site
21388                && coefficients[nonzero_index] == 1;
21389            if is_canonical_tag_pinner {
21390                if *bias != 0 && *bias != -1 {
21391                    return Err(GenericImpossibilityWitness::for_identity(
21392                        "https://uor.foundation/foundation/CoproductTagEncoding",
21393                    ));
21394                }
21395                if in_left_region {
21396                    *left_pins = left_pins.saturating_add(1);
21397                    if *bias != 0 {
21398                        *left_bias_ok = false;
21399                    }
21400                } else {
21401                    *right_pins = right_pins.saturating_add(1);
21402                    if *bias != -1 {
21403                        *right_bias_ok = false;
21404                    }
21405                }
21406            } else if touches_tag_site {
21407                let nonzero_only_at_tag_site =
21408                    nonzero_count == 1 && (nonzero_index as u16) == tag_site;
21409                if nonzero_only_at_tag_site {
21410                    return Err(GenericImpossibilityWitness::for_identity(
21411                        "https://uor.foundation/foundation/CoproductTagEncoding",
21412                    ));
21413                } else {
21414                    return Err(GenericImpossibilityWitness::for_identity(
21415                        "https://uor.foundation/op/ST_6",
21416                    ));
21417                }
21418            }
21419        }
21420        crate::pipeline::ConstraintRef::Conjunction {
21421            conjuncts,
21422            conjunct_count,
21423        } => {
21424            if max_depth == 0 {
21425                return Err(GenericImpossibilityWitness::for_identity(
21426                    "https://uor.foundation/op/ST_6",
21427                ));
21428            }
21429            let count = *conjunct_count as usize;
21430            let mut idx: usize = 0;
21431            while idx < count && idx < crate::pipeline::CONJUNCTION_MAX_TERMS {
21432                let lifted = conjuncts[idx].into_constraint();
21433                pc_classify_constraint(
21434                    &lifted,
21435                    in_left_region,
21436                    tag_site,
21437                    max_depth - 1,
21438                    left_pins,
21439                    right_pins,
21440                    left_bias_ok,
21441                    right_bias_ok,
21442                )?;
21443                idx += 1;
21444            }
21445        }
21446        crate::pipeline::ConstraintRef::Residue { .. }
21447        | crate::pipeline::ConstraintRef::Hamming { .. }
21448        | crate::pipeline::ConstraintRef::Depth { .. }
21449        | crate::pipeline::ConstraintRef::SatClauses { .. }
21450        | crate::pipeline::ConstraintRef::Bound { .. } => {
21451            // No site references at this level; nothing to check.
21452        }
21453    }
21454    Ok(())
21455}
21456
21457/// Validates ST_6 / ST_7 / ST_8 for a PartitionCoproduct construction by
21458/// walking the emitted constraint array. Recurses into
21459/// `ConstraintRef::Conjunction` conjuncts up to depth 8 (bounded by
21460/// `NERVE_CONSTRAINTS_CAP`) so nested constructions are audited without
21461/// unbounded recursion.
21462/// # Errors
21463/// Returns `GenericImpossibilityWitness::for_identity(...)` citing the
21464/// specific failed identity: `op/ST_6`, `op/ST_7`, or
21465/// `foundation/CoproductTagEncoding`. ST_8 is implied by ST_6 ∧ ST_7 and
21466/// is not cited separately on failure.
21467pub(crate) fn validate_coproduct_structure(
21468    combined_constraints: &[crate::pipeline::ConstraintRef],
21469    left_constraint_count: usize,
21470    tag_site: u16,
21471) -> Result<(), GenericImpossibilityWitness> {
21472    let mut left_pins: u32 = 0;
21473    let mut right_pins: u32 = 0;
21474    let mut left_bias_ok: bool = true;
21475    let mut right_bias_ok: bool = true;
21476    let mut idx: usize = 0;
21477    while idx < combined_constraints.len() {
21478        let in_left_region = idx < left_constraint_count;
21479        pc_classify_constraint(
21480            &combined_constraints[idx],
21481            in_left_region,
21482            tag_site,
21483            NERVE_CONSTRAINTS_CAP as u32,
21484            &mut left_pins,
21485            &mut right_pins,
21486            &mut left_bias_ok,
21487            &mut right_bias_ok,
21488        )?;
21489        idx += 1;
21490    }
21491    if left_pins != 1 || right_pins != 1 {
21492        return Err(GenericImpossibilityWitness::for_identity(
21493            "https://uor.foundation/op/ST_6",
21494        ));
21495    }
21496    if !left_bias_ok || !right_bias_ok {
21497        return Err(GenericImpossibilityWitness::for_identity(
21498            "https://uor.foundation/op/ST_7",
21499        ));
21500    }
21501    Ok(())
21502}
21503
21504/// Mint a `PartitionProductWitness` after verifying PT_1, PT_3, PT_4, and
21505/// the `ProductLayoutWidth` layout invariant. PT_2a is structural (the
21506/// witness existing is the claim); no separate check is needed once the
21507/// invariants match.
21508#[allow(clippy::too_many_arguments)]
21509pub(crate) fn pc_primitive_partition_product(
21510    witt_bits: u16,
21511    left_fingerprint: ContentFingerprint,
21512    right_fingerprint: ContentFingerprint,
21513    left_site_budget: u16,
21514    right_site_budget: u16,
21515    left_total_site_count: u16,
21516    right_total_site_count: u16,
21517    left_euler: i32,
21518    right_euler: i32,
21519    left_entropy_nats_bits: u64,
21520    right_entropy_nats_bits: u64,
21521    combined_site_budget: u16,
21522    combined_site_count: u16,
21523    combined_euler: i32,
21524    combined_entropy_nats_bits: u64,
21525    combined_fingerprint: ContentFingerprint,
21526) -> Result<PartitionProductWitness, GenericImpossibilityWitness> {
21527    let left_entropy_nats =
21528        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21529    let right_entropy_nats =
21530        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21531    let combined_entropy_nats =
21532        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21533    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21534        return Err(GenericImpossibilityWitness::for_identity(
21535            "https://uor.foundation/op/PT_1",
21536        ));
21537    }
21538    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21539        return Err(GenericImpossibilityWitness::for_identity(
21540            "https://uor.foundation/foundation/ProductLayoutWidth",
21541        ));
21542    }
21543    if combined_euler != left_euler.saturating_add(right_euler) {
21544        return Err(GenericImpossibilityWitness::for_identity(
21545            "https://uor.foundation/op/PT_3",
21546        ));
21547    }
21548    if !pc_entropy_input_is_valid(left_entropy_nats)
21549        || !pc_entropy_input_is_valid(right_entropy_nats)
21550        || !pc_entropy_input_is_valid(combined_entropy_nats)
21551    {
21552        return Err(GenericImpossibilityWitness::for_identity(
21553            "https://uor.foundation/op/PT_4",
21554        ));
21555    }
21556    let expected_entropy = left_entropy_nats + right_entropy_nats;
21557    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21558        return Err(GenericImpossibilityWitness::for_identity(
21559            "https://uor.foundation/op/PT_4",
21560        ));
21561    }
21562    Ok(PartitionProductWitness::with_level_fingerprints_and_sites(
21563        witt_bits,
21564        combined_fingerprint,
21565        left_fingerprint,
21566        right_fingerprint,
21567        combined_site_budget,
21568        combined_site_count,
21569    ))
21570}
21571
21572/// Mint a `PartitionCoproductWitness` after verifying ST_1, ST_2, ST_6,
21573/// ST_7, ST_8, ST_9, ST_10, the `CoproductLayoutWidth` layout invariant,
21574/// the tag-site alignment against §4b', and running
21575/// `validate_coproduct_structure` over the supplied constraint array.
21576#[allow(clippy::too_many_arguments)]
21577pub(crate) fn pc_primitive_partition_coproduct(
21578    witt_bits: u16,
21579    left_fingerprint: ContentFingerprint,
21580    right_fingerprint: ContentFingerprint,
21581    left_site_budget: u16,
21582    right_site_budget: u16,
21583    left_total_site_count: u16,
21584    right_total_site_count: u16,
21585    left_euler: i32,
21586    right_euler: i32,
21587    left_entropy_nats_bits: u64,
21588    right_entropy_nats_bits: u64,
21589    left_betti: [u32; MAX_BETTI_DIMENSION],
21590    right_betti: [u32; MAX_BETTI_DIMENSION],
21591    combined_site_budget: u16,
21592    combined_site_count: u16,
21593    combined_euler: i32,
21594    combined_entropy_nats_bits: u64,
21595    combined_betti: [u32; MAX_BETTI_DIMENSION],
21596    combined_fingerprint: ContentFingerprint,
21597    combined_constraints: &[crate::pipeline::ConstraintRef],
21598    left_constraint_count: usize,
21599    tag_site: u16,
21600) -> Result<PartitionCoproductWitness, GenericImpossibilityWitness> {
21601    let left_entropy_nats =
21602        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21603    let right_entropy_nats =
21604        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21605    let combined_entropy_nats =
21606        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21607    let expected_budget = if left_site_budget > right_site_budget {
21608        left_site_budget
21609    } else {
21610        right_site_budget
21611    };
21612    if combined_site_budget != expected_budget {
21613        return Err(GenericImpossibilityWitness::for_identity(
21614            "https://uor.foundation/op/ST_1",
21615        ));
21616    }
21617    let max_total = if left_total_site_count > right_total_site_count {
21618        left_total_site_count
21619    } else {
21620        right_total_site_count
21621    };
21622    let expected_total = max_total.saturating_add(1);
21623    if combined_site_count != expected_total {
21624        return Err(GenericImpossibilityWitness::for_identity(
21625            "https://uor.foundation/foundation/CoproductLayoutWidth",
21626        ));
21627    }
21628    if !pc_entropy_input_is_valid(left_entropy_nats)
21629        || !pc_entropy_input_is_valid(right_entropy_nats)
21630        || !pc_entropy_input_is_valid(combined_entropy_nats)
21631    {
21632        return Err(GenericImpossibilityWitness::for_identity(
21633            "https://uor.foundation/op/ST_2",
21634        ));
21635    }
21636    let max_operand_entropy = if left_entropy_nats > right_entropy_nats {
21637        left_entropy_nats
21638    } else {
21639        right_entropy_nats
21640    };
21641    let expected_entropy = core::f64::consts::LN_2 + max_operand_entropy;
21642    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21643        return Err(GenericImpossibilityWitness::for_identity(
21644            "https://uor.foundation/op/ST_2",
21645        ));
21646    }
21647    if tag_site != max_total {
21648        return Err(GenericImpossibilityWitness::for_identity(
21649            "https://uor.foundation/foundation/CoproductLayoutWidth",
21650        ));
21651    }
21652    validate_coproduct_structure(combined_constraints, left_constraint_count, tag_site)?;
21653    if combined_euler != left_euler.saturating_add(right_euler) {
21654        return Err(GenericImpossibilityWitness::for_identity(
21655            "https://uor.foundation/op/ST_9",
21656        ));
21657    }
21658    let mut k: usize = 0;
21659    while k < MAX_BETTI_DIMENSION {
21660        if combined_betti[k] != left_betti[k].saturating_add(right_betti[k]) {
21661            return Err(GenericImpossibilityWitness::for_identity(
21662                "https://uor.foundation/op/ST_10",
21663            ));
21664        }
21665        k += 1;
21666    }
21667    Ok(
21668        PartitionCoproductWitness::with_level_fingerprints_sites_and_tag(
21669            witt_bits,
21670            combined_fingerprint,
21671            left_fingerprint,
21672            right_fingerprint,
21673            combined_site_budget,
21674            combined_site_count,
21675            max_total,
21676        ),
21677    )
21678}
21679
21680/// Mint a `CartesianProductWitness` after verifying CPT_1, CPT_3, CPT_4,
21681/// CPT_5, and the `CartesianLayoutWidth` layout invariant. Checks
21682/// caller-supplied Künneth-composed invariants against the component
21683/// values (the witness defines these axiomatically per §3c).
21684#[allow(clippy::too_many_arguments)]
21685pub(crate) fn pc_primitive_cartesian_product(
21686    witt_bits: u16,
21687    left_fingerprint: ContentFingerprint,
21688    right_fingerprint: ContentFingerprint,
21689    left_site_budget: u16,
21690    right_site_budget: u16,
21691    left_total_site_count: u16,
21692    right_total_site_count: u16,
21693    left_euler: i32,
21694    right_euler: i32,
21695    left_betti: [u32; MAX_BETTI_DIMENSION],
21696    right_betti: [u32; MAX_BETTI_DIMENSION],
21697    left_entropy_nats_bits: u64,
21698    right_entropy_nats_bits: u64,
21699    combined_site_budget: u16,
21700    combined_site_count: u16,
21701    combined_euler: i32,
21702    combined_betti: [u32; MAX_BETTI_DIMENSION],
21703    combined_entropy_nats_bits: u64,
21704    combined_fingerprint: ContentFingerprint,
21705) -> Result<CartesianProductWitness, GenericImpossibilityWitness> {
21706    let left_entropy_nats =
21707        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21708    let right_entropy_nats =
21709        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21710    let combined_entropy_nats =
21711        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21712    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21713        return Err(GenericImpossibilityWitness::for_identity(
21714            "https://uor.foundation/op/CPT_1",
21715        ));
21716    }
21717    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21718        return Err(GenericImpossibilityWitness::for_identity(
21719            "https://uor.foundation/foundation/CartesianLayoutWidth",
21720        ));
21721    }
21722    if combined_euler != left_euler.saturating_mul(right_euler) {
21723        return Err(GenericImpossibilityWitness::for_identity(
21724            "https://uor.foundation/op/CPT_3",
21725        ));
21726    }
21727    let kunneth = crate::pipeline::kunneth_compose(&left_betti, &right_betti);
21728    let mut k: usize = 0;
21729    while k < MAX_BETTI_DIMENSION {
21730        if combined_betti[k] != kunneth[k] {
21731            return Err(GenericImpossibilityWitness::for_identity(
21732                "https://uor.foundation/op/CPT_4",
21733            ));
21734        }
21735        k += 1;
21736    }
21737    if !pc_entropy_input_is_valid(left_entropy_nats)
21738        || !pc_entropy_input_is_valid(right_entropy_nats)
21739        || !pc_entropy_input_is_valid(combined_entropy_nats)
21740    {
21741        return Err(GenericImpossibilityWitness::for_identity(
21742            "https://uor.foundation/op/CPT_5",
21743        ));
21744    }
21745    let expected_entropy = left_entropy_nats + right_entropy_nats;
21746    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21747        return Err(GenericImpossibilityWitness::for_identity(
21748            "https://uor.foundation/op/CPT_5",
21749        ));
21750    }
21751    Ok(
21752        CartesianProductWitness::with_level_fingerprints_and_invariants(
21753            witt_bits,
21754            combined_fingerprint,
21755            left_fingerprint,
21756            right_fingerprint,
21757            combined_site_budget,
21758            combined_site_count,
21759            combined_euler,
21760            combined_betti,
21761        ),
21762    )
21763}
21764
21765impl VerifiedMint for PartitionProductWitness {
21766    type Inputs = PartitionProductMintInputs;
21767    type Error = GenericImpossibilityWitness;
21768    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21769        pc_primitive_partition_product(
21770            inputs.witt_bits,
21771            inputs.left_fingerprint,
21772            inputs.right_fingerprint,
21773            inputs.left_site_budget,
21774            inputs.right_site_budget,
21775            inputs.left_total_site_count,
21776            inputs.right_total_site_count,
21777            inputs.left_euler,
21778            inputs.right_euler,
21779            inputs.left_entropy_nats_bits,
21780            inputs.right_entropy_nats_bits,
21781            inputs.combined_site_budget,
21782            inputs.combined_site_count,
21783            inputs.combined_euler,
21784            inputs.combined_entropy_nats_bits,
21785            inputs.combined_fingerprint,
21786        )
21787    }
21788}
21789
21790impl VerifiedMint for PartitionCoproductWitness {
21791    type Inputs = PartitionCoproductMintInputs;
21792    type Error = GenericImpossibilityWitness;
21793    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21794        pc_primitive_partition_coproduct(
21795            inputs.witt_bits,
21796            inputs.left_fingerprint,
21797            inputs.right_fingerprint,
21798            inputs.left_site_budget,
21799            inputs.right_site_budget,
21800            inputs.left_total_site_count,
21801            inputs.right_total_site_count,
21802            inputs.left_euler,
21803            inputs.right_euler,
21804            inputs.left_entropy_nats_bits,
21805            inputs.right_entropy_nats_bits,
21806            inputs.left_betti,
21807            inputs.right_betti,
21808            inputs.combined_site_budget,
21809            inputs.combined_site_count,
21810            inputs.combined_euler,
21811            inputs.combined_entropy_nats_bits,
21812            inputs.combined_betti,
21813            inputs.combined_fingerprint,
21814            inputs.combined_constraints,
21815            inputs.left_constraint_count,
21816            inputs.tag_site,
21817        )
21818    }
21819}
21820
21821impl VerifiedMint for CartesianProductWitness {
21822    type Inputs = CartesianProductMintInputs;
21823    type Error = GenericImpossibilityWitness;
21824    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21825        pc_primitive_cartesian_product(
21826            inputs.witt_bits,
21827            inputs.left_fingerprint,
21828            inputs.right_fingerprint,
21829            inputs.left_site_budget,
21830            inputs.right_site_budget,
21831            inputs.left_total_site_count,
21832            inputs.right_total_site_count,
21833            inputs.left_euler,
21834            inputs.right_euler,
21835            inputs.left_betti,
21836            inputs.right_betti,
21837            inputs.left_entropy_nats_bits,
21838            inputs.right_entropy_nats_bits,
21839            inputs.combined_site_budget,
21840            inputs.combined_site_count,
21841            inputs.combined_euler,
21842            inputs.combined_betti,
21843            inputs.combined_entropy_nats_bits,
21844            inputs.combined_fingerprint,
21845        )
21846    }
21847}
21848
21849/// Data record of a partition's runtime-queried properties. Produced at
21850/// witness-mint time and consulted by consumer code that holds a
21851/// `PartitionHandle` and a `PartitionResolver`. Phase 9 stores entropy
21852/// as the IEEE-754 `u64` bit-pattern (`entropy_nats_bits`) so the record
21853/// derives `Eq + Hash` cleanly; consumers project to `H::Decimal` via
21854/// `<H::Decimal as DecimalTranscendental>::from_bits`.
21855#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21856pub struct PartitionRecord<H: crate::HostTypes> {
21857    /// Data sites only — the partition's `siteBudget`, not its layout width.
21858    pub site_budget: u16,
21859    /// Euler characteristic of the partition's nerve.
21860    pub euler: i32,
21861    /// Betti profile of the partition's nerve, padded to `MAX_BETTI_DIMENSION`.
21862    pub betti: [u32; MAX_BETTI_DIMENSION],
21863    /// Shannon entropy in nats (matches `LandauerBudget::nats()` convention).
21864    pub entropy_nats_bits: u64,
21865    _phantom: core::marker::PhantomData<H>,
21866}
21867
21868impl<H: crate::HostTypes> PartitionRecord<H> {
21869    /// Construct a new record. The phantom marker ensures records are
21870    /// parameterized by the host types they originate from.
21871    #[inline]
21872    #[must_use]
21873    pub const fn new(
21874        site_budget: u16,
21875        euler: i32,
21876        betti: [u32; MAX_BETTI_DIMENSION],
21877        entropy_nats_bits: u64,
21878    ) -> Self {
21879        Self {
21880            site_budget,
21881            euler,
21882            betti,
21883            entropy_nats_bits,
21884            _phantom: core::marker::PhantomData,
21885        }
21886    }
21887}
21888
21889/// Resolver mapping content fingerprints to `PartitionRecord`s. Provided
21890/// by the host application — typically a persistent store, an in-memory
21891/// registry populated from witness mint-time data, or a chain-of-witnesses
21892/// trail that can reconstruct properties.
21893pub trait PartitionResolver<H: crate::HostTypes> {
21894    /// Look up partition data by fingerprint. Returns `None` if the
21895    /// resolver has no record for the handle. Handles remain valid as
21896    /// identity tokens regardless of resolver presence.
21897    fn resolve(&self, fp: ContentFingerprint) -> Option<PartitionRecord<H>>;
21898}
21899
21900/// Content-addressed identity token for a partition. Carries only a
21901/// fingerprint; partition data is recovered by pairing the handle with a
21902/// `PartitionResolver` via `resolve_with`. Handles compare and hash by
21903/// fingerprint, so they can serve as keys in content-addressed indices
21904/// without resolver access.
21905#[derive(Debug)]
21906pub struct PartitionHandle<H: crate::HostTypes> {
21907    fingerprint: ContentFingerprint,
21908    _phantom: core::marker::PhantomData<H>,
21909}
21910impl<H: crate::HostTypes> Copy for PartitionHandle<H> {}
21911impl<H: crate::HostTypes> Clone for PartitionHandle<H> {
21912    #[inline]
21913    fn clone(&self) -> Self {
21914        *self
21915    }
21916}
21917impl<H: crate::HostTypes> PartialEq for PartitionHandle<H> {
21918    #[inline]
21919    fn eq(&self, other: &Self) -> bool {
21920        self.fingerprint == other.fingerprint
21921    }
21922}
21923impl<H: crate::HostTypes> Eq for PartitionHandle<H> {}
21924impl<H: crate::HostTypes> core::hash::Hash for PartitionHandle<H> {
21925    #[inline]
21926    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
21927        self.fingerprint.hash(state);
21928    }
21929}
21930
21931impl<H: crate::HostTypes> PartitionHandle<H> {
21932    /// Construct a handle from a content fingerprint.
21933    #[inline]
21934    #[must_use]
21935    pub const fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
21936        Self {
21937            fingerprint,
21938            _phantom: core::marker::PhantomData,
21939        }
21940    }
21941    /// Return the content fingerprint this handle references.
21942    #[inline]
21943    #[must_use]
21944    pub const fn fingerprint(&self) -> ContentFingerprint {
21945        self.fingerprint
21946    }
21947    /// Resolve this handle against a consumer-supplied resolver.
21948    /// Returns `None` if the resolver has no record for this fingerprint.
21949    #[inline]
21950    pub fn resolve_with<R: PartitionResolver<H>>(
21951        &self,
21952        resolver: &R,
21953    ) -> Option<PartitionRecord<H>> {
21954        resolver.resolve(self.fingerprint)
21955    }
21956}
21957
21958/// Resolver-absent default `Element<H>`. Returns empty defaults via the
21959/// `HostTypes::EMPTY_*` constants — used by `NullDatum<H>` and
21960/// `NullTypeDefinition<H>` to satisfy their `Element` associated types.
21961#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21962pub struct NullElement<H: HostTypes> {
21963    _phantom: core::marker::PhantomData<H>,
21964}
21965impl<H: HostTypes> Default for NullElement<H> {
21966    fn default() -> Self {
21967        Self {
21968            _phantom: core::marker::PhantomData,
21969        }
21970    }
21971}
21972impl<H: HostTypes> crate::kernel::address::Element<H> for NullElement<H> {
21973    fn length(&self) -> u64 {
21974        0
21975    }
21976    fn addresses(&self) -> &H::HostString {
21977        H::EMPTY_HOST_STRING
21978    }
21979    fn digest(&self) -> &H::HostString {
21980        H::EMPTY_HOST_STRING
21981    }
21982    fn digest_algorithm(&self) -> &H::HostString {
21983        H::EMPTY_HOST_STRING
21984    }
21985    fn canonical_bytes(&self) -> &H::WitnessBytes {
21986        H::EMPTY_WITNESS_BYTES
21987    }
21988    fn witt_length(&self) -> u64 {
21989        0
21990    }
21991}
21992
21993/// Resolver-absent default `Datum<H>`. All numeric methods return 0.
21994#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21995pub struct NullDatum<H: HostTypes> {
21996    element: NullElement<H>,
21997    _phantom: core::marker::PhantomData<H>,
21998}
21999impl<H: HostTypes> Default for NullDatum<H> {
22000    fn default() -> Self {
22001        Self {
22002            element: NullElement::default(),
22003            _phantom: core::marker::PhantomData,
22004        }
22005    }
22006}
22007impl<H: HostTypes> crate::kernel::schema::Datum<H> for NullDatum<H> {
22008    fn value(&self) -> u64 {
22009        0
22010    }
22011    fn witt_length(&self) -> u64 {
22012        0
22013    }
22014    fn stratum(&self) -> u64 {
22015        0
22016    }
22017    fn spectrum(&self) -> u64 {
22018        0
22019    }
22020    type Element = NullElement<H>;
22021    fn element(&self) -> &Self::Element {
22022        &self.element
22023    }
22024}
22025
22026/// Resolver-absent default `TermExpression<H>`. Empty marker trait, no methods.
22027#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22028pub struct NullTermExpression<H: HostTypes> {
22029    _phantom: core::marker::PhantomData<H>,
22030}
22031impl<H: HostTypes> Default for NullTermExpression<H> {
22032    fn default() -> Self {
22033        Self {
22034            _phantom: core::marker::PhantomData,
22035        }
22036    }
22037}
22038impl<H: HostTypes> crate::kernel::schema::TermExpression<H> for NullTermExpression<H> {}
22039
22040/// Resolver-absent default `SiteIndex<H>`. Self-recursive: `ancilla_site()`
22041/// returns `&self` (no ancilla pairing in the default).
22042#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22043pub struct NullSiteIndex<H: HostTypes> {
22044    _phantom: core::marker::PhantomData<H>,
22045}
22046impl<H: HostTypes> Default for NullSiteIndex<H> {
22047    fn default() -> Self {
22048        Self {
22049            _phantom: core::marker::PhantomData,
22050        }
22051    }
22052}
22053impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullSiteIndex<H> {
22054    fn site_position(&self) -> u64 {
22055        0
22056    }
22057    fn site_state(&self) -> u64 {
22058        0
22059    }
22060    type SiteIndexTarget = NullSiteIndex<H>;
22061    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22062        self
22063    }
22064}
22065
22066/// Resolver-absent default `TagSite<H>`. Embeds an inline `NullSiteIndex`
22067/// field so the inherited `ancilla_site()` accessor returns a valid
22068/// reference; `tag_value()` returns false.
22069#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22070pub struct NullTagSite<H: HostTypes> {
22071    ancilla: NullSiteIndex<H>,
22072}
22073impl<H: HostTypes> Default for NullTagSite<H> {
22074    fn default() -> Self {
22075        Self {
22076            ancilla: NullSiteIndex::default(),
22077        }
22078    }
22079}
22080impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullTagSite<H> {
22081    fn site_position(&self) -> u64 {
22082        0
22083    }
22084    fn site_state(&self) -> u64 {
22085        0
22086    }
22087    type SiteIndexTarget = NullSiteIndex<H>;
22088    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22089        &self.ancilla
22090    }
22091}
22092impl<H: HostTypes> crate::bridge::partition::TagSite<H> for NullTagSite<H> {
22093    fn tag_value(&self) -> bool {
22094        false
22095    }
22096}
22097
22098/// Resolver-absent default `SiteBinding<H>`. Embeds inline `NullConstraint`
22099/// and `NullSiteIndex` so the trait's reference accessors work via &self.field.
22100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22101pub struct NullSiteBinding<H: HostTypes> {
22102    constraint: NullConstraint<H>,
22103    site_index: NullSiteIndex<H>,
22104}
22105impl<H: HostTypes> Default for NullSiteBinding<H> {
22106    fn default() -> Self {
22107        Self {
22108            constraint: NullConstraint::default(),
22109            site_index: NullSiteIndex::default(),
22110        }
22111    }
22112}
22113impl<H: HostTypes> crate::bridge::partition::SiteBinding<H> for NullSiteBinding<H> {
22114    type Constraint = NullConstraint<H>;
22115    fn pinned_by(&self) -> &Self::Constraint {
22116        &self.constraint
22117    }
22118    type SiteIndex = NullSiteIndex<H>;
22119    fn pins_coordinate(&self) -> &Self::SiteIndex {
22120        &self.site_index
22121    }
22122}
22123
22124/// Resolver-absent default `Constraint<H>`. Returns Vertical metric axis,
22125/// empty pinned-sites slice, and zero crossing cost.
22126#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22127pub struct NullConstraint<H: HostTypes> {
22128    _phantom: core::marker::PhantomData<H>,
22129}
22130impl<H: HostTypes> Default for NullConstraint<H> {
22131    fn default() -> Self {
22132        Self {
22133            _phantom: core::marker::PhantomData,
22134        }
22135    }
22136}
22137impl<H: HostTypes> crate::user::type_::Constraint<H> for NullConstraint<H> {
22138    fn metric_axis(&self) -> MetricAxis {
22139        MetricAxis::Vertical
22140    }
22141    type SiteIndex = NullSiteIndex<H>;
22142    fn pins_sites(&self) -> &[Self::SiteIndex] {
22143        &[]
22144    }
22145    fn crossing_cost(&self) -> u64 {
22146        0
22147    }
22148}
22149
22150/// Resolver-absent default `FreeRank<H>`. Empty budget — `is_closed()` true,
22151/// zero counts. Empty `has_site` / `has_binding` slices.
22152#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22153pub struct NullFreeRank<H: HostTypes> {
22154    _phantom: core::marker::PhantomData<H>,
22155}
22156impl<H: HostTypes> Default for NullFreeRank<H> {
22157    fn default() -> Self {
22158        Self {
22159            _phantom: core::marker::PhantomData,
22160        }
22161    }
22162}
22163impl<H: HostTypes> crate::bridge::partition::FreeRank<H> for NullFreeRank<H> {
22164    fn total_sites(&self) -> u64 {
22165        0
22166    }
22167    fn pinned_count(&self) -> u64 {
22168        0
22169    }
22170    fn free_rank(&self) -> u64 {
22171        0
22172    }
22173    fn is_closed(&self) -> bool {
22174        true
22175    }
22176    type SiteIndex = NullSiteIndex<H>;
22177    fn has_site(&self) -> &[Self::SiteIndex] {
22178        &[]
22179    }
22180    type SiteBinding = NullSiteBinding<H>;
22181    fn has_binding(&self) -> &[Self::SiteBinding] {
22182        &[]
22183    }
22184    fn reversible_strategy(&self) -> bool {
22185        false
22186    }
22187}
22188
22189/// Resolver-absent default `IrreducibleSet<H>`. Implements `Component<H>` with empty
22190/// `member` slice and zero `cardinality`.
22191#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22192pub struct NullIrreducibleSet<H: HostTypes> {
22193    _phantom: core::marker::PhantomData<H>,
22194}
22195impl<H: HostTypes> Default for NullIrreducibleSet<H> {
22196    fn default() -> Self {
22197        Self {
22198            _phantom: core::marker::PhantomData,
22199        }
22200    }
22201}
22202impl<H: HostTypes> crate::bridge::partition::Component<H> for NullIrreducibleSet<H> {
22203    type Datum = NullDatum<H>;
22204    fn member(&self) -> &[Self::Datum] {
22205        &[]
22206    }
22207    fn cardinality(&self) -> u64 {
22208        0
22209    }
22210}
22211impl<H: HostTypes> crate::bridge::partition::IrreducibleSet<H> for NullIrreducibleSet<H> {}
22212
22213/// Resolver-absent default `ReducibleSet<H>`. Implements `Component<H>` with empty
22214/// `member` slice and zero `cardinality`.
22215#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22216pub struct NullReducibleSet<H: HostTypes> {
22217    _phantom: core::marker::PhantomData<H>,
22218}
22219impl<H: HostTypes> Default for NullReducibleSet<H> {
22220    fn default() -> Self {
22221        Self {
22222            _phantom: core::marker::PhantomData,
22223        }
22224    }
22225}
22226impl<H: HostTypes> crate::bridge::partition::Component<H> for NullReducibleSet<H> {
22227    type Datum = NullDatum<H>;
22228    fn member(&self) -> &[Self::Datum] {
22229        &[]
22230    }
22231    fn cardinality(&self) -> u64 {
22232        0
22233    }
22234}
22235impl<H: HostTypes> crate::bridge::partition::ReducibleSet<H> for NullReducibleSet<H> {}
22236
22237/// Resolver-absent default `UnitGroup<H>`. Implements `Component<H>` with empty
22238/// `member` slice and zero `cardinality`.
22239#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22240pub struct NullUnitGroup<H: HostTypes> {
22241    _phantom: core::marker::PhantomData<H>,
22242}
22243impl<H: HostTypes> Default for NullUnitGroup<H> {
22244    fn default() -> Self {
22245        Self {
22246            _phantom: core::marker::PhantomData,
22247        }
22248    }
22249}
22250impl<H: HostTypes> crate::bridge::partition::Component<H> for NullUnitGroup<H> {
22251    type Datum = NullDatum<H>;
22252    fn member(&self) -> &[Self::Datum] {
22253        &[]
22254    }
22255    fn cardinality(&self) -> u64 {
22256        0
22257    }
22258}
22259impl<H: HostTypes> crate::bridge::partition::UnitGroup<H> for NullUnitGroup<H> {}
22260
22261/// Resolver-absent default `Complement<H>`. Implements `Component<H>` plus
22262/// the `exterior_criteria()` accessor returning a reference to an embedded
22263/// `NullTermExpression`.
22264#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22265pub struct NullComplement<H: HostTypes> {
22266    term: NullTermExpression<H>,
22267}
22268impl<H: HostTypes> Default for NullComplement<H> {
22269    fn default() -> Self {
22270        Self {
22271            term: NullTermExpression::default(),
22272        }
22273    }
22274}
22275impl<H: HostTypes> crate::bridge::partition::Component<H> for NullComplement<H> {
22276    type Datum = NullDatum<H>;
22277    fn member(&self) -> &[Self::Datum] {
22278        &[]
22279    }
22280    fn cardinality(&self) -> u64 {
22281        0
22282    }
22283}
22284impl<H: HostTypes> crate::bridge::partition::Complement<H> for NullComplement<H> {
22285    type TermExpression = NullTermExpression<H>;
22286    fn exterior_criteria(&self) -> &Self::TermExpression {
22287        &self.term
22288    }
22289}
22290
22291/// Resolver-absent default `TypeDefinition<H>`. Embeds inline `NullElement`
22292/// for the content_address accessor.
22293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22294pub struct NullTypeDefinition<H: HostTypes> {
22295    element: NullElement<H>,
22296}
22297impl<H: HostTypes> Default for NullTypeDefinition<H> {
22298    fn default() -> Self {
22299        Self {
22300            element: NullElement::default(),
22301        }
22302    }
22303}
22304impl<H: HostTypes> crate::user::type_::TypeDefinition<H> for NullTypeDefinition<H> {
22305    type Element = NullElement<H>;
22306    fn content_address(&self) -> &Self::Element {
22307        &self.element
22308    }
22309}
22310
22311/// Resolver-absent default `Partition<H>`. Embeds inline stubs for every
22312/// sub-trait associated type so `Partition<H>` accessors return references
22313/// to fields rather than to statics. The only meaningful state is the
22314/// `fingerprint`; everything else uses `HostTypes::EMPTY_*` defaults.
22315/// Returned by the three witness trait impls' `left_factor` / `right_factor`
22316/// / `left_summand` / etc. accessors as the resolver-absent value pathway.
22317/// Consumers needing real partition data pair the sibling `PartitionHandle`
22318/// with a `PartitionResolver` instead.
22319#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22320pub struct NullPartition<H: HostTypes> {
22321    irreducibles: NullIrreducibleSet<H>,
22322    reducibles: NullReducibleSet<H>,
22323    units: NullUnitGroup<H>,
22324    exterior: NullComplement<H>,
22325    free_rank: NullFreeRank<H>,
22326    tag_site: NullTagSite<H>,
22327    source_type: NullTypeDefinition<H>,
22328    fingerprint: ContentFingerprint,
22329}
22330
22331impl<H: HostTypes> NullPartition<H> {
22332    /// Construct a NullPartition with the given content fingerprint.
22333    /// All other fields are resolver-absent defaults.
22334    #[inline]
22335    #[must_use]
22336    pub fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
22337        Self {
22338            irreducibles: NullIrreducibleSet::default(),
22339            reducibles: NullReducibleSet::default(),
22340            units: NullUnitGroup::default(),
22341            exterior: NullComplement::default(),
22342            free_rank: NullFreeRank::default(),
22343            tag_site: NullTagSite::default(),
22344            source_type: NullTypeDefinition::default(),
22345            fingerprint,
22346        }
22347    }
22348    /// Returns the content fingerprint identifying which Partition this stub stands in for.
22349    #[inline]
22350    #[must_use]
22351    pub const fn fingerprint(&self) -> ContentFingerprint {
22352        self.fingerprint
22353    }
22354    /// Phase 2 (orphan-closure): absent-value sentinel used by Null stubs
22355    /// in other namespaces to satisfy `&Self::Partition` return borrows.
22356    pub const ABSENT: NullPartition<H> = NullPartition {
22357        irreducibles: NullIrreducibleSet {
22358            _phantom: core::marker::PhantomData,
22359        },
22360        reducibles: NullReducibleSet {
22361            _phantom: core::marker::PhantomData,
22362        },
22363        units: NullUnitGroup {
22364            _phantom: core::marker::PhantomData,
22365        },
22366        exterior: NullComplement {
22367            term: NullTermExpression {
22368                _phantom: core::marker::PhantomData,
22369            },
22370        },
22371        free_rank: NullFreeRank {
22372            _phantom: core::marker::PhantomData,
22373        },
22374        tag_site: NullTagSite {
22375            ancilla: NullSiteIndex {
22376                _phantom: core::marker::PhantomData,
22377            },
22378        },
22379        source_type: NullTypeDefinition {
22380            element: NullElement {
22381                _phantom: core::marker::PhantomData,
22382            },
22383        },
22384        fingerprint: ContentFingerprint::zero(),
22385    };
22386}
22387
22388impl<H: HostTypes> crate::bridge::partition::Partition<H> for NullPartition<H> {
22389    type IrreducibleSet = NullIrreducibleSet<H>;
22390    fn irreducibles(&self) -> &Self::IrreducibleSet {
22391        &self.irreducibles
22392    }
22393    type ReducibleSet = NullReducibleSet<H>;
22394    fn reducibles(&self) -> &Self::ReducibleSet {
22395        &self.reducibles
22396    }
22397    type UnitGroup = NullUnitGroup<H>;
22398    fn units(&self) -> &Self::UnitGroup {
22399        &self.units
22400    }
22401    type Complement = NullComplement<H>;
22402    fn exterior(&self) -> &Self::Complement {
22403        &self.exterior
22404    }
22405    fn density(&self) -> H::Decimal {
22406        H::EMPTY_DECIMAL
22407    }
22408    type TypeDefinition = NullTypeDefinition<H>;
22409    fn source_type(&self) -> &Self::TypeDefinition {
22410        &self.source_type
22411    }
22412    fn witt_length(&self) -> u64 {
22413        0
22414    }
22415    type FreeRank = NullFreeRank<H>;
22416    fn site_budget(&self) -> &Self::FreeRank {
22417        &self.free_rank
22418    }
22419    fn is_exhaustive(&self) -> bool {
22420        true
22421    }
22422    type TagSite = NullTagSite<H>;
22423    fn tag_site_of(&self) -> &Self::TagSite {
22424        &self.tag_site
22425    }
22426    fn product_category_level(&self) -> &H::HostString {
22427        H::EMPTY_HOST_STRING
22428    }
22429}
22430
22431impl<H: HostTypes> crate::bridge::partition::PartitionProduct<H> for PartitionProductWitness {
22432    type Partition = NullPartition<H>;
22433    fn left_factor(&self) -> Self::Partition {
22434        NullPartition::from_fingerprint(self.left_fingerprint)
22435    }
22436    fn right_factor(&self) -> Self::Partition {
22437        NullPartition::from_fingerprint(self.right_fingerprint)
22438    }
22439}
22440
22441impl<H: HostTypes> crate::bridge::partition::PartitionCoproduct<H> for PartitionCoproductWitness {
22442    type Partition = NullPartition<H>;
22443    fn left_summand(&self) -> Self::Partition {
22444        NullPartition::from_fingerprint(self.left_fingerprint)
22445    }
22446    fn right_summand(&self) -> Self::Partition {
22447        NullPartition::from_fingerprint(self.right_fingerprint)
22448    }
22449}
22450
22451impl<H: HostTypes> crate::bridge::partition::CartesianPartitionProduct<H>
22452    for CartesianProductWitness
22453{
22454    type Partition = NullPartition<H>;
22455    fn left_cartesian_factor(&self) -> Self::Partition {
22456        NullPartition::from_fingerprint(self.left_fingerprint)
22457    }
22458    fn right_cartesian_factor(&self) -> Self::Partition {
22459        NullPartition::from_fingerprint(self.right_fingerprint)
22460    }
22461}
22462
22463/// v0.2.1 ergonomics prelude. Re-exports the core symbols downstream crates
22464/// need for the consumer-facing one-liners.
22465/// Ontology-driven: the set of certificate / type / builder symbols is
22466/// sourced from `conformance:PreludeExport` individuals. Adding a new
22467/// symbol to the prelude is an ontology edit, verified against the
22468/// codegen's known-name mapping at build time.
22469pub mod prelude {
22470    pub use super::calibrations;
22471    pub use super::Add;
22472    pub use super::And;
22473    pub use super::BNot;
22474    pub use super::BinaryGroundingMap;
22475    pub use super::BindingEntry;
22476    pub use super::BindingsTable;
22477    pub use super::BornRuleVerification;
22478    pub use super::Calibration;
22479    pub use super::CalibrationError;
22480    pub use super::CanonicalTimingPolicy;
22481    pub use super::Certificate;
22482    pub use super::Certified;
22483    pub use super::ChainAuditTrail;
22484    pub use super::CompileTime;
22485    pub use super::CompileUnit;
22486    pub use super::CompileUnitBuilder;
22487    pub use super::CompletenessAuditTrail;
22488    pub use super::CompletenessCertificate;
22489    pub use super::ConstrainedTypeInput;
22490    pub use super::ContentAddress;
22491    pub use super::ContentFingerprint;
22492    pub use super::Datum;
22493    pub use super::DigestGroundingMap;
22494    pub use super::Embed;
22495    pub use super::FragmentMarker;
22496    pub use super::GenericImpossibilityWitness;
22497    pub use super::GeodesicCertificate;
22498    pub use super::GeodesicEvidenceBundle;
22499    pub use super::Grounded;
22500    pub use super::GroundedCoord;
22501    pub use super::GroundedShape;
22502    pub use super::GroundedTuple;
22503    pub use super::GroundedValue;
22504    pub use super::Grounding;
22505    pub use super::GroundingCertificate;
22506    pub use super::GroundingExt;
22507    pub use super::GroundingMapKind;
22508    pub use super::GroundingProgram;
22509    pub use super::Hasher;
22510    pub use super::ImpossibilityWitnessKind;
22511    pub use super::InhabitanceCertificate;
22512    pub use super::InhabitanceImpossibilityWitness;
22513    pub use super::IntegerGroundingMap;
22514    pub use super::Invertible;
22515    pub use super::InvolutionCertificate;
22516    pub use super::IsometryCertificate;
22517    pub use super::JsonGroundingMap;
22518    pub use super::LandauerBudget;
22519    pub use super::LiftChainCertificate;
22520    pub use super::MeasurementCertificate;
22521    pub use super::Mul;
22522    pub use super::Nanos;
22523    pub use super::Neg;
22524    pub use super::OntologyTarget;
22525    pub use super::Or;
22526    pub use super::PipelineFailure;
22527    pub use super::PreservesMetric;
22528    pub use super::PreservesStructure;
22529    pub use super::RingOp;
22530    pub use super::Runtime;
22531    pub use super::ShapeViolation;
22532    pub use super::Sub;
22533    pub use super::Succ;
22534    pub use super::Term;
22535    pub use super::TermArena;
22536    pub use super::TimingPolicy;
22537    pub use super::Total;
22538    pub use super::TransformCertificate;
22539    pub use super::Triad;
22540    pub use super::UnaryRingOp;
22541    pub use super::UorTime;
22542    pub use super::Utf8GroundingMap;
22543    pub use super::ValidLevelEmbedding;
22544    pub use super::Validated;
22545    pub use super::ValidationPhase;
22546    pub use super::Xor;
22547    pub use super::W16;
22548    pub use super::W8;
22549    pub use crate::pipeline::empty_bindings_table;
22550    pub use crate::pipeline::{
22551        validate_constrained_type, validate_constrained_type_const, ConstrainedTypeShape,
22552        ConstraintRef, FragmentKind,
22553    };
22554    pub use crate::{DecimalTranscendental, DefaultHostTypes, HostTypes, WittLevel};
22555}