Skip to main content

uor_foundation/
enforcement.rs

1// @generated by uor-crate from uor-ontology — do not edit manually
2
3//! Declarative enforcement types.
4//!
5//! This module contains the opaque witness types, declarative builders,
6//! the Term AST, and the v0.2.1 ergonomics surface (sealed `Grounded<T>`,
7//! the `Certify` trait, `PipelineFailure`, ring-op phantom wrappers,
8//! fragment markers, dispatch tables, and the `prelude` module).
9//!
10//! # Layers
11//!
12//! - **Layer 1** \[Opaque Witnesses\]: `Datum`, `Validated<T>`, `Derivation`,
13//!   `FreeRank` \[private fields, no public constructors\]
14//! - **Layer 2** \[Declarative Builders\]: `CompileUnitBuilder`,
15//!   `EffectDeclarationBuilder`, etc. \[produce `Validated<T>` on success\]
16//! - **Term AST**: `Term`, `TermArena`, `Binding`, `Assertion`, etc.
17//! - **v0.2.1 Ergonomics**: `OntologyTarget`, `GroundedShape`, `Grounded<T>`,
18//!   `Certify`, `PipelineFailure`, `RingOp<L>`, fragment markers,
19//!   `INHABITANCE_DISPATCH_TABLE`, and the `prelude` module.
20
21use crate::{
22    DecimalTranscendental, HostTypes, MetricAxis, PrimitiveOp, VerificationDomain, ViolationKind,
23    WittLevel,
24};
25use core::marker::PhantomData;
26
27/// Private sealed module preventing downstream implementations.
28/// Only `GroundedCoord` and `GroundedTuple<N>` implement `Sealed`.
29mod sealed {
30    /// Sealed trait. Not publicly implementable because this module is private.
31    pub trait Sealed {}
32    impl Sealed for super::GroundedCoord {}
33    impl<const N: usize> Sealed for super::GroundedTuple<N> {}
34}
35
36/// Internal level-tagged ring value. Width determined by the Witt level.
37/// Variants are emitted parametrically from `schema:WittLevel` individuals
38/// in the ontology; adding a new level to the ontology regenerates this enum.
39/// Not publicly constructible \[sealed within the crate\].
40#[derive(Debug, Clone, PartialEq, Eq)]
41#[allow(clippy::large_enum_variant, dead_code)]
42pub(crate) enum DatumInner {
43    /// W8: 8-bit ring Z/(2^8)Z.
44    W8([u8; 1]),
45    /// W16: 16-bit ring Z/(2^16)Z.
46    W16([u8; 2]),
47    /// W24: 24-bit ring Z/(2^24)Z.
48    W24([u8; 3]),
49    /// W32: 32-bit ring Z/(2^32)Z.
50    W32([u8; 4]),
51    /// W40: 40-bit ring Z/(2^40)Z.
52    W40([u8; 5]),
53    /// W48: 48-bit ring Z/(2^48)Z.
54    W48([u8; 6]),
55    /// W56: 56-bit ring Z/(2^56)Z.
56    W56([u8; 7]),
57    /// W64: 64-bit ring Z/(2^64)Z.
58    W64([u8; 8]),
59    /// W72: 72-bit ring Z/(2^72)Z.
60    W72([u8; 9]),
61    /// W80: 80-bit ring Z/(2^80)Z.
62    W80([u8; 10]),
63    /// W88: 88-bit ring Z/(2^88)Z.
64    W88([u8; 11]),
65    /// W96: 96-bit ring Z/(2^96)Z.
66    W96([u8; 12]),
67    /// W104: 104-bit ring Z/(2^104)Z.
68    W104([u8; 13]),
69    /// W112: 112-bit ring Z/(2^112)Z.
70    W112([u8; 14]),
71    /// W120: 120-bit ring Z/(2^120)Z.
72    W120([u8; 15]),
73    /// W128: 128-bit ring Z/(2^128)Z.
74    W128([u8; 16]),
75}
76
77/// A ring element at its minting Witt level.
78/// Cannot be constructed outside the `uor_foundation` crate.
79/// The only way to obtain a `Datum` is through reduction evaluation
80/// or the two-phase minting boundary (`validate_and_mint_coord` /
81/// `validate_and_mint_tuple`).
82/// # Examples
83/// ```no_run
84/// // A Datum is produced by reduction evaluation or the minting boundary —
85/// // you never construct one directly.
86/// fn inspect_datum(d: &uor_foundation::enforcement::Datum) {
87///     // Query its Witt level (W8 = 8-bit, W32 = 32-bit, etc.)
88///     let _level = d.level();
89///     // Datum width is determined by its level:
90///     //   W8 → 1 byte,  W16 → 2 bytes,  W24 → 3 bytes,  W32 → 4 bytes.
91///     let _bytes = d.as_bytes();
92/// }
93/// ```
94#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct Datum {
96    /// Level-tagged ring value \[sealed\].
97    inner: DatumInner,
98}
99
100impl Datum {
101    /// Returns the Witt level at which this datum was minted.
102    #[inline]
103    #[must_use]
104    pub const fn level(&self) -> WittLevel {
105        match self.inner {
106            DatumInner::W8(_) => WittLevel::W8,
107            DatumInner::W16(_) => WittLevel::W16,
108            DatumInner::W24(_) => WittLevel::new(24),
109            DatumInner::W32(_) => WittLevel::new(32),
110            DatumInner::W40(_) => WittLevel::new(40),
111            DatumInner::W48(_) => WittLevel::new(48),
112            DatumInner::W56(_) => WittLevel::new(56),
113            DatumInner::W64(_) => WittLevel::new(64),
114            DatumInner::W72(_) => WittLevel::new(72),
115            DatumInner::W80(_) => WittLevel::new(80),
116            DatumInner::W88(_) => WittLevel::new(88),
117            DatumInner::W96(_) => WittLevel::new(96),
118            DatumInner::W104(_) => WittLevel::new(104),
119            DatumInner::W112(_) => WittLevel::new(112),
120            DatumInner::W120(_) => WittLevel::new(120),
121            DatumInner::W128(_) => WittLevel::new(128),
122        }
123    }
124
125    /// Returns the raw byte representation of this datum.
126    #[inline]
127    #[must_use]
128    pub fn as_bytes(&self) -> &[u8] {
129        match &self.inner {
130            DatumInner::W8(b) => b,
131            DatumInner::W16(b) => b,
132            DatumInner::W24(b) => b,
133            DatumInner::W32(b) => b,
134            DatumInner::W40(b) => b,
135            DatumInner::W48(b) => b,
136            DatumInner::W56(b) => b,
137            DatumInner::W64(b) => b,
138            DatumInner::W72(b) => b,
139            DatumInner::W80(b) => b,
140            DatumInner::W88(b) => b,
141            DatumInner::W96(b) => b,
142            DatumInner::W104(b) => b,
143            DatumInner::W112(b) => b,
144            DatumInner::W120(b) => b,
145            DatumInner::W128(b) => b,
146        }
147    }
148}
149
150/// Internal level-tagged coordinate value for grounding intermediates.
151/// Variant set mirrors `DatumInner`: one per `schema:WittLevel`.
152#[derive(Debug, Clone, PartialEq, Eq)]
153#[allow(clippy::large_enum_variant, dead_code)]
154pub(crate) enum GroundedCoordInner {
155    /// W8: 8-bit coordinate.
156    W8([u8; 1]),
157    /// W16: 16-bit coordinate.
158    W16([u8; 2]),
159    /// W24: 24-bit coordinate.
160    W24([u8; 3]),
161    /// W32: 32-bit coordinate.
162    W32([u8; 4]),
163    /// W40: 40-bit coordinate.
164    W40([u8; 5]),
165    /// W48: 48-bit coordinate.
166    W48([u8; 6]),
167    /// W56: 56-bit coordinate.
168    W56([u8; 7]),
169    /// W64: 64-bit coordinate.
170    W64([u8; 8]),
171    /// W72: 72-bit coordinate.
172    W72([u8; 9]),
173    /// W80: 80-bit coordinate.
174    W80([u8; 10]),
175    /// W88: 88-bit coordinate.
176    W88([u8; 11]),
177    /// W96: 96-bit coordinate.
178    W96([u8; 12]),
179    /// W104: 104-bit coordinate.
180    W104([u8; 13]),
181    /// W112: 112-bit coordinate.
182    W112([u8; 14]),
183    /// W120: 120-bit coordinate.
184    W120([u8; 15]),
185    /// W128: 128-bit coordinate.
186    W128([u8; 16]),
187}
188
189/// A single grounded coordinate value.
190/// Not a `Datum` \[this is the narrow intermediate that a `Grounding`
191/// impl produces\]. The foundation validates and mints it into a `Datum`.
192/// Uses the same closed level-tagged family as `Datum`, ensuring that
193/// coordinate width matches the target Witt level.
194/// # Examples
195/// ```rust
196/// use uor_foundation::enforcement::GroundedCoord;
197///
198/// // W8: 8-bit ring Z/256Z — lightweight, exhaustive-verification baseline
199/// let byte_coord = GroundedCoord::w8(42);
200///
201/// // W16: 16-bit ring Z/65536Z — audio samples, small indices
202/// let short_coord = GroundedCoord::w16(1000);
203///
204/// // W32: 32-bit ring Z/2^32Z — pixel data, general-purpose integers
205/// let word_coord = GroundedCoord::w32(70_000);
206/// ```
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub struct GroundedCoord {
209    /// Level-tagged coordinate bytes.
210    pub(crate) inner: GroundedCoordInner,
211}
212
213impl GroundedCoord {
214    /// Construct a W8 coordinate from a `u8` value (little-endian).
215    #[inline]
216    #[must_use]
217    pub const fn w8(value: u8) -> Self {
218        Self {
219            inner: GroundedCoordInner::W8(value.to_le_bytes()),
220        }
221    }
222
223    /// Construct a W16 coordinate from a `u16` value (little-endian).
224    #[inline]
225    #[must_use]
226    pub const fn w16(value: u16) -> Self {
227        Self {
228            inner: GroundedCoordInner::W16(value.to_le_bytes()),
229        }
230    }
231
232    /// Construct a W24 coordinate from a `u32` value (little-endian).
233    #[inline]
234    #[must_use]
235    pub const fn w24(value: u32) -> Self {
236        let full = value.to_le_bytes();
237        let mut out = [0u8; 3];
238        let mut i = 0;
239        while i < 3 {
240            out[i] = full[i];
241            i += 1;
242        }
243        Self {
244            inner: GroundedCoordInner::W24(out),
245        }
246    }
247
248    /// Construct a W32 coordinate from a `u32` value (little-endian).
249    #[inline]
250    #[must_use]
251    pub const fn w32(value: u32) -> Self {
252        Self {
253            inner: GroundedCoordInner::W32(value.to_le_bytes()),
254        }
255    }
256
257    /// Construct a W40 coordinate from a `u64` value (little-endian).
258    #[inline]
259    #[must_use]
260    pub const fn w40(value: u64) -> Self {
261        let full = value.to_le_bytes();
262        let mut out = [0u8; 5];
263        let mut i = 0;
264        while i < 5 {
265            out[i] = full[i];
266            i += 1;
267        }
268        Self {
269            inner: GroundedCoordInner::W40(out),
270        }
271    }
272
273    /// Construct a W48 coordinate from a `u64` value (little-endian).
274    #[inline]
275    #[must_use]
276    pub const fn w48(value: u64) -> Self {
277        let full = value.to_le_bytes();
278        let mut out = [0u8; 6];
279        let mut i = 0;
280        while i < 6 {
281            out[i] = full[i];
282            i += 1;
283        }
284        Self {
285            inner: GroundedCoordInner::W48(out),
286        }
287    }
288
289    /// Construct a W56 coordinate from a `u64` value (little-endian).
290    #[inline]
291    #[must_use]
292    pub const fn w56(value: u64) -> Self {
293        let full = value.to_le_bytes();
294        let mut out = [0u8; 7];
295        let mut i = 0;
296        while i < 7 {
297            out[i] = full[i];
298            i += 1;
299        }
300        Self {
301            inner: GroundedCoordInner::W56(out),
302        }
303    }
304
305    /// Construct a W64 coordinate from a `u64` value (little-endian).
306    #[inline]
307    #[must_use]
308    pub const fn w64(value: u64) -> Self {
309        Self {
310            inner: GroundedCoordInner::W64(value.to_le_bytes()),
311        }
312    }
313
314    /// Construct a W72 coordinate from a `u128` value (little-endian).
315    #[inline]
316    #[must_use]
317    pub const fn w72(value: u128) -> Self {
318        let full = value.to_le_bytes();
319        let mut out = [0u8; 9];
320        let mut i = 0;
321        while i < 9 {
322            out[i] = full[i];
323            i += 1;
324        }
325        Self {
326            inner: GroundedCoordInner::W72(out),
327        }
328    }
329
330    /// Construct a W80 coordinate from a `u128` value (little-endian).
331    #[inline]
332    #[must_use]
333    pub const fn w80(value: u128) -> Self {
334        let full = value.to_le_bytes();
335        let mut out = [0u8; 10];
336        let mut i = 0;
337        while i < 10 {
338            out[i] = full[i];
339            i += 1;
340        }
341        Self {
342            inner: GroundedCoordInner::W80(out),
343        }
344    }
345
346    /// Construct a W88 coordinate from a `u128` value (little-endian).
347    #[inline]
348    #[must_use]
349    pub const fn w88(value: u128) -> Self {
350        let full = value.to_le_bytes();
351        let mut out = [0u8; 11];
352        let mut i = 0;
353        while i < 11 {
354            out[i] = full[i];
355            i += 1;
356        }
357        Self {
358            inner: GroundedCoordInner::W88(out),
359        }
360    }
361
362    /// Construct a W96 coordinate from a `u128` value (little-endian).
363    #[inline]
364    #[must_use]
365    pub const fn w96(value: u128) -> Self {
366        let full = value.to_le_bytes();
367        let mut out = [0u8; 12];
368        let mut i = 0;
369        while i < 12 {
370            out[i] = full[i];
371            i += 1;
372        }
373        Self {
374            inner: GroundedCoordInner::W96(out),
375        }
376    }
377
378    /// Construct a W104 coordinate from a `u128` value (little-endian).
379    #[inline]
380    #[must_use]
381    pub const fn w104(value: u128) -> Self {
382        let full = value.to_le_bytes();
383        let mut out = [0u8; 13];
384        let mut i = 0;
385        while i < 13 {
386            out[i] = full[i];
387            i += 1;
388        }
389        Self {
390            inner: GroundedCoordInner::W104(out),
391        }
392    }
393
394    /// Construct a W112 coordinate from a `u128` value (little-endian).
395    #[inline]
396    #[must_use]
397    pub const fn w112(value: u128) -> Self {
398        let full = value.to_le_bytes();
399        let mut out = [0u8; 14];
400        let mut i = 0;
401        while i < 14 {
402            out[i] = full[i];
403            i += 1;
404        }
405        Self {
406            inner: GroundedCoordInner::W112(out),
407        }
408    }
409
410    /// Construct a W120 coordinate from a `u128` value (little-endian).
411    #[inline]
412    #[must_use]
413    pub const fn w120(value: u128) -> Self {
414        let full = value.to_le_bytes();
415        let mut out = [0u8; 15];
416        let mut i = 0;
417        while i < 15 {
418            out[i] = full[i];
419            i += 1;
420        }
421        Self {
422            inner: GroundedCoordInner::W120(out),
423        }
424    }
425
426    /// Construct a W128 coordinate from a `u128` value (little-endian).
427    #[inline]
428    #[must_use]
429    pub const fn w128(value: u128) -> Self {
430        let full = value.to_le_bytes();
431        let mut out = [0u8; 16];
432        let mut i = 0;
433        while i < 16 {
434            out[i] = full[i];
435            i += 1;
436        }
437        Self {
438            inner: GroundedCoordInner::W128(out),
439        }
440    }
441}
442
443/// A grounded tuple: a fixed-size array of `GroundedCoord` values.
444/// Represents a structured type (e.g., the 8 coordinates of an E8
445/// lattice point). Not a `Datum` until the foundation validates and
446/// mints it. Stack-resident, no heap allocation.
447/// # Examples
448/// ```rust
449/// use uor_foundation::enforcement::{GroundedCoord, GroundedTuple};
450///
451/// // A 2D pixel: (red, green) at W8 (8-bit per channel)
452/// let pixel = GroundedTuple::new([
453///     GroundedCoord::w8(255), // red channel
454///     GroundedCoord::w8(128), // green channel
455/// ]);
456///
457/// // An E8 lattice point: 8 coordinates at W8
458/// let lattice_point = GroundedTuple::new([
459///     GroundedCoord::w8(2), GroundedCoord::w8(0),
460///     GroundedCoord::w8(0), GroundedCoord::w8(0),
461///     GroundedCoord::w8(0), GroundedCoord::w8(0),
462///     GroundedCoord::w8(0), GroundedCoord::w8(0),
463/// ]);
464/// ```
465#[derive(Debug, Clone, PartialEq, Eq)]
466pub struct GroundedTuple<const N: usize> {
467    /// The coordinate array.
468    pub(crate) coords: [GroundedCoord; N],
469}
470
471impl<const N: usize> GroundedTuple<N> {
472    /// Construct a tuple from a fixed-size array of coordinates.
473    #[inline]
474    #[must_use]
475    pub const fn new(coords: [GroundedCoord; N]) -> Self {
476        Self { coords }
477    }
478}
479
480/// Sealed marker trait for grounded intermediates.
481/// Implemented only for `GroundedCoord` and `GroundedTuple<N>`.
482/// Prism code cannot implement this \[the sealed module pattern
483/// prevents it\].
484pub trait GroundedValue: sealed::Sealed {}
485impl GroundedValue for GroundedCoord {}
486impl<const N: usize> GroundedValue for GroundedTuple<N> {}
487
488/// Target §3: sealed marker trait shared by all morphism kinds.
489/// `GroundingMapKind` (inbound) and `ProjectionMapKind` (outbound) both
490/// extend this trait; the four structural markers (`Total`, `Invertible`,
491/// `PreservesStructure`, `PreservesMetric`) are bounded on `MorphismKind`.
492pub trait MorphismKind: morphism_kind_sealed::Sealed {
493    /// The ontology IRI of this morphism kind.
494    const ONTOLOGY_IRI: &'static str;
495}
496
497/// v0.2.2 W4: sealed marker trait for the kind of a `Grounding` map.
498/// Implemented by exactly the `morphism:GroundingMap` individuals declared in
499/// the ontology; downstream cannot extend the kind set.
500pub trait GroundingMapKind: MorphismKind + grounding_map_kind_sealed::Sealed {}
501
502/// Target §3: sealed marker trait for the kind of a `Sinking` projection.
503/// Implemented by exactly the `morphism:ProjectionMap` individuals declared
504/// in the ontology; downstream cannot extend the kind set.
505pub trait ProjectionMapKind: MorphismKind + projection_map_kind_sealed::Sealed {}
506
507/// v0.2.2 W4: kinds whose image is total over the input domain
508/// (every input maps successfully).
509pub trait Total: MorphismKind {}
510
511/// v0.2.2 W4: kinds whose map is injective and admits an inverse on its image.
512pub trait Invertible: MorphismKind {}
513
514/// v0.2.2 W4: kinds whose map preserves the algebraic structure of the
515/// source domain (homomorphism-like).
516pub trait PreservesStructure: MorphismKind {}
517
518/// v0.2.2 W4: kinds whose map preserves the metric of the source domain
519/// (isometry-like).
520pub trait PreservesMetric: MorphismKind {}
521
522/// v0.2.2 W4: kind for raw byte ingestion. Total and invertible; preserves bit identity only.
523#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
524pub struct BinaryGroundingMap;
525
526/// v0.2.2 W4: kind for one-way digest functions (e.g., SHA-256). Total but not invertible; preserves no structure.
527#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
528pub struct DigestGroundingMap;
529
530/// v0.2.2 W4: kind for integer surface symbols. Total, invertible, structure-preserving.
531#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
532pub struct IntegerGroundingMap;
533
534/// v0.2.2 W4: kind for JSON host strings. Invertible on its image, structure-preserving.
535#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
536pub struct JsonGroundingMap;
537
538/// v0.2.2 W4: kind for UTF-8 host strings. Invertible on its image, structure-preserving.
539#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
540pub struct Utf8GroundingMap;
541
542/// Target §3: kind for raw byte projections. Total and invertible; preserves bit identity only.
543#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
544pub struct BinaryProjectionMap;
545
546/// Target §3: kind for fixed-size digests projected outward. Total but not invertible; preserves no structure.
547#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
548pub struct DigestProjectionMap;
549
550/// Target §3: kind for integer surface symbols projected outward. Invertible, structure-preserving.
551#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
552pub struct IntegerProjectionMap;
553
554/// Target §3: kind for JSON host strings projected outward. Invertible, structure-preserving.
555#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
556pub struct JsonProjectionMap;
557
558/// Target §3: kind for UTF-8 host strings projected outward. Invertible, structure-preserving.
559#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
560pub struct Utf8ProjectionMap;
561
562mod morphism_kind_sealed {
563    /// Private supertrait for MorphismKind. Not implementable outside this crate.
564    pub trait Sealed {}
565    impl Sealed for super::BinaryGroundingMap {}
566    impl Sealed for super::DigestGroundingMap {}
567    impl Sealed for super::IntegerGroundingMap {}
568    impl Sealed for super::JsonGroundingMap {}
569    impl Sealed for super::Utf8GroundingMap {}
570    impl Sealed for super::BinaryProjectionMap {}
571    impl Sealed for super::DigestProjectionMap {}
572    impl Sealed for super::IntegerProjectionMap {}
573    impl Sealed for super::JsonProjectionMap {}
574    impl Sealed for super::Utf8ProjectionMap {}
575}
576
577mod grounding_map_kind_sealed {
578    /// Private supertrait. Not implementable outside this crate.
579    pub trait Sealed {}
580    impl Sealed for super::BinaryGroundingMap {}
581    impl Sealed for super::DigestGroundingMap {}
582    impl Sealed for super::IntegerGroundingMap {}
583    impl Sealed for super::JsonGroundingMap {}
584    impl Sealed for super::Utf8GroundingMap {}
585}
586
587mod projection_map_kind_sealed {
588    /// Private supertrait. Not implementable outside this crate.
589    pub trait Sealed {}
590    impl Sealed for super::BinaryProjectionMap {}
591    impl Sealed for super::DigestProjectionMap {}
592    impl Sealed for super::IntegerProjectionMap {}
593    impl Sealed for super::JsonProjectionMap {}
594    impl Sealed for super::Utf8ProjectionMap {}
595}
596
597impl MorphismKind for BinaryGroundingMap {
598    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/BinaryGroundingMap";
599}
600
601impl MorphismKind for DigestGroundingMap {
602    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/DigestGroundingMap";
603}
604
605impl MorphismKind for IntegerGroundingMap {
606    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/IntegerGroundingMap";
607}
608
609impl MorphismKind for JsonGroundingMap {
610    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/JsonGroundingMap";
611}
612
613impl MorphismKind for Utf8GroundingMap {
614    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/Utf8GroundingMap";
615}
616
617impl MorphismKind for BinaryProjectionMap {
618    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/BinaryProjectionMap";
619}
620
621impl MorphismKind for DigestProjectionMap {
622    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/DigestProjectionMap";
623}
624
625impl MorphismKind for IntegerProjectionMap {
626    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/IntegerProjectionMap";
627}
628
629impl MorphismKind for JsonProjectionMap {
630    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/JsonProjectionMap";
631}
632
633impl MorphismKind for Utf8ProjectionMap {
634    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/Utf8ProjectionMap";
635}
636
637impl GroundingMapKind for BinaryGroundingMap {}
638impl GroundingMapKind for DigestGroundingMap {}
639impl GroundingMapKind for IntegerGroundingMap {}
640impl GroundingMapKind for JsonGroundingMap {}
641impl GroundingMapKind for Utf8GroundingMap {}
642
643impl ProjectionMapKind for BinaryProjectionMap {}
644impl ProjectionMapKind for DigestProjectionMap {}
645impl ProjectionMapKind for IntegerProjectionMap {}
646impl ProjectionMapKind for JsonProjectionMap {}
647impl ProjectionMapKind for Utf8ProjectionMap {}
648
649impl Total for IntegerGroundingMap {}
650impl Invertible for IntegerGroundingMap {}
651impl PreservesStructure for IntegerGroundingMap {}
652
653impl Invertible for Utf8GroundingMap {}
654impl PreservesStructure for Utf8GroundingMap {}
655
656impl Invertible for JsonGroundingMap {}
657impl PreservesStructure for JsonGroundingMap {}
658
659impl Total for DigestGroundingMap {}
660
661impl Total for BinaryGroundingMap {}
662impl Invertible for BinaryGroundingMap {}
663
664impl Invertible for IntegerProjectionMap {}
665impl PreservesStructure for IntegerProjectionMap {}
666
667impl Invertible for Utf8ProjectionMap {}
668impl PreservesStructure for Utf8ProjectionMap {}
669
670impl Invertible for JsonProjectionMap {}
671impl PreservesStructure for JsonProjectionMap {}
672
673impl Total for DigestProjectionMap {}
674
675impl Total for BinaryProjectionMap {}
676impl Invertible for BinaryProjectionMap {}
677
678/// Open trait for boundary crossing: external data to grounded intermediate.
679/// The foundation validates the returned value against the declared
680/// `GroundingShape` and mints it into a `Datum` if conformant.
681/// v0.2.2 W4 adds the `Map: GroundingMapKind` associated type — every impl
682/// must declare what *kind* of grounding map it is. Foundation operations
683/// that require structure preservation gate on `<G as Grounding>::Map: PreservesStructure`,
684/// and a digest-style impl is rejected at the call site.
685/// # Examples
686/// ```no_run
687/// use uor_foundation::enforcement::{
688///     Grounding, GroundedCoord, GroundingProgram, BinaryGroundingMap, combinators,
689/// };
690///
691/// /// Byte-passthrough grounding: reads the first byte of input as a W8 Datum.
692/// struct PassthroughGrounding;
693///
694/// impl Grounding for PassthroughGrounding {
695///     type Output = GroundedCoord;
696///     type Map = BinaryGroundingMap;
697///
698///     // Phase K: provide the combinator program; the type system verifies
699///     // at compile time that its marker tuple matches Self::Map via
700///     // GroundingProgram::from_primitive's MarkersImpliedBy<Map> bound.
701///     fn program(&self) -> GroundingProgram<GroundedCoord, BinaryGroundingMap> {
702///         GroundingProgram::from_primitive(combinators::read_bytes::<GroundedCoord>())
703///     }
704///     // Foundation supplies `ground()` via the sealed `GroundingExt`
705///     // extension trait — downstream implementers provide only `program()`.
706/// }
707/// ```
708pub trait Grounding {
709    /// The grounded intermediate type. Bounded by `GroundedValue`,
710    /// which is sealed \[only `GroundedCoord` and `GroundedTuple<N>`
711    /// are permitted\].
712    type Output: GroundedValue;
713
714    /// v0.2.2 W4: the kind of grounding map this impl is. Sealed to the
715    /// set of `morphism:GroundingMap` individuals declared in the
716    /// ontology. Every impl must declare the kind explicitly; if no kind
717    /// applies, use `BinaryGroundingMap` (the most permissive — total +
718    /// invertible, no structure preservation).
719    type Map: GroundingMapKind;
720
721    /// Phase K / W4 closure (target §4.3 + §9 criterion 1): the combinator
722    /// program that decomposes this grounding. The program's `Map` parameter
723    /// equals the impl's `Map` associated type, so the kind discriminator is
724    /// mechanically verifiable from the combinator decomposition — not a
725    /// promise. This is the only required method; `ground` is foundation-
726    /// supplied via `GroundingExt`.
727    fn program(&self) -> GroundingProgram<Self::Output, Self::Map>;
728}
729
730/// W4 closure (target §4.3 + §9 criterion 1): foundation-authored
731/// extension trait that supplies `ground()` for every `Grounding`
732/// impl. Downstream implementers provide only `program()`;
733/// the foundation runs it via the blanket `impl<G: Grounding>`
734/// below. The sealed supertrait prevents downstream from
735/// implementing `GroundingExt` directly — there is no second path.
736mod grounding_ext_sealed {
737    /// Private supertrait. Not implementable outside this crate.
738    pub trait Sealed {}
739    impl<G: super::Grounding> Sealed for G {}
740}
741
742/// Crate-internal bridge from `GroundingProgram` to `Option<Out>`.
743/// Blanket-impl'd for the two `GroundedValue` members
744/// (`GroundedCoord` and `GroundedTuple<N>`) so the `GroundingExt`
745/// blanket compiles for any output in the closed set.
746pub trait GroundingProgramRun<Out> {
747    /// Run the program on external bytes.
748    fn run_program(&self, external: &[u8]) -> Option<Out>;
749}
750
751impl<Map: GroundingMapKind> GroundingProgramRun<GroundedCoord>
752    for GroundingProgram<GroundedCoord, Map>
753{
754    #[inline]
755    fn run_program(&self, external: &[u8]) -> Option<GroundedCoord> {
756        self.run(external)
757    }
758}
759
760impl<const N: usize, Map: GroundingMapKind> GroundingProgramRun<GroundedTuple<N>>
761    for GroundingProgram<GroundedTuple<N>, Map>
762{
763    #[inline]
764    fn run_program(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
765        self.run(external)
766    }
767}
768
769/// Foundation-supplied `ground()` for every `Grounding` impl.
770/// The blanket `impl<G: Grounding> GroundingExt for G` below
771/// routes every call of `.ground(bytes)` through
772/// `self.program().run_program(bytes)`. Downstream cannot
773/// override this path: `GroundingExt` has a sealed supertrait
774/// and downstream cannot impl `GroundingExt` directly.
775pub trait GroundingExt: Grounding + grounding_ext_sealed::Sealed {
776    /// Map external bytes into a grounded value via this impl's combinator program.
777    /// Returns `None` when the combinator chain rejects the input (e.g. empty slice
778    /// for `ReadBytes`, malformed UTF-8 for `DecodeUtf8`).
779    fn ground(&self, external: &[u8]) -> Option<Self::Output>;
780}
781
782impl<G: Grounding> GroundingExt for G
783where
784    GroundingProgram<G::Output, G::Map>: GroundingProgramRun<G::Output>,
785{
786    #[inline]
787    fn ground(&self, external: &[u8]) -> Option<Self::Output> {
788        self.program().run_program(external)
789    }
790}
791
792/// Target §3 + §4.6: the foundation-owned operational contract for outbound
793/// boundary crossings. Dual of `Grounding`.
794/// A `Sinking` impl projects a `Grounded<Source>` value to a host-side
795/// `Output` through a specific `ProjectionMap` kind. The `&Grounded<Source>`
796/// input is structurally unforgeable (sealed per §2) — no raw data can be
797/// laundered through this contract. Downstream authors implement `Sinking`
798/// for their projection types; the foundation guarantees the input pedigree.
799/// # Examples
800/// ```no_run
801/// use uor_foundation::enforcement::{
802///     Grounded, Sinking, Utf8ProjectionMap, ConstrainedTypeInput,
803/// };
804///
805/// struct MyJsonSink;
806///
807/// impl Sinking for MyJsonSink {
808///     type Source = ConstrainedTypeInput;
809///     type ProjectionMap = Utf8ProjectionMap;
810///     type Output = String;
811///
812///     fn project(&self, grounded: &Grounded<ConstrainedTypeInput>) -> String {
813///         format!("{:?}", grounded.unit_address())
814///     }
815/// }
816/// ```
817pub trait Sinking {
818    /// The ring-side shape `T` carried by the `Grounded<T>` being projected.
819    /// Sealed via `GroundedShape` — downstream cannot forge an admissible Source.
820    type Source: GroundedShape;
821
822    /// The ontology-declared ProjectionMap kind this impl serves. Sealed to
823    /// the closed set of `morphism:ProjectionMap` individuals.
824    type ProjectionMap: ProjectionMapKind;
825
826    /// The host-side output type of this projection. Intentionally generic —
827    /// downstream chooses `String`, `Vec<u8>`, `serde_json::Value`, or any
828    /// host-appropriate carrier.
829    type Output;
830
831    /// Project a grounded ring value to the host output. The `&Grounded<Source>`
832    /// input is unforgeable (Grounded is sealed per §2) — no raw data can be
833    /// laundered through this contract.
834    fn project(&self, grounded: &Grounded<Self::Source>) -> Self::Output;
835}
836
837/// Target §4.6: extension trait tying `EmitEffect<H>` (ontology-declarative)
838/// to `Sinking` (Rust-operational). Emit-effect implementations carry a
839/// specific `Sinking` impl; the emit operation threads a sealed
840/// `Grounded<Source>` through the projection.
841pub trait EmitThrough<H: crate::HostTypes>: crate::bridge::boundary::EmitEffect<H> {
842    /// The `Sinking` implementation this emit-effect routes through.
843    type Sinking: Sinking;
844
845    /// Emit a grounded value through this effect's bound `Sinking`. The
846    /// input type is the sealed `Grounded<Source>` of the bound `Sinking`;
847    /// nothing else is admissible.
848    fn emit(
849        &self,
850        grounded: &Grounded<<Self::Sinking as Sinking>::Source>,
851    ) -> <Self::Sinking as Sinking>::Output;
852}
853
854/// v0.2.2 W13: sealed marker trait for the validation phase at which a
855/// `Validated<T, Phase>` was witnessed. Implemented only by `CompileTime`
856/// and `Runtime`; downstream cannot extend.
857pub trait ValidationPhase: validation_phase_sealed::Sealed {}
858
859mod validation_phase_sealed {
860    /// Private supertrait. Not implementable outside this crate.
861    pub trait Sealed {}
862    impl Sealed for super::CompileTime {}
863    impl Sealed for super::Runtime {}
864}
865
866/// v0.2.2 W13: marker for compile-time validated witnesses produced by
867/// `validate_const()` and usable in `const` contexts. Convertible to
868/// `Validated<T, Runtime>` via `From`.
869#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
870pub struct CompileTime;
871impl ValidationPhase for CompileTime {}
872
873/// v0.2.2 W13: marker for runtime-validated witnesses produced by
874/// `validate()`. The default phase of `Validated<T>` so v0.2.1 call
875/// sites continue to compile.
876#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
877pub struct Runtime;
878impl ValidationPhase for Runtime {}
879
880/// Proof that a value was produced by the conformance checker,
881/// not fabricated by Prism code.
882/// The inner value and `_sealed` field are private, so `Validated<T>`
883/// can only be constructed within this crate.
884/// v0.2.2 W13: parameterized by a `Phase: ValidationPhase` discriminator.
885/// `Validated<T, CompileTime>` was witnessed by `validate_const()` and is
886/// usable in const contexts. `Validated<T, Runtime>` (the default) was
887/// witnessed by `validate()`. A `CompileTime` witness is convertible to
888/// a `Runtime` witness via `From`.
889/// # Examples
890/// ```no_run
891/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
892/// use uor_foundation::{WittLevel, VerificationDomain};
893///
894/// // Validated<T> proves that a value passed conformance checking.
895/// // You cannot construct one directly — only builder validate() methods
896/// // and the minting boundary produce them.
897/// let terms = [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
898/// let domains = [VerificationDomain::Enumerative];
899///
900/// let validated = CompileUnitBuilder::new()
901///     .root_term(&terms)
902///     .witt_level_ceiling(WittLevel::W8)
903///     .thermodynamic_budget(1024)
904///     .target_domains(&domains)
905///     .result_type::<ConstrainedTypeInput>()
906///     .validate()
907///     .expect("all fields set");
908///
909/// // Access the inner value through the proof wrapper:
910/// let _compile_unit = validated.inner();
911/// ```
912#[derive(Debug, Clone, PartialEq, Eq)]
913pub struct Validated<T, Phase: ValidationPhase = Runtime> {
914    /// The validated inner value.
915    inner: T,
916    /// Phantom marker for the validation phase (`CompileTime` or `Runtime`).
917    _phase: PhantomData<Phase>,
918    /// Prevents external construction.
919    _sealed: (),
920}
921
922impl<T, Phase: ValidationPhase> Validated<T, Phase> {
923    /// Returns a reference to the validated inner value.
924    #[inline]
925    #[must_use]
926    pub const fn inner(&self) -> &T {
927        &self.inner
928    }
929
930    /// Creates a new `Validated<T, Phase>` wrapper. Only callable within the crate.
931    #[inline]
932    #[allow(dead_code)]
933    pub(crate) const fn new(inner: T) -> Self {
934        Self {
935            inner,
936            _phase: PhantomData,
937            _sealed: (),
938        }
939    }
940}
941
942/// v0.2.2 W13: a compile-time witness is usable wherever a runtime witness is required.
943impl<T> From<Validated<T, CompileTime>> for Validated<T, Runtime> {
944    #[inline]
945    fn from(value: Validated<T, CompileTime>) -> Self {
946        Self {
947            inner: value.inner,
948            _phase: PhantomData,
949            _sealed: (),
950        }
951    }
952}
953
954/// An opaque derivation trace that can only be extended by the rewrite engine.
955/// Records the rewrite-step count, the source `witt_level_bits`, and the
956/// parametric `content_fingerprint`. Private fields prevent external
957/// construction; produced exclusively by `Grounded::derivation()` so the
958/// verify path can re-derive the source certificate via
959/// `Derivation::replay() -> Trace -> verify_trace`.
960#[derive(Debug, Clone, PartialEq, Eq)]
961pub struct Derivation {
962    /// Number of rewrite steps in this derivation.
963    step_count: u32,
964    /// v0.2.2 T5: Witt level the source grounding was minted at. Carried
965    /// through replay so the verifier can reconstruct the certificate.
966    witt_level_bits: u16,
967    /// v0.2.2 T5: parametric content fingerprint of the source unit's
968    /// full state, computed at grounding time by the consumer-supplied
969    /// `Hasher`. Carried through replay so the verifier can reproduce
970    /// the source certificate via passthrough.
971    content_fingerprint: ContentFingerprint,
972}
973
974impl Derivation {
975    /// Returns the number of rewrite steps.
976    #[inline]
977    #[must_use]
978    pub const fn step_count(&self) -> u32 {
979        self.step_count
980    }
981
982    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
983    #[inline]
984    #[must_use]
985    pub const fn witt_level_bits(&self) -> u16 {
986        self.witt_level_bits
987    }
988
989    /// v0.2.2 T5: returns the parametric content fingerprint of the source
990    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
991    #[inline]
992    #[must_use]
993    pub const fn content_fingerprint(&self) -> ContentFingerprint {
994        self.content_fingerprint
995    }
996
997    /// Creates a new derivation. Only callable within the crate.
998    #[inline]
999    #[must_use]
1000    #[allow(dead_code)]
1001    pub(crate) const fn new(
1002        step_count: u32,
1003        witt_level_bits: u16,
1004        content_fingerprint: ContentFingerprint,
1005    ) -> Self {
1006        Self {
1007            step_count,
1008            witt_level_bits,
1009            content_fingerprint,
1010        }
1011    }
1012}
1013
1014/// An opaque free rank that can only be decremented by `PinningEffect`
1015/// and incremented by `UnbindingEffect` \[never by direct mutation\].
1016#[derive(Debug, Clone, PartialEq, Eq)]
1017pub struct FreeRank {
1018    /// Total site capacity at the Witt level.
1019    total: u32,
1020    /// Currently pinned sites.
1021    pinned: u32,
1022}
1023
1024impl FreeRank {
1025    /// Returns the total site capacity.
1026    #[inline]
1027    #[must_use]
1028    pub const fn total(&self) -> u32 {
1029        self.total
1030    }
1031
1032    /// Returns the number of currently pinned sites.
1033    #[inline]
1034    #[must_use]
1035    pub const fn pinned(&self) -> u32 {
1036        self.pinned
1037    }
1038
1039    /// Returns the number of remaining (unpinned) sites.
1040    #[inline]
1041    #[must_use]
1042    pub const fn remaining(&self) -> u32 {
1043        self.total - self.pinned
1044    }
1045
1046    /// Creates a new free rank. Only callable within the crate.
1047    #[inline]
1048    #[allow(dead_code)]
1049    pub(crate) const fn new(total: u32, pinned: u32) -> Self {
1050        Self { total, pinned }
1051    }
1052}
1053
1054/// v0.2.2 Phase A: sealed `H::Decimal`-backed newtype carrying the
1055/// `observable:LandauerCost` accumulator in `observable:Nats`.
1056/// Monotonic within a pipeline invocation. The UOR ring operates
1057/// at the Landauer temperature (β* = ln 2), so this observable is
1058/// a direct measure of irreversible bit-erasure performed.
1059/// Phase 9: parameterized over `H: HostTypes` so the underlying
1060/// decimal type tracks the host's chosen precision.
1061#[derive(Debug)]
1062pub struct LandauerBudget<H: HostTypes = crate::DefaultHostTypes> {
1063    /// Accumulated Landauer cost in nats. Non-negative, finite.
1064    nats: H::Decimal,
1065    /// Phantom marker pinning the host type.
1066    _phantom: core::marker::PhantomData<H>,
1067    /// Prevents external construction.
1068    _sealed: (),
1069}
1070
1071impl<H: HostTypes> LandauerBudget<H> {
1072    /// Returns the accumulated Landauer cost in nats.
1073    #[inline]
1074    #[must_use]
1075    pub const fn nats(&self) -> H::Decimal {
1076        self.nats
1077    }
1078
1079    /// Crate-internal constructor. Caller guarantees `nats` is
1080    /// non-negative and finite (i.e. not NaN, not infinite).
1081    #[inline]
1082    #[must_use]
1083    #[allow(dead_code)]
1084    pub(crate) const fn new(nats: H::Decimal) -> Self {
1085        Self {
1086            nats,
1087            _phantom: core::marker::PhantomData,
1088            _sealed: (),
1089        }
1090    }
1091
1092    /// Crate-internal constructor for the zero-cost initial budget.
1093    #[inline]
1094    #[must_use]
1095    #[allow(dead_code)]
1096    pub(crate) const fn zero() -> Self {
1097        Self {
1098            nats: H::EMPTY_DECIMAL,
1099            _phantom: core::marker::PhantomData,
1100            _sealed: (),
1101        }
1102    }
1103}
1104
1105impl<H: HostTypes> Copy for LandauerBudget<H> {}
1106impl<H: HostTypes> Clone for LandauerBudget<H> {
1107    #[inline]
1108    fn clone(&self) -> Self {
1109        *self
1110    }
1111}
1112impl<H: HostTypes> PartialEq for LandauerBudget<H> {
1113    #[inline]
1114    fn eq(&self, other: &Self) -> bool {
1115        self.nats == other.nats
1116    }
1117}
1118impl<H: HostTypes> Eq for LandauerBudget<H> {}
1119impl<H: HostTypes> PartialOrd for LandauerBudget<H> {
1120    #[inline]
1121    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1122        Some(self.cmp(other))
1123    }
1124}
1125impl<H: HostTypes> Ord for LandauerBudget<H> {
1126    #[inline]
1127    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1128        // Total order on H::Decimal with NaN excluded by construction.
1129        self.nats
1130            .partial_cmp(&other.nats)
1131            .unwrap_or(core::cmp::Ordering::Equal)
1132    }
1133}
1134impl<H: HostTypes> core::hash::Hash for LandauerBudget<H> {
1135    #[inline]
1136    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1137        // DecimalTranscendental::to_bits gives a stable u64 fingerprint
1138        // for any in-range Decimal value.
1139        self.nats.to_bits().hash(state);
1140    }
1141}
1142
1143/// v0.2.2 Phase A: foundation-internal deterministic two-clock value
1144/// carried by every `Grounded<T>` and `Certified<C>`. The two clocks are
1145/// `landauer_nats` (a `LandauerBudget` value backed by `observable:LandauerCost`)
1146/// and `rewrite_steps` (a `u64` backed by `derivation:stepCount` on
1147/// `derivation:TermMetrics`). Each clock is monotonic within a pipeline
1148/// invocation, content-deterministic, ontology-grounded, and binds to a
1149/// physical wall-clock lower bound through established physics (Landauer's
1150/// principle for nats; Margolus-Levitin for rewrite steps). Two clocks
1151/// because exactly two physical lower-bound theorems are grounded; adding
1152/// a third clock would require grounding a third physical theorem.
1153/// `PartialOrd` is component-wise: `a < b` iff every field of `a` is `<=`
1154/// the corresponding field of `b` and at least one is strictly `<`. Two
1155/// `UorTime` values from unrelated computations are genuinely incomparable,
1156/// so `UorTime` is `PartialOrd` but **not** `Ord`.
1157#[derive(Debug)]
1158pub struct UorTime<H: HostTypes = crate::DefaultHostTypes> {
1159    /// Landauer budget consumed, in `observable:Nats`.
1160    landauer_nats: LandauerBudget<H>,
1161    /// Total rewrite steps taken (`derivation:stepCount`).
1162    rewrite_steps: u64,
1163    /// Prevents external construction.
1164    _sealed: (),
1165}
1166
1167impl<H: HostTypes> UorTime<H> {
1168    /// Returns the Landauer budget consumed, in `observable:Nats`.
1169    /// Maps to `observable:LandauerCost`.
1170    #[inline]
1171    #[must_use]
1172    pub const fn landauer_nats(&self) -> LandauerBudget<H> {
1173        self.landauer_nats
1174    }
1175
1176    /// Returns the total rewrite steps taken.
1177    /// Maps to `derivation:stepCount` on `derivation:TermMetrics`.
1178    #[inline]
1179    #[must_use]
1180    pub const fn rewrite_steps(&self) -> u64 {
1181        self.rewrite_steps
1182    }
1183
1184    /// Crate-internal constructor. Reachable only from the pipeline at witness mint time.
1185    #[inline]
1186    #[must_use]
1187    #[allow(dead_code)]
1188    pub(crate) const fn new(landauer_nats: LandauerBudget<H>, rewrite_steps: u64) -> Self {
1189        Self {
1190            landauer_nats,
1191            rewrite_steps,
1192            _sealed: (),
1193        }
1194    }
1195
1196    /// Crate-internal constructor for the zero initial value.
1197    #[inline]
1198    #[must_use]
1199    #[allow(dead_code)]
1200    pub(crate) const fn zero() -> Self {
1201        Self {
1202            landauer_nats: LandauerBudget::<H>::zero(),
1203            rewrite_steps: 0,
1204            _sealed: (),
1205        }
1206    }
1207
1208    /// Returns the provable minimum wall-clock duration that the
1209    /// computation producing this witness could have taken under the
1210    /// given calibration. Returns `max(Landauer-bound, Margolus-Levitin-bound)`.
1211    /// The Landauer bound is `landauer_nats × k_B·T / thermal_power`.
1212    /// The Margolus-Levitin bound is `π·ℏ·rewrite_steps / (2·characteristic_energy)`.
1213    /// Pure arithmetic — no transcendentals, no state. Const-evaluable
1214    /// where the `UorTime` value is known at compile time.
1215    #[inline]
1216    #[must_use]
1217    pub fn min_wall_clock(&self, cal: &Calibration<H>) -> Nanos {
1218        // Landauer bound: nats × k_B·T / thermal_power = seconds.
1219        let landauer_seconds = self.landauer_nats.nats() * cal.k_b_t() / cal.thermal_power();
1220        // Margolus-Levitin bound: π·ℏ / (2·E) per orthogonal state transition.
1221        // π·ℏ ≈ 3.31194e-34 J·s; encoded as the f64 bit pattern of
1222        // `core::f64::consts::PI * 1.054_571_817e-34` so the constant is
1223        // representable across host Decimal types.
1224        let pi_times_h_bar =
1225            <H::Decimal as DecimalTranscendental>::from_bits(crate::PI_TIMES_H_BAR_BITS);
1226        let two = <H::Decimal as DecimalTranscendental>::from_u32(2);
1227        let ml_seconds_per_step = pi_times_h_bar / (two * cal.characteristic_energy());
1228        let steps = <H::Decimal as DecimalTranscendental>::from_u64(self.rewrite_steps);
1229        let ml_seconds = ml_seconds_per_step * steps;
1230        let max_seconds = if landauer_seconds > ml_seconds {
1231            landauer_seconds
1232        } else {
1233            ml_seconds
1234        };
1235        // Convert seconds to nanoseconds, saturate on overflow.
1236        let nanos_per_second =
1237            <H::Decimal as DecimalTranscendental>::from_bits(crate::NANOS_PER_SECOND_BITS);
1238        let nanos = max_seconds * nanos_per_second;
1239        Nanos {
1240            ns: <H::Decimal as DecimalTranscendental>::as_u64_saturating(nanos),
1241            _sealed: (),
1242        }
1243    }
1244}
1245
1246impl<H: HostTypes> Copy for UorTime<H> {}
1247impl<H: HostTypes> Clone for UorTime<H> {
1248    #[inline]
1249    fn clone(&self) -> Self {
1250        *self
1251    }
1252}
1253impl<H: HostTypes> PartialEq for UorTime<H> {
1254    #[inline]
1255    fn eq(&self, other: &Self) -> bool {
1256        self.landauer_nats == other.landauer_nats && self.rewrite_steps == other.rewrite_steps
1257    }
1258}
1259impl<H: HostTypes> Eq for UorTime<H> {}
1260impl<H: HostTypes> core::hash::Hash for UorTime<H> {
1261    #[inline]
1262    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1263        self.landauer_nats.hash(state);
1264        self.rewrite_steps.hash(state);
1265    }
1266}
1267impl<H: HostTypes> PartialOrd for UorTime<H> {
1268    #[inline]
1269    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1270        let l = self.landauer_nats.cmp(&other.landauer_nats);
1271        let r = self.rewrite_steps.cmp(&other.rewrite_steps);
1272        match (l, r) {
1273            (core::cmp::Ordering::Equal, core::cmp::Ordering::Equal) => {
1274                Some(core::cmp::Ordering::Equal)
1275            }
1276            (core::cmp::Ordering::Less, core::cmp::Ordering::Less)
1277            | (core::cmp::Ordering::Less, core::cmp::Ordering::Equal)
1278            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Less) => {
1279                Some(core::cmp::Ordering::Less)
1280            }
1281            (core::cmp::Ordering::Greater, core::cmp::Ordering::Greater)
1282            | (core::cmp::Ordering::Greater, core::cmp::Ordering::Equal)
1283            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Greater) => {
1284                Some(core::cmp::Ordering::Greater)
1285            }
1286            _ => None,
1287        }
1288    }
1289}
1290
1291/// v0.2.2 Phase A: sealed lower-bound carrier for wall-clock duration.
1292/// Produced only by `UorTime::min_wall_clock` and similar foundation
1293/// time conversions. The sealing guarantees that any `Nanos` value is
1294/// a provable physical bound, not a raw integer. Developers who need
1295/// the underlying `u64` call `.as_u64()`; the sealing prevents
1296/// accidentally passing a host-measured duration where the type system
1297/// expects "a provable minimum".
1298#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1299pub struct Nanos {
1300    /// The provable lower-bound duration in nanoseconds.
1301    ns: u64,
1302    /// Prevents external construction.
1303    _sealed: (),
1304}
1305
1306impl Nanos {
1307    /// Returns the underlying nanosecond count. The value is a provable
1308    /// physical lower bound under whatever calibration produced it.
1309    #[inline]
1310    #[must_use]
1311    pub const fn as_u64(self) -> u64 {
1312        self.ns
1313    }
1314}
1315
1316/// v0.2.2 Phase A: error returned by `Calibration::new` when the supplied
1317/// physical parameters fail plausibility validation.
1318#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1319pub enum CalibrationError {
1320    /// `k_b_t` was non-positive, NaN, or outside the known-universe
1321    /// temperature range (`1e-30 ≤ k_b_t ≤ 1e-15` joules).
1322    ThermalEnergy,
1323    /// `thermal_power` was non-positive, NaN, or above the thermodynamic maximum (`1e9` W).
1324    ThermalPower,
1325    /// `characteristic_energy` was non-positive, NaN, or above the
1326    /// k_B·T × Avogadro-class bound (`1e3` joules).
1327    CharacteristicEnergy,
1328}
1329
1330impl core::fmt::Display for CalibrationError {
1331    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1332        match self {
1333            Self::ThermalEnergy => {
1334                f.write_str("calibration k_b_t out of range (must be in [1e-30, 1e-15] joules)")
1335            }
1336            Self::ThermalPower => {
1337                f.write_str("calibration thermal_power out of range (must be > 0 and <= 1e9 W)")
1338            }
1339            Self::CharacteristicEnergy => f.write_str(
1340                "calibration characteristic_energy out of range (must be > 0 and <= 1e3 J)",
1341            ),
1342        }
1343    }
1344}
1345
1346impl core::error::Error for CalibrationError {}
1347
1348/// v0.2.2 Phase A: physical-substrate calibration for wall-clock binding.
1349/// Construction is open via [`Calibration::new`], but the fields are
1350/// private and validated for physical plausibility. Used to convert
1351/// `UorTime` to a provable wall-clock lower bound via
1352/// [`UorTime::min_wall_clock`].
1353/// **A `Calibration` is never passed into `pipeline::run`,
1354/// `resolver::*::certify`, `validate_const`, or any other foundation entry
1355/// point.** The foundation computes `UorTime` without physical
1356/// interpretation; the developer applies a `Calibration` after the fact.
1357#[derive(Debug)]
1358pub struct Calibration<H: HostTypes = crate::DefaultHostTypes> {
1359    /// Boltzmann constant times temperature, in joules.
1360    k_b_t: H::Decimal,
1361    /// Sustained dissipation in watts.
1362    thermal_power: H::Decimal,
1363    /// Mean energy above ground state, in joules.
1364    characteristic_energy: H::Decimal,
1365    /// Phantom marker pinning the host type.
1366    _phantom: core::marker::PhantomData<H>,
1367}
1368
1369impl<H: HostTypes> Copy for Calibration<H> {}
1370impl<H: HostTypes> Clone for Calibration<H> {
1371    #[inline]
1372    fn clone(&self) -> Self {
1373        *self
1374    }
1375}
1376impl<H: HostTypes> PartialEq for Calibration<H> {
1377    #[inline]
1378    fn eq(&self, other: &Self) -> bool {
1379        self.k_b_t == other.k_b_t
1380            && self.thermal_power == other.thermal_power
1381            && self.characteristic_energy == other.characteristic_energy
1382    }
1383}
1384
1385impl<H: HostTypes> Calibration<H> {
1386    /// Construct a calibration with physically plausible parameters.
1387    /// Validation: every parameter must be positive and finite. `k_b_t`
1388    /// must lie within the known-universe temperature range
1389    /// (`1e-30 <= k_b_t <= 1e-15` joules covers ~1 nK to ~1e8 K).
1390    /// `thermal_power` must be at most `1e9` W (gigawatt class — far above
1391    /// any plausible single-compute envelope). `characteristic_energy`
1392    /// must be at most `1e3` J (kilojoule class — astronomically generous).
1393    /// # Errors
1394    /// Returns `CalibrationError::InvalidThermalEnergy` when `k_b_t` is
1395    /// non-positive, NaN, or outside the temperature range.
1396    /// Returns `CalibrationError::InvalidThermalPower` when `thermal_power`
1397    /// is non-positive, NaN, or above the maximum.
1398    /// Returns `CalibrationError::InvalidCharacteristicEnergy` when
1399    /// `characteristic_energy` is non-positive, NaN, or above the maximum.
1400    /// # Example
1401    /// ```
1402    /// use uor_foundation::enforcement::Calibration;
1403    /// use uor_foundation::DefaultHostTypes;
1404    /// // X86 server-class envelope at room temperature.
1405    /// // k_B·T at 300 K = 4.14e-21 J; 85 W sustained TDP; ~1e-15 J/op.
1406    /// let cal = Calibration::<DefaultHostTypes>::new(4.14e-21, 85.0, 1.0e-15)
1407    ///     .expect("physically plausible server calibration");
1408    /// # let _ = cal;
1409    /// ```
1410    #[inline]
1411    pub fn new(
1412        k_b_t: H::Decimal,
1413        thermal_power: H::Decimal,
1414        characteristic_energy: H::Decimal,
1415    ) -> Result<Self, CalibrationError> {
1416        // Bit-pattern bounds for the validation envelope. Reading them
1417        // through `from_bits` lets the host's chosen Decimal precision
1418        // resolve the comparison without any hardcoded f64 in source.
1419        let zero = <H::Decimal as Default>::default();
1420        let kbt_lo =
1421            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_LO_BITS);
1422        let kbt_hi =
1423            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_HI_BITS);
1424        let tp_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1425            crate::CALIBRATION_THERMAL_POWER_HI_BITS,
1426        );
1427        let ce_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1428            crate::CALIBRATION_CHAR_ENERGY_HI_BITS,
1429        );
1430        // NaN identity: NaN != NaN. PartialEq is the defining bound.
1431        #[allow(clippy::eq_op)]
1432        let k_b_t_nan = k_b_t != k_b_t;
1433        if k_b_t_nan || k_b_t <= zero || k_b_t < kbt_lo || k_b_t > kbt_hi {
1434            return Err(CalibrationError::ThermalEnergy);
1435        }
1436        #[allow(clippy::eq_op)]
1437        let tp_nan = thermal_power != thermal_power;
1438        if tp_nan || thermal_power <= zero || thermal_power > tp_hi {
1439            return Err(CalibrationError::ThermalPower);
1440        }
1441        #[allow(clippy::eq_op)]
1442        let ce_nan = characteristic_energy != characteristic_energy;
1443        if ce_nan || characteristic_energy <= zero || characteristic_energy > ce_hi {
1444            return Err(CalibrationError::CharacteristicEnergy);
1445        }
1446        Ok(Self {
1447            k_b_t,
1448            thermal_power,
1449            characteristic_energy,
1450            _phantom: core::marker::PhantomData,
1451        })
1452    }
1453
1454    /// Returns the Boltzmann constant times temperature, in joules.
1455    #[inline]
1456    #[must_use]
1457    pub const fn k_b_t(&self) -> H::Decimal {
1458        self.k_b_t
1459    }
1460
1461    /// Returns the sustained thermal power dissipation, in watts.
1462    #[inline]
1463    #[must_use]
1464    pub const fn thermal_power(&self) -> H::Decimal {
1465        self.thermal_power
1466    }
1467
1468    /// Returns the characteristic energy above ground state, in joules.
1469    #[inline]
1470    #[must_use]
1471    pub const fn characteristic_energy(&self) -> H::Decimal {
1472        self.characteristic_energy
1473    }
1474
1475    /// v0.2.2 T5.5: zero sentinel. All three fields are 0.0 — physically
1476    /// meaningless but safely constructible. Used as the unreachable-branch
1477    /// placeholder in the const-context preset literals (`X86_SERVER`,
1478    /// `ARM_MOBILE`, `CORTEX_M_EMBEDDED`, `CONSERVATIVE_WORST_CASE`). The
1479    /// `meta/calibration_presets_valid` conformance check verifies the
1480    /// preset literals always succeed in `Calibration::new`, so this
1481    /// sentinel is never produced in practice. Do not use it directly;
1482    /// it is exposed only because Rust's const-eval needs a fallback for
1483    /// the impossible `Err` arm of the preset match.
1484    pub const ZERO_SENTINEL: Calibration<H> = Self {
1485        k_b_t: H::EMPTY_DECIMAL,
1486        thermal_power: H::EMPTY_DECIMAL,
1487        characteristic_energy: H::EMPTY_DECIMAL,
1488        _phantom: core::marker::PhantomData,
1489    };
1490}
1491
1492impl Calibration<crate::DefaultHostTypes> {
1493    /// Const constructor for the default-host (f64) path. Bypasses runtime validation; use only for the spec-shipped preset literals where the envelope is statically guaranteed. Parameter types are written as `<DefaultHostTypes as HostTypes>::Decimal` so no `: f64` annotation appears in the public-API surface — the host-type alias is the canonical name; downstream that swaps the host gets the matching decimal automatically.
1494    #[inline]
1495    #[must_use]
1496    pub(crate) const fn from_f64_unchecked(
1497        k_b_t: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1498        thermal_power: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1499        characteristic_energy: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1500    ) -> Self {
1501        Self {
1502            k_b_t,
1503            thermal_power,
1504            characteristic_energy,
1505            _phantom: core::marker::PhantomData,
1506        }
1507    }
1508}
1509
1510/// v0.2.2 Phase A: foundation-shipped preset calibrations covering common
1511/// substrates. The values are derived from published substrate thermals at
1512/// T=300 K (room temperature, where k_B·T ≈ 4.14e-21 J).
1513pub mod calibrations {
1514    use super::Calibration;
1515    use crate::DefaultHostTypes;
1516
1517    /// Server-class x86 (Xeon/EPYC sustained envelope).
1518    /// k_B·T = 4.14e-21 J (T = 300 K), thermal_power = 85 W (typical TDP),
1519    /// characteristic_energy = 1e-15 J/op (~1 fJ/op for modern CMOS).
1520    pub const X86_SERVER: Calibration<DefaultHostTypes> =
1521        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 85.0, 1.0e-15);
1522
1523    /// Mobile ARM SoC (Apple M-series, Snapdragon 8-series sustained envelope).
1524    /// k_B·T = 4.14e-21 J, thermal_power = 5 W, characteristic_energy = 1e-16 J/op.
1525    pub const ARM_MOBILE: Calibration<DefaultHostTypes> =
1526        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 5.0, 1.0e-16);
1527
1528    /// Cortex-M embedded (STM32/nRF52 at 80 MHz).
1529    /// k_B·T = 4.14e-21 J, thermal_power = 0.1 W, characteristic_energy = 1e-17 J/op.
1530    pub const CORTEX_M_EMBEDDED: Calibration<DefaultHostTypes> =
1531        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 0.1, 1.0e-17);
1532
1533    /// The tightest provable lower bound that requires no trust in the
1534    /// issuer's claimed substrate. Values are physically sound but maximally
1535    /// generous: k_B·T at 300 K floor, thermal_power at 1 GW (above any
1536    /// plausible single-compute envelope), characteristic_energy at 1 J
1537    /// (astronomically generous).
1538    /// Applying this calibration yields the smallest `Nanos` physically
1539    /// possible for the computation regardless of substrate claims.
1540    pub const CONSERVATIVE_WORST_CASE: Calibration<DefaultHostTypes> =
1541        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 1.0e9, 1.0);
1542}
1543
1544/// v0.2.2 Phase B (target §1.7): timing-policy carrier. Parametric over host tuning.
1545/// Supplies the preflight / runtime Nanos budgets (canonical values from
1546/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`) plus
1547/// the `Calibration` used to convert an input's a-priori `UorTime` estimate
1548/// into a Nanos lower bound for comparison against the budget.
1549/// The foundation-canonical default [`CanonicalTimingPolicy`] uses
1550/// `calibrations::CONSERVATIVE_WORST_CASE` (the tightest provable lower-bound
1551/// calibration) and the 10 ms budget from the ontology. Host code overrides by
1552/// implementing `TimingPolicy` on a marker struct and substituting at the
1553/// preflight-function call site.
1554pub trait TimingPolicy {
1555    /// Preflight Nanos budget. Inputs whose a-priori UorTime → min_wall_clock
1556    /// under `Self::CALIBRATION` exceeds this value are rejected at preflight.
1557    const PREFLIGHT_BUDGET_NS: u64;
1558    /// Runtime Nanos budget for post-admission reduction.
1559    const RUNTIME_BUDGET_NS: u64;
1560    /// Canonical Calibration used to convert a-priori UorTime estimates to Nanos.
1561    /// Phase 9: pinned to `Calibration<DefaultHostTypes>` because the trait's `const` slot can't carry a non-DefaultHost generic. Polymorphic consumers build a `Calibration<H>` at runtime via `Calibration::new`.
1562    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes>;
1563}
1564
1565/// v0.2.2 Phase B: foundation-canonical [`TimingPolicy`]. Budget values mirror
1566/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`; calibration
1567/// is `calibrations::CONSERVATIVE_WORST_CASE` so the Nanos lower bound from any
1568/// input UorTime is the tightest physically-defensible value.
1569#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1570pub struct CanonicalTimingPolicy;
1571
1572impl TimingPolicy for CanonicalTimingPolicy {
1573    const PREFLIGHT_BUDGET_NS: u64 = 10_000_000;
1574    const RUNTIME_BUDGET_NS: u64 = 10_000_000;
1575    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes> =
1576        &calibrations::CONSERVATIVE_WORST_CASE;
1577}
1578
1579/// Phase H (target §1.6): foundation-owned transcendental-arithmetic entry points.
1580/// Routes through the always-on `libm` dependency so every build — std, alloc,
1581/// and strict no_std — has access to `ln` / `exp` / `sqrt` for `xsd:decimal`
1582/// observables. Gating these behind an optional feature flag was considered and
1583/// rejected per target §1.6: an observable that exists in one build and not
1584/// another violates the foundation's "one surface" discipline.
1585/// Downstream code that needs transcendentals should call these wrappers —
1586/// they are the canonical entry point for the four observables target §3 enumerates
1587/// (`convergenceRate`, `residualEntropy`, `collapseAmplitude`, and `op:OA_5` pricing)
1588/// and for any future observable whose implementation admits transcendentals.
1589pub mod transcendentals {
1590    use crate::DecimalTranscendental;
1591
1592    /// Natural logarithm. Dispatches via `DecimalTranscendental::ln`; the foundation's f64 / f32 impls route through `libm::log` / `logf`.
1593    /// Returns `NaN` for `x <= 0.0`, preserving `libm`'s contract.
1594    #[inline]
1595    #[must_use]
1596    pub fn ln<D: DecimalTranscendental>(x: D) -> D {
1597        x.ln()
1598    }
1599
1600    /// Exponential `e^x`. Dispatches via `DecimalTranscendental::exp`.
1601    #[inline]
1602    #[must_use]
1603    pub fn exp<D: DecimalTranscendental>(x: D) -> D {
1604        x.exp()
1605    }
1606
1607    /// Square root. Dispatches via `DecimalTranscendental::sqrt`. Returns `NaN` for `x < 0.0`.
1608    #[inline]
1609    #[must_use]
1610    pub fn sqrt<D: DecimalTranscendental>(x: D) -> D {
1611        x.sqrt()
1612    }
1613
1614    /// Shannon entropy term `-p · ln(p)` in nats. Returns 0 for `p = 0` by
1615    /// continuous extension. Used by `observable:residualEntropy`.
1616    #[inline]
1617    #[must_use]
1618    pub fn entropy_term_nats<D: DecimalTranscendental>(p: D) -> D {
1619        let zero = <D as Default>::default();
1620        if p <= zero {
1621            zero
1622        } else {
1623            zero - p * p.ln()
1624        }
1625    }
1626}
1627
1628/// Fixed-capacity term list for `#![no_std]`. Indices into a `TermArena`.
1629#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1630pub struct TermList {
1631    /// Start index in the arena.
1632    pub start: u32,
1633    /// Number of terms in this list.
1634    pub len: u32,
1635}
1636
1637/// Stack-resident arena for `Term` trees.
1638/// Fixed capacity determined by the const generic `CAP`.
1639/// All `Term` child references are `u32` indices into this arena.
1640/// `#![no_std]`-safe: no heap allocation.
1641/// # Examples
1642/// ```rust
1643/// use uor_foundation::enforcement::{TermArena, Term, TermList};
1644/// use uor_foundation::{WittLevel, PrimitiveOp};
1645///
1646/// // Build the expression `add(3, 5)` bottom-up in an arena.
1647/// let mut arena = TermArena::<4>::new();
1648///
1649/// // Push leaves first:
1650/// let idx_3 = arena.push(uor_foundation::pipeline::literal_u64(3, WittLevel::W8));
1651/// let idx_5 = arena.push(uor_foundation::pipeline::literal_u64(5, WittLevel::W8));
1652///
1653/// // Push the application node, referencing the leaves by index:
1654/// let idx_add = arena.push(Term::Application {
1655///     operator: PrimitiveOp::Add,
1656///     args: TermList { start: idx_3.unwrap_or(0), len: 2 },
1657/// });
1658///
1659/// assert_eq!(arena.len(), 3);
1660/// // Retrieve a node by index:
1661/// let node = arena.get(idx_add.unwrap_or(0));
1662/// assert!(node.is_some());
1663/// ```
1664#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1665pub struct TermArena<const CAP: usize> {
1666    /// Node storage. `None` slots are unused.
1667    nodes: [Option<Term>; CAP],
1668    /// Number of allocated nodes.
1669    len: u32,
1670}
1671
1672impl<const CAP: usize> TermArena<CAP> {
1673    /// Creates an empty arena.
1674    #[inline]
1675    #[must_use]
1676    pub const fn new() -> Self {
1677        // v0.2.2 T4.5.a: const-stable on MSRV 1.70 via the `[None; CAP]`
1678        // initializer (Term is Copy as of T4.5.a, so Option<Term> is Copy).
1679        Self {
1680            nodes: [None; CAP],
1681            len: 0,
1682        }
1683    }
1684
1685    /// Push a term into the arena and return its index.
1686    /// # Errors
1687    /// Returns `None` if the arena is full.
1688    #[must_use]
1689    pub fn push(&mut self, term: Term) -> Option<u32> {
1690        let idx = self.len;
1691        if (idx as usize) >= CAP {
1692            return None;
1693        }
1694        self.nodes[idx as usize] = Some(term);
1695        self.len = idx + 1;
1696        Some(idx)
1697    }
1698
1699    /// Returns a reference to the term at `index`, or `None` if out of bounds.
1700    #[inline]
1701    #[must_use]
1702    pub fn get(&self, index: u32) -> Option<&Term> {
1703        self.nodes
1704            .get(index as usize)
1705            .and_then(|slot| slot.as_ref())
1706    }
1707
1708    /// Returns the number of allocated nodes.
1709    #[inline]
1710    #[must_use]
1711    pub const fn len(&self) -> u32 {
1712        self.len
1713    }
1714
1715    /// Returns `true` if the arena has no allocated nodes.
1716    #[inline]
1717    #[must_use]
1718    pub const fn is_empty(&self) -> bool {
1719        self.len == 0
1720    }
1721
1722    /// v0.2.2 T4.5.b: returns the populated prefix of the arena as a slice.
1723    /// Each entry is `Some(term)` for the populated indices `0..len()`;
1724    /// downstream consumers index into this slice via `TermList::start` and
1725    /// `TermList::len` to walk the children of an Application/Match node.
1726    #[inline]
1727    #[must_use]
1728    pub fn as_slice(&self) -> &[Option<Term>] {
1729        &self.nodes[..self.len as usize]
1730    }
1731
1732    /// Wiki ADR-022 D2: const constructor that copies a static term slice
1733    /// into the arena. Used by the `prism_model!` proc-macro to emit a
1734    /// `const ROUTE: TermArena<CAP> = TermArena::from_slice(ROUTE_SLICE)`
1735    /// declaration alongside the model — the `const ROUTE_SLICE` carrying
1736    /// the term tree, this `from_slice` wrapping it into the arena form
1737    /// [`crate::pipeline::run_route`] consumes.
1738    /// `CAP` MUST be at least `slice.len()`; if the slice exceeds the
1739    /// arena's capacity the trailing terms are silently dropped (the
1740    /// `prism_model!` macro emits an arena sized to fit the route's term
1741    /// count plus headroom, so this case is unreachable from the macro's
1742    /// output).
1743    #[inline]
1744    #[must_use]
1745    pub const fn from_slice(slice: &'static [Term]) -> Self {
1746        let mut nodes: [Option<Term>; CAP] = [None; CAP];
1747        let mut i = 0usize;
1748        while i < slice.len() && i < CAP {
1749            nodes[i] = Some(slice[i]);
1750            i += 1;
1751        }
1752        // Cap at min(slice.len(), CAP) so a too-large slice doesn't
1753        // overrun. The macro emits arena CAP >= slice.len() so the
1754        // truncation branch is unreachable in practice.
1755        #[allow(clippy::cast_possible_truncation)]
1756        let len = if slice.len() > CAP {
1757            CAP as u32
1758        } else {
1759            slice.len() as u32
1760        };
1761        Self { nodes, len }
1762    }
1763}
1764
1765impl<const CAP: usize> Default for TermArena<CAP> {
1766    fn default() -> Self {
1767        Self::new()
1768    }
1769}
1770
1771/// Concrete AST node for the UOR term language.
1772/// Mirrors the EBNF grammar productions. All child references are
1773/// indices into a `TermArena`, keeping the AST stack-resident and
1774/// `#![no_std]`-safe.
1775/// # Examples
1776/// ```rust
1777/// use uor_foundation::enforcement::{Term, TermList};
1778/// use uor_foundation::{WittLevel, PrimitiveOp};
1779///
1780/// // Literal: an integer value tagged with a Witt level.
1781/// let lit = uor_foundation::pipeline::literal_u64(42, WittLevel::W8);
1782///
1783/// // Application: an operation applied to arguments.
1784/// // `args` is a TermList { start, len } pointing into a TermArena.
1785/// let app = Term::Application {
1786///     operator: PrimitiveOp::Mul,
1787///     args: TermList { start: 0, len: 2 },
1788/// };
1789///
1790/// // Lift: canonical injection from a lower to a higher Witt level.
1791/// let lift = Term::Lift { operand_index: 0, target: WittLevel::new(32) };
1792///
1793/// // Project: canonical surjection from a higher to a lower level.
1794/// let proj = Term::Project { operand_index: 0, target: WittLevel::W8 };
1795/// ```
1796#[allow(clippy::large_enum_variant)]
1797#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1798pub enum Term {
1799    /// Integer literal with Witt level annotation. Per ADR-051 the value
1800    /// carrier is a `TermValue` byte sequence whose length matches the declared
1801    /// `level`'s byte width. Use `uor_foundation::pipeline::literal_u64(value, level)`
1802    /// to construct a literal from a `u64` value (the narrow form).
1803    Literal {
1804        /// The literal value as a byte sequence (ADR-051). Length equals
1805        /// `level.witt_length() / 8`. Wider widths (W128, W256, …) are
1806        /// natively representable without `Concat` composition.
1807        value: crate::pipeline::TermValue,
1808        /// The Witt level of this literal.
1809        level: WittLevel,
1810    },
1811    /// Variable reference by name index.
1812    Variable {
1813        /// Index into the name table.
1814        name_index: u32,
1815    },
1816    /// Operation application: operator applied to arguments.
1817    Application {
1818        /// The primitive operation to apply.
1819        operator: PrimitiveOp,
1820        /// Argument list (indices into arena).
1821        args: TermList,
1822    },
1823    /// Lift: canonical injection W_n to W_m (n < m, lossless).
1824    Lift {
1825        /// Index of the operand term in the arena.
1826        operand_index: u32,
1827        /// Target Witt level.
1828        target: WittLevel,
1829    },
1830    /// Project: canonical surjection W_m to W_n (m > n, lossy).
1831    Project {
1832        /// Index of the operand term in the arena.
1833        operand_index: u32,
1834        /// Target Witt level.
1835        target: WittLevel,
1836    },
1837    /// Match expression with pattern-result pairs.
1838    Match {
1839        /// Index of the scrutinee term in the arena.
1840        scrutinee_index: u32,
1841        /// Match arms (indices into arena).
1842        arms: TermList,
1843    },
1844    /// Bounded recursion with descent measure.
1845    Recurse {
1846        /// Index of the descent measure term.
1847        measure_index: u32,
1848        /// Index of the base case term.
1849        base_index: u32,
1850        /// Index of the recursive step term.
1851        step_index: u32,
1852    },
1853    /// Stream construction via unfold.
1854    Unfold {
1855        /// Index of the seed term.
1856        seed_index: u32,
1857        /// Index of the step function term.
1858        step_index: u32,
1859    },
1860    /// Try expression with failure recovery.
1861    Try {
1862        /// Index of the body term.
1863        body_index: u32,
1864        /// Index of the handler term.
1865        handler_index: u32,
1866    },
1867    /// Substitution-axis-realized verb projection (wiki ADR-029 + ADR-030).
1868    /// Delegates evaluation to the application's `AxisTuple` substitution-axis
1869    /// impl: the catamorphism evaluates the input subtree, dispatches the
1870    /// axis at `axis_index` to the kernel identified by `kernel_id`, and
1871    /// emits the kernel's output as the result. Emitted by
1872    /// `prism_model!` from the closure-body form `hash(input)` (ADR-026 G19,
1873    /// which lowers to AxisInvocation against the application's HashAxis).
1874    AxisInvocation {
1875        /// Position of the axis in the application's `AxisTuple`.
1876        axis_index: u32,
1877        /// Per-axis kernel id (the SDK macro emits per-method `KERNEL_*` consts).
1878        kernel_id: u32,
1879        /// Input subtree's arena index (single input — current axes are 1-arg).
1880        input_index: u32,
1881    },
1882    /// Field-access projection over a partition_product input (wiki
1883    /// ADR-033 G20). The catamorphism's fold-rule evaluates `source`
1884    /// and slices `[byte_offset .. byte_offset + byte_length]` from
1885    /// the resulting bytes. Emitted by `prism_model!` and `verb!`
1886    /// from the closure-body forms `<expr>.<index>` and
1887    /// `<expr>.<field_name>` (named-field access requires the
1888    /// `partition_product!` declaration to use the named-field form).
1889    /// Coproduct field-access is rejected at macro-expansion time.
1890    ProjectField {
1891        /// Arena index of the source expression's term tree.
1892        source_index: u32,
1893        /// Byte offset into the source's evaluated bytes (proc-
1894        /// macro-computed from factor MAX_BYTES).
1895        byte_offset: u32,
1896        /// Length of the projected slice in bytes.
1897        byte_length: u32,
1898    },
1899    /// Bounded search with structural early termination (wiki ADR-034).
1900    /// The catamorphism iterates `idx` from 0 up to (but excluding) the
1901    /// evaluated `domain_size`; for each iteration it evaluates
1902    /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to `idx`.
1903    /// On the first non-zero predicate result the fold emits the
1904    /// coproduct value `(0x01, idx_bytes)` and terminates iteration; if
1905    /// no `idx` admits, the fold emits `(0x00, idx-width zero bytes)`.
1906    /// Emitted by `prism_model!` and `verb!` from the closure-body
1907    /// form `first_admit(<DomainTy>, |idx| <pred>)` (ADR-026 G16; the
1908    /// lowering target shifted from `Term::Recurse` to `Term::FirstAdmit`
1909    /// per ADR-034's structural-search commitment).
1910    FirstAdmit {
1911        /// Arena index of the domain-cardinality term (typically a
1912        /// `Term::Literal` carrying `<DomainTy as ConstrainedTypeShape>::CYCLE_SIZE`).
1913        domain_size_index: u32,
1914        /// Arena index of the predicate body. Evaluation visits
1915        /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to the
1916        /// current candidate `idx`.
1917        predicate_index: u32,
1918    },
1919    /// ψ_1 (wiki ADR-035): nerve construction — Constraints → SimplicialComplex.
1920    /// Lowered from the closure-body form `nerve(<value_expr>)` (G21).
1921    /// Resolver-bound: consults the ResolverTuple's NerveResolver per ADR-036.
1922    Nerve {
1923        /// Arena index of the value-bytes operand (typically a
1924        /// `Term::Variable` for the route input or a `Term::ProjectField`).
1925        value_index: u32,
1926    },
1927    /// ψ_2 (wiki ADR-035): chain functor — SimplicialComplex → ChainComplex.
1928    /// Lowered from `chain_complex(<simplicial_expr>)` (G22).
1929    /// Resolver-bound: ChainComplexResolver per ADR-036.
1930    ChainComplex { simplicial_index: u32 },
1931    /// ψ_3 (wiki ADR-035): homology functor — ChainComplex → HomologyGroups.
1932    /// `H_k(C) = ker(∂_k) / im(∂_{k+1})`.
1933    /// Lowered from `homology_groups(<chain_expr>)` (G23).
1934    /// Resolver-bound: HomologyGroupResolver per ADR-036.
1935    HomologyGroups { chain_index: u32 },
1936    /// ψ_4 (wiki ADR-035): Betti-number extraction — HomologyGroups → BettiNumbers.
1937    /// Pure computation on resolved homology groups; no resolver consultation.
1938    /// Lowered from `betti(<homology_expr>)` (G24).
1939    Betti { homology_index: u32 },
1940    /// ψ_5 (wiki ADR-035): dualization functor — ChainComplex → CochainComplex.
1941    /// `C^k = Hom(C_k, R)`.
1942    /// Lowered from `cochain_complex(<chain_expr>)` (G25).
1943    /// Resolver-bound: CochainComplexResolver per ADR-036.
1944    CochainComplex { chain_index: u32 },
1945    /// ψ_6 (wiki ADR-035): cohomology functor — CochainComplex → CohomologyGroups.
1946    /// `H^k(C) = ker(δ^k) / im(δ^{k-1})`.
1947    /// Lowered from `cohomology_groups(<cochain_expr>)` (G26).
1948    /// Resolver-bound: CohomologyGroupResolver per ADR-036.
1949    CohomologyGroups { cochain_index: u32 },
1950    /// ψ_7 (wiki ADR-035): Kan-completion + Postnikov truncation —
1951    /// SimplicialComplex → PostnikovTower. The PostnikovResolver performs
1952    /// the Kan-completion internally; verb authors do not need to construct
1953    /// KanComplex values explicitly.
1954    /// Lowered from `postnikov_tower(<simplicial_expr>)` (G27).
1955    /// Resolver-bound: PostnikovResolver per ADR-036.
1956    PostnikovTower { simplicial_index: u32 },
1957    /// ψ_8 (wiki ADR-035): homotopy extraction — PostnikovTower → HomotopyGroups.
1958    /// π_k from each truncation stage.
1959    /// Lowered from `homotopy_groups(<postnikov_expr>)` (G28).
1960    /// Resolver-bound: HomotopyGroupResolver per ADR-036.
1961    HomotopyGroups { postnikov_index: u32 },
1962    /// ψ_9 (wiki ADR-035): k-invariant computation — HomotopyGroups → KInvariants.
1963    /// κ_k classifying the Postnikov tower.
1964    /// Lowered from `k_invariants(<homotopy_expr>)` (G29).
1965    /// Resolver-bound: KInvariantResolver per ADR-036.
1966    KInvariants { homotopy_index: u32 },
1967}
1968
1969/// Wiki ADR-024 verb-graph compile-time inlining: shift the arena-index
1970/// fields of `term` by `offset`. Used by [`inline_verb_fragment`] to
1971/// inline a verb's term-tree fragment into a host arena at compile time.
1972/// `Term::Variable`'s `name_index` is a binding-name reference (not an
1973/// arena index) and is preserved unchanged. `Term::Try`'s `handler_index`
1974/// is preserved unchanged when it equals `u32::MAX` (the default-
1975/// propagation sentinel per ADR-022 D3 G9).
1976#[must_use]
1977pub const fn shift_term(term: Term, offset: u32) -> Term {
1978    match term {
1979        Term::Literal { value, level } => Term::Literal { value, level },
1980        // name_index is a binding-name reference, not an arena index.
1981        Term::Variable { name_index } => Term::Variable { name_index },
1982        Term::Application { operator, args } => Term::Application {
1983            operator,
1984            args: TermList {
1985                start: args.start + offset,
1986                len: args.len,
1987            },
1988        },
1989        Term::Lift {
1990            operand_index,
1991            target,
1992        } => Term::Lift {
1993            operand_index: operand_index + offset,
1994            target,
1995        },
1996        Term::Project {
1997            operand_index,
1998            target,
1999        } => Term::Project {
2000            operand_index: operand_index + offset,
2001            target,
2002        },
2003        Term::Match {
2004            scrutinee_index,
2005            arms,
2006        } => Term::Match {
2007            scrutinee_index: scrutinee_index + offset,
2008            arms: TermList {
2009                start: arms.start + offset,
2010                len: arms.len,
2011            },
2012        },
2013        Term::Recurse {
2014            measure_index,
2015            base_index,
2016            step_index,
2017        } => Term::Recurse {
2018            measure_index: measure_index + offset,
2019            base_index: base_index + offset,
2020            step_index: step_index + offset,
2021        },
2022        Term::Unfold {
2023            seed_index,
2024            step_index,
2025        } => Term::Unfold {
2026            seed_index: seed_index + offset,
2027            step_index: step_index + offset,
2028        },
2029        Term::Try {
2030            body_index,
2031            handler_index,
2032        } => Term::Try {
2033            body_index: body_index + offset,
2034            handler_index: if handler_index == u32::MAX {
2035                u32::MAX
2036            } else {
2037                handler_index + offset
2038            },
2039        },
2040        Term::AxisInvocation {
2041            axis_index,
2042            kernel_id,
2043            input_index,
2044        } => Term::AxisInvocation {
2045            axis_index,
2046            kernel_id,
2047            input_index: input_index + offset,
2048        },
2049        Term::ProjectField {
2050            source_index,
2051            byte_offset,
2052            byte_length,
2053        } => Term::ProjectField {
2054            source_index: source_index + offset,
2055            byte_offset,
2056            byte_length,
2057        },
2058        Term::FirstAdmit {
2059            domain_size_index,
2060            predicate_index,
2061        } => Term::FirstAdmit {
2062            domain_size_index: domain_size_index + offset,
2063            predicate_index: predicate_index + offset,
2064        },
2065        Term::Nerve { value_index } => Term::Nerve {
2066            value_index: value_index + offset,
2067        },
2068        Term::ChainComplex { simplicial_index } => Term::ChainComplex {
2069            simplicial_index: simplicial_index + offset,
2070        },
2071        Term::HomologyGroups { chain_index } => Term::HomologyGroups {
2072            chain_index: chain_index + offset,
2073        },
2074        Term::Betti { homology_index } => Term::Betti {
2075            homology_index: homology_index + offset,
2076        },
2077        Term::CochainComplex { chain_index } => Term::CochainComplex {
2078            chain_index: chain_index + offset,
2079        },
2080        Term::CohomologyGroups { cochain_index } => Term::CohomologyGroups {
2081            cochain_index: cochain_index + offset,
2082        },
2083        Term::PostnikovTower { simplicial_index } => Term::PostnikovTower {
2084            simplicial_index: simplicial_index + offset,
2085        },
2086        Term::HomotopyGroups { postnikov_index } => Term::HomotopyGroups {
2087            postnikov_index: postnikov_index + offset,
2088        },
2089        Term::KInvariants { homotopy_index } => Term::KInvariants {
2090            homotopy_index: homotopy_index + offset,
2091        },
2092    }
2093}
2094
2095/// Wiki ADR-024 compile-time verb-fragment inlining helper.
2096/// Copies the verb `fragment` slice into `buf` starting at `len` while applying
2097/// two simultaneous transformations per term so the verb body becomes part of
2098/// the calling route's flat arena: Variable(0) substitution (the verb's `input`
2099/// parameter binds to the caller's argument expression by replacing each
2100/// `Variable { name_index: 0 }` with a copy of `buf[arg_root_idx]`), and arena-
2101/// index shifting (every non-Variable(0) term has its arena-index fields shifted
2102/// by `len` so internal references resolve correctly within the host).
2103/// The combined transformation realises ADR-024's compile-time inlining: the
2104/// verb body lands in the host arena with its `input` bound to the caller's
2105/// argument expression — verb-graph acyclicity is checked at const-eval time,
2106/// no `Term::VerbReference` variant or runtime depth guard is required.
2107/// # Panics
2108/// Panics at const-eval time if `len + fragment.len() > CAP` or if
2109/// `arg_root_idx as usize >= len`.
2110#[must_use]
2111pub const fn inline_verb_fragment<const CAP: usize>(
2112    mut buf: [Term; CAP],
2113    mut len: usize,
2114    fragment: &[Term],
2115    arg_root_idx: u32,
2116) -> ([Term; CAP], usize) {
2117    let offset = len as u32;
2118    // Capture a copy of the caller's argument root term; `Variable { name_index: 0 }`
2119    // occurrences in the fragment are replaced by this copy per ADR-024.
2120    let arg_root_term = buf[arg_root_idx as usize];
2121    let mut i = 0;
2122    while i < fragment.len() {
2123        let term = fragment[i];
2124        let new_term = match term {
2125            Term::Variable { name_index: 0 } => arg_root_term,
2126            other => shift_term(other, offset),
2127        };
2128        buf[len] = new_term;
2129        len += 1;
2130        i += 1;
2131    }
2132    (buf, len)
2133}
2134
2135/// A type declaration with constraint kinds.
2136#[derive(Debug, Clone, PartialEq, Eq)]
2137pub struct TypeDeclaration {
2138    /// Name index for this type.
2139    pub name_index: u32,
2140    /// Constraint terms (indices into arena).
2141    pub constraints: TermList,
2142}
2143
2144/// A named binding: `let name : Type = term`.
2145#[derive(Debug, Clone, PartialEq, Eq)]
2146pub struct Binding {
2147    /// Name index for this binding.
2148    pub name_index: u32,
2149    /// Index of the type declaration.
2150    pub type_index: u32,
2151    /// Index of the value term in the arena.
2152    pub value_index: u32,
2153    /// EBNF surface syntax (compile-time constant).
2154    pub surface: &'static str,
2155    /// FNV-1a content address (compile-time constant).
2156    pub content_address: u64,
2157}
2158
2159impl Binding {
2160    /// v0.2.2 Phase P.3: lift this binding to the `BindingEntry` shape consumed by
2161    /// `BindingsTable`. `address` is derived from `content_address` via
2162    /// `ContentAddress::from_u64_fingerprint`; `bytes` re-uses the `surface` slice.
2163    /// Content-deterministic; const-compatible since all fields are `'static`.
2164    #[inline]
2165    #[must_use]
2166    pub const fn to_binding_entry(&self) -> BindingEntry {
2167        BindingEntry {
2168            address: ContentAddress::from_u64_fingerprint(self.content_address),
2169            bytes: self.surface.as_bytes(),
2170        }
2171    }
2172}
2173
2174/// An assertion: `assert lhs = rhs`.
2175#[derive(Debug, Clone, PartialEq, Eq)]
2176pub struct Assertion {
2177    /// Index of the left-hand side term.
2178    pub lhs_index: u32,
2179    /// Index of the right-hand side term.
2180    pub rhs_index: u32,
2181    /// EBNF surface syntax (compile-time constant).
2182    pub surface: &'static str,
2183}
2184
2185/// Boundary source declaration: `source name : Type via grounding`.
2186#[derive(Debug, Clone, PartialEq, Eq)]
2187pub struct SourceDeclaration {
2188    /// Name index for the source.
2189    pub name_index: u32,
2190    /// Index of the type declaration.
2191    pub type_index: u32,
2192    /// Name index of the grounding map.
2193    pub grounding_name_index: u32,
2194}
2195
2196/// Boundary sink declaration: `sink name : Type via projection`.
2197#[derive(Debug, Clone, PartialEq, Eq)]
2198pub struct SinkDeclaration {
2199    /// Name index for the sink.
2200    pub name_index: u32,
2201    /// Index of the type declaration.
2202    pub type_index: u32,
2203    /// Name index of the projection map.
2204    pub projection_name_index: u32,
2205}
2206
2207/// Structured violation diagnostic carrying metadata from the
2208/// conformance namespace. Every field is machine-readable.
2209/// # Examples
2210/// ```rust
2211/// use uor_foundation::enforcement::ShapeViolation;
2212/// use uor_foundation::ViolationKind;
2213///
2214/// // ShapeViolation carries structured metadata from the ontology.
2215/// // Every field is machine-readable — IRIs, counts, and a typed kind.
2216/// let violation = ShapeViolation {
2217///     shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2218///     constraint_iri: "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2219///     property_iri: "https://uor.foundation/reduction/rootTerm",
2220///     expected_range: "https://uor.foundation/schema/Term",
2221///     min_count: 1,
2222///     max_count: 1,
2223///     kind: ViolationKind::Missing,
2224/// };
2225///
2226/// // Machine-readable for tooling (IDE plugins, CI pipelines):
2227/// assert_eq!(violation.kind, ViolationKind::Missing);
2228/// assert!(violation.shape_iri.ends_with("CompileUnitShape"));
2229/// assert_eq!(violation.min_count, 1);
2230/// ```
2231#[derive(Debug, Clone, PartialEq, Eq)]
2232pub struct ShapeViolation {
2233    /// IRI of the `conformance:Shape` that was validated against.
2234    pub shape_iri: &'static str,
2235    /// IRI of the specific `conformance:PropertyConstraint` that failed.
2236    pub constraint_iri: &'static str,
2237    /// IRI of the property that was missing or invalid.
2238    pub property_iri: &'static str,
2239    /// The expected range class IRI.
2240    pub expected_range: &'static str,
2241    /// Minimum cardinality from the constraint.
2242    pub min_count: u32,
2243    /// Maximum cardinality (0 = unbounded).
2244    pub max_count: u32,
2245    /// What went wrong.
2246    pub kind: ViolationKind,
2247}
2248
2249impl core::fmt::Display for ShapeViolation {
2250    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2251        write!(
2252            f,
2253            "shape violation: {} (constraint {}, property {}, kind {:?})",
2254            self.shape_iri, self.constraint_iri, self.property_iri, self.kind,
2255        )
2256    }
2257}
2258
2259impl core::error::Error for ShapeViolation {}
2260
2261impl ShapeViolation {
2262    /// Phase C.3: returns the shape IRI as a `&'static str` suitable for
2263    /// `const fn` panic messages. The IRI uniquely identifies the violated
2264    /// constraint in the conformance catalog.
2265    #[inline]
2266    #[must_use]
2267    pub const fn const_message(&self) -> &'static str {
2268        self.shape_iri
2269    }
2270}
2271
2272/// Builder for `CompileUnit` admission into the reduction pipeline.
2273/// Collects `rootTerm`, `wittLevelCeiling`, `thermodynamicBudget`,
2274/// and `targetDomains`. The `validate()` method checks structural
2275/// constraints (Tier 1) and value-dependent constraints (Tier 2).
2276/// # Examples
2277/// ```rust
2278/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
2279/// use uor_foundation::{WittLevel, VerificationDomain, ViolationKind};
2280///
2281/// // A CompileUnit packages a term graph for reduction admission.
2282/// // The builder enforces that all required fields are present.
2283/// let terms = [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
2284/// let domains = [VerificationDomain::Enumerative];
2285///
2286/// let unit = CompileUnitBuilder::new()
2287///     .root_term(&terms)
2288///     .witt_level_ceiling(WittLevel::W8)
2289///     .thermodynamic_budget(1024)
2290///     .target_domains(&domains)
2291///     .result_type::<ConstrainedTypeInput>()
2292///     .validate();
2293/// assert!(unit.is_ok());
2294///
2295/// // Omitting a required field produces a ShapeViolation
2296/// // with the exact conformance IRI that failed:
2297/// let err = CompileUnitBuilder::new()
2298///     .witt_level_ceiling(WittLevel::W8)
2299///     .thermodynamic_budget(1024)
2300///     .target_domains(&domains)
2301///     .result_type::<ConstrainedTypeInput>()
2302///     .validate();
2303/// assert!(err.is_err());
2304/// if let Err(violation) = err {
2305///     assert_eq!(violation.kind, ViolationKind::Missing);
2306///     assert!(violation.property_iri.contains("rootTerm"));
2307/// }
2308/// ```
2309#[derive(Debug, Clone)]
2310pub struct CompileUnitBuilder<'a> {
2311    /// The root term expression.
2312    root_term: Option<&'a [Term]>,
2313    /// v0.2.2 Phase H1: named bindings (`let name : Type = term` forms)
2314    /// declared by the compile unit. Stage 5 extracts these into a `BindingsTable`
2315    /// for grounding-aware and session resolvers; an empty slice declares no bindings.
2316    bindings: Option<&'a [Binding]>,
2317    /// The widest Witt level the computation may reference.
2318    witt_level_ceiling: Option<WittLevel>,
2319    /// Landauer-bounded energy budget.
2320    thermodynamic_budget: Option<u64>,
2321    /// Verification domains targeted.
2322    target_domains: Option<&'a [VerificationDomain]>,
2323    /// v0.2.2 T6.11: result-type IRI for ShapeMismatch detection.
2324    /// Set via `result_type::<T: ConstrainedTypeShape>()`. Required by
2325    /// `validate()` and `validate_compile_unit_const`. The pipeline checks
2326    /// `unit.result_type_iri() == T::IRI` at `pipeline::run` invocation
2327    /// time, returning `PipelineFailure::ShapeMismatch` on mismatch.
2328    result_type_iri: Option<&'static str>,
2329}
2330
2331/// A validated compile unit ready for reduction admission.
2332/// v0.2.2 Phase A (carrier widening): the lifetime parameter `'a` ties
2333/// the post-validation carrier to its builder's borrow. The `root_term`
2334/// and `target_domains` slices are retained through validation so
2335/// resolvers can inspect declared structure — previously these fields
2336/// were discarded at `validate()` and every resolver received a
2337/// 3-field scalar witness with no walkable structure.
2338/// Const-constructed compile units use the trivial specialization
2339/// `CompileUnit<'static>` — borrow-free and usable in const contexts.
2340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2341pub struct CompileUnit<'a> {
2342    /// The Witt level ceiling.
2343    level: WittLevel,
2344    /// The thermodynamic budget.
2345    budget: u64,
2346    /// v0.2.2 T6.11: result-type IRI. The pipeline matches this against
2347    /// the caller's `T::IRI` to detect shape mismatches.
2348    result_type_iri: &'static str,
2349    /// v0.2.2 Phase A: root term expression, retained from the builder.
2350    /// Stage 5 (extract bindings) and the grounding-aware resolver walk
2351    /// this slice. Empty slice for the trivial `CompileUnit<'static>`
2352    /// specialization produced by builders that don't carry a term AST.
2353    root_term: &'a [Term],
2354    /// v0.2.2 Phase H1: named bindings retained from the builder. Consumed by Stage 5
2355    /// (`bindings_from_unit`) to materialize the `BindingsTable` for grounding-aware,
2356    /// session, and superposition resolvers. Empty slice declares no bindings.
2357    bindings: &'a [Binding],
2358    /// v0.2.2 Phase A: verification domains targeted, retained from the builder.
2359    target_domains: &'a [VerificationDomain],
2360}
2361
2362impl<'a> CompileUnit<'a> {
2363    /// Returns the Witt level ceiling declared at validation time.
2364    #[inline]
2365    #[must_use]
2366    pub const fn witt_level(&self) -> WittLevel {
2367        self.level
2368    }
2369
2370    /// Returns the thermodynamic budget declared at validation time.
2371    #[inline]
2372    #[must_use]
2373    pub const fn thermodynamic_budget(&self) -> u64 {
2374        self.budget
2375    }
2376
2377    /// v0.2.2 T6.11: returns the result-type IRI declared at validation
2378    /// time. The pipeline matches this against the caller's `T::IRI` to
2379    /// detect shape mismatches.
2380    #[inline]
2381    #[must_use]
2382    pub const fn result_type_iri(&self) -> &'static str {
2383        self.result_type_iri
2384    }
2385
2386    /// v0.2.2 Phase A: returns the root term slice declared at validation time.
2387    /// Empty for builders that did not supply a term AST.
2388    #[inline]
2389    #[must_use]
2390    pub const fn root_term(&self) -> &'a [Term] {
2391        self.root_term
2392    }
2393
2394    /// v0.2.2 Phase H1: returns the named bindings declared at validation time.
2395    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the `BindingsTable`.
2396    /// Empty slice for compile units that declare no bindings.
2397    #[inline]
2398    #[must_use]
2399    pub const fn bindings(&self) -> &'a [Binding] {
2400        self.bindings
2401    }
2402
2403    /// v0.2.2 Phase A: returns the verification domains declared at validation time.
2404    #[inline]
2405    #[must_use]
2406    pub const fn target_domains(&self) -> &'a [VerificationDomain] {
2407        self.target_domains
2408    }
2409
2410    /// v0.2.2 Phase G / T2.8 + T6.11: const-constructible parts form used
2411    /// by `validate_compile_unit_const` — the const-fn path reads the
2412    /// builder's fields and packs them into the `Validated` result.
2413    /// v0.2.2 Phase H1: bindings slice is retained alongside root_term;
2414    /// empty slice declares no bindings.
2415    #[inline]
2416    #[must_use]
2417    pub(crate) const fn from_parts_const(
2418        level: WittLevel,
2419        budget: u64,
2420        result_type_iri: &'static str,
2421        root_term: &'a [Term],
2422        bindings: &'a [Binding],
2423        target_domains: &'a [VerificationDomain],
2424    ) -> Self {
2425        Self {
2426            level,
2427            budget,
2428            result_type_iri,
2429            root_term,
2430            bindings,
2431            target_domains,
2432        }
2433    }
2434}
2435
2436impl<'a> CompileUnitBuilder<'a> {
2437    /// Creates a new empty builder.
2438    #[must_use]
2439    pub const fn new() -> Self {
2440        Self {
2441            root_term: None,
2442            bindings: None,
2443            witt_level_ceiling: None,
2444            thermodynamic_budget: None,
2445            target_domains: None,
2446            result_type_iri: None,
2447        }
2448    }
2449
2450    /// Set the root term expression.
2451    #[must_use]
2452    pub const fn root_term(mut self, terms: &'a [Term]) -> Self {
2453        self.root_term = Some(terms);
2454        self
2455    }
2456
2457    /// v0.2.2 Phase H1: set the named bindings declared by this compile unit.
2458    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the
2459    /// `BindingsTable` for grounding-aware, session, and superposition resolvers.
2460    /// Omit for compile units without bindings; the default is the empty slice.
2461    #[must_use]
2462    pub const fn bindings(mut self, bindings: &'a [Binding]) -> Self {
2463        self.bindings = Some(bindings);
2464        self
2465    }
2466
2467    /// Set the Witt level ceiling.
2468    #[must_use]
2469    pub const fn witt_level_ceiling(mut self, level: WittLevel) -> Self {
2470        self.witt_level_ceiling = Some(level);
2471        self
2472    }
2473
2474    /// Set the thermodynamic budget.
2475    #[must_use]
2476    pub const fn thermodynamic_budget(mut self, budget: u64) -> Self {
2477        self.thermodynamic_budget = Some(budget);
2478        self
2479    }
2480
2481    /// Set the target verification domains.
2482    #[must_use]
2483    pub const fn target_domains(mut self, domains: &'a [VerificationDomain]) -> Self {
2484        self.target_domains = Some(domains);
2485        self
2486    }
2487
2488    /// v0.2.2 T6.11: set the result-type IRI from a `ConstrainedTypeShape`
2489    /// type parameter. The pipeline matches this against the caller's
2490    /// `T::IRI` at `pipeline::run` invocation time, returning
2491    /// `PipelineFailure::ShapeMismatch` on mismatch.
2492    /// Required: `validate()` and `validate_compile_unit_const` reject
2493    /// builders without a result type set.
2494    #[must_use]
2495    pub const fn result_type<T: crate::pipeline::ConstrainedTypeShape>(mut self) -> Self {
2496        self.result_type_iri = Some(T::IRI);
2497        self
2498    }
2499
2500    /// v0.2.2 T2.8: const-fn accessor exposing the stored Witt level
2501    /// ceiling (or `None` if unset). Used by `validate_compile_unit_const`.
2502    #[inline]
2503    #[must_use]
2504    pub const fn witt_level_option(&self) -> Option<WittLevel> {
2505        self.witt_level_ceiling
2506    }
2507
2508    /// v0.2.2 T2.8: const-fn accessor exposing the stored thermodynamic
2509    /// budget (or `None` if unset).
2510    #[inline]
2511    #[must_use]
2512    pub const fn budget_option(&self) -> Option<u64> {
2513        self.thermodynamic_budget
2514    }
2515
2516    /// v0.2.2 T6.13: const-fn accessor — `true` iff `root_term` is set.
2517    #[inline]
2518    #[must_use]
2519    pub const fn has_root_term_const(&self) -> bool {
2520        self.root_term.is_some()
2521    }
2522
2523    /// v0.2.2 T6.13: const-fn accessor — `true` iff `target_domains` is
2524    /// set and non-empty.
2525    #[inline]
2526    #[must_use]
2527    pub const fn has_target_domains_const(&self) -> bool {
2528        match self.target_domains {
2529            Some(d) => !d.is_empty(),
2530            None => false,
2531        }
2532    }
2533
2534    /// v0.2.2 T6.13: const-fn accessor exposing the stored result-type IRI
2535    /// (or `None` if unset). Used by `validate_compile_unit_const`.
2536    #[inline]
2537    #[must_use]
2538    pub const fn result_type_iri_const(&self) -> Option<&'static str> {
2539        self.result_type_iri
2540    }
2541
2542    /// v0.2.2 Phase A: const-fn accessor exposing the stored root-term slice,
2543    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2544    /// propagate the AST into the widened `CompileUnit<'a>` carrier.
2545    #[inline]
2546    #[must_use]
2547    pub const fn root_term_slice_const(&self) -> &'a [Term] {
2548        match self.root_term {
2549            Some(terms) => terms,
2550            None => &[],
2551        }
2552    }
2553
2554    /// v0.2.2 Phase H1: const-fn accessor exposing the stored bindings slice,
2555    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2556    /// propagate the bindings declaration into the widened `CompileUnit<'a>` carrier.
2557    #[inline]
2558    #[must_use]
2559    pub const fn bindings_slice_const(&self) -> &'a [Binding] {
2560        match self.bindings {
2561            Some(bindings) => bindings,
2562            None => &[],
2563        }
2564    }
2565
2566    /// v0.2.2 Phase A: const-fn accessor exposing the stored target-domains
2567    /// slice, or an empty slice if unset. Used by `validate_compile_unit_const`.
2568    #[inline]
2569    #[must_use]
2570    pub const fn target_domains_slice_const(&self) -> &'a [VerificationDomain] {
2571        match self.target_domains {
2572            Some(d) => d,
2573            None => &[],
2574        }
2575    }
2576
2577    /// Validate against `CompileUnitShape`.
2578    /// Tier 1: checks presence and cardinality of all required fields.
2579    /// Tier 2: checks budget solvency and level coherence.
2580    /// # Errors
2581    /// Returns `ShapeViolation` if any constraint is not satisfied.
2582    pub fn validate(self) -> Result<Validated<CompileUnit<'a>>, ShapeViolation> {
2583        let root_term = match self.root_term {
2584            Some(terms) => terms,
2585            None => {
2586                return Err(ShapeViolation {
2587                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2588                    constraint_iri:
2589                        "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2590                    property_iri: "https://uor.foundation/reduction/rootTerm",
2591                    expected_range: "https://uor.foundation/schema/Term",
2592                    min_count: 1,
2593                    max_count: 1,
2594                    kind: ViolationKind::Missing,
2595                })
2596            }
2597        };
2598        let level =
2599            match self.witt_level_ceiling {
2600                Some(l) => l,
2601                None => return Err(ShapeViolation {
2602                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2603                    constraint_iri:
2604                        "https://uor.foundation/conformance/compileUnit_unitWittLevel_constraint",
2605                    property_iri: "https://uor.foundation/reduction/unitWittLevel",
2606                    expected_range: "https://uor.foundation/schema/WittLevel",
2607                    min_count: 1,
2608                    max_count: 1,
2609                    kind: ViolationKind::Missing,
2610                }),
2611            };
2612        let budget = match self.thermodynamic_budget {
2613            Some(b) => b,
2614            None => return Err(ShapeViolation {
2615                shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2616                constraint_iri:
2617                    "https://uor.foundation/conformance/compileUnit_thermodynamicBudget_constraint",
2618                property_iri: "https://uor.foundation/reduction/thermodynamicBudget",
2619                expected_range: "http://www.w3.org/2001/XMLSchema#decimal",
2620                min_count: 1,
2621                max_count: 1,
2622                kind: ViolationKind::Missing,
2623            }),
2624        };
2625        let target_domains =
2626            match self.target_domains {
2627                Some(d) if !d.is_empty() => d,
2628                _ => return Err(ShapeViolation {
2629                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2630                    constraint_iri:
2631                        "https://uor.foundation/conformance/compileUnit_targetDomains_constraint",
2632                    property_iri: "https://uor.foundation/reduction/targetDomains",
2633                    expected_range: "https://uor.foundation/op/VerificationDomain",
2634                    min_count: 1,
2635                    max_count: 0,
2636                    kind: ViolationKind::Missing,
2637                }),
2638            };
2639        let result_type_iri = match self.result_type_iri {
2640            Some(iri) => iri,
2641            None => {
2642                return Err(ShapeViolation {
2643                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2644                    constraint_iri:
2645                        "https://uor.foundation/conformance/compileUnit_resultType_constraint",
2646                    property_iri: "https://uor.foundation/reduction/resultType",
2647                    expected_range: "https://uor.foundation/type/ConstrainedType",
2648                    min_count: 1,
2649                    max_count: 1,
2650                    kind: ViolationKind::Missing,
2651                })
2652            }
2653        };
2654        // v0.2.2 Phase H1: bindings is optional; absent declares no bindings.
2655        let bindings: &'a [Binding] = match self.bindings {
2656            Some(b) => b,
2657            None => &[],
2658        };
2659        Ok(Validated::new(CompileUnit {
2660            level,
2661            budget,
2662            result_type_iri,
2663            root_term,
2664            bindings,
2665            target_domains,
2666        }))
2667    }
2668}
2669
2670impl<'a> Default for CompileUnitBuilder<'a> {
2671    fn default() -> Self {
2672        Self::new()
2673    }
2674}
2675
2676/// Builder for `EffectDeclaration`. Validates against `EffectShape`.
2677#[derive(Debug, Clone)]
2678pub struct EffectDeclarationBuilder<'a> {
2679    /// The `name` field.
2680    name: Option<&'a str>,
2681    /// The `target_sites` field.
2682    target_sites: Option<&'a [u32]>,
2683    /// The `budget_delta` field.
2684    budget_delta: Option<i64>,
2685    /// The `commutes` field.
2686    commutes: Option<bool>,
2687}
2688
2689/// Declared effect validated against `EffectShape`.
2690#[derive(Debug, Clone, PartialEq, Eq)]
2691pub struct EffectDeclaration {
2692    /// Shape IRI this declaration was validated against.
2693    pub shape_iri: &'static str,
2694}
2695
2696impl EffectDeclaration {
2697    /// v0.2.2 Phase G: const-constructible empty form used by
2698    /// `validate_*_const` companion functions.
2699    #[inline]
2700    #[must_use]
2701    #[allow(dead_code)]
2702    pub(crate) const fn empty_const() -> Self {
2703        Self {
2704            shape_iri: "https://uor.foundation/conformance/EffectShape",
2705        }
2706    }
2707}
2708
2709impl<'a> EffectDeclarationBuilder<'a> {
2710    /// Creates a new empty builder.
2711    #[must_use]
2712    pub const fn new() -> Self {
2713        Self {
2714            name: None,
2715            target_sites: None,
2716            budget_delta: None,
2717            commutes: None,
2718        }
2719    }
2720
2721    /// Set the `name` field.
2722    #[must_use]
2723    pub const fn name(mut self, value: &'a str) -> Self {
2724        self.name = Some(value);
2725        self
2726    }
2727
2728    /// Set the `target_sites` field.
2729    #[must_use]
2730    pub const fn target_sites(mut self, value: &'a [u32]) -> Self {
2731        self.target_sites = Some(value);
2732        self
2733    }
2734
2735    /// Set the `budget_delta` field.
2736    #[must_use]
2737    pub const fn budget_delta(mut self, value: i64) -> Self {
2738        self.budget_delta = Some(value);
2739        self
2740    }
2741
2742    /// Set the `commutes` field.
2743    #[must_use]
2744    pub const fn commutes(mut self, value: bool) -> Self {
2745        self.commutes = Some(value);
2746        self
2747    }
2748
2749    /// Validate against `EffectShape`.
2750    /// # Errors
2751    /// Returns `ShapeViolation` if any required field is missing.
2752    pub fn validate(self) -> Result<Validated<EffectDeclaration>, ShapeViolation> {
2753        if self.name.is_none() {
2754            return Err(ShapeViolation {
2755                shape_iri: "https://uor.foundation/conformance/EffectShape",
2756                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2757                property_iri: "https://uor.foundation/conformance/name",
2758                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2759                min_count: 1,
2760                max_count: 1,
2761                kind: ViolationKind::Missing,
2762            });
2763        }
2764        if self.target_sites.is_none() {
2765            return Err(ShapeViolation {
2766                shape_iri: "https://uor.foundation/conformance/EffectShape",
2767                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2768                property_iri: "https://uor.foundation/conformance/target_sites",
2769                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2770                min_count: 1,
2771                max_count: 1,
2772                kind: ViolationKind::Missing,
2773            });
2774        }
2775        if self.budget_delta.is_none() {
2776            return Err(ShapeViolation {
2777                shape_iri: "https://uor.foundation/conformance/EffectShape",
2778                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2779                property_iri: "https://uor.foundation/conformance/budget_delta",
2780                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2781                min_count: 1,
2782                max_count: 1,
2783                kind: ViolationKind::Missing,
2784            });
2785        }
2786        if self.commutes.is_none() {
2787            return Err(ShapeViolation {
2788                shape_iri: "https://uor.foundation/conformance/EffectShape",
2789                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2790                property_iri: "https://uor.foundation/conformance/commutes",
2791                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2792                min_count: 1,
2793                max_count: 1,
2794                kind: ViolationKind::Missing,
2795            });
2796        }
2797        Ok(Validated::new(EffectDeclaration {
2798            shape_iri: "https://uor.foundation/conformance/EffectShape",
2799        }))
2800    }
2801
2802    /// Phase C.1: const-fn companion for `EffectDeclarationBuilder::validate`.
2803    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2804    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2805    /// # Errors
2806    /// Returns `ShapeViolation` if any required field is missing.
2807    pub const fn validate_const(
2808        &self,
2809    ) -> Result<Validated<EffectDeclaration, CompileTime>, ShapeViolation> {
2810        if self.name.is_none() {
2811            return Err(ShapeViolation {
2812                shape_iri: "https://uor.foundation/conformance/EffectShape",
2813                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2814                property_iri: "https://uor.foundation/conformance/name",
2815                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2816                min_count: 1,
2817                max_count: 1,
2818                kind: ViolationKind::Missing,
2819            });
2820        }
2821        if self.target_sites.is_none() {
2822            return Err(ShapeViolation {
2823                shape_iri: "https://uor.foundation/conformance/EffectShape",
2824                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2825                property_iri: "https://uor.foundation/conformance/target_sites",
2826                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2827                min_count: 1,
2828                max_count: 1,
2829                kind: ViolationKind::Missing,
2830            });
2831        }
2832        if self.budget_delta.is_none() {
2833            return Err(ShapeViolation {
2834                shape_iri: "https://uor.foundation/conformance/EffectShape",
2835                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2836                property_iri: "https://uor.foundation/conformance/budget_delta",
2837                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2838                min_count: 1,
2839                max_count: 1,
2840                kind: ViolationKind::Missing,
2841            });
2842        }
2843        if self.commutes.is_none() {
2844            return Err(ShapeViolation {
2845                shape_iri: "https://uor.foundation/conformance/EffectShape",
2846                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2847                property_iri: "https://uor.foundation/conformance/commutes",
2848                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2849                min_count: 1,
2850                max_count: 1,
2851                kind: ViolationKind::Missing,
2852            });
2853        }
2854        Ok(Validated::new(EffectDeclaration {
2855            shape_iri: "https://uor.foundation/conformance/EffectShape",
2856        }))
2857    }
2858}
2859
2860impl<'a> Default for EffectDeclarationBuilder<'a> {
2861    fn default() -> Self {
2862        Self::new()
2863    }
2864}
2865
2866/// Builder for `GroundingDeclaration`. Validates against `GroundingShape`.
2867#[derive(Debug, Clone)]
2868pub struct GroundingDeclarationBuilder<'a> {
2869    /// The `source_type` field.
2870    source_type: Option<&'a str>,
2871    /// The `ring_mapping` field.
2872    ring_mapping: Option<&'a str>,
2873    /// The `invertibility` field.
2874    invertibility: Option<bool>,
2875}
2876
2877/// Declared grounding validated against `GroundingShape`.
2878#[derive(Debug, Clone, PartialEq, Eq)]
2879pub struct GroundingDeclaration {
2880    /// Shape IRI this declaration was validated against.
2881    pub shape_iri: &'static str,
2882}
2883
2884impl GroundingDeclaration {
2885    /// v0.2.2 Phase G: const-constructible empty form used by
2886    /// `validate_*_const` companion functions.
2887    #[inline]
2888    #[must_use]
2889    #[allow(dead_code)]
2890    pub(crate) const fn empty_const() -> Self {
2891        Self {
2892            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2893        }
2894    }
2895}
2896
2897impl<'a> GroundingDeclarationBuilder<'a> {
2898    /// Creates a new empty builder.
2899    #[must_use]
2900    pub const fn new() -> Self {
2901        Self {
2902            source_type: None,
2903            ring_mapping: None,
2904            invertibility: None,
2905        }
2906    }
2907
2908    /// Set the `source_type` field.
2909    #[must_use]
2910    pub const fn source_type(mut self, value: &'a str) -> Self {
2911        self.source_type = Some(value);
2912        self
2913    }
2914
2915    /// Set the `ring_mapping` field.
2916    #[must_use]
2917    pub const fn ring_mapping(mut self, value: &'a str) -> Self {
2918        self.ring_mapping = Some(value);
2919        self
2920    }
2921
2922    /// Set the `invertibility` field.
2923    #[must_use]
2924    pub const fn invertibility(mut self, value: bool) -> Self {
2925        self.invertibility = Some(value);
2926        self
2927    }
2928
2929    /// Validate against `GroundingShape`.
2930    /// # Errors
2931    /// Returns `ShapeViolation` if any required field is missing.
2932    pub fn validate(self) -> Result<Validated<GroundingDeclaration>, ShapeViolation> {
2933        if self.source_type.is_none() {
2934            return Err(ShapeViolation {
2935                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2936                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2937                property_iri: "https://uor.foundation/conformance/source_type",
2938                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2939                min_count: 1,
2940                max_count: 1,
2941                kind: ViolationKind::Missing,
2942            });
2943        }
2944        if self.ring_mapping.is_none() {
2945            return Err(ShapeViolation {
2946                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2947                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2948                property_iri: "https://uor.foundation/conformance/ring_mapping",
2949                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2950                min_count: 1,
2951                max_count: 1,
2952                kind: ViolationKind::Missing,
2953            });
2954        }
2955        if self.invertibility.is_none() {
2956            return Err(ShapeViolation {
2957                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2958                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2959                property_iri: "https://uor.foundation/conformance/invertibility",
2960                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2961                min_count: 1,
2962                max_count: 1,
2963                kind: ViolationKind::Missing,
2964            });
2965        }
2966        Ok(Validated::new(GroundingDeclaration {
2967            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2968        }))
2969    }
2970
2971    /// Phase C.1: const-fn companion for `GroundingDeclarationBuilder::validate`.
2972    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2973    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2974    /// # Errors
2975    /// Returns `ShapeViolation` if any required field is missing.
2976    pub const fn validate_const(
2977        &self,
2978    ) -> Result<Validated<GroundingDeclaration, CompileTime>, ShapeViolation> {
2979        if self.source_type.is_none() {
2980            return Err(ShapeViolation {
2981                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2982                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2983                property_iri: "https://uor.foundation/conformance/source_type",
2984                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2985                min_count: 1,
2986                max_count: 1,
2987                kind: ViolationKind::Missing,
2988            });
2989        }
2990        if self.ring_mapping.is_none() {
2991            return Err(ShapeViolation {
2992                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2993                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2994                property_iri: "https://uor.foundation/conformance/ring_mapping",
2995                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2996                min_count: 1,
2997                max_count: 1,
2998                kind: ViolationKind::Missing,
2999            });
3000        }
3001        if self.invertibility.is_none() {
3002            return Err(ShapeViolation {
3003                shape_iri: "https://uor.foundation/conformance/GroundingShape",
3004                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
3005                property_iri: "https://uor.foundation/conformance/invertibility",
3006                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3007                min_count: 1,
3008                max_count: 1,
3009                kind: ViolationKind::Missing,
3010            });
3011        }
3012        Ok(Validated::new(GroundingDeclaration {
3013            shape_iri: "https://uor.foundation/conformance/GroundingShape",
3014        }))
3015    }
3016}
3017
3018impl<'a> Default for GroundingDeclarationBuilder<'a> {
3019    fn default() -> Self {
3020        Self::new()
3021    }
3022}
3023
3024/// Builder for `DispatchDeclaration`. Validates against `DispatchShape`.
3025#[derive(Debug, Clone)]
3026pub struct DispatchDeclarationBuilder<'a> {
3027    /// The `predicate` field.
3028    predicate: Option<&'a [Term]>,
3029    /// The `target_resolver` field.
3030    target_resolver: Option<&'a str>,
3031    /// The `priority` field.
3032    priority: Option<u32>,
3033}
3034
3035/// Declared dispatch rule validated against `DispatchShape`.
3036#[derive(Debug, Clone, PartialEq, Eq)]
3037pub struct DispatchDeclaration {
3038    /// Shape IRI this declaration was validated against.
3039    pub shape_iri: &'static str,
3040}
3041
3042impl DispatchDeclaration {
3043    /// v0.2.2 Phase G: const-constructible empty form used by
3044    /// `validate_*_const` companion functions.
3045    #[inline]
3046    #[must_use]
3047    #[allow(dead_code)]
3048    pub(crate) const fn empty_const() -> Self {
3049        Self {
3050            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3051        }
3052    }
3053}
3054
3055impl<'a> DispatchDeclarationBuilder<'a> {
3056    /// Creates a new empty builder.
3057    #[must_use]
3058    pub const fn new() -> Self {
3059        Self {
3060            predicate: None,
3061            target_resolver: None,
3062            priority: None,
3063        }
3064    }
3065
3066    /// Set the `predicate` field.
3067    #[must_use]
3068    pub const fn predicate(mut self, value: &'a [Term]) -> Self {
3069        self.predicate = Some(value);
3070        self
3071    }
3072
3073    /// Set the `target_resolver` field.
3074    #[must_use]
3075    pub const fn target_resolver(mut self, value: &'a str) -> Self {
3076        self.target_resolver = Some(value);
3077        self
3078    }
3079
3080    /// Set the `priority` field.
3081    #[must_use]
3082    pub const fn priority(mut self, value: u32) -> Self {
3083        self.priority = Some(value);
3084        self
3085    }
3086
3087    /// Validate against `DispatchShape`.
3088    /// # Errors
3089    /// Returns `ShapeViolation` if any required field is missing.
3090    pub fn validate(self) -> Result<Validated<DispatchDeclaration>, ShapeViolation> {
3091        if self.predicate.is_none() {
3092            return Err(ShapeViolation {
3093                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3094                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3095                property_iri: "https://uor.foundation/conformance/predicate",
3096                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3097                min_count: 1,
3098                max_count: 1,
3099                kind: ViolationKind::Missing,
3100            });
3101        }
3102        if self.target_resolver.is_none() {
3103            return Err(ShapeViolation {
3104                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3105                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3106                property_iri: "https://uor.foundation/conformance/target_resolver",
3107                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3108                min_count: 1,
3109                max_count: 1,
3110                kind: ViolationKind::Missing,
3111            });
3112        }
3113        if self.priority.is_none() {
3114            return Err(ShapeViolation {
3115                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3116                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3117                property_iri: "https://uor.foundation/conformance/priority",
3118                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3119                min_count: 1,
3120                max_count: 1,
3121                kind: ViolationKind::Missing,
3122            });
3123        }
3124        Ok(Validated::new(DispatchDeclaration {
3125            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3126        }))
3127    }
3128
3129    /// Phase C.1: const-fn companion for `DispatchDeclarationBuilder::validate`.
3130    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3131    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3132    /// # Errors
3133    /// Returns `ShapeViolation` if any required field is missing.
3134    pub const fn validate_const(
3135        &self,
3136    ) -> Result<Validated<DispatchDeclaration, CompileTime>, ShapeViolation> {
3137        if self.predicate.is_none() {
3138            return Err(ShapeViolation {
3139                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3140                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3141                property_iri: "https://uor.foundation/conformance/predicate",
3142                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3143                min_count: 1,
3144                max_count: 1,
3145                kind: ViolationKind::Missing,
3146            });
3147        }
3148        if self.target_resolver.is_none() {
3149            return Err(ShapeViolation {
3150                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3151                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3152                property_iri: "https://uor.foundation/conformance/target_resolver",
3153                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3154                min_count: 1,
3155                max_count: 1,
3156                kind: ViolationKind::Missing,
3157            });
3158        }
3159        if self.priority.is_none() {
3160            return Err(ShapeViolation {
3161                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3162                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3163                property_iri: "https://uor.foundation/conformance/priority",
3164                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3165                min_count: 1,
3166                max_count: 1,
3167                kind: ViolationKind::Missing,
3168            });
3169        }
3170        Ok(Validated::new(DispatchDeclaration {
3171            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3172        }))
3173    }
3174}
3175
3176impl<'a> Default for DispatchDeclarationBuilder<'a> {
3177    fn default() -> Self {
3178        Self::new()
3179    }
3180}
3181
3182/// Builder for `LeaseDeclaration`. Validates against `LeaseShape`.
3183#[derive(Debug, Clone)]
3184pub struct LeaseDeclarationBuilder<'a> {
3185    /// The `linear_site` field.
3186    linear_site: Option<u32>,
3187    /// The `scope` field.
3188    scope: Option<&'a str>,
3189}
3190
3191/// Declared lease validated against `LeaseShape`.
3192#[derive(Debug, Clone, PartialEq, Eq)]
3193pub struct LeaseDeclaration {
3194    /// Shape IRI this declaration was validated against.
3195    pub shape_iri: &'static str,
3196}
3197
3198impl LeaseDeclaration {
3199    /// v0.2.2 Phase G: const-constructible empty form used by
3200    /// `validate_*_const` companion functions.
3201    #[inline]
3202    #[must_use]
3203    #[allow(dead_code)]
3204    pub(crate) const fn empty_const() -> Self {
3205        Self {
3206            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3207        }
3208    }
3209}
3210
3211impl<'a> LeaseDeclarationBuilder<'a> {
3212    /// Creates a new empty builder.
3213    #[must_use]
3214    pub const fn new() -> Self {
3215        Self {
3216            linear_site: None,
3217            scope: None,
3218        }
3219    }
3220
3221    /// Set the `linear_site` field.
3222    #[must_use]
3223    pub const fn linear_site(mut self, value: u32) -> Self {
3224        self.linear_site = Some(value);
3225        self
3226    }
3227
3228    /// Set the `scope` field.
3229    #[must_use]
3230    pub const fn scope(mut self, value: &'a str) -> Self {
3231        self.scope = Some(value);
3232        self
3233    }
3234
3235    /// Validate against `LeaseShape`.
3236    /// # Errors
3237    /// Returns `ShapeViolation` if any required field is missing.
3238    pub fn validate(self) -> Result<Validated<LeaseDeclaration>, ShapeViolation> {
3239        if self.linear_site.is_none() {
3240            return Err(ShapeViolation {
3241                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3242                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3243                property_iri: "https://uor.foundation/conformance/linear_site",
3244                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3245                min_count: 1,
3246                max_count: 1,
3247                kind: ViolationKind::Missing,
3248            });
3249        }
3250        if self.scope.is_none() {
3251            return Err(ShapeViolation {
3252                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3253                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3254                property_iri: "https://uor.foundation/conformance/scope",
3255                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3256                min_count: 1,
3257                max_count: 1,
3258                kind: ViolationKind::Missing,
3259            });
3260        }
3261        Ok(Validated::new(LeaseDeclaration {
3262            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3263        }))
3264    }
3265
3266    /// Phase C.1: const-fn companion for `LeaseDeclarationBuilder::validate`.
3267    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3268    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3269    /// # Errors
3270    /// Returns `ShapeViolation` if any required field is missing.
3271    pub const fn validate_const(
3272        &self,
3273    ) -> Result<Validated<LeaseDeclaration, CompileTime>, ShapeViolation> {
3274        if self.linear_site.is_none() {
3275            return Err(ShapeViolation {
3276                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3277                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3278                property_iri: "https://uor.foundation/conformance/linear_site",
3279                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3280                min_count: 1,
3281                max_count: 1,
3282                kind: ViolationKind::Missing,
3283            });
3284        }
3285        if self.scope.is_none() {
3286            return Err(ShapeViolation {
3287                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3288                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3289                property_iri: "https://uor.foundation/conformance/scope",
3290                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3291                min_count: 1,
3292                max_count: 1,
3293                kind: ViolationKind::Missing,
3294            });
3295        }
3296        Ok(Validated::new(LeaseDeclaration {
3297            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3298        }))
3299    }
3300}
3301
3302impl<'a> Default for LeaseDeclarationBuilder<'a> {
3303    fn default() -> Self {
3304        Self::new()
3305    }
3306}
3307
3308/// Builder for `StreamDeclaration`. Validates against `StreamShape`.
3309#[derive(Debug, Clone)]
3310pub struct StreamDeclarationBuilder<'a> {
3311    /// The `seed` field.
3312    seed: Option<&'a [Term]>,
3313    /// The `step` field.
3314    step: Option<&'a [Term]>,
3315    /// The `productivity_witness` field.
3316    productivity_witness: Option<&'a str>,
3317}
3318
3319/// Declared stream validated against `StreamShape`.
3320#[derive(Debug, Clone, PartialEq, Eq)]
3321pub struct StreamDeclaration {
3322    /// Shape IRI this declaration was validated against.
3323    pub shape_iri: &'static str,
3324}
3325
3326impl StreamDeclaration {
3327    /// v0.2.2 Phase G: const-constructible empty form used by
3328    /// `validate_*_const` companion functions.
3329    #[inline]
3330    #[must_use]
3331    #[allow(dead_code)]
3332    pub(crate) const fn empty_const() -> Self {
3333        Self {
3334            shape_iri: "https://uor.foundation/conformance/StreamShape",
3335        }
3336    }
3337}
3338
3339impl<'a> StreamDeclarationBuilder<'a> {
3340    /// Creates a new empty builder.
3341    #[must_use]
3342    pub const fn new() -> Self {
3343        Self {
3344            seed: None,
3345            step: None,
3346            productivity_witness: None,
3347        }
3348    }
3349
3350    /// Set the `seed` field.
3351    #[must_use]
3352    pub const fn seed(mut self, value: &'a [Term]) -> Self {
3353        self.seed = Some(value);
3354        self
3355    }
3356
3357    /// Set the `step` field.
3358    #[must_use]
3359    pub const fn step(mut self, value: &'a [Term]) -> Self {
3360        self.step = Some(value);
3361        self
3362    }
3363
3364    /// Set the `productivity_witness` field.
3365    #[must_use]
3366    pub const fn productivity_witness(mut self, value: &'a str) -> Self {
3367        self.productivity_witness = Some(value);
3368        self
3369    }
3370
3371    /// Validate against `StreamShape`.
3372    /// # Errors
3373    /// Returns `ShapeViolation` if any required field is missing.
3374    pub fn validate(self) -> Result<Validated<StreamDeclaration>, ShapeViolation> {
3375        if self.seed.is_none() {
3376            return Err(ShapeViolation {
3377                shape_iri: "https://uor.foundation/conformance/StreamShape",
3378                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3379                property_iri: "https://uor.foundation/conformance/seed",
3380                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3381                min_count: 1,
3382                max_count: 1,
3383                kind: ViolationKind::Missing,
3384            });
3385        }
3386        if self.step.is_none() {
3387            return Err(ShapeViolation {
3388                shape_iri: "https://uor.foundation/conformance/StreamShape",
3389                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3390                property_iri: "https://uor.foundation/conformance/step",
3391                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3392                min_count: 1,
3393                max_count: 1,
3394                kind: ViolationKind::Missing,
3395            });
3396        }
3397        if self.productivity_witness.is_none() {
3398            return Err(ShapeViolation {
3399                shape_iri: "https://uor.foundation/conformance/StreamShape",
3400                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3401                property_iri: "https://uor.foundation/conformance/productivity_witness",
3402                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3403                min_count: 1,
3404                max_count: 1,
3405                kind: ViolationKind::Missing,
3406            });
3407        }
3408        Ok(Validated::new(StreamDeclaration {
3409            shape_iri: "https://uor.foundation/conformance/StreamShape",
3410        }))
3411    }
3412
3413    /// Phase C.1: const-fn companion for `StreamDeclarationBuilder::validate`.
3414    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3415    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3416    /// # Errors
3417    /// Returns `ShapeViolation` if any required field is missing.
3418    pub const fn validate_const(
3419        &self,
3420    ) -> Result<Validated<StreamDeclaration, CompileTime>, ShapeViolation> {
3421        if self.seed.is_none() {
3422            return Err(ShapeViolation {
3423                shape_iri: "https://uor.foundation/conformance/StreamShape",
3424                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3425                property_iri: "https://uor.foundation/conformance/seed",
3426                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3427                min_count: 1,
3428                max_count: 1,
3429                kind: ViolationKind::Missing,
3430            });
3431        }
3432        if self.step.is_none() {
3433            return Err(ShapeViolation {
3434                shape_iri: "https://uor.foundation/conformance/StreamShape",
3435                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3436                property_iri: "https://uor.foundation/conformance/step",
3437                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3438                min_count: 1,
3439                max_count: 1,
3440                kind: ViolationKind::Missing,
3441            });
3442        }
3443        if self.productivity_witness.is_none() {
3444            return Err(ShapeViolation {
3445                shape_iri: "https://uor.foundation/conformance/StreamShape",
3446                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3447                property_iri: "https://uor.foundation/conformance/productivity_witness",
3448                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3449                min_count: 1,
3450                max_count: 1,
3451                kind: ViolationKind::Missing,
3452            });
3453        }
3454        Ok(Validated::new(StreamDeclaration {
3455            shape_iri: "https://uor.foundation/conformance/StreamShape",
3456        }))
3457    }
3458}
3459
3460impl<'a> Default for StreamDeclarationBuilder<'a> {
3461    fn default() -> Self {
3462        Self::new()
3463    }
3464}
3465
3466/// Builder for `PredicateDeclaration`. Validates against `PredicateShape`.
3467#[derive(Debug, Clone)]
3468pub struct PredicateDeclarationBuilder<'a> {
3469    /// The `input_type` field.
3470    input_type: Option<&'a str>,
3471    /// The `evaluator` field.
3472    evaluator: Option<&'a [Term]>,
3473    /// The `termination_witness` field.
3474    termination_witness: Option<&'a str>,
3475}
3476
3477/// Declared predicate validated against `PredicateShape`.
3478#[derive(Debug, Clone, PartialEq, Eq)]
3479pub struct PredicateDeclaration {
3480    /// Shape IRI this declaration was validated against.
3481    pub shape_iri: &'static str,
3482}
3483
3484impl PredicateDeclaration {
3485    /// v0.2.2 Phase G: const-constructible empty form used by
3486    /// `validate_*_const` companion functions.
3487    #[inline]
3488    #[must_use]
3489    #[allow(dead_code)]
3490    pub(crate) const fn empty_const() -> Self {
3491        Self {
3492            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3493        }
3494    }
3495}
3496
3497impl<'a> PredicateDeclarationBuilder<'a> {
3498    /// Creates a new empty builder.
3499    #[must_use]
3500    pub const fn new() -> Self {
3501        Self {
3502            input_type: None,
3503            evaluator: None,
3504            termination_witness: None,
3505        }
3506    }
3507
3508    /// Set the `input_type` field.
3509    #[must_use]
3510    pub const fn input_type(mut self, value: &'a str) -> Self {
3511        self.input_type = Some(value);
3512        self
3513    }
3514
3515    /// Set the `evaluator` field.
3516    #[must_use]
3517    pub const fn evaluator(mut self, value: &'a [Term]) -> Self {
3518        self.evaluator = Some(value);
3519        self
3520    }
3521
3522    /// Set the `termination_witness` field.
3523    #[must_use]
3524    pub const fn termination_witness(mut self, value: &'a str) -> Self {
3525        self.termination_witness = Some(value);
3526        self
3527    }
3528
3529    /// Validate against `PredicateShape`.
3530    /// # Errors
3531    /// Returns `ShapeViolation` if any required field is missing.
3532    pub fn validate(self) -> Result<Validated<PredicateDeclaration>, ShapeViolation> {
3533        if self.input_type.is_none() {
3534            return Err(ShapeViolation {
3535                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3536                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3537                property_iri: "https://uor.foundation/conformance/input_type",
3538                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3539                min_count: 1,
3540                max_count: 1,
3541                kind: ViolationKind::Missing,
3542            });
3543        }
3544        if self.evaluator.is_none() {
3545            return Err(ShapeViolation {
3546                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3547                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3548                property_iri: "https://uor.foundation/conformance/evaluator",
3549                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3550                min_count: 1,
3551                max_count: 1,
3552                kind: ViolationKind::Missing,
3553            });
3554        }
3555        if self.termination_witness.is_none() {
3556            return Err(ShapeViolation {
3557                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3558                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3559                property_iri: "https://uor.foundation/conformance/termination_witness",
3560                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3561                min_count: 1,
3562                max_count: 1,
3563                kind: ViolationKind::Missing,
3564            });
3565        }
3566        Ok(Validated::new(PredicateDeclaration {
3567            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3568        }))
3569    }
3570
3571    /// Phase C.1: const-fn companion for `PredicateDeclarationBuilder::validate`.
3572    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3573    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3574    /// # Errors
3575    /// Returns `ShapeViolation` if any required field is missing.
3576    pub const fn validate_const(
3577        &self,
3578    ) -> Result<Validated<PredicateDeclaration, CompileTime>, ShapeViolation> {
3579        if self.input_type.is_none() {
3580            return Err(ShapeViolation {
3581                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3582                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3583                property_iri: "https://uor.foundation/conformance/input_type",
3584                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3585                min_count: 1,
3586                max_count: 1,
3587                kind: ViolationKind::Missing,
3588            });
3589        }
3590        if self.evaluator.is_none() {
3591            return Err(ShapeViolation {
3592                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3593                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3594                property_iri: "https://uor.foundation/conformance/evaluator",
3595                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3596                min_count: 1,
3597                max_count: 1,
3598                kind: ViolationKind::Missing,
3599            });
3600        }
3601        if self.termination_witness.is_none() {
3602            return Err(ShapeViolation {
3603                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3604                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3605                property_iri: "https://uor.foundation/conformance/termination_witness",
3606                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3607                min_count: 1,
3608                max_count: 1,
3609                kind: ViolationKind::Missing,
3610            });
3611        }
3612        Ok(Validated::new(PredicateDeclaration {
3613            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3614        }))
3615    }
3616}
3617
3618impl<'a> Default for PredicateDeclarationBuilder<'a> {
3619    fn default() -> Self {
3620        Self::new()
3621    }
3622}
3623
3624/// Builder for `ParallelDeclaration`. Validates against `ParallelShape`.
3625#[derive(Debug, Clone)]
3626pub struct ParallelDeclarationBuilder<'a> {
3627    /// The `site_partition` field.
3628    site_partition: Option<&'a [u32]>,
3629    /// The `disjointness_witness` field.
3630    disjointness_witness: Option<&'a str>,
3631}
3632
3633/// Declared parallel composition validated against `ParallelShape`.
3634#[derive(Debug, Clone, PartialEq, Eq)]
3635pub struct ParallelDeclaration {
3636    /// Shape IRI this declaration was validated against.
3637    pub shape_iri: &'static str,
3638}
3639
3640impl ParallelDeclaration {
3641    /// v0.2.2 Phase G: const-constructible empty form used by
3642    /// `validate_*_const` companion functions.
3643    #[inline]
3644    #[must_use]
3645    #[allow(dead_code)]
3646    pub(crate) const fn empty_const() -> Self {
3647        Self {
3648            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3649        }
3650    }
3651}
3652
3653impl<'a> ParallelDeclarationBuilder<'a> {
3654    /// Creates a new empty builder.
3655    #[must_use]
3656    pub const fn new() -> Self {
3657        Self {
3658            site_partition: None,
3659            disjointness_witness: None,
3660        }
3661    }
3662
3663    /// Set the `site_partition` field.
3664    #[must_use]
3665    pub const fn site_partition(mut self, value: &'a [u32]) -> Self {
3666        self.site_partition = Some(value);
3667        self
3668    }
3669
3670    /// Set the `disjointness_witness` field.
3671    #[must_use]
3672    pub const fn disjointness_witness(mut self, value: &'a str) -> Self {
3673        self.disjointness_witness = Some(value);
3674        self
3675    }
3676
3677    /// Validate against `ParallelShape`.
3678    /// # Errors
3679    /// Returns `ShapeViolation` if any required field is missing.
3680    pub fn validate(self) -> Result<Validated<ParallelDeclaration>, ShapeViolation> {
3681        if self.site_partition.is_none() {
3682            return Err(ShapeViolation {
3683                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3684                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3685                property_iri: "https://uor.foundation/conformance/site_partition",
3686                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3687                min_count: 1,
3688                max_count: 1,
3689                kind: ViolationKind::Missing,
3690            });
3691        }
3692        if self.disjointness_witness.is_none() {
3693            return Err(ShapeViolation {
3694                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3695                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3696                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3697                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3698                min_count: 1,
3699                max_count: 1,
3700                kind: ViolationKind::Missing,
3701            });
3702        }
3703        Ok(Validated::new(ParallelDeclaration {
3704            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3705        }))
3706    }
3707
3708    /// Phase C.1: const-fn companion for `ParallelDeclarationBuilder::validate`.
3709    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3710    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3711    /// # Errors
3712    /// Returns `ShapeViolation` if any required field is missing.
3713    pub const fn validate_const(
3714        &self,
3715    ) -> Result<Validated<ParallelDeclaration, CompileTime>, ShapeViolation> {
3716        if self.site_partition.is_none() {
3717            return Err(ShapeViolation {
3718                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3719                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3720                property_iri: "https://uor.foundation/conformance/site_partition",
3721                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3722                min_count: 1,
3723                max_count: 1,
3724                kind: ViolationKind::Missing,
3725            });
3726        }
3727        if self.disjointness_witness.is_none() {
3728            return Err(ShapeViolation {
3729                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3730                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3731                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3732                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3733                min_count: 1,
3734                max_count: 1,
3735                kind: ViolationKind::Missing,
3736            });
3737        }
3738        Ok(Validated::new(ParallelDeclaration {
3739            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3740        }))
3741    }
3742}
3743
3744impl<'a> Default for ParallelDeclarationBuilder<'a> {
3745    fn default() -> Self {
3746        Self::new()
3747    }
3748}
3749
3750impl<'a> ParallelDeclarationBuilder<'a> {
3751    /// v0.2.2 T2.7: const-fn accessor returning the length of the
3752    /// declared site partition (or 0 if unset).
3753    #[inline]
3754    #[must_use]
3755    pub const fn site_partition_len(&self) -> usize {
3756        match self.site_partition {
3757            Some(p) => p.len(),
3758            None => 0,
3759        }
3760    }
3761
3762    /// v0.2.2 Phase A: const-fn accessor returning the declared site-partition
3763    /// slice, or an empty slice if unset. Used by `validate_parallel_const`
3764    /// to propagate the partition into the widened `ParallelDeclaration<'a>`.
3765    #[inline]
3766    #[must_use]
3767    pub const fn site_partition_slice_const(&self) -> &'a [u32] {
3768        match self.site_partition {
3769            Some(p) => p,
3770            None => &[],
3771        }
3772    }
3773
3774    /// v0.2.2 Phase A: const-fn accessor returning the declared disjointness-witness
3775    /// IRI string, or an empty string if unset.
3776    #[inline]
3777    #[must_use]
3778    pub const fn disjointness_witness_const(&self) -> &'a str {
3779        match self.disjointness_witness {
3780            Some(s) => s,
3781            None => "",
3782        }
3783    }
3784}
3785
3786impl<'a> StreamDeclarationBuilder<'a> {
3787    /// v0.2.2 canonical: productivity bound is 1 if a `productivityWitness`
3788    /// IRI is declared (the stream attests termination via a `proof:Proof`
3789    /// individual), 0 otherwise. The witness's IRI points to the termination
3790    /// proof; downstream resolvers dereference it for detailed bound
3791    /// information. This two-level split (presence flag here, IRI dereference
3792    /// elsewhere) is the canonical foundation-level shape.
3793    #[inline]
3794    #[must_use]
3795    pub const fn productivity_bound_const(&self) -> u64 {
3796        match self.productivity_witness {
3797            Some(_) => 1,
3798            None => 0,
3799        }
3800    }
3801
3802    /// v0.2.2 Phase A: const-fn accessor returning the declared seed term slice,
3803    /// or an empty slice if unset.
3804    #[inline]
3805    #[must_use]
3806    pub const fn seed_slice_const(&self) -> &'a [Term] {
3807        match self.seed {
3808            Some(t) => t,
3809            None => &[],
3810        }
3811    }
3812
3813    /// v0.2.2 Phase A: const-fn accessor returning the declared step term slice,
3814    /// or an empty slice if unset.
3815    #[inline]
3816    #[must_use]
3817    pub const fn step_slice_const(&self) -> &'a [Term] {
3818        match self.step {
3819            Some(t) => t,
3820            None => &[],
3821        }
3822    }
3823
3824    /// v0.2.2 Phase A: const-fn accessor returning the declared productivity-witness
3825    /// IRI, or an empty string if unset.
3826    #[inline]
3827    #[must_use]
3828    pub const fn productivity_witness_const(&self) -> &'a str {
3829        match self.productivity_witness {
3830            Some(s) => s,
3831            None => "",
3832        }
3833    }
3834}
3835
3836/// Builder for declaring a new Witt level beyond W32.
3837/// Validates against `WittLevelShape`.
3838#[derive(Debug, Clone)]
3839pub struct WittLevelDeclarationBuilder {
3840    /// The declared bit width.
3841    bit_width: Option<u32>,
3842    /// The declared cycle size.
3843    cycle_size: Option<u128>,
3844    /// The predecessor level.
3845    predecessor: Option<WittLevel>,
3846}
3847
3848/// Validated Witt level declaration.
3849#[derive(Debug, Clone, PartialEq, Eq)]
3850pub struct WittLevelDeclaration {
3851    /// The declared bit width.
3852    pub bit_width: u32,
3853    /// The predecessor level.
3854    pub predecessor: WittLevel,
3855}
3856
3857impl WittLevelDeclarationBuilder {
3858    /// Creates a new empty builder.
3859    #[must_use]
3860    pub const fn new() -> Self {
3861        Self {
3862            bit_width: None,
3863            cycle_size: None,
3864            predecessor: None,
3865        }
3866    }
3867
3868    /// Set the declared bit width.
3869    #[must_use]
3870    pub const fn bit_width(mut self, w: u32) -> Self {
3871        self.bit_width = Some(w);
3872        self
3873    }
3874
3875    /// Set the declared cycle size.
3876    #[must_use]
3877    pub const fn cycle_size(mut self, s: u128) -> Self {
3878        self.cycle_size = Some(s);
3879        self
3880    }
3881
3882    /// Set the predecessor Witt level.
3883    #[must_use]
3884    pub const fn predecessor(mut self, level: WittLevel) -> Self {
3885        self.predecessor = Some(level);
3886        self
3887    }
3888
3889    /// Validate against `WittLevelShape`.
3890    /// # Errors
3891    /// Returns `ShapeViolation` if any required field is missing.
3892    pub fn validate(self) -> Result<Validated<WittLevelDeclaration>, ShapeViolation> {
3893        let bw = match self.bit_width {
3894            Some(w) => w,
3895            None => {
3896                return Err(ShapeViolation {
3897                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3898                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3899                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3900                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3901                    min_count: 1,
3902                    max_count: 1,
3903                    kind: ViolationKind::Missing,
3904                })
3905            }
3906        };
3907        let pred = match self.predecessor {
3908            Some(p) => p,
3909            None => {
3910                return Err(ShapeViolation {
3911                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3912                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3913                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3914                    expected_range: "https://uor.foundation/schema/WittLevel",
3915                    min_count: 1,
3916                    max_count: 1,
3917                    kind: ViolationKind::Missing,
3918                })
3919            }
3920        };
3921        Ok(Validated::new(WittLevelDeclaration {
3922            bit_width: bw,
3923            predecessor: pred,
3924        }))
3925    }
3926
3927    /// Phase C.1: const-fn companion for `WittLevelDeclarationBuilder::validate`.
3928    /// # Errors
3929    /// Returns `ShapeViolation` if any required field is missing.
3930    pub const fn validate_const(
3931        &self,
3932    ) -> Result<Validated<WittLevelDeclaration, CompileTime>, ShapeViolation> {
3933        let bw = match self.bit_width {
3934            Some(w) => w,
3935            None => {
3936                return Err(ShapeViolation {
3937                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3938                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3939                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3940                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3941                    min_count: 1,
3942                    max_count: 1,
3943                    kind: ViolationKind::Missing,
3944                })
3945            }
3946        };
3947        let pred = match self.predecessor {
3948            Some(p) => p,
3949            None => {
3950                return Err(ShapeViolation {
3951                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3952                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3953                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3954                    expected_range: "https://uor.foundation/schema/WittLevel",
3955                    min_count: 1,
3956                    max_count: 1,
3957                    kind: ViolationKind::Missing,
3958                })
3959            }
3960        };
3961        Ok(Validated::new(WittLevelDeclaration {
3962            bit_width: bw,
3963            predecessor: pred,
3964        }))
3965    }
3966}
3967
3968impl Default for WittLevelDeclarationBuilder {
3969    fn default() -> Self {
3970        Self::new()
3971    }
3972}
3973
3974/// Boundary session state tracker for the two-phase minting boundary.
3975/// Records crossing count and idempotency flag. Private fields
3976/// prevent external construction.
3977#[derive(Debug, Clone, PartialEq, Eq)]
3978pub struct BoundarySession {
3979    /// Total boundary crossings in this session.
3980    crossing_count: u32,
3981    /// Whether the boundary effect is idempotent.
3982    is_idempotent: bool,
3983}
3984
3985impl BoundarySession {
3986    /// Creates a new boundary session. Only callable within the crate.
3987    #[inline]
3988    #[allow(dead_code)]
3989    pub(crate) const fn new(is_idempotent: bool) -> Self {
3990        Self {
3991            crossing_count: 0,
3992            is_idempotent,
3993        }
3994    }
3995
3996    /// Returns the total boundary crossings.
3997    #[inline]
3998    #[must_use]
3999    pub const fn crossing_count(&self) -> u32 {
4000        self.crossing_count
4001    }
4002
4003    /// Returns whether the boundary effect is idempotent.
4004    #[inline]
4005    #[must_use]
4006    pub const fn is_idempotent(&self) -> bool {
4007        self.is_idempotent
4008    }
4009}
4010
4011/// Validate a scalar grounding intermediate against a `GroundingShape`
4012/// and mint it into a `Datum`. Only callable within `uor-foundation`.
4013/// # Errors
4014/// Returns `ShapeViolation` if the coordinate fails validation.
4015#[allow(dead_code)]
4016pub(crate) fn validate_and_mint_coord(
4017    grounded: GroundedCoord,
4018    shape: &Validated<GroundingDeclaration>,
4019    session: &mut BoundarySession,
4020) -> Result<Datum, ShapeViolation> {
4021    // The Validated<GroundingDeclaration> proves the shape was already
4022    // validated at builder time. The coordinate's level is guaranteed
4023    // correct by the closed GroundedCoordInner enum — the type system
4024    // enforces that only supported levels can be constructed.
4025    let _ = shape; // shape validation passed at builder time
4026    session.crossing_count += 1;
4027    let inner = match grounded.inner {
4028        GroundedCoordInner::W8(b) => DatumInner::W8(b),
4029        GroundedCoordInner::W16(b) => DatumInner::W16(b),
4030        GroundedCoordInner::W24(b) => DatumInner::W24(b),
4031        GroundedCoordInner::W32(b) => DatumInner::W32(b),
4032        GroundedCoordInner::W40(b) => DatumInner::W40(b),
4033        GroundedCoordInner::W48(b) => DatumInner::W48(b),
4034        GroundedCoordInner::W56(b) => DatumInner::W56(b),
4035        GroundedCoordInner::W64(b) => DatumInner::W64(b),
4036        GroundedCoordInner::W72(b) => DatumInner::W72(b),
4037        GroundedCoordInner::W80(b) => DatumInner::W80(b),
4038        GroundedCoordInner::W88(b) => DatumInner::W88(b),
4039        GroundedCoordInner::W96(b) => DatumInner::W96(b),
4040        GroundedCoordInner::W104(b) => DatumInner::W104(b),
4041        GroundedCoordInner::W112(b) => DatumInner::W112(b),
4042        GroundedCoordInner::W120(b) => DatumInner::W120(b),
4043        GroundedCoordInner::W128(b) => DatumInner::W128(b),
4044    };
4045    Ok(Datum { inner })
4046}
4047
4048/// Validate a tuple grounding intermediate and mint into a `Datum`.
4049/// Only callable within `uor-foundation`.
4050/// Mints the first coordinate of the tuple as the representative `Datum`.
4051/// Composite multi-coordinate `Datum` construction depends on the target
4052/// type's site decomposition, which is resolved during reduction evaluation.
4053/// # Errors
4054/// Returns `ShapeViolation` if the tuple is empty or fails validation.
4055#[allow(dead_code)]
4056pub(crate) fn validate_and_mint_tuple<const N: usize>(
4057    grounded: GroundedTuple<N>,
4058    shape: &Validated<GroundingDeclaration>,
4059    session: &mut BoundarySession,
4060) -> Result<Datum, ShapeViolation> {
4061    if N == 0 {
4062        return Err(ShapeViolation {
4063            shape_iri: shape.inner().shape_iri,
4064            constraint_iri: shape.inner().shape_iri,
4065            property_iri: "https://uor.foundation/conformance/groundingSourceType",
4066            expected_range: "https://uor.foundation/type/TypeDefinition",
4067            min_count: 1,
4068            max_count: 0,
4069            kind: ViolationKind::CardinalityViolation,
4070        });
4071    }
4072    // Mint the first coordinate as the representative Datum.
4073    // The full tuple is decomposed during reduction evaluation,
4074    // where each coordinate maps to a site in the constrained type.
4075    validate_and_mint_coord(grounded.coords[0].clone(), shape, session)
4076}
4077
4078/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Datum`.
4079/// Takes host bytes that have already passed the author's `Grounding` impl and
4080/// mints them into a sealed `Datum` at the supplied Witt level. The bytes are
4081/// decoded according to the level's byte width.
4082/// # Errors
4083/// Returns [`ShapeViolation`] if `bytes.len()` doesn't match the level's byte width
4084/// or if the level is unsupported.
4085pub fn mint_datum(level: crate::WittLevel, bytes: &[u8]) -> Result<Datum, ShapeViolation> {
4086    let expected_bytes = (level.witt_length() / 8) as usize;
4087    if bytes.len() != expected_bytes {
4088        return Err(ShapeViolation {
4089            shape_iri: "https://uor.foundation/u/Datum",
4090            constraint_iri: "https://uor.foundation/u/DatumByteWidth",
4091            property_iri: "https://uor.foundation/u/datumBytes",
4092            expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
4093            min_count: expected_bytes as u32,
4094            max_count: expected_bytes as u32,
4095            kind: crate::ViolationKind::CardinalityViolation,
4096        });
4097    }
4098    let inner = match level.witt_length() {
4099        8 => {
4100            let mut buf = [0u8; 1];
4101            let mut i = 0;
4102            while i < 1 {
4103                buf[i] = bytes[i];
4104                i += 1;
4105            }
4106            DatumInner::W8(buf)
4107        }
4108        16 => {
4109            let mut buf = [0u8; 2];
4110            let mut i = 0;
4111            while i < 2 {
4112                buf[i] = bytes[i];
4113                i += 1;
4114            }
4115            DatumInner::W16(buf)
4116        }
4117        24 => {
4118            let mut buf = [0u8; 3];
4119            let mut i = 0;
4120            while i < 3 {
4121                buf[i] = bytes[i];
4122                i += 1;
4123            }
4124            DatumInner::W24(buf)
4125        }
4126        32 => {
4127            let mut buf = [0u8; 4];
4128            let mut i = 0;
4129            while i < 4 {
4130                buf[i] = bytes[i];
4131                i += 1;
4132            }
4133            DatumInner::W32(buf)
4134        }
4135        40 => {
4136            let mut buf = [0u8; 5];
4137            let mut i = 0;
4138            while i < 5 {
4139                buf[i] = bytes[i];
4140                i += 1;
4141            }
4142            DatumInner::W40(buf)
4143        }
4144        48 => {
4145            let mut buf = [0u8; 6];
4146            let mut i = 0;
4147            while i < 6 {
4148                buf[i] = bytes[i];
4149                i += 1;
4150            }
4151            DatumInner::W48(buf)
4152        }
4153        56 => {
4154            let mut buf = [0u8; 7];
4155            let mut i = 0;
4156            while i < 7 {
4157                buf[i] = bytes[i];
4158                i += 1;
4159            }
4160            DatumInner::W56(buf)
4161        }
4162        64 => {
4163            let mut buf = [0u8; 8];
4164            let mut i = 0;
4165            while i < 8 {
4166                buf[i] = bytes[i];
4167                i += 1;
4168            }
4169            DatumInner::W64(buf)
4170        }
4171        72 => {
4172            let mut buf = [0u8; 9];
4173            let mut i = 0;
4174            while i < 9 {
4175                buf[i] = bytes[i];
4176                i += 1;
4177            }
4178            DatumInner::W72(buf)
4179        }
4180        80 => {
4181            let mut buf = [0u8; 10];
4182            let mut i = 0;
4183            while i < 10 {
4184                buf[i] = bytes[i];
4185                i += 1;
4186            }
4187            DatumInner::W80(buf)
4188        }
4189        88 => {
4190            let mut buf = [0u8; 11];
4191            let mut i = 0;
4192            while i < 11 {
4193                buf[i] = bytes[i];
4194                i += 1;
4195            }
4196            DatumInner::W88(buf)
4197        }
4198        96 => {
4199            let mut buf = [0u8; 12];
4200            let mut i = 0;
4201            while i < 12 {
4202                buf[i] = bytes[i];
4203                i += 1;
4204            }
4205            DatumInner::W96(buf)
4206        }
4207        104 => {
4208            let mut buf = [0u8; 13];
4209            let mut i = 0;
4210            while i < 13 {
4211                buf[i] = bytes[i];
4212                i += 1;
4213            }
4214            DatumInner::W104(buf)
4215        }
4216        112 => {
4217            let mut buf = [0u8; 14];
4218            let mut i = 0;
4219            while i < 14 {
4220                buf[i] = bytes[i];
4221                i += 1;
4222            }
4223            DatumInner::W112(buf)
4224        }
4225        120 => {
4226            let mut buf = [0u8; 15];
4227            let mut i = 0;
4228            while i < 15 {
4229                buf[i] = bytes[i];
4230                i += 1;
4231            }
4232            DatumInner::W120(buf)
4233        }
4234        128 => {
4235            let mut buf = [0u8; 16];
4236            let mut i = 0;
4237            while i < 16 {
4238                buf[i] = bytes[i];
4239                i += 1;
4240            }
4241            DatumInner::W128(buf)
4242        }
4243        _ => {
4244            return Err(ShapeViolation {
4245                shape_iri: "https://uor.foundation/u/Datum",
4246                constraint_iri: "https://uor.foundation/u/DatumLevel",
4247                property_iri: "https://uor.foundation/u/datumLevel",
4248                expected_range: "https://uor.foundation/schema/WittLevel",
4249                min_count: 1,
4250                max_count: 1,
4251                kind: crate::ViolationKind::ValueCheck,
4252            })
4253        }
4254    };
4255    Ok(Datum { inner })
4256}
4257
4258/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Triad<L>`.
4259/// Takes three coordinate values that satisfy the Triad shape constraint and
4260/// mints them into a sealed `Triad<L>` at the level marker `L`.
4261#[must_use]
4262pub const fn mint_triad<L>(stratum: u64, spectrum: u64, address: u64) -> Triad<L> {
4263    Triad::new(stratum, spectrum, address)
4264}
4265
4266/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Derivation`.
4267/// Takes the precursor's step count + Witt level + content fingerprint and mints
4268/// a sealed `Derivation` carrying the typed transition witness.
4269#[must_use]
4270pub const fn mint_derivation(
4271    step_count: u32,
4272    witt_level_bits: u16,
4273    content_fingerprint: ContentFingerprint,
4274) -> Derivation {
4275    Derivation::new(step_count, witt_level_bits, content_fingerprint)
4276}
4277
4278/// Wiki ADR-016 mint primitive: cross-crate construction surface for `FreeRank`.
4279/// Takes a natural-number rank witness (total site capacity at the Witt level plus
4280/// the number of currently pinned sites) and mints it into a sealed `FreeRank`.
4281#[must_use]
4282pub const fn mint_freerank(total: u32, pinned: u32) -> FreeRank {
4283    FreeRank::new(total, pinned)
4284}
4285
4286/// Evaluate a binary ring operation at compile time.
4287/// One helper is emitted per `schema:WittLevel` individual. The `uor!`
4288/// proc macro delegates to these helpers; it never performs ring
4289/// arithmetic itself.
4290/// # Examples
4291/// ```rust
4292/// use uor_foundation::enforcement::{const_ring_eval_w8, const_ring_eval_unary_w8};
4293/// use uor_foundation::PrimitiveOp;
4294///
4295/// // Ring arithmetic in Z/256Z: all operations wrap modulo 256.
4296///
4297/// // Addition wraps: 200 + 100 = 300 -> 300 - 256 = 44
4298/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Add, 200, 100), 44);
4299///
4300/// // Multiplication: 3 * 5 = 15 (no wrap needed)
4301/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Mul, 3, 5), 15);
4302///
4303/// // XOR: bitwise exclusive-or
4304/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Xor, 0b1010, 0b1100), 0b0110);
4305///
4306/// // Negation: neg(x) = 256 - x (additive inverse in Z/256Z)
4307/// assert_eq!(const_ring_eval_unary_w8(PrimitiveOp::Neg, 1), 255);
4308///
4309/// // The critical identity: neg(bnot(x)) = succ(x) for all x
4310/// let x = 42u8;
4311/// let lhs = const_ring_eval_unary_w8(PrimitiveOp::Neg,
4312///     const_ring_eval_unary_w8(PrimitiveOp::Bnot, x));
4313/// let rhs = const_ring_eval_unary_w8(PrimitiveOp::Succ, x);
4314/// assert_eq!(lhs, rhs);
4315/// ```
4316#[inline]
4317#[must_use]
4318#[allow(clippy::manual_checked_ops)]
4319pub const fn const_ring_eval_w8(op: PrimitiveOp, a: u8, b: u8) -> u8 {
4320    match op {
4321        PrimitiveOp::Add => a.wrapping_add(b),
4322        PrimitiveOp::Sub => a.wrapping_sub(b),
4323        PrimitiveOp::Mul => a.wrapping_mul(b),
4324        PrimitiveOp::Xor => a ^ b,
4325        PrimitiveOp::And => a & b,
4326        PrimitiveOp::Or => a | b,
4327        PrimitiveOp::Le => (a <= b) as u8,
4328        PrimitiveOp::Lt => (a < b) as u8,
4329        PrimitiveOp::Ge => (a >= b) as u8,
4330        PrimitiveOp::Gt => (a > b) as u8,
4331        PrimitiveOp::Concat => 0,
4332        PrimitiveOp::Div => {
4333            if b == 0 {
4334                0
4335            } else {
4336                a / b
4337            }
4338        }
4339        PrimitiveOp::Mod => {
4340            if b == 0 {
4341                0
4342            } else {
4343                a % b
4344            }
4345        }
4346        PrimitiveOp::Pow => const_pow_w8(a, b),
4347        _ => 0,
4348    }
4349}
4350
4351#[inline]
4352#[must_use]
4353pub const fn const_pow_w8(base: u8, exp: u8) -> u8 {
4354    let mut result: u8 = 1;
4355    let mut b: u8 = base;
4356    let mut e: u8 = exp;
4357    while e > 0 {
4358        if (e & 1) == 1 {
4359            result = result.wrapping_mul(b);
4360        }
4361        b = b.wrapping_mul(b);
4362        e >>= 1;
4363    }
4364    result
4365}
4366
4367#[inline]
4368#[must_use]
4369pub const fn const_ring_eval_unary_w8(op: PrimitiveOp, a: u8) -> u8 {
4370    match op {
4371        PrimitiveOp::Neg => 0u8.wrapping_sub(a),
4372        PrimitiveOp::Bnot => !a,
4373        PrimitiveOp::Succ => a.wrapping_add(1),
4374        PrimitiveOp::Pred => a.wrapping_sub(1),
4375        _ => 0,
4376    }
4377}
4378
4379#[inline]
4380#[must_use]
4381#[allow(clippy::manual_checked_ops)]
4382pub const fn const_ring_eval_w16(op: PrimitiveOp, a: u16, b: u16) -> u16 {
4383    match op {
4384        PrimitiveOp::Add => a.wrapping_add(b),
4385        PrimitiveOp::Sub => a.wrapping_sub(b),
4386        PrimitiveOp::Mul => a.wrapping_mul(b),
4387        PrimitiveOp::Xor => a ^ b,
4388        PrimitiveOp::And => a & b,
4389        PrimitiveOp::Or => a | b,
4390        PrimitiveOp::Le => (a <= b) as u16,
4391        PrimitiveOp::Lt => (a < b) as u16,
4392        PrimitiveOp::Ge => (a >= b) as u16,
4393        PrimitiveOp::Gt => (a > b) as u16,
4394        PrimitiveOp::Concat => 0,
4395        PrimitiveOp::Div => {
4396            if b == 0 {
4397                0
4398            } else {
4399                a / b
4400            }
4401        }
4402        PrimitiveOp::Mod => {
4403            if b == 0 {
4404                0
4405            } else {
4406                a % b
4407            }
4408        }
4409        PrimitiveOp::Pow => const_pow_w16(a, b),
4410        _ => 0,
4411    }
4412}
4413
4414#[inline]
4415#[must_use]
4416pub const fn const_pow_w16(base: u16, exp: u16) -> u16 {
4417    let mut result: u16 = 1;
4418    let mut b: u16 = base;
4419    let mut e: u16 = exp;
4420    while e > 0 {
4421        if (e & 1) == 1 {
4422            result = result.wrapping_mul(b);
4423        }
4424        b = b.wrapping_mul(b);
4425        e >>= 1;
4426    }
4427    result
4428}
4429
4430#[inline]
4431#[must_use]
4432pub const fn const_ring_eval_unary_w16(op: PrimitiveOp, a: u16) -> u16 {
4433    match op {
4434        PrimitiveOp::Neg => 0u16.wrapping_sub(a),
4435        PrimitiveOp::Bnot => !a,
4436        PrimitiveOp::Succ => a.wrapping_add(1),
4437        PrimitiveOp::Pred => a.wrapping_sub(1),
4438        _ => 0,
4439    }
4440}
4441
4442#[inline]
4443#[must_use]
4444#[allow(clippy::manual_checked_ops)]
4445pub const fn const_ring_eval_w24(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4446    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4447    match op {
4448        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4449        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4450        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4451        PrimitiveOp::Xor => (a ^ b) & MASK,
4452        PrimitiveOp::And => (a & b) & MASK,
4453        PrimitiveOp::Or => (a | b) & MASK,
4454        PrimitiveOp::Le => (a <= b) as u32,
4455        PrimitiveOp::Lt => (a < b) as u32,
4456        PrimitiveOp::Ge => (a >= b) as u32,
4457        PrimitiveOp::Gt => (a > b) as u32,
4458        PrimitiveOp::Concat => 0,
4459        PrimitiveOp::Div => {
4460            if b == 0 {
4461                0
4462            } else {
4463                (a / b) & MASK
4464            }
4465        }
4466        PrimitiveOp::Mod => {
4467            if b == 0 {
4468                0
4469            } else {
4470                (a % b) & MASK
4471            }
4472        }
4473        PrimitiveOp::Pow => (const_pow_w24(a, b)) & MASK,
4474        _ => 0,
4475    }
4476}
4477
4478#[inline]
4479#[must_use]
4480pub const fn const_pow_w24(base: u32, exp: u32) -> u32 {
4481    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4482    let mut result: u32 = 1;
4483    let mut b: u32 = (base) & MASK;
4484    let mut e: u32 = exp;
4485    while e > 0 {
4486        if (e & 1) == 1 {
4487            result = (result.wrapping_mul(b)) & MASK;
4488        }
4489        b = (b.wrapping_mul(b)) & MASK;
4490        e >>= 1;
4491    }
4492    result
4493}
4494
4495#[inline]
4496#[must_use]
4497pub const fn const_ring_eval_unary_w24(op: PrimitiveOp, a: u32) -> u32 {
4498    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4499    match op {
4500        PrimitiveOp::Neg => (0u32.wrapping_sub(a)) & MASK,
4501        PrimitiveOp::Bnot => (!a) & MASK,
4502        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4503        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4504        _ => 0,
4505    }
4506}
4507
4508#[inline]
4509#[must_use]
4510#[allow(clippy::manual_checked_ops)]
4511pub const fn const_ring_eval_w32(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4512    match op {
4513        PrimitiveOp::Add => a.wrapping_add(b),
4514        PrimitiveOp::Sub => a.wrapping_sub(b),
4515        PrimitiveOp::Mul => a.wrapping_mul(b),
4516        PrimitiveOp::Xor => a ^ b,
4517        PrimitiveOp::And => a & b,
4518        PrimitiveOp::Or => a | b,
4519        PrimitiveOp::Le => (a <= b) as u32,
4520        PrimitiveOp::Lt => (a < b) as u32,
4521        PrimitiveOp::Ge => (a >= b) as u32,
4522        PrimitiveOp::Gt => (a > b) as u32,
4523        PrimitiveOp::Concat => 0,
4524        PrimitiveOp::Div => {
4525            if b == 0 {
4526                0
4527            } else {
4528                a / b
4529            }
4530        }
4531        PrimitiveOp::Mod => {
4532            if b == 0 {
4533                0
4534            } else {
4535                a % b
4536            }
4537        }
4538        PrimitiveOp::Pow => const_pow_w32(a, b),
4539        _ => 0,
4540    }
4541}
4542
4543#[inline]
4544#[must_use]
4545pub const fn const_pow_w32(base: u32, exp: u32) -> u32 {
4546    let mut result: u32 = 1;
4547    let mut b: u32 = base;
4548    let mut e: u32 = exp;
4549    while e > 0 {
4550        if (e & 1) == 1 {
4551            result = result.wrapping_mul(b);
4552        }
4553        b = b.wrapping_mul(b);
4554        e >>= 1;
4555    }
4556    result
4557}
4558
4559#[inline]
4560#[must_use]
4561pub const fn const_ring_eval_unary_w32(op: PrimitiveOp, a: u32) -> u32 {
4562    match op {
4563        PrimitiveOp::Neg => 0u32.wrapping_sub(a),
4564        PrimitiveOp::Bnot => !a,
4565        PrimitiveOp::Succ => a.wrapping_add(1),
4566        PrimitiveOp::Pred => a.wrapping_sub(1),
4567        _ => 0,
4568    }
4569}
4570
4571#[inline]
4572#[must_use]
4573#[allow(clippy::manual_checked_ops)]
4574pub const fn const_ring_eval_w40(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4575    const MASK: u64 = u64::MAX >> (64 - 40);
4576    match op {
4577        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4578        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4579        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4580        PrimitiveOp::Xor => (a ^ b) & MASK,
4581        PrimitiveOp::And => (a & b) & MASK,
4582        PrimitiveOp::Or => (a | b) & MASK,
4583        PrimitiveOp::Le => (a <= b) as u64,
4584        PrimitiveOp::Lt => (a < b) as u64,
4585        PrimitiveOp::Ge => (a >= b) as u64,
4586        PrimitiveOp::Gt => (a > b) as u64,
4587        PrimitiveOp::Concat => 0,
4588        PrimitiveOp::Div => {
4589            if b == 0 {
4590                0
4591            } else {
4592                (a / b) & MASK
4593            }
4594        }
4595        PrimitiveOp::Mod => {
4596            if b == 0 {
4597                0
4598            } else {
4599                (a % b) & MASK
4600            }
4601        }
4602        PrimitiveOp::Pow => (const_pow_w40(a, b)) & MASK,
4603        _ => 0,
4604    }
4605}
4606
4607#[inline]
4608#[must_use]
4609pub const fn const_pow_w40(base: u64, exp: u64) -> u64 {
4610    const MASK: u64 = u64::MAX >> (64 - 40);
4611    let mut result: u64 = 1;
4612    let mut b: u64 = (base) & MASK;
4613    let mut e: u64 = exp;
4614    while e > 0 {
4615        if (e & 1) == 1 {
4616            result = (result.wrapping_mul(b)) & MASK;
4617        }
4618        b = (b.wrapping_mul(b)) & MASK;
4619        e >>= 1;
4620    }
4621    result
4622}
4623
4624#[inline]
4625#[must_use]
4626pub const fn const_ring_eval_unary_w40(op: PrimitiveOp, a: u64) -> u64 {
4627    const MASK: u64 = u64::MAX >> (64 - 40);
4628    match op {
4629        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4630        PrimitiveOp::Bnot => (!a) & MASK,
4631        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4632        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4633        _ => 0,
4634    }
4635}
4636
4637#[inline]
4638#[must_use]
4639#[allow(clippy::manual_checked_ops)]
4640pub const fn const_ring_eval_w48(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4641    const MASK: u64 = u64::MAX >> (64 - 48);
4642    match op {
4643        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4644        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4645        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4646        PrimitiveOp::Xor => (a ^ b) & MASK,
4647        PrimitiveOp::And => (a & b) & MASK,
4648        PrimitiveOp::Or => (a | b) & MASK,
4649        PrimitiveOp::Le => (a <= b) as u64,
4650        PrimitiveOp::Lt => (a < b) as u64,
4651        PrimitiveOp::Ge => (a >= b) as u64,
4652        PrimitiveOp::Gt => (a > b) as u64,
4653        PrimitiveOp::Concat => 0,
4654        PrimitiveOp::Div => {
4655            if b == 0 {
4656                0
4657            } else {
4658                (a / b) & MASK
4659            }
4660        }
4661        PrimitiveOp::Mod => {
4662            if b == 0 {
4663                0
4664            } else {
4665                (a % b) & MASK
4666            }
4667        }
4668        PrimitiveOp::Pow => (const_pow_w48(a, b)) & MASK,
4669        _ => 0,
4670    }
4671}
4672
4673#[inline]
4674#[must_use]
4675pub const fn const_pow_w48(base: u64, exp: u64) -> u64 {
4676    const MASK: u64 = u64::MAX >> (64 - 48);
4677    let mut result: u64 = 1;
4678    let mut b: u64 = (base) & MASK;
4679    let mut e: u64 = exp;
4680    while e > 0 {
4681        if (e & 1) == 1 {
4682            result = (result.wrapping_mul(b)) & MASK;
4683        }
4684        b = (b.wrapping_mul(b)) & MASK;
4685        e >>= 1;
4686    }
4687    result
4688}
4689
4690#[inline]
4691#[must_use]
4692pub const fn const_ring_eval_unary_w48(op: PrimitiveOp, a: u64) -> u64 {
4693    const MASK: u64 = u64::MAX >> (64 - 48);
4694    match op {
4695        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4696        PrimitiveOp::Bnot => (!a) & MASK,
4697        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4698        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4699        _ => 0,
4700    }
4701}
4702
4703#[inline]
4704#[must_use]
4705#[allow(clippy::manual_checked_ops)]
4706pub const fn const_ring_eval_w56(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4707    const MASK: u64 = u64::MAX >> (64 - 56);
4708    match op {
4709        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4710        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4711        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4712        PrimitiveOp::Xor => (a ^ b) & MASK,
4713        PrimitiveOp::And => (a & b) & MASK,
4714        PrimitiveOp::Or => (a | b) & MASK,
4715        PrimitiveOp::Le => (a <= b) as u64,
4716        PrimitiveOp::Lt => (a < b) as u64,
4717        PrimitiveOp::Ge => (a >= b) as u64,
4718        PrimitiveOp::Gt => (a > b) as u64,
4719        PrimitiveOp::Concat => 0,
4720        PrimitiveOp::Div => {
4721            if b == 0 {
4722                0
4723            } else {
4724                (a / b) & MASK
4725            }
4726        }
4727        PrimitiveOp::Mod => {
4728            if b == 0 {
4729                0
4730            } else {
4731                (a % b) & MASK
4732            }
4733        }
4734        PrimitiveOp::Pow => (const_pow_w56(a, b)) & MASK,
4735        _ => 0,
4736    }
4737}
4738
4739#[inline]
4740#[must_use]
4741pub const fn const_pow_w56(base: u64, exp: u64) -> u64 {
4742    const MASK: u64 = u64::MAX >> (64 - 56);
4743    let mut result: u64 = 1;
4744    let mut b: u64 = (base) & MASK;
4745    let mut e: u64 = exp;
4746    while e > 0 {
4747        if (e & 1) == 1 {
4748            result = (result.wrapping_mul(b)) & MASK;
4749        }
4750        b = (b.wrapping_mul(b)) & MASK;
4751        e >>= 1;
4752    }
4753    result
4754}
4755
4756#[inline]
4757#[must_use]
4758pub const fn const_ring_eval_unary_w56(op: PrimitiveOp, a: u64) -> u64 {
4759    const MASK: u64 = u64::MAX >> (64 - 56);
4760    match op {
4761        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4762        PrimitiveOp::Bnot => (!a) & MASK,
4763        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4764        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4765        _ => 0,
4766    }
4767}
4768
4769#[inline]
4770#[must_use]
4771#[allow(clippy::manual_checked_ops)]
4772pub const fn const_ring_eval_w64(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4773    match op {
4774        PrimitiveOp::Add => a.wrapping_add(b),
4775        PrimitiveOp::Sub => a.wrapping_sub(b),
4776        PrimitiveOp::Mul => a.wrapping_mul(b),
4777        PrimitiveOp::Xor => a ^ b,
4778        PrimitiveOp::And => a & b,
4779        PrimitiveOp::Or => a | b,
4780        PrimitiveOp::Le => (a <= b) as u64,
4781        PrimitiveOp::Lt => (a < b) as u64,
4782        PrimitiveOp::Ge => (a >= b) as u64,
4783        PrimitiveOp::Gt => (a > b) as u64,
4784        PrimitiveOp::Concat => 0,
4785        PrimitiveOp::Div => {
4786            if b == 0 {
4787                0
4788            } else {
4789                a / b
4790            }
4791        }
4792        PrimitiveOp::Mod => {
4793            if b == 0 {
4794                0
4795            } else {
4796                a % b
4797            }
4798        }
4799        PrimitiveOp::Pow => const_pow_w64(a, b),
4800        _ => 0,
4801    }
4802}
4803
4804#[inline]
4805#[must_use]
4806pub const fn const_pow_w64(base: u64, exp: u64) -> u64 {
4807    let mut result: u64 = 1;
4808    let mut b: u64 = base;
4809    let mut e: u64 = exp;
4810    while e > 0 {
4811        if (e & 1) == 1 {
4812            result = result.wrapping_mul(b);
4813        }
4814        b = b.wrapping_mul(b);
4815        e >>= 1;
4816    }
4817    result
4818}
4819
4820#[inline]
4821#[must_use]
4822pub const fn const_ring_eval_unary_w64(op: PrimitiveOp, a: u64) -> u64 {
4823    match op {
4824        PrimitiveOp::Neg => 0u64.wrapping_sub(a),
4825        PrimitiveOp::Bnot => !a,
4826        PrimitiveOp::Succ => a.wrapping_add(1),
4827        PrimitiveOp::Pred => a.wrapping_sub(1),
4828        _ => 0,
4829    }
4830}
4831
4832#[inline]
4833#[must_use]
4834#[allow(clippy::manual_checked_ops)]
4835pub const fn const_ring_eval_w72(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4836    const MASK: u128 = u128::MAX >> (128 - 72);
4837    match op {
4838        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4839        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4840        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4841        PrimitiveOp::Xor => (a ^ b) & MASK,
4842        PrimitiveOp::And => (a & b) & MASK,
4843        PrimitiveOp::Or => (a | b) & MASK,
4844        PrimitiveOp::Le => (a <= b) as u128,
4845        PrimitiveOp::Lt => (a < b) as u128,
4846        PrimitiveOp::Ge => (a >= b) as u128,
4847        PrimitiveOp::Gt => (a > b) as u128,
4848        PrimitiveOp::Concat => 0,
4849        PrimitiveOp::Div => {
4850            if b == 0 {
4851                0
4852            } else {
4853                (a / b) & MASK
4854            }
4855        }
4856        PrimitiveOp::Mod => {
4857            if b == 0 {
4858                0
4859            } else {
4860                (a % b) & MASK
4861            }
4862        }
4863        PrimitiveOp::Pow => (const_pow_w72(a, b)) & MASK,
4864        _ => 0,
4865    }
4866}
4867
4868#[inline]
4869#[must_use]
4870pub const fn const_pow_w72(base: u128, exp: u128) -> u128 {
4871    const MASK: u128 = u128::MAX >> (128 - 72);
4872    let mut result: u128 = 1;
4873    let mut b: u128 = (base) & MASK;
4874    let mut e: u128 = exp;
4875    while e > 0 {
4876        if (e & 1) == 1 {
4877            result = (result.wrapping_mul(b)) & MASK;
4878        }
4879        b = (b.wrapping_mul(b)) & MASK;
4880        e >>= 1;
4881    }
4882    result
4883}
4884
4885#[inline]
4886#[must_use]
4887pub const fn const_ring_eval_unary_w72(op: PrimitiveOp, a: u128) -> u128 {
4888    const MASK: u128 = u128::MAX >> (128 - 72);
4889    match op {
4890        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4891        PrimitiveOp::Bnot => (!a) & MASK,
4892        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4893        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4894        _ => 0,
4895    }
4896}
4897
4898#[inline]
4899#[must_use]
4900#[allow(clippy::manual_checked_ops)]
4901pub const fn const_ring_eval_w80(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4902    const MASK: u128 = u128::MAX >> (128 - 80);
4903    match op {
4904        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4905        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4906        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4907        PrimitiveOp::Xor => (a ^ b) & MASK,
4908        PrimitiveOp::And => (a & b) & MASK,
4909        PrimitiveOp::Or => (a | b) & MASK,
4910        PrimitiveOp::Le => (a <= b) as u128,
4911        PrimitiveOp::Lt => (a < b) as u128,
4912        PrimitiveOp::Ge => (a >= b) as u128,
4913        PrimitiveOp::Gt => (a > b) as u128,
4914        PrimitiveOp::Concat => 0,
4915        PrimitiveOp::Div => {
4916            if b == 0 {
4917                0
4918            } else {
4919                (a / b) & MASK
4920            }
4921        }
4922        PrimitiveOp::Mod => {
4923            if b == 0 {
4924                0
4925            } else {
4926                (a % b) & MASK
4927            }
4928        }
4929        PrimitiveOp::Pow => (const_pow_w80(a, b)) & MASK,
4930        _ => 0,
4931    }
4932}
4933
4934#[inline]
4935#[must_use]
4936pub const fn const_pow_w80(base: u128, exp: u128) -> u128 {
4937    const MASK: u128 = u128::MAX >> (128 - 80);
4938    let mut result: u128 = 1;
4939    let mut b: u128 = (base) & MASK;
4940    let mut e: u128 = exp;
4941    while e > 0 {
4942        if (e & 1) == 1 {
4943            result = (result.wrapping_mul(b)) & MASK;
4944        }
4945        b = (b.wrapping_mul(b)) & MASK;
4946        e >>= 1;
4947    }
4948    result
4949}
4950
4951#[inline]
4952#[must_use]
4953pub const fn const_ring_eval_unary_w80(op: PrimitiveOp, a: u128) -> u128 {
4954    const MASK: u128 = u128::MAX >> (128 - 80);
4955    match op {
4956        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4957        PrimitiveOp::Bnot => (!a) & MASK,
4958        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4959        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4960        _ => 0,
4961    }
4962}
4963
4964#[inline]
4965#[must_use]
4966#[allow(clippy::manual_checked_ops)]
4967pub const fn const_ring_eval_w88(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4968    const MASK: u128 = u128::MAX >> (128 - 88);
4969    match op {
4970        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4971        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4972        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4973        PrimitiveOp::Xor => (a ^ b) & MASK,
4974        PrimitiveOp::And => (a & b) & MASK,
4975        PrimitiveOp::Or => (a | b) & MASK,
4976        PrimitiveOp::Le => (a <= b) as u128,
4977        PrimitiveOp::Lt => (a < b) as u128,
4978        PrimitiveOp::Ge => (a >= b) as u128,
4979        PrimitiveOp::Gt => (a > b) as u128,
4980        PrimitiveOp::Concat => 0,
4981        PrimitiveOp::Div => {
4982            if b == 0 {
4983                0
4984            } else {
4985                (a / b) & MASK
4986            }
4987        }
4988        PrimitiveOp::Mod => {
4989            if b == 0 {
4990                0
4991            } else {
4992                (a % b) & MASK
4993            }
4994        }
4995        PrimitiveOp::Pow => (const_pow_w88(a, b)) & MASK,
4996        _ => 0,
4997    }
4998}
4999
5000#[inline]
5001#[must_use]
5002pub const fn const_pow_w88(base: u128, exp: u128) -> u128 {
5003    const MASK: u128 = u128::MAX >> (128 - 88);
5004    let mut result: u128 = 1;
5005    let mut b: u128 = (base) & MASK;
5006    let mut e: u128 = exp;
5007    while e > 0 {
5008        if (e & 1) == 1 {
5009            result = (result.wrapping_mul(b)) & MASK;
5010        }
5011        b = (b.wrapping_mul(b)) & MASK;
5012        e >>= 1;
5013    }
5014    result
5015}
5016
5017#[inline]
5018#[must_use]
5019pub const fn const_ring_eval_unary_w88(op: PrimitiveOp, a: u128) -> u128 {
5020    const MASK: u128 = u128::MAX >> (128 - 88);
5021    match op {
5022        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5023        PrimitiveOp::Bnot => (!a) & MASK,
5024        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5025        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5026        _ => 0,
5027    }
5028}
5029
5030#[inline]
5031#[must_use]
5032#[allow(clippy::manual_checked_ops)]
5033pub const fn const_ring_eval_w96(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5034    const MASK: u128 = u128::MAX >> (128 - 96);
5035    match op {
5036        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5037        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5038        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5039        PrimitiveOp::Xor => (a ^ b) & MASK,
5040        PrimitiveOp::And => (a & b) & MASK,
5041        PrimitiveOp::Or => (a | b) & MASK,
5042        PrimitiveOp::Le => (a <= b) as u128,
5043        PrimitiveOp::Lt => (a < b) as u128,
5044        PrimitiveOp::Ge => (a >= b) as u128,
5045        PrimitiveOp::Gt => (a > b) as u128,
5046        PrimitiveOp::Concat => 0,
5047        PrimitiveOp::Div => {
5048            if b == 0 {
5049                0
5050            } else {
5051                (a / b) & MASK
5052            }
5053        }
5054        PrimitiveOp::Mod => {
5055            if b == 0 {
5056                0
5057            } else {
5058                (a % b) & MASK
5059            }
5060        }
5061        PrimitiveOp::Pow => (const_pow_w96(a, b)) & MASK,
5062        _ => 0,
5063    }
5064}
5065
5066#[inline]
5067#[must_use]
5068pub const fn const_pow_w96(base: u128, exp: u128) -> u128 {
5069    const MASK: u128 = u128::MAX >> (128 - 96);
5070    let mut result: u128 = 1;
5071    let mut b: u128 = (base) & MASK;
5072    let mut e: u128 = exp;
5073    while e > 0 {
5074        if (e & 1) == 1 {
5075            result = (result.wrapping_mul(b)) & MASK;
5076        }
5077        b = (b.wrapping_mul(b)) & MASK;
5078        e >>= 1;
5079    }
5080    result
5081}
5082
5083#[inline]
5084#[must_use]
5085pub const fn const_ring_eval_unary_w96(op: PrimitiveOp, a: u128) -> u128 {
5086    const MASK: u128 = u128::MAX >> (128 - 96);
5087    match op {
5088        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5089        PrimitiveOp::Bnot => (!a) & MASK,
5090        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5091        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5092        _ => 0,
5093    }
5094}
5095
5096#[inline]
5097#[must_use]
5098#[allow(clippy::manual_checked_ops)]
5099pub const fn const_ring_eval_w104(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5100    const MASK: u128 = u128::MAX >> (128 - 104);
5101    match op {
5102        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5103        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5104        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5105        PrimitiveOp::Xor => (a ^ b) & MASK,
5106        PrimitiveOp::And => (a & b) & MASK,
5107        PrimitiveOp::Or => (a | b) & MASK,
5108        PrimitiveOp::Le => (a <= b) as u128,
5109        PrimitiveOp::Lt => (a < b) as u128,
5110        PrimitiveOp::Ge => (a >= b) as u128,
5111        PrimitiveOp::Gt => (a > b) as u128,
5112        PrimitiveOp::Concat => 0,
5113        PrimitiveOp::Div => {
5114            if b == 0 {
5115                0
5116            } else {
5117                (a / b) & MASK
5118            }
5119        }
5120        PrimitiveOp::Mod => {
5121            if b == 0 {
5122                0
5123            } else {
5124                (a % b) & MASK
5125            }
5126        }
5127        PrimitiveOp::Pow => (const_pow_w104(a, b)) & MASK,
5128        _ => 0,
5129    }
5130}
5131
5132#[inline]
5133#[must_use]
5134pub const fn const_pow_w104(base: u128, exp: u128) -> u128 {
5135    const MASK: u128 = u128::MAX >> (128 - 104);
5136    let mut result: u128 = 1;
5137    let mut b: u128 = (base) & MASK;
5138    let mut e: u128 = exp;
5139    while e > 0 {
5140        if (e & 1) == 1 {
5141            result = (result.wrapping_mul(b)) & MASK;
5142        }
5143        b = (b.wrapping_mul(b)) & MASK;
5144        e >>= 1;
5145    }
5146    result
5147}
5148
5149#[inline]
5150#[must_use]
5151pub const fn const_ring_eval_unary_w104(op: PrimitiveOp, a: u128) -> u128 {
5152    const MASK: u128 = u128::MAX >> (128 - 104);
5153    match op {
5154        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5155        PrimitiveOp::Bnot => (!a) & MASK,
5156        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5157        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5158        _ => 0,
5159    }
5160}
5161
5162#[inline]
5163#[must_use]
5164#[allow(clippy::manual_checked_ops)]
5165pub const fn const_ring_eval_w112(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5166    const MASK: u128 = u128::MAX >> (128 - 112);
5167    match op {
5168        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5169        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5170        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5171        PrimitiveOp::Xor => (a ^ b) & MASK,
5172        PrimitiveOp::And => (a & b) & MASK,
5173        PrimitiveOp::Or => (a | b) & MASK,
5174        PrimitiveOp::Le => (a <= b) as u128,
5175        PrimitiveOp::Lt => (a < b) as u128,
5176        PrimitiveOp::Ge => (a >= b) as u128,
5177        PrimitiveOp::Gt => (a > b) as u128,
5178        PrimitiveOp::Concat => 0,
5179        PrimitiveOp::Div => {
5180            if b == 0 {
5181                0
5182            } else {
5183                (a / b) & MASK
5184            }
5185        }
5186        PrimitiveOp::Mod => {
5187            if b == 0 {
5188                0
5189            } else {
5190                (a % b) & MASK
5191            }
5192        }
5193        PrimitiveOp::Pow => (const_pow_w112(a, b)) & MASK,
5194        _ => 0,
5195    }
5196}
5197
5198#[inline]
5199#[must_use]
5200pub const fn const_pow_w112(base: u128, exp: u128) -> u128 {
5201    const MASK: u128 = u128::MAX >> (128 - 112);
5202    let mut result: u128 = 1;
5203    let mut b: u128 = (base) & MASK;
5204    let mut e: u128 = exp;
5205    while e > 0 {
5206        if (e & 1) == 1 {
5207            result = (result.wrapping_mul(b)) & MASK;
5208        }
5209        b = (b.wrapping_mul(b)) & MASK;
5210        e >>= 1;
5211    }
5212    result
5213}
5214
5215#[inline]
5216#[must_use]
5217pub const fn const_ring_eval_unary_w112(op: PrimitiveOp, a: u128) -> u128 {
5218    const MASK: u128 = u128::MAX >> (128 - 112);
5219    match op {
5220        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5221        PrimitiveOp::Bnot => (!a) & MASK,
5222        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5223        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5224        _ => 0,
5225    }
5226}
5227
5228#[inline]
5229#[must_use]
5230#[allow(clippy::manual_checked_ops)]
5231pub const fn const_ring_eval_w120(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5232    const MASK: u128 = u128::MAX >> (128 - 120);
5233    match op {
5234        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5235        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5236        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5237        PrimitiveOp::Xor => (a ^ b) & MASK,
5238        PrimitiveOp::And => (a & b) & MASK,
5239        PrimitiveOp::Or => (a | b) & MASK,
5240        PrimitiveOp::Le => (a <= b) as u128,
5241        PrimitiveOp::Lt => (a < b) as u128,
5242        PrimitiveOp::Ge => (a >= b) as u128,
5243        PrimitiveOp::Gt => (a > b) as u128,
5244        PrimitiveOp::Concat => 0,
5245        PrimitiveOp::Div => {
5246            if b == 0 {
5247                0
5248            } else {
5249                (a / b) & MASK
5250            }
5251        }
5252        PrimitiveOp::Mod => {
5253            if b == 0 {
5254                0
5255            } else {
5256                (a % b) & MASK
5257            }
5258        }
5259        PrimitiveOp::Pow => (const_pow_w120(a, b)) & MASK,
5260        _ => 0,
5261    }
5262}
5263
5264#[inline]
5265#[must_use]
5266pub const fn const_pow_w120(base: u128, exp: u128) -> u128 {
5267    const MASK: u128 = u128::MAX >> (128 - 120);
5268    let mut result: u128 = 1;
5269    let mut b: u128 = (base) & MASK;
5270    let mut e: u128 = exp;
5271    while e > 0 {
5272        if (e & 1) == 1 {
5273            result = (result.wrapping_mul(b)) & MASK;
5274        }
5275        b = (b.wrapping_mul(b)) & MASK;
5276        e >>= 1;
5277    }
5278    result
5279}
5280
5281#[inline]
5282#[must_use]
5283pub const fn const_ring_eval_unary_w120(op: PrimitiveOp, a: u128) -> u128 {
5284    const MASK: u128 = u128::MAX >> (128 - 120);
5285    match op {
5286        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5287        PrimitiveOp::Bnot => (!a) & MASK,
5288        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5289        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5290        _ => 0,
5291    }
5292}
5293
5294#[inline]
5295#[must_use]
5296#[allow(clippy::manual_checked_ops)]
5297pub const fn const_ring_eval_w128(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5298    match op {
5299        PrimitiveOp::Add => a.wrapping_add(b),
5300        PrimitiveOp::Sub => a.wrapping_sub(b),
5301        PrimitiveOp::Mul => a.wrapping_mul(b),
5302        PrimitiveOp::Xor => a ^ b,
5303        PrimitiveOp::And => a & b,
5304        PrimitiveOp::Or => a | b,
5305        PrimitiveOp::Le => (a <= b) as u128,
5306        PrimitiveOp::Lt => (a < b) as u128,
5307        PrimitiveOp::Ge => (a >= b) as u128,
5308        PrimitiveOp::Gt => (a > b) as u128,
5309        PrimitiveOp::Concat => 0,
5310        PrimitiveOp::Div => {
5311            if b == 0 {
5312                0
5313            } else {
5314                a / b
5315            }
5316        }
5317        PrimitiveOp::Mod => {
5318            if b == 0 {
5319                0
5320            } else {
5321                a % b
5322            }
5323        }
5324        PrimitiveOp::Pow => const_pow_w128(a, b),
5325        _ => 0,
5326    }
5327}
5328
5329#[inline]
5330#[must_use]
5331pub const fn const_pow_w128(base: u128, exp: u128) -> u128 {
5332    let mut result: u128 = 1;
5333    let mut b: u128 = base;
5334    let mut e: u128 = exp;
5335    while e > 0 {
5336        if (e & 1) == 1 {
5337            result = result.wrapping_mul(b);
5338        }
5339        b = b.wrapping_mul(b);
5340        e >>= 1;
5341    }
5342    result
5343}
5344
5345#[inline]
5346#[must_use]
5347pub const fn const_ring_eval_unary_w128(op: PrimitiveOp, a: u128) -> u128 {
5348    match op {
5349        PrimitiveOp::Neg => 0u128.wrapping_sub(a),
5350        PrimitiveOp::Bnot => !a,
5351        PrimitiveOp::Succ => a.wrapping_add(1),
5352        PrimitiveOp::Pred => a.wrapping_sub(1),
5353        _ => 0,
5354    }
5355}
5356
5357/// v0.2.2 Phase C.3: foundation-internal generic backing for Witt
5358/// levels above W128. Holds an inline `[u64; N]` array with no heap
5359/// allocation, no global state, and `const fn` arithmetic throughout.
5360/// Constructors are `pub(crate)`; downstream cannot fabricate a `Limbs<N>`.
5361/// Multiplication is schoolbook-only at v0.2.2 Phase C.3; the Toom-Cook
5362/// framework with parametric splitting factor `R` ships in Phase C.4 via
5363/// the `resolver::multiplication::certify` resolver, which decides `R`
5364/// per call from a Landauer cost function constrained by stack budget.
5365#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5366pub struct Limbs<const N: usize> {
5367    /// Little-endian limbs: `words[0]` is the low 64 bits.
5368    words: [u64; N],
5369    /// Prevents external construction.
5370    _sealed: (),
5371}
5372
5373impl<const N: usize> Limbs<N> {
5374    /// Crate-internal constructor from a fixed-size limb array.
5375    #[inline]
5376    #[must_use]
5377    #[allow(dead_code)]
5378    pub(crate) const fn from_words(words: [u64; N]) -> Self {
5379        Self { words, _sealed: () }
5380    }
5381
5382    /// All-zeros constructor.
5383    #[inline]
5384    #[must_use]
5385    #[allow(dead_code)]
5386    pub(crate) const fn zero() -> Self {
5387        Self {
5388            words: [0u64; N],
5389            _sealed: (),
5390        }
5391    }
5392
5393    /// Returns a reference to the underlying limb array.
5394    #[inline]
5395    #[must_use]
5396    pub const fn words(&self) -> &[u64; N] {
5397        &self.words
5398    }
5399
5400    /// Wrapping addition mod 2^(64*N). Const-fn schoolbook with carry.
5401    #[inline]
5402    #[must_use]
5403    #[allow(dead_code)]
5404    pub(crate) const fn wrapping_add(self, other: Self) -> Self {
5405        let mut out = [0u64; N];
5406        let mut carry: u64 = 0;
5407        let mut i = 0;
5408        while i < N {
5409            let (s1, c1) = self.words[i].overflowing_add(other.words[i]);
5410            let (s2, c2) = s1.overflowing_add(carry);
5411            out[i] = s2;
5412            carry = (c1 as u64) | (c2 as u64);
5413            i += 1;
5414        }
5415        Self {
5416            words: out,
5417            _sealed: (),
5418        }
5419    }
5420
5421    /// Wrapping subtraction mod 2^(64*N). Const-fn schoolbook with borrow.
5422    #[inline]
5423    #[must_use]
5424    #[allow(dead_code)]
5425    pub(crate) const fn wrapping_sub(self, other: Self) -> Self {
5426        let mut out = [0u64; N];
5427        let mut borrow: u64 = 0;
5428        let mut i = 0;
5429        while i < N {
5430            let (d1, b1) = self.words[i].overflowing_sub(other.words[i]);
5431            let (d2, b2) = d1.overflowing_sub(borrow);
5432            out[i] = d2;
5433            borrow = (b1 as u64) | (b2 as u64);
5434            i += 1;
5435        }
5436        Self {
5437            words: out,
5438            _sealed: (),
5439        }
5440    }
5441
5442    /// Wrapping schoolbook multiplication mod 2^(64*N). The high N limbs of
5443    /// the 2N-limb full product are discarded (mod 2^bits truncation).
5444    /// v0.2.2 Phase C.3: schoolbook only. Phase C.4 adds the Toom-Cook
5445    /// framework with parametric R via `resolver::multiplication::certify`.
5446    #[inline]
5447    #[must_use]
5448    #[allow(dead_code)]
5449    pub(crate) const fn wrapping_mul(self, other: Self) -> Self {
5450        let mut out = [0u64; N];
5451        let mut i = 0;
5452        while i < N {
5453            let mut carry: u128 = 0;
5454            let mut j = 0;
5455            while j < N - i {
5456                let prod = (self.words[i] as u128) * (other.words[j] as u128)
5457                    + (out[i + j] as u128)
5458                    + carry;
5459                out[i + j] = prod as u64;
5460                carry = prod >> 64;
5461                j += 1;
5462            }
5463            i += 1;
5464        }
5465        Self {
5466            words: out,
5467            _sealed: (),
5468        }
5469    }
5470
5471    /// Bitwise XOR.
5472    #[inline]
5473    #[must_use]
5474    #[allow(dead_code)]
5475    pub(crate) const fn xor(self, other: Self) -> Self {
5476        let mut out = [0u64; N];
5477        let mut i = 0;
5478        while i < N {
5479            out[i] = self.words[i] ^ other.words[i];
5480            i += 1;
5481        }
5482        Self {
5483            words: out,
5484            _sealed: (),
5485        }
5486    }
5487
5488    /// Bitwise AND.
5489    #[inline]
5490    #[must_use]
5491    #[allow(dead_code)]
5492    pub(crate) const fn and(self, other: Self) -> Self {
5493        let mut out = [0u64; N];
5494        let mut i = 0;
5495        while i < N {
5496            out[i] = self.words[i] & other.words[i];
5497            i += 1;
5498        }
5499        Self {
5500            words: out,
5501            _sealed: (),
5502        }
5503    }
5504
5505    /// Bitwise OR.
5506    #[inline]
5507    #[must_use]
5508    #[allow(dead_code)]
5509    pub(crate) const fn or(self, other: Self) -> Self {
5510        let mut out = [0u64; N];
5511        let mut i = 0;
5512        while i < N {
5513            out[i] = self.words[i] | other.words[i];
5514            i += 1;
5515        }
5516        Self {
5517            words: out,
5518            _sealed: (),
5519        }
5520    }
5521
5522    /// Bitwise NOT.
5523    #[inline]
5524    #[must_use]
5525    #[allow(dead_code)]
5526    pub(crate) const fn not(self) -> Self {
5527        let mut out = [0u64; N];
5528        let mut i = 0;
5529        while i < N {
5530            out[i] = !self.words[i];
5531            i += 1;
5532        }
5533        Self {
5534            words: out,
5535            _sealed: (),
5536        }
5537    }
5538
5539    /// Mask the high bits of the value to keep only the low `bits` bits.
5540    /// Used at the arithmetic boundary for non-exact-fit Witt widths (e.g.,
5541    /// W160 over `Limbs<3>`: 64+64+32 bits = mask the upper 32 bits of words[2]).
5542    #[inline]
5543    #[must_use]
5544    #[allow(dead_code)]
5545    pub(crate) const fn mask_high_bits(self, bits: u32) -> Self {
5546        let mut out = self.words;
5547        let high_word_idx = (bits / 64) as usize;
5548        let low_bits_in_high_word = bits % 64;
5549        if low_bits_in_high_word != 0 && high_word_idx < N {
5550            let mask = (1u64 << low_bits_in_high_word) - 1;
5551            out[high_word_idx] &= mask;
5552            // Zero everything above the high word.
5553            let mut i = high_word_idx + 1;
5554            while i < N {
5555                out[i] = 0;
5556                i += 1;
5557            }
5558        } else if low_bits_in_high_word == 0 && high_word_idx < N {
5559            // bits is exactly a multiple of 64; zero everything from high_word_idx.
5560            let mut i = high_word_idx;
5561            while i < N {
5562                out[i] = 0;
5563                i += 1;
5564            }
5565        }
5566        Self {
5567            words: out,
5568            _sealed: (),
5569        }
5570    }
5571}
5572
5573/// Sealed marker trait identifying types produced by the foundation crate's
5574/// conformance/reduction pipeline. v0.2.1 bounds `Validated<T>` on this trait
5575/// so downstream crates cannot fabricate `Validated<UserType>` — user types
5576/// cannot impl `OntologyTarget` because the supertrait is private.
5577pub trait OntologyTarget: ontology_target_sealed::Sealed {}
5578
5579/// Sealed shim for `cert:GroundingCertificate`. Produced by GroundingAwareResolver.
5580#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5581pub struct GroundingCertificate {
5582    witt_bits: u16,
5583    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5584    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5585    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5586    /// are never equal even when leading bytes coincide.
5587    content_fingerprint: ContentFingerprint,
5588}
5589
5590impl GroundingCertificate {
5591    /// Returns the Witt level the certificate was issued for. Sourced
5592    /// from the pipeline's substrate hash output at minting time.
5593    #[inline]
5594    #[must_use]
5595    pub const fn witt_bits(&self) -> u16 {
5596        self.witt_bits
5597    }
5598
5599    /// v0.2.2 T5: returns the parametric content fingerprint of the
5600    /// source state, computed at mint time by the consumer-supplied
5601    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5602    /// certificates from different hashers are never equal because
5603    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5604    #[inline]
5605    #[must_use]
5606    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5607        self.content_fingerprint
5608    }
5609
5610    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5611    /// witt-bits value AND the parametric content fingerprint. Used by
5612    /// `pipeline::run` and `certify_*_const` to mint a certificate
5613    /// carrying the substrate-computed fingerprint of the source state.
5614    #[inline]
5615    #[must_use]
5616    #[allow(dead_code)]
5617    pub(crate) const fn with_level_and_fingerprint_const(
5618        witt_bits: u16,
5619        content_fingerprint: ContentFingerprint,
5620    ) -> Self {
5621        Self {
5622            witt_bits,
5623            content_fingerprint,
5624        }
5625    }
5626}
5627
5628/// Sealed shim for `cert:LiftChainCertificate`. Carries the v0.2.1 `target_level()` accessor populated from the pipeline's StageOutcome.
5629#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5630pub struct LiftChainCertificate {
5631    witt_bits: u16,
5632    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5633    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5634    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5635    /// are never equal even when leading bytes coincide.
5636    content_fingerprint: ContentFingerprint,
5637}
5638
5639impl LiftChainCertificate {
5640    /// Returns the Witt level the certificate was issued for. Sourced
5641    /// from the pipeline's substrate hash output at minting time.
5642    #[inline]
5643    #[must_use]
5644    pub const fn witt_bits(&self) -> u16 {
5645        self.witt_bits
5646    }
5647
5648    /// v0.2.2 T5: returns the parametric content fingerprint of the
5649    /// source state, computed at mint time by the consumer-supplied
5650    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5651    /// certificates from different hashers are never equal because
5652    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5653    #[inline]
5654    #[must_use]
5655    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5656        self.content_fingerprint
5657    }
5658
5659    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5660    /// witt-bits value AND the parametric content fingerprint. Used by
5661    /// `pipeline::run` and `certify_*_const` to mint a certificate
5662    /// carrying the substrate-computed fingerprint of the source state.
5663    #[inline]
5664    #[must_use]
5665    #[allow(dead_code)]
5666    pub(crate) const fn with_level_and_fingerprint_const(
5667        witt_bits: u16,
5668        content_fingerprint: ContentFingerprint,
5669    ) -> Self {
5670        Self {
5671            witt_bits,
5672            content_fingerprint,
5673        }
5674    }
5675}
5676
5677/// Sealed shim for `cert:InhabitanceCertificate` (v0.2.1).
5678#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5679pub struct InhabitanceCertificate {
5680    witt_bits: u16,
5681    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5682    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5683    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5684    /// are never equal even when leading bytes coincide.
5685    content_fingerprint: ContentFingerprint,
5686}
5687
5688impl InhabitanceCertificate {
5689    /// Returns the Witt level the certificate was issued for. Sourced
5690    /// from the pipeline's substrate hash output at minting time.
5691    #[inline]
5692    #[must_use]
5693    pub const fn witt_bits(&self) -> u16 {
5694        self.witt_bits
5695    }
5696
5697    /// v0.2.2 T5: returns the parametric content fingerprint of the
5698    /// source state, computed at mint time by the consumer-supplied
5699    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5700    /// certificates from different hashers are never equal because
5701    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5702    #[inline]
5703    #[must_use]
5704    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5705        self.content_fingerprint
5706    }
5707
5708    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5709    /// witt-bits value AND the parametric content fingerprint. Used by
5710    /// `pipeline::run` and `certify_*_const` to mint a certificate
5711    /// carrying the substrate-computed fingerprint of the source state.
5712    #[inline]
5713    #[must_use]
5714    #[allow(dead_code)]
5715    pub(crate) const fn with_level_and_fingerprint_const(
5716        witt_bits: u16,
5717        content_fingerprint: ContentFingerprint,
5718    ) -> Self {
5719        Self {
5720            witt_bits,
5721            content_fingerprint,
5722        }
5723    }
5724}
5725
5726/// Sealed shim for `cert:CompletenessCertificate`.
5727#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5728pub struct CompletenessCertificate {
5729    witt_bits: u16,
5730    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5731    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5732    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5733    /// are never equal even when leading bytes coincide.
5734    content_fingerprint: ContentFingerprint,
5735}
5736
5737impl CompletenessCertificate {
5738    /// Returns the Witt level the certificate was issued for. Sourced
5739    /// from the pipeline's substrate hash output at minting time.
5740    #[inline]
5741    #[must_use]
5742    pub const fn witt_bits(&self) -> u16 {
5743        self.witt_bits
5744    }
5745
5746    /// v0.2.2 T5: returns the parametric content fingerprint of the
5747    /// source state, computed at mint time by the consumer-supplied
5748    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5749    /// certificates from different hashers are never equal because
5750    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5751    #[inline]
5752    #[must_use]
5753    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5754        self.content_fingerprint
5755    }
5756
5757    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5758    /// witt-bits value AND the parametric content fingerprint. Used by
5759    /// `pipeline::run` and `certify_*_const` to mint a certificate
5760    /// carrying the substrate-computed fingerprint of the source state.
5761    #[inline]
5762    #[must_use]
5763    #[allow(dead_code)]
5764    pub(crate) const fn with_level_and_fingerprint_const(
5765        witt_bits: u16,
5766        content_fingerprint: ContentFingerprint,
5767    ) -> Self {
5768        Self {
5769            witt_bits,
5770            content_fingerprint,
5771        }
5772    }
5773}
5774
5775/// Sealed shim for `cert:MultiplicationCertificate` (v0.2.2 Phase C.4). Carries the cost-optimal Toom-Cook splitting factor R, the recursive sub-multiplication count, and the accumulated Landauer cost in nats.
5776#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5777pub struct MultiplicationCertificate {
5778    witt_bits: u16,
5779    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5780    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5781    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5782    /// are never equal even when leading bytes coincide.
5783    content_fingerprint: ContentFingerprint,
5784}
5785
5786impl MultiplicationCertificate {
5787    /// Returns the Witt level the certificate was issued for. Sourced
5788    /// from the pipeline's substrate hash output at minting time.
5789    #[inline]
5790    #[must_use]
5791    pub const fn witt_bits(&self) -> u16 {
5792        self.witt_bits
5793    }
5794
5795    /// v0.2.2 T5: returns the parametric content fingerprint of the
5796    /// source state, computed at mint time by the consumer-supplied
5797    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5798    /// certificates from different hashers are never equal because
5799    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5800    #[inline]
5801    #[must_use]
5802    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5803        self.content_fingerprint
5804    }
5805
5806    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5807    /// witt-bits value AND the parametric content fingerprint. Used by
5808    /// `pipeline::run` and `certify_*_const` to mint a certificate
5809    /// carrying the substrate-computed fingerprint of the source state.
5810    #[inline]
5811    #[must_use]
5812    #[allow(dead_code)]
5813    pub(crate) const fn with_level_and_fingerprint_const(
5814        witt_bits: u16,
5815        content_fingerprint: ContentFingerprint,
5816    ) -> Self {
5817        Self {
5818            witt_bits,
5819            content_fingerprint,
5820        }
5821    }
5822}
5823
5824/// Sealed shim for `cert:PartitionCertificate` (v0.2.2 Phase E). Attests the partition component classification of a Datum.
5825#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5826pub struct PartitionCertificate {
5827    witt_bits: u16,
5828    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5829    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5830    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5831    /// are never equal even when leading bytes coincide.
5832    content_fingerprint: ContentFingerprint,
5833}
5834
5835impl PartitionCertificate {
5836    /// Returns the Witt level the certificate was issued for. Sourced
5837    /// from the pipeline's substrate hash output at minting time.
5838    #[inline]
5839    #[must_use]
5840    pub const fn witt_bits(&self) -> u16 {
5841        self.witt_bits
5842    }
5843
5844    /// v0.2.2 T5: returns the parametric content fingerprint of the
5845    /// source state, computed at mint time by the consumer-supplied
5846    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5847    /// certificates from different hashers are never equal because
5848    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5849    #[inline]
5850    #[must_use]
5851    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5852        self.content_fingerprint
5853    }
5854
5855    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5856    /// witt-bits value AND the parametric content fingerprint. Used by
5857    /// `pipeline::run` and `certify_*_const` to mint a certificate
5858    /// carrying the substrate-computed fingerprint of the source state.
5859    #[inline]
5860    #[must_use]
5861    #[allow(dead_code)]
5862    pub(crate) const fn with_level_and_fingerprint_const(
5863        witt_bits: u16,
5864        content_fingerprint: ContentFingerprint,
5865    ) -> Self {
5866        Self {
5867            witt_bits,
5868            content_fingerprint,
5869        }
5870    }
5871}
5872
5873/// Sealed shim for `proof:ImpossibilityWitness`. Returned by completeness and grounding resolvers on failure.
5874#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5875pub struct GenericImpossibilityWitness {
5876    /// Optional theorem / invariant IRI identifying the failed identity.
5877    /// `None` for legacy call sites minting via `Default::default()`;
5878    /// `Some(iri)` when the witness is constructed via `for_identity`
5879    /// (Product/Coproduct Completion Amendment §2.3a).
5880    identity: Option<&'static str>,
5881}
5882
5883impl Default for GenericImpossibilityWitness {
5884    #[inline]
5885    fn default() -> Self {
5886        Self { identity: None }
5887    }
5888}
5889
5890impl GenericImpossibilityWitness {
5891    /// Construct a witness citing a specific theorem / invariant IRI.
5892    /// Introduced by the Product/Coproduct Completion Amendment §2.3a
5893    /// so mint primitives can emit typed failures against `op/*` theorems
5894    /// and `foundation/*` layout invariants.
5895    #[inline]
5896    #[must_use]
5897    pub const fn for_identity(identity: &'static str) -> Self {
5898        Self {
5899            identity: Some(identity),
5900        }
5901    }
5902
5903    /// Returns the theorem / invariant IRI this witness cites, if any.
5904    #[inline]
5905    #[must_use]
5906    pub const fn identity(&self) -> Option<&'static str> {
5907        self.identity
5908    }
5909}
5910
5911/// Sealed shim for `proof:InhabitanceImpossibilityWitness` (v0.2.1).
5912#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5913pub struct InhabitanceImpossibilityWitness {
5914    _private: (),
5915}
5916
5917/// Input shim for `type:ConstrainedType`. Used as `Certify::Input` for InhabitanceResolver, TowerCompletenessResolver, and IncrementalCompletenessResolver.
5918#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5919pub struct ConstrainedTypeInput {
5920    _private: (),
5921}
5922
5923impl core::fmt::Display for GenericImpossibilityWitness {
5924    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5925        match self.identity {
5926            Some(iri) => write!(f, "GenericImpossibilityWitness({iri})"),
5927            None => f.write_str("GenericImpossibilityWitness"),
5928        }
5929    }
5930}
5931impl core::error::Error for GenericImpossibilityWitness {}
5932
5933impl core::fmt::Display for InhabitanceImpossibilityWitness {
5934    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5935        f.write_str("InhabitanceImpossibilityWitness")
5936    }
5937}
5938impl core::error::Error for InhabitanceImpossibilityWitness {}
5939
5940impl LiftChainCertificate {
5941    /// Returns the Witt level the certificate was issued for.
5942    #[inline]
5943    #[must_use]
5944    pub const fn target_level(&self) -> WittLevel {
5945        WittLevel::new(self.witt_bits as u32)
5946    }
5947}
5948
5949impl InhabitanceCertificate {
5950    /// Returns the witness value tuple bytes when `verified` is true.
5951    /// The sealed shim returns `None`; real witnesses flow through the
5952    /// macro back-door path.
5953    #[inline]
5954    #[must_use]
5955    pub const fn witness(&self) -> Option<&'static [u8]> {
5956        None
5957    }
5958}
5959
5960pub(crate) mod ontology_target_sealed {
5961    /// Private supertrait. Not implementable outside this crate.
5962    pub trait Sealed {}
5963    impl Sealed for super::GroundingCertificate {}
5964    impl Sealed for super::LiftChainCertificate {}
5965    impl Sealed for super::InhabitanceCertificate {}
5966    impl Sealed for super::CompletenessCertificate {}
5967    impl Sealed for super::MultiplicationCertificate {}
5968    impl Sealed for super::PartitionCertificate {}
5969    impl Sealed for super::GenericImpossibilityWitness {}
5970    impl Sealed for super::InhabitanceImpossibilityWitness {}
5971    impl Sealed for super::ConstrainedTypeInput {}
5972    impl Sealed for super::PartitionProductWitness {}
5973    impl Sealed for super::PartitionCoproductWitness {}
5974    impl Sealed for super::CartesianProductWitness {}
5975    impl Sealed for super::CompileUnit<'_> {}
5976}
5977
5978impl OntologyTarget for GroundingCertificate {}
5979impl OntologyTarget for LiftChainCertificate {}
5980impl OntologyTarget for InhabitanceCertificate {}
5981impl OntologyTarget for CompletenessCertificate {}
5982impl OntologyTarget for MultiplicationCertificate {}
5983impl OntologyTarget for PartitionCertificate {}
5984impl OntologyTarget for GenericImpossibilityWitness {}
5985impl OntologyTarget for InhabitanceImpossibilityWitness {}
5986impl OntologyTarget for ConstrainedTypeInput {}
5987impl OntologyTarget for PartitionProductWitness {}
5988impl OntologyTarget for PartitionCoproductWitness {}
5989impl OntologyTarget for CartesianProductWitness {}
5990impl OntologyTarget for CompileUnit<'_> {}
5991
5992/// v0.2.2 W11: supporting evidence type for `CompletenessCertificate`.
5993/// Linked from the certificate via the `Certificate::Evidence` associated type.
5994#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5995pub struct CompletenessAuditTrail {
5996    _private: (),
5997}
5998
5999/// v0.2.2 W11: supporting evidence type for `LiftChainCertificate`.
6000#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6001pub struct ChainAuditTrail {
6002    _private: (),
6003}
6004
6005/// v0.2.2 W11: supporting evidence type for `GeodesicCertificate`.
6006#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6007pub struct GeodesicEvidenceBundle {
6008    _private: (),
6009}
6010
6011/// v0.2.2 W11: sealed carrier for `cert:TransformCertificate`.
6012/// Phase X.1: minted with a Witt level and content fingerprint so the
6013/// resolver whose `resolver:CertifyMapping` produces this class can fold
6014/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6015/// constructor matches every other `cert:Certificate` subclass.
6016#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6017pub struct TransformCertificate {
6018    witt_bits: u16,
6019    content_fingerprint: ContentFingerprint,
6020    _private: (),
6021}
6022
6023impl TransformCertificate {
6024    /// Phase X.1: content-addressed constructor. Mints a certificate
6025    /// carrying the Witt level and substrate-hasher fingerprint of the
6026    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6027    #[inline]
6028    #[must_use]
6029    #[allow(dead_code)]
6030    pub(crate) const fn with_level_and_fingerprint_const(
6031        witt_bits: u16,
6032        content_fingerprint: ContentFingerprint,
6033    ) -> Self {
6034        Self {
6035            witt_bits,
6036            content_fingerprint,
6037            _private: (),
6038        }
6039    }
6040
6041    /// Phase X.1: legacy zero-fingerprint constructor retained for
6042    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6043    #[inline]
6044    #[must_use]
6045    #[allow(dead_code)]
6046    pub(crate) const fn empty_const() -> Self {
6047        Self {
6048            witt_bits: 0,
6049            content_fingerprint: ContentFingerprint::zero(),
6050            _private: (),
6051        }
6052    }
6053
6054    /// Phase X.1: the Witt level at which this certificate was minted.
6055    #[inline]
6056    #[must_use]
6057    pub const fn witt_bits(&self) -> u16 {
6058        self.witt_bits
6059    }
6060
6061    /// Phase X.1: the content fingerprint of the resolver decision.
6062    #[inline]
6063    #[must_use]
6064    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6065        self.content_fingerprint
6066    }
6067}
6068
6069/// v0.2.2 W11: sealed carrier for `cert:IsometryCertificate`.
6070/// Phase X.1: minted with a Witt level and content fingerprint so the
6071/// resolver whose `resolver:CertifyMapping` produces this class can fold
6072/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6073/// constructor matches every other `cert:Certificate` subclass.
6074#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6075pub struct IsometryCertificate {
6076    witt_bits: u16,
6077    content_fingerprint: ContentFingerprint,
6078    _private: (),
6079}
6080
6081impl IsometryCertificate {
6082    /// Phase X.1: content-addressed constructor. Mints a certificate
6083    /// carrying the Witt level and substrate-hasher fingerprint of the
6084    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6085    #[inline]
6086    #[must_use]
6087    #[allow(dead_code)]
6088    pub(crate) const fn with_level_and_fingerprint_const(
6089        witt_bits: u16,
6090        content_fingerprint: ContentFingerprint,
6091    ) -> Self {
6092        Self {
6093            witt_bits,
6094            content_fingerprint,
6095            _private: (),
6096        }
6097    }
6098
6099    /// Phase X.1: legacy zero-fingerprint constructor retained for
6100    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6101    #[inline]
6102    #[must_use]
6103    #[allow(dead_code)]
6104    pub(crate) const fn empty_const() -> Self {
6105        Self {
6106            witt_bits: 0,
6107            content_fingerprint: ContentFingerprint::zero(),
6108            _private: (),
6109        }
6110    }
6111
6112    /// Phase X.1: the Witt level at which this certificate was minted.
6113    #[inline]
6114    #[must_use]
6115    pub const fn witt_bits(&self) -> u16 {
6116        self.witt_bits
6117    }
6118
6119    /// Phase X.1: the content fingerprint of the resolver decision.
6120    #[inline]
6121    #[must_use]
6122    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6123        self.content_fingerprint
6124    }
6125}
6126
6127/// v0.2.2 W11: sealed carrier for `cert:InvolutionCertificate`.
6128/// Phase X.1: minted with a Witt level and content fingerprint so the
6129/// resolver whose `resolver:CertifyMapping` produces this class can fold
6130/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6131/// constructor matches every other `cert:Certificate` subclass.
6132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6133pub struct InvolutionCertificate {
6134    witt_bits: u16,
6135    content_fingerprint: ContentFingerprint,
6136    _private: (),
6137}
6138
6139impl InvolutionCertificate {
6140    /// Phase X.1: content-addressed constructor. Mints a certificate
6141    /// carrying the Witt level and substrate-hasher fingerprint of the
6142    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6143    #[inline]
6144    #[must_use]
6145    #[allow(dead_code)]
6146    pub(crate) const fn with_level_and_fingerprint_const(
6147        witt_bits: u16,
6148        content_fingerprint: ContentFingerprint,
6149    ) -> Self {
6150        Self {
6151            witt_bits,
6152            content_fingerprint,
6153            _private: (),
6154        }
6155    }
6156
6157    /// Phase X.1: legacy zero-fingerprint constructor retained for
6158    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6159    #[inline]
6160    #[must_use]
6161    #[allow(dead_code)]
6162    pub(crate) const fn empty_const() -> Self {
6163        Self {
6164            witt_bits: 0,
6165            content_fingerprint: ContentFingerprint::zero(),
6166            _private: (),
6167        }
6168    }
6169
6170    /// Phase X.1: the Witt level at which this certificate was minted.
6171    #[inline]
6172    #[must_use]
6173    pub const fn witt_bits(&self) -> u16 {
6174        self.witt_bits
6175    }
6176
6177    /// Phase X.1: the content fingerprint of the resolver decision.
6178    #[inline]
6179    #[must_use]
6180    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6181        self.content_fingerprint
6182    }
6183}
6184
6185/// v0.2.2 W11: sealed carrier for `cert:GeodesicCertificate`.
6186/// Phase X.1: minted with a Witt level and content fingerprint so the
6187/// resolver whose `resolver:CertifyMapping` produces this class can fold
6188/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6189/// constructor matches every other `cert:Certificate` subclass.
6190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6191pub struct GeodesicCertificate {
6192    witt_bits: u16,
6193    content_fingerprint: ContentFingerprint,
6194    _private: (),
6195}
6196
6197impl GeodesicCertificate {
6198    /// Phase X.1: content-addressed constructor. Mints a certificate
6199    /// carrying the Witt level and substrate-hasher fingerprint of the
6200    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6201    #[inline]
6202    #[must_use]
6203    #[allow(dead_code)]
6204    pub(crate) const fn with_level_and_fingerprint_const(
6205        witt_bits: u16,
6206        content_fingerprint: ContentFingerprint,
6207    ) -> Self {
6208        Self {
6209            witt_bits,
6210            content_fingerprint,
6211            _private: (),
6212        }
6213    }
6214
6215    /// Phase X.1: legacy zero-fingerprint constructor retained for
6216    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6217    #[inline]
6218    #[must_use]
6219    #[allow(dead_code)]
6220    pub(crate) const fn empty_const() -> Self {
6221        Self {
6222            witt_bits: 0,
6223            content_fingerprint: ContentFingerprint::zero(),
6224            _private: (),
6225        }
6226    }
6227
6228    /// Phase X.1: the Witt level at which this certificate was minted.
6229    #[inline]
6230    #[must_use]
6231    pub const fn witt_bits(&self) -> u16 {
6232        self.witt_bits
6233    }
6234
6235    /// Phase X.1: the content fingerprint of the resolver decision.
6236    #[inline]
6237    #[must_use]
6238    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6239        self.content_fingerprint
6240    }
6241}
6242
6243/// v0.2.2 W11: sealed carrier for `cert:MeasurementCertificate`.
6244/// Phase X.1: minted with a Witt level and content fingerprint so the
6245/// resolver whose `resolver:CertifyMapping` produces this class can fold
6246/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6247/// constructor matches every other `cert:Certificate` subclass.
6248#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6249pub struct MeasurementCertificate {
6250    witt_bits: u16,
6251    content_fingerprint: ContentFingerprint,
6252    _private: (),
6253}
6254
6255impl MeasurementCertificate {
6256    /// Phase X.1: content-addressed constructor. Mints a certificate
6257    /// carrying the Witt level and substrate-hasher fingerprint of the
6258    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6259    #[inline]
6260    #[must_use]
6261    #[allow(dead_code)]
6262    pub(crate) const fn with_level_and_fingerprint_const(
6263        witt_bits: u16,
6264        content_fingerprint: ContentFingerprint,
6265    ) -> Self {
6266        Self {
6267            witt_bits,
6268            content_fingerprint,
6269            _private: (),
6270        }
6271    }
6272
6273    /// Phase X.1: legacy zero-fingerprint constructor retained for
6274    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6275    #[inline]
6276    #[must_use]
6277    #[allow(dead_code)]
6278    pub(crate) const fn empty_const() -> Self {
6279        Self {
6280            witt_bits: 0,
6281            content_fingerprint: ContentFingerprint::zero(),
6282            _private: (),
6283        }
6284    }
6285
6286    /// Phase X.1: the Witt level at which this certificate was minted.
6287    #[inline]
6288    #[must_use]
6289    pub const fn witt_bits(&self) -> u16 {
6290        self.witt_bits
6291    }
6292
6293    /// Phase X.1: the content fingerprint of the resolver decision.
6294    #[inline]
6295    #[must_use]
6296    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6297        self.content_fingerprint
6298    }
6299}
6300
6301/// v0.2.2 W11: sealed carrier for `cert:BornRuleVerification`.
6302/// Phase X.1: minted with a Witt level and content fingerprint so the
6303/// resolver whose `resolver:CertifyMapping` produces this class can fold
6304/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6305/// constructor matches every other `cert:Certificate` subclass.
6306#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6307pub struct BornRuleVerification {
6308    witt_bits: u16,
6309    content_fingerprint: ContentFingerprint,
6310    _private: (),
6311}
6312
6313impl BornRuleVerification {
6314    /// Phase X.1: content-addressed constructor. Mints a certificate
6315    /// carrying the Witt level and substrate-hasher fingerprint of the
6316    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6317    #[inline]
6318    #[must_use]
6319    #[allow(dead_code)]
6320    pub(crate) const fn with_level_and_fingerprint_const(
6321        witt_bits: u16,
6322        content_fingerprint: ContentFingerprint,
6323    ) -> Self {
6324        Self {
6325            witt_bits,
6326            content_fingerprint,
6327            _private: (),
6328        }
6329    }
6330
6331    /// Phase X.1: legacy zero-fingerprint constructor retained for
6332    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6333    #[inline]
6334    #[must_use]
6335    #[allow(dead_code)]
6336    pub(crate) const fn empty_const() -> Self {
6337        Self {
6338            witt_bits: 0,
6339            content_fingerprint: ContentFingerprint::zero(),
6340            _private: (),
6341        }
6342    }
6343
6344    /// Phase X.1: the Witt level at which this certificate was minted.
6345    #[inline]
6346    #[must_use]
6347    pub const fn witt_bits(&self) -> u16 {
6348        self.witt_bits
6349    }
6350
6351    /// Phase X.1: the content fingerprint of the resolver decision.
6352    #[inline]
6353    #[must_use]
6354    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6355        self.content_fingerprint
6356    }
6357}
6358
6359/// v0.2.2 W11: sealed marker trait for foundation-supplied certificate kinds.
6360/// Implemented by every `cert:Certificate` subclass via codegen; not
6361/// implementable outside this crate.
6362pub trait Certificate: certificate_sealed::Sealed {
6363    /// The ontology IRI of this certificate class.
6364    const IRI: &'static str;
6365    /// The structured evidence carried by this certificate (or `()` if none).
6366    type Evidence;
6367}
6368
6369pub(crate) mod certificate_sealed {
6370    /// Private supertrait. Not implementable outside this crate.
6371    pub trait Sealed {}
6372    impl Sealed for super::GroundingCertificate {}
6373    impl Sealed for super::LiftChainCertificate {}
6374    impl Sealed for super::InhabitanceCertificate {}
6375    impl Sealed for super::CompletenessCertificate {}
6376    impl Sealed for super::TransformCertificate {}
6377    impl Sealed for super::IsometryCertificate {}
6378    impl Sealed for super::InvolutionCertificate {}
6379    impl Sealed for super::GeodesicCertificate {}
6380    impl Sealed for super::MeasurementCertificate {}
6381    impl Sealed for super::BornRuleVerification {}
6382    impl Sealed for super::MultiplicationCertificate {}
6383    impl Sealed for super::PartitionCertificate {}
6384    impl Sealed for super::GenericImpossibilityWitness {}
6385    impl Sealed for super::InhabitanceImpossibilityWitness {}
6386    impl Sealed for super::PartitionProductWitness {}
6387    impl Sealed for super::PartitionCoproductWitness {}
6388    impl Sealed for super::CartesianProductWitness {}
6389}
6390
6391impl Certificate for GroundingCertificate {
6392    const IRI: &'static str = "https://uor.foundation/cert/GroundingCertificate";
6393    type Evidence = ();
6394}
6395
6396impl Certificate for LiftChainCertificate {
6397    const IRI: &'static str = "https://uor.foundation/cert/LiftChainCertificate";
6398    type Evidence = ChainAuditTrail;
6399}
6400
6401impl Certificate for InhabitanceCertificate {
6402    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceCertificate";
6403    type Evidence = ();
6404}
6405
6406impl Certificate for CompletenessCertificate {
6407    const IRI: &'static str = "https://uor.foundation/cert/CompletenessCertificate";
6408    type Evidence = CompletenessAuditTrail;
6409}
6410
6411impl Certificate for TransformCertificate {
6412    const IRI: &'static str = "https://uor.foundation/cert/TransformCertificate";
6413    type Evidence = ();
6414}
6415
6416impl Certificate for IsometryCertificate {
6417    const IRI: &'static str = "https://uor.foundation/cert/IsometryCertificate";
6418    type Evidence = ();
6419}
6420
6421impl Certificate for InvolutionCertificate {
6422    const IRI: &'static str = "https://uor.foundation/cert/InvolutionCertificate";
6423    type Evidence = ();
6424}
6425
6426impl Certificate for GeodesicCertificate {
6427    const IRI: &'static str = "https://uor.foundation/cert/GeodesicCertificate";
6428    type Evidence = GeodesicEvidenceBundle;
6429}
6430
6431impl Certificate for MeasurementCertificate {
6432    const IRI: &'static str = "https://uor.foundation/cert/MeasurementCertificate";
6433    type Evidence = ();
6434}
6435
6436impl Certificate for BornRuleVerification {
6437    const IRI: &'static str = "https://uor.foundation/cert/BornRuleVerification";
6438    type Evidence = ();
6439}
6440
6441impl Certificate for MultiplicationCertificate {
6442    const IRI: &'static str = "https://uor.foundation/cert/MultiplicationCertificate";
6443    type Evidence = MultiplicationEvidence;
6444}
6445
6446impl Certificate for PartitionCertificate {
6447    const IRI: &'static str = "https://uor.foundation/cert/PartitionCertificate";
6448    type Evidence = ();
6449}
6450
6451impl Certificate for GenericImpossibilityWitness {
6452    const IRI: &'static str = "https://uor.foundation/cert/GenericImpossibilityCertificate";
6453    type Evidence = ();
6454}
6455
6456impl Certificate for InhabitanceImpossibilityWitness {
6457    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceImpossibilityCertificate";
6458    type Evidence = ();
6459}
6460
6461/// Phase X.1: uniform mint interface over cert subclasses. Each
6462/// `Certificate` implementer that accepts `(witt_bits, ContentFingerprint)`
6463/// at construction time implements this trait. Lives inside a
6464/// `certify_const_mint` module so the symbol doesn't leak into top-level
6465/// documentation alongside `Certificate`.
6466pub(crate) mod certify_const_mint {
6467    use super::{Certificate, ContentFingerprint};
6468    pub trait MintWithLevelFingerprint: Certificate {
6469        fn mint_with_level_fingerprint(
6470            witt_bits: u16,
6471            content_fingerprint: ContentFingerprint,
6472        ) -> Self;
6473    }
6474    impl MintWithLevelFingerprint for super::GroundingCertificate {
6475        #[inline]
6476        fn mint_with_level_fingerprint(
6477            witt_bits: u16,
6478            content_fingerprint: ContentFingerprint,
6479        ) -> Self {
6480            super::GroundingCertificate::with_level_and_fingerprint_const(
6481                witt_bits,
6482                content_fingerprint,
6483            )
6484        }
6485    }
6486    impl MintWithLevelFingerprint for super::LiftChainCertificate {
6487        #[inline]
6488        fn mint_with_level_fingerprint(
6489            witt_bits: u16,
6490            content_fingerprint: ContentFingerprint,
6491        ) -> Self {
6492            super::LiftChainCertificate::with_level_and_fingerprint_const(
6493                witt_bits,
6494                content_fingerprint,
6495            )
6496        }
6497    }
6498    impl MintWithLevelFingerprint for super::InhabitanceCertificate {
6499        #[inline]
6500        fn mint_with_level_fingerprint(
6501            witt_bits: u16,
6502            content_fingerprint: ContentFingerprint,
6503        ) -> Self {
6504            super::InhabitanceCertificate::with_level_and_fingerprint_const(
6505                witt_bits,
6506                content_fingerprint,
6507            )
6508        }
6509    }
6510    impl MintWithLevelFingerprint for super::CompletenessCertificate {
6511        #[inline]
6512        fn mint_with_level_fingerprint(
6513            witt_bits: u16,
6514            content_fingerprint: ContentFingerprint,
6515        ) -> Self {
6516            super::CompletenessCertificate::with_level_and_fingerprint_const(
6517                witt_bits,
6518                content_fingerprint,
6519            )
6520        }
6521    }
6522    impl MintWithLevelFingerprint for super::MultiplicationCertificate {
6523        #[inline]
6524        fn mint_with_level_fingerprint(
6525            witt_bits: u16,
6526            content_fingerprint: ContentFingerprint,
6527        ) -> Self {
6528            super::MultiplicationCertificate::with_level_and_fingerprint_const(
6529                witt_bits,
6530                content_fingerprint,
6531            )
6532        }
6533    }
6534    impl MintWithLevelFingerprint for super::PartitionCertificate {
6535        #[inline]
6536        fn mint_with_level_fingerprint(
6537            witt_bits: u16,
6538            content_fingerprint: ContentFingerprint,
6539        ) -> Self {
6540            super::PartitionCertificate::with_level_and_fingerprint_const(
6541                witt_bits,
6542                content_fingerprint,
6543            )
6544        }
6545    }
6546    impl MintWithLevelFingerprint for super::TransformCertificate {
6547        #[inline]
6548        fn mint_with_level_fingerprint(
6549            witt_bits: u16,
6550            content_fingerprint: ContentFingerprint,
6551        ) -> Self {
6552            super::TransformCertificate::with_level_and_fingerprint_const(
6553                witt_bits,
6554                content_fingerprint,
6555            )
6556        }
6557    }
6558    impl MintWithLevelFingerprint for super::IsometryCertificate {
6559        #[inline]
6560        fn mint_with_level_fingerprint(
6561            witt_bits: u16,
6562            content_fingerprint: ContentFingerprint,
6563        ) -> Self {
6564            super::IsometryCertificate::with_level_and_fingerprint_const(
6565                witt_bits,
6566                content_fingerprint,
6567            )
6568        }
6569    }
6570    impl MintWithLevelFingerprint for super::InvolutionCertificate {
6571        #[inline]
6572        fn mint_with_level_fingerprint(
6573            witt_bits: u16,
6574            content_fingerprint: ContentFingerprint,
6575        ) -> Self {
6576            super::InvolutionCertificate::with_level_and_fingerprint_const(
6577                witt_bits,
6578                content_fingerprint,
6579            )
6580        }
6581    }
6582    impl MintWithLevelFingerprint for super::GeodesicCertificate {
6583        #[inline]
6584        fn mint_with_level_fingerprint(
6585            witt_bits: u16,
6586            content_fingerprint: ContentFingerprint,
6587        ) -> Self {
6588            super::GeodesicCertificate::with_level_and_fingerprint_const(
6589                witt_bits,
6590                content_fingerprint,
6591            )
6592        }
6593    }
6594    impl MintWithLevelFingerprint for super::MeasurementCertificate {
6595        #[inline]
6596        fn mint_with_level_fingerprint(
6597            witt_bits: u16,
6598            content_fingerprint: ContentFingerprint,
6599        ) -> Self {
6600            super::MeasurementCertificate::with_level_and_fingerprint_const(
6601                witt_bits,
6602                content_fingerprint,
6603            )
6604        }
6605    }
6606    impl MintWithLevelFingerprint for super::BornRuleVerification {
6607        #[inline]
6608        fn mint_with_level_fingerprint(
6609            witt_bits: u16,
6610            content_fingerprint: ContentFingerprint,
6611        ) -> Self {
6612            super::BornRuleVerification::with_level_and_fingerprint_const(
6613                witt_bits,
6614                content_fingerprint,
6615            )
6616        }
6617    }
6618}
6619
6620/// v0.2.2 W11: parametric carrier for any foundation-supplied certificate.
6621/// Replaces the v0.2.1 per-class shim duplication. The `Certificate` trait
6622/// is sealed and the `_private` field prevents external construction; only
6623/// the foundation's pipeline / resolver paths produce `Certified<C>` values.
6624#[derive(Debug, Clone)]
6625pub struct Certified<C: Certificate> {
6626    /// The certificate kind value carried by this wrapper.
6627    inner: C,
6628    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6629    uor_time: UorTime,
6630    /// Prevents external construction.
6631    _private: (),
6632}
6633
6634impl<C: Certificate> Certified<C> {
6635    /// Returns a reference to the carried certificate kind value.
6636    #[inline]
6637    #[must_use]
6638    pub const fn certificate(&self) -> &C {
6639        &self.inner
6640    }
6641
6642    /// Returns the ontology IRI of this certificate's kind.
6643    #[inline]
6644    #[must_use]
6645    pub const fn iri(&self) -> &'static str {
6646        C::IRI
6647    }
6648
6649    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6650    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
6651    /// `observable:LandauerCost`. Content-deterministic: same computation →
6652    /// same `UorTime`. Composable against wall-clock bounds via
6653    /// [`UorTime::min_wall_clock`] and a downstream-supplied `Calibration`.
6654    #[inline]
6655    #[must_use]
6656    pub const fn uor_time(&self) -> UorTime {
6657        self.uor_time
6658    }
6659
6660    /// Crate-internal constructor. Reachable only from the pipeline / resolver paths.
6661    /// The `uor_time` is computed deterministically from the certificate kind's `IRI`
6662    /// length: the rewrite-step count is the IRI byte length, and the Landauer cost
6663    /// is `rewrite_steps × ln 2` (the Landauer-temperature cost of traversing that
6664    /// many orthogonal states). Two `Certified<C>` values with the same `C` share the
6665    /// same `UorTime`, preserving content-determinism across pipeline invocations.
6666    #[inline]
6667    #[allow(dead_code)]
6668    pub(crate) const fn new(inner: C) -> Self {
6669        // IRI length is the deterministic proxy for the cert class's structural
6670        // complexity. Phase D threads real resolver-counted steps through.
6671        let steps = C::IRI.len() as u64;
6672        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
6673        let uor_time = UorTime::new(landauer, steps);
6674        Self {
6675            inner,
6676            uor_time,
6677            _private: (),
6678        }
6679    }
6680}
6681
6682/// v0.2.2 Phase C.4: call-site context consumed by the multiplication
6683/// resolver. Carries the stack budget (`linear:stackBudgetBytes`), the
6684/// const-eval regime, and the limb count of the operand's `Limbs<N>`
6685/// backing. The resolver picks the cost-optimal Toom-Cook splitting
6686/// factor R based on this context.
6687#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6688pub struct MulContext {
6689    /// Stack budget available at the call site, in bytes. Zero is
6690    /// inadmissible; the resolver returns an impossibility witness.
6691    pub stack_budget_bytes: u64,
6692    /// True if this call is in const-eval context. In const-eval, only
6693    /// R = 1 (schoolbook) is admissible because deeper recursion blows
6694    /// the const-eval depth limit.
6695    pub const_eval: bool,
6696    /// Number of 64-bit limbs in the operand's `Limbs<N>` backing.
6697    /// Schoolbook cost is proportional to `N^2`; Karatsuba cost is
6698    /// proportional to `3 · (N/2)^2`. For native-backed levels
6699    /// (W8..W128), pass the equivalent limb count.
6700    pub limb_count: usize,
6701}
6702
6703impl MulContext {
6704    /// Construct a new `MulContext` for the call site.
6705    #[inline]
6706    #[must_use]
6707    pub const fn new(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> Self {
6708        Self {
6709            stack_budget_bytes,
6710            const_eval,
6711            limb_count,
6712        }
6713    }
6714}
6715
6716/// v0.2.2 Phase C.4: evidence returned alongside a `MultiplicationCertificate`.
6717/// The certificate is a sealed handle; its evidence (chosen splitting factor,
6718/// sub-multiplication count, accumulated Landauer cost in nats) lives here.
6719#[derive(Debug, Clone, Copy, PartialEq)]
6720pub struct MultiplicationEvidence {
6721    splitting_factor: u32,
6722    sub_multiplication_count: u32,
6723    landauer_cost_nats_bits: u64,
6724}
6725
6726impl MultiplicationEvidence {
6727    /// The Toom-Cook splitting factor R chosen by the resolver.
6728    #[inline]
6729    #[must_use]
6730    pub const fn splitting_factor(&self) -> u32 {
6731        self.splitting_factor
6732    }
6733
6734    /// The recursive sub-multiplication count for one multiplication.
6735    #[inline]
6736    #[must_use]
6737    pub const fn sub_multiplication_count(&self) -> u32 {
6738        self.sub_multiplication_count
6739    }
6740
6741    /// Accumulated Landauer cost in nats, priced per `op:OA_5`. Returned as the IEEE-754 bit pattern; project to `H::Decimal` at use sites via `<H::Decimal as DecimalTranscendental>::from_bits(_)`.
6742    #[inline]
6743    #[must_use]
6744    pub const fn landauer_cost_nats_bits(&self) -> u64 {
6745        self.landauer_cost_nats_bits
6746    }
6747}
6748
6749impl MultiplicationCertificate {
6750    /// v0.2.2 T6.7: construct a `MultiplicationCertificate` with substrate-
6751    /// computed evidence. Crate-internal only; downstream obtains certificates
6752    /// via `resolver::multiplication::certify::<H>`.
6753    #[inline]
6754    #[must_use]
6755    pub(crate) fn with_evidence(
6756        splitting_factor: u32,
6757        sub_multiplication_count: u32,
6758        landauer_cost_nats_bits: u64,
6759        content_fingerprint: ContentFingerprint,
6760    ) -> Self {
6761        let _ = MultiplicationEvidence {
6762            splitting_factor,
6763            sub_multiplication_count,
6764            landauer_cost_nats_bits,
6765        };
6766        Self::with_level_and_fingerprint_const(32, content_fingerprint)
6767    }
6768}
6769
6770/// v0.2.2 Phase E: maximum simplicial dimension tracked by the
6771/// constraint-nerve Betti-numbers vector. The bound is 8 for the
6772/// currently-supported WittLevel set per the existing partition:FreeRank
6773/// capacity properties; the constant is `pub` (part of the public-API
6774/// snapshot) so future expansions require explicit review.
6775/// Wiki ADR-037: alias of [`crate::HostBounds::BETTI_DIMENSION_MAX`] via
6776/// [`crate::DefaultHostBounds`].
6777pub const MAX_BETTI_DIMENSION: usize =
6778    <crate::DefaultHostBounds as crate::HostBounds>::BETTI_DIMENSION_MAX;
6779
6780/// Sealed newtype for the grounding completion ratio σ ∈
6781/// [0.0, 1.0]. σ = 1 indicates the ground state; σ = 0 the
6782/// unbound state. Backs observable:GroundingSigma. Phase 9: parametric over
6783/// the host's `H::Decimal` precision.
6784#[derive(Debug)]
6785pub struct SigmaValue<H: HostTypes = crate::DefaultHostTypes> {
6786    value: H::Decimal,
6787    _phantom: core::marker::PhantomData<H>,
6788    _sealed: (),
6789}
6790
6791impl<H: HostTypes> Copy for SigmaValue<H> {}
6792impl<H: HostTypes> Clone for SigmaValue<H> {
6793    #[inline]
6794    fn clone(&self) -> Self {
6795        *self
6796    }
6797}
6798impl<H: HostTypes> PartialEq for SigmaValue<H> {
6799    #[inline]
6800    fn eq(&self, other: &Self) -> bool {
6801        self.value == other.value
6802    }
6803}
6804
6805impl<H: HostTypes> SigmaValue<H> {
6806    /// Returns the stored σ value in the range [0.0, 1.0].
6807    #[inline]
6808    #[must_use]
6809    pub const fn value(&self) -> H::Decimal {
6810        self.value
6811    }
6812
6813    /// Crate-internal constructor. Caller guarantees `value` is in
6814    /// the closed range [0.0, 1.0] and is not NaN.
6815    #[inline]
6816    #[must_use]
6817    #[allow(dead_code)]
6818    pub(crate) const fn new_unchecked(value: H::Decimal) -> Self {
6819        Self {
6820            value,
6821            _phantom: core::marker::PhantomData,
6822            _sealed: (),
6823        }
6824    }
6825}
6826
6827/// Phase A.3: sealed stratum coordinate (the v₂ valuation of a `Datum` at level `L`).
6828/// Backs `schema:stratum`. The value is non-negative and bounded by `L`'s `bit_width`
6829/// per the ontology's `nonNegativeInteger` range. Constructed only by foundation code
6830/// at grounding time; no public constructor — the `Stratum<W8>` / `Stratum<W16>` / ...
6831/// type family is closed under the WittLevel individual set.
6832#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6833pub struct Stratum<L> {
6834    value: u32,
6835    _level: PhantomData<L>,
6836    _sealed: (),
6837}
6838
6839impl<L> Stratum<L> {
6840    /// Returns the raw v₂ valuation as a `u32`. The value is bounded by `L`'s bit_width.
6841    #[inline]
6842    #[must_use]
6843    pub const fn as_u32(&self) -> u32 {
6844        self.value
6845    }
6846
6847    /// Crate-internal constructor. Reachable only from grounding-time minting.
6848    #[inline]
6849    #[must_use]
6850    #[allow(dead_code)]
6851    pub(crate) const fn new(value: u32) -> Self {
6852        Self {
6853            value,
6854            _level: PhantomData,
6855            _sealed: (),
6856        }
6857    }
6858}
6859
6860/// Phase A.4: sealed carrier for `observable:d_delta_metric` (metric incompatibility).
6861#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6862pub struct DDeltaMetric {
6863    value: i64,
6864    _sealed: (),
6865}
6866
6867impl DDeltaMetric {
6868    /// Returns the signed incompatibility magnitude (ring distance minus Hamming distance).
6869    #[inline]
6870    #[must_use]
6871    pub const fn as_i64(&self) -> i64 {
6872        self.value
6873    }
6874
6875    /// Crate-internal constructor.
6876    #[inline]
6877    #[must_use]
6878    #[allow(dead_code)]
6879    pub(crate) const fn new(value: i64) -> Self {
6880        Self { value, _sealed: () }
6881    }
6882}
6883
6884/// Phase A.4: sealed carrier for `observable:euler_metric` (Euler characteristic).
6885#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6886pub struct EulerMetric {
6887    value: i64,
6888    _sealed: (),
6889}
6890
6891impl EulerMetric {
6892    /// Returns the Euler characteristic χ of the constraint nerve.
6893    #[inline]
6894    #[must_use]
6895    pub const fn as_i64(&self) -> i64 {
6896        self.value
6897    }
6898
6899    /// Crate-internal constructor.
6900    #[inline]
6901    #[must_use]
6902    #[allow(dead_code)]
6903    pub(crate) const fn new(value: i64) -> Self {
6904        Self { value, _sealed: () }
6905    }
6906}
6907
6908/// Phase A.4: sealed carrier for `observable:residual_metric` (free-site count r).
6909#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6910pub struct ResidualMetric {
6911    value: u32,
6912    _sealed: (),
6913}
6914
6915impl ResidualMetric {
6916    /// Returns the free-site count r at grounding time.
6917    #[inline]
6918    #[must_use]
6919    pub const fn as_u32(&self) -> u32 {
6920        self.value
6921    }
6922
6923    /// Crate-internal constructor.
6924    #[inline]
6925    #[must_use]
6926    #[allow(dead_code)]
6927    pub(crate) const fn new(value: u32) -> Self {
6928        Self { value, _sealed: () }
6929    }
6930}
6931
6932/// Phase A.4: sealed carrier for `observable:betti_metric` (Betti-number vector).
6933/// Fixed-capacity `[u32; MAX_BETTI_DIMENSION]` backing; no heap.
6934#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6935pub struct BettiMetric {
6936    values: [u32; MAX_BETTI_DIMENSION],
6937    _sealed: (),
6938}
6939
6940impl BettiMetric {
6941    /// Returns the Betti-number vector as a fixed-size array reference.
6942    #[inline]
6943    #[must_use]
6944    pub const fn as_array(&self) -> &[u32; MAX_BETTI_DIMENSION] {
6945        &self.values
6946    }
6947
6948    /// Returns the individual Betti number βₖ for dimension k.
6949    /// Returns 0 when k >= MAX_BETTI_DIMENSION.
6950    #[inline]
6951    #[must_use]
6952    pub const fn beta(&self, k: usize) -> u32 {
6953        if k < MAX_BETTI_DIMENSION {
6954            self.values[k]
6955        } else {
6956            0
6957        }
6958    }
6959
6960    /// Crate-internal constructor.
6961    #[inline]
6962    #[must_use]
6963    #[allow(dead_code)]
6964    pub(crate) const fn new(values: [u32; MAX_BETTI_DIMENSION]) -> Self {
6965        Self {
6966            values,
6967            _sealed: (),
6968        }
6969    }
6970}
6971
6972/// Maximum site count of the Jacobian row per Datum at any supported
6973/// WittLevel. Sourced from the partition:FreeRank capacity bound.
6974/// v0.2.2 T2.6 (cleanup): reduced from 64 to 8 to keep `Grounded` under
6975/// the 256-byte size budget enforced by `phantom_tag::grounded_sealed_field_count_unchanged`.
6976/// 8 matches `MAX_BETTI_DIMENSION` and is sufficient for the v0.2.2 partition rank set.
6977/// Wiki ADR-037: alias of [`crate::HostBounds::JACOBIAN_SITES_MAX`] via
6978/// [`crate::DefaultHostBounds`].
6979pub const JACOBIAN_MAX_SITES: usize =
6980    <crate::DefaultHostBounds as crate::HostBounds>::JACOBIAN_SITES_MAX;
6981
6982/// v0.2.2 Phase E: sealed Jacobian row carrier, parametric over the
6983/// WittLevel marker. Fixed-size `[i64; JACOBIAN_MAX_SITES]` backing; no
6984/// heap. The row records the per-site partial derivative of the ring
6985/// operation that produced the Datum. Backs observable:JacobianObservable.
6986#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6987pub struct JacobianMetric<L> {
6988    entries: [i64; JACOBIAN_MAX_SITES],
6989    len: u16,
6990    _level: PhantomData<L>,
6991    _sealed: (),
6992}
6993
6994impl<L> JacobianMetric<L> {
6995    /// Construct a zeroed Jacobian row with the given active length.
6996    #[inline]
6997    #[must_use]
6998    #[allow(dead_code)]
6999    pub(crate) const fn zero(len: u16) -> Self {
7000        Self {
7001            entries: [0i64; JACOBIAN_MAX_SITES],
7002            len,
7003            _level: PhantomData,
7004            _sealed: (),
7005        }
7006    }
7007
7008    /// v0.2.2 T2.6 (cleanup): crate-internal constructor used by the
7009    /// BaseMetric accessor on `Grounded` to return a `JacobianMetric`
7010    /// backed by stored field values.
7011    #[inline]
7012    #[must_use]
7013    #[allow(dead_code)]
7014    pub(crate) const fn from_entries(entries: [i64; JACOBIAN_MAX_SITES], len: u16) -> Self {
7015        Self {
7016            entries,
7017            len,
7018            _level: PhantomData,
7019            _sealed: (),
7020        }
7021    }
7022
7023    /// Access the Jacobian row entries.
7024    #[inline]
7025    #[must_use]
7026    pub const fn entries(&self) -> &[i64; JACOBIAN_MAX_SITES] {
7027        &self.entries
7028    }
7029
7030    /// Number of active sites (the row's logical length).
7031    #[inline]
7032    #[must_use]
7033    pub const fn len(&self) -> u16 {
7034        self.len
7035    }
7036
7037    /// Whether the Jacobian row is empty.
7038    #[inline]
7039    #[must_use]
7040    pub const fn is_empty(&self) -> bool {
7041        self.len == 0
7042    }
7043}
7044
7045/// v0.2.2 Phase E: sealed Partition component classification.
7046/// Closed enumeration mirroring the partition:PartitionComponent
7047/// ontology class.
7048#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7049#[non_exhaustive]
7050pub enum PartitionComponent {
7051    /// The irreducible component.
7052    Irreducible,
7053    /// The reducible component.
7054    Reducible,
7055    /// The unit component.
7056    Units,
7057    /// The exterior component.
7058    Exterior,
7059}
7060
7061/// Sealed marker trait identifying type:ConstrainedType subclasses that may
7062/// appear as the parameter of `Grounded<T>`.
7063/// Per wiki ADR-027, the seal is the same `__sdk_seal::Sealed` supertrait
7064/// foundation uses for `FoundationClosed`, `PrismModel`, and
7065/// `IntoBindingValue`: only foundation and the SDK shape macros emit
7066/// impls. The foundation-sanctioned identity output `ConstrainedTypeInput`
7067/// retains its direct impl; application authors declaring custom Output
7068/// shapes invoke the `output_shape!` SDK macro, which emits
7069/// `__sdk_seal::Sealed`, `GroundedShape`, `IntoBindingValue`, and
7070/// `ConstrainedTypeShape` together.
7071pub trait GroundedShape: crate::pipeline::__sdk_seal::Sealed {}
7072impl GroundedShape for ConstrainedTypeInput {}
7073
7074/// v0.2.2 T4.2: sealed content-addressed handle.
7075/// Wraps a 128-bit identity used for `BindingsTable` lookups and as a
7076/// compact identity handle for `Grounded` values. The underlying `u128`
7077/// is visible via `as_u128()` for interop. Distinct from
7078/// `ContentFingerprint` (the parametric-width fingerprint computed by
7079/// the substrate `Hasher` — see T5.C3.d below): `ContentAddress` is a
7080/// fixed 16-byte sortable handle, while `ContentFingerprint` is the full
7081/// substrate-computed identity that round-trips through `verify_trace`.
7082#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7083pub struct ContentAddress {
7084    raw: u128,
7085    _sealed: (),
7086}
7087
7088impl ContentAddress {
7089    /// The zero content address. Used as the "unset" placeholder in
7090    /// `BindingsTable` lookups, the default state of an uninitialised
7091    /// `Grounded::unit_address`, and the initial seed of replay folds.
7092    #[inline]
7093    #[must_use]
7094    pub const fn zero() -> Self {
7095        Self {
7096            raw: 0,
7097            _sealed: (),
7098        }
7099    }
7100
7101    /// Returns the underlying 128-bit content hash.
7102    #[inline]
7103    #[must_use]
7104    pub const fn as_u128(&self) -> u128 {
7105        self.raw
7106    }
7107
7108    /// Whether this content address is the zero handle.
7109    #[inline]
7110    #[must_use]
7111    pub const fn is_zero(&self) -> bool {
7112        self.raw == 0
7113    }
7114
7115    /// v0.2.2 T5.C1: public ctor. Promoted from `pub(crate)` in T5 so
7116    /// downstream tests can construct deterministic `ContentAddress` values
7117    /// for fixture data without going through the foundation pipeline.
7118    #[inline]
7119    #[must_use]
7120    pub const fn from_u128(raw: u128) -> Self {
7121        Self { raw, _sealed: () }
7122    }
7123
7124    /// v0.2.2 Phase P.3: construct a `ContentAddress` from a `u64` FNV-1a fingerprint
7125    /// by right-padding the value into the 128-bit address space. Used by
7126    /// `Binding::to_binding_entry` to bridge the `Binding.content_address: u64`
7127    /// carrier to the `BindingEntry.address: ContentAddress` (`u128`-backed) shape.
7128    /// The lift is `raw = (fingerprint as u128) << 64` — upper 64 bits carry the
7129    /// FNV-1a value; lower 64 bits are zero. Content-deterministic; round-trips via
7130    /// `ContentAddress::as_u128() >> 64` back to the original `u64`.
7131    #[inline]
7132    #[must_use]
7133    pub const fn from_u64_fingerprint(fingerprint: u64) -> Self {
7134        Self {
7135            raw: (fingerprint as u128) << 64,
7136            _sealed: (),
7137        }
7138    }
7139}
7140
7141impl Default for ContentAddress {
7142    #[inline]
7143    fn default() -> Self {
7144        Self::zero()
7145    }
7146}
7147
7148/// Trace wire-format identifier. Per the wiki's ADR-018, wire-format
7149/// identifiers are explicitly carved out of the `HostBounds` rule because
7150/// cross-implementation interop requires a single shared format identifier.
7151/// Increment when the layout changes (event ordering, trailing fields,
7152/// primitive-op discriminant table, certificate-kind discriminant table).
7153/// Pinned by the `rust/trace_byte_layout_pinned` conformance validator.
7154pub const TRACE_REPLAY_FORMAT_VERSION: u16 = 10;
7155
7156/// v0.2.2 T5: pluggable content hasher with parametric output width.
7157/// The foundation does not ship an implementation. Downstream substrate
7158/// consumers (PRISM, application crates) supply their own `Hasher` impl
7159/// — BLAKE3, SHA-256, SHA-512, BLAKE2b, SipHash 2-4, FNV-1a, or any
7160/// other byte-stream hash whose output width satisfies the foundation's
7161/// derived collision-bound minimum.
7162/// # Foundation recommendation
7163/// The foundation **recommends BLAKE3** as the default substrate hash for
7164/// production deployments. BLAKE3 is fast, well-audited, has no known
7165/// cryptographic weaknesses, supports parallel and SIMD-accelerated
7166/// implementations, and has a flexible output length. PRISM ships a BLAKE3
7167/// `Hasher` impl as its production substrate; application crates should
7168/// use it unless they have a specific reason to deviate.
7169/// The recommendation is non-binding: any conforming `Hasher` impl works
7170/// with the foundation's pipeline and verify path. The foundation never
7171/// invokes a hash function itself, so the choice is fully a downstream
7172/// decision.
7173/// # Architecture
7174/// The architectural shape mirrors `Calibration`: the foundation defines
7175/// the abstract quantity (`ContentFingerprint`) and the substitution point
7176/// (`Hasher`); downstream provides the concrete substrate AND chooses the
7177/// output width within the foundation's correctness budget.
7178/// # Required laws
7179/// 1. **Width-in-budget**: `OUTPUT_BYTES` must be in
7180///    `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]` where `FP_MAX`
7181///    is the const-generic carrying `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
7182///    Enforced at codegen time via a `const _: () = assert!(...)` block
7183///    emitted inside every `pipeline::run::<T, _, H>` body.
7184/// 2. **Determinism**: identical byte sequences produce bit-identical outputs
7185///    across program runs, builds, target architectures, and rustc versions.
7186/// 3. **Sensitivity**: hashing two byte sequences that differ in any byte
7187///    produces two distinct outputs with probability bounded by the hasher's
7188///    documented collision rate.
7189/// 4. **No interior mutability**: `fold_byte` consumes `self` and returns a
7190///    new state. Impls that depend on hidden mutable state violate the contract.
7191/// # Example
7192/// ```
7193/// use uor_foundation::enforcement::Hasher;
7194/// /// Minimal 128-bit (16-byte) FNV-1a substrate — two 64-bit lanes.
7195/// #[derive(Clone, Copy)]
7196/// pub struct Fnv1a16 { a: u64, b: u64 }
7197/// impl Hasher for Fnv1a16 {
7198///     const OUTPUT_BYTES: usize = 16;
7199///     fn initial() -> Self {
7200///         Self { a: 0xcbf29ce484222325, b: 0x84222325cbf29ce4 }
7201///     }
7202///     fn fold_byte(mut self, x: u8) -> Self {
7203///         self.a ^= x as u64;
7204///         self.a = self.a.wrapping_mul(0x100000001b3);
7205///         self.b ^= (x as u64).rotate_left(8);
7206///         self.b = self.b.wrapping_mul(0x100000001b3);
7207///         self
7208///     }
7209///     fn finalize(self) -> [u8; 32] {
7210///         let mut buf = [0u8; 32];
7211///         buf[..8].copy_from_slice(&self.a.to_be_bytes());
7212///         buf[8..16].copy_from_slice(&self.b.to_be_bytes());
7213///         buf
7214///     }
7215/// }
7216/// ```
7217/// Above, `Hasher` is reached through its default const-generic
7218/// `<FP_MAX = 32>`, which is the `DefaultHostBounds::FINGERPRINT_MAX_BYTES`
7219/// value. Applications that select a different `HostBounds` impl write
7220/// `impl Hasher<{<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES}> for MyHasher`.
7221pub trait Hasher<const FP_MAX: usize = 32> {
7222    /// Active output width in bytes. Must lie within the bounds
7223    /// the application's selected `HostBounds` declares —
7224    /// `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]`.
7225    const OUTPUT_BYTES: usize;
7226
7227    /// Initial hasher state.
7228    fn initial() -> Self;
7229
7230    /// Fold a single byte into the running state.
7231    #[must_use]
7232    fn fold_byte(self, b: u8) -> Self;
7233
7234    /// Fold a slice of bytes (default impl: byte-by-byte).
7235    #[inline]
7236    #[must_use]
7237    fn fold_bytes(mut self, bytes: &[u8]) -> Self
7238    where
7239        Self: Sized,
7240    {
7241        let mut i = 0;
7242        while i < bytes.len() {
7243            self = self.fold_byte(bytes[i]);
7244            i += 1;
7245        }
7246        self
7247    }
7248
7249    /// Finalize into the canonical max-width buffer of `FP_MAX` bytes.
7250    /// Bytes `0..OUTPUT_BYTES` carry the hash result; bytes
7251    /// `OUTPUT_BYTES..FP_MAX` MUST be zero.
7252    fn finalize(self) -> [u8; FP_MAX];
7253}
7254
7255/// ADR-030 adapter: wrap any [`Hasher`] impl as an
7256/// [`crate::pipeline::AxisExtension`]. The lone supported kernel id
7257/// is [`HashAxis::KERNEL_HASH`] = 0, which folds the input bytes
7258/// through the wrapped Hasher and writes the first `OUTPUT_BYTES`
7259/// digest bytes to the caller-provided buffer.
7260#[derive(Debug, Clone, Copy)]
7261pub struct HashAxis<H: Hasher>(core::marker::PhantomData<H>);
7262
7263impl<H: Hasher> HashAxis<H> {
7264    /// Canonical kernel id for the hash operation. The closure-body
7265    /// grammar G19 form `hash(input)` lowers to
7266    /// `Term::AxisInvocation { axis_index: 0, kernel_id: HashAxis::KERNEL_HASH, input_index }`.
7267    pub const KERNEL_HASH: u32 = 0;
7268}
7269
7270impl<H: Hasher> crate::pipeline::__sdk_seal::Sealed for HashAxis<H> {}
7271impl<H: Hasher> crate::pipeline::SubstrateTermBody for HashAxis<H> {
7272    fn body_arena() -> &'static [Term] {
7273        &[]
7274    }
7275}
7276impl<H: Hasher> crate::pipeline::AxisExtension for HashAxis<H> {
7277    const AXIS_ADDRESS: &'static str = "https://uor.foundation/axis/HashAxis";
7278    const MAX_OUTPUT_BYTES: usize = <H as Hasher>::OUTPUT_BYTES;
7279    fn dispatch_kernel(
7280        kernel_id: u32,
7281        input: &[u8],
7282        out: &mut [u8],
7283    ) -> Result<usize, ShapeViolation> {
7284        if kernel_id != Self::KERNEL_HASH {
7285            return Err(ShapeViolation {
7286                shape_iri: "https://uor.foundation/axis/HashAxis",
7287                constraint_iri: "https://uor.foundation/axis/HashAxis/kernelId",
7288                property_iri: "https://uor.foundation/axis/kernelId",
7289                expected_range: "https://uor.foundation/axis/HashAxis/KERNEL_HASH",
7290                min_count: 0,
7291                max_count: 1,
7292                kind: crate::ViolationKind::ValueCheck,
7293            });
7294        }
7295        let mut hasher = <H as Hasher>::initial();
7296        hasher = hasher.fold_bytes(input);
7297        let digest = hasher.finalize();
7298        let n = <H as Hasher>::OUTPUT_BYTES.min(out.len()).min(digest.len());
7299        let mut i = 0;
7300        while i < n {
7301            out[i] = digest[i];
7302            i += 1;
7303        }
7304        Ok(n)
7305    }
7306}
7307
7308/// Sealed parametric content fingerprint.
7309/// Wraps a fixed-capacity byte buffer of `FP_MAX` bytes plus the
7310/// active width in bytes. `FP_MAX` is the const-generic that carries
7311/// the application's selected `HostBounds::FINGERPRINT_MAX_BYTES`
7312/// (default = 32, matching `DefaultHostBounds`). The active width
7313/// is set by the producing `Hasher::OUTPUT_BYTES` and recorded so
7314/// downstream can distinguish "this is a 128-bit fingerprint" from
7315/// "this is a 256-bit fingerprint" without inspecting trailing zeros.
7316/// Equality is bit-equality on the full buffer + width tag, so two
7317/// fingerprints from different hashers (different widths) are never
7318/// equal even if their leading bytes happen to coincide. This prevents
7319/// silent collisions when downstream consumers mix substrate hashers.
7320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7321pub struct ContentFingerprint<const FP_MAX: usize = 32> {
7322    bytes: [u8; FP_MAX],
7323    width_bytes: u8,
7324    _sealed: (),
7325}
7326
7327impl<const FP_MAX: usize> ContentFingerprint<FP_MAX> {
7328    /// Crate-internal zero placeholder. Used internally as the
7329    /// `Trace::empty()` field initializer and the `Default` impl. Not
7330    /// publicly constructible; downstream that needs a `ContentFingerprint`
7331    /// constructs one via `Hasher::finalize()` followed by `from_buffer()`.
7332    #[inline]
7333    #[must_use]
7334    #[allow(dead_code)]
7335    pub(crate) const fn zero() -> Self {
7336        Self {
7337            bytes: [0u8; FP_MAX],
7338            width_bytes: 0,
7339            _sealed: (),
7340        }
7341    }
7342
7343    /// Whether this fingerprint is the all-zero placeholder.
7344    #[inline]
7345    #[must_use]
7346    pub const fn is_zero(&self) -> bool {
7347        self.width_bytes == 0
7348    }
7349
7350    /// Active width in bytes (set by the producing hasher).
7351    #[inline]
7352    #[must_use]
7353    pub const fn width_bytes(&self) -> u8 {
7354        self.width_bytes
7355    }
7356
7357    /// Active width in bits (`width_bytes * 8`).
7358    #[inline]
7359    #[must_use]
7360    pub const fn width_bits(&self) -> u16 {
7361        (self.width_bytes as u16) * 8
7362    }
7363
7364    /// The full buffer. Bytes `0..width_bytes` are the hash; bytes
7365    /// `width_bytes..FP_MAX` are zero.
7366    #[inline]
7367    #[must_use]
7368    pub const fn as_bytes(&self) -> &[u8; FP_MAX] {
7369        &self.bytes
7370    }
7371
7372    /// Construct a fingerprint from a hasher's finalize buffer + width tag.
7373    /// Production paths reach this via `pipeline::run::<T, _, H>`; test
7374    /// paths via the `__test_helpers` back-door.
7375    #[inline]
7376    #[must_use]
7377    pub const fn from_buffer(bytes: [u8; FP_MAX], width_bytes: u8) -> Self {
7378        Self {
7379            bytes,
7380            width_bytes,
7381            _sealed: (),
7382        }
7383    }
7384}
7385
7386impl<const FP_MAX: usize> Default for ContentFingerprint<FP_MAX> {
7387    #[inline]
7388    fn default() -> Self {
7389        Self::zero()
7390    }
7391}
7392
7393/// v0.2.2 T5: stable u8 discriminant for `PrimitiveOp`. Locked to the
7394/// codegen output order; do not reorder `PrimitiveOp` variants without
7395/// bumping `TRACE_REPLAY_FORMAT_VERSION`. Folded into the canonical byte
7396/// layout of every `TraceEvent` so substrate hashers produce stable
7397/// fingerprints across builds.
7398#[inline]
7399#[must_use]
7400pub const fn primitive_op_discriminant(op: crate::PrimitiveOp) -> u8 {
7401    match op {
7402        crate::PrimitiveOp::Neg => 0,
7403        crate::PrimitiveOp::Bnot => 1,
7404        crate::PrimitiveOp::Succ => 2,
7405        crate::PrimitiveOp::Pred => 3,
7406        crate::PrimitiveOp::Add => 4,
7407        crate::PrimitiveOp::Sub => 5,
7408        crate::PrimitiveOp::Mul => 6,
7409        crate::PrimitiveOp::Xor => 7,
7410        crate::PrimitiveOp::And => 8,
7411        crate::PrimitiveOp::Or => 9,
7412        // ADR-013/TR-08 substrate amendment: byte-level ops 10..15.
7413        crate::PrimitiveOp::Le => 10,
7414        crate::PrimitiveOp::Lt => 11,
7415        crate::PrimitiveOp::Ge => 12,
7416        crate::PrimitiveOp::Gt => 13,
7417        crate::PrimitiveOp::Concat => 14,
7418        // ADR-053 substrate amendment: ring-axis arithmetic completion.
7419        crate::PrimitiveOp::Div => 15,
7420        crate::PrimitiveOp::Mod => 16,
7421        crate::PrimitiveOp::Pow => 17,
7422    }
7423}
7424
7425/// v0.2.2 T5: stable u8 discriminant tag distinguishing the certificate
7426/// kinds the foundation pipeline mints. Folded into the trailing byte of
7427/// every canonical digest so two certificates over the same source unit
7428/// but of different kinds produce distinct fingerprints. Locked at v0.2.2;
7429/// reordering or inserting variants requires bumping
7430/// `TRACE_REPLAY_FORMAT_VERSION`.
7431#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7432#[non_exhaustive]
7433pub enum CertificateKind {
7434    /// Cert minted by `pipeline::run` and `run_const` (retained for
7435    /// `run_grounding_aware`).
7436    Grounding,
7437    /// Cert minted by `certify_tower_completeness_const`.
7438    TowerCompleteness,
7439    /// Cert minted by `certify_incremental_completeness_const`.
7440    IncrementalCompleteness,
7441    /// Cert minted by `certify_inhabitance_const` / `run_inhabitance`.
7442    Inhabitance,
7443    /// Cert minted by `certify_multiplication_const`.
7444    Multiplication,
7445    /// Cert minted by `resolver::two_sat_decider::certify`.
7446    TwoSat,
7447    /// Cert minted by `resolver::horn_sat_decider::certify`.
7448    HornSat,
7449    /// Cert minted by `resolver::residual_verdict::certify`.
7450    ResidualVerdict,
7451    /// Cert minted by `resolver::canonical_form::certify`.
7452    CanonicalForm,
7453    /// Cert minted by `resolver::type_synthesis::certify`.
7454    TypeSynthesis,
7455    /// Cert minted by `resolver::homotopy::certify`.
7456    Homotopy,
7457    /// Cert minted by `resolver::monodromy::certify`.
7458    Monodromy,
7459    /// Cert minted by `resolver::moduli::certify`.
7460    Moduli,
7461    /// Cert minted by `resolver::jacobian_guided::certify`.
7462    JacobianGuided,
7463    /// Cert minted by `resolver::evaluation::certify`.
7464    Evaluation,
7465    /// Cert minted by `resolver::session::certify`.
7466    Session,
7467    /// Cert minted by `resolver::superposition::certify`.
7468    Superposition,
7469    /// Cert minted by `resolver::measurement::certify`.
7470    Measurement,
7471    /// Cert minted by `resolver::witt_level_resolver::certify`.
7472    WittLevel,
7473    /// Cert minted by `resolver::dihedral_factorization::certify`.
7474    DihedralFactorization,
7475    /// Cert minted by `resolver::completeness::certify`.
7476    Completeness,
7477    /// Cert minted by `resolver::geodesic_validator::certify`.
7478    GeodesicValidator,
7479}
7480
7481/// v0.2.2 T5: stable u8 discriminant for `CertificateKind`. Folded into
7482/// the trailing byte of canonical digests via the `*Digest` types so two
7483/// distinct certificate kinds over the same source unit produce distinct
7484/// fingerprints. Locked at v0.2.2.
7485#[inline]
7486#[must_use]
7487pub const fn certificate_kind_discriminant(kind: CertificateKind) -> u8 {
7488    match kind {
7489        CertificateKind::Grounding => 1,
7490        CertificateKind::TowerCompleteness => 2,
7491        CertificateKind::IncrementalCompleteness => 3,
7492        CertificateKind::Inhabitance => 4,
7493        CertificateKind::Multiplication => 5,
7494        CertificateKind::TwoSat => 6,
7495        CertificateKind::HornSat => 7,
7496        CertificateKind::ResidualVerdict => 8,
7497        CertificateKind::CanonicalForm => 9,
7498        CertificateKind::TypeSynthesis => 10,
7499        CertificateKind::Homotopy => 11,
7500        CertificateKind::Monodromy => 12,
7501        CertificateKind::Moduli => 13,
7502        CertificateKind::JacobianGuided => 14,
7503        CertificateKind::Evaluation => 15,
7504        CertificateKind::Session => 16,
7505        CertificateKind::Superposition => 17,
7506        CertificateKind::Measurement => 18,
7507        CertificateKind::WittLevel => 19,
7508        CertificateKind::DihedralFactorization => 20,
7509        CertificateKind::Completeness => 21,
7510        CertificateKind::GeodesicValidator => 22,
7511    }
7512}
7513
7514/// v0.2.2 T5: fold a `ConstraintRef` into a `Hasher` via the canonical
7515/// byte layout. Each variant emits a discriminant byte (1..=9) followed by
7516/// its payload bytes in big-endian order. Locked at v0.2.2; reordering
7517/// variants requires bumping `TRACE_REPLAY_FORMAT_VERSION`.
7518/// Used by `pipeline::run`, `run_const`, and the four `certify_*` entry
7519/// points to fold a unit's constraint set into the substrate fingerprint.
7520pub fn fold_constraint_ref<H: Hasher>(mut hasher: H, c: &crate::pipeline::ConstraintRef) -> H {
7521    use crate::pipeline::ConstraintRef as C;
7522    match c {
7523        C::Residue { modulus, residue } => {
7524            hasher = hasher.fold_byte(1);
7525            hasher = hasher.fold_bytes(&modulus.to_be_bytes());
7526            hasher = hasher.fold_bytes(&residue.to_be_bytes());
7527        }
7528        C::Hamming { bound } => {
7529            hasher = hasher.fold_byte(2);
7530            hasher = hasher.fold_bytes(&bound.to_be_bytes());
7531        }
7532        C::Depth { min, max } => {
7533            hasher = hasher.fold_byte(3);
7534            hasher = hasher.fold_bytes(&min.to_be_bytes());
7535            hasher = hasher.fold_bytes(&max.to_be_bytes());
7536        }
7537        C::Carry { site } => {
7538            hasher = hasher.fold_byte(4);
7539            hasher = hasher.fold_bytes(&site.to_be_bytes());
7540        }
7541        C::Site { position } => {
7542            hasher = hasher.fold_byte(5);
7543            hasher = hasher.fold_bytes(&position.to_be_bytes());
7544        }
7545        C::Affine {
7546            coefficients,
7547            coefficient_count,
7548            bias,
7549        } => {
7550            hasher = hasher.fold_byte(6);
7551            hasher = hasher.fold_bytes(&coefficient_count.to_be_bytes());
7552            let count = *coefficient_count as usize;
7553            let mut i = 0;
7554            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
7555                hasher = hasher.fold_bytes(&coefficients[i].to_be_bytes());
7556                i += 1;
7557            }
7558            hasher = hasher.fold_bytes(&bias.to_be_bytes());
7559        }
7560        C::SatClauses { clauses, num_vars } => {
7561            hasher = hasher.fold_byte(7);
7562            hasher = hasher.fold_bytes(&num_vars.to_be_bytes());
7563            hasher = hasher.fold_bytes(&(clauses.len() as u32).to_be_bytes());
7564            let mut i = 0;
7565            while i < clauses.len() {
7566                let clause = clauses[i];
7567                hasher = hasher.fold_bytes(&(clause.len() as u32).to_be_bytes());
7568                let mut j = 0;
7569                while j < clause.len() {
7570                    let (var, neg) = clause[j];
7571                    hasher = hasher.fold_bytes(&var.to_be_bytes());
7572                    hasher = hasher.fold_byte(if neg { 1 } else { 0 });
7573                    j += 1;
7574                }
7575                i += 1;
7576            }
7577        }
7578        C::Bound {
7579            observable_iri,
7580            bound_shape_iri,
7581            args_repr,
7582        } => {
7583            hasher = hasher.fold_byte(8);
7584            hasher = hasher.fold_bytes(observable_iri.as_bytes());
7585            hasher = hasher.fold_byte(0);
7586            hasher = hasher.fold_bytes(bound_shape_iri.as_bytes());
7587            hasher = hasher.fold_byte(0);
7588            hasher = hasher.fold_bytes(args_repr.as_bytes());
7589            hasher = hasher.fold_byte(0);
7590        }
7591        C::Conjunction {
7592            conjuncts,
7593            conjunct_count,
7594        } => {
7595            hasher = hasher.fold_byte(9);
7596            hasher = hasher.fold_bytes(&conjunct_count.to_be_bytes());
7597            let count = *conjunct_count as usize;
7598            let mut i = 0;
7599            while i < count && i < crate::pipeline::CONJUNCTION_MAX_TERMS {
7600                let lifted = conjuncts[i].into_constraint();
7601                hasher = fold_constraint_ref(hasher, &lifted);
7602                i += 1;
7603            }
7604        }
7605        // ADR-057 wire-format: discriminant byte 10 + content-addressed
7606        // shape_iri + descent_bound. The discriminant table extension
7607        // requires TRACE_REPLAY_FORMAT_VERSION bump per ADR-013/TR-08.
7608        C::Recurse {
7609            shape_iri,
7610            descent_bound,
7611        } => {
7612            hasher = hasher.fold_byte(10);
7613            hasher = hasher.fold_bytes(shape_iri.as_bytes());
7614            hasher = hasher.fold_byte(0);
7615            hasher = hasher.fold_bytes(&descent_bound.to_be_bytes());
7616        }
7617    }
7618    hasher
7619}
7620
7621/// v0.2.2 T5: fold the canonical CompileUnit byte layout into a `Hasher`.
7622/// Layout: `level_bits (2 BE) || budget (8 BE) || iri bytes || 0x00 ||
7623/// site_count (8 BE) || for each constraint: fold_constraint_ref ||
7624/// certificate_kind_discriminant (1 byte trailing)`.
7625/// Locked at v0.2.2 by the `rust/trace_byte_layout_pinned` conformance
7626/// validator. Used by `pipeline::run`, `run_const`, and the four
7627/// `certify_*` entry points.
7628pub fn fold_unit_digest<H: Hasher>(
7629    mut hasher: H,
7630    level_bits: u16,
7631    budget: u64,
7632    iri: &str,
7633    site_count: usize,
7634    constraints: &[crate::pipeline::ConstraintRef],
7635    kind: CertificateKind,
7636) -> H {
7637    hasher = hasher.fold_bytes(&level_bits.to_be_bytes());
7638    hasher = hasher.fold_bytes(&budget.to_be_bytes());
7639    hasher = hasher.fold_bytes(iri.as_bytes());
7640    hasher = hasher.fold_byte(0);
7641    hasher = hasher.fold_bytes(&(site_count as u64).to_be_bytes());
7642    let mut i = 0;
7643    while i < constraints.len() {
7644        hasher = fold_constraint_ref(hasher, &constraints[i]);
7645        i += 1;
7646    }
7647    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7648    hasher
7649}
7650
7651/// v0.2.2 T5: fold the canonical ParallelDeclaration byte layout into a `Hasher`.
7652/// Layout: `site_count (8 BE) || iri bytes || 0x00 || decl_site_count (8 BE) ||
7653/// for each constraint: fold_constraint_ref || certificate_kind_discriminant`.
7654pub fn fold_parallel_digest<H: Hasher>(
7655    mut hasher: H,
7656    decl_site_count: u64,
7657    iri: &str,
7658    type_site_count: usize,
7659    constraints: &[crate::pipeline::ConstraintRef],
7660    kind: CertificateKind,
7661) -> H {
7662    hasher = hasher.fold_bytes(&decl_site_count.to_be_bytes());
7663    hasher = hasher.fold_bytes(iri.as_bytes());
7664    hasher = hasher.fold_byte(0);
7665    hasher = hasher.fold_bytes(&(type_site_count as u64).to_be_bytes());
7666    let mut i = 0;
7667    while i < constraints.len() {
7668        hasher = fold_constraint_ref(hasher, &constraints[i]);
7669        i += 1;
7670    }
7671    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7672    hasher
7673}
7674
7675/// v0.2.2 T5: fold the canonical StreamDeclaration byte layout into a `Hasher`.
7676pub fn fold_stream_digest<H: Hasher>(
7677    mut hasher: H,
7678    productivity_bound: u64,
7679    iri: &str,
7680    constraints: &[crate::pipeline::ConstraintRef],
7681    kind: CertificateKind,
7682) -> H {
7683    hasher = hasher.fold_bytes(&productivity_bound.to_be_bytes());
7684    hasher = hasher.fold_bytes(iri.as_bytes());
7685    hasher = hasher.fold_byte(0);
7686    let mut i = 0;
7687    while i < constraints.len() {
7688        hasher = fold_constraint_ref(hasher, &constraints[i]);
7689        i += 1;
7690    }
7691    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7692    hasher
7693}
7694
7695/// v0.2.2 T5: fold the canonical InteractionDeclaration byte layout into a `Hasher`.
7696pub fn fold_interaction_digest<H: Hasher>(
7697    mut hasher: H,
7698    convergence_seed: u64,
7699    iri: &str,
7700    constraints: &[crate::pipeline::ConstraintRef],
7701    kind: CertificateKind,
7702) -> H {
7703    hasher = hasher.fold_bytes(&convergence_seed.to_be_bytes());
7704    hasher = hasher.fold_bytes(iri.as_bytes());
7705    hasher = hasher.fold_byte(0);
7706    let mut i = 0;
7707    while i < constraints.len() {
7708        hasher = fold_constraint_ref(hasher, &constraints[i]);
7709        i += 1;
7710    }
7711    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7712    hasher
7713}
7714
7715/// v0.2.2 Phase J primitive: `reduction:ReductionStep` / `recursion:BoundedRecursion`.
7716/// Content-deterministic reduction signature: `(witt_bits, constraint_count, satisfiable_bit)`.
7717pub(crate) fn primitive_terminal_reduction<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7718    witt_bits: u16,
7719) -> Result<(u16, u32, u8), PipelineFailure> {
7720    let outcome = crate::pipeline::run_reduction_stages::<T>(witt_bits)?;
7721    let satisfiable_bit: u8 = if outcome.satisfiable { 1 } else { 0 };
7722    Ok((
7723        outcome.witt_bits,
7724        T::CONSTRAINTS.len() as u32,
7725        satisfiable_bit,
7726    ))
7727}
7728
7729/// v0.2.2 Phase J: fold the TerminalReduction triple into the hasher.
7730pub(crate) fn fold_terminal_reduction<H: Hasher>(
7731    mut hasher: H,
7732    witt_bits: u16,
7733    constraint_count: u32,
7734    satisfiable_bit: u8,
7735) -> H {
7736    hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
7737    hasher = hasher.fold_bytes(&constraint_count.to_be_bytes());
7738    hasher = hasher.fold_byte(satisfiable_bit);
7739    hasher
7740}
7741
7742/// Phase X.4: `resolver:CechNerve` / `homology:ChainComplex`.
7743/// Computes the content-deterministic Betti tuple `[b_0, b_1, b_2, 0, .., 0]`
7744/// from the 2-complex constraint-nerve over `T::CONSTRAINTS`:
7745/// vertices = constraints, 1-simplices = pairs of constraints with intersecting
7746/// site support, 2-simplices = triples of constraints with a common site.
7747/// `b_k = dim ker(∂_k) - dim im(∂_{k+1})` for k ∈ {0,1,2}; `b_3..b_7 = 0`.
7748/// Ranks of the boundary operators ∂_1, ∂_2 are computed over ℤ/p (p prime,
7749/// `NERVE_RANK_MOD_P = 1_000_000_007`) by `integer_matrix_rank`. Nerve boundary
7750/// matrices have ±1/0 entries and are totally unimodular, so rank over ℤ/p
7751/// equals rank over ℚ equals rank over ℤ for any prime p not dividing a minor.
7752/// Phase 1a (orphan-closure): inputs larger than `NERVE_CONSTRAINTS_CAP = 8`
7753/// constraints or `NERVE_SITES_CAP = 8` sites return
7754/// `Err(GenericImpossibilityWitness::for_identity("NERVE_CAPACITY_EXCEEDED"))`
7755/// rather than silently truncating — truncation produced Betti numbers for a
7756/// differently-shaped complex than the caller asked about. Callers propagate
7757/// the witness via `?` (pattern mirrored on `primitive_terminal_reduction`).
7758/// # Errors
7759/// Returns `NERVE_CAPACITY_EXCEEDED` when either cap is exceeded.
7760pub fn primitive_simplicial_nerve_betti<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7761) -> Result<[u32; MAX_BETTI_DIMENSION], GenericImpossibilityWitness> {
7762    let k_all = T::CONSTRAINTS.len();
7763    if k_all > NERVE_CONSTRAINTS_CAP {
7764        return Err(GenericImpossibilityWitness::for_identity(
7765            "NERVE_CAPACITY_EXCEEDED",
7766        ));
7767    }
7768    let s_all = T::SITE_COUNT;
7769    if s_all > NERVE_SITES_CAP {
7770        return Err(GenericImpossibilityWitness::for_identity(
7771            "NERVE_CAPACITY_EXCEEDED",
7772        ));
7773    }
7774    let n_constraints = k_all;
7775    let n_sites = s_all;
7776    let mut out = [0u32; MAX_BETTI_DIMENSION];
7777    if n_constraints == 0 {
7778        out[0] = 1;
7779        return Ok(out);
7780    }
7781    // Compute site-support bitmask per constraint (bit `s` set iff constraint touches site `s`).
7782    let mut support = [0u16; NERVE_CONSTRAINTS_CAP];
7783    let mut c = 0;
7784    while c < n_constraints {
7785        support[c] = constraint_site_support_mask::<T>(c, n_sites);
7786        c += 1;
7787    }
7788    // Enumerate 1-simplices: pairs (i,j) with i<j and support[i] & support[j] != 0.
7789    // Index in c1_pairs_lo/hi corresponds to the column in ∂_1 / row in ∂_2.
7790    let mut c1_pairs_lo = [0u8; NERVE_C1_MAX];
7791    let mut c1_pairs_hi = [0u8; NERVE_C1_MAX];
7792    let mut n_c1: usize = 0;
7793    let mut i = 0;
7794    while i < n_constraints {
7795        let mut j = i + 1;
7796        while j < n_constraints {
7797            if (support[i] & support[j]) != 0 && n_c1 < NERVE_C1_MAX {
7798                c1_pairs_lo[n_c1] = i as u8;
7799                c1_pairs_hi[n_c1] = j as u8;
7800                n_c1 += 1;
7801            }
7802            j += 1;
7803        }
7804        i += 1;
7805    }
7806    // Enumerate 2-simplices: triples (i,j,k) with i<j<k and support[i] & support[j] & support[k] != 0.
7807    let mut c2_i = [0u8; NERVE_C2_MAX];
7808    let mut c2_j = [0u8; NERVE_C2_MAX];
7809    let mut c2_k = [0u8; NERVE_C2_MAX];
7810    let mut n_c2: usize = 0;
7811    let mut i2 = 0;
7812    while i2 < n_constraints {
7813        let mut j2 = i2 + 1;
7814        while j2 < n_constraints {
7815            let mut k2 = j2 + 1;
7816            while k2 < n_constraints {
7817                if (support[i2] & support[j2] & support[k2]) != 0 && n_c2 < NERVE_C2_MAX {
7818                    c2_i[n_c2] = i2 as u8;
7819                    c2_j[n_c2] = j2 as u8;
7820                    c2_k[n_c2] = k2 as u8;
7821                    n_c2 += 1;
7822                }
7823                k2 += 1;
7824            }
7825            j2 += 1;
7826        }
7827        i2 += 1;
7828    }
7829    // Build ∂_1: rows = n_constraints (vertices of the nerve), cols = n_c1.
7830    // Convention: ∂(c_i, c_j) = c_j - c_i for i < j.
7831    let mut partial_1 = [[0i64; NERVE_C1_MAX]; NERVE_CONSTRAINTS_CAP];
7832    let mut e = 0;
7833    while e < n_c1 {
7834        let lo = c1_pairs_lo[e] as usize;
7835        let hi = c1_pairs_hi[e] as usize;
7836        partial_1[lo][e] = NERVE_RANK_MOD_P - 1; // -1 mod p
7837        partial_1[hi][e] = 1;
7838        e += 1;
7839    }
7840    let rank_1 = integer_matrix_rank::<NERVE_CONSTRAINTS_CAP, NERVE_C1_MAX>(
7841        &mut partial_1,
7842        n_constraints,
7843        n_c1,
7844    );
7845    // Build ∂_2: rows = n_c1, cols = n_c2.
7846    // Convention: ∂(c_i, c_j, c_k) = (c_j, c_k) - (c_i, c_k) + (c_i, c_j).
7847    let mut partial_2 = [[0i64; NERVE_C2_MAX]; NERVE_C1_MAX];
7848    let mut t = 0;
7849    while t < n_c2 {
7850        let ti = c2_i[t];
7851        let tj = c2_j[t];
7852        let tk = c2_k[t];
7853        let idx_jk = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, tj, tk);
7854        let idx_ik = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tk);
7855        let idx_ij = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tj);
7856        if idx_jk < NERVE_C1_MAX {
7857            partial_2[idx_jk][t] = 1;
7858        }
7859        if idx_ik < NERVE_C1_MAX {
7860            partial_2[idx_ik][t] = NERVE_RANK_MOD_P - 1;
7861        }
7862        if idx_ij < NERVE_C1_MAX {
7863            partial_2[idx_ij][t] = 1;
7864        }
7865        t += 1;
7866    }
7867    let rank_2 = integer_matrix_rank::<NERVE_C1_MAX, NERVE_C2_MAX>(&mut partial_2, n_c1, n_c2);
7868    // b_0 = |C_0| - rank(∂_1). Always ≥ 1 because partial_1 has at least one all-zero row.
7869    let b0 = (n_constraints - rank_1) as u32;
7870    // b_1 = (|C_1| - rank(∂_1)) - rank(∂_2).
7871    let cycles_1 = n_c1.saturating_sub(rank_1);
7872    let b1 = cycles_1.saturating_sub(rank_2) as u32;
7873    // b_2 = |C_2| - rank(∂_2) (the complex is 2-dimensional; no ∂_3).
7874    let b2 = n_c2.saturating_sub(rank_2) as u32;
7875    out[0] = if b0 == 0 { 1 } else { b0 };
7876    if MAX_BETTI_DIMENSION > 1 {
7877        out[1] = b1;
7878    }
7879    if MAX_BETTI_DIMENSION > 2 {
7880        out[2] = b2;
7881    }
7882    Ok(out)
7883}
7884
7885/// Phase X.4: cap on the number of constraints considered by the nerve
7886/// primitive. Phase 1a (orphan-closure): inputs exceeding this cap are
7887/// rejected via `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
7888/// Wiki ADR-037: alias of [`crate::HostBounds::NERVE_CONSTRAINTS_MAX`] via
7889/// [`crate::DefaultHostBounds`].
7890pub const NERVE_CONSTRAINTS_CAP: usize =
7891    <crate::DefaultHostBounds as crate::HostBounds>::NERVE_CONSTRAINTS_MAX;
7892
7893/// Phase X.4: cap on site-support bitmask width (matches `u16` storage).
7894/// Phase 1a (orphan-closure): inputs exceeding this cap are rejected via
7895/// `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
7896/// Wiki ADR-037: alias of [`crate::HostBounds::NERVE_SITES_MAX`] via
7897/// [`crate::DefaultHostBounds`].
7898pub const NERVE_SITES_CAP: usize = <crate::DefaultHostBounds as crate::HostBounds>::NERVE_SITES_MAX;
7899
7900/// Phase X.4: maximum number of 1-simplices = C(NERVE_CONSTRAINTS_CAP, 2) = 28.
7901pub const NERVE_C1_MAX: usize = 28;
7902
7903/// Phase X.4: maximum number of 2-simplices = C(NERVE_CONSTRAINTS_CAP, 3) = 56.
7904pub const NERVE_C2_MAX: usize = 56;
7905
7906/// Phase X.4: prime modulus for nerve boundary-matrix rank computation.
7907/// Chosen so `(i64 * i64) mod p` never overflows (`p² < 2⁶³`). Nerve boundary
7908/// matrices have entries in {-1, 0, 1}; rank over ℤ/p equals rank over ℚ.
7909pub(crate) const NERVE_RANK_MOD_P: i64 = 1_000_000_007;
7910
7911/// Phase X.4: per-constraint site-support bitmask. Returns bit `s` set iff
7912/// constraint `c` in `T::CONSTRAINTS` touches site index `s` (`s < n_sites`).
7913/// `Affine { coefficients, .. }` returns the bitmask of sites whose
7914/// coefficient is non-zero — the natural "site support" of the affine
7915/// relation. Remaining non-site-local variants (Residue, Hamming, Depth,
7916/// Bound, Conjunction, SatClauses) return an all-ones mask over `n_sites`.
7917pub(crate) const fn constraint_site_support_mask<
7918    T: crate::pipeline::ConstrainedTypeShape + ?Sized,
7919>(
7920    c: usize,
7921    n_sites: usize,
7922) -> u16 {
7923    let all_mask: u16 = if n_sites == 0 {
7924        0
7925    } else {
7926        (1u16 << n_sites) - 1
7927    };
7928    match &T::CONSTRAINTS[c] {
7929        crate::pipeline::ConstraintRef::Site { position } => {
7930            if n_sites == 0 {
7931                0
7932            } else {
7933                1u16 << (*position as usize % n_sites)
7934            }
7935        }
7936        crate::pipeline::ConstraintRef::Carry { site } => {
7937            if n_sites == 0 {
7938                0
7939            } else {
7940                1u16 << (*site as usize % n_sites)
7941            }
7942        }
7943        crate::pipeline::ConstraintRef::Affine {
7944            coefficients,
7945            coefficient_count,
7946            ..
7947        } => {
7948            if n_sites == 0 {
7949                0
7950            } else {
7951                let mut mask: u16 = 0;
7952                let count = *coefficient_count as usize;
7953                let mut i = 0;
7954                while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS && i < n_sites {
7955                    if coefficients[i] != 0 {
7956                        mask |= 1u16 << i;
7957                    }
7958                    i += 1;
7959                }
7960                if mask == 0 {
7961                    all_mask
7962                } else {
7963                    mask
7964                }
7965            }
7966        }
7967        _ => all_mask,
7968    }
7969}
7970
7971/// Phase X.4: find the column index of the 1-simplex (lo, hi) in the enumerated
7972/// pair list. Returns `NERVE_C1_MAX` (sentinel = not found) when absent.
7973pub(crate) const fn find_pair_index(
7974    lo_arr: &[u8; NERVE_C1_MAX],
7975    hi_arr: &[u8; NERVE_C1_MAX],
7976    n_c1: usize,
7977    lo: u8,
7978    hi: u8,
7979) -> usize {
7980    let mut i = 0;
7981    while i < n_c1 {
7982        if lo_arr[i] == lo && hi_arr[i] == hi {
7983            return i;
7984        }
7985        i += 1;
7986    }
7987    NERVE_C1_MAX
7988}
7989
7990/// Phase X.4: rank of an integer matrix over ℤ/`NERVE_RANK_MOD_P` via modular
7991/// Gaussian elimination. Entries are reduced mod p and elimination uses
7992/// Fermat-inverse pivot normalization. For ±1/0 boundary matrices this
7993/// coincides with rank over ℤ.
7994pub(crate) const fn integer_matrix_rank<const R: usize, const C: usize>(
7995    matrix: &mut [[i64; C]; R],
7996    rows: usize,
7997    cols: usize,
7998) -> usize {
7999    let p = NERVE_RANK_MOD_P;
8000    // Reduce all entries into [0, p).
8001    let mut r = 0;
8002    while r < rows {
8003        let mut c = 0;
8004        while c < cols {
8005            let v = matrix[r][c] % p;
8006            matrix[r][c] = if v < 0 { v + p } else { v };
8007            c += 1;
8008        }
8009        r += 1;
8010    }
8011    let mut rank: usize = 0;
8012    let mut col: usize = 0;
8013    while col < cols && rank < rows {
8014        // Find a pivot row in column `col`, starting at `rank`.
8015        let mut pivot_row = rank;
8016        while pivot_row < rows && matrix[pivot_row][col] == 0 {
8017            pivot_row += 1;
8018        }
8019        if pivot_row == rows {
8020            col += 1;
8021            continue;
8022        }
8023        // Swap into position.
8024        if pivot_row != rank {
8025            let mut k = 0;
8026            while k < cols {
8027                let tmp = matrix[rank][k];
8028                matrix[rank][k] = matrix[pivot_row][k];
8029                matrix[pivot_row][k] = tmp;
8030                k += 1;
8031            }
8032        }
8033        // Normalize pivot row to have leading 1.
8034        let pivot = matrix[rank][col];
8035        let pivot_inv = mod_pow(pivot, p - 2, p);
8036        let mut k = 0;
8037        while k < cols {
8038            matrix[rank][k] = (matrix[rank][k] * pivot_inv) % p;
8039            k += 1;
8040        }
8041        // Eliminate the column entry from every other row.
8042        let mut r2 = 0;
8043        while r2 < rows {
8044            if r2 != rank {
8045                let factor = matrix[r2][col];
8046                if factor != 0 {
8047                    let mut kk = 0;
8048                    while kk < cols {
8049                        let sub = (matrix[rank][kk] * factor) % p;
8050                        let mut v = matrix[r2][kk] - sub;
8051                        v %= p;
8052                        if v < 0 {
8053                            v += p;
8054                        }
8055                        matrix[r2][kk] = v;
8056                        kk += 1;
8057                    }
8058                }
8059            }
8060            r2 += 1;
8061        }
8062        rank += 1;
8063        col += 1;
8064    }
8065    rank
8066}
8067
8068/// Phase X.4: modular exponentiation `base^exp mod p`, const-fn. Used by
8069/// `integer_matrix_rank` via Fermat's little theorem for modular inverses.
8070pub(crate) const fn mod_pow(base: i64, exp: i64, p: i64) -> i64 {
8071    let mut result: i64 = 1;
8072    let mut b = ((base % p) + p) % p;
8073    let mut e = exp;
8074    while e > 0 {
8075        if e & 1 == 1 {
8076            result = (result * b) % p;
8077        }
8078        b = (b * b) % p;
8079        e >>= 1;
8080    }
8081    result
8082}
8083
8084/// v0.2.2 Phase J: fold the Betti tuple into the hasher.
8085pub(crate) fn fold_betti_tuple<H: Hasher>(mut hasher: H, betti: &[u32; MAX_BETTI_DIMENSION]) -> H {
8086    let mut i = 0;
8087    while i < MAX_BETTI_DIMENSION {
8088        hasher = hasher.fold_bytes(&betti[i].to_be_bytes());
8089        i += 1;
8090    }
8091    hasher
8092}
8093
8094/// v0.2.2 Phase J: Euler characteristic `χ = Σ(-1)^k b_k` from the Betti tuple.
8095#[must_use]
8096pub(crate) fn primitive_euler_characteristic(betti: &[u32; MAX_BETTI_DIMENSION]) -> i64 {
8097    let mut chi: i64 = 0;
8098    let mut k = 0;
8099    while k < MAX_BETTI_DIMENSION {
8100        let term = betti[k] as i64;
8101        if k % 2 == 0 {
8102            chi += term;
8103        } else {
8104            chi -= term;
8105        }
8106        k += 1;
8107    }
8108    chi
8109}
8110
8111/// v0.2.2 Phase J primitive: `op:DihedralGroup` / `op:D_7`.
8112/// Returns `(orbit_size, representative)` under D_{2^n} acting on `T::SITE_COUNT`.
8113/// `orbit_size = 2n` when n ≥ 2, 2 when n == 1, 1 when n == 0 (group identity only).
8114/// `representative` is the lexicographically-minimal element of the orbit of
8115/// site 0 under D_{2n}: rotations `r^k → k mod n` and reflections `s·r^k → (n - k) mod n`.
8116/// For the orbit of site 0, both maps produce 0 as a group element, so the
8117/// representative is always 0; for a non-canonical starting index `i`, the
8118/// representative would be `min(i, (n - i) mod n)`. This helper uses site 0 as the
8119/// canonical starting point (the foundation's convention), so the representative
8120/// reflects the orbit's algebraic content, not a sentinel.
8121pub(crate) fn primitive_dihedral_signature<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8122) -> (u32, u32) {
8123    let n = T::SITE_COUNT as u32;
8124    let orbit_size = if n < 2 {
8125        if n == 0 {
8126            1
8127        } else {
8128            2
8129        }
8130    } else {
8131        2 * n
8132    };
8133    // v0.2.2 Phase S.2: compute the lexicographically-minimal orbit element.
8134    // Orbit of site 0 under D_{2n} contains: rotation images {0, 1, ..., n-1}
8135    // (since r^k maps 0 → k mod n) and reflection images {0, n-1, n-2, ..., 1}
8136    // (since s·r^k maps 0 → (n - k) mod n). The union is {0, 1, ..., n-1}.
8137    // The lex-min is 0 by construction; formalize it by min-walking the orbit.
8138    let mut rep: u32 = 0;
8139    let mut k = 1u32;
8140    while k < n {
8141        let rot = k % n;
8142        let refl = (n - k) % n;
8143        if rot < rep {
8144            rep = rot;
8145        }
8146        if refl < rep {
8147            rep = refl;
8148        }
8149        k += 1;
8150    }
8151    (orbit_size, rep)
8152}
8153
8154/// v0.2.2 Phase J: fold the dihedral `(orbit_size, representative)` pair.
8155pub(crate) fn fold_dihedral_signature<H: Hasher>(
8156    mut hasher: H,
8157    orbit_size: u32,
8158    representative: u32,
8159) -> H {
8160    hasher = hasher.fold_bytes(&orbit_size.to_be_bytes());
8161    hasher = hasher.fold_bytes(&representative.to_be_bytes());
8162    hasher
8163}
8164
8165/// v0.2.2 Phase J primitive: `observable:Jacobian` / `op:DC_10`.
8166/// Content-deterministic per-site Jacobian profile: for each site `i`, the number
8167/// of constraints that mention site index `i` (derived from the constraint encoding).
8168/// Truncated / zero-padded to `JACOBIAN_MAX_SITES` entries to keep the fold fixed-size.
8169pub(crate) fn primitive_curvature_jacobian<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8170) -> [i32; JACOBIAN_MAX_SITES] {
8171    let mut out = [0i32; JACOBIAN_MAX_SITES];
8172    let mut ci = 0;
8173    while ci < T::CONSTRAINTS.len() {
8174        if let crate::pipeline::ConstraintRef::Site { position } = T::CONSTRAINTS[ci] {
8175            let idx = (position as usize) % JACOBIAN_MAX_SITES;
8176            out[idx] = out[idx].saturating_add(1);
8177        }
8178        ci += 1;
8179    }
8180    // Also account for residue and hamming constraints as contributing uniformly
8181    // across all sites (they are not site-local). Represented as +1 to site 0.
8182    let total = T::CONSTRAINTS.len() as i32;
8183    out[0] = out[0].saturating_add(total);
8184    out
8185}
8186
8187/// v0.2.2 Phase J: DC_10 selects the site with the maximum absolute Jacobian value.
8188#[must_use]
8189pub(crate) fn primitive_dc10_select(jac: &[i32; JACOBIAN_MAX_SITES]) -> usize {
8190    let mut best_idx: usize = 0;
8191    let mut best_abs: i32 = jac[0].unsigned_abs() as i32;
8192    let mut i = 1;
8193    while i < JACOBIAN_MAX_SITES {
8194        let a = jac[i].unsigned_abs() as i32;
8195        if a > best_abs {
8196            best_abs = a;
8197            best_idx = i;
8198        }
8199        i += 1;
8200    }
8201    best_idx
8202}
8203
8204/// v0.2.2 Phase J: fold the Jacobian profile into the hasher.
8205pub(crate) fn fold_jacobian_profile<H: Hasher>(
8206    mut hasher: H,
8207    jac: &[i32; JACOBIAN_MAX_SITES],
8208) -> H {
8209    let mut i = 0;
8210    while i < JACOBIAN_MAX_SITES {
8211        hasher = hasher.fold_bytes(&jac[i].to_be_bytes());
8212        i += 1;
8213    }
8214    hasher
8215}
8216
8217/// v0.2.2 Phase J primitive: `state:BindingAccumulator` / `state:ContextLease`.
8218/// Returns `(binding_count, fold_address)` — a content-deterministic session signature.
8219/// v0.2.2 Phase S.4: uses an FNV-1a-style order-preserving incremental hash
8220/// (rotate-and-multiply) over each binding's `(name_index, type_index,
8221/// content_address)` tuple, rather than XOR-accumulation (which is commutative
8222/// and collides on reordered-but-otherwise-identical binding sets). Order-dependence
8223/// is intentional: `state:BindingAccumulator` semantics treat the insertion
8224/// sequence as part of the session signature.
8225pub(crate) fn primitive_session_binding_signature(bindings: &[Binding]) -> (u32, u64) {
8226    // FNV-1a-style incremental mix: start from the FNV offset basis,
8227    // multiply-then-XOR each limb. Order-dependent by construction.
8228    let mut fold: u64 = 0xcbf2_9ce4_8422_2325;
8229    const FNV_PRIME: u64 = 0x0000_0100_0000_01b3;
8230    let mut i = 0;
8231    while i < bindings.len() {
8232        let b = &bindings[i];
8233        // Mix in (name_index, type_index, content_address) per binding.
8234        fold = fold.wrapping_mul(FNV_PRIME);
8235        fold ^= b.name_index as u64;
8236        fold = fold.wrapping_mul(FNV_PRIME);
8237        fold ^= b.type_index as u64;
8238        fold = fold.wrapping_mul(FNV_PRIME);
8239        fold ^= b.content_address;
8240        i += 1;
8241    }
8242    (bindings.len() as u32, fold)
8243}
8244
8245/// v0.2.2 Phase J: fold the session-binding signature into the hasher.
8246pub(crate) fn fold_session_signature<H: Hasher>(
8247    mut hasher: H,
8248    binding_count: u32,
8249    fold_address: u64,
8250) -> H {
8251    hasher = hasher.fold_bytes(&binding_count.to_be_bytes());
8252    hasher = hasher.fold_bytes(&fold_address.to_be_bytes());
8253    hasher
8254}
8255
8256/// v0.2.2 Phase J primitive: `op:QM_1` / `op:QM_5` / `resolver:collapseAmplitude`.
8257/// Seeds a two-state amplitude vector from the CompileUnit's thermodynamic budget,
8258/// computes Born-rule probabilities `P(0) = |α_0|²` and `P(1) = |α_1|²`,
8259/// verifies QM_5 normalization `Σ P = 1`, and returns `(outcome_index, probability)`
8260/// where `outcome_index` is the index of the larger amplitude and `probability` is its value.
8261/// QM_1 Landauer equality: `pre_entropy == post_cost` at β* = ln 2; since both
8262/// sides derive from the same budget the equality holds by construction.
8263/// v0.2.2 Phase S.3: amplitudes are sourced from two decorrelated projections
8264/// of the thermodynamic budget — the high 32 bits become the alpha-0
8265/// magnitude and the low 32 bits become the alpha-1 magnitude. This replaces
8266/// the earlier XOR-with-fixed-constants sourcing, preserving determinism while
8267/// ensuring both amplitudes derive from independent halves of the budget's
8268/// thermodynamic-entropy state. Born normalization and QM_1 Landauer equality
8269/// remain invariant under this sourcing change.
8270pub(crate) fn primitive_measurement_projection(budget: u64) -> (u64, u64) {
8271    // Decorrelated amplitude sourcing: high-32-bits drives alpha_0,
8272    // low-32-bits drives alpha_1. Distinct bit halves yield independent
8273    // magnitudes under any non-degenerate budget.
8274    let alpha0_bits: u32 = (budget >> 32) as u32;
8275    let alpha1_bits: u32 = (budget & 0xFFFF_FFFF) as u32;
8276    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8277    let a0 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha0_bits)
8278        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8279    let a1 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha1_bits)
8280        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8281    let norm = a0 * a0 + a1 * a1;
8282    let zero = <DefaultDecimal as Default>::default();
8283    let half =
8284        <DefaultDecimal as crate::DecimalTranscendental>::from_bits(0x3FE0_0000_0000_0000_u64);
8285    // QM_5 normalization: P(k) = |alpha_k|^2 / norm. Degenerate budget = 0
8286    // yields norm = 0; fall through to the uniform distribution (P(0) = 0.5,
8287    // P(1) = 0.5), which is the maximum-entropy projection under QM_1.
8288    let p0 = if norm > zero { (a0 * a0) / norm } else { half };
8289    let p1 = if norm > zero { (a1 * a1) / norm } else { half };
8290    if p0 >= p1 {
8291        (
8292            0,
8293            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p0),
8294        )
8295    } else {
8296        (
8297            1,
8298            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p1),
8299        )
8300    }
8301}
8302
8303/// v0.2.2 Phase J / Phase 9: fold the Born-rule outcome into the hasher.
8304/// `probability_bits` is the IEEE-754 bit pattern (call sites convert via
8305/// `<H::Decimal as DecimalTranscendental>::to_bits` if working in `H::Decimal`).
8306pub(crate) fn fold_born_outcome<H: Hasher>(
8307    mut hasher: H,
8308    outcome_index: u64,
8309    probability_bits: u64,
8310) -> H {
8311    hasher = hasher.fold_bytes(&outcome_index.to_be_bytes());
8312    hasher = hasher.fold_bytes(&probability_bits.to_be_bytes());
8313    hasher
8314}
8315
8316/// v0.2.2 Phase J primitive: `recursion:DescentMeasure` / `observable:ResidualEntropy`.
8317/// Computes `(residual_count, entropy_bits)` from `T::SITE_COUNT` and the Euler char.
8318/// `residual_count = max(0, site_count - euler_char)` — free sites after constraint contraction.
8319/// `entropy = (residual_count) × ln 2` — Landauer-temperature entropy in nats.
8320/// Phase 9: returns `(residual_count, entropy_bits)` where `entropy_bits` is the
8321/// IEEE-754 bit pattern of `residual × ln 2`. Consumers project to `H::Decimal`
8322/// via `<H::Decimal as DecimalTranscendental>::from_bits`.
8323pub(crate) fn primitive_descent_metrics<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8324    betti: &[u32; MAX_BETTI_DIMENSION],
8325) -> (u32, u64) {
8326    let chi = primitive_euler_characteristic(betti);
8327    let n = T::SITE_COUNT as i64;
8328    let residual = if n > chi { (n - chi) as u32 } else { 0u32 };
8329    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8330    let residual_d = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(residual);
8331    let ln_2 = <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
8332    let entropy = residual_d * ln_2;
8333    (
8334        residual,
8335        <DefaultDecimal as crate::DecimalTranscendental>::to_bits(entropy),
8336    )
8337}
8338
8339/// v0.2.2 Phase J / Phase 9: fold the descent metrics into the hasher.
8340/// `entropy_bits` is the IEEE-754 bit pattern of the descent entropy.
8341pub(crate) fn fold_descent_metrics<H: Hasher>(
8342    mut hasher: H,
8343    residual_count: u32,
8344    entropy_bits: u64,
8345) -> H {
8346    hasher = hasher.fold_bytes(&residual_count.to_be_bytes());
8347    hasher = hasher.fold_bytes(&entropy_bits.to_be_bytes());
8348    hasher
8349}
8350
8351/// Phase X.2: upper bound on cohomology class dimension. Cup products
8352/// whose summed dimension exceeds this cap are rejected as
8353/// `CohomologyError::DimensionOverflow`.
8354pub const MAX_COHOMOLOGY_DIMENSION: u32 = 32;
8355
8356/// Phase X.2: a cohomology class `H^n(·)` at dimension `n` with a content
8357/// fingerprint of the underlying cochain representative. Parametric over
8358/// dimension via a runtime field because generic-const-expression arithmetic
8359/// over `N + M` is unstable at the crate's MSRV (Rust 1.81).
8360#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8361pub struct CohomologyClass {
8362    dimension: u32,
8363    fingerprint: ContentFingerprint,
8364    _sealed: (),
8365}
8366
8367impl CohomologyClass {
8368    /// Phase X.2: crate-sealed constructor. Public callers go through
8369    /// `mint_cohomology_class` so that construction always routes through a
8370    /// validating hash of the cochain representative.
8371    #[inline]
8372    pub(crate) const fn with_dimension_and_fingerprint(
8373        dimension: u32,
8374        fingerprint: ContentFingerprint,
8375    ) -> Self {
8376        Self {
8377            dimension,
8378            fingerprint,
8379            _sealed: (),
8380        }
8381    }
8382
8383    /// The dimension `n` of this cohomology class `H^n(·)`.
8384    #[inline]
8385    #[must_use]
8386    pub const fn dimension(&self) -> u32 {
8387        self.dimension
8388    }
8389
8390    /// The content fingerprint of the underlying cochain representative.
8391    #[inline]
8392    #[must_use]
8393    pub const fn fingerprint(&self) -> ContentFingerprint {
8394        self.fingerprint
8395    }
8396
8397    /// Phase X.2: cup product `H^n × H^m → H^{n+m}`. The resulting class
8398    /// carries dimension `n + m` and a fingerprint folded from both
8399    /// operand dimensions and fingerprints via `fold_cup_product`. The
8400    /// fold is ordered (lhs-then-rhs) — graded-commutativity of the cup
8401    /// product at the algebraic level is not a fingerprint-level property.
8402    /// # Errors
8403    /// Returns `CohomologyError::DimensionOverflow` when `n + m >
8404    /// MAX_COHOMOLOGY_DIMENSION`.
8405    pub fn cup<H: Hasher>(
8406        self,
8407        other: CohomologyClass,
8408    ) -> Result<CohomologyClass, CohomologyError> {
8409        let sum = self.dimension.saturating_add(other.dimension);
8410        if sum > MAX_COHOMOLOGY_DIMENSION {
8411            return Err(CohomologyError::DimensionOverflow {
8412                lhs: self.dimension,
8413                rhs: other.dimension,
8414            });
8415        }
8416        let hasher = H::initial();
8417        let hasher = fold_cup_product(
8418            hasher,
8419            self.dimension,
8420            &self.fingerprint,
8421            other.dimension,
8422            &other.fingerprint,
8423        );
8424        let buf = hasher.finalize();
8425        let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8426        Ok(Self::with_dimension_and_fingerprint(sum, fp))
8427    }
8428}
8429
8430/// Phase X.2: error returned by `CohomologyClass::cup` when the summed
8431/// dimension exceeds `MAX_COHOMOLOGY_DIMENSION`.
8432#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8433pub enum CohomologyError {
8434    /// Cup product would exceed `MAX_COHOMOLOGY_DIMENSION`.
8435    DimensionOverflow { lhs: u32, rhs: u32 },
8436}
8437
8438impl core::fmt::Display for CohomologyError {
8439    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8440        match self {
8441            Self::DimensionOverflow { lhs, rhs } => write!(
8442                f,
8443                "cup product dimension overflow: {lhs} + {rhs} > MAX_COHOMOLOGY_DIMENSION ({})",
8444                MAX_COHOMOLOGY_DIMENSION
8445            ),
8446        }
8447    }
8448}
8449impl core::error::Error for CohomologyError {}
8450
8451/// Phase X.2: homology class dual to `CohomologyClass`. A homology class
8452/// `H_n(·)` at dimension `n` with a content fingerprint of its chain
8453/// representative. Shares the dimension-as-runtime-field discipline.
8454#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8455pub struct HomologyClass {
8456    dimension: u32,
8457    fingerprint: ContentFingerprint,
8458    _sealed: (),
8459}
8460
8461impl HomologyClass {
8462    /// Phase X.2: crate-sealed constructor. Public callers go through
8463    /// `mint_homology_class`.
8464    #[inline]
8465    pub(crate) const fn with_dimension_and_fingerprint(
8466        dimension: u32,
8467        fingerprint: ContentFingerprint,
8468    ) -> Self {
8469        Self {
8470            dimension,
8471            fingerprint,
8472            _sealed: (),
8473        }
8474    }
8475
8476    /// The dimension `n` of this homology class `H_n(·)`.
8477    #[inline]
8478    #[must_use]
8479    pub const fn dimension(&self) -> u32 {
8480        self.dimension
8481    }
8482
8483    /// The content fingerprint of the underlying chain representative.
8484    #[inline]
8485    #[must_use]
8486    pub const fn fingerprint(&self) -> ContentFingerprint {
8487        self.fingerprint
8488    }
8489}
8490
8491/// Phase X.2: fold the cup-product operand pair into the hasher. Ordered
8492/// (lhs dimension + fingerprint, then rhs dimension + fingerprint).
8493pub fn fold_cup_product<H: Hasher>(
8494    mut hasher: H,
8495    lhs_dim: u32,
8496    lhs_fp: &ContentFingerprint,
8497    rhs_dim: u32,
8498    rhs_fp: &ContentFingerprint,
8499) -> H {
8500    hasher = hasher.fold_bytes(&lhs_dim.to_be_bytes());
8501    hasher = hasher.fold_bytes(lhs_fp.as_bytes());
8502    hasher = hasher.fold_bytes(&rhs_dim.to_be_bytes());
8503    hasher = hasher.fold_bytes(rhs_fp.as_bytes());
8504    hasher
8505}
8506
8507/// Phase X.2: mint a `CohomologyClass` from a cochain representative `seed`.
8508/// Hashes `seed` through `H` to produce the class fingerprint. The caller's
8509/// choice of `H` determines the fingerprint width.
8510/// # Errors
8511/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8512/// MAX_COHOMOLOGY_DIMENSION`.
8513pub fn mint_cohomology_class<H: Hasher>(
8514    dimension: u32,
8515    seed: &[u8],
8516) -> Result<CohomologyClass, CohomologyError> {
8517    if dimension > MAX_COHOMOLOGY_DIMENSION {
8518        return Err(CohomologyError::DimensionOverflow {
8519            lhs: dimension,
8520            rhs: 0,
8521        });
8522    }
8523    let mut hasher = H::initial();
8524    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8525    hasher = hasher.fold_bytes(seed);
8526    let buf = hasher.finalize();
8527    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8528    Ok(CohomologyClass::with_dimension_and_fingerprint(
8529        dimension, fp,
8530    ))
8531}
8532
8533/// Phase X.2: mint a `HomologyClass` from a chain representative `seed`.
8534/// Hashes `seed` through `H` to produce the class fingerprint.
8535/// # Errors
8536/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8537/// MAX_COHOMOLOGY_DIMENSION`.
8538pub fn mint_homology_class<H: Hasher>(
8539    dimension: u32,
8540    seed: &[u8],
8541) -> Result<HomologyClass, CohomologyError> {
8542    if dimension > MAX_COHOMOLOGY_DIMENSION {
8543        return Err(CohomologyError::DimensionOverflow {
8544            lhs: dimension,
8545            rhs: 0,
8546        });
8547    }
8548    let mut hasher = H::initial();
8549    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8550    hasher = hasher.fold_bytes(seed);
8551    let buf = hasher.finalize();
8552    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8553    Ok(HomologyClass::with_dimension_and_fingerprint(dimension, fp))
8554}
8555
8556/// v0.2.2 T6.1: per-step canonical byte layout for `StreamDriver::next()`.
8557/// Layout: `productivity_remaining (8 BE) || rewrite_steps (8 BE) || seed (8 BE) ||
8558/// iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8559pub fn fold_stream_step_digest<H: Hasher>(
8560    mut hasher: H,
8561    productivity_remaining: u64,
8562    rewrite_steps: u64,
8563    seed: u64,
8564    iri: &str,
8565    kind: CertificateKind,
8566) -> H {
8567    hasher = hasher.fold_bytes(&productivity_remaining.to_be_bytes());
8568    hasher = hasher.fold_bytes(&rewrite_steps.to_be_bytes());
8569    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8570    hasher = hasher.fold_bytes(iri.as_bytes());
8571    hasher = hasher.fold_byte(0);
8572    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8573    hasher
8574}
8575
8576/// v0.2.2 T6.1: per-step canonical byte layout for `InteractionDriver::step()`
8577/// and `InteractionDriver::finalize()`.
8578/// Layout: `commutator_acc[0..4] (4 × 8 BE bytes) || peer_step_count (8 BE) ||
8579/// seed (8 BE) || iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8580pub fn fold_interaction_step_digest<H: Hasher>(
8581    mut hasher: H,
8582    commutator_acc: &[u64; 4],
8583    peer_step_count: u64,
8584    seed: u64,
8585    iri: &str,
8586    kind: CertificateKind,
8587) -> H {
8588    let mut i = 0;
8589    while i < 4 {
8590        hasher = hasher.fold_bytes(&commutator_acc[i].to_be_bytes());
8591        i += 1;
8592    }
8593    hasher = hasher.fold_bytes(&peer_step_count.to_be_bytes());
8594    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8595    hasher = hasher.fold_bytes(iri.as_bytes());
8596    hasher = hasher.fold_byte(0);
8597    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8598    hasher
8599}
8600
8601/// Utility — extract the leading 16 bytes of a `Hasher::finalize` buffer
8602/// as a `ContentAddress`. Used by pipeline entry points to derive the
8603/// 16-byte unit_address handle from a freshly-computed substrate
8604/// fingerprint, so two units with distinct fingerprints have distinct
8605/// unit_address handles too.
8606/// Per the wiki's ADR-018 the `FP_MAX` const-generic carries the
8607/// application's selected `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
8608/// `FP_MAX` MUST be at least 16; smaller buffers cannot supply the
8609/// 16-byte address prefix.
8610#[inline]
8611#[must_use]
8612pub const fn unit_address_from_buffer<const FP_MAX: usize>(
8613    buffer: &[u8; FP_MAX],
8614) -> ContentAddress {
8615    let mut bytes = [0u8; 16];
8616    let mut i = 0;
8617    while i < 16 {
8618        bytes[i] = buffer[i];
8619        i += 1;
8620    }
8621    ContentAddress::from_u128(u128::from_be_bytes(bytes))
8622}
8623
8624/// v0.2.2 T6.11: const-fn equality on `&str` slices. `str::eq` is not
8625/// stable in const eval under MSRV 1.81; this helper provides a
8626/// byte-by-byte equality check for use in `pipeline::run`'s ShapeMismatch
8627/// detection without runtime allocation.
8628#[inline]
8629#[must_use]
8630pub const fn str_eq(a: &str, b: &str) -> bool {
8631    let a = a.as_bytes();
8632    let b = b.as_bytes();
8633    if a.len() != b.len() {
8634        return false;
8635    }
8636    let mut i = 0;
8637    while i < a.len() {
8638        if a[i] != b[i] {
8639            return false;
8640        }
8641        i += 1;
8642    }
8643    true
8644}
8645
8646/// A binding entry in a `BindingsTable`. Pairs a `ContentAddress`
8647/// (hash of the query coordinate) with the bound bytes.
8648#[derive(Debug, Clone, Copy)]
8649pub struct BindingEntry {
8650    /// Content-hashed query address.
8651    pub address: ContentAddress,
8652    /// Bound payload bytes (length determined by the WittLevel of the table).
8653    pub bytes: &'static [u8],
8654}
8655
8656/// A static, sorted-by-address binding table laid out for `op:GS_5` zero-step
8657/// access. Looked up via binary search; the foundation guarantees the table
8658/// is materialized at compile time from the attested `state:GroundedContext`.
8659#[derive(Debug, Clone, Copy)]
8660pub struct BindingsTable {
8661    /// Entries, sorted ascending by `address`.
8662    pub entries: &'static [BindingEntry],
8663}
8664
8665impl BindingsTable {
8666    /// v0.2.2 T5 C4: validating constructor. Checks that `entries` are
8667    /// strictly ascending by `address`, which is the invariant
8668    /// `Grounded::get_binding` relies on for its binary-search lookup.
8669    /// # Errors
8670    /// Returns `BindingsTableError::Unsorted { at }` where `at` is the first
8671    /// index where the order is violated (i.e., `entries[at].address <=
8672    /// entries[at - 1].address`).
8673    pub const fn try_new(entries: &'static [BindingEntry]) -> Result<Self, BindingsTableError> {
8674        let mut i = 1;
8675        while i < entries.len() {
8676            if entries[i].address.as_u128() <= entries[i - 1].address.as_u128() {
8677                return Err(BindingsTableError::Unsorted { at: i });
8678            }
8679            i += 1;
8680        }
8681        Ok(Self { entries })
8682    }
8683}
8684
8685/// v0.2.2 T5 C4: errors returned by `BindingsTable::try_new`.
8686#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8687#[non_exhaustive]
8688pub enum BindingsTableError {
8689    /// Entries at index `at` and `at - 1` are out of order (the slice is
8690    /// not strictly ascending by `address`).
8691    Unsorted {
8692        /// The first index where the order is violated.
8693        at: usize,
8694    },
8695}
8696
8697impl core::fmt::Display for BindingsTableError {
8698    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8699        match self {
8700            Self::Unsorted { at } => write!(
8701                f,
8702                "BindingsTable entries not sorted: address at index {at} <= address at index {}",
8703                at - 1,
8704            ),
8705        }
8706    }
8707}
8708
8709impl core::error::Error for BindingsTableError {}
8710
8711/// The compile-time witness that `op:GS_4` holds for the value it carries:
8712/// σ = 1, freeRank = 0, S = 0, T_ctx = 0. `Grounded<T, Tag>` is constructed
8713/// only by the reduction pipeline and provides `op:GS_5` zero-step binding access.
8714/// v0.2.2 Phase B (Q3): the `Tag` phantom parameter (default `Tag = T`)
8715/// lets downstream code attach a domain marker to a grounded witness without
8716/// any new sealing — e.g., `Grounded<ConstrainedTypeInput, BlockHashTag>` is
8717/// a distinct Rust type from `Grounded<ConstrainedTypeInput, PixelTag>`. The
8718/// inner witness is unchanged; the tag is pure decoration. The foundation
8719/// guarantees ring soundness on the inner witness; the tag is the developer's
8720/// domain claim. Coerce via `Grounded::tag::<NewTag>()` (zero-cost).
8721///
8722/// # Wiki ADR-039 — Inhabitance verdict realization mapping
8723///
8724/// For typed feature hierarchies whose admission relations are
8725/// inhabitance questions, a successful `Grounded<Output>` IS a
8726/// `cert:InhabitanceCertificate` envelope:
8727///
8728/// - The κ-label (homotopy-classification structural witness at ψ_9
8729///   per ADR-035) is the `Term::KInvariants` emission's bytes, exposed
8730///   via [`Grounded::output_bytes`].
8731/// - The concrete `cert:witness` ValueTuple is derivable from
8732///   `Term::Nerve`'s 0-simplices at ψ_1 (the per-value bytes the model's
8733///   NerveResolver consumed).
8734/// - The `cert:searchTrace` is realized as
8735///   [`Grounded::derivation`]`().replay()`.
8736///
8737/// The κ-label and `cert:witness` are different witness granularities
8738/// (homotopy classification vs. concrete ValueTuple); the canonical
8739/// k-invariants branch ψ_1 → ψ_7 → ψ_8 → ψ_9 produces both, at the
8740/// ψ_9 and ψ_1 stages respectively. Ontology references:
8741/// `<https://uor.foundation/cert/InhabitanceCertificate>`,
8742/// `<https://uor.foundation/cert/witness>`,
8743/// `<https://uor.foundation/cert/searchTrace>`.
8744#[derive(Debug, Clone)]
8745pub struct Grounded<T: GroundedShape, Tag = T> {
8746    /// The validated grounding certificate this wrapper carries.
8747    validated: Validated<GroundingCertificate>,
8748    /// The compile-time-materialized bindings table.
8749    bindings: BindingsTable,
8750    /// The Witt level the grounded value was minted at.
8751    witt_level_bits: u16,
8752    /// Content-address of the originating CompileUnit.
8753    unit_address: ContentAddress,
8754    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
8755    /// Computed deterministically from (witt_level_bits, unit_address, bindings).
8756    uor_time: UorTime,
8757    /// v0.2.2 T2.6 (cleanup): BaseMetric storage — populated by the
8758    /// pipeline at mint time as a deterministic function of witt level,
8759    /// unit address, and bindings. All six fields are read-only from
8760    /// the accessors; downstream cannot mutate them.
8761    /// Grounding completion ratio σ × 10⁶ (parts per million).
8762    sigma_ppm: u32,
8763    /// Metric incompatibility d_Δ.
8764    d_delta: i64,
8765    /// Euler characteristic of the constraint nerve.
8766    euler_characteristic: i64,
8767    /// Free-site count at grounding time.
8768    residual_count: u32,
8769    /// Per-site Jacobian row (fixed capacity, zero-padded).
8770    jacobian_entries: [i64; JACOBIAN_MAX_SITES],
8771    /// Active length of jacobian_entries.
8772    jacobian_len: u16,
8773    /// Betti numbers β_0..β_{MAX_BETTI_DIMENSION-1}.
8774    betti_numbers: [u32; MAX_BETTI_DIMENSION],
8775    /// v0.2.2 T5: parametric content fingerprint of the source unit's
8776    /// full state, computed at grounding time by the consumer-supplied
8777    /// `Hasher`. Width is `ContentFingerprint::width_bytes()`, set by
8778    /// `H::OUTPUT_BYTES` at the call site. Read by `Grounded::derivation()`
8779    /// so the verify path can re-derive the source certificate.
8780    content_fingerprint: ContentFingerprint,
8781    /// Wiki ADR-028: output-value payload — the catamorphism's evaluation
8782    /// result populated by `pipeline::run_route` per ADR-029's per-variant
8783    /// fold rules. Fixed-capacity stack buffer; the active prefix runs to
8784    /// `output_len` bytes. Read via [`Grounded::output_bytes`].
8785    output_payload: [u8; crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES],
8786    /// Active length of `output_payload` (the route's evaluation output length).
8787    output_len: u16,
8788    /// Phantom type tying this `Grounded` to a specific `ConstrainedType`.
8789    _phantom: PhantomData<T>,
8790    /// Phantom domain tag (Q3). Defaults to `T` for backwards-compatible
8791    /// call sites; downstream attaches a custom tag via `tag::<NewTag>()`.
8792    _tag: PhantomData<Tag>,
8793}
8794
8795impl<T: GroundedShape, Tag> Grounded<T, Tag> {
8796    /// Returns the binding for the given query address, or `None` if not in
8797    /// the table. Resolves in O(log n) via binary search; for true `op:GS_5`
8798    /// zero-step access, downstream code uses statically-known indices.
8799    #[inline]
8800    #[must_use]
8801    pub fn get_binding(&self, address: ContentAddress) -> Option<&'static [u8]> {
8802        self.bindings
8803            .entries
8804            .binary_search_by_key(&address.as_u128(), |e| e.address.as_u128())
8805            .ok()
8806            .map(|i| self.bindings.entries[i].bytes)
8807    }
8808
8809    /// Iterate over all bindings in this grounded context.
8810    #[inline]
8811    pub fn iter_bindings(&self) -> impl Iterator<Item = &BindingEntry> + '_ {
8812        self.bindings.entries.iter()
8813    }
8814
8815    /// Returns the Witt level the grounded value was minted at.
8816    #[inline]
8817    #[must_use]
8818    pub const fn witt_level_bits(&self) -> u16 {
8819        self.witt_level_bits
8820    }
8821
8822    /// Returns the content-address of the originating CompileUnit.
8823    #[inline]
8824    #[must_use]
8825    pub const fn unit_address(&self) -> ContentAddress {
8826        self.unit_address
8827    }
8828
8829    /// Returns the validated grounding certificate this wrapper carries.
8830    #[inline]
8831    #[must_use]
8832    pub const fn certificate(&self) -> &Validated<GroundingCertificate> {
8833        &self.validated
8834    }
8835
8836    /// Phase A.4: `observable:d_delta_metric` — sealed metric incompatibility between
8837    /// ring distance and Hamming distance for this datum's neighborhood.
8838    #[inline]
8839    #[must_use]
8840    pub const fn d_delta(&self) -> DDeltaMetric {
8841        DDeltaMetric::new(self.d_delta)
8842    }
8843
8844    /// Phase A.4: `observable:sigma_metric` — sealed grounding completion ratio.
8845    #[inline]
8846    #[must_use]
8847    pub fn sigma(&self) -> SigmaValue<crate::DefaultHostTypes> {
8848        // Default-host (f64) projection; polymorphic consumers
8849        // can re-encode via DecimalTranscendental::from_u32 + Div.
8850        let value = <f64 as crate::DecimalTranscendental>::from_u32(self.sigma_ppm)
8851            / <f64 as crate::DecimalTranscendental>::from_u32(1_000_000);
8852        SigmaValue::<crate::DefaultHostTypes>::new_unchecked(value)
8853    }
8854
8855    /// Phase A.4: `observable:jacobian_metric` — sealed per-site Jacobian row.
8856    #[inline]
8857    #[must_use]
8858    pub fn jacobian(&self) -> JacobianMetric<T> {
8859        JacobianMetric::from_entries(self.jacobian_entries, self.jacobian_len)
8860    }
8861
8862    /// Phase A.4: `observable:betti_metric` — sealed Betti-number vector.
8863    #[inline]
8864    #[must_use]
8865    pub const fn betti(&self) -> BettiMetric {
8866        BettiMetric::new(self.betti_numbers)
8867    }
8868
8869    /// Phase A.4: `observable:euler_metric` — sealed Euler characteristic χ of
8870    /// the constraint nerve.
8871    #[inline]
8872    #[must_use]
8873    pub const fn euler(&self) -> EulerMetric {
8874        EulerMetric::new(self.euler_characteristic)
8875    }
8876
8877    /// Phase A.4: `observable:residual_metric` — sealed free-site count r at grounding.
8878    #[inline]
8879    #[must_use]
8880    pub const fn residual(&self) -> ResidualMetric {
8881        ResidualMetric::new(self.residual_count)
8882    }
8883
8884    /// v0.2.2 T5: returns the parametric content fingerprint of the source
8885    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
8886    /// Width is set by `H::OUTPUT_BYTES` at the call site. Used by
8887    /// `derivation()` to seed the replayed Trace's fingerprint, which
8888    /// `verify_trace` then passes through to the re-derived certificate.
8889    #[inline]
8890    #[must_use]
8891    pub const fn content_fingerprint(&self) -> ContentFingerprint {
8892        self.content_fingerprint
8893    }
8894
8895    /// v0.2.2 T5 (C2): returns the `Derivation` that produced this grounded
8896    /// value. Use the returned `Derivation` with `Derivation::replay()` and
8897    /// then `uor_foundation_verify::verify_trace` to re-derive the source
8898    /// certificate without re-running the deciders.
8899    /// The round-trip property:
8900    /// ```text
8901    /// verify_trace(&grounded.derivation().replay()).certificate()
8902    ///     == grounded.certificate()
8903    /// ```
8904    /// holds for every conforming substrate `Hasher`.
8905    #[inline]
8906    #[must_use]
8907    pub const fn derivation(&self) -> Derivation {
8908        Derivation::new(
8909            (self.jacobian_len as u32) + 1,
8910            self.witt_level_bits,
8911            self.content_fingerprint,
8912        )
8913    }
8914
8915    /// v0.2.2 Phase B (Q3): coerce this `Grounded<T, Tag>` to a different
8916    /// phantom tag. Zero-cost — the inner witness is unchanged; only the
8917    /// type-system view differs. Downstream uses this to attach a domain
8918    /// marker for use in function signatures (e.g., `Grounded<_, BlockHashTag>`
8919    /// vs `Grounded<_, PixelTag>` are distinct Rust types).
8920    /// **The foundation does not validate the tag.** The tag records what
8921    /// the developer is claiming about the witness's domain semantics; the
8922    /// foundation's contract is about ring soundness, not domain semantics.
8923    #[inline]
8924    #[must_use]
8925    pub fn tag<NewTag>(self) -> Grounded<T, NewTag> {
8926        Grounded {
8927            validated: self.validated,
8928            bindings: self.bindings,
8929            witt_level_bits: self.witt_level_bits,
8930            unit_address: self.unit_address,
8931            uor_time: self.uor_time,
8932            sigma_ppm: self.sigma_ppm,
8933            d_delta: self.d_delta,
8934            euler_characteristic: self.euler_characteristic,
8935            residual_count: self.residual_count,
8936            jacobian_entries: self.jacobian_entries,
8937            jacobian_len: self.jacobian_len,
8938            betti_numbers: self.betti_numbers,
8939            content_fingerprint: self.content_fingerprint,
8940            output_payload: self.output_payload,
8941            output_len: self.output_len,
8942            _phantom: PhantomData,
8943            _tag: PhantomData,
8944        }
8945    }
8946
8947    /// Wiki ADR-028: returns the catamorphism's evaluation output bytes — the
8948    /// active prefix of the on-stack output payload `pipeline::run_route`
8949    /// populated per ADR-029's per-variant fold rules.
8950    /// For the foundation-sanctioned identity output (`ConstrainedTypeInput`)
8951    /// the slice is empty (no transformation, identity route). For shapes
8952    /// declared via the `output_shape!` SDK macro the slice carries the
8953    /// route's evaluation result.
8954    #[inline]
8955    #[must_use]
8956    pub fn output_bytes(&self) -> &[u8] {
8957        let len = self.output_len as usize;
8958        &self.output_payload[..len]
8959    }
8960
8961    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
8962    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
8963    /// `observable:LandauerCost`. The value is content-deterministic: two `Grounded`
8964    /// witnesses minted from the same inputs share the same `UorTime`.
8965    /// Compose with a `Calibration` via [`UorTime::min_wall_clock`] to
8966    /// bound the provable minimum wall-clock duration the computation required.
8967    #[inline]
8968    #[must_use]
8969    pub const fn uor_time(&self) -> UorTime {
8970        self.uor_time
8971    }
8972
8973    /// Phase A.2: the sealed triadic coordinate `(stratum, spectrum, address)` at the
8974    /// witness's Witt level, projected from the content-addressed unit.
8975    /// `stratum` is the v₂ valuation of the lower unit-address half; `spectrum`
8976    /// is the lower 64 bits of the unit address; `address` is the upper 64 bits.
8977    /// The projection is deterministic and content-addressed, so replay reproduces the
8978    /// same `Triad` bit-for-bit.
8979    #[inline]
8980    #[must_use]
8981    pub const fn triad(&self) -> Triad<T> {
8982        let addr = self.unit_address.as_u128();
8983        let addr_lo = addr as u64;
8984        let addr_hi = (addr >> 64) as u64;
8985        let stratum = if addr_lo == 0 {
8986            0u64
8987        } else {
8988            addr_lo.trailing_zeros() as u64
8989        };
8990        Triad::new(stratum, addr_lo, addr_hi)
8991    }
8992
8993    /// Crate-internal constructor used by the pipeline at mint time.
8994    /// Not callable from outside `uor-foundation`. The tag defaults to `T`
8995    /// (the unparameterized form); downstream attaches a custom tag via `tag()`.
8996    /// v0.2.2 T2.6 (cleanup): BaseMetric fields are computed here from
8997    /// the input witt level, bindings, and unit address. Two `Grounded`
8998    /// values built from the same inputs return identical metrics; two
8999    /// built from different inputs differ in at least three fields.
9000    #[inline]
9001    #[allow(dead_code)]
9002    pub(crate) const fn new_internal(
9003        validated: Validated<GroundingCertificate>,
9004        bindings: BindingsTable,
9005        witt_level_bits: u16,
9006        unit_address: ContentAddress,
9007        content_fingerprint: ContentFingerprint,
9008    ) -> Self {
9009        let bound_count = bindings.entries.len() as u32;
9010        let declared_sites = if witt_level_bits == 0 {
9011            1u32
9012        } else {
9013            witt_level_bits as u32
9014        };
9015        // sigma = bound / declared, in parts per million.
9016        let sigma_ppm = if bound_count >= declared_sites {
9017            1_000_000u32
9018        } else {
9019            // Integer division, rounded down, cannot exceed 1_000_000.
9020            let num = (bound_count as u64) * 1_000_000u64;
9021            (num / (declared_sites as u64)) as u32
9022        };
9023        // residual_count = declared - bound (saturating).
9024        let residual_count = declared_sites.saturating_sub(bound_count);
9025        // d_delta = witt_bits - bound_count (signed).
9026        let d_delta = (witt_level_bits as i64) - (bound_count as i64);
9027        // Betti numbers: β_0 = 1 (connected); β_k = bit k of witt_level_bits.
9028        let mut betti = [0u32; MAX_BETTI_DIMENSION];
9029        betti[0] = 1;
9030        let mut k = 1usize;
9031        while k < MAX_BETTI_DIMENSION {
9032            betti[k] = ((witt_level_bits as u32) >> (k - 1)) & 1;
9033            k += 1;
9034        }
9035        // Euler characteristic: alternating sum of Betti numbers.
9036        let mut euler: i64 = 0;
9037        let mut k = 0usize;
9038        while k < MAX_BETTI_DIMENSION {
9039            if k & 1 == 0 {
9040                euler += betti[k] as i64;
9041            } else {
9042                euler -= betti[k] as i64;
9043            }
9044            k += 1;
9045        }
9046        // Jacobian row: entry i = (unit_address.as_u128() as i64 XOR (i as i64)) mod witt+1.
9047        let mut jac = [0i64; JACOBIAN_MAX_SITES];
9048        let modulus = (witt_level_bits as i64) + 1;
9049        let ua_lo = unit_address.as_u128() as i64;
9050        let mut i = 0usize;
9051        let jac_len = if (witt_level_bits as usize) < JACOBIAN_MAX_SITES {
9052            witt_level_bits as usize
9053        } else {
9054            JACOBIAN_MAX_SITES
9055        };
9056        while i < jac_len {
9057            let raw = ua_lo ^ (i as i64);
9058            // Rust's % is remainder; ensure non-negative.
9059            let m = if modulus == 0 { 1 } else { modulus };
9060            jac[i] = ((raw % m) + m) % m;
9061            i += 1;
9062        }
9063        // Phase A.1: uor_time is content-deterministic. rewrite_steps counts
9064        // the reduction work proxied by (witt bits + bound count + active jac len);
9065        // Landauer nats = rewrite_steps × ln 2 (Landauer-temperature cost of
9066        // traversing that many orthogonal states). Two Grounded values minted from
9067        // the same inputs share the same UorTime.
9068        let steps = (witt_level_bits as u64) + (bound_count as u64) + (jac_len as u64);
9069        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
9070        let uor_time = UorTime::new(landauer, steps);
9071        Self {
9072            validated,
9073            bindings,
9074            witt_level_bits,
9075            unit_address,
9076            uor_time,
9077            sigma_ppm,
9078            d_delta,
9079            euler_characteristic: euler,
9080            residual_count,
9081            jacobian_entries: jac,
9082            jacobian_len: jac_len as u16,
9083            betti_numbers: betti,
9084            content_fingerprint,
9085            output_payload: [0u8; crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES],
9086            output_len: 0,
9087            _phantom: PhantomData,
9088            _tag: PhantomData,
9089        }
9090    }
9091
9092    /// Wiki ADR-028: crate-internal setter for the output-value payload.
9093    /// Called by `pipeline::run_route` after the catamorphism evaluates the
9094    /// Term tree per ADR-029. The bytes are copied into the on-stack
9095    /// buffer; bytes beyond `len` are zero-padded. Returns self for chaining.
9096    /// Panics if `bytes.len() > crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES`.
9097    #[inline]
9098    #[must_use]
9099    pub(crate) fn with_output_bytes(mut self, bytes: &[u8]) -> Self {
9100        let len = bytes.len();
9101        debug_assert!(len <= crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES);
9102        let copy_len = if len > crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES {
9103            crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES
9104        } else {
9105            len
9106        };
9107        let mut i = 0;
9108        while i < copy_len {
9109            self.output_payload[i] = bytes[i];
9110            i += 1;
9111        }
9112        self.output_len = copy_len as u16;
9113        self
9114    }
9115
9116    /// v0.2.2 T6.17: attach a downstream-validated `BindingsTable` to this
9117    /// grounded value. The original `Grounded` was minted by the foundation
9118    /// pipeline with a substrate-computed certificate; this builder lets
9119    /// downstream attach its own binding table without re-grounding.
9120    /// The `bindings` parameter must satisfy the sortedness invariant. Use
9121    /// [`BindingsTable::try_new`] to construct a validated table from a
9122    /// pre-sorted slice.
9123    /// **Trust boundary:** the certificate witnesses the unit's grounding,
9124    /// not the bindings' contents. A downstream consumer that uses the
9125    /// certificate as a trust root for the bindings is wrong.
9126    #[inline]
9127    #[must_use]
9128    pub fn with_bindings(self, bindings: BindingsTable) -> Self {
9129        Self { bindings, ..self }
9130    }
9131
9132    /// Wiki ADR-042: borrow `self` as an
9133    /// [`crate::pipeline::InhabitanceCertificateView`] over the canonical
9134    /// k-invariants branch's verdict envelope.
9135    /// Universal — available for any `Grounded<T, Tag>`; applications whose
9136    /// admission relations are not inhabitance questions simply don't
9137    /// call the typed accessors. The view is zero-cost
9138    /// (`#[repr(transparent)]` over `&'a Grounded<T, Tag>`).
9139    #[inline]
9140    #[must_use]
9141    pub fn as_inhabitance_certificate(
9142        &self,
9143    ) -> crate::pipeline::InhabitanceCertificateView<'_, T, Tag> {
9144        crate::pipeline::InhabitanceCertificateView(self)
9145    }
9146}
9147
9148/// v0.2.2 W8: triadic coordinate of a Datum at level `L`. Bundles the
9149/// (stratum, spectrum, address) projection in one structurally-enforced
9150/// type. No public constructor — `Triad<L>` is built only by foundation code
9151/// at grounding time. Field access goes through the named accessors.
9152#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9153pub struct Triad<L> {
9154    /// The stratum coordinate (two-adic valuation).
9155    stratum: u64,
9156    /// The spectrum coordinate (Walsh-Hadamard image).
9157    spectrum: u64,
9158    /// The address coordinate (Braille-glyph address).
9159    address: u64,
9160    /// Phantom marker for the Witt level.
9161    _level: PhantomData<L>,
9162}
9163
9164impl<L> Triad<L> {
9165    /// Returns the stratum component (`query:TwoAdicValuation` coordinate).
9166    #[inline]
9167    #[must_use]
9168    pub const fn stratum(&self) -> u64 {
9169        self.stratum
9170    }
9171
9172    /// Returns the spectrum component (`query:WalshHadamardImage` coordinate).
9173    #[inline]
9174    #[must_use]
9175    pub const fn spectrum(&self) -> u64 {
9176        self.spectrum
9177    }
9178
9179    /// Returns the address component (`query:Address` coordinate).
9180    #[inline]
9181    #[must_use]
9182    pub const fn address(&self) -> u64 {
9183        self.address
9184    }
9185
9186    /// Crate-internal constructor. Reachable only from grounding-time minting.
9187    #[inline]
9188    #[must_use]
9189    #[allow(dead_code)]
9190    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
9191        Self {
9192            stratum,
9193            spectrum,
9194            address,
9195            _level: PhantomData,
9196        }
9197    }
9198}
9199
9200/// The Rust-surface rendering of `reduction:PipelineFailureReason` and the
9201/// v0.2.1 cross-namespace failure variants. Variant set and field shapes are
9202/// generated parametrically by walking `reduction:FailureField` individuals;
9203/// adding a new field requires only an ontology edit.
9204///
9205/// # Wiki ADR-039 — Inhabitance verdict realization mapping
9206///
9207/// An `Err(PipelineFailure)` whose structural cause is "the constraint
9208/// nerve has empty Kan completion" realizes a `cert:InhabitanceImpossibilityCertificate`
9209/// envelope, carrying `proof:InhabitanceImpossibilityWitness` as the
9210/// proof payload with `proof:contradictionProof` as the canonical-form
9211/// encoding of the failure trace. The verdict mapping is the dual of
9212/// the `Grounded<Output>` → `cert:InhabitanceCertificate` mapping; the
9213/// two together realize the ontology's three-primitive inhabitance
9214/// verdict structure (success / impossibility-witnessed / unknown).
9215/// Ontology references:
9216/// `<https://uor.foundation/cert/InhabitanceImpossibilityCertificate>`,
9217/// `<https://uor.foundation/proof/InhabitanceImpossibilityWitness>`,
9218/// `<https://uor.foundation/proof/contradictionProof>`.
9219#[derive(Debug, Clone, PartialEq)]
9220#[non_exhaustive]
9221pub enum PipelineFailure {
9222    /// `DispatchMiss` failure variant.
9223    DispatchMiss {
9224        /// query_iri field.
9225        query_iri: &'static str,
9226        /// table_iri field.
9227        table_iri: &'static str,
9228    },
9229    /// `GroundingFailure` failure variant.
9230    GroundingFailure {
9231        /// reason_iri field.
9232        reason_iri: &'static str,
9233    },
9234    /// `ConvergenceStall` failure variant.
9235    ConvergenceStall {
9236        /// stage_iri field.
9237        stage_iri: &'static str,
9238        /// angle_milliradians field.
9239        angle_milliradians: i64,
9240    },
9241    /// `ContradictionDetected` failure variant.
9242    ContradictionDetected {
9243        /// at_step field.
9244        at_step: usize,
9245        /// trace_iri field.
9246        trace_iri: &'static str,
9247    },
9248    /// `CoherenceViolation` failure variant.
9249    CoherenceViolation {
9250        /// site_position field.
9251        site_position: usize,
9252        /// constraint_iri field.
9253        constraint_iri: &'static str,
9254    },
9255    /// `ShapeMismatch` failure variant.
9256    ShapeMismatch {
9257        /// expected field.
9258        expected: &'static str,
9259        /// got field.
9260        got: &'static str,
9261    },
9262    /// `LiftObstructionFailure` failure variant.
9263    LiftObstructionFailure {
9264        /// site_position field.
9265        site_position: usize,
9266        /// obstruction_class_iri field.
9267        obstruction_class_iri: &'static str,
9268    },
9269    /// `ShapeViolation` failure variant.
9270    ShapeViolation {
9271        /// report field.
9272        report: ShapeViolation,
9273    },
9274}
9275
9276impl core::fmt::Display for PipelineFailure {
9277    fn fmt(&self, ff: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9278        match self {
9279            Self::DispatchMiss {
9280                query_iri,
9281                table_iri,
9282            } => write!(
9283                ff,
9284                "DispatchMiss(query_iri={:?}, table_iri={:?})",
9285                query_iri, table_iri
9286            ),
9287            Self::GroundingFailure { reason_iri } => {
9288                write!(ff, "GroundingFailure(reason_iri={:?})", reason_iri)
9289            }
9290            Self::ConvergenceStall {
9291                stage_iri,
9292                angle_milliradians,
9293            } => write!(
9294                ff,
9295                "ConvergenceStall(stage_iri={:?}, angle_milliradians={:?})",
9296                stage_iri, angle_milliradians
9297            ),
9298            Self::ContradictionDetected { at_step, trace_iri } => write!(
9299                ff,
9300                "ContradictionDetected(at_step={:?}, trace_iri={:?})",
9301                at_step, trace_iri
9302            ),
9303            Self::CoherenceViolation {
9304                site_position,
9305                constraint_iri,
9306            } => write!(
9307                ff,
9308                "CoherenceViolation(site_position={:?}, constraint_iri={:?})",
9309                site_position, constraint_iri
9310            ),
9311            Self::ShapeMismatch { expected, got } => {
9312                write!(ff, "ShapeMismatch(expected={:?}, got={:?})", expected, got)
9313            }
9314            Self::LiftObstructionFailure {
9315                site_position,
9316                obstruction_class_iri,
9317            } => write!(
9318                ff,
9319                "LiftObstructionFailure(site_position={:?}, obstruction_class_iri={:?})",
9320                site_position, obstruction_class_iri
9321            ),
9322            Self::ShapeViolation { report } => write!(ff, "ShapeViolation({:?})", report),
9323        }
9324    }
9325}
9326
9327impl core::error::Error for PipelineFailure {}
9328
9329/// Sealed marker for impossibility witnesses returned by the resolver
9330/// free-function path. Every failure return value of every
9331/// `resolver::<name>::certify(...)` call is a member of this set.
9332pub trait ImpossibilityWitnessKind: impossibility_witness_kind_sealed::Sealed {}
9333
9334mod impossibility_witness_kind_sealed {
9335    /// Private supertrait.
9336    pub trait Sealed {}
9337    impl Sealed for super::GenericImpossibilityWitness {}
9338    impl Sealed for super::InhabitanceImpossibilityWitness {}
9339}
9340
9341impl ImpossibilityWitnessKind for GenericImpossibilityWitness {}
9342impl ImpossibilityWitnessKind for InhabitanceImpossibilityWitness {}
9343
9344/// v0.2.2 W12: resolver free functions. Replaces the v0.2.1 unit-struct
9345/// façades with module-per-resolver free functions returning the W11
9346/// `Certified<C>` parametric carrier.
9347pub mod resolver {
9348    use super::{
9349        BornRuleVerification,
9350        Certified,
9351        CompileUnit,
9352        CompletenessCertificate,
9353        GenericImpossibilityWitness,
9354        GeodesicCertificate,
9355        GroundingCertificate,
9356        InhabitanceCertificate,
9357        InhabitanceImpossibilityWitness,
9358        InvolutionCertificate,
9359        IsometryCertificate,
9360        LiftChainCertificate,
9361        MeasurementCertificate,
9362        // Phase X.1: per-resolver cert discrimination.
9363        TransformCertificate,
9364        Validated,
9365        WittLevel,
9366    };
9367
9368    /// v0.2.2 W12: certify tower-completeness for a constrained type.
9369    ///
9370    /// Replaces `TowerCompletenessResolver::new().certify(input)` from v0.2.1.
9371    /// Delegates to `crate::pipeline::run_tower_completeness` and wraps the
9372    /// returned `LiftChainCertificate` in the W11 `Certified<_>` carrier.
9373    ///
9374    /// # Errors
9375    ///
9376    /// Returns `GenericImpossibilityWitness` when no certificate can be issued.
9377    pub mod tower_completeness {
9378        use super::*;
9379        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9380        ///
9381        /// # Errors
9382        ///
9383        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9384        pub fn certify<T, P, H>(
9385            input: &Validated<T, P>,
9386        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9387        where
9388            T: crate::pipeline::ConstrainedTypeShape,
9389            P: crate::enforcement::ValidationPhase,
9390            H: crate::enforcement::Hasher,
9391        {
9392            certify_at::<T, P, H>(input, WittLevel::W32)
9393        }
9394
9395        /// Certify at an explicit Witt level.
9396        ///
9397        /// # Errors
9398        ///
9399        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9400        pub fn certify_at<T, P, H>(
9401            input: &Validated<T, P>,
9402            level: WittLevel,
9403        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9404        where
9405            T: crate::pipeline::ConstrainedTypeShape,
9406            P: crate::enforcement::ValidationPhase,
9407            H: crate::enforcement::Hasher,
9408        {
9409            crate::pipeline::run_tower_completeness::<T, H>(input.inner(), level)
9410                .map(|v| Certified::new(*v.inner()))
9411                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9412        }
9413    }
9414
9415    /// v0.2.2 closure: certify incremental completeness for a constrained type.
9416    pub mod incremental_completeness {
9417        use super::*;
9418        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9419        ///
9420        /// # Errors
9421        ///
9422        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9423        pub fn certify<T, P, H>(
9424            input: &Validated<T, P>,
9425        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9426        where
9427            T: crate::pipeline::ConstrainedTypeShape,
9428            P: crate::enforcement::ValidationPhase,
9429            H: crate::enforcement::Hasher,
9430        {
9431            certify_at::<T, P, H>(input, WittLevel::W32)
9432        }
9433
9434        /// Certify at an explicit Witt level.
9435        ///
9436        /// # Errors
9437        ///
9438        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9439        pub fn certify_at<T, P, H>(
9440            input: &Validated<T, P>,
9441            level: WittLevel,
9442        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9443        where
9444            T: crate::pipeline::ConstrainedTypeShape,
9445            P: crate::enforcement::ValidationPhase,
9446            H: crate::enforcement::Hasher,
9447        {
9448            crate::pipeline::run_incremental_completeness::<T, H>(input.inner(), level)
9449                .map(|v| Certified::new(*v.inner()))
9450                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9451        }
9452    }
9453
9454    /// v0.2.2 closure: certify grounding-aware reduction for a CompileUnit.
9455    pub mod grounding_aware {
9456        use super::*;
9457        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9458        ///
9459        /// # Errors
9460        ///
9461        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9462        pub fn certify<P, H>(
9463            input: &Validated<CompileUnit, P>,
9464        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9465        where
9466            P: crate::enforcement::ValidationPhase,
9467            H: crate::enforcement::Hasher,
9468        {
9469            certify_at::<P, H>(input, WittLevel::W32)
9470        }
9471
9472        /// Certify at an explicit Witt level.
9473        ///
9474        /// # Errors
9475        ///
9476        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9477        pub fn certify_at<P, H>(
9478            input: &Validated<CompileUnit, P>,
9479            level: WittLevel,
9480        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9481        where
9482            P: crate::enforcement::ValidationPhase,
9483            H: crate::enforcement::Hasher,
9484        {
9485            crate::pipeline::run_grounding_aware::<H>(input.inner(), level)
9486                .map(|v| Certified::new(*v.inner()))
9487                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9488        }
9489    }
9490
9491    /// v0.2.2 closure: certify inhabitance for a constrained type.
9492    pub mod inhabitance {
9493        use super::*;
9494        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9495        ///
9496        /// # Errors
9497        ///
9498        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9499        pub fn certify<T, P, H>(
9500            input: &Validated<T, P>,
9501        ) -> Result<Certified<InhabitanceCertificate>, Certified<InhabitanceImpossibilityWitness>>
9502        where
9503            T: crate::pipeline::ConstrainedTypeShape,
9504            P: crate::enforcement::ValidationPhase,
9505            H: crate::enforcement::Hasher,
9506        {
9507            certify_at::<T, P, H>(input, WittLevel::W32)
9508        }
9509
9510        /// Certify at an explicit Witt level.
9511        ///
9512        /// # Errors
9513        ///
9514        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9515        pub fn certify_at<T, P, H>(
9516            input: &Validated<T, P>,
9517            level: WittLevel,
9518        ) -> Result<Certified<InhabitanceCertificate>, Certified<InhabitanceImpossibilityWitness>>
9519        where
9520            T: crate::pipeline::ConstrainedTypeShape,
9521            P: crate::enforcement::ValidationPhase,
9522            H: crate::enforcement::Hasher,
9523        {
9524            crate::pipeline::run_inhabitance::<T, H>(input.inner(), level)
9525                .map(|v: Validated<InhabitanceCertificate>| Certified::new(*v.inner()))
9526                .map_err(|_| Certified::new(InhabitanceImpossibilityWitness::default()))
9527        }
9528    }
9529
9530    /// v0.2.2 Phase C.4: multiplication resolver — picks the cost-optimal
9531    /// Toom-Cook splitting factor R for a `Datum<L>` × `Datum<L>`
9532    /// multiplication at a given call-site context. The cost function is
9533    /// closed-form and grounded in `op:OA_5`:
9534    ///
9535    /// ```text
9536    /// sub_mul_count(N, R) = (2R - 1)  for R > 1
9537    ///                     = 1         for R = 1 (schoolbook)
9538    /// landauer_cost(N, R) = sub_mul_count(N, R) · (N/R)² · 64 · ln 2  nats
9539    /// ```
9540    pub mod multiplication {
9541        use super::super::{MulContext, MultiplicationCertificate};
9542        use super::*;
9543
9544        /// v0.2.2 T6.7: parameterized over `H: Hasher`. Pick the cost-optimal
9545        /// splitting factor R for a multiplication at the given call-site
9546        /// context and return a `Certified<MultiplicationCertificate>`
9547        /// recording the choice. The certificate carries a substrate-computed
9548        /// content fingerprint.
9549        ///
9550        /// # Errors
9551        ///
9552        /// Returns `GenericImpossibilityWitness` if the call-site context is
9553        /// inadmissible (`stack_budget_bytes == 0`). The resolver is otherwise
9554        /// total over admissible inputs.
9555        pub fn certify<H: crate::enforcement::Hasher>(
9556            context: &MulContext,
9557        ) -> Result<Certified<MultiplicationCertificate>, GenericImpossibilityWitness> {
9558            if context.stack_budget_bytes == 0 {
9559                return Err(GenericImpossibilityWitness::default());
9560            }
9561            // Closed-form cost search: R = 1 (schoolbook) vs R = 2 (Karatsuba).
9562            let limb_count = context.limb_count.max(1);
9563            let karatsuba_stack_need = limb_count * 8 * 6;
9564            let choose_karatsuba = !context.const_eval
9565                && (context.stack_budget_bytes as usize) >= karatsuba_stack_need;
9566            // v0.2.2 T6.7: compute substrate fingerprint over the MulContext.
9567            let mut hasher = H::initial();
9568            hasher = hasher.fold_bytes(&context.stack_budget_bytes.to_be_bytes());
9569            hasher = hasher.fold_byte(if context.const_eval { 1 } else { 0 });
9570            hasher = hasher.fold_bytes(&(limb_count as u64).to_be_bytes());
9571            hasher = hasher.fold_byte(crate::enforcement::certificate_kind_discriminant(
9572                crate::enforcement::CertificateKind::Multiplication,
9573            ));
9574            let buffer = hasher.finalize();
9575            let fp =
9576                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9577            let cert = if choose_karatsuba {
9578                MultiplicationCertificate::with_evidence(
9579                    2,
9580                    3,
9581                    karatsuba_landauer_cost(limb_count),
9582                    fp,
9583                )
9584            } else {
9585                MultiplicationCertificate::with_evidence(
9586                    1,
9587                    1,
9588                    schoolbook_landauer_cost(limb_count),
9589                    fp,
9590                )
9591            };
9592            Ok(Certified::new(cert))
9593        }
9594
9595        // Local default-host alias for the Landauer cost helpers below.
9596        type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
9597
9598        /// Schoolbook Landauer cost in nats for an N-limb multiplication:
9599        /// `N² · 64 · ln 2`. Returns the IEEE-754 bit pattern;
9600        /// see `MultiplicationEvidence::landauer_cost_nats_bits`.
9601        fn schoolbook_landauer_cost(limb_count: usize) -> u64 {
9602            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
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            (n * n * sixty_four * ln_2).to_bits()
9607        }
9608
9609        /// Karatsuba Landauer cost: `3 · (N/2)² · 64 · ln 2`.
9610        /// Returns the IEEE-754 bit pattern.
9611        fn karatsuba_landauer_cost(limb_count: usize) -> u64 {
9612            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9613            let two = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(2);
9614            let three = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(3);
9615            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9616            let ln_2 =
9617                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9618            let n_half = n / two;
9619            (three * n_half * n_half * sixty_four * ln_2).to_bits()
9620        }
9621    }
9622
9623    /// v0.2.2 Phase C: `pub(crate)` trait parameterizing the 15 Phase D resolver kernels.
9624    /// Each kernel marker supplies a `CertificateKind` discriminant and its
9625    /// ontology-declared certificate type via `type Cert`. The shared
9626    /// `certify_at` bodies (see `emit_phase_d_ct_body` / `emit_phase_d_cu_body`)
9627    /// mint `Certified<Kernel::Cert>` directly — so each resolver's cert class
9628    /// matches its `resolver:CertifyMapping` in the ontology.
9629    pub(crate) trait ResolverKernel {
9630        const KIND: crate::enforcement::CertificateKind;
9631        /// Phase X.1: the ontology-declared certificate class produced by
9632        /// this resolver (per `resolver:CertifyMapping`).
9633        type Cert: crate::enforcement::Certificate;
9634    }
9635
9636    /// 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.
9637    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9638    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9639    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9640    /// failure — the witness itself is certified so downstream can persist it
9641    /// alongside success certs in a uniform `Certified<_>` channel.
9642    /// Phase X.1: the produced cert class is the ontology-declared class for
9643    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9644    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9645    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9646    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9647    /// kernels so each resolver's class discrimination is load-bearing.
9648    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9649    /// kernel's composition spec) whose output is folded into the canonical
9650    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9651    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9652    /// content-addressed per its ontology class.
9653    pub mod two_sat_decider {
9654        use super::*;
9655
9656        #[doc(hidden)]
9657        pub struct Kernel;
9658        impl super::ResolverKernel for Kernel {
9659            type Cert = crate::enforcement::GroundingCertificate;
9660            const KIND: crate::enforcement::CertificateKind =
9661                crate::enforcement::CertificateKind::TwoSat;
9662        }
9663
9664        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9665        ///
9666        /// # Errors
9667        ///
9668        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9669        pub fn certify<
9670            T: crate::pipeline::ConstrainedTypeShape,
9671            P: crate::enforcement::ValidationPhase,
9672            H: crate::enforcement::Hasher,
9673        >(
9674            input: &Validated<T, P>,
9675        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9676        {
9677            certify_at::<T, P, H>(input, WittLevel::W32)
9678        }
9679
9680        /// Phase D (target §4.2): certify at an explicit Witt level.
9681        ///
9682        /// # Errors
9683        ///
9684        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9685        pub fn certify_at<
9686            T: crate::pipeline::ConstrainedTypeShape,
9687            P: crate::enforcement::ValidationPhase,
9688            H: crate::enforcement::Hasher,
9689        >(
9690            input: &Validated<T, P>,
9691            level: WittLevel,
9692        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9693        {
9694            let _ = input.inner();
9695            let witt_bits = level.witt_length() as u16;
9696            let (tr_bits, tr_constraints, tr_sat) =
9697                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9698                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9699            if tr_sat == 0 {
9700                return Err(Certified::new(GenericImpossibilityWitness::default()));
9701            }
9702            let mut hasher = H::initial();
9703            hasher = crate::enforcement::fold_terminal_reduction(
9704                hasher,
9705                tr_bits,
9706                tr_constraints,
9707                tr_sat,
9708            );
9709            hasher = crate::enforcement::fold_unit_digest(
9710                hasher,
9711                witt_bits,
9712                witt_bits as u64,
9713                T::IRI,
9714                T::SITE_COUNT,
9715                T::CONSTRAINTS,
9716                <Kernel as super::ResolverKernel>::KIND,
9717            );
9718            let buffer = hasher.finalize();
9719            let fp =
9720                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9721            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9722            Ok(Certified::new(cert))
9723        }
9724    }
9725
9726    /// Phase D (target §4.2): `resolver:HornSatDecider` — certify that `predicate:IsHornShape` inputs are Horn-SAT-decidable via unit propagation (O(n+m)).
9727    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9728    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9729    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9730    /// failure — the witness itself is certified so downstream can persist it
9731    /// alongside success certs in a uniform `Certified<_>` channel.
9732    /// Phase X.1: the produced cert class is the ontology-declared class for
9733    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9734    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9735    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9736    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9737    /// kernels so each resolver's class discrimination is load-bearing.
9738    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9739    /// kernel's composition spec) whose output is folded into the canonical
9740    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9741    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9742    /// content-addressed per its ontology class.
9743    pub mod horn_sat_decider {
9744        use super::*;
9745
9746        #[doc(hidden)]
9747        pub struct Kernel;
9748        impl super::ResolverKernel for Kernel {
9749            type Cert = crate::enforcement::GroundingCertificate;
9750            const KIND: crate::enforcement::CertificateKind =
9751                crate::enforcement::CertificateKind::HornSat;
9752        }
9753
9754        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9755        ///
9756        /// # Errors
9757        ///
9758        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9759        pub fn certify<
9760            T: crate::pipeline::ConstrainedTypeShape,
9761            P: crate::enforcement::ValidationPhase,
9762            H: crate::enforcement::Hasher,
9763        >(
9764            input: &Validated<T, P>,
9765        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9766        {
9767            certify_at::<T, P, H>(input, WittLevel::W32)
9768        }
9769
9770        /// Phase D (target §4.2): certify at an explicit Witt level.
9771        ///
9772        /// # Errors
9773        ///
9774        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9775        pub fn certify_at<
9776            T: crate::pipeline::ConstrainedTypeShape,
9777            P: crate::enforcement::ValidationPhase,
9778            H: crate::enforcement::Hasher,
9779        >(
9780            input: &Validated<T, P>,
9781            level: WittLevel,
9782        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9783        {
9784            let _ = input.inner();
9785            let witt_bits = level.witt_length() as u16;
9786            let (tr_bits, tr_constraints, tr_sat) =
9787                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9788                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9789            if tr_sat == 0 {
9790                return Err(Certified::new(GenericImpossibilityWitness::default()));
9791            }
9792            let mut hasher = H::initial();
9793            hasher = crate::enforcement::fold_terminal_reduction(
9794                hasher,
9795                tr_bits,
9796                tr_constraints,
9797                tr_sat,
9798            );
9799            hasher = crate::enforcement::fold_unit_digest(
9800                hasher,
9801                witt_bits,
9802                witt_bits as u64,
9803                T::IRI,
9804                T::SITE_COUNT,
9805                T::CONSTRAINTS,
9806                <Kernel as super::ResolverKernel>::KIND,
9807            );
9808            let buffer = hasher.finalize();
9809            let fp =
9810                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9811            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9812            Ok(Certified::new(cert))
9813        }
9814    }
9815
9816    /// 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).
9817    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9818    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9819    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9820    /// failure — the witness itself is certified so downstream can persist it
9821    /// alongside success certs in a uniform `Certified<_>` channel.
9822    /// Phase X.1: the produced cert class is the ontology-declared class for
9823    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9824    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9825    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9826    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9827    /// kernels so each resolver's class discrimination is load-bearing.
9828    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9829    /// kernel's composition spec) whose output is folded into the canonical
9830    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9831    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9832    /// content-addressed per its ontology class.
9833    pub mod residual_verdict {
9834        use super::*;
9835
9836        #[doc(hidden)]
9837        pub struct Kernel;
9838        impl super::ResolverKernel for Kernel {
9839            type Cert = crate::enforcement::GroundingCertificate;
9840            const KIND: crate::enforcement::CertificateKind =
9841                crate::enforcement::CertificateKind::ResidualVerdict;
9842        }
9843
9844        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9845        ///
9846        /// # Errors
9847        ///
9848        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9849        pub fn certify<
9850            T: crate::pipeline::ConstrainedTypeShape,
9851            P: crate::enforcement::ValidationPhase,
9852            H: crate::enforcement::Hasher,
9853        >(
9854            input: &Validated<T, P>,
9855        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9856        {
9857            certify_at::<T, P, H>(input, WittLevel::W32)
9858        }
9859
9860        /// Phase D (target §4.2): certify at an explicit Witt level.
9861        ///
9862        /// # Errors
9863        ///
9864        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9865        pub fn certify_at<
9866            T: crate::pipeline::ConstrainedTypeShape,
9867            P: crate::enforcement::ValidationPhase,
9868            H: crate::enforcement::Hasher,
9869        >(
9870            input: &Validated<T, P>,
9871            level: WittLevel,
9872        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9873        {
9874            let _ = input.inner();
9875            let witt_bits = level.witt_length() as u16;
9876            let (tr_bits, tr_constraints, tr_sat) =
9877                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9878                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9879            if tr_sat == 0 {
9880                return Err(Certified::new(GenericImpossibilityWitness::default()));
9881            }
9882            let mut hasher = H::initial();
9883            hasher = crate::enforcement::fold_terminal_reduction(
9884                hasher,
9885                tr_bits,
9886                tr_constraints,
9887                tr_sat,
9888            );
9889            hasher = crate::enforcement::fold_unit_digest(
9890                hasher,
9891                witt_bits,
9892                witt_bits as u64,
9893                T::IRI,
9894                T::SITE_COUNT,
9895                T::CONSTRAINTS,
9896                <Kernel as super::ResolverKernel>::KIND,
9897            );
9898            let buffer = hasher.finalize();
9899            let fp =
9900                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9901            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9902            Ok(Certified::new(cert))
9903        }
9904    }
9905
9906    /// 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.
9907    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
9908    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9909    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9910    /// failure — the witness itself is certified so downstream can persist it
9911    /// alongside success certs in a uniform `Certified<_>` channel.
9912    /// Phase X.1: the produced cert class is the ontology-declared class for
9913    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9914    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9915    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9916    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9917    /// kernels so each resolver's class discrimination is load-bearing.
9918    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9919    /// kernel's composition spec) whose output is folded into the canonical
9920    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9921    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9922    /// content-addressed per its ontology class.
9923    pub mod canonical_form {
9924        use super::*;
9925
9926        #[doc(hidden)]
9927        pub struct Kernel;
9928        impl super::ResolverKernel for Kernel {
9929            type Cert = crate::enforcement::TransformCertificate;
9930            const KIND: crate::enforcement::CertificateKind =
9931                crate::enforcement::CertificateKind::CanonicalForm;
9932        }
9933
9934        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9935        ///
9936        /// # Errors
9937        ///
9938        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9939        pub fn certify<
9940            T: crate::pipeline::ConstrainedTypeShape,
9941            P: crate::enforcement::ValidationPhase,
9942            H: crate::enforcement::Hasher,
9943        >(
9944            input: &Validated<T, P>,
9945        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
9946        {
9947            certify_at::<T, P, H>(input, WittLevel::W32)
9948        }
9949
9950        /// Phase D (target §4.2): certify at an explicit Witt level.
9951        ///
9952        /// # Errors
9953        ///
9954        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9955        pub fn certify_at<
9956            T: crate::pipeline::ConstrainedTypeShape,
9957            P: crate::enforcement::ValidationPhase,
9958            H: crate::enforcement::Hasher,
9959        >(
9960            input: &Validated<T, P>,
9961            level: WittLevel,
9962        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
9963        {
9964            let _ = input.inner();
9965            let witt_bits = level.witt_length() as u16;
9966            let (tr_bits, tr_constraints, tr_sat) =
9967                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9968                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9969            if tr_sat == 0 {
9970                return Err(Certified::new(GenericImpossibilityWitness::default()));
9971            }
9972            let mut hasher = H::initial();
9973            hasher = crate::enforcement::fold_terminal_reduction(
9974                hasher,
9975                tr_bits,
9976                tr_constraints,
9977                tr_sat,
9978            );
9979            let (tr2_bits, tr2_constraints, tr2_sat) =
9980                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9981                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9982            // Church-Rosser: second reduction must agree with the first.
9983            if tr2_bits != tr_bits || tr2_constraints != tr_constraints || tr2_sat != tr_sat {
9984                return Err(Certified::new(GenericImpossibilityWitness::default()));
9985            }
9986            hasher = crate::enforcement::fold_terminal_reduction(
9987                hasher,
9988                tr2_bits,
9989                tr2_constraints,
9990                tr2_sat,
9991            );
9992            hasher = crate::enforcement::fold_unit_digest(
9993                hasher,
9994                witt_bits,
9995                witt_bits as u64,
9996                T::IRI,
9997                T::SITE_COUNT,
9998                T::CONSTRAINTS,
9999                <Kernel as super::ResolverKernel>::KIND,
10000            );
10001            let buffer = hasher.finalize();
10002            let fp =
10003                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10004            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10005            Ok(Certified::new(cert))
10006        }
10007    }
10008
10009    /// 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.
10010    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10011    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10012    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10013    /// failure — the witness itself is certified so downstream can persist it
10014    /// alongside success certs in a uniform `Certified<_>` channel.
10015    /// Phase X.1: the produced cert class is the ontology-declared class for
10016    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10017    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10018    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10019    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10020    /// kernels so each resolver's class discrimination is load-bearing.
10021    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10022    /// kernel's composition spec) whose output is folded into the canonical
10023    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10024    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10025    /// content-addressed per its ontology class.
10026    pub mod type_synthesis {
10027        use super::*;
10028
10029        #[doc(hidden)]
10030        pub struct Kernel;
10031        impl super::ResolverKernel for Kernel {
10032            type Cert = crate::enforcement::TransformCertificate;
10033            const KIND: crate::enforcement::CertificateKind =
10034                crate::enforcement::CertificateKind::TypeSynthesis;
10035        }
10036
10037        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10038        ///
10039        /// # Errors
10040        ///
10041        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10042        pub fn certify<
10043            T: crate::pipeline::ConstrainedTypeShape,
10044            P: crate::enforcement::ValidationPhase,
10045            H: crate::enforcement::Hasher,
10046        >(
10047            input: &Validated<T, P>,
10048        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10049        {
10050            certify_at::<T, P, H>(input, WittLevel::W32)
10051        }
10052
10053        /// Phase D (target §4.2): certify at an explicit Witt level.
10054        ///
10055        /// # Errors
10056        ///
10057        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10058        pub fn certify_at<
10059            T: crate::pipeline::ConstrainedTypeShape,
10060            P: crate::enforcement::ValidationPhase,
10061            H: crate::enforcement::Hasher,
10062        >(
10063            input: &Validated<T, P>,
10064            level: WittLevel,
10065        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10066        {
10067            let _ = input.inner();
10068            let witt_bits = level.witt_length() as u16;
10069            let (tr_bits, tr_constraints, tr_sat) =
10070                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10071                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10072            if tr_sat == 0 {
10073                return Err(Certified::new(GenericImpossibilityWitness::default()));
10074            }
10075            let mut hasher = H::initial();
10076            hasher = crate::enforcement::fold_terminal_reduction(
10077                hasher,
10078                tr_bits,
10079                tr_constraints,
10080                tr_sat,
10081            );
10082            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10083                .map_err(crate::enforcement::Certified::new)?;
10084            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10085            let (residual, entropy) = crate::enforcement::primitive_descent_metrics::<T>(&betti);
10086            hasher = crate::enforcement::fold_descent_metrics(hasher, residual, entropy);
10087            hasher = crate::enforcement::fold_unit_digest(
10088                hasher,
10089                witt_bits,
10090                witt_bits as u64,
10091                T::IRI,
10092                T::SITE_COUNT,
10093                T::CONSTRAINTS,
10094                <Kernel as super::ResolverKernel>::KIND,
10095            );
10096            let buffer = hasher.finalize();
10097            let fp =
10098                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10099            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10100            Ok(Certified::new(cert))
10101        }
10102    }
10103
10104    /// 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.
10105    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10106    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10107    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10108    /// failure — the witness itself is certified so downstream can persist it
10109    /// alongside success certs in a uniform `Certified<_>` channel.
10110    /// Phase X.1: the produced cert class is the ontology-declared class for
10111    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10112    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10113    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10114    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10115    /// kernels so each resolver's class discrimination is load-bearing.
10116    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10117    /// kernel's composition spec) whose output is folded into the canonical
10118    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10119    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10120    /// content-addressed per its ontology class.
10121    pub mod homotopy {
10122        use super::*;
10123
10124        #[doc(hidden)]
10125        pub struct Kernel;
10126        impl super::ResolverKernel for Kernel {
10127            type Cert = crate::enforcement::TransformCertificate;
10128            const KIND: crate::enforcement::CertificateKind =
10129                crate::enforcement::CertificateKind::Homotopy;
10130        }
10131
10132        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10133        ///
10134        /// # Errors
10135        ///
10136        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10137        pub fn certify<
10138            T: crate::pipeline::ConstrainedTypeShape,
10139            P: crate::enforcement::ValidationPhase,
10140            H: crate::enforcement::Hasher,
10141        >(
10142            input: &Validated<T, P>,
10143        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10144        {
10145            certify_at::<T, P, H>(input, WittLevel::W32)
10146        }
10147
10148        /// Phase D (target §4.2): certify at an explicit Witt level.
10149        ///
10150        /// # Errors
10151        ///
10152        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10153        pub fn certify_at<
10154            T: crate::pipeline::ConstrainedTypeShape,
10155            P: crate::enforcement::ValidationPhase,
10156            H: crate::enforcement::Hasher,
10157        >(
10158            input: &Validated<T, P>,
10159            level: WittLevel,
10160        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10161        {
10162            let _ = input.inner();
10163            let witt_bits = level.witt_length() as u16;
10164            let (tr_bits, tr_constraints, tr_sat) =
10165                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10166                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10167            if tr_sat == 0 {
10168                return Err(Certified::new(GenericImpossibilityWitness::default()));
10169            }
10170            let mut hasher = H::initial();
10171            hasher = crate::enforcement::fold_terminal_reduction(
10172                hasher,
10173                tr_bits,
10174                tr_constraints,
10175                tr_sat,
10176            );
10177            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10178                .map_err(crate::enforcement::Certified::new)?;
10179            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10180            hasher = crate::enforcement::fold_unit_digest(
10181                hasher,
10182                witt_bits,
10183                witt_bits as u64,
10184                T::IRI,
10185                T::SITE_COUNT,
10186                T::CONSTRAINTS,
10187                <Kernel as super::ResolverKernel>::KIND,
10188            );
10189            let buffer = hasher.finalize();
10190            let fp =
10191                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10192            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10193            Ok(Certified::new(cert))
10194        }
10195    }
10196
10197    /// Phase D (target §4.2): `resolver:MonodromyResolver` — compute monodromy-group observables by tracing the constraint-nerve boundary cycles at the input's Witt level.
10198    /// Returns `Certified<IsometryCertificate>` on success carrying the Witt
10199    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10200    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10201    /// failure — the witness itself is certified so downstream can persist it
10202    /// alongside success certs in a uniform `Certified<_>` channel.
10203    /// Phase X.1: the produced cert class is the ontology-declared class for
10204    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10205    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10206    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10207    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10208    /// kernels so each resolver's class discrimination is load-bearing.
10209    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10210    /// kernel's composition spec) whose output is folded into the canonical
10211    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10212    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10213    /// content-addressed per its ontology class.
10214    pub mod monodromy {
10215        use super::*;
10216
10217        #[doc(hidden)]
10218        pub struct Kernel;
10219        impl super::ResolverKernel for Kernel {
10220            type Cert = crate::enforcement::IsometryCertificate;
10221            const KIND: crate::enforcement::CertificateKind =
10222                crate::enforcement::CertificateKind::Monodromy;
10223        }
10224
10225        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10226        ///
10227        /// # Errors
10228        ///
10229        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10230        pub fn certify<
10231            T: crate::pipeline::ConstrainedTypeShape,
10232            P: crate::enforcement::ValidationPhase,
10233            H: crate::enforcement::Hasher,
10234        >(
10235            input: &Validated<T, P>,
10236        ) -> Result<Certified<IsometryCertificate>, Certified<GenericImpossibilityWitness>>
10237        {
10238            certify_at::<T, P, H>(input, WittLevel::W32)
10239        }
10240
10241        /// Phase D (target §4.2): certify at an explicit Witt level.
10242        ///
10243        /// # Errors
10244        ///
10245        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10246        pub fn certify_at<
10247            T: crate::pipeline::ConstrainedTypeShape,
10248            P: crate::enforcement::ValidationPhase,
10249            H: crate::enforcement::Hasher,
10250        >(
10251            input: &Validated<T, P>,
10252            level: WittLevel,
10253        ) -> Result<Certified<IsometryCertificate>, Certified<GenericImpossibilityWitness>>
10254        {
10255            let _ = input.inner();
10256            let witt_bits = level.witt_length() as u16;
10257            let (tr_bits, tr_constraints, tr_sat) =
10258                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10259                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10260            if tr_sat == 0 {
10261                return Err(Certified::new(GenericImpossibilityWitness::default()));
10262            }
10263            let mut hasher = H::initial();
10264            hasher = crate::enforcement::fold_terminal_reduction(
10265                hasher,
10266                tr_bits,
10267                tr_constraints,
10268                tr_sat,
10269            );
10270            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10271                .map_err(crate::enforcement::Certified::new)?;
10272            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10273            let (orbit_size, representative) =
10274                crate::enforcement::primitive_dihedral_signature::<T>();
10275            hasher =
10276                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
10277            hasher = crate::enforcement::fold_unit_digest(
10278                hasher,
10279                witt_bits,
10280                witt_bits as u64,
10281                T::IRI,
10282                T::SITE_COUNT,
10283                T::CONSTRAINTS,
10284                <Kernel as super::ResolverKernel>::KIND,
10285            );
10286            let buffer = hasher.finalize();
10287            let fp =
10288                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10289            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10290            Ok(Certified::new(cert))
10291        }
10292    }
10293
10294    /// Phase D (target §4.2): `resolver:ModuliResolver` — compute the local moduli-space structure at a `CompleteType`: DeformationComplex, HolonomyStratum, tangent/obstruction dimensions.
10295    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10296    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10297    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10298    /// failure — the witness itself is certified so downstream can persist it
10299    /// alongside success certs in a uniform `Certified<_>` channel.
10300    /// Phase X.1: the produced cert class is the ontology-declared class for
10301    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10302    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10303    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10304    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10305    /// kernels so each resolver's class discrimination is load-bearing.
10306    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10307    /// kernel's composition spec) whose output is folded into the canonical
10308    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10309    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10310    /// content-addressed per its ontology class.
10311    pub mod moduli {
10312        use super::*;
10313
10314        #[doc(hidden)]
10315        pub struct Kernel;
10316        impl super::ResolverKernel for Kernel {
10317            type Cert = crate::enforcement::TransformCertificate;
10318            const KIND: crate::enforcement::CertificateKind =
10319                crate::enforcement::CertificateKind::Moduli;
10320        }
10321
10322        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10323        ///
10324        /// # Errors
10325        ///
10326        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10327        pub fn certify<
10328            T: crate::pipeline::ConstrainedTypeShape,
10329            P: crate::enforcement::ValidationPhase,
10330            H: crate::enforcement::Hasher,
10331        >(
10332            input: &Validated<T, P>,
10333        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10334        {
10335            certify_at::<T, P, H>(input, WittLevel::W32)
10336        }
10337
10338        /// Phase D (target §4.2): certify at an explicit Witt level.
10339        ///
10340        /// # Errors
10341        ///
10342        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10343        pub fn certify_at<
10344            T: crate::pipeline::ConstrainedTypeShape,
10345            P: crate::enforcement::ValidationPhase,
10346            H: crate::enforcement::Hasher,
10347        >(
10348            input: &Validated<T, P>,
10349            level: WittLevel,
10350        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10351        {
10352            let _ = input.inner();
10353            let witt_bits = level.witt_length() as u16;
10354            let (tr_bits, tr_constraints, tr_sat) =
10355                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10356                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10357            if tr_sat == 0 {
10358                return Err(Certified::new(GenericImpossibilityWitness::default()));
10359            }
10360            let mut hasher = H::initial();
10361            hasher = crate::enforcement::fold_terminal_reduction(
10362                hasher,
10363                tr_bits,
10364                tr_constraints,
10365                tr_sat,
10366            );
10367            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10368                .map_err(crate::enforcement::Certified::new)?;
10369            let automorphisms: u32 = betti[0];
10370            let deformations: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 1 {
10371                betti[1]
10372            } else {
10373                0
10374            };
10375            let obstructions: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 2 {
10376                betti[2]
10377            } else {
10378                0
10379            };
10380            hasher = hasher.fold_bytes(&automorphisms.to_be_bytes());
10381            hasher = hasher.fold_bytes(&deformations.to_be_bytes());
10382            hasher = hasher.fold_bytes(&obstructions.to_be_bytes());
10383            hasher = crate::enforcement::fold_unit_digest(
10384                hasher,
10385                witt_bits,
10386                witt_bits as u64,
10387                T::IRI,
10388                T::SITE_COUNT,
10389                T::CONSTRAINTS,
10390                <Kernel as super::ResolverKernel>::KIND,
10391            );
10392            let buffer = hasher.finalize();
10393            let fp =
10394                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10395            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10396            Ok(Certified::new(cert))
10397        }
10398    }
10399
10400    /// 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.
10401    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10402    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10403    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10404    /// failure — the witness itself is certified so downstream can persist it
10405    /// alongside success certs in a uniform `Certified<_>` channel.
10406    /// Phase X.1: the produced cert class is the ontology-declared class for
10407    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10408    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10409    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10410    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10411    /// kernels so each resolver's class discrimination is load-bearing.
10412    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10413    /// kernel's composition spec) whose output is folded into the canonical
10414    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10415    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10416    /// content-addressed per its ontology class.
10417    pub mod jacobian_guided {
10418        use super::*;
10419
10420        #[doc(hidden)]
10421        pub struct Kernel;
10422        impl super::ResolverKernel for Kernel {
10423            type Cert = crate::enforcement::GroundingCertificate;
10424            const KIND: crate::enforcement::CertificateKind =
10425                crate::enforcement::CertificateKind::JacobianGuided;
10426        }
10427
10428        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10429        ///
10430        /// # Errors
10431        ///
10432        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10433        pub fn certify<
10434            T: crate::pipeline::ConstrainedTypeShape,
10435            P: crate::enforcement::ValidationPhase,
10436            H: crate::enforcement::Hasher,
10437        >(
10438            input: &Validated<T, P>,
10439        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10440        {
10441            certify_at::<T, P, H>(input, WittLevel::W32)
10442        }
10443
10444        /// Phase D (target §4.2): certify at an explicit Witt level.
10445        ///
10446        /// # Errors
10447        ///
10448        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10449        pub fn certify_at<
10450            T: crate::pipeline::ConstrainedTypeShape,
10451            P: crate::enforcement::ValidationPhase,
10452            H: crate::enforcement::Hasher,
10453        >(
10454            input: &Validated<T, P>,
10455            level: WittLevel,
10456        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10457        {
10458            let _ = input.inner();
10459            let witt_bits = level.witt_length() as u16;
10460            let (tr_bits, tr_constraints, tr_sat) =
10461                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10462                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10463            if tr_sat == 0 {
10464                return Err(Certified::new(GenericImpossibilityWitness::default()));
10465            }
10466            let mut hasher = H::initial();
10467            hasher = crate::enforcement::fold_terminal_reduction(
10468                hasher,
10469                tr_bits,
10470                tr_constraints,
10471                tr_sat,
10472            );
10473            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
10474            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
10475            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
10476            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
10477            hasher = crate::enforcement::fold_unit_digest(
10478                hasher,
10479                witt_bits,
10480                witt_bits as u64,
10481                T::IRI,
10482                T::SITE_COUNT,
10483                T::CONSTRAINTS,
10484                <Kernel as super::ResolverKernel>::KIND,
10485            );
10486            let buffer = hasher.finalize();
10487            let fp =
10488                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10489            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10490            Ok(Certified::new(cert))
10491        }
10492    }
10493
10494    /// 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.
10495    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10496    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10497    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10498    /// failure — the witness itself is certified so downstream can persist it
10499    /// alongside success certs in a uniform `Certified<_>` channel.
10500    /// Phase X.1: the produced cert class is the ontology-declared class for
10501    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10502    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10503    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10504    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10505    /// kernels so each resolver's class discrimination is load-bearing.
10506    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10507    /// kernel's composition spec) whose output is folded into the canonical
10508    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10509    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10510    /// content-addressed per its ontology class.
10511    pub mod evaluation {
10512        use super::*;
10513
10514        #[doc(hidden)]
10515        pub struct Kernel;
10516        impl super::ResolverKernel for Kernel {
10517            type Cert = crate::enforcement::GroundingCertificate;
10518            const KIND: crate::enforcement::CertificateKind =
10519                crate::enforcement::CertificateKind::Evaluation;
10520        }
10521
10522        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10523        ///
10524        /// # Errors
10525        ///
10526        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10527        pub fn certify<
10528            T: crate::pipeline::ConstrainedTypeShape,
10529            P: crate::enforcement::ValidationPhase,
10530            H: crate::enforcement::Hasher,
10531        >(
10532            input: &Validated<T, P>,
10533        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10534        {
10535            certify_at::<T, P, H>(input, WittLevel::W32)
10536        }
10537
10538        /// Phase D (target §4.2): certify at an explicit Witt level.
10539        ///
10540        /// # Errors
10541        ///
10542        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10543        pub fn certify_at<
10544            T: crate::pipeline::ConstrainedTypeShape,
10545            P: crate::enforcement::ValidationPhase,
10546            H: crate::enforcement::Hasher,
10547        >(
10548            input: &Validated<T, P>,
10549            level: WittLevel,
10550        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10551        {
10552            let _ = input.inner();
10553            let witt_bits = level.witt_length() as u16;
10554            let (tr_bits, tr_constraints, tr_sat) =
10555                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10556                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10557            if tr_sat == 0 {
10558                return Err(Certified::new(GenericImpossibilityWitness::default()));
10559            }
10560            let mut hasher = H::initial();
10561            hasher = crate::enforcement::fold_terminal_reduction(
10562                hasher,
10563                tr_bits,
10564                tr_constraints,
10565                tr_sat,
10566            );
10567            hasher = crate::enforcement::fold_unit_digest(
10568                hasher,
10569                witt_bits,
10570                witt_bits as u64,
10571                T::IRI,
10572                T::SITE_COUNT,
10573                T::CONSTRAINTS,
10574                <Kernel as super::ResolverKernel>::KIND,
10575            );
10576            let buffer = hasher.finalize();
10577            let fp =
10578                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10579            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10580            Ok(Certified::new(cert))
10581        }
10582    }
10583
10584    /// 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.
10585    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10586    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10587    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10588    /// failure — the witness itself is certified so downstream can persist it
10589    /// alongside success certs in a uniform `Certified<_>` channel.
10590    /// Phase X.1: the produced cert class is the ontology-declared class for
10591    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10592    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10593    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10594    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10595    /// kernels so each resolver's class discrimination is load-bearing.
10596    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10597    /// kernel's composition spec) whose output is folded into the canonical
10598    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10599    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10600    /// content-addressed per its ontology class.
10601    pub mod session {
10602        use super::*;
10603
10604        #[doc(hidden)]
10605        pub struct Kernel;
10606        impl super::ResolverKernel for Kernel {
10607            type Cert = crate::enforcement::GroundingCertificate;
10608            const KIND: crate::enforcement::CertificateKind =
10609                crate::enforcement::CertificateKind::Session;
10610        }
10611
10612        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10613        ///
10614        /// # Errors
10615        ///
10616        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10617        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10618            input: &Validated<CompileUnit, P>,
10619        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10620        {
10621            certify_at::<P, H>(input, WittLevel::W32)
10622        }
10623
10624        /// Phase D (target §4.2): certify at an explicit Witt level.
10625        ///
10626        /// # Errors
10627        ///
10628        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10629        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10630            input: &Validated<CompileUnit, P>,
10631            level: WittLevel,
10632        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10633        {
10634            let unit = input.inner();
10635            let witt_bits = level.witt_length() as u16;
10636            let budget = unit.thermodynamic_budget();
10637            let result_type_iri = unit.result_type_iri();
10638            let mut hasher = H::initial();
10639            let (binding_count, fold_addr) =
10640                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10641            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10642            hasher = crate::enforcement::fold_unit_digest(
10643                hasher,
10644                witt_bits,
10645                budget,
10646                result_type_iri,
10647                0usize,
10648                &[],
10649                <Kernel as super::ResolverKernel>::KIND,
10650            );
10651            let buffer = hasher.finalize();
10652            let fp =
10653                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10654            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10655            Ok(Certified::new(cert))
10656        }
10657    }
10658
10659    /// 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).
10660    /// Returns `Certified<BornRuleVerification>` on success carrying the Witt
10661    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10662    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10663    /// failure — the witness itself is certified so downstream can persist it
10664    /// alongside success certs in a uniform `Certified<_>` channel.
10665    /// Phase X.1: the produced cert class is the ontology-declared class for
10666    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10667    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10668    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10669    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10670    /// kernels so each resolver's class discrimination is load-bearing.
10671    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10672    /// kernel's composition spec) whose output is folded into the canonical
10673    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10674    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10675    /// content-addressed per its ontology class.
10676    pub mod superposition {
10677        use super::*;
10678
10679        #[doc(hidden)]
10680        pub struct Kernel;
10681        impl super::ResolverKernel for Kernel {
10682            type Cert = crate::enforcement::BornRuleVerification;
10683            const KIND: crate::enforcement::CertificateKind =
10684                crate::enforcement::CertificateKind::Superposition;
10685        }
10686
10687        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10688        ///
10689        /// # Errors
10690        ///
10691        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10692        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10693            input: &Validated<CompileUnit, P>,
10694        ) -> Result<Certified<BornRuleVerification>, Certified<GenericImpossibilityWitness>>
10695        {
10696            certify_at::<P, H>(input, WittLevel::W32)
10697        }
10698
10699        /// Phase D (target §4.2): certify at an explicit Witt level.
10700        ///
10701        /// # Errors
10702        ///
10703        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10704        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10705            input: &Validated<CompileUnit, P>,
10706            level: WittLevel,
10707        ) -> Result<Certified<BornRuleVerification>, Certified<GenericImpossibilityWitness>>
10708        {
10709            let unit = input.inner();
10710            let witt_bits = level.witt_length() as u16;
10711            let budget = unit.thermodynamic_budget();
10712            let result_type_iri = unit.result_type_iri();
10713            let mut hasher = H::initial();
10714            let (binding_count, fold_addr) =
10715                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10716            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10717            let (outcome_index, probability) =
10718                crate::enforcement::primitive_measurement_projection(budget);
10719            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10720            hasher = crate::enforcement::fold_unit_digest(
10721                hasher,
10722                witt_bits,
10723                budget,
10724                result_type_iri,
10725                0usize,
10726                &[],
10727                <Kernel as super::ResolverKernel>::KIND,
10728            );
10729            let buffer = hasher.finalize();
10730            let fp =
10731                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10732            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10733            Ok(Certified::new(cert))
10734        }
10735    }
10736
10737    /// Phase D (target §4.2): `resolver:MeasurementResolver` — resolve a `trace:MeasurementEvent` against the von Neumann-Landauer bridge (QM_1): `preCollapseEntropy = postCollapseLandauerCost` at β* = ln 2.
10738    /// Returns `Certified<MeasurementCertificate>` on success carrying the Witt
10739    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10740    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10741    /// failure — the witness itself is certified so downstream can persist it
10742    /// alongside success certs in a uniform `Certified<_>` channel.
10743    /// Phase X.1: the produced cert class is the ontology-declared class for
10744    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10745    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10746    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10747    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10748    /// kernels so each resolver's class discrimination is load-bearing.
10749    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10750    /// kernel's composition spec) whose output is folded into the canonical
10751    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10752    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10753    /// content-addressed per its ontology class.
10754    pub mod measurement {
10755        use super::*;
10756
10757        #[doc(hidden)]
10758        pub struct Kernel;
10759        impl super::ResolverKernel for Kernel {
10760            type Cert = crate::enforcement::MeasurementCertificate;
10761            const KIND: crate::enforcement::CertificateKind =
10762                crate::enforcement::CertificateKind::Measurement;
10763        }
10764
10765        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10766        ///
10767        /// # Errors
10768        ///
10769        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10770        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10771            input: &Validated<CompileUnit, P>,
10772        ) -> Result<Certified<MeasurementCertificate>, Certified<GenericImpossibilityWitness>>
10773        {
10774            certify_at::<P, H>(input, WittLevel::W32)
10775        }
10776
10777        /// Phase D (target §4.2): certify at an explicit Witt level.
10778        ///
10779        /// # Errors
10780        ///
10781        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10782        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10783            input: &Validated<CompileUnit, P>,
10784            level: WittLevel,
10785        ) -> Result<Certified<MeasurementCertificate>, Certified<GenericImpossibilityWitness>>
10786        {
10787            let unit = input.inner();
10788            let witt_bits = level.witt_length() as u16;
10789            let budget = unit.thermodynamic_budget();
10790            let result_type_iri = unit.result_type_iri();
10791            let mut hasher = H::initial();
10792            let (outcome_index, probability) =
10793                crate::enforcement::primitive_measurement_projection(budget);
10794            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10795            hasher = crate::enforcement::fold_unit_digest(
10796                hasher,
10797                witt_bits,
10798                budget,
10799                result_type_iri,
10800                0usize,
10801                &[],
10802                <Kernel as super::ResolverKernel>::KIND,
10803            );
10804            let buffer = hasher.finalize();
10805            let fp =
10806                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10807            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10808            Ok(Certified::new(cert))
10809        }
10810    }
10811
10812    /// 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.
10813    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10814    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10815    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10816    /// failure — the witness itself is certified so downstream can persist it
10817    /// alongside success certs in a uniform `Certified<_>` channel.
10818    /// Phase X.1: the produced cert class is the ontology-declared class for
10819    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10820    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10821    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10822    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10823    /// kernels so each resolver's class discrimination is load-bearing.
10824    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10825    /// kernel's composition spec) whose output is folded into the canonical
10826    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10827    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10828    /// content-addressed per its ontology class.
10829    pub mod witt_level_resolver {
10830        use super::*;
10831
10832        #[doc(hidden)]
10833        pub struct Kernel;
10834        impl super::ResolverKernel for Kernel {
10835            type Cert = crate::enforcement::GroundingCertificate;
10836            const KIND: crate::enforcement::CertificateKind =
10837                crate::enforcement::CertificateKind::WittLevel;
10838        }
10839
10840        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10841        ///
10842        /// # Errors
10843        ///
10844        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10845        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10846            input: &Validated<CompileUnit, P>,
10847        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10848        {
10849            certify_at::<P, H>(input, WittLevel::W32)
10850        }
10851
10852        /// Phase D (target §4.2): certify at an explicit Witt level.
10853        ///
10854        /// # Errors
10855        ///
10856        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10857        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10858            input: &Validated<CompileUnit, P>,
10859            level: WittLevel,
10860        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10861        {
10862            let unit = input.inner();
10863            let witt_bits = level.witt_length() as u16;
10864            let budget = unit.thermodynamic_budget();
10865            let result_type_iri = unit.result_type_iri();
10866            let mut hasher = H::initial();
10867            hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
10868            let declared_level_bits = unit.witt_level().witt_length() as u16;
10869            hasher = hasher.fold_bytes(&declared_level_bits.to_be_bytes());
10870            hasher = crate::enforcement::fold_unit_digest(
10871                hasher,
10872                witt_bits,
10873                budget,
10874                result_type_iri,
10875                0usize,
10876                &[],
10877                <Kernel as super::ResolverKernel>::KIND,
10878            );
10879            let buffer = hasher.finalize();
10880            let fp =
10881                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10882            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10883            Ok(Certified::new(cert))
10884        }
10885    }
10886
10887    /// Phase D (target §4.2): `resolver:DihedralFactorizationResolver` — run the dihedral factorization decider on a `ConstrainedType`'s carrier, producing a cert over the factor structure.
10888    /// Returns `Certified<InvolutionCertificate>` on success carrying the Witt
10889    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10890    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10891    /// failure — the witness itself is certified so downstream can persist it
10892    /// alongside success certs in a uniform `Certified<_>` channel.
10893    /// Phase X.1: the produced cert class is the ontology-declared class for
10894    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10895    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10896    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10897    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10898    /// kernels so each resolver's class discrimination is load-bearing.
10899    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10900    /// kernel's composition spec) whose output is folded into the canonical
10901    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10902    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10903    /// content-addressed per its ontology class.
10904    pub mod dihedral_factorization {
10905        use super::*;
10906
10907        #[doc(hidden)]
10908        pub struct Kernel;
10909        impl super::ResolverKernel for Kernel {
10910            type Cert = crate::enforcement::InvolutionCertificate;
10911            const KIND: crate::enforcement::CertificateKind =
10912                crate::enforcement::CertificateKind::DihedralFactorization;
10913        }
10914
10915        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10916        ///
10917        /// # Errors
10918        ///
10919        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10920        pub fn certify<
10921            T: crate::pipeline::ConstrainedTypeShape,
10922            P: crate::enforcement::ValidationPhase,
10923            H: crate::enforcement::Hasher,
10924        >(
10925            input: &Validated<T, P>,
10926        ) -> Result<Certified<InvolutionCertificate>, Certified<GenericImpossibilityWitness>>
10927        {
10928            certify_at::<T, P, H>(input, WittLevel::W32)
10929        }
10930
10931        /// Phase D (target §4.2): certify at an explicit Witt level.
10932        ///
10933        /// # Errors
10934        ///
10935        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10936        pub fn certify_at<
10937            T: crate::pipeline::ConstrainedTypeShape,
10938            P: crate::enforcement::ValidationPhase,
10939            H: crate::enforcement::Hasher,
10940        >(
10941            input: &Validated<T, P>,
10942            level: WittLevel,
10943        ) -> Result<Certified<InvolutionCertificate>, Certified<GenericImpossibilityWitness>>
10944        {
10945            let _ = input.inner();
10946            let witt_bits = level.witt_length() as u16;
10947            let (tr_bits, tr_constraints, tr_sat) =
10948                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10949                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10950            if tr_sat == 0 {
10951                return Err(Certified::new(GenericImpossibilityWitness::default()));
10952            }
10953            let mut hasher = H::initial();
10954            hasher = crate::enforcement::fold_terminal_reduction(
10955                hasher,
10956                tr_bits,
10957                tr_constraints,
10958                tr_sat,
10959            );
10960            let (orbit_size, representative) =
10961                crate::enforcement::primitive_dihedral_signature::<T>();
10962            hasher =
10963                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
10964            hasher = crate::enforcement::fold_unit_digest(
10965                hasher,
10966                witt_bits,
10967                witt_bits as u64,
10968                T::IRI,
10969                T::SITE_COUNT,
10970                T::CONSTRAINTS,
10971                <Kernel as super::ResolverKernel>::KIND,
10972            );
10973            let buffer = hasher.finalize();
10974            let fp =
10975                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10976            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10977            Ok(Certified::new(cert))
10978        }
10979    }
10980
10981    /// 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.
10982    /// Returns `Certified<CompletenessCertificate>` on success carrying the Witt
10983    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10984    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10985    /// failure — the witness itself is certified so downstream can persist it
10986    /// alongside success certs in a uniform `Certified<_>` channel.
10987    /// Phase X.1: the produced cert class is the ontology-declared class for
10988    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10989    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10990    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10991    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10992    /// kernels so each resolver's class discrimination is load-bearing.
10993    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10994    /// kernel's composition spec) whose output is folded into the canonical
10995    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10996    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10997    /// content-addressed per its ontology class.
10998    pub mod completeness {
10999        use super::*;
11000
11001        #[doc(hidden)]
11002        pub struct Kernel;
11003        impl super::ResolverKernel for Kernel {
11004            type Cert = crate::enforcement::CompletenessCertificate;
11005            const KIND: crate::enforcement::CertificateKind =
11006                crate::enforcement::CertificateKind::Completeness;
11007        }
11008
11009        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11010        ///
11011        /// # Errors
11012        ///
11013        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11014        pub fn certify<
11015            T: crate::pipeline::ConstrainedTypeShape,
11016            P: crate::enforcement::ValidationPhase,
11017            H: crate::enforcement::Hasher,
11018        >(
11019            input: &Validated<T, P>,
11020        ) -> Result<Certified<CompletenessCertificate>, Certified<GenericImpossibilityWitness>>
11021        {
11022            certify_at::<T, P, H>(input, WittLevel::W32)
11023        }
11024
11025        /// Phase D (target §4.2): certify at an explicit Witt level.
11026        ///
11027        /// # Errors
11028        ///
11029        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11030        pub fn certify_at<
11031            T: crate::pipeline::ConstrainedTypeShape,
11032            P: crate::enforcement::ValidationPhase,
11033            H: crate::enforcement::Hasher,
11034        >(
11035            input: &Validated<T, P>,
11036            level: WittLevel,
11037        ) -> Result<Certified<CompletenessCertificate>, Certified<GenericImpossibilityWitness>>
11038        {
11039            let _ = input.inner();
11040            let witt_bits = level.witt_length() as u16;
11041            let (tr_bits, tr_constraints, tr_sat) =
11042                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11043                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11044            if tr_sat == 0 {
11045                return Err(Certified::new(GenericImpossibilityWitness::default()));
11046            }
11047            let mut hasher = H::initial();
11048            hasher = crate::enforcement::fold_terminal_reduction(
11049                hasher,
11050                tr_bits,
11051                tr_constraints,
11052                tr_sat,
11053            );
11054            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
11055                .map_err(crate::enforcement::Certified::new)?;
11056            let chi = crate::enforcement::primitive_euler_characteristic(&betti);
11057            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
11058            hasher = hasher.fold_bytes(&chi.to_be_bytes());
11059            hasher = crate::enforcement::fold_unit_digest(
11060                hasher,
11061                witt_bits,
11062                witt_bits as u64,
11063                T::IRI,
11064                T::SITE_COUNT,
11065                T::CONSTRAINTS,
11066                <Kernel as super::ResolverKernel>::KIND,
11067            );
11068            let buffer = hasher.finalize();
11069            let fp =
11070                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11071            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11072            Ok(Certified::new(cert))
11073        }
11074    }
11075
11076    /// 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.
11077    /// Returns `Certified<GeodesicCertificate>` on success carrying the Witt
11078    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11079    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11080    /// failure — the witness itself is certified so downstream can persist it
11081    /// alongside success certs in a uniform `Certified<_>` channel.
11082    /// Phase X.1: the produced cert class is the ontology-declared class for
11083    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11084    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11085    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11086    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11087    /// kernels so each resolver's class discrimination is load-bearing.
11088    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11089    /// kernel's composition spec) whose output is folded into the canonical
11090    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11091    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11092    /// content-addressed per its ontology class.
11093    pub mod geodesic_validator {
11094        use super::*;
11095
11096        #[doc(hidden)]
11097        pub struct Kernel;
11098        impl super::ResolverKernel for Kernel {
11099            type Cert = crate::enforcement::GeodesicCertificate;
11100            const KIND: crate::enforcement::CertificateKind =
11101                crate::enforcement::CertificateKind::GeodesicValidator;
11102        }
11103
11104        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11105        ///
11106        /// # Errors
11107        ///
11108        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11109        pub fn certify<
11110            T: crate::pipeline::ConstrainedTypeShape,
11111            P: crate::enforcement::ValidationPhase,
11112            H: crate::enforcement::Hasher,
11113        >(
11114            input: &Validated<T, P>,
11115        ) -> Result<Certified<GeodesicCertificate>, Certified<GenericImpossibilityWitness>>
11116        {
11117            certify_at::<T, P, H>(input, WittLevel::W32)
11118        }
11119
11120        /// Phase D (target §4.2): certify at an explicit Witt level.
11121        ///
11122        /// # Errors
11123        ///
11124        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11125        pub fn certify_at<
11126            T: crate::pipeline::ConstrainedTypeShape,
11127            P: crate::enforcement::ValidationPhase,
11128            H: crate::enforcement::Hasher,
11129        >(
11130            input: &Validated<T, P>,
11131            level: WittLevel,
11132        ) -> Result<Certified<GeodesicCertificate>, Certified<GenericImpossibilityWitness>>
11133        {
11134            let _ = input.inner();
11135            let witt_bits = level.witt_length() as u16;
11136            let (tr_bits, tr_constraints, tr_sat) =
11137                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11138                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11139            if tr_sat == 0 {
11140                return Err(Certified::new(GenericImpossibilityWitness::default()));
11141            }
11142            let mut hasher = H::initial();
11143            hasher = crate::enforcement::fold_terminal_reduction(
11144                hasher,
11145                tr_bits,
11146                tr_constraints,
11147                tr_sat,
11148            );
11149            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
11150            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
11151            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
11152            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
11153            hasher = crate::enforcement::fold_unit_digest(
11154                hasher,
11155                witt_bits,
11156                witt_bits as u64,
11157                T::IRI,
11158                T::SITE_COUNT,
11159                T::CONSTRAINTS,
11160                <Kernel as super::ResolverKernel>::KIND,
11161            );
11162            let buffer = hasher.finalize();
11163            let fp =
11164                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11165            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11166            Ok(Certified::new(cert))
11167        }
11168    }
11169}
11170
11171/// v0.2.2 phantom-typed ring operation surface. Each phantom struct binds a
11172/// `WittLevel` at the type level so consumers can write
11173/// `Mul::<W8>::apply(a, b)` for compile-time level-checked arithmetic.
11174pub trait RingOp<L> {
11175    /// Operand type at this level.
11176    type Operand;
11177    /// Apply this binary ring op.
11178    fn apply(a: Self::Operand, b: Self::Operand) -> Self::Operand;
11179}
11180
11181/// v0.2.2 W3: unary phantom-typed ring operation surface. Mirrors `RingOp`
11182/// for arity-1 operations (`Neg`, `BNot`, `Succ`) so consumers can write
11183/// `Neg::<W8>::apply(a)` for compile-time level-checked unary arithmetic.
11184pub trait UnaryRingOp<L> {
11185    /// Operand type at this level.
11186    type Operand;
11187    /// Apply this unary ring op.
11188    fn apply(a: Self::Operand) -> Self::Operand;
11189}
11190
11191/// Multiplicative ring op. phantom-typed at level `L`.
11192#[derive(Debug, Default, Clone, Copy)]
11193pub struct Mul<L>(PhantomData<L>);
11194
11195/// Additive ring op. phantom-typed at level `L`.
11196#[derive(Debug, Default, Clone, Copy)]
11197pub struct Add<L>(PhantomData<L>);
11198
11199/// Subtractive ring op. phantom-typed at level `L`.
11200#[derive(Debug, Default, Clone, Copy)]
11201pub struct Sub<L>(PhantomData<L>);
11202
11203/// Bitwise XOR ring op. phantom-typed at level `L`.
11204#[derive(Debug, Default, Clone, Copy)]
11205pub struct Xor<L>(PhantomData<L>);
11206
11207/// Bitwise AND ring op. phantom-typed at level `L`.
11208#[derive(Debug, Default, Clone, Copy)]
11209pub struct And<L>(PhantomData<L>);
11210
11211/// Bitwise OR ring op. phantom-typed at level `L`.
11212#[derive(Debug, Default, Clone, Copy)]
11213pub struct Or<L>(PhantomData<L>);
11214
11215/// Ring negation (the canonical involution: x → -x). Phantom-typed at level `L` (v0.2.2 W3).
11216#[derive(Debug, Default, Clone, Copy)]
11217pub struct Neg<L>(PhantomData<L>);
11218
11219/// Bitwise NOT (the Hamming involution: x → (2^n - 1) XOR x). Phantom-typed at level `L` (v0.2.2 W3).
11220#[derive(Debug, Default, Clone, Copy)]
11221pub struct BNot<L>(PhantomData<L>);
11222
11223/// Successor (= Neg ∘ BNot per the critical composition law). Phantom-typed at level `L` (v0.2.2 W3).
11224#[derive(Debug, Default, Clone, Copy)]
11225pub struct Succ<L>(PhantomData<L>);
11226
11227/// W8 marker — 8-bit Witt level reified at the type level.
11228#[derive(Debug, Default, Clone, Copy)]
11229pub struct W8;
11230
11231/// W16 marker — 16-bit Witt level reified at the type level.
11232#[derive(Debug, Default, Clone, Copy)]
11233pub struct W16;
11234
11235/// W24 marker — 24-bit Witt level reified at the type level.
11236#[derive(Debug, Default, Clone, Copy)]
11237pub struct W24;
11238
11239/// W32 marker — 32-bit Witt level reified at the type level.
11240#[derive(Debug, Default, Clone, Copy)]
11241pub struct W32;
11242
11243/// W40 marker — 40-bit Witt level reified at the type level.
11244#[derive(Debug, Default, Clone, Copy)]
11245pub struct W40;
11246
11247/// W48 marker — 48-bit Witt level reified at the type level.
11248#[derive(Debug, Default, Clone, Copy)]
11249pub struct W48;
11250
11251/// W56 marker — 56-bit Witt level reified at the type level.
11252#[derive(Debug, Default, Clone, Copy)]
11253pub struct W56;
11254
11255/// W64 marker — 64-bit Witt level reified at the type level.
11256#[derive(Debug, Default, Clone, Copy)]
11257pub struct W64;
11258
11259/// W72 marker — 72-bit Witt level reified at the type level.
11260#[derive(Debug, Default, Clone, Copy)]
11261pub struct W72;
11262
11263/// W80 marker — 80-bit Witt level reified at the type level.
11264#[derive(Debug, Default, Clone, Copy)]
11265pub struct W80;
11266
11267/// W88 marker — 88-bit Witt level reified at the type level.
11268#[derive(Debug, Default, Clone, Copy)]
11269pub struct W88;
11270
11271/// W96 marker — 96-bit Witt level reified at the type level.
11272#[derive(Debug, Default, Clone, Copy)]
11273pub struct W96;
11274
11275/// W104 marker — 104-bit Witt level reified at the type level.
11276#[derive(Debug, Default, Clone, Copy)]
11277pub struct W104;
11278
11279/// W112 marker — 112-bit Witt level reified at the type level.
11280#[derive(Debug, Default, Clone, Copy)]
11281pub struct W112;
11282
11283/// W120 marker — 120-bit Witt level reified at the type level.
11284#[derive(Debug, Default, Clone, Copy)]
11285pub struct W120;
11286
11287/// W128 marker — 128-bit Witt level reified at the type level.
11288#[derive(Debug, Default, Clone, Copy)]
11289pub struct W128;
11290
11291impl RingOp<W8> for Mul<W8> {
11292    type Operand = u8;
11293    #[inline]
11294    fn apply(a: u8, b: u8) -> u8 {
11295        const_ring_eval_w8(PrimitiveOp::Mul, a, b)
11296    }
11297}
11298
11299impl RingOp<W8> for Add<W8> {
11300    type Operand = u8;
11301    #[inline]
11302    fn apply(a: u8, b: u8) -> u8 {
11303        const_ring_eval_w8(PrimitiveOp::Add, a, b)
11304    }
11305}
11306
11307impl RingOp<W8> for Sub<W8> {
11308    type Operand = u8;
11309    #[inline]
11310    fn apply(a: u8, b: u8) -> u8 {
11311        const_ring_eval_w8(PrimitiveOp::Sub, a, b)
11312    }
11313}
11314
11315impl RingOp<W8> for Xor<W8> {
11316    type Operand = u8;
11317    #[inline]
11318    fn apply(a: u8, b: u8) -> u8 {
11319        const_ring_eval_w8(PrimitiveOp::Xor, a, b)
11320    }
11321}
11322
11323impl RingOp<W8> for And<W8> {
11324    type Operand = u8;
11325    #[inline]
11326    fn apply(a: u8, b: u8) -> u8 {
11327        const_ring_eval_w8(PrimitiveOp::And, a, b)
11328    }
11329}
11330
11331impl RingOp<W8> for Or<W8> {
11332    type Operand = u8;
11333    #[inline]
11334    fn apply(a: u8, b: u8) -> u8 {
11335        const_ring_eval_w8(PrimitiveOp::Or, a, b)
11336    }
11337}
11338
11339impl RingOp<W16> for Mul<W16> {
11340    type Operand = u16;
11341    #[inline]
11342    fn apply(a: u16, b: u16) -> u16 {
11343        const_ring_eval_w16(PrimitiveOp::Mul, a, b)
11344    }
11345}
11346
11347impl RingOp<W16> for Add<W16> {
11348    type Operand = u16;
11349    #[inline]
11350    fn apply(a: u16, b: u16) -> u16 {
11351        const_ring_eval_w16(PrimitiveOp::Add, a, b)
11352    }
11353}
11354
11355impl RingOp<W16> for Sub<W16> {
11356    type Operand = u16;
11357    #[inline]
11358    fn apply(a: u16, b: u16) -> u16 {
11359        const_ring_eval_w16(PrimitiveOp::Sub, a, b)
11360    }
11361}
11362
11363impl RingOp<W16> for Xor<W16> {
11364    type Operand = u16;
11365    #[inline]
11366    fn apply(a: u16, b: u16) -> u16 {
11367        const_ring_eval_w16(PrimitiveOp::Xor, a, b)
11368    }
11369}
11370
11371impl RingOp<W16> for And<W16> {
11372    type Operand = u16;
11373    #[inline]
11374    fn apply(a: u16, b: u16) -> u16 {
11375        const_ring_eval_w16(PrimitiveOp::And, a, b)
11376    }
11377}
11378
11379impl RingOp<W16> for Or<W16> {
11380    type Operand = u16;
11381    #[inline]
11382    fn apply(a: u16, b: u16) -> u16 {
11383        const_ring_eval_w16(PrimitiveOp::Or, a, b)
11384    }
11385}
11386
11387impl RingOp<W24> for Mul<W24> {
11388    type Operand = u32;
11389    #[inline]
11390    fn apply(a: u32, b: u32) -> u32 {
11391        const_ring_eval_w24(PrimitiveOp::Mul, a, b)
11392    }
11393}
11394
11395impl RingOp<W24> for Add<W24> {
11396    type Operand = u32;
11397    #[inline]
11398    fn apply(a: u32, b: u32) -> u32 {
11399        const_ring_eval_w24(PrimitiveOp::Add, a, b)
11400    }
11401}
11402
11403impl RingOp<W24> for Sub<W24> {
11404    type Operand = u32;
11405    #[inline]
11406    fn apply(a: u32, b: u32) -> u32 {
11407        const_ring_eval_w24(PrimitiveOp::Sub, a, b)
11408    }
11409}
11410
11411impl RingOp<W24> for Xor<W24> {
11412    type Operand = u32;
11413    #[inline]
11414    fn apply(a: u32, b: u32) -> u32 {
11415        const_ring_eval_w24(PrimitiveOp::Xor, a, b)
11416    }
11417}
11418
11419impl RingOp<W24> for And<W24> {
11420    type Operand = u32;
11421    #[inline]
11422    fn apply(a: u32, b: u32) -> u32 {
11423        const_ring_eval_w24(PrimitiveOp::And, a, b)
11424    }
11425}
11426
11427impl RingOp<W24> for Or<W24> {
11428    type Operand = u32;
11429    #[inline]
11430    fn apply(a: u32, b: u32) -> u32 {
11431        const_ring_eval_w24(PrimitiveOp::Or, a, b)
11432    }
11433}
11434
11435impl RingOp<W32> for Mul<W32> {
11436    type Operand = u32;
11437    #[inline]
11438    fn apply(a: u32, b: u32) -> u32 {
11439        const_ring_eval_w32(PrimitiveOp::Mul, a, b)
11440    }
11441}
11442
11443impl RingOp<W32> for Add<W32> {
11444    type Operand = u32;
11445    #[inline]
11446    fn apply(a: u32, b: u32) -> u32 {
11447        const_ring_eval_w32(PrimitiveOp::Add, a, b)
11448    }
11449}
11450
11451impl RingOp<W32> for Sub<W32> {
11452    type Operand = u32;
11453    #[inline]
11454    fn apply(a: u32, b: u32) -> u32 {
11455        const_ring_eval_w32(PrimitiveOp::Sub, a, b)
11456    }
11457}
11458
11459impl RingOp<W32> for Xor<W32> {
11460    type Operand = u32;
11461    #[inline]
11462    fn apply(a: u32, b: u32) -> u32 {
11463        const_ring_eval_w32(PrimitiveOp::Xor, a, b)
11464    }
11465}
11466
11467impl RingOp<W32> for And<W32> {
11468    type Operand = u32;
11469    #[inline]
11470    fn apply(a: u32, b: u32) -> u32 {
11471        const_ring_eval_w32(PrimitiveOp::And, a, b)
11472    }
11473}
11474
11475impl RingOp<W32> for Or<W32> {
11476    type Operand = u32;
11477    #[inline]
11478    fn apply(a: u32, b: u32) -> u32 {
11479        const_ring_eval_w32(PrimitiveOp::Or, a, b)
11480    }
11481}
11482
11483impl RingOp<W40> for Mul<W40> {
11484    type Operand = u64;
11485    #[inline]
11486    fn apply(a: u64, b: u64) -> u64 {
11487        const_ring_eval_w40(PrimitiveOp::Mul, a, b)
11488    }
11489}
11490
11491impl RingOp<W40> for Add<W40> {
11492    type Operand = u64;
11493    #[inline]
11494    fn apply(a: u64, b: u64) -> u64 {
11495        const_ring_eval_w40(PrimitiveOp::Add, a, b)
11496    }
11497}
11498
11499impl RingOp<W40> for Sub<W40> {
11500    type Operand = u64;
11501    #[inline]
11502    fn apply(a: u64, b: u64) -> u64 {
11503        const_ring_eval_w40(PrimitiveOp::Sub, a, b)
11504    }
11505}
11506
11507impl RingOp<W40> for Xor<W40> {
11508    type Operand = u64;
11509    #[inline]
11510    fn apply(a: u64, b: u64) -> u64 {
11511        const_ring_eval_w40(PrimitiveOp::Xor, a, b)
11512    }
11513}
11514
11515impl RingOp<W40> for And<W40> {
11516    type Operand = u64;
11517    #[inline]
11518    fn apply(a: u64, b: u64) -> u64 {
11519        const_ring_eval_w40(PrimitiveOp::And, a, b)
11520    }
11521}
11522
11523impl RingOp<W40> for Or<W40> {
11524    type Operand = u64;
11525    #[inline]
11526    fn apply(a: u64, b: u64) -> u64 {
11527        const_ring_eval_w40(PrimitiveOp::Or, a, b)
11528    }
11529}
11530
11531impl RingOp<W48> for Mul<W48> {
11532    type Operand = u64;
11533    #[inline]
11534    fn apply(a: u64, b: u64) -> u64 {
11535        const_ring_eval_w48(PrimitiveOp::Mul, a, b)
11536    }
11537}
11538
11539impl RingOp<W48> for Add<W48> {
11540    type Operand = u64;
11541    #[inline]
11542    fn apply(a: u64, b: u64) -> u64 {
11543        const_ring_eval_w48(PrimitiveOp::Add, a, b)
11544    }
11545}
11546
11547impl RingOp<W48> for Sub<W48> {
11548    type Operand = u64;
11549    #[inline]
11550    fn apply(a: u64, b: u64) -> u64 {
11551        const_ring_eval_w48(PrimitiveOp::Sub, a, b)
11552    }
11553}
11554
11555impl RingOp<W48> for Xor<W48> {
11556    type Operand = u64;
11557    #[inline]
11558    fn apply(a: u64, b: u64) -> u64 {
11559        const_ring_eval_w48(PrimitiveOp::Xor, a, b)
11560    }
11561}
11562
11563impl RingOp<W48> for And<W48> {
11564    type Operand = u64;
11565    #[inline]
11566    fn apply(a: u64, b: u64) -> u64 {
11567        const_ring_eval_w48(PrimitiveOp::And, a, b)
11568    }
11569}
11570
11571impl RingOp<W48> for Or<W48> {
11572    type Operand = u64;
11573    #[inline]
11574    fn apply(a: u64, b: u64) -> u64 {
11575        const_ring_eval_w48(PrimitiveOp::Or, a, b)
11576    }
11577}
11578
11579impl RingOp<W56> for Mul<W56> {
11580    type Operand = u64;
11581    #[inline]
11582    fn apply(a: u64, b: u64) -> u64 {
11583        const_ring_eval_w56(PrimitiveOp::Mul, a, b)
11584    }
11585}
11586
11587impl RingOp<W56> for Add<W56> {
11588    type Operand = u64;
11589    #[inline]
11590    fn apply(a: u64, b: u64) -> u64 {
11591        const_ring_eval_w56(PrimitiveOp::Add, a, b)
11592    }
11593}
11594
11595impl RingOp<W56> for Sub<W56> {
11596    type Operand = u64;
11597    #[inline]
11598    fn apply(a: u64, b: u64) -> u64 {
11599        const_ring_eval_w56(PrimitiveOp::Sub, a, b)
11600    }
11601}
11602
11603impl RingOp<W56> for Xor<W56> {
11604    type Operand = u64;
11605    #[inline]
11606    fn apply(a: u64, b: u64) -> u64 {
11607        const_ring_eval_w56(PrimitiveOp::Xor, a, b)
11608    }
11609}
11610
11611impl RingOp<W56> for And<W56> {
11612    type Operand = u64;
11613    #[inline]
11614    fn apply(a: u64, b: u64) -> u64 {
11615        const_ring_eval_w56(PrimitiveOp::And, a, b)
11616    }
11617}
11618
11619impl RingOp<W56> for Or<W56> {
11620    type Operand = u64;
11621    #[inline]
11622    fn apply(a: u64, b: u64) -> u64 {
11623        const_ring_eval_w56(PrimitiveOp::Or, a, b)
11624    }
11625}
11626
11627impl RingOp<W64> for Mul<W64> {
11628    type Operand = u64;
11629    #[inline]
11630    fn apply(a: u64, b: u64) -> u64 {
11631        const_ring_eval_w64(PrimitiveOp::Mul, a, b)
11632    }
11633}
11634
11635impl RingOp<W64> for Add<W64> {
11636    type Operand = u64;
11637    #[inline]
11638    fn apply(a: u64, b: u64) -> u64 {
11639        const_ring_eval_w64(PrimitiveOp::Add, a, b)
11640    }
11641}
11642
11643impl RingOp<W64> for Sub<W64> {
11644    type Operand = u64;
11645    #[inline]
11646    fn apply(a: u64, b: u64) -> u64 {
11647        const_ring_eval_w64(PrimitiveOp::Sub, a, b)
11648    }
11649}
11650
11651impl RingOp<W64> for Xor<W64> {
11652    type Operand = u64;
11653    #[inline]
11654    fn apply(a: u64, b: u64) -> u64 {
11655        const_ring_eval_w64(PrimitiveOp::Xor, a, b)
11656    }
11657}
11658
11659impl RingOp<W64> for And<W64> {
11660    type Operand = u64;
11661    #[inline]
11662    fn apply(a: u64, b: u64) -> u64 {
11663        const_ring_eval_w64(PrimitiveOp::And, a, b)
11664    }
11665}
11666
11667impl RingOp<W64> for Or<W64> {
11668    type Operand = u64;
11669    #[inline]
11670    fn apply(a: u64, b: u64) -> u64 {
11671        const_ring_eval_w64(PrimitiveOp::Or, a, b)
11672    }
11673}
11674
11675impl RingOp<W72> for Mul<W72> {
11676    type Operand = u128;
11677    #[inline]
11678    fn apply(a: u128, b: u128) -> u128 {
11679        const_ring_eval_w72(PrimitiveOp::Mul, a, b)
11680    }
11681}
11682
11683impl RingOp<W72> for Add<W72> {
11684    type Operand = u128;
11685    #[inline]
11686    fn apply(a: u128, b: u128) -> u128 {
11687        const_ring_eval_w72(PrimitiveOp::Add, a, b)
11688    }
11689}
11690
11691impl RingOp<W72> for Sub<W72> {
11692    type Operand = u128;
11693    #[inline]
11694    fn apply(a: u128, b: u128) -> u128 {
11695        const_ring_eval_w72(PrimitiveOp::Sub, a, b)
11696    }
11697}
11698
11699impl RingOp<W72> for Xor<W72> {
11700    type Operand = u128;
11701    #[inline]
11702    fn apply(a: u128, b: u128) -> u128 {
11703        const_ring_eval_w72(PrimitiveOp::Xor, a, b)
11704    }
11705}
11706
11707impl RingOp<W72> for And<W72> {
11708    type Operand = u128;
11709    #[inline]
11710    fn apply(a: u128, b: u128) -> u128 {
11711        const_ring_eval_w72(PrimitiveOp::And, a, b)
11712    }
11713}
11714
11715impl RingOp<W72> for Or<W72> {
11716    type Operand = u128;
11717    #[inline]
11718    fn apply(a: u128, b: u128) -> u128 {
11719        const_ring_eval_w72(PrimitiveOp::Or, a, b)
11720    }
11721}
11722
11723impl RingOp<W80> for Mul<W80> {
11724    type Operand = u128;
11725    #[inline]
11726    fn apply(a: u128, b: u128) -> u128 {
11727        const_ring_eval_w80(PrimitiveOp::Mul, a, b)
11728    }
11729}
11730
11731impl RingOp<W80> for Add<W80> {
11732    type Operand = u128;
11733    #[inline]
11734    fn apply(a: u128, b: u128) -> u128 {
11735        const_ring_eval_w80(PrimitiveOp::Add, a, b)
11736    }
11737}
11738
11739impl RingOp<W80> for Sub<W80> {
11740    type Operand = u128;
11741    #[inline]
11742    fn apply(a: u128, b: u128) -> u128 {
11743        const_ring_eval_w80(PrimitiveOp::Sub, a, b)
11744    }
11745}
11746
11747impl RingOp<W80> for Xor<W80> {
11748    type Operand = u128;
11749    #[inline]
11750    fn apply(a: u128, b: u128) -> u128 {
11751        const_ring_eval_w80(PrimitiveOp::Xor, a, b)
11752    }
11753}
11754
11755impl RingOp<W80> for And<W80> {
11756    type Operand = u128;
11757    #[inline]
11758    fn apply(a: u128, b: u128) -> u128 {
11759        const_ring_eval_w80(PrimitiveOp::And, a, b)
11760    }
11761}
11762
11763impl RingOp<W80> for Or<W80> {
11764    type Operand = u128;
11765    #[inline]
11766    fn apply(a: u128, b: u128) -> u128 {
11767        const_ring_eval_w80(PrimitiveOp::Or, a, b)
11768    }
11769}
11770
11771impl RingOp<W88> for Mul<W88> {
11772    type Operand = u128;
11773    #[inline]
11774    fn apply(a: u128, b: u128) -> u128 {
11775        const_ring_eval_w88(PrimitiveOp::Mul, a, b)
11776    }
11777}
11778
11779impl RingOp<W88> for Add<W88> {
11780    type Operand = u128;
11781    #[inline]
11782    fn apply(a: u128, b: u128) -> u128 {
11783        const_ring_eval_w88(PrimitiveOp::Add, a, b)
11784    }
11785}
11786
11787impl RingOp<W88> for Sub<W88> {
11788    type Operand = u128;
11789    #[inline]
11790    fn apply(a: u128, b: u128) -> u128 {
11791        const_ring_eval_w88(PrimitiveOp::Sub, a, b)
11792    }
11793}
11794
11795impl RingOp<W88> for Xor<W88> {
11796    type Operand = u128;
11797    #[inline]
11798    fn apply(a: u128, b: u128) -> u128 {
11799        const_ring_eval_w88(PrimitiveOp::Xor, a, b)
11800    }
11801}
11802
11803impl RingOp<W88> for And<W88> {
11804    type Operand = u128;
11805    #[inline]
11806    fn apply(a: u128, b: u128) -> u128 {
11807        const_ring_eval_w88(PrimitiveOp::And, a, b)
11808    }
11809}
11810
11811impl RingOp<W88> for Or<W88> {
11812    type Operand = u128;
11813    #[inline]
11814    fn apply(a: u128, b: u128) -> u128 {
11815        const_ring_eval_w88(PrimitiveOp::Or, a, b)
11816    }
11817}
11818
11819impl RingOp<W96> for Mul<W96> {
11820    type Operand = u128;
11821    #[inline]
11822    fn apply(a: u128, b: u128) -> u128 {
11823        const_ring_eval_w96(PrimitiveOp::Mul, a, b)
11824    }
11825}
11826
11827impl RingOp<W96> for Add<W96> {
11828    type Operand = u128;
11829    #[inline]
11830    fn apply(a: u128, b: u128) -> u128 {
11831        const_ring_eval_w96(PrimitiveOp::Add, a, b)
11832    }
11833}
11834
11835impl RingOp<W96> for Sub<W96> {
11836    type Operand = u128;
11837    #[inline]
11838    fn apply(a: u128, b: u128) -> u128 {
11839        const_ring_eval_w96(PrimitiveOp::Sub, a, b)
11840    }
11841}
11842
11843impl RingOp<W96> for Xor<W96> {
11844    type Operand = u128;
11845    #[inline]
11846    fn apply(a: u128, b: u128) -> u128 {
11847        const_ring_eval_w96(PrimitiveOp::Xor, a, b)
11848    }
11849}
11850
11851impl RingOp<W96> for And<W96> {
11852    type Operand = u128;
11853    #[inline]
11854    fn apply(a: u128, b: u128) -> u128 {
11855        const_ring_eval_w96(PrimitiveOp::And, a, b)
11856    }
11857}
11858
11859impl RingOp<W96> for Or<W96> {
11860    type Operand = u128;
11861    #[inline]
11862    fn apply(a: u128, b: u128) -> u128 {
11863        const_ring_eval_w96(PrimitiveOp::Or, a, b)
11864    }
11865}
11866
11867impl RingOp<W104> for Mul<W104> {
11868    type Operand = u128;
11869    #[inline]
11870    fn apply(a: u128, b: u128) -> u128 {
11871        const_ring_eval_w104(PrimitiveOp::Mul, a, b)
11872    }
11873}
11874
11875impl RingOp<W104> for Add<W104> {
11876    type Operand = u128;
11877    #[inline]
11878    fn apply(a: u128, b: u128) -> u128 {
11879        const_ring_eval_w104(PrimitiveOp::Add, a, b)
11880    }
11881}
11882
11883impl RingOp<W104> for Sub<W104> {
11884    type Operand = u128;
11885    #[inline]
11886    fn apply(a: u128, b: u128) -> u128 {
11887        const_ring_eval_w104(PrimitiveOp::Sub, a, b)
11888    }
11889}
11890
11891impl RingOp<W104> for Xor<W104> {
11892    type Operand = u128;
11893    #[inline]
11894    fn apply(a: u128, b: u128) -> u128 {
11895        const_ring_eval_w104(PrimitiveOp::Xor, a, b)
11896    }
11897}
11898
11899impl RingOp<W104> for And<W104> {
11900    type Operand = u128;
11901    #[inline]
11902    fn apply(a: u128, b: u128) -> u128 {
11903        const_ring_eval_w104(PrimitiveOp::And, a, b)
11904    }
11905}
11906
11907impl RingOp<W104> for Or<W104> {
11908    type Operand = u128;
11909    #[inline]
11910    fn apply(a: u128, b: u128) -> u128 {
11911        const_ring_eval_w104(PrimitiveOp::Or, a, b)
11912    }
11913}
11914
11915impl RingOp<W112> for Mul<W112> {
11916    type Operand = u128;
11917    #[inline]
11918    fn apply(a: u128, b: u128) -> u128 {
11919        const_ring_eval_w112(PrimitiveOp::Mul, a, b)
11920    }
11921}
11922
11923impl RingOp<W112> for Add<W112> {
11924    type Operand = u128;
11925    #[inline]
11926    fn apply(a: u128, b: u128) -> u128 {
11927        const_ring_eval_w112(PrimitiveOp::Add, a, b)
11928    }
11929}
11930
11931impl RingOp<W112> for Sub<W112> {
11932    type Operand = u128;
11933    #[inline]
11934    fn apply(a: u128, b: u128) -> u128 {
11935        const_ring_eval_w112(PrimitiveOp::Sub, a, b)
11936    }
11937}
11938
11939impl RingOp<W112> for Xor<W112> {
11940    type Operand = u128;
11941    #[inline]
11942    fn apply(a: u128, b: u128) -> u128 {
11943        const_ring_eval_w112(PrimitiveOp::Xor, a, b)
11944    }
11945}
11946
11947impl RingOp<W112> for And<W112> {
11948    type Operand = u128;
11949    #[inline]
11950    fn apply(a: u128, b: u128) -> u128 {
11951        const_ring_eval_w112(PrimitiveOp::And, a, b)
11952    }
11953}
11954
11955impl RingOp<W112> for Or<W112> {
11956    type Operand = u128;
11957    #[inline]
11958    fn apply(a: u128, b: u128) -> u128 {
11959        const_ring_eval_w112(PrimitiveOp::Or, a, b)
11960    }
11961}
11962
11963impl RingOp<W120> for Mul<W120> {
11964    type Operand = u128;
11965    #[inline]
11966    fn apply(a: u128, b: u128) -> u128 {
11967        const_ring_eval_w120(PrimitiveOp::Mul, a, b)
11968    }
11969}
11970
11971impl RingOp<W120> for Add<W120> {
11972    type Operand = u128;
11973    #[inline]
11974    fn apply(a: u128, b: u128) -> u128 {
11975        const_ring_eval_w120(PrimitiveOp::Add, a, b)
11976    }
11977}
11978
11979impl RingOp<W120> for Sub<W120> {
11980    type Operand = u128;
11981    #[inline]
11982    fn apply(a: u128, b: u128) -> u128 {
11983        const_ring_eval_w120(PrimitiveOp::Sub, a, b)
11984    }
11985}
11986
11987impl RingOp<W120> for Xor<W120> {
11988    type Operand = u128;
11989    #[inline]
11990    fn apply(a: u128, b: u128) -> u128 {
11991        const_ring_eval_w120(PrimitiveOp::Xor, a, b)
11992    }
11993}
11994
11995impl RingOp<W120> for And<W120> {
11996    type Operand = u128;
11997    #[inline]
11998    fn apply(a: u128, b: u128) -> u128 {
11999        const_ring_eval_w120(PrimitiveOp::And, a, b)
12000    }
12001}
12002
12003impl RingOp<W120> for Or<W120> {
12004    type Operand = u128;
12005    #[inline]
12006    fn apply(a: u128, b: u128) -> u128 {
12007        const_ring_eval_w120(PrimitiveOp::Or, a, b)
12008    }
12009}
12010
12011impl RingOp<W128> for Mul<W128> {
12012    type Operand = u128;
12013    #[inline]
12014    fn apply(a: u128, b: u128) -> u128 {
12015        const_ring_eval_w128(PrimitiveOp::Mul, a, b)
12016    }
12017}
12018
12019impl RingOp<W128> for Add<W128> {
12020    type Operand = u128;
12021    #[inline]
12022    fn apply(a: u128, b: u128) -> u128 {
12023        const_ring_eval_w128(PrimitiveOp::Add, a, b)
12024    }
12025}
12026
12027impl RingOp<W128> for Sub<W128> {
12028    type Operand = u128;
12029    #[inline]
12030    fn apply(a: u128, b: u128) -> u128 {
12031        const_ring_eval_w128(PrimitiveOp::Sub, a, b)
12032    }
12033}
12034
12035impl RingOp<W128> for Xor<W128> {
12036    type Operand = u128;
12037    #[inline]
12038    fn apply(a: u128, b: u128) -> u128 {
12039        const_ring_eval_w128(PrimitiveOp::Xor, a, b)
12040    }
12041}
12042
12043impl RingOp<W128> for And<W128> {
12044    type Operand = u128;
12045    #[inline]
12046    fn apply(a: u128, b: u128) -> u128 {
12047        const_ring_eval_w128(PrimitiveOp::And, a, b)
12048    }
12049}
12050
12051impl RingOp<W128> for Or<W128> {
12052    type Operand = u128;
12053    #[inline]
12054    fn apply(a: u128, b: u128) -> u128 {
12055        const_ring_eval_w128(PrimitiveOp::Or, a, b)
12056    }
12057}
12058
12059impl UnaryRingOp<W8> for Neg<W8> {
12060    type Operand = u8;
12061    #[inline]
12062    fn apply(a: u8) -> u8 {
12063        const_ring_eval_w8(PrimitiveOp::Sub, 0, a)
12064    }
12065}
12066
12067impl UnaryRingOp<W8> for BNot<W8> {
12068    type Operand = u8;
12069    #[inline]
12070    fn apply(a: u8) -> u8 {
12071        const_ring_eval_w8(PrimitiveOp::Xor, a, u8::MAX)
12072    }
12073}
12074
12075impl UnaryRingOp<W8> for Succ<W8> {
12076    type Operand = u8;
12077    #[inline]
12078    fn apply(a: u8) -> u8 {
12079        <Neg<W8> as UnaryRingOp<W8>>::apply(<BNot<W8> as UnaryRingOp<W8>>::apply(a))
12080    }
12081}
12082
12083impl UnaryRingOp<W16> for Neg<W16> {
12084    type Operand = u16;
12085    #[inline]
12086    fn apply(a: u16) -> u16 {
12087        const_ring_eval_w16(PrimitiveOp::Sub, 0, a)
12088    }
12089}
12090
12091impl UnaryRingOp<W16> for BNot<W16> {
12092    type Operand = u16;
12093    #[inline]
12094    fn apply(a: u16) -> u16 {
12095        const_ring_eval_w16(PrimitiveOp::Xor, a, u16::MAX)
12096    }
12097}
12098
12099impl UnaryRingOp<W16> for Succ<W16> {
12100    type Operand = u16;
12101    #[inline]
12102    fn apply(a: u16) -> u16 {
12103        <Neg<W16> as UnaryRingOp<W16>>::apply(<BNot<W16> as UnaryRingOp<W16>>::apply(a))
12104    }
12105}
12106
12107impl UnaryRingOp<W24> for Neg<W24> {
12108    type Operand = u32;
12109    #[inline]
12110    fn apply(a: u32) -> u32 {
12111        const_ring_eval_w24(PrimitiveOp::Sub, 0, a)
12112    }
12113}
12114
12115impl UnaryRingOp<W24> for BNot<W24> {
12116    type Operand = u32;
12117    #[inline]
12118    fn apply(a: u32) -> u32 {
12119        const_ring_eval_w24(PrimitiveOp::Xor, a, 0x00FF_FFFFu32)
12120    }
12121}
12122
12123impl UnaryRingOp<W24> for Succ<W24> {
12124    type Operand = u32;
12125    #[inline]
12126    fn apply(a: u32) -> u32 {
12127        <Neg<W24> as UnaryRingOp<W24>>::apply(<BNot<W24> as UnaryRingOp<W24>>::apply(a))
12128    }
12129}
12130
12131impl UnaryRingOp<W32> for Neg<W32> {
12132    type Operand = u32;
12133    #[inline]
12134    fn apply(a: u32) -> u32 {
12135        const_ring_eval_w32(PrimitiveOp::Sub, 0, a)
12136    }
12137}
12138
12139impl UnaryRingOp<W32> for BNot<W32> {
12140    type Operand = u32;
12141    #[inline]
12142    fn apply(a: u32) -> u32 {
12143        const_ring_eval_w32(PrimitiveOp::Xor, a, u32::MAX)
12144    }
12145}
12146
12147impl UnaryRingOp<W32> for Succ<W32> {
12148    type Operand = u32;
12149    #[inline]
12150    fn apply(a: u32) -> u32 {
12151        <Neg<W32> as UnaryRingOp<W32>>::apply(<BNot<W32> as UnaryRingOp<W32>>::apply(a))
12152    }
12153}
12154
12155impl UnaryRingOp<W40> for Neg<W40> {
12156    type Operand = u64;
12157    #[inline]
12158    fn apply(a: u64) -> u64 {
12159        const_ring_eval_w40(PrimitiveOp::Sub, 0, a)
12160    }
12161}
12162
12163impl UnaryRingOp<W40> for BNot<W40> {
12164    type Operand = u64;
12165    #[inline]
12166    fn apply(a: u64) -> u64 {
12167        const_ring_eval_w40(PrimitiveOp::Xor, a, 0x0000_00FF_FFFF_FFFFu64)
12168    }
12169}
12170
12171impl UnaryRingOp<W40> for Succ<W40> {
12172    type Operand = u64;
12173    #[inline]
12174    fn apply(a: u64) -> u64 {
12175        <Neg<W40> as UnaryRingOp<W40>>::apply(<BNot<W40> as UnaryRingOp<W40>>::apply(a))
12176    }
12177}
12178
12179impl UnaryRingOp<W48> for Neg<W48> {
12180    type Operand = u64;
12181    #[inline]
12182    fn apply(a: u64) -> u64 {
12183        const_ring_eval_w48(PrimitiveOp::Sub, 0, a)
12184    }
12185}
12186
12187impl UnaryRingOp<W48> for BNot<W48> {
12188    type Operand = u64;
12189    #[inline]
12190    fn apply(a: u64) -> u64 {
12191        const_ring_eval_w48(PrimitiveOp::Xor, a, 0x0000_FFFF_FFFF_FFFFu64)
12192    }
12193}
12194
12195impl UnaryRingOp<W48> for Succ<W48> {
12196    type Operand = u64;
12197    #[inline]
12198    fn apply(a: u64) -> u64 {
12199        <Neg<W48> as UnaryRingOp<W48>>::apply(<BNot<W48> as UnaryRingOp<W48>>::apply(a))
12200    }
12201}
12202
12203impl UnaryRingOp<W56> for Neg<W56> {
12204    type Operand = u64;
12205    #[inline]
12206    fn apply(a: u64) -> u64 {
12207        const_ring_eval_w56(PrimitiveOp::Sub, 0, a)
12208    }
12209}
12210
12211impl UnaryRingOp<W56> for BNot<W56> {
12212    type Operand = u64;
12213    #[inline]
12214    fn apply(a: u64) -> u64 {
12215        const_ring_eval_w56(PrimitiveOp::Xor, a, 0x00FF_FFFF_FFFF_FFFFu64)
12216    }
12217}
12218
12219impl UnaryRingOp<W56> for Succ<W56> {
12220    type Operand = u64;
12221    #[inline]
12222    fn apply(a: u64) -> u64 {
12223        <Neg<W56> as UnaryRingOp<W56>>::apply(<BNot<W56> as UnaryRingOp<W56>>::apply(a))
12224    }
12225}
12226
12227impl UnaryRingOp<W64> for Neg<W64> {
12228    type Operand = u64;
12229    #[inline]
12230    fn apply(a: u64) -> u64 {
12231        const_ring_eval_w64(PrimitiveOp::Sub, 0, a)
12232    }
12233}
12234
12235impl UnaryRingOp<W64> for BNot<W64> {
12236    type Operand = u64;
12237    #[inline]
12238    fn apply(a: u64) -> u64 {
12239        const_ring_eval_w64(PrimitiveOp::Xor, a, u64::MAX)
12240    }
12241}
12242
12243impl UnaryRingOp<W64> for Succ<W64> {
12244    type Operand = u64;
12245    #[inline]
12246    fn apply(a: u64) -> u64 {
12247        <Neg<W64> as UnaryRingOp<W64>>::apply(<BNot<W64> as UnaryRingOp<W64>>::apply(a))
12248    }
12249}
12250
12251impl UnaryRingOp<W72> for Neg<W72> {
12252    type Operand = u128;
12253    #[inline]
12254    fn apply(a: u128) -> u128 {
12255        const_ring_eval_w72(PrimitiveOp::Sub, 0, a)
12256    }
12257}
12258
12259impl UnaryRingOp<W72> for BNot<W72> {
12260    type Operand = u128;
12261    #[inline]
12262    fn apply(a: u128) -> u128 {
12263        const_ring_eval_w72(PrimitiveOp::Xor, a, u128::MAX >> (128 - 72))
12264    }
12265}
12266
12267impl UnaryRingOp<W72> for Succ<W72> {
12268    type Operand = u128;
12269    #[inline]
12270    fn apply(a: u128) -> u128 {
12271        <Neg<W72> as UnaryRingOp<W72>>::apply(<BNot<W72> as UnaryRingOp<W72>>::apply(a))
12272    }
12273}
12274
12275impl UnaryRingOp<W80> for Neg<W80> {
12276    type Operand = u128;
12277    #[inline]
12278    fn apply(a: u128) -> u128 {
12279        const_ring_eval_w80(PrimitiveOp::Sub, 0, a)
12280    }
12281}
12282
12283impl UnaryRingOp<W80> for BNot<W80> {
12284    type Operand = u128;
12285    #[inline]
12286    fn apply(a: u128) -> u128 {
12287        const_ring_eval_w80(PrimitiveOp::Xor, a, u128::MAX >> (128 - 80))
12288    }
12289}
12290
12291impl UnaryRingOp<W80> for Succ<W80> {
12292    type Operand = u128;
12293    #[inline]
12294    fn apply(a: u128) -> u128 {
12295        <Neg<W80> as UnaryRingOp<W80>>::apply(<BNot<W80> as UnaryRingOp<W80>>::apply(a))
12296    }
12297}
12298
12299impl UnaryRingOp<W88> for Neg<W88> {
12300    type Operand = u128;
12301    #[inline]
12302    fn apply(a: u128) -> u128 {
12303        const_ring_eval_w88(PrimitiveOp::Sub, 0, a)
12304    }
12305}
12306
12307impl UnaryRingOp<W88> for BNot<W88> {
12308    type Operand = u128;
12309    #[inline]
12310    fn apply(a: u128) -> u128 {
12311        const_ring_eval_w88(PrimitiveOp::Xor, a, u128::MAX >> (128 - 88))
12312    }
12313}
12314
12315impl UnaryRingOp<W88> for Succ<W88> {
12316    type Operand = u128;
12317    #[inline]
12318    fn apply(a: u128) -> u128 {
12319        <Neg<W88> as UnaryRingOp<W88>>::apply(<BNot<W88> as UnaryRingOp<W88>>::apply(a))
12320    }
12321}
12322
12323impl UnaryRingOp<W96> for Neg<W96> {
12324    type Operand = u128;
12325    #[inline]
12326    fn apply(a: u128) -> u128 {
12327        const_ring_eval_w96(PrimitiveOp::Sub, 0, a)
12328    }
12329}
12330
12331impl UnaryRingOp<W96> for BNot<W96> {
12332    type Operand = u128;
12333    #[inline]
12334    fn apply(a: u128) -> u128 {
12335        const_ring_eval_w96(PrimitiveOp::Xor, a, u128::MAX >> (128 - 96))
12336    }
12337}
12338
12339impl UnaryRingOp<W96> for Succ<W96> {
12340    type Operand = u128;
12341    #[inline]
12342    fn apply(a: u128) -> u128 {
12343        <Neg<W96> as UnaryRingOp<W96>>::apply(<BNot<W96> as UnaryRingOp<W96>>::apply(a))
12344    }
12345}
12346
12347impl UnaryRingOp<W104> for Neg<W104> {
12348    type Operand = u128;
12349    #[inline]
12350    fn apply(a: u128) -> u128 {
12351        const_ring_eval_w104(PrimitiveOp::Sub, 0, a)
12352    }
12353}
12354
12355impl UnaryRingOp<W104> for BNot<W104> {
12356    type Operand = u128;
12357    #[inline]
12358    fn apply(a: u128) -> u128 {
12359        const_ring_eval_w104(PrimitiveOp::Xor, a, u128::MAX >> (128 - 104))
12360    }
12361}
12362
12363impl UnaryRingOp<W104> for Succ<W104> {
12364    type Operand = u128;
12365    #[inline]
12366    fn apply(a: u128) -> u128 {
12367        <Neg<W104> as UnaryRingOp<W104>>::apply(<BNot<W104> as UnaryRingOp<W104>>::apply(a))
12368    }
12369}
12370
12371impl UnaryRingOp<W112> for Neg<W112> {
12372    type Operand = u128;
12373    #[inline]
12374    fn apply(a: u128) -> u128 {
12375        const_ring_eval_w112(PrimitiveOp::Sub, 0, a)
12376    }
12377}
12378
12379impl UnaryRingOp<W112> for BNot<W112> {
12380    type Operand = u128;
12381    #[inline]
12382    fn apply(a: u128) -> u128 {
12383        const_ring_eval_w112(PrimitiveOp::Xor, a, u128::MAX >> (128 - 112))
12384    }
12385}
12386
12387impl UnaryRingOp<W112> for Succ<W112> {
12388    type Operand = u128;
12389    #[inline]
12390    fn apply(a: u128) -> u128 {
12391        <Neg<W112> as UnaryRingOp<W112>>::apply(<BNot<W112> as UnaryRingOp<W112>>::apply(a))
12392    }
12393}
12394
12395impl UnaryRingOp<W120> for Neg<W120> {
12396    type Operand = u128;
12397    #[inline]
12398    fn apply(a: u128) -> u128 {
12399        const_ring_eval_w120(PrimitiveOp::Sub, 0, a)
12400    }
12401}
12402
12403impl UnaryRingOp<W120> for BNot<W120> {
12404    type Operand = u128;
12405    #[inline]
12406    fn apply(a: u128) -> u128 {
12407        const_ring_eval_w120(PrimitiveOp::Xor, a, u128::MAX >> (128 - 120))
12408    }
12409}
12410
12411impl UnaryRingOp<W120> for Succ<W120> {
12412    type Operand = u128;
12413    #[inline]
12414    fn apply(a: u128) -> u128 {
12415        <Neg<W120> as UnaryRingOp<W120>>::apply(<BNot<W120> as UnaryRingOp<W120>>::apply(a))
12416    }
12417}
12418
12419impl UnaryRingOp<W128> for Neg<W128> {
12420    type Operand = u128;
12421    #[inline]
12422    fn apply(a: u128) -> u128 {
12423        const_ring_eval_w128(PrimitiveOp::Sub, 0, a)
12424    }
12425}
12426
12427impl UnaryRingOp<W128> for BNot<W128> {
12428    type Operand = u128;
12429    #[inline]
12430    fn apply(a: u128) -> u128 {
12431        const_ring_eval_w128(PrimitiveOp::Xor, a, u128::MAX)
12432    }
12433}
12434
12435impl UnaryRingOp<W128> for Succ<W128> {
12436    type Operand = u128;
12437    #[inline]
12438    fn apply(a: u128) -> u128 {
12439        <Neg<W128> as UnaryRingOp<W128>>::apply(<BNot<W128> as UnaryRingOp<W128>>::apply(a))
12440    }
12441}
12442
12443/// Sealed marker for well-formed level embedding pairs (`(From, To)` with
12444/// `From <= To`). v0.2.2 W3.
12445pub trait ValidLevelEmbedding: valid_level_embedding_sealed::Sealed {}
12446
12447mod valid_level_embedding_sealed {
12448    /// Private supertrait. Not implementable outside this crate.
12449    pub trait Sealed {}
12450    impl Sealed for (super::W8, super::W8) {}
12451    impl Sealed for (super::W8, super::W16) {}
12452    impl Sealed for (super::W8, super::W24) {}
12453    impl Sealed for (super::W8, super::W32) {}
12454    impl Sealed for (super::W8, super::W40) {}
12455    impl Sealed for (super::W8, super::W48) {}
12456    impl Sealed for (super::W8, super::W56) {}
12457    impl Sealed for (super::W8, super::W64) {}
12458    impl Sealed for (super::W8, super::W72) {}
12459    impl Sealed for (super::W8, super::W80) {}
12460    impl Sealed for (super::W8, super::W88) {}
12461    impl Sealed for (super::W8, super::W96) {}
12462    impl Sealed for (super::W8, super::W104) {}
12463    impl Sealed for (super::W8, super::W112) {}
12464    impl Sealed for (super::W8, super::W120) {}
12465    impl Sealed for (super::W8, super::W128) {}
12466    impl Sealed for (super::W16, super::W16) {}
12467    impl Sealed for (super::W16, super::W24) {}
12468    impl Sealed for (super::W16, super::W32) {}
12469    impl Sealed for (super::W16, super::W40) {}
12470    impl Sealed for (super::W16, super::W48) {}
12471    impl Sealed for (super::W16, super::W56) {}
12472    impl Sealed for (super::W16, super::W64) {}
12473    impl Sealed for (super::W16, super::W72) {}
12474    impl Sealed for (super::W16, super::W80) {}
12475    impl Sealed for (super::W16, super::W88) {}
12476    impl Sealed for (super::W16, super::W96) {}
12477    impl Sealed for (super::W16, super::W104) {}
12478    impl Sealed for (super::W16, super::W112) {}
12479    impl Sealed for (super::W16, super::W120) {}
12480    impl Sealed for (super::W16, super::W128) {}
12481    impl Sealed for (super::W24, super::W24) {}
12482    impl Sealed for (super::W24, super::W32) {}
12483    impl Sealed for (super::W24, super::W40) {}
12484    impl Sealed for (super::W24, super::W48) {}
12485    impl Sealed for (super::W24, super::W56) {}
12486    impl Sealed for (super::W24, super::W64) {}
12487    impl Sealed for (super::W24, super::W72) {}
12488    impl Sealed for (super::W24, super::W80) {}
12489    impl Sealed for (super::W24, super::W88) {}
12490    impl Sealed for (super::W24, super::W96) {}
12491    impl Sealed for (super::W24, super::W104) {}
12492    impl Sealed for (super::W24, super::W112) {}
12493    impl Sealed for (super::W24, super::W120) {}
12494    impl Sealed for (super::W24, super::W128) {}
12495    impl Sealed for (super::W32, super::W32) {}
12496    impl Sealed for (super::W32, super::W40) {}
12497    impl Sealed for (super::W32, super::W48) {}
12498    impl Sealed for (super::W32, super::W56) {}
12499    impl Sealed for (super::W32, super::W64) {}
12500    impl Sealed for (super::W32, super::W72) {}
12501    impl Sealed for (super::W32, super::W80) {}
12502    impl Sealed for (super::W32, super::W88) {}
12503    impl Sealed for (super::W32, super::W96) {}
12504    impl Sealed for (super::W32, super::W104) {}
12505    impl Sealed for (super::W32, super::W112) {}
12506    impl Sealed for (super::W32, super::W120) {}
12507    impl Sealed for (super::W32, super::W128) {}
12508    impl Sealed for (super::W40, super::W40) {}
12509    impl Sealed for (super::W40, super::W48) {}
12510    impl Sealed for (super::W40, super::W56) {}
12511    impl Sealed for (super::W40, super::W64) {}
12512    impl Sealed for (super::W40, super::W72) {}
12513    impl Sealed for (super::W40, super::W80) {}
12514    impl Sealed for (super::W40, super::W88) {}
12515    impl Sealed for (super::W40, super::W96) {}
12516    impl Sealed for (super::W40, super::W104) {}
12517    impl Sealed for (super::W40, super::W112) {}
12518    impl Sealed for (super::W40, super::W120) {}
12519    impl Sealed for (super::W40, super::W128) {}
12520    impl Sealed for (super::W48, super::W48) {}
12521    impl Sealed for (super::W48, super::W56) {}
12522    impl Sealed for (super::W48, super::W64) {}
12523    impl Sealed for (super::W48, super::W72) {}
12524    impl Sealed for (super::W48, super::W80) {}
12525    impl Sealed for (super::W48, super::W88) {}
12526    impl Sealed for (super::W48, super::W96) {}
12527    impl Sealed for (super::W48, super::W104) {}
12528    impl Sealed for (super::W48, super::W112) {}
12529    impl Sealed for (super::W48, super::W120) {}
12530    impl Sealed for (super::W48, super::W128) {}
12531    impl Sealed for (super::W56, super::W56) {}
12532    impl Sealed for (super::W56, super::W64) {}
12533    impl Sealed for (super::W56, super::W72) {}
12534    impl Sealed for (super::W56, super::W80) {}
12535    impl Sealed for (super::W56, super::W88) {}
12536    impl Sealed for (super::W56, super::W96) {}
12537    impl Sealed for (super::W56, super::W104) {}
12538    impl Sealed for (super::W56, super::W112) {}
12539    impl Sealed for (super::W56, super::W120) {}
12540    impl Sealed for (super::W56, super::W128) {}
12541    impl Sealed for (super::W64, super::W64) {}
12542    impl Sealed for (super::W64, super::W72) {}
12543    impl Sealed for (super::W64, super::W80) {}
12544    impl Sealed for (super::W64, super::W88) {}
12545    impl Sealed for (super::W64, super::W96) {}
12546    impl Sealed for (super::W64, super::W104) {}
12547    impl Sealed for (super::W64, super::W112) {}
12548    impl Sealed for (super::W64, super::W120) {}
12549    impl Sealed for (super::W64, super::W128) {}
12550    impl Sealed for (super::W72, super::W72) {}
12551    impl Sealed for (super::W72, super::W80) {}
12552    impl Sealed for (super::W72, super::W88) {}
12553    impl Sealed for (super::W72, super::W96) {}
12554    impl Sealed for (super::W72, super::W104) {}
12555    impl Sealed for (super::W72, super::W112) {}
12556    impl Sealed for (super::W72, super::W120) {}
12557    impl Sealed for (super::W72, super::W128) {}
12558    impl Sealed for (super::W80, super::W80) {}
12559    impl Sealed for (super::W80, super::W88) {}
12560    impl Sealed for (super::W80, super::W96) {}
12561    impl Sealed for (super::W80, super::W104) {}
12562    impl Sealed for (super::W80, super::W112) {}
12563    impl Sealed for (super::W80, super::W120) {}
12564    impl Sealed for (super::W80, super::W128) {}
12565    impl Sealed for (super::W88, super::W88) {}
12566    impl Sealed for (super::W88, super::W96) {}
12567    impl Sealed for (super::W88, super::W104) {}
12568    impl Sealed for (super::W88, super::W112) {}
12569    impl Sealed for (super::W88, super::W120) {}
12570    impl Sealed for (super::W88, super::W128) {}
12571    impl Sealed for (super::W96, super::W96) {}
12572    impl Sealed for (super::W96, super::W104) {}
12573    impl Sealed for (super::W96, super::W112) {}
12574    impl Sealed for (super::W96, super::W120) {}
12575    impl Sealed for (super::W96, super::W128) {}
12576    impl Sealed for (super::W104, super::W104) {}
12577    impl Sealed for (super::W104, super::W112) {}
12578    impl Sealed for (super::W104, super::W120) {}
12579    impl Sealed for (super::W104, super::W128) {}
12580    impl Sealed for (super::W112, super::W112) {}
12581    impl Sealed for (super::W112, super::W120) {}
12582    impl Sealed for (super::W112, super::W128) {}
12583    impl Sealed for (super::W120, super::W120) {}
12584    impl Sealed for (super::W120, super::W128) {}
12585    impl Sealed for (super::W128, super::W128) {}
12586}
12587
12588impl ValidLevelEmbedding for (W8, W8) {}
12589impl ValidLevelEmbedding for (W8, W16) {}
12590impl ValidLevelEmbedding for (W8, W24) {}
12591impl ValidLevelEmbedding for (W8, W32) {}
12592impl ValidLevelEmbedding for (W8, W40) {}
12593impl ValidLevelEmbedding for (W8, W48) {}
12594impl ValidLevelEmbedding for (W8, W56) {}
12595impl ValidLevelEmbedding for (W8, W64) {}
12596impl ValidLevelEmbedding for (W8, W72) {}
12597impl ValidLevelEmbedding for (W8, W80) {}
12598impl ValidLevelEmbedding for (W8, W88) {}
12599impl ValidLevelEmbedding for (W8, W96) {}
12600impl ValidLevelEmbedding for (W8, W104) {}
12601impl ValidLevelEmbedding for (W8, W112) {}
12602impl ValidLevelEmbedding for (W8, W120) {}
12603impl ValidLevelEmbedding for (W8, W128) {}
12604impl ValidLevelEmbedding for (W16, W16) {}
12605impl ValidLevelEmbedding for (W16, W24) {}
12606impl ValidLevelEmbedding for (W16, W32) {}
12607impl ValidLevelEmbedding for (W16, W40) {}
12608impl ValidLevelEmbedding for (W16, W48) {}
12609impl ValidLevelEmbedding for (W16, W56) {}
12610impl ValidLevelEmbedding for (W16, W64) {}
12611impl ValidLevelEmbedding for (W16, W72) {}
12612impl ValidLevelEmbedding for (W16, W80) {}
12613impl ValidLevelEmbedding for (W16, W88) {}
12614impl ValidLevelEmbedding for (W16, W96) {}
12615impl ValidLevelEmbedding for (W16, W104) {}
12616impl ValidLevelEmbedding for (W16, W112) {}
12617impl ValidLevelEmbedding for (W16, W120) {}
12618impl ValidLevelEmbedding for (W16, W128) {}
12619impl ValidLevelEmbedding for (W24, W24) {}
12620impl ValidLevelEmbedding for (W24, W32) {}
12621impl ValidLevelEmbedding for (W24, W40) {}
12622impl ValidLevelEmbedding for (W24, W48) {}
12623impl ValidLevelEmbedding for (W24, W56) {}
12624impl ValidLevelEmbedding for (W24, W64) {}
12625impl ValidLevelEmbedding for (W24, W72) {}
12626impl ValidLevelEmbedding for (W24, W80) {}
12627impl ValidLevelEmbedding for (W24, W88) {}
12628impl ValidLevelEmbedding for (W24, W96) {}
12629impl ValidLevelEmbedding for (W24, W104) {}
12630impl ValidLevelEmbedding for (W24, W112) {}
12631impl ValidLevelEmbedding for (W24, W120) {}
12632impl ValidLevelEmbedding for (W24, W128) {}
12633impl ValidLevelEmbedding for (W32, W32) {}
12634impl ValidLevelEmbedding for (W32, W40) {}
12635impl ValidLevelEmbedding for (W32, W48) {}
12636impl ValidLevelEmbedding for (W32, W56) {}
12637impl ValidLevelEmbedding for (W32, W64) {}
12638impl ValidLevelEmbedding for (W32, W72) {}
12639impl ValidLevelEmbedding for (W32, W80) {}
12640impl ValidLevelEmbedding for (W32, W88) {}
12641impl ValidLevelEmbedding for (W32, W96) {}
12642impl ValidLevelEmbedding for (W32, W104) {}
12643impl ValidLevelEmbedding for (W32, W112) {}
12644impl ValidLevelEmbedding for (W32, W120) {}
12645impl ValidLevelEmbedding for (W32, W128) {}
12646impl ValidLevelEmbedding for (W40, W40) {}
12647impl ValidLevelEmbedding for (W40, W48) {}
12648impl ValidLevelEmbedding for (W40, W56) {}
12649impl ValidLevelEmbedding for (W40, W64) {}
12650impl ValidLevelEmbedding for (W40, W72) {}
12651impl ValidLevelEmbedding for (W40, W80) {}
12652impl ValidLevelEmbedding for (W40, W88) {}
12653impl ValidLevelEmbedding for (W40, W96) {}
12654impl ValidLevelEmbedding for (W40, W104) {}
12655impl ValidLevelEmbedding for (W40, W112) {}
12656impl ValidLevelEmbedding for (W40, W120) {}
12657impl ValidLevelEmbedding for (W40, W128) {}
12658impl ValidLevelEmbedding for (W48, W48) {}
12659impl ValidLevelEmbedding for (W48, W56) {}
12660impl ValidLevelEmbedding for (W48, W64) {}
12661impl ValidLevelEmbedding for (W48, W72) {}
12662impl ValidLevelEmbedding for (W48, W80) {}
12663impl ValidLevelEmbedding for (W48, W88) {}
12664impl ValidLevelEmbedding for (W48, W96) {}
12665impl ValidLevelEmbedding for (W48, W104) {}
12666impl ValidLevelEmbedding for (W48, W112) {}
12667impl ValidLevelEmbedding for (W48, W120) {}
12668impl ValidLevelEmbedding for (W48, W128) {}
12669impl ValidLevelEmbedding for (W56, W56) {}
12670impl ValidLevelEmbedding for (W56, W64) {}
12671impl ValidLevelEmbedding for (W56, W72) {}
12672impl ValidLevelEmbedding for (W56, W80) {}
12673impl ValidLevelEmbedding for (W56, W88) {}
12674impl ValidLevelEmbedding for (W56, W96) {}
12675impl ValidLevelEmbedding for (W56, W104) {}
12676impl ValidLevelEmbedding for (W56, W112) {}
12677impl ValidLevelEmbedding for (W56, W120) {}
12678impl ValidLevelEmbedding for (W56, W128) {}
12679impl ValidLevelEmbedding for (W64, W64) {}
12680impl ValidLevelEmbedding for (W64, W72) {}
12681impl ValidLevelEmbedding for (W64, W80) {}
12682impl ValidLevelEmbedding for (W64, W88) {}
12683impl ValidLevelEmbedding for (W64, W96) {}
12684impl ValidLevelEmbedding for (W64, W104) {}
12685impl ValidLevelEmbedding for (W64, W112) {}
12686impl ValidLevelEmbedding for (W64, W120) {}
12687impl ValidLevelEmbedding for (W64, W128) {}
12688impl ValidLevelEmbedding for (W72, W72) {}
12689impl ValidLevelEmbedding for (W72, W80) {}
12690impl ValidLevelEmbedding for (W72, W88) {}
12691impl ValidLevelEmbedding for (W72, W96) {}
12692impl ValidLevelEmbedding for (W72, W104) {}
12693impl ValidLevelEmbedding for (W72, W112) {}
12694impl ValidLevelEmbedding for (W72, W120) {}
12695impl ValidLevelEmbedding for (W72, W128) {}
12696impl ValidLevelEmbedding for (W80, W80) {}
12697impl ValidLevelEmbedding for (W80, W88) {}
12698impl ValidLevelEmbedding for (W80, W96) {}
12699impl ValidLevelEmbedding for (W80, W104) {}
12700impl ValidLevelEmbedding for (W80, W112) {}
12701impl ValidLevelEmbedding for (W80, W120) {}
12702impl ValidLevelEmbedding for (W80, W128) {}
12703impl ValidLevelEmbedding for (W88, W88) {}
12704impl ValidLevelEmbedding for (W88, W96) {}
12705impl ValidLevelEmbedding for (W88, W104) {}
12706impl ValidLevelEmbedding for (W88, W112) {}
12707impl ValidLevelEmbedding for (W88, W120) {}
12708impl ValidLevelEmbedding for (W88, W128) {}
12709impl ValidLevelEmbedding for (W96, W96) {}
12710impl ValidLevelEmbedding for (W96, W104) {}
12711impl ValidLevelEmbedding for (W96, W112) {}
12712impl ValidLevelEmbedding for (W96, W120) {}
12713impl ValidLevelEmbedding for (W96, W128) {}
12714impl ValidLevelEmbedding for (W104, W104) {}
12715impl ValidLevelEmbedding for (W104, W112) {}
12716impl ValidLevelEmbedding for (W104, W120) {}
12717impl ValidLevelEmbedding for (W104, W128) {}
12718impl ValidLevelEmbedding for (W112, W112) {}
12719impl ValidLevelEmbedding for (W112, W120) {}
12720impl ValidLevelEmbedding for (W112, W128) {}
12721impl ValidLevelEmbedding for (W120, W120) {}
12722impl ValidLevelEmbedding for (W120, W128) {}
12723impl ValidLevelEmbedding for (W128, W128) {}
12724
12725/// v0.2.2 W3: phantom-typed level embedding `Embed<From, To>` for the
12726/// canonical injection ι : R_From → R_To when `From <= To`.
12727/// Implementations exist only for sealed `(From, To)` pairs in the
12728/// `ValidLevelEmbedding` trait, so attempting an unsupported direction
12729/// (e.g., `Embed<W32, W8>`) fails at compile time.
12730#[derive(Debug, Default, Clone, Copy)]
12731pub struct Embed<From, To>(PhantomData<(From, To)>);
12732
12733impl Embed<W8, W8> {
12734    /// Embed a `u8` value at W8 into a `u8` value at W8.
12735    #[inline]
12736    #[must_use]
12737    pub const fn apply(value: u8) -> u8 {
12738        value
12739    }
12740}
12741
12742impl Embed<W8, W16> {
12743    /// Embed a `u8` value at W8 into a `u16` value at W16.
12744    #[inline]
12745    #[must_use]
12746    pub const fn apply(value: u8) -> u16 {
12747        value as u16
12748    }
12749}
12750
12751impl Embed<W8, W24> {
12752    /// Embed a `u8` value at W8 into a `u32` value at W24.
12753    #[inline]
12754    #[must_use]
12755    pub const fn apply(value: u8) -> u32 {
12756        value as u32
12757    }
12758}
12759
12760impl Embed<W8, W32> {
12761    /// Embed a `u8` value at W8 into a `u32` value at W32.
12762    #[inline]
12763    #[must_use]
12764    pub const fn apply(value: u8) -> u32 {
12765        value as u32
12766    }
12767}
12768
12769impl Embed<W8, W40> {
12770    /// Embed a `u8` value at W8 into a `u64` value at W40.
12771    #[inline]
12772    #[must_use]
12773    pub const fn apply(value: u8) -> u64 {
12774        value as u64
12775    }
12776}
12777
12778impl Embed<W8, W48> {
12779    /// Embed a `u8` value at W8 into a `u64` value at W48.
12780    #[inline]
12781    #[must_use]
12782    pub const fn apply(value: u8) -> u64 {
12783        value as u64
12784    }
12785}
12786
12787impl Embed<W8, W56> {
12788    /// Embed a `u8` value at W8 into a `u64` value at W56.
12789    #[inline]
12790    #[must_use]
12791    pub const fn apply(value: u8) -> u64 {
12792        value as u64
12793    }
12794}
12795
12796impl Embed<W8, W64> {
12797    /// Embed a `u8` value at W8 into a `u64` value at W64.
12798    #[inline]
12799    #[must_use]
12800    pub const fn apply(value: u8) -> u64 {
12801        value as u64
12802    }
12803}
12804
12805impl Embed<W8, W72> {
12806    /// Embed a `u8` value at W8 into a `u128` value at W72.
12807    #[inline]
12808    #[must_use]
12809    pub const fn apply(value: u8) -> u128 {
12810        value as u128
12811    }
12812}
12813
12814impl Embed<W8, W80> {
12815    /// Embed a `u8` value at W8 into a `u128` value at W80.
12816    #[inline]
12817    #[must_use]
12818    pub const fn apply(value: u8) -> u128 {
12819        value as u128
12820    }
12821}
12822
12823impl Embed<W8, W88> {
12824    /// Embed a `u8` value at W8 into a `u128` value at W88.
12825    #[inline]
12826    #[must_use]
12827    pub const fn apply(value: u8) -> u128 {
12828        value as u128
12829    }
12830}
12831
12832impl Embed<W8, W96> {
12833    /// Embed a `u8` value at W8 into a `u128` value at W96.
12834    #[inline]
12835    #[must_use]
12836    pub const fn apply(value: u8) -> u128 {
12837        value as u128
12838    }
12839}
12840
12841impl Embed<W8, W104> {
12842    /// Embed a `u8` value at W8 into a `u128` value at W104.
12843    #[inline]
12844    #[must_use]
12845    pub const fn apply(value: u8) -> u128 {
12846        value as u128
12847    }
12848}
12849
12850impl Embed<W8, W112> {
12851    /// Embed a `u8` value at W8 into a `u128` value at W112.
12852    #[inline]
12853    #[must_use]
12854    pub const fn apply(value: u8) -> u128 {
12855        value as u128
12856    }
12857}
12858
12859impl Embed<W8, W120> {
12860    /// Embed a `u8` value at W8 into a `u128` value at W120.
12861    #[inline]
12862    #[must_use]
12863    pub const fn apply(value: u8) -> u128 {
12864        value as u128
12865    }
12866}
12867
12868impl Embed<W8, W128> {
12869    /// Embed a `u8` value at W8 into a `u128` value at W128.
12870    #[inline]
12871    #[must_use]
12872    pub const fn apply(value: u8) -> u128 {
12873        value as u128
12874    }
12875}
12876
12877impl Embed<W16, W16> {
12878    /// Embed a `u16` value at W16 into a `u16` value at W16.
12879    #[inline]
12880    #[must_use]
12881    pub const fn apply(value: u16) -> u16 {
12882        value
12883    }
12884}
12885
12886impl Embed<W16, W24> {
12887    /// Embed a `u16` value at W16 into a `u32` value at W24.
12888    #[inline]
12889    #[must_use]
12890    pub const fn apply(value: u16) -> u32 {
12891        value as u32
12892    }
12893}
12894
12895impl Embed<W16, W32> {
12896    /// Embed a `u16` value at W16 into a `u32` value at W32.
12897    #[inline]
12898    #[must_use]
12899    pub const fn apply(value: u16) -> u32 {
12900        value as u32
12901    }
12902}
12903
12904impl Embed<W16, W40> {
12905    /// Embed a `u16` value at W16 into a `u64` value at W40.
12906    #[inline]
12907    #[must_use]
12908    pub const fn apply(value: u16) -> u64 {
12909        value as u64
12910    }
12911}
12912
12913impl Embed<W16, W48> {
12914    /// Embed a `u16` value at W16 into a `u64` value at W48.
12915    #[inline]
12916    #[must_use]
12917    pub const fn apply(value: u16) -> u64 {
12918        value as u64
12919    }
12920}
12921
12922impl Embed<W16, W56> {
12923    /// Embed a `u16` value at W16 into a `u64` value at W56.
12924    #[inline]
12925    #[must_use]
12926    pub const fn apply(value: u16) -> u64 {
12927        value as u64
12928    }
12929}
12930
12931impl Embed<W16, W64> {
12932    /// Embed a `u16` value at W16 into a `u64` value at W64.
12933    #[inline]
12934    #[must_use]
12935    pub const fn apply(value: u16) -> u64 {
12936        value as u64
12937    }
12938}
12939
12940impl Embed<W16, W72> {
12941    /// Embed a `u16` value at W16 into a `u128` value at W72.
12942    #[inline]
12943    #[must_use]
12944    pub const fn apply(value: u16) -> u128 {
12945        value as u128
12946    }
12947}
12948
12949impl Embed<W16, W80> {
12950    /// Embed a `u16` value at W16 into a `u128` value at W80.
12951    #[inline]
12952    #[must_use]
12953    pub const fn apply(value: u16) -> u128 {
12954        value as u128
12955    }
12956}
12957
12958impl Embed<W16, W88> {
12959    /// Embed a `u16` value at W16 into a `u128` value at W88.
12960    #[inline]
12961    #[must_use]
12962    pub const fn apply(value: u16) -> u128 {
12963        value as u128
12964    }
12965}
12966
12967impl Embed<W16, W96> {
12968    /// Embed a `u16` value at W16 into a `u128` value at W96.
12969    #[inline]
12970    #[must_use]
12971    pub const fn apply(value: u16) -> u128 {
12972        value as u128
12973    }
12974}
12975
12976impl Embed<W16, W104> {
12977    /// Embed a `u16` value at W16 into a `u128` value at W104.
12978    #[inline]
12979    #[must_use]
12980    pub const fn apply(value: u16) -> u128 {
12981        value as u128
12982    }
12983}
12984
12985impl Embed<W16, W112> {
12986    /// Embed a `u16` value at W16 into a `u128` value at W112.
12987    #[inline]
12988    #[must_use]
12989    pub const fn apply(value: u16) -> u128 {
12990        value as u128
12991    }
12992}
12993
12994impl Embed<W16, W120> {
12995    /// Embed a `u16` value at W16 into a `u128` value at W120.
12996    #[inline]
12997    #[must_use]
12998    pub const fn apply(value: u16) -> u128 {
12999        value as u128
13000    }
13001}
13002
13003impl Embed<W16, W128> {
13004    /// Embed a `u16` value at W16 into a `u128` value at W128.
13005    #[inline]
13006    #[must_use]
13007    pub const fn apply(value: u16) -> u128 {
13008        value as u128
13009    }
13010}
13011
13012impl Embed<W24, W24> {
13013    /// Embed a `u32` value at W24 into a `u32` value at W24.
13014    #[inline]
13015    #[must_use]
13016    pub const fn apply(value: u32) -> u32 {
13017        value
13018    }
13019}
13020
13021impl Embed<W24, W32> {
13022    /// Embed a `u32` value at W24 into a `u32` value at W32.
13023    #[inline]
13024    #[must_use]
13025    pub const fn apply(value: u32) -> u32 {
13026        value
13027    }
13028}
13029
13030impl Embed<W24, W40> {
13031    /// Embed a `u32` value at W24 into a `u64` value at W40.
13032    #[inline]
13033    #[must_use]
13034    pub const fn apply(value: u32) -> u64 {
13035        value as u64
13036    }
13037}
13038
13039impl Embed<W24, W48> {
13040    /// Embed a `u32` value at W24 into a `u64` value at W48.
13041    #[inline]
13042    #[must_use]
13043    pub const fn apply(value: u32) -> u64 {
13044        value as u64
13045    }
13046}
13047
13048impl Embed<W24, W56> {
13049    /// Embed a `u32` value at W24 into a `u64` value at W56.
13050    #[inline]
13051    #[must_use]
13052    pub const fn apply(value: u32) -> u64 {
13053        value as u64
13054    }
13055}
13056
13057impl Embed<W24, W64> {
13058    /// Embed a `u32` value at W24 into a `u64` value at W64.
13059    #[inline]
13060    #[must_use]
13061    pub const fn apply(value: u32) -> u64 {
13062        value as u64
13063    }
13064}
13065
13066impl Embed<W24, W72> {
13067    /// Embed a `u32` value at W24 into a `u128` value at W72.
13068    #[inline]
13069    #[must_use]
13070    pub const fn apply(value: u32) -> u128 {
13071        value as u128
13072    }
13073}
13074
13075impl Embed<W24, W80> {
13076    /// Embed a `u32` value at W24 into a `u128` value at W80.
13077    #[inline]
13078    #[must_use]
13079    pub const fn apply(value: u32) -> u128 {
13080        value as u128
13081    }
13082}
13083
13084impl Embed<W24, W88> {
13085    /// Embed a `u32` value at W24 into a `u128` value at W88.
13086    #[inline]
13087    #[must_use]
13088    pub const fn apply(value: u32) -> u128 {
13089        value as u128
13090    }
13091}
13092
13093impl Embed<W24, W96> {
13094    /// Embed a `u32` value at W24 into a `u128` value at W96.
13095    #[inline]
13096    #[must_use]
13097    pub const fn apply(value: u32) -> u128 {
13098        value as u128
13099    }
13100}
13101
13102impl Embed<W24, W104> {
13103    /// Embed a `u32` value at W24 into a `u128` value at W104.
13104    #[inline]
13105    #[must_use]
13106    pub const fn apply(value: u32) -> u128 {
13107        value as u128
13108    }
13109}
13110
13111impl Embed<W24, W112> {
13112    /// Embed a `u32` value at W24 into a `u128` value at W112.
13113    #[inline]
13114    #[must_use]
13115    pub const fn apply(value: u32) -> u128 {
13116        value as u128
13117    }
13118}
13119
13120impl Embed<W24, W120> {
13121    /// Embed a `u32` value at W24 into a `u128` value at W120.
13122    #[inline]
13123    #[must_use]
13124    pub const fn apply(value: u32) -> u128 {
13125        value as u128
13126    }
13127}
13128
13129impl Embed<W24, W128> {
13130    /// Embed a `u32` value at W24 into a `u128` value at W128.
13131    #[inline]
13132    #[must_use]
13133    pub const fn apply(value: u32) -> u128 {
13134        value as u128
13135    }
13136}
13137
13138impl Embed<W32, W32> {
13139    /// Embed a `u32` value at W32 into a `u32` value at W32.
13140    #[inline]
13141    #[must_use]
13142    pub const fn apply(value: u32) -> u32 {
13143        value
13144    }
13145}
13146
13147impl Embed<W32, W40> {
13148    /// Embed a `u32` value at W32 into a `u64` value at W40.
13149    #[inline]
13150    #[must_use]
13151    pub const fn apply(value: u32) -> u64 {
13152        value as u64
13153    }
13154}
13155
13156impl Embed<W32, W48> {
13157    /// Embed a `u32` value at W32 into a `u64` value at W48.
13158    #[inline]
13159    #[must_use]
13160    pub const fn apply(value: u32) -> u64 {
13161        value as u64
13162    }
13163}
13164
13165impl Embed<W32, W56> {
13166    /// Embed a `u32` value at W32 into a `u64` value at W56.
13167    #[inline]
13168    #[must_use]
13169    pub const fn apply(value: u32) -> u64 {
13170        value as u64
13171    }
13172}
13173
13174impl Embed<W32, W64> {
13175    /// Embed a `u32` value at W32 into a `u64` value at W64.
13176    #[inline]
13177    #[must_use]
13178    pub const fn apply(value: u32) -> u64 {
13179        value as u64
13180    }
13181}
13182
13183impl Embed<W32, W72> {
13184    /// Embed a `u32` value at W32 into a `u128` value at W72.
13185    #[inline]
13186    #[must_use]
13187    pub const fn apply(value: u32) -> u128 {
13188        value as u128
13189    }
13190}
13191
13192impl Embed<W32, W80> {
13193    /// Embed a `u32` value at W32 into a `u128` value at W80.
13194    #[inline]
13195    #[must_use]
13196    pub const fn apply(value: u32) -> u128 {
13197        value as u128
13198    }
13199}
13200
13201impl Embed<W32, W88> {
13202    /// Embed a `u32` value at W32 into a `u128` value at W88.
13203    #[inline]
13204    #[must_use]
13205    pub const fn apply(value: u32) -> u128 {
13206        value as u128
13207    }
13208}
13209
13210impl Embed<W32, W96> {
13211    /// Embed a `u32` value at W32 into a `u128` value at W96.
13212    #[inline]
13213    #[must_use]
13214    pub const fn apply(value: u32) -> u128 {
13215        value as u128
13216    }
13217}
13218
13219impl Embed<W32, W104> {
13220    /// Embed a `u32` value at W32 into a `u128` value at W104.
13221    #[inline]
13222    #[must_use]
13223    pub const fn apply(value: u32) -> u128 {
13224        value as u128
13225    }
13226}
13227
13228impl Embed<W32, W112> {
13229    /// Embed a `u32` value at W32 into a `u128` value at W112.
13230    #[inline]
13231    #[must_use]
13232    pub const fn apply(value: u32) -> u128 {
13233        value as u128
13234    }
13235}
13236
13237impl Embed<W32, W120> {
13238    /// Embed a `u32` value at W32 into a `u128` value at W120.
13239    #[inline]
13240    #[must_use]
13241    pub const fn apply(value: u32) -> u128 {
13242        value as u128
13243    }
13244}
13245
13246impl Embed<W32, W128> {
13247    /// Embed a `u32` value at W32 into a `u128` value at W128.
13248    #[inline]
13249    #[must_use]
13250    pub const fn apply(value: u32) -> u128 {
13251        value as u128
13252    }
13253}
13254
13255impl Embed<W40, W40> {
13256    /// Embed a `u64` value at W40 into a `u64` value at W40.
13257    #[inline]
13258    #[must_use]
13259    pub const fn apply(value: u64) -> u64 {
13260        value
13261    }
13262}
13263
13264impl Embed<W40, W48> {
13265    /// Embed a `u64` value at W40 into a `u64` value at W48.
13266    #[inline]
13267    #[must_use]
13268    pub const fn apply(value: u64) -> u64 {
13269        value
13270    }
13271}
13272
13273impl Embed<W40, W56> {
13274    /// Embed a `u64` value at W40 into a `u64` value at W56.
13275    #[inline]
13276    #[must_use]
13277    pub const fn apply(value: u64) -> u64 {
13278        value
13279    }
13280}
13281
13282impl Embed<W40, W64> {
13283    /// Embed a `u64` value at W40 into a `u64` value at W64.
13284    #[inline]
13285    #[must_use]
13286    pub const fn apply(value: u64) -> u64 {
13287        value
13288    }
13289}
13290
13291impl Embed<W40, W72> {
13292    /// Embed a `u64` value at W40 into a `u128` value at W72.
13293    #[inline]
13294    #[must_use]
13295    pub const fn apply(value: u64) -> u128 {
13296        value as u128
13297    }
13298}
13299
13300impl Embed<W40, W80> {
13301    /// Embed a `u64` value at W40 into a `u128` value at W80.
13302    #[inline]
13303    #[must_use]
13304    pub const fn apply(value: u64) -> u128 {
13305        value as u128
13306    }
13307}
13308
13309impl Embed<W40, W88> {
13310    /// Embed a `u64` value at W40 into a `u128` value at W88.
13311    #[inline]
13312    #[must_use]
13313    pub const fn apply(value: u64) -> u128 {
13314        value as u128
13315    }
13316}
13317
13318impl Embed<W40, W96> {
13319    /// Embed a `u64` value at W40 into a `u128` value at W96.
13320    #[inline]
13321    #[must_use]
13322    pub const fn apply(value: u64) -> u128 {
13323        value as u128
13324    }
13325}
13326
13327impl Embed<W40, W104> {
13328    /// Embed a `u64` value at W40 into a `u128` value at W104.
13329    #[inline]
13330    #[must_use]
13331    pub const fn apply(value: u64) -> u128 {
13332        value as u128
13333    }
13334}
13335
13336impl Embed<W40, W112> {
13337    /// Embed a `u64` value at W40 into a `u128` value at W112.
13338    #[inline]
13339    #[must_use]
13340    pub const fn apply(value: u64) -> u128 {
13341        value as u128
13342    }
13343}
13344
13345impl Embed<W40, W120> {
13346    /// Embed a `u64` value at W40 into a `u128` value at W120.
13347    #[inline]
13348    #[must_use]
13349    pub const fn apply(value: u64) -> u128 {
13350        value as u128
13351    }
13352}
13353
13354impl Embed<W40, W128> {
13355    /// Embed a `u64` value at W40 into a `u128` value at W128.
13356    #[inline]
13357    #[must_use]
13358    pub const fn apply(value: u64) -> u128 {
13359        value as u128
13360    }
13361}
13362
13363impl Embed<W48, W48> {
13364    /// Embed a `u64` value at W48 into a `u64` value at W48.
13365    #[inline]
13366    #[must_use]
13367    pub const fn apply(value: u64) -> u64 {
13368        value
13369    }
13370}
13371
13372impl Embed<W48, W56> {
13373    /// Embed a `u64` value at W48 into a `u64` value at W56.
13374    #[inline]
13375    #[must_use]
13376    pub const fn apply(value: u64) -> u64 {
13377        value
13378    }
13379}
13380
13381impl Embed<W48, W64> {
13382    /// Embed a `u64` value at W48 into a `u64` value at W64.
13383    #[inline]
13384    #[must_use]
13385    pub const fn apply(value: u64) -> u64 {
13386        value
13387    }
13388}
13389
13390impl Embed<W48, W72> {
13391    /// Embed a `u64` value at W48 into a `u128` value at W72.
13392    #[inline]
13393    #[must_use]
13394    pub const fn apply(value: u64) -> u128 {
13395        value as u128
13396    }
13397}
13398
13399impl Embed<W48, W80> {
13400    /// Embed a `u64` value at W48 into a `u128` value at W80.
13401    #[inline]
13402    #[must_use]
13403    pub const fn apply(value: u64) -> u128 {
13404        value as u128
13405    }
13406}
13407
13408impl Embed<W48, W88> {
13409    /// Embed a `u64` value at W48 into a `u128` value at W88.
13410    #[inline]
13411    #[must_use]
13412    pub const fn apply(value: u64) -> u128 {
13413        value as u128
13414    }
13415}
13416
13417impl Embed<W48, W96> {
13418    /// Embed a `u64` value at W48 into a `u128` value at W96.
13419    #[inline]
13420    #[must_use]
13421    pub const fn apply(value: u64) -> u128 {
13422        value as u128
13423    }
13424}
13425
13426impl Embed<W48, W104> {
13427    /// Embed a `u64` value at W48 into a `u128` value at W104.
13428    #[inline]
13429    #[must_use]
13430    pub const fn apply(value: u64) -> u128 {
13431        value as u128
13432    }
13433}
13434
13435impl Embed<W48, W112> {
13436    /// Embed a `u64` value at W48 into a `u128` value at W112.
13437    #[inline]
13438    #[must_use]
13439    pub const fn apply(value: u64) -> u128 {
13440        value as u128
13441    }
13442}
13443
13444impl Embed<W48, W120> {
13445    /// Embed a `u64` value at W48 into a `u128` value at W120.
13446    #[inline]
13447    #[must_use]
13448    pub const fn apply(value: u64) -> u128 {
13449        value as u128
13450    }
13451}
13452
13453impl Embed<W48, W128> {
13454    /// Embed a `u64` value at W48 into a `u128` value at W128.
13455    #[inline]
13456    #[must_use]
13457    pub const fn apply(value: u64) -> u128 {
13458        value as u128
13459    }
13460}
13461
13462impl Embed<W56, W56> {
13463    /// Embed a `u64` value at W56 into a `u64` value at W56.
13464    #[inline]
13465    #[must_use]
13466    pub const fn apply(value: u64) -> u64 {
13467        value
13468    }
13469}
13470
13471impl Embed<W56, W64> {
13472    /// Embed a `u64` value at W56 into a `u64` value at W64.
13473    #[inline]
13474    #[must_use]
13475    pub const fn apply(value: u64) -> u64 {
13476        value
13477    }
13478}
13479
13480impl Embed<W56, W72> {
13481    /// Embed a `u64` value at W56 into a `u128` value at W72.
13482    #[inline]
13483    #[must_use]
13484    pub const fn apply(value: u64) -> u128 {
13485        value as u128
13486    }
13487}
13488
13489impl Embed<W56, W80> {
13490    /// Embed a `u64` value at W56 into a `u128` value at W80.
13491    #[inline]
13492    #[must_use]
13493    pub const fn apply(value: u64) -> u128 {
13494        value as u128
13495    }
13496}
13497
13498impl Embed<W56, W88> {
13499    /// Embed a `u64` value at W56 into a `u128` value at W88.
13500    #[inline]
13501    #[must_use]
13502    pub const fn apply(value: u64) -> u128 {
13503        value as u128
13504    }
13505}
13506
13507impl Embed<W56, W96> {
13508    /// Embed a `u64` value at W56 into a `u128` value at W96.
13509    #[inline]
13510    #[must_use]
13511    pub const fn apply(value: u64) -> u128 {
13512        value as u128
13513    }
13514}
13515
13516impl Embed<W56, W104> {
13517    /// Embed a `u64` value at W56 into a `u128` value at W104.
13518    #[inline]
13519    #[must_use]
13520    pub const fn apply(value: u64) -> u128 {
13521        value as u128
13522    }
13523}
13524
13525impl Embed<W56, W112> {
13526    /// Embed a `u64` value at W56 into a `u128` value at W112.
13527    #[inline]
13528    #[must_use]
13529    pub const fn apply(value: u64) -> u128 {
13530        value as u128
13531    }
13532}
13533
13534impl Embed<W56, W120> {
13535    /// Embed a `u64` value at W56 into a `u128` value at W120.
13536    #[inline]
13537    #[must_use]
13538    pub const fn apply(value: u64) -> u128 {
13539        value as u128
13540    }
13541}
13542
13543impl Embed<W56, W128> {
13544    /// Embed a `u64` value at W56 into a `u128` value at W128.
13545    #[inline]
13546    #[must_use]
13547    pub const fn apply(value: u64) -> u128 {
13548        value as u128
13549    }
13550}
13551
13552impl Embed<W64, W64> {
13553    /// Embed a `u64` value at W64 into a `u64` value at W64.
13554    #[inline]
13555    #[must_use]
13556    pub const fn apply(value: u64) -> u64 {
13557        value
13558    }
13559}
13560
13561impl Embed<W64, W72> {
13562    /// Embed a `u64` value at W64 into a `u128` value at W72.
13563    #[inline]
13564    #[must_use]
13565    pub const fn apply(value: u64) -> u128 {
13566        value as u128
13567    }
13568}
13569
13570impl Embed<W64, W80> {
13571    /// Embed a `u64` value at W64 into a `u128` value at W80.
13572    #[inline]
13573    #[must_use]
13574    pub const fn apply(value: u64) -> u128 {
13575        value as u128
13576    }
13577}
13578
13579impl Embed<W64, W88> {
13580    /// Embed a `u64` value at W64 into a `u128` value at W88.
13581    #[inline]
13582    #[must_use]
13583    pub const fn apply(value: u64) -> u128 {
13584        value as u128
13585    }
13586}
13587
13588impl Embed<W64, W96> {
13589    /// Embed a `u64` value at W64 into a `u128` value at W96.
13590    #[inline]
13591    #[must_use]
13592    pub const fn apply(value: u64) -> u128 {
13593        value as u128
13594    }
13595}
13596
13597impl Embed<W64, W104> {
13598    /// Embed a `u64` value at W64 into a `u128` value at W104.
13599    #[inline]
13600    #[must_use]
13601    pub const fn apply(value: u64) -> u128 {
13602        value as u128
13603    }
13604}
13605
13606impl Embed<W64, W112> {
13607    /// Embed a `u64` value at W64 into a `u128` value at W112.
13608    #[inline]
13609    #[must_use]
13610    pub const fn apply(value: u64) -> u128 {
13611        value as u128
13612    }
13613}
13614
13615impl Embed<W64, W120> {
13616    /// Embed a `u64` value at W64 into a `u128` value at W120.
13617    #[inline]
13618    #[must_use]
13619    pub const fn apply(value: u64) -> u128 {
13620        value as u128
13621    }
13622}
13623
13624impl Embed<W64, W128> {
13625    /// Embed a `u64` value at W64 into a `u128` value at W128.
13626    #[inline]
13627    #[must_use]
13628    pub const fn apply(value: u64) -> u128 {
13629        value as u128
13630    }
13631}
13632
13633impl Embed<W72, W72> {
13634    /// Embed a `u128` value at W72 into a `u128` value at W72.
13635    #[inline]
13636    #[must_use]
13637    pub const fn apply(value: u128) -> u128 {
13638        value
13639    }
13640}
13641
13642impl Embed<W72, W80> {
13643    /// Embed a `u128` value at W72 into a `u128` value at W80.
13644    #[inline]
13645    #[must_use]
13646    pub const fn apply(value: u128) -> u128 {
13647        value
13648    }
13649}
13650
13651impl Embed<W72, W88> {
13652    /// Embed a `u128` value at W72 into a `u128` value at W88.
13653    #[inline]
13654    #[must_use]
13655    pub const fn apply(value: u128) -> u128 {
13656        value
13657    }
13658}
13659
13660impl Embed<W72, W96> {
13661    /// Embed a `u128` value at W72 into a `u128` value at W96.
13662    #[inline]
13663    #[must_use]
13664    pub const fn apply(value: u128) -> u128 {
13665        value
13666    }
13667}
13668
13669impl Embed<W72, W104> {
13670    /// Embed a `u128` value at W72 into a `u128` value at W104.
13671    #[inline]
13672    #[must_use]
13673    pub const fn apply(value: u128) -> u128 {
13674        value
13675    }
13676}
13677
13678impl Embed<W72, W112> {
13679    /// Embed a `u128` value at W72 into a `u128` value at W112.
13680    #[inline]
13681    #[must_use]
13682    pub const fn apply(value: u128) -> u128 {
13683        value
13684    }
13685}
13686
13687impl Embed<W72, W120> {
13688    /// Embed a `u128` value at W72 into a `u128` value at W120.
13689    #[inline]
13690    #[must_use]
13691    pub const fn apply(value: u128) -> u128 {
13692        value
13693    }
13694}
13695
13696impl Embed<W72, W128> {
13697    /// Embed a `u128` value at W72 into a `u128` value at W128.
13698    #[inline]
13699    #[must_use]
13700    pub const fn apply(value: u128) -> u128 {
13701        value
13702    }
13703}
13704
13705impl Embed<W80, W80> {
13706    /// Embed a `u128` value at W80 into a `u128` value at W80.
13707    #[inline]
13708    #[must_use]
13709    pub const fn apply(value: u128) -> u128 {
13710        value
13711    }
13712}
13713
13714impl Embed<W80, W88> {
13715    /// Embed a `u128` value at W80 into a `u128` value at W88.
13716    #[inline]
13717    #[must_use]
13718    pub const fn apply(value: u128) -> u128 {
13719        value
13720    }
13721}
13722
13723impl Embed<W80, W96> {
13724    /// Embed a `u128` value at W80 into a `u128` value at W96.
13725    #[inline]
13726    #[must_use]
13727    pub const fn apply(value: u128) -> u128 {
13728        value
13729    }
13730}
13731
13732impl Embed<W80, W104> {
13733    /// Embed a `u128` value at W80 into a `u128` value at W104.
13734    #[inline]
13735    #[must_use]
13736    pub const fn apply(value: u128) -> u128 {
13737        value
13738    }
13739}
13740
13741impl Embed<W80, W112> {
13742    /// Embed a `u128` value at W80 into a `u128` value at W112.
13743    #[inline]
13744    #[must_use]
13745    pub const fn apply(value: u128) -> u128 {
13746        value
13747    }
13748}
13749
13750impl Embed<W80, W120> {
13751    /// Embed a `u128` value at W80 into a `u128` value at W120.
13752    #[inline]
13753    #[must_use]
13754    pub const fn apply(value: u128) -> u128 {
13755        value
13756    }
13757}
13758
13759impl Embed<W80, W128> {
13760    /// Embed a `u128` value at W80 into a `u128` value at W128.
13761    #[inline]
13762    #[must_use]
13763    pub const fn apply(value: u128) -> u128 {
13764        value
13765    }
13766}
13767
13768impl Embed<W88, W88> {
13769    /// Embed a `u128` value at W88 into a `u128` value at W88.
13770    #[inline]
13771    #[must_use]
13772    pub const fn apply(value: u128) -> u128 {
13773        value
13774    }
13775}
13776
13777impl Embed<W88, W96> {
13778    /// Embed a `u128` value at W88 into a `u128` value at W96.
13779    #[inline]
13780    #[must_use]
13781    pub const fn apply(value: u128) -> u128 {
13782        value
13783    }
13784}
13785
13786impl Embed<W88, W104> {
13787    /// Embed a `u128` value at W88 into a `u128` value at W104.
13788    #[inline]
13789    #[must_use]
13790    pub const fn apply(value: u128) -> u128 {
13791        value
13792    }
13793}
13794
13795impl Embed<W88, W112> {
13796    /// Embed a `u128` value at W88 into a `u128` value at W112.
13797    #[inline]
13798    #[must_use]
13799    pub const fn apply(value: u128) -> u128 {
13800        value
13801    }
13802}
13803
13804impl Embed<W88, W120> {
13805    /// Embed a `u128` value at W88 into a `u128` value at W120.
13806    #[inline]
13807    #[must_use]
13808    pub const fn apply(value: u128) -> u128 {
13809        value
13810    }
13811}
13812
13813impl Embed<W88, W128> {
13814    /// Embed a `u128` value at W88 into a `u128` value at W128.
13815    #[inline]
13816    #[must_use]
13817    pub const fn apply(value: u128) -> u128 {
13818        value
13819    }
13820}
13821
13822impl Embed<W96, W96> {
13823    /// Embed a `u128` value at W96 into a `u128` value at W96.
13824    #[inline]
13825    #[must_use]
13826    pub const fn apply(value: u128) -> u128 {
13827        value
13828    }
13829}
13830
13831impl Embed<W96, W104> {
13832    /// Embed a `u128` value at W96 into a `u128` value at W104.
13833    #[inline]
13834    #[must_use]
13835    pub const fn apply(value: u128) -> u128 {
13836        value
13837    }
13838}
13839
13840impl Embed<W96, W112> {
13841    /// Embed a `u128` value at W96 into a `u128` value at W112.
13842    #[inline]
13843    #[must_use]
13844    pub const fn apply(value: u128) -> u128 {
13845        value
13846    }
13847}
13848
13849impl Embed<W96, W120> {
13850    /// Embed a `u128` value at W96 into a `u128` value at W120.
13851    #[inline]
13852    #[must_use]
13853    pub const fn apply(value: u128) -> u128 {
13854        value
13855    }
13856}
13857
13858impl Embed<W96, W128> {
13859    /// Embed a `u128` value at W96 into a `u128` value at W128.
13860    #[inline]
13861    #[must_use]
13862    pub const fn apply(value: u128) -> u128 {
13863        value
13864    }
13865}
13866
13867impl Embed<W104, W104> {
13868    /// Embed a `u128` value at W104 into a `u128` value at W104.
13869    #[inline]
13870    #[must_use]
13871    pub const fn apply(value: u128) -> u128 {
13872        value
13873    }
13874}
13875
13876impl Embed<W104, W112> {
13877    /// Embed a `u128` value at W104 into a `u128` value at W112.
13878    #[inline]
13879    #[must_use]
13880    pub const fn apply(value: u128) -> u128 {
13881        value
13882    }
13883}
13884
13885impl Embed<W104, W120> {
13886    /// Embed a `u128` value at W104 into a `u128` value at W120.
13887    #[inline]
13888    #[must_use]
13889    pub const fn apply(value: u128) -> u128 {
13890        value
13891    }
13892}
13893
13894impl Embed<W104, W128> {
13895    /// Embed a `u128` value at W104 into a `u128` value at W128.
13896    #[inline]
13897    #[must_use]
13898    pub const fn apply(value: u128) -> u128 {
13899        value
13900    }
13901}
13902
13903impl Embed<W112, W112> {
13904    /// Embed a `u128` value at W112 into a `u128` value at W112.
13905    #[inline]
13906    #[must_use]
13907    pub const fn apply(value: u128) -> u128 {
13908        value
13909    }
13910}
13911
13912impl Embed<W112, W120> {
13913    /// Embed a `u128` value at W112 into a `u128` value at W120.
13914    #[inline]
13915    #[must_use]
13916    pub const fn apply(value: u128) -> u128 {
13917        value
13918    }
13919}
13920
13921impl Embed<W112, W128> {
13922    /// Embed a `u128` value at W112 into a `u128` value at W128.
13923    #[inline]
13924    #[must_use]
13925    pub const fn apply(value: u128) -> u128 {
13926        value
13927    }
13928}
13929
13930impl Embed<W120, W120> {
13931    /// Embed a `u128` value at W120 into a `u128` value at W120.
13932    #[inline]
13933    #[must_use]
13934    pub const fn apply(value: u128) -> u128 {
13935        value
13936    }
13937}
13938
13939impl Embed<W120, W128> {
13940    /// Embed a `u128` value at W120 into a `u128` value at W128.
13941    #[inline]
13942    #[must_use]
13943    pub const fn apply(value: u128) -> u128 {
13944        value
13945    }
13946}
13947
13948impl Embed<W128, W128> {
13949    /// Embed a `u128` value at W128 into a `u128` value at W128.
13950    #[inline]
13951    #[must_use]
13952    pub const fn apply(value: u128) -> u128 {
13953        value
13954    }
13955}
13956
13957/// v0.2.2 Phase C.3: marker structs for Limbs-backed Witt levels.
13958/// Each level binds a const-generic `Limbs<N>` width at the type level.
13959/// W160 marker — 160-bit Witt level, Limbs-backed.
13960#[derive(Debug, Default, Clone, Copy)]
13961pub struct W160;
13962
13963/// W192 marker — 192-bit Witt level, Limbs-backed.
13964#[derive(Debug, Default, Clone, Copy)]
13965pub struct W192;
13966
13967/// W224 marker — 224-bit Witt level, Limbs-backed.
13968#[derive(Debug, Default, Clone, Copy)]
13969pub struct W224;
13970
13971/// W256 marker — 256-bit Witt level, Limbs-backed.
13972#[derive(Debug, Default, Clone, Copy)]
13973pub struct W256;
13974
13975/// W384 marker — 384-bit Witt level, Limbs-backed.
13976#[derive(Debug, Default, Clone, Copy)]
13977pub struct W384;
13978
13979/// W448 marker — 448-bit Witt level, Limbs-backed.
13980#[derive(Debug, Default, Clone, Copy)]
13981pub struct W448;
13982
13983/// W512 marker — 512-bit Witt level, Limbs-backed.
13984#[derive(Debug, Default, Clone, Copy)]
13985pub struct W512;
13986
13987/// W520 marker — 520-bit Witt level, Limbs-backed.
13988#[derive(Debug, Default, Clone, Copy)]
13989pub struct W520;
13990
13991/// W528 marker — 528-bit Witt level, Limbs-backed.
13992#[derive(Debug, Default, Clone, Copy)]
13993pub struct W528;
13994
13995/// W1024 marker — 1024-bit Witt level, Limbs-backed.
13996#[derive(Debug, Default, Clone, Copy)]
13997pub struct W1024;
13998
13999/// W2048 marker — 2048-bit Witt level, Limbs-backed.
14000#[derive(Debug, Default, Clone, Copy)]
14001pub struct W2048;
14002
14003/// W4096 marker — 4096-bit Witt level, Limbs-backed.
14004#[derive(Debug, Default, Clone, Copy)]
14005pub struct W4096;
14006
14007/// W8192 marker — 8192-bit Witt level, Limbs-backed.
14008#[derive(Debug, Default, Clone, Copy)]
14009pub struct W8192;
14010
14011/// W12288 marker — 12288-bit Witt level, Limbs-backed.
14012#[derive(Debug, Default, Clone, Copy)]
14013pub struct W12288;
14014
14015/// W16384 marker — 16384-bit Witt level, Limbs-backed.
14016#[derive(Debug, Default, Clone, Copy)]
14017pub struct W16384;
14018
14019/// W32768 marker — 32768-bit Witt level, Limbs-backed.
14020#[derive(Debug, Default, Clone, Copy)]
14021pub struct W32768;
14022
14023impl RingOp<W160> for Mul<W160> {
14024    type Operand = Limbs<3>;
14025    #[inline]
14026    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14027        a.wrapping_mul(b).mask_high_bits(160)
14028    }
14029}
14030
14031impl RingOp<W160> for Add<W160> {
14032    type Operand = Limbs<3>;
14033    #[inline]
14034    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14035        a.wrapping_add(b).mask_high_bits(160)
14036    }
14037}
14038
14039impl RingOp<W160> for Sub<W160> {
14040    type Operand = Limbs<3>;
14041    #[inline]
14042    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14043        a.wrapping_sub(b).mask_high_bits(160)
14044    }
14045}
14046
14047impl RingOp<W160> for Xor<W160> {
14048    type Operand = Limbs<3>;
14049    #[inline]
14050    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14051        a.xor(b).mask_high_bits(160)
14052    }
14053}
14054
14055impl RingOp<W160> for And<W160> {
14056    type Operand = Limbs<3>;
14057    #[inline]
14058    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14059        a.and(b).mask_high_bits(160)
14060    }
14061}
14062
14063impl RingOp<W160> for Or<W160> {
14064    type Operand = Limbs<3>;
14065    #[inline]
14066    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14067        a.or(b).mask_high_bits(160)
14068    }
14069}
14070
14071impl UnaryRingOp<W160> for Neg<W160> {
14072    type Operand = Limbs<3>;
14073    #[inline]
14074    fn apply(a: Limbs<3>) -> Limbs<3> {
14075        (Limbs::<3>::zero().wrapping_sub(a)).mask_high_bits(160)
14076    }
14077}
14078
14079impl UnaryRingOp<W160> for BNot<W160> {
14080    type Operand = Limbs<3>;
14081    #[inline]
14082    fn apply(a: Limbs<3>) -> Limbs<3> {
14083        (a.not()).mask_high_bits(160)
14084    }
14085}
14086
14087impl UnaryRingOp<W160> for Succ<W160> {
14088    type Operand = Limbs<3>;
14089    #[inline]
14090    fn apply(a: Limbs<3>) -> Limbs<3> {
14091        (a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))).mask_high_bits(160)
14092    }
14093}
14094
14095impl RingOp<W192> for Mul<W192> {
14096    type Operand = Limbs<3>;
14097    #[inline]
14098    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14099        a.wrapping_mul(b)
14100    }
14101}
14102
14103impl RingOp<W192> for Add<W192> {
14104    type Operand = Limbs<3>;
14105    #[inline]
14106    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14107        a.wrapping_add(b)
14108    }
14109}
14110
14111impl RingOp<W192> for Sub<W192> {
14112    type Operand = Limbs<3>;
14113    #[inline]
14114    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14115        a.wrapping_sub(b)
14116    }
14117}
14118
14119impl RingOp<W192> for Xor<W192> {
14120    type Operand = Limbs<3>;
14121    #[inline]
14122    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14123        a.xor(b)
14124    }
14125}
14126
14127impl RingOp<W192> for And<W192> {
14128    type Operand = Limbs<3>;
14129    #[inline]
14130    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14131        a.and(b)
14132    }
14133}
14134
14135impl RingOp<W192> for Or<W192> {
14136    type Operand = Limbs<3>;
14137    #[inline]
14138    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14139        a.or(b)
14140    }
14141}
14142
14143impl UnaryRingOp<W192> for Neg<W192> {
14144    type Operand = Limbs<3>;
14145    #[inline]
14146    fn apply(a: Limbs<3>) -> Limbs<3> {
14147        Limbs::<3>::zero().wrapping_sub(a)
14148    }
14149}
14150
14151impl UnaryRingOp<W192> for BNot<W192> {
14152    type Operand = Limbs<3>;
14153    #[inline]
14154    fn apply(a: Limbs<3>) -> Limbs<3> {
14155        a.not()
14156    }
14157}
14158
14159impl UnaryRingOp<W192> for Succ<W192> {
14160    type Operand = Limbs<3>;
14161    #[inline]
14162    fn apply(a: Limbs<3>) -> Limbs<3> {
14163        a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))
14164    }
14165}
14166
14167impl RingOp<W224> for Mul<W224> {
14168    type Operand = Limbs<4>;
14169    #[inline]
14170    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14171        a.wrapping_mul(b).mask_high_bits(224)
14172    }
14173}
14174
14175impl RingOp<W224> for Add<W224> {
14176    type Operand = Limbs<4>;
14177    #[inline]
14178    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14179        a.wrapping_add(b).mask_high_bits(224)
14180    }
14181}
14182
14183impl RingOp<W224> for Sub<W224> {
14184    type Operand = Limbs<4>;
14185    #[inline]
14186    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14187        a.wrapping_sub(b).mask_high_bits(224)
14188    }
14189}
14190
14191impl RingOp<W224> for Xor<W224> {
14192    type Operand = Limbs<4>;
14193    #[inline]
14194    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14195        a.xor(b).mask_high_bits(224)
14196    }
14197}
14198
14199impl RingOp<W224> for And<W224> {
14200    type Operand = Limbs<4>;
14201    #[inline]
14202    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14203        a.and(b).mask_high_bits(224)
14204    }
14205}
14206
14207impl RingOp<W224> for Or<W224> {
14208    type Operand = Limbs<4>;
14209    #[inline]
14210    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14211        a.or(b).mask_high_bits(224)
14212    }
14213}
14214
14215impl UnaryRingOp<W224> for Neg<W224> {
14216    type Operand = Limbs<4>;
14217    #[inline]
14218    fn apply(a: Limbs<4>) -> Limbs<4> {
14219        (Limbs::<4>::zero().wrapping_sub(a)).mask_high_bits(224)
14220    }
14221}
14222
14223impl UnaryRingOp<W224> for BNot<W224> {
14224    type Operand = Limbs<4>;
14225    #[inline]
14226    fn apply(a: Limbs<4>) -> Limbs<4> {
14227        (a.not()).mask_high_bits(224)
14228    }
14229}
14230
14231impl UnaryRingOp<W224> for Succ<W224> {
14232    type Operand = Limbs<4>;
14233    #[inline]
14234    fn apply(a: Limbs<4>) -> Limbs<4> {
14235        (a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))).mask_high_bits(224)
14236    }
14237}
14238
14239impl RingOp<W256> for Mul<W256> {
14240    type Operand = Limbs<4>;
14241    #[inline]
14242    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14243        a.wrapping_mul(b)
14244    }
14245}
14246
14247impl RingOp<W256> for Add<W256> {
14248    type Operand = Limbs<4>;
14249    #[inline]
14250    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14251        a.wrapping_add(b)
14252    }
14253}
14254
14255impl RingOp<W256> for Sub<W256> {
14256    type Operand = Limbs<4>;
14257    #[inline]
14258    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14259        a.wrapping_sub(b)
14260    }
14261}
14262
14263impl RingOp<W256> for Xor<W256> {
14264    type Operand = Limbs<4>;
14265    #[inline]
14266    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14267        a.xor(b)
14268    }
14269}
14270
14271impl RingOp<W256> for And<W256> {
14272    type Operand = Limbs<4>;
14273    #[inline]
14274    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14275        a.and(b)
14276    }
14277}
14278
14279impl RingOp<W256> for Or<W256> {
14280    type Operand = Limbs<4>;
14281    #[inline]
14282    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14283        a.or(b)
14284    }
14285}
14286
14287impl UnaryRingOp<W256> for Neg<W256> {
14288    type Operand = Limbs<4>;
14289    #[inline]
14290    fn apply(a: Limbs<4>) -> Limbs<4> {
14291        Limbs::<4>::zero().wrapping_sub(a)
14292    }
14293}
14294
14295impl UnaryRingOp<W256> for BNot<W256> {
14296    type Operand = Limbs<4>;
14297    #[inline]
14298    fn apply(a: Limbs<4>) -> Limbs<4> {
14299        a.not()
14300    }
14301}
14302
14303impl UnaryRingOp<W256> for Succ<W256> {
14304    type Operand = Limbs<4>;
14305    #[inline]
14306    fn apply(a: Limbs<4>) -> Limbs<4> {
14307        a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))
14308    }
14309}
14310
14311impl RingOp<W384> for Mul<W384> {
14312    type Operand = Limbs<6>;
14313    #[inline]
14314    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14315        a.wrapping_mul(b)
14316    }
14317}
14318
14319impl RingOp<W384> for Add<W384> {
14320    type Operand = Limbs<6>;
14321    #[inline]
14322    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14323        a.wrapping_add(b)
14324    }
14325}
14326
14327impl RingOp<W384> for Sub<W384> {
14328    type Operand = Limbs<6>;
14329    #[inline]
14330    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14331        a.wrapping_sub(b)
14332    }
14333}
14334
14335impl RingOp<W384> for Xor<W384> {
14336    type Operand = Limbs<6>;
14337    #[inline]
14338    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14339        a.xor(b)
14340    }
14341}
14342
14343impl RingOp<W384> for And<W384> {
14344    type Operand = Limbs<6>;
14345    #[inline]
14346    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14347        a.and(b)
14348    }
14349}
14350
14351impl RingOp<W384> for Or<W384> {
14352    type Operand = Limbs<6>;
14353    #[inline]
14354    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14355        a.or(b)
14356    }
14357}
14358
14359impl UnaryRingOp<W384> for Neg<W384> {
14360    type Operand = Limbs<6>;
14361    #[inline]
14362    fn apply(a: Limbs<6>) -> Limbs<6> {
14363        Limbs::<6>::zero().wrapping_sub(a)
14364    }
14365}
14366
14367impl UnaryRingOp<W384> for BNot<W384> {
14368    type Operand = Limbs<6>;
14369    #[inline]
14370    fn apply(a: Limbs<6>) -> Limbs<6> {
14371        a.not()
14372    }
14373}
14374
14375impl UnaryRingOp<W384> for Succ<W384> {
14376    type Operand = Limbs<6>;
14377    #[inline]
14378    fn apply(a: Limbs<6>) -> Limbs<6> {
14379        a.wrapping_add(Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64]))
14380    }
14381}
14382
14383impl RingOp<W448> for Mul<W448> {
14384    type Operand = Limbs<7>;
14385    #[inline]
14386    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14387        a.wrapping_mul(b)
14388    }
14389}
14390
14391impl RingOp<W448> for Add<W448> {
14392    type Operand = Limbs<7>;
14393    #[inline]
14394    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14395        a.wrapping_add(b)
14396    }
14397}
14398
14399impl RingOp<W448> for Sub<W448> {
14400    type Operand = Limbs<7>;
14401    #[inline]
14402    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14403        a.wrapping_sub(b)
14404    }
14405}
14406
14407impl RingOp<W448> for Xor<W448> {
14408    type Operand = Limbs<7>;
14409    #[inline]
14410    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14411        a.xor(b)
14412    }
14413}
14414
14415impl RingOp<W448> for And<W448> {
14416    type Operand = Limbs<7>;
14417    #[inline]
14418    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14419        a.and(b)
14420    }
14421}
14422
14423impl RingOp<W448> for Or<W448> {
14424    type Operand = Limbs<7>;
14425    #[inline]
14426    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14427        a.or(b)
14428    }
14429}
14430
14431impl UnaryRingOp<W448> for Neg<W448> {
14432    type Operand = Limbs<7>;
14433    #[inline]
14434    fn apply(a: Limbs<7>) -> Limbs<7> {
14435        Limbs::<7>::zero().wrapping_sub(a)
14436    }
14437}
14438
14439impl UnaryRingOp<W448> for BNot<W448> {
14440    type Operand = Limbs<7>;
14441    #[inline]
14442    fn apply(a: Limbs<7>) -> Limbs<7> {
14443        a.not()
14444    }
14445}
14446
14447impl UnaryRingOp<W448> for Succ<W448> {
14448    type Operand = Limbs<7>;
14449    #[inline]
14450    fn apply(a: Limbs<7>) -> Limbs<7> {
14451        a.wrapping_add(Limbs::<7>::from_words([
14452            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14453        ]))
14454    }
14455}
14456
14457impl RingOp<W512> for Mul<W512> {
14458    type Operand = Limbs<8>;
14459    #[inline]
14460    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14461        a.wrapping_mul(b)
14462    }
14463}
14464
14465impl RingOp<W512> for Add<W512> {
14466    type Operand = Limbs<8>;
14467    #[inline]
14468    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14469        a.wrapping_add(b)
14470    }
14471}
14472
14473impl RingOp<W512> for Sub<W512> {
14474    type Operand = Limbs<8>;
14475    #[inline]
14476    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14477        a.wrapping_sub(b)
14478    }
14479}
14480
14481impl RingOp<W512> for Xor<W512> {
14482    type Operand = Limbs<8>;
14483    #[inline]
14484    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14485        a.xor(b)
14486    }
14487}
14488
14489impl RingOp<W512> for And<W512> {
14490    type Operand = Limbs<8>;
14491    #[inline]
14492    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14493        a.and(b)
14494    }
14495}
14496
14497impl RingOp<W512> for Or<W512> {
14498    type Operand = Limbs<8>;
14499    #[inline]
14500    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14501        a.or(b)
14502    }
14503}
14504
14505impl UnaryRingOp<W512> for Neg<W512> {
14506    type Operand = Limbs<8>;
14507    #[inline]
14508    fn apply(a: Limbs<8>) -> Limbs<8> {
14509        Limbs::<8>::zero().wrapping_sub(a)
14510    }
14511}
14512
14513impl UnaryRingOp<W512> for BNot<W512> {
14514    type Operand = Limbs<8>;
14515    #[inline]
14516    fn apply(a: Limbs<8>) -> Limbs<8> {
14517        a.not()
14518    }
14519}
14520
14521impl UnaryRingOp<W512> for Succ<W512> {
14522    type Operand = Limbs<8>;
14523    #[inline]
14524    fn apply(a: Limbs<8>) -> Limbs<8> {
14525        a.wrapping_add(Limbs::<8>::from_words([
14526            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14527        ]))
14528    }
14529}
14530
14531impl RingOp<W520> for Mul<W520> {
14532    type Operand = Limbs<9>;
14533    #[inline]
14534    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14535        a.wrapping_mul(b).mask_high_bits(520)
14536    }
14537}
14538
14539impl RingOp<W520> for Add<W520> {
14540    type Operand = Limbs<9>;
14541    #[inline]
14542    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14543        a.wrapping_add(b).mask_high_bits(520)
14544    }
14545}
14546
14547impl RingOp<W520> for Sub<W520> {
14548    type Operand = Limbs<9>;
14549    #[inline]
14550    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14551        a.wrapping_sub(b).mask_high_bits(520)
14552    }
14553}
14554
14555impl RingOp<W520> for Xor<W520> {
14556    type Operand = Limbs<9>;
14557    #[inline]
14558    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14559        a.xor(b).mask_high_bits(520)
14560    }
14561}
14562
14563impl RingOp<W520> for And<W520> {
14564    type Operand = Limbs<9>;
14565    #[inline]
14566    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14567        a.and(b).mask_high_bits(520)
14568    }
14569}
14570
14571impl RingOp<W520> for Or<W520> {
14572    type Operand = Limbs<9>;
14573    #[inline]
14574    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14575        a.or(b).mask_high_bits(520)
14576    }
14577}
14578
14579impl UnaryRingOp<W520> for Neg<W520> {
14580    type Operand = Limbs<9>;
14581    #[inline]
14582    fn apply(a: Limbs<9>) -> Limbs<9> {
14583        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(520)
14584    }
14585}
14586
14587impl UnaryRingOp<W520> for BNot<W520> {
14588    type Operand = Limbs<9>;
14589    #[inline]
14590    fn apply(a: Limbs<9>) -> Limbs<9> {
14591        (a.not()).mask_high_bits(520)
14592    }
14593}
14594
14595impl UnaryRingOp<W520> for Succ<W520> {
14596    type Operand = Limbs<9>;
14597    #[inline]
14598    fn apply(a: Limbs<9>) -> Limbs<9> {
14599        (a.wrapping_add(Limbs::<9>::from_words([
14600            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14601        ])))
14602        .mask_high_bits(520)
14603    }
14604}
14605
14606impl RingOp<W528> for Mul<W528> {
14607    type Operand = Limbs<9>;
14608    #[inline]
14609    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14610        a.wrapping_mul(b).mask_high_bits(528)
14611    }
14612}
14613
14614impl RingOp<W528> for Add<W528> {
14615    type Operand = Limbs<9>;
14616    #[inline]
14617    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14618        a.wrapping_add(b).mask_high_bits(528)
14619    }
14620}
14621
14622impl RingOp<W528> for Sub<W528> {
14623    type Operand = Limbs<9>;
14624    #[inline]
14625    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14626        a.wrapping_sub(b).mask_high_bits(528)
14627    }
14628}
14629
14630impl RingOp<W528> for Xor<W528> {
14631    type Operand = Limbs<9>;
14632    #[inline]
14633    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14634        a.xor(b).mask_high_bits(528)
14635    }
14636}
14637
14638impl RingOp<W528> for And<W528> {
14639    type Operand = Limbs<9>;
14640    #[inline]
14641    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14642        a.and(b).mask_high_bits(528)
14643    }
14644}
14645
14646impl RingOp<W528> for Or<W528> {
14647    type Operand = Limbs<9>;
14648    #[inline]
14649    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14650        a.or(b).mask_high_bits(528)
14651    }
14652}
14653
14654impl UnaryRingOp<W528> for Neg<W528> {
14655    type Operand = Limbs<9>;
14656    #[inline]
14657    fn apply(a: Limbs<9>) -> Limbs<9> {
14658        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(528)
14659    }
14660}
14661
14662impl UnaryRingOp<W528> for BNot<W528> {
14663    type Operand = Limbs<9>;
14664    #[inline]
14665    fn apply(a: Limbs<9>) -> Limbs<9> {
14666        (a.not()).mask_high_bits(528)
14667    }
14668}
14669
14670impl UnaryRingOp<W528> for Succ<W528> {
14671    type Operand = Limbs<9>;
14672    #[inline]
14673    fn apply(a: Limbs<9>) -> Limbs<9> {
14674        (a.wrapping_add(Limbs::<9>::from_words([
14675            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14676        ])))
14677        .mask_high_bits(528)
14678    }
14679}
14680
14681impl RingOp<W1024> for Mul<W1024> {
14682    type Operand = Limbs<16>;
14683    #[inline]
14684    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14685        a.wrapping_mul(b)
14686    }
14687}
14688
14689impl RingOp<W1024> for Add<W1024> {
14690    type Operand = Limbs<16>;
14691    #[inline]
14692    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14693        a.wrapping_add(b)
14694    }
14695}
14696
14697impl RingOp<W1024> for Sub<W1024> {
14698    type Operand = Limbs<16>;
14699    #[inline]
14700    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14701        a.wrapping_sub(b)
14702    }
14703}
14704
14705impl RingOp<W1024> for Xor<W1024> {
14706    type Operand = Limbs<16>;
14707    #[inline]
14708    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14709        a.xor(b)
14710    }
14711}
14712
14713impl RingOp<W1024> for And<W1024> {
14714    type Operand = Limbs<16>;
14715    #[inline]
14716    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14717        a.and(b)
14718    }
14719}
14720
14721impl RingOp<W1024> for Or<W1024> {
14722    type Operand = Limbs<16>;
14723    #[inline]
14724    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14725        a.or(b)
14726    }
14727}
14728
14729impl UnaryRingOp<W1024> for Neg<W1024> {
14730    type Operand = Limbs<16>;
14731    #[inline]
14732    fn apply(a: Limbs<16>) -> Limbs<16> {
14733        Limbs::<16>::zero().wrapping_sub(a)
14734    }
14735}
14736
14737impl UnaryRingOp<W1024> for BNot<W1024> {
14738    type Operand = Limbs<16>;
14739    #[inline]
14740    fn apply(a: Limbs<16>) -> Limbs<16> {
14741        a.not()
14742    }
14743}
14744
14745impl UnaryRingOp<W1024> for Succ<W1024> {
14746    type Operand = Limbs<16>;
14747    #[inline]
14748    fn apply(a: Limbs<16>) -> Limbs<16> {
14749        a.wrapping_add(Limbs::<16>::from_words([
14750            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14751            0u64, 0u64,
14752        ]))
14753    }
14754}
14755
14756impl RingOp<W2048> for Mul<W2048> {
14757    type Operand = Limbs<32>;
14758    #[inline]
14759    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14760        a.wrapping_mul(b)
14761    }
14762}
14763
14764impl RingOp<W2048> for Add<W2048> {
14765    type Operand = Limbs<32>;
14766    #[inline]
14767    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14768        a.wrapping_add(b)
14769    }
14770}
14771
14772impl RingOp<W2048> for Sub<W2048> {
14773    type Operand = Limbs<32>;
14774    #[inline]
14775    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14776        a.wrapping_sub(b)
14777    }
14778}
14779
14780impl RingOp<W2048> for Xor<W2048> {
14781    type Operand = Limbs<32>;
14782    #[inline]
14783    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14784        a.xor(b)
14785    }
14786}
14787
14788impl RingOp<W2048> for And<W2048> {
14789    type Operand = Limbs<32>;
14790    #[inline]
14791    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14792        a.and(b)
14793    }
14794}
14795
14796impl RingOp<W2048> for Or<W2048> {
14797    type Operand = Limbs<32>;
14798    #[inline]
14799    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14800        a.or(b)
14801    }
14802}
14803
14804impl UnaryRingOp<W2048> for Neg<W2048> {
14805    type Operand = Limbs<32>;
14806    #[inline]
14807    fn apply(a: Limbs<32>) -> Limbs<32> {
14808        Limbs::<32>::zero().wrapping_sub(a)
14809    }
14810}
14811
14812impl UnaryRingOp<W2048> for BNot<W2048> {
14813    type Operand = Limbs<32>;
14814    #[inline]
14815    fn apply(a: Limbs<32>) -> Limbs<32> {
14816        a.not()
14817    }
14818}
14819
14820impl UnaryRingOp<W2048> for Succ<W2048> {
14821    type Operand = Limbs<32>;
14822    #[inline]
14823    fn apply(a: Limbs<32>) -> Limbs<32> {
14824        a.wrapping_add(Limbs::<32>::from_words([
14825            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14826            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14827            0u64, 0u64, 0u64, 0u64,
14828        ]))
14829    }
14830}
14831
14832impl RingOp<W4096> for Mul<W4096> {
14833    type Operand = Limbs<64>;
14834    #[inline]
14835    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14836        a.wrapping_mul(b)
14837    }
14838}
14839
14840impl RingOp<W4096> for Add<W4096> {
14841    type Operand = Limbs<64>;
14842    #[inline]
14843    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14844        a.wrapping_add(b)
14845    }
14846}
14847
14848impl RingOp<W4096> for Sub<W4096> {
14849    type Operand = Limbs<64>;
14850    #[inline]
14851    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14852        a.wrapping_sub(b)
14853    }
14854}
14855
14856impl RingOp<W4096> for Xor<W4096> {
14857    type Operand = Limbs<64>;
14858    #[inline]
14859    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14860        a.xor(b)
14861    }
14862}
14863
14864impl RingOp<W4096> for And<W4096> {
14865    type Operand = Limbs<64>;
14866    #[inline]
14867    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14868        a.and(b)
14869    }
14870}
14871
14872impl RingOp<W4096> for Or<W4096> {
14873    type Operand = Limbs<64>;
14874    #[inline]
14875    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14876        a.or(b)
14877    }
14878}
14879
14880impl UnaryRingOp<W4096> for Neg<W4096> {
14881    type Operand = Limbs<64>;
14882    #[inline]
14883    fn apply(a: Limbs<64>) -> Limbs<64> {
14884        Limbs::<64>::zero().wrapping_sub(a)
14885    }
14886}
14887
14888impl UnaryRingOp<W4096> for BNot<W4096> {
14889    type Operand = Limbs<64>;
14890    #[inline]
14891    fn apply(a: Limbs<64>) -> Limbs<64> {
14892        a.not()
14893    }
14894}
14895
14896impl UnaryRingOp<W4096> for Succ<W4096> {
14897    type Operand = Limbs<64>;
14898    #[inline]
14899    fn apply(a: Limbs<64>) -> Limbs<64> {
14900        a.wrapping_add(Limbs::<64>::from_words([
14901            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14902            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14903            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14904            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14905            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14906        ]))
14907    }
14908}
14909
14910impl RingOp<W8192> for Mul<W8192> {
14911    type Operand = Limbs<128>;
14912    #[inline]
14913    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14914        a.wrapping_mul(b)
14915    }
14916}
14917
14918impl RingOp<W8192> for Add<W8192> {
14919    type Operand = Limbs<128>;
14920    #[inline]
14921    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14922        a.wrapping_add(b)
14923    }
14924}
14925
14926impl RingOp<W8192> for Sub<W8192> {
14927    type Operand = Limbs<128>;
14928    #[inline]
14929    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14930        a.wrapping_sub(b)
14931    }
14932}
14933
14934impl RingOp<W8192> for Xor<W8192> {
14935    type Operand = Limbs<128>;
14936    #[inline]
14937    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14938        a.xor(b)
14939    }
14940}
14941
14942impl RingOp<W8192> for And<W8192> {
14943    type Operand = Limbs<128>;
14944    #[inline]
14945    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14946        a.and(b)
14947    }
14948}
14949
14950impl RingOp<W8192> for Or<W8192> {
14951    type Operand = Limbs<128>;
14952    #[inline]
14953    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
14954        a.or(b)
14955    }
14956}
14957
14958impl UnaryRingOp<W8192> for Neg<W8192> {
14959    type Operand = Limbs<128>;
14960    #[inline]
14961    fn apply(a: Limbs<128>) -> Limbs<128> {
14962        Limbs::<128>::zero().wrapping_sub(a)
14963    }
14964}
14965
14966impl UnaryRingOp<W8192> for BNot<W8192> {
14967    type Operand = Limbs<128>;
14968    #[inline]
14969    fn apply(a: Limbs<128>) -> Limbs<128> {
14970        a.not()
14971    }
14972}
14973
14974impl UnaryRingOp<W8192> for Succ<W8192> {
14975    type Operand = Limbs<128>;
14976    #[inline]
14977    fn apply(a: Limbs<128>) -> Limbs<128> {
14978        a.wrapping_add(Limbs::<128>::from_words([
14979            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14980            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14981            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14982            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14983            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14984            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14985            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14986            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14987            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14988            0u64, 0u64,
14989        ]))
14990    }
14991}
14992
14993impl RingOp<W12288> for Mul<W12288> {
14994    type Operand = Limbs<192>;
14995    #[inline]
14996    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
14997        a.wrapping_mul(b)
14998    }
14999}
15000
15001impl RingOp<W12288> for Add<W12288> {
15002    type Operand = Limbs<192>;
15003    #[inline]
15004    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15005        a.wrapping_add(b)
15006    }
15007}
15008
15009impl RingOp<W12288> for Sub<W12288> {
15010    type Operand = Limbs<192>;
15011    #[inline]
15012    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15013        a.wrapping_sub(b)
15014    }
15015}
15016
15017impl RingOp<W12288> for Xor<W12288> {
15018    type Operand = Limbs<192>;
15019    #[inline]
15020    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15021        a.xor(b)
15022    }
15023}
15024
15025impl RingOp<W12288> for And<W12288> {
15026    type Operand = Limbs<192>;
15027    #[inline]
15028    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15029        a.and(b)
15030    }
15031}
15032
15033impl RingOp<W12288> for Or<W12288> {
15034    type Operand = Limbs<192>;
15035    #[inline]
15036    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15037        a.or(b)
15038    }
15039}
15040
15041impl UnaryRingOp<W12288> for Neg<W12288> {
15042    type Operand = Limbs<192>;
15043    #[inline]
15044    fn apply(a: Limbs<192>) -> Limbs<192> {
15045        Limbs::<192>::zero().wrapping_sub(a)
15046    }
15047}
15048
15049impl UnaryRingOp<W12288> for BNot<W12288> {
15050    type Operand = Limbs<192>;
15051    #[inline]
15052    fn apply(a: Limbs<192>) -> Limbs<192> {
15053        a.not()
15054    }
15055}
15056
15057impl UnaryRingOp<W12288> for Succ<W12288> {
15058    type Operand = Limbs<192>;
15059    #[inline]
15060    fn apply(a: Limbs<192>) -> Limbs<192> {
15061        a.wrapping_add(Limbs::<192>::from_words([
15062            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15063            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15064            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15065            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15066            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15067            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15068            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15069            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15070            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15071            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15072            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15073            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15074            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15075            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15076        ]))
15077    }
15078}
15079
15080impl RingOp<W16384> for Mul<W16384> {
15081    type Operand = Limbs<256>;
15082    #[inline]
15083    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15084        a.wrapping_mul(b)
15085    }
15086}
15087
15088impl RingOp<W16384> for Add<W16384> {
15089    type Operand = Limbs<256>;
15090    #[inline]
15091    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15092        a.wrapping_add(b)
15093    }
15094}
15095
15096impl RingOp<W16384> for Sub<W16384> {
15097    type Operand = Limbs<256>;
15098    #[inline]
15099    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15100        a.wrapping_sub(b)
15101    }
15102}
15103
15104impl RingOp<W16384> for Xor<W16384> {
15105    type Operand = Limbs<256>;
15106    #[inline]
15107    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15108        a.xor(b)
15109    }
15110}
15111
15112impl RingOp<W16384> for And<W16384> {
15113    type Operand = Limbs<256>;
15114    #[inline]
15115    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15116        a.and(b)
15117    }
15118}
15119
15120impl RingOp<W16384> for Or<W16384> {
15121    type Operand = Limbs<256>;
15122    #[inline]
15123    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15124        a.or(b)
15125    }
15126}
15127
15128impl UnaryRingOp<W16384> for Neg<W16384> {
15129    type Operand = Limbs<256>;
15130    #[inline]
15131    fn apply(a: Limbs<256>) -> Limbs<256> {
15132        Limbs::<256>::zero().wrapping_sub(a)
15133    }
15134}
15135
15136impl UnaryRingOp<W16384> for BNot<W16384> {
15137    type Operand = Limbs<256>;
15138    #[inline]
15139    fn apply(a: Limbs<256>) -> Limbs<256> {
15140        a.not()
15141    }
15142}
15143
15144impl UnaryRingOp<W16384> for Succ<W16384> {
15145    type Operand = Limbs<256>;
15146    #[inline]
15147    fn apply(a: Limbs<256>) -> Limbs<256> {
15148        a.wrapping_add(Limbs::<256>::from_words([
15149            1u64, 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, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15156            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15157            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15158            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15159            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15160            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15161            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15162            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15163            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15164            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15165            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15166            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15167            0u64, 0u64, 0u64, 0u64,
15168        ]))
15169    }
15170}
15171
15172impl RingOp<W32768> for Mul<W32768> {
15173    type Operand = Limbs<512>;
15174    #[inline]
15175    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15176        a.wrapping_mul(b)
15177    }
15178}
15179
15180impl RingOp<W32768> for Add<W32768> {
15181    type Operand = Limbs<512>;
15182    #[inline]
15183    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15184        a.wrapping_add(b)
15185    }
15186}
15187
15188impl RingOp<W32768> for Sub<W32768> {
15189    type Operand = Limbs<512>;
15190    #[inline]
15191    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15192        a.wrapping_sub(b)
15193    }
15194}
15195
15196impl RingOp<W32768> for Xor<W32768> {
15197    type Operand = Limbs<512>;
15198    #[inline]
15199    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15200        a.xor(b)
15201    }
15202}
15203
15204impl RingOp<W32768> for And<W32768> {
15205    type Operand = Limbs<512>;
15206    #[inline]
15207    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15208        a.and(b)
15209    }
15210}
15211
15212impl RingOp<W32768> for Or<W32768> {
15213    type Operand = Limbs<512>;
15214    #[inline]
15215    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15216        a.or(b)
15217    }
15218}
15219
15220impl UnaryRingOp<W32768> for Neg<W32768> {
15221    type Operand = Limbs<512>;
15222    #[inline]
15223    fn apply(a: Limbs<512>) -> Limbs<512> {
15224        Limbs::<512>::zero().wrapping_sub(a)
15225    }
15226}
15227
15228impl UnaryRingOp<W32768> for BNot<W32768> {
15229    type Operand = Limbs<512>;
15230    #[inline]
15231    fn apply(a: Limbs<512>) -> Limbs<512> {
15232        a.not()
15233    }
15234}
15235
15236impl UnaryRingOp<W32768> for Succ<W32768> {
15237    type Operand = Limbs<512>;
15238    #[inline]
15239    fn apply(a: Limbs<512>) -> Limbs<512> {
15240        a.wrapping_add(Limbs::<512>::from_words([
15241            1u64, 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, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15266            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15267            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15268            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15269            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15270            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15271            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15272            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15273            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15274            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15275            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15276            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15277            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15278        ]))
15279    }
15280}
15281
15282/// Phase L.2 (target §4.5): `const_ring_eval_w{n}` helpers for Limbs-backed
15283/// Witt levels. Each helper runs a `PrimitiveOp` over two `Limbs<N>` operands
15284/// and applies the level's bit-width mask to the result.
15285/// These helpers are always const-fn; whether `rustc` can complete a specific
15286/// compile-time evaluation within the developer's budget is a function of the
15287/// invocation (see target §4.5 Q2 practicality table).
15288#[inline]
15289#[must_use]
15290pub const fn const_ring_eval_w160(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15291    let raw = match op {
15292        PrimitiveOp::Add => a.wrapping_add(b),
15293        PrimitiveOp::Sub => a.wrapping_sub(b),
15294        PrimitiveOp::Mul => a.wrapping_mul(b),
15295        PrimitiveOp::And => a.and(b),
15296        PrimitiveOp::Or => a.or(b),
15297        PrimitiveOp::Xor => a.xor(b),
15298        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15299        PrimitiveOp::Bnot => a.not(),
15300        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15301        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15302        PrimitiveOp::Le => {
15303            if limbs_le_3(a, b) {
15304                limbs_one_3()
15305            } else {
15306                Limbs::<3>::zero()
15307            }
15308        }
15309        PrimitiveOp::Lt => {
15310            if limbs_lt_3(a, b) {
15311                limbs_one_3()
15312            } else {
15313                Limbs::<3>::zero()
15314            }
15315        }
15316        PrimitiveOp::Ge => {
15317            if limbs_le_3(b, a) {
15318                limbs_one_3()
15319            } else {
15320                Limbs::<3>::zero()
15321            }
15322        }
15323        PrimitiveOp::Gt => {
15324            if limbs_lt_3(b, a) {
15325                limbs_one_3()
15326            } else {
15327                Limbs::<3>::zero()
15328            }
15329        }
15330        PrimitiveOp::Concat => Limbs::<3>::zero(),
15331        PrimitiveOp::Div => {
15332            if limbs_is_zero_3(b) {
15333                Limbs::<3>::zero()
15334            } else {
15335                limbs_div_3(a, b)
15336            }
15337        }
15338        PrimitiveOp::Mod => {
15339            if limbs_is_zero_3(b) {
15340                Limbs::<3>::zero()
15341            } else {
15342                limbs_mod_3(a, b)
15343            }
15344        }
15345        PrimitiveOp::Pow => limbs_pow_3(a, b),
15346    };
15347    raw.mask_high_bits(160)
15348}
15349
15350#[inline]
15351#[must_use]
15352pub const fn const_ring_eval_w192(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15353    match op {
15354        PrimitiveOp::Add => a.wrapping_add(b),
15355        PrimitiveOp::Sub => a.wrapping_sub(b),
15356        PrimitiveOp::Mul => a.wrapping_mul(b),
15357        PrimitiveOp::And => a.and(b),
15358        PrimitiveOp::Or => a.or(b),
15359        PrimitiveOp::Xor => a.xor(b),
15360        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15361        PrimitiveOp::Bnot => a.not(),
15362        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15363        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15364        PrimitiveOp::Le => {
15365            if limbs_le_3(a, b) {
15366                limbs_one_3()
15367            } else {
15368                Limbs::<3>::zero()
15369            }
15370        }
15371        PrimitiveOp::Lt => {
15372            if limbs_lt_3(a, b) {
15373                limbs_one_3()
15374            } else {
15375                Limbs::<3>::zero()
15376            }
15377        }
15378        PrimitiveOp::Ge => {
15379            if limbs_le_3(b, a) {
15380                limbs_one_3()
15381            } else {
15382                Limbs::<3>::zero()
15383            }
15384        }
15385        PrimitiveOp::Gt => {
15386            if limbs_lt_3(b, a) {
15387                limbs_one_3()
15388            } else {
15389                Limbs::<3>::zero()
15390            }
15391        }
15392        PrimitiveOp::Concat => Limbs::<3>::zero(),
15393        PrimitiveOp::Div => {
15394            if limbs_is_zero_3(b) {
15395                Limbs::<3>::zero()
15396            } else {
15397                limbs_div_3(a, b)
15398            }
15399        }
15400        PrimitiveOp::Mod => {
15401            if limbs_is_zero_3(b) {
15402                Limbs::<3>::zero()
15403            } else {
15404                limbs_mod_3(a, b)
15405            }
15406        }
15407        PrimitiveOp::Pow => limbs_pow_3(a, b),
15408    }
15409}
15410
15411#[inline]
15412#[must_use]
15413pub const fn const_ring_eval_w224(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15414    let raw = match op {
15415        PrimitiveOp::Add => a.wrapping_add(b),
15416        PrimitiveOp::Sub => a.wrapping_sub(b),
15417        PrimitiveOp::Mul => a.wrapping_mul(b),
15418        PrimitiveOp::And => a.and(b),
15419        PrimitiveOp::Or => a.or(b),
15420        PrimitiveOp::Xor => a.xor(b),
15421        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15422        PrimitiveOp::Bnot => a.not(),
15423        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15424        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15425        PrimitiveOp::Le => {
15426            if limbs_le_4(a, b) {
15427                limbs_one_4()
15428            } else {
15429                Limbs::<4>::zero()
15430            }
15431        }
15432        PrimitiveOp::Lt => {
15433            if limbs_lt_4(a, b) {
15434                limbs_one_4()
15435            } else {
15436                Limbs::<4>::zero()
15437            }
15438        }
15439        PrimitiveOp::Ge => {
15440            if limbs_le_4(b, a) {
15441                limbs_one_4()
15442            } else {
15443                Limbs::<4>::zero()
15444            }
15445        }
15446        PrimitiveOp::Gt => {
15447            if limbs_lt_4(b, a) {
15448                limbs_one_4()
15449            } else {
15450                Limbs::<4>::zero()
15451            }
15452        }
15453        PrimitiveOp::Concat => Limbs::<4>::zero(),
15454        PrimitiveOp::Div => {
15455            if limbs_is_zero_4(b) {
15456                Limbs::<4>::zero()
15457            } else {
15458                limbs_div_4(a, b)
15459            }
15460        }
15461        PrimitiveOp::Mod => {
15462            if limbs_is_zero_4(b) {
15463                Limbs::<4>::zero()
15464            } else {
15465                limbs_mod_4(a, b)
15466            }
15467        }
15468        PrimitiveOp::Pow => limbs_pow_4(a, b),
15469    };
15470    raw.mask_high_bits(224)
15471}
15472
15473#[inline]
15474#[must_use]
15475pub const fn const_ring_eval_w256(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15476    match op {
15477        PrimitiveOp::Add => a.wrapping_add(b),
15478        PrimitiveOp::Sub => a.wrapping_sub(b),
15479        PrimitiveOp::Mul => a.wrapping_mul(b),
15480        PrimitiveOp::And => a.and(b),
15481        PrimitiveOp::Or => a.or(b),
15482        PrimitiveOp::Xor => a.xor(b),
15483        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15484        PrimitiveOp::Bnot => a.not(),
15485        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15486        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15487        PrimitiveOp::Le => {
15488            if limbs_le_4(a, b) {
15489                limbs_one_4()
15490            } else {
15491                Limbs::<4>::zero()
15492            }
15493        }
15494        PrimitiveOp::Lt => {
15495            if limbs_lt_4(a, b) {
15496                limbs_one_4()
15497            } else {
15498                Limbs::<4>::zero()
15499            }
15500        }
15501        PrimitiveOp::Ge => {
15502            if limbs_le_4(b, a) {
15503                limbs_one_4()
15504            } else {
15505                Limbs::<4>::zero()
15506            }
15507        }
15508        PrimitiveOp::Gt => {
15509            if limbs_lt_4(b, a) {
15510                limbs_one_4()
15511            } else {
15512                Limbs::<4>::zero()
15513            }
15514        }
15515        PrimitiveOp::Concat => Limbs::<4>::zero(),
15516        PrimitiveOp::Div => {
15517            if limbs_is_zero_4(b) {
15518                Limbs::<4>::zero()
15519            } else {
15520                limbs_div_4(a, b)
15521            }
15522        }
15523        PrimitiveOp::Mod => {
15524            if limbs_is_zero_4(b) {
15525                Limbs::<4>::zero()
15526            } else {
15527                limbs_mod_4(a, b)
15528            }
15529        }
15530        PrimitiveOp::Pow => limbs_pow_4(a, b),
15531    }
15532}
15533
15534#[inline]
15535#[must_use]
15536pub const fn const_ring_eval_w384(op: PrimitiveOp, a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
15537    match op {
15538        PrimitiveOp::Add => a.wrapping_add(b),
15539        PrimitiveOp::Sub => a.wrapping_sub(b),
15540        PrimitiveOp::Mul => a.wrapping_mul(b),
15541        PrimitiveOp::And => a.and(b),
15542        PrimitiveOp::Or => a.or(b),
15543        PrimitiveOp::Xor => a.xor(b),
15544        PrimitiveOp::Neg => Limbs::<6>::zero().wrapping_sub(a),
15545        PrimitiveOp::Bnot => a.not(),
15546        PrimitiveOp::Succ => a.wrapping_add(limbs_one_6()),
15547        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_6()),
15548        PrimitiveOp::Le => {
15549            if limbs_le_6(a, b) {
15550                limbs_one_6()
15551            } else {
15552                Limbs::<6>::zero()
15553            }
15554        }
15555        PrimitiveOp::Lt => {
15556            if limbs_lt_6(a, b) {
15557                limbs_one_6()
15558            } else {
15559                Limbs::<6>::zero()
15560            }
15561        }
15562        PrimitiveOp::Ge => {
15563            if limbs_le_6(b, a) {
15564                limbs_one_6()
15565            } else {
15566                Limbs::<6>::zero()
15567            }
15568        }
15569        PrimitiveOp::Gt => {
15570            if limbs_lt_6(b, a) {
15571                limbs_one_6()
15572            } else {
15573                Limbs::<6>::zero()
15574            }
15575        }
15576        PrimitiveOp::Concat => Limbs::<6>::zero(),
15577        PrimitiveOp::Div => {
15578            if limbs_is_zero_6(b) {
15579                Limbs::<6>::zero()
15580            } else {
15581                limbs_div_6(a, b)
15582            }
15583        }
15584        PrimitiveOp::Mod => {
15585            if limbs_is_zero_6(b) {
15586                Limbs::<6>::zero()
15587            } else {
15588                limbs_mod_6(a, b)
15589            }
15590        }
15591        PrimitiveOp::Pow => limbs_pow_6(a, b),
15592    }
15593}
15594
15595#[inline]
15596#[must_use]
15597pub const fn const_ring_eval_w448(op: PrimitiveOp, a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
15598    match op {
15599        PrimitiveOp::Add => a.wrapping_add(b),
15600        PrimitiveOp::Sub => a.wrapping_sub(b),
15601        PrimitiveOp::Mul => a.wrapping_mul(b),
15602        PrimitiveOp::And => a.and(b),
15603        PrimitiveOp::Or => a.or(b),
15604        PrimitiveOp::Xor => a.xor(b),
15605        PrimitiveOp::Neg => Limbs::<7>::zero().wrapping_sub(a),
15606        PrimitiveOp::Bnot => a.not(),
15607        PrimitiveOp::Succ => a.wrapping_add(limbs_one_7()),
15608        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_7()),
15609        PrimitiveOp::Le => {
15610            if limbs_le_7(a, b) {
15611                limbs_one_7()
15612            } else {
15613                Limbs::<7>::zero()
15614            }
15615        }
15616        PrimitiveOp::Lt => {
15617            if limbs_lt_7(a, b) {
15618                limbs_one_7()
15619            } else {
15620                Limbs::<7>::zero()
15621            }
15622        }
15623        PrimitiveOp::Ge => {
15624            if limbs_le_7(b, a) {
15625                limbs_one_7()
15626            } else {
15627                Limbs::<7>::zero()
15628            }
15629        }
15630        PrimitiveOp::Gt => {
15631            if limbs_lt_7(b, a) {
15632                limbs_one_7()
15633            } else {
15634                Limbs::<7>::zero()
15635            }
15636        }
15637        PrimitiveOp::Concat => Limbs::<7>::zero(),
15638        PrimitiveOp::Div => {
15639            if limbs_is_zero_7(b) {
15640                Limbs::<7>::zero()
15641            } else {
15642                limbs_div_7(a, b)
15643            }
15644        }
15645        PrimitiveOp::Mod => {
15646            if limbs_is_zero_7(b) {
15647                Limbs::<7>::zero()
15648            } else {
15649                limbs_mod_7(a, b)
15650            }
15651        }
15652        PrimitiveOp::Pow => limbs_pow_7(a, b),
15653    }
15654}
15655
15656#[inline]
15657#[must_use]
15658pub const fn const_ring_eval_w512(op: PrimitiveOp, a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
15659    match op {
15660        PrimitiveOp::Add => a.wrapping_add(b),
15661        PrimitiveOp::Sub => a.wrapping_sub(b),
15662        PrimitiveOp::Mul => a.wrapping_mul(b),
15663        PrimitiveOp::And => a.and(b),
15664        PrimitiveOp::Or => a.or(b),
15665        PrimitiveOp::Xor => a.xor(b),
15666        PrimitiveOp::Neg => Limbs::<8>::zero().wrapping_sub(a),
15667        PrimitiveOp::Bnot => a.not(),
15668        PrimitiveOp::Succ => a.wrapping_add(limbs_one_8()),
15669        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_8()),
15670        PrimitiveOp::Le => {
15671            if limbs_le_8(a, b) {
15672                limbs_one_8()
15673            } else {
15674                Limbs::<8>::zero()
15675            }
15676        }
15677        PrimitiveOp::Lt => {
15678            if limbs_lt_8(a, b) {
15679                limbs_one_8()
15680            } else {
15681                Limbs::<8>::zero()
15682            }
15683        }
15684        PrimitiveOp::Ge => {
15685            if limbs_le_8(b, a) {
15686                limbs_one_8()
15687            } else {
15688                Limbs::<8>::zero()
15689            }
15690        }
15691        PrimitiveOp::Gt => {
15692            if limbs_lt_8(b, a) {
15693                limbs_one_8()
15694            } else {
15695                Limbs::<8>::zero()
15696            }
15697        }
15698        PrimitiveOp::Concat => Limbs::<8>::zero(),
15699        PrimitiveOp::Div => {
15700            if limbs_is_zero_8(b) {
15701                Limbs::<8>::zero()
15702            } else {
15703                limbs_div_8(a, b)
15704            }
15705        }
15706        PrimitiveOp::Mod => {
15707            if limbs_is_zero_8(b) {
15708                Limbs::<8>::zero()
15709            } else {
15710                limbs_mod_8(a, b)
15711            }
15712        }
15713        PrimitiveOp::Pow => limbs_pow_8(a, b),
15714    }
15715}
15716
15717#[inline]
15718#[must_use]
15719pub const fn const_ring_eval_w520(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
15720    let raw = match op {
15721        PrimitiveOp::Add => a.wrapping_add(b),
15722        PrimitiveOp::Sub => a.wrapping_sub(b),
15723        PrimitiveOp::Mul => a.wrapping_mul(b),
15724        PrimitiveOp::And => a.and(b),
15725        PrimitiveOp::Or => a.or(b),
15726        PrimitiveOp::Xor => a.xor(b),
15727        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
15728        PrimitiveOp::Bnot => a.not(),
15729        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
15730        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
15731        PrimitiveOp::Le => {
15732            if limbs_le_9(a, b) {
15733                limbs_one_9()
15734            } else {
15735                Limbs::<9>::zero()
15736            }
15737        }
15738        PrimitiveOp::Lt => {
15739            if limbs_lt_9(a, b) {
15740                limbs_one_9()
15741            } else {
15742                Limbs::<9>::zero()
15743            }
15744        }
15745        PrimitiveOp::Ge => {
15746            if limbs_le_9(b, a) {
15747                limbs_one_9()
15748            } else {
15749                Limbs::<9>::zero()
15750            }
15751        }
15752        PrimitiveOp::Gt => {
15753            if limbs_lt_9(b, a) {
15754                limbs_one_9()
15755            } else {
15756                Limbs::<9>::zero()
15757            }
15758        }
15759        PrimitiveOp::Concat => Limbs::<9>::zero(),
15760        PrimitiveOp::Div => {
15761            if limbs_is_zero_9(b) {
15762                Limbs::<9>::zero()
15763            } else {
15764                limbs_div_9(a, b)
15765            }
15766        }
15767        PrimitiveOp::Mod => {
15768            if limbs_is_zero_9(b) {
15769                Limbs::<9>::zero()
15770            } else {
15771                limbs_mod_9(a, b)
15772            }
15773        }
15774        PrimitiveOp::Pow => limbs_pow_9(a, b),
15775    };
15776    raw.mask_high_bits(520)
15777}
15778
15779#[inline]
15780#[must_use]
15781pub const fn const_ring_eval_w528(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
15782    let raw = match op {
15783        PrimitiveOp::Add => a.wrapping_add(b),
15784        PrimitiveOp::Sub => a.wrapping_sub(b),
15785        PrimitiveOp::Mul => a.wrapping_mul(b),
15786        PrimitiveOp::And => a.and(b),
15787        PrimitiveOp::Or => a.or(b),
15788        PrimitiveOp::Xor => a.xor(b),
15789        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
15790        PrimitiveOp::Bnot => a.not(),
15791        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
15792        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
15793        PrimitiveOp::Le => {
15794            if limbs_le_9(a, b) {
15795                limbs_one_9()
15796            } else {
15797                Limbs::<9>::zero()
15798            }
15799        }
15800        PrimitiveOp::Lt => {
15801            if limbs_lt_9(a, b) {
15802                limbs_one_9()
15803            } else {
15804                Limbs::<9>::zero()
15805            }
15806        }
15807        PrimitiveOp::Ge => {
15808            if limbs_le_9(b, a) {
15809                limbs_one_9()
15810            } else {
15811                Limbs::<9>::zero()
15812            }
15813        }
15814        PrimitiveOp::Gt => {
15815            if limbs_lt_9(b, a) {
15816                limbs_one_9()
15817            } else {
15818                Limbs::<9>::zero()
15819            }
15820        }
15821        PrimitiveOp::Concat => Limbs::<9>::zero(),
15822        PrimitiveOp::Div => {
15823            if limbs_is_zero_9(b) {
15824                Limbs::<9>::zero()
15825            } else {
15826                limbs_div_9(a, b)
15827            }
15828        }
15829        PrimitiveOp::Mod => {
15830            if limbs_is_zero_9(b) {
15831                Limbs::<9>::zero()
15832            } else {
15833                limbs_mod_9(a, b)
15834            }
15835        }
15836        PrimitiveOp::Pow => limbs_pow_9(a, b),
15837    };
15838    raw.mask_high_bits(528)
15839}
15840
15841#[inline]
15842#[must_use]
15843pub const fn const_ring_eval_w1024(op: PrimitiveOp, a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
15844    match op {
15845        PrimitiveOp::Add => a.wrapping_add(b),
15846        PrimitiveOp::Sub => a.wrapping_sub(b),
15847        PrimitiveOp::Mul => a.wrapping_mul(b),
15848        PrimitiveOp::And => a.and(b),
15849        PrimitiveOp::Or => a.or(b),
15850        PrimitiveOp::Xor => a.xor(b),
15851        PrimitiveOp::Neg => Limbs::<16>::zero().wrapping_sub(a),
15852        PrimitiveOp::Bnot => a.not(),
15853        PrimitiveOp::Succ => a.wrapping_add(limbs_one_16()),
15854        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_16()),
15855        PrimitiveOp::Le => {
15856            if limbs_le_16(a, b) {
15857                limbs_one_16()
15858            } else {
15859                Limbs::<16>::zero()
15860            }
15861        }
15862        PrimitiveOp::Lt => {
15863            if limbs_lt_16(a, b) {
15864                limbs_one_16()
15865            } else {
15866                Limbs::<16>::zero()
15867            }
15868        }
15869        PrimitiveOp::Ge => {
15870            if limbs_le_16(b, a) {
15871                limbs_one_16()
15872            } else {
15873                Limbs::<16>::zero()
15874            }
15875        }
15876        PrimitiveOp::Gt => {
15877            if limbs_lt_16(b, a) {
15878                limbs_one_16()
15879            } else {
15880                Limbs::<16>::zero()
15881            }
15882        }
15883        PrimitiveOp::Concat => Limbs::<16>::zero(),
15884        PrimitiveOp::Div => {
15885            if limbs_is_zero_16(b) {
15886                Limbs::<16>::zero()
15887            } else {
15888                limbs_div_16(a, b)
15889            }
15890        }
15891        PrimitiveOp::Mod => {
15892            if limbs_is_zero_16(b) {
15893                Limbs::<16>::zero()
15894            } else {
15895                limbs_mod_16(a, b)
15896            }
15897        }
15898        PrimitiveOp::Pow => limbs_pow_16(a, b),
15899    }
15900}
15901
15902#[inline]
15903#[must_use]
15904pub const fn const_ring_eval_w2048(op: PrimitiveOp, a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15905    match op {
15906        PrimitiveOp::Add => a.wrapping_add(b),
15907        PrimitiveOp::Sub => a.wrapping_sub(b),
15908        PrimitiveOp::Mul => a.wrapping_mul(b),
15909        PrimitiveOp::And => a.and(b),
15910        PrimitiveOp::Or => a.or(b),
15911        PrimitiveOp::Xor => a.xor(b),
15912        PrimitiveOp::Neg => Limbs::<32>::zero().wrapping_sub(a),
15913        PrimitiveOp::Bnot => a.not(),
15914        PrimitiveOp::Succ => a.wrapping_add(limbs_one_32()),
15915        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_32()),
15916        PrimitiveOp::Le => {
15917            if limbs_le_32(a, b) {
15918                limbs_one_32()
15919            } else {
15920                Limbs::<32>::zero()
15921            }
15922        }
15923        PrimitiveOp::Lt => {
15924            if limbs_lt_32(a, b) {
15925                limbs_one_32()
15926            } else {
15927                Limbs::<32>::zero()
15928            }
15929        }
15930        PrimitiveOp::Ge => {
15931            if limbs_le_32(b, a) {
15932                limbs_one_32()
15933            } else {
15934                Limbs::<32>::zero()
15935            }
15936        }
15937        PrimitiveOp::Gt => {
15938            if limbs_lt_32(b, a) {
15939                limbs_one_32()
15940            } else {
15941                Limbs::<32>::zero()
15942            }
15943        }
15944        PrimitiveOp::Concat => Limbs::<32>::zero(),
15945        PrimitiveOp::Div => {
15946            if limbs_is_zero_32(b) {
15947                Limbs::<32>::zero()
15948            } else {
15949                limbs_div_32(a, b)
15950            }
15951        }
15952        PrimitiveOp::Mod => {
15953            if limbs_is_zero_32(b) {
15954                Limbs::<32>::zero()
15955            } else {
15956                limbs_mod_32(a, b)
15957            }
15958        }
15959        PrimitiveOp::Pow => limbs_pow_32(a, b),
15960    }
15961}
15962
15963#[inline]
15964#[must_use]
15965pub const fn const_ring_eval_w4096(op: PrimitiveOp, a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15966    match op {
15967        PrimitiveOp::Add => a.wrapping_add(b),
15968        PrimitiveOp::Sub => a.wrapping_sub(b),
15969        PrimitiveOp::Mul => a.wrapping_mul(b),
15970        PrimitiveOp::And => a.and(b),
15971        PrimitiveOp::Or => a.or(b),
15972        PrimitiveOp::Xor => a.xor(b),
15973        PrimitiveOp::Neg => Limbs::<64>::zero().wrapping_sub(a),
15974        PrimitiveOp::Bnot => a.not(),
15975        PrimitiveOp::Succ => a.wrapping_add(limbs_one_64()),
15976        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_64()),
15977        PrimitiveOp::Le => {
15978            if limbs_le_64(a, b) {
15979                limbs_one_64()
15980            } else {
15981                Limbs::<64>::zero()
15982            }
15983        }
15984        PrimitiveOp::Lt => {
15985            if limbs_lt_64(a, b) {
15986                limbs_one_64()
15987            } else {
15988                Limbs::<64>::zero()
15989            }
15990        }
15991        PrimitiveOp::Ge => {
15992            if limbs_le_64(b, a) {
15993                limbs_one_64()
15994            } else {
15995                Limbs::<64>::zero()
15996            }
15997        }
15998        PrimitiveOp::Gt => {
15999            if limbs_lt_64(b, a) {
16000                limbs_one_64()
16001            } else {
16002                Limbs::<64>::zero()
16003            }
16004        }
16005        PrimitiveOp::Concat => Limbs::<64>::zero(),
16006        PrimitiveOp::Div => {
16007            if limbs_is_zero_64(b) {
16008                Limbs::<64>::zero()
16009            } else {
16010                limbs_div_64(a, b)
16011            }
16012        }
16013        PrimitiveOp::Mod => {
16014            if limbs_is_zero_64(b) {
16015                Limbs::<64>::zero()
16016            } else {
16017                limbs_mod_64(a, b)
16018            }
16019        }
16020        PrimitiveOp::Pow => limbs_pow_64(a, b),
16021    }
16022}
16023
16024#[inline]
16025#[must_use]
16026pub const fn const_ring_eval_w8192(op: PrimitiveOp, a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
16027    match op {
16028        PrimitiveOp::Add => a.wrapping_add(b),
16029        PrimitiveOp::Sub => a.wrapping_sub(b),
16030        PrimitiveOp::Mul => a.wrapping_mul(b),
16031        PrimitiveOp::And => a.and(b),
16032        PrimitiveOp::Or => a.or(b),
16033        PrimitiveOp::Xor => a.xor(b),
16034        PrimitiveOp::Neg => Limbs::<128>::zero().wrapping_sub(a),
16035        PrimitiveOp::Bnot => a.not(),
16036        PrimitiveOp::Succ => a.wrapping_add(limbs_one_128()),
16037        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_128()),
16038        PrimitiveOp::Le => {
16039            if limbs_le_128(a, b) {
16040                limbs_one_128()
16041            } else {
16042                Limbs::<128>::zero()
16043            }
16044        }
16045        PrimitiveOp::Lt => {
16046            if limbs_lt_128(a, b) {
16047                limbs_one_128()
16048            } else {
16049                Limbs::<128>::zero()
16050            }
16051        }
16052        PrimitiveOp::Ge => {
16053            if limbs_le_128(b, a) {
16054                limbs_one_128()
16055            } else {
16056                Limbs::<128>::zero()
16057            }
16058        }
16059        PrimitiveOp::Gt => {
16060            if limbs_lt_128(b, a) {
16061                limbs_one_128()
16062            } else {
16063                Limbs::<128>::zero()
16064            }
16065        }
16066        PrimitiveOp::Concat => Limbs::<128>::zero(),
16067        PrimitiveOp::Div => {
16068            if limbs_is_zero_128(b) {
16069                Limbs::<128>::zero()
16070            } else {
16071                limbs_div_128(a, b)
16072            }
16073        }
16074        PrimitiveOp::Mod => {
16075            if limbs_is_zero_128(b) {
16076                Limbs::<128>::zero()
16077            } else {
16078                limbs_mod_128(a, b)
16079            }
16080        }
16081        PrimitiveOp::Pow => limbs_pow_128(a, b),
16082    }
16083}
16084
16085#[inline]
16086#[must_use]
16087pub const fn const_ring_eval_w12288(op: PrimitiveOp, a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
16088    match op {
16089        PrimitiveOp::Add => a.wrapping_add(b),
16090        PrimitiveOp::Sub => a.wrapping_sub(b),
16091        PrimitiveOp::Mul => a.wrapping_mul(b),
16092        PrimitiveOp::And => a.and(b),
16093        PrimitiveOp::Or => a.or(b),
16094        PrimitiveOp::Xor => a.xor(b),
16095        PrimitiveOp::Neg => Limbs::<192>::zero().wrapping_sub(a),
16096        PrimitiveOp::Bnot => a.not(),
16097        PrimitiveOp::Succ => a.wrapping_add(limbs_one_192()),
16098        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_192()),
16099        PrimitiveOp::Le => {
16100            if limbs_le_192(a, b) {
16101                limbs_one_192()
16102            } else {
16103                Limbs::<192>::zero()
16104            }
16105        }
16106        PrimitiveOp::Lt => {
16107            if limbs_lt_192(a, b) {
16108                limbs_one_192()
16109            } else {
16110                Limbs::<192>::zero()
16111            }
16112        }
16113        PrimitiveOp::Ge => {
16114            if limbs_le_192(b, a) {
16115                limbs_one_192()
16116            } else {
16117                Limbs::<192>::zero()
16118            }
16119        }
16120        PrimitiveOp::Gt => {
16121            if limbs_lt_192(b, a) {
16122                limbs_one_192()
16123            } else {
16124                Limbs::<192>::zero()
16125            }
16126        }
16127        PrimitiveOp::Concat => Limbs::<192>::zero(),
16128        PrimitiveOp::Div => {
16129            if limbs_is_zero_192(b) {
16130                Limbs::<192>::zero()
16131            } else {
16132                limbs_div_192(a, b)
16133            }
16134        }
16135        PrimitiveOp::Mod => {
16136            if limbs_is_zero_192(b) {
16137                Limbs::<192>::zero()
16138            } else {
16139                limbs_mod_192(a, b)
16140            }
16141        }
16142        PrimitiveOp::Pow => limbs_pow_192(a, b),
16143    }
16144}
16145
16146#[inline]
16147#[must_use]
16148pub const fn const_ring_eval_w16384(op: PrimitiveOp, a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
16149    match op {
16150        PrimitiveOp::Add => a.wrapping_add(b),
16151        PrimitiveOp::Sub => a.wrapping_sub(b),
16152        PrimitiveOp::Mul => a.wrapping_mul(b),
16153        PrimitiveOp::And => a.and(b),
16154        PrimitiveOp::Or => a.or(b),
16155        PrimitiveOp::Xor => a.xor(b),
16156        PrimitiveOp::Neg => Limbs::<256>::zero().wrapping_sub(a),
16157        PrimitiveOp::Bnot => a.not(),
16158        PrimitiveOp::Succ => a.wrapping_add(limbs_one_256()),
16159        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_256()),
16160        PrimitiveOp::Le => {
16161            if limbs_le_256(a, b) {
16162                limbs_one_256()
16163            } else {
16164                Limbs::<256>::zero()
16165            }
16166        }
16167        PrimitiveOp::Lt => {
16168            if limbs_lt_256(a, b) {
16169                limbs_one_256()
16170            } else {
16171                Limbs::<256>::zero()
16172            }
16173        }
16174        PrimitiveOp::Ge => {
16175            if limbs_le_256(b, a) {
16176                limbs_one_256()
16177            } else {
16178                Limbs::<256>::zero()
16179            }
16180        }
16181        PrimitiveOp::Gt => {
16182            if limbs_lt_256(b, a) {
16183                limbs_one_256()
16184            } else {
16185                Limbs::<256>::zero()
16186            }
16187        }
16188        PrimitiveOp::Concat => Limbs::<256>::zero(),
16189        PrimitiveOp::Div => {
16190            if limbs_is_zero_256(b) {
16191                Limbs::<256>::zero()
16192            } else {
16193                limbs_div_256(a, b)
16194            }
16195        }
16196        PrimitiveOp::Mod => {
16197            if limbs_is_zero_256(b) {
16198                Limbs::<256>::zero()
16199            } else {
16200                limbs_mod_256(a, b)
16201            }
16202        }
16203        PrimitiveOp::Pow => limbs_pow_256(a, b),
16204    }
16205}
16206
16207#[inline]
16208#[must_use]
16209pub const fn const_ring_eval_w32768(op: PrimitiveOp, a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
16210    match op {
16211        PrimitiveOp::Add => a.wrapping_add(b),
16212        PrimitiveOp::Sub => a.wrapping_sub(b),
16213        PrimitiveOp::Mul => a.wrapping_mul(b),
16214        PrimitiveOp::And => a.and(b),
16215        PrimitiveOp::Or => a.or(b),
16216        PrimitiveOp::Xor => a.xor(b),
16217        PrimitiveOp::Neg => Limbs::<512>::zero().wrapping_sub(a),
16218        PrimitiveOp::Bnot => a.not(),
16219        PrimitiveOp::Succ => a.wrapping_add(limbs_one_512()),
16220        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_512()),
16221        PrimitiveOp::Le => {
16222            if limbs_le_512(a, b) {
16223                limbs_one_512()
16224            } else {
16225                Limbs::<512>::zero()
16226            }
16227        }
16228        PrimitiveOp::Lt => {
16229            if limbs_lt_512(a, b) {
16230                limbs_one_512()
16231            } else {
16232                Limbs::<512>::zero()
16233            }
16234        }
16235        PrimitiveOp::Ge => {
16236            if limbs_le_512(b, a) {
16237                limbs_one_512()
16238            } else {
16239                Limbs::<512>::zero()
16240            }
16241        }
16242        PrimitiveOp::Gt => {
16243            if limbs_lt_512(b, a) {
16244                limbs_one_512()
16245            } else {
16246                Limbs::<512>::zero()
16247            }
16248        }
16249        PrimitiveOp::Concat => Limbs::<512>::zero(),
16250        PrimitiveOp::Div => {
16251            if limbs_is_zero_512(b) {
16252                Limbs::<512>::zero()
16253            } else {
16254                limbs_div_512(a, b)
16255            }
16256        }
16257        PrimitiveOp::Mod => {
16258            if limbs_is_zero_512(b) {
16259                Limbs::<512>::zero()
16260            } else {
16261                limbs_mod_512(a, b)
16262            }
16263        }
16264        PrimitiveOp::Pow => limbs_pow_512(a, b),
16265    }
16266}
16267
16268/// Phase L.2: one-constant helpers for `Limbs<N>::from_words([1, 0, ...])`.
16269#[inline]
16270#[must_use]
16271const fn limbs_one_3() -> Limbs<3> {
16272    Limbs::<3>::from_words([1u64, 0u64, 0u64])
16273}
16274
16275#[inline]
16276#[must_use]
16277const fn limbs_one_4() -> Limbs<4> {
16278    Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64])
16279}
16280
16281#[inline]
16282#[must_use]
16283const fn limbs_one_6() -> Limbs<6> {
16284    Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16285}
16286
16287#[inline]
16288#[must_use]
16289const fn limbs_one_7() -> Limbs<7> {
16290    Limbs::<7>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16291}
16292
16293#[inline]
16294#[must_use]
16295const fn limbs_one_8() -> Limbs<8> {
16296    Limbs::<8>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16297}
16298
16299#[inline]
16300#[must_use]
16301const fn limbs_one_9() -> Limbs<9> {
16302    Limbs::<9>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16303}
16304
16305#[inline]
16306#[must_use]
16307const fn limbs_one_16() -> Limbs<16> {
16308    Limbs::<16>::from_words([
16309        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16310        0u64,
16311    ])
16312}
16313
16314#[inline]
16315#[must_use]
16316const fn limbs_one_32() -> Limbs<32> {
16317    Limbs::<32>::from_words([
16318        1u64, 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,
16321    ])
16322}
16323
16324#[inline]
16325#[must_use]
16326const fn limbs_one_64() -> Limbs<64> {
16327    Limbs::<64>::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,
16333    ])
16334}
16335
16336#[inline]
16337#[must_use]
16338const fn limbs_one_128() -> Limbs<128> {
16339    Limbs::<128>::from_words([
16340        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16341        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16342        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16343        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16344        0u64, 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,
16349    ])
16350}
16351
16352#[inline]
16353#[must_use]
16354const fn limbs_one_192() -> Limbs<192> {
16355    Limbs::<192>::from_words([
16356        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16357        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16358        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16359        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16360        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16361        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16362        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16363        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16364        0u64, 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,
16369    ])
16370}
16371
16372#[inline]
16373#[must_use]
16374const fn limbs_one_256() -> Limbs<256> {
16375    Limbs::<256>::from_words([
16376        1u64, 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, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16382        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16383        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16384        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16385        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16386        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16387        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16388        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16389        0u64, 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,
16394    ])
16395}
16396
16397#[inline]
16398#[must_use]
16399const fn limbs_one_512() -> Limbs<512> {
16400    Limbs::<512>::from_words([
16401        1u64, 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, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16424        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16425        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16426        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16427        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16428        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16429        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16430        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16431        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16432        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16433        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16434        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16435        0u64, 0u64,
16436    ])
16437}
16438
16439/// ADR-013/TR-08: const-fn limb comparisons used by `const_ring_eval_w{n}`
16440/// to lift the comparison primitives to 0/1-valued ring indicators.
16441#[inline]
16442#[must_use]
16443const fn limbs_lt_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16444    let aw = a.words();
16445    let bw = b.words();
16446    let mut i = 3;
16447    while i > 0 {
16448        i -= 1;
16449        if aw[i] < bw[i] {
16450            return true;
16451        }
16452        if aw[i] > bw[i] {
16453            return false;
16454        }
16455    }
16456    false
16457}
16458
16459#[inline]
16460#[must_use]
16461const fn limbs_le_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16462    let aw = a.words();
16463    let bw = b.words();
16464    let mut i = 3;
16465    while i > 0 {
16466        i -= 1;
16467        if aw[i] < bw[i] {
16468            return true;
16469        }
16470        if aw[i] > bw[i] {
16471            return false;
16472        }
16473    }
16474    true
16475}
16476
16477#[inline]
16478#[must_use]
16479const fn limbs_lt_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16480    let aw = a.words();
16481    let bw = b.words();
16482    let mut i = 4;
16483    while i > 0 {
16484        i -= 1;
16485        if aw[i] < bw[i] {
16486            return true;
16487        }
16488        if aw[i] > bw[i] {
16489            return false;
16490        }
16491    }
16492    false
16493}
16494
16495#[inline]
16496#[must_use]
16497const fn limbs_le_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16498    let aw = a.words();
16499    let bw = b.words();
16500    let mut i = 4;
16501    while i > 0 {
16502        i -= 1;
16503        if aw[i] < bw[i] {
16504            return true;
16505        }
16506        if aw[i] > bw[i] {
16507            return false;
16508        }
16509    }
16510    true
16511}
16512
16513#[inline]
16514#[must_use]
16515const fn limbs_lt_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16516    let aw = a.words();
16517    let bw = b.words();
16518    let mut i = 6;
16519    while i > 0 {
16520        i -= 1;
16521        if aw[i] < bw[i] {
16522            return true;
16523        }
16524        if aw[i] > bw[i] {
16525            return false;
16526        }
16527    }
16528    false
16529}
16530
16531#[inline]
16532#[must_use]
16533const fn limbs_le_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16534    let aw = a.words();
16535    let bw = b.words();
16536    let mut i = 6;
16537    while i > 0 {
16538        i -= 1;
16539        if aw[i] < bw[i] {
16540            return true;
16541        }
16542        if aw[i] > bw[i] {
16543            return false;
16544        }
16545    }
16546    true
16547}
16548
16549#[inline]
16550#[must_use]
16551const fn limbs_lt_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16552    let aw = a.words();
16553    let bw = b.words();
16554    let mut i = 7;
16555    while i > 0 {
16556        i -= 1;
16557        if aw[i] < bw[i] {
16558            return true;
16559        }
16560        if aw[i] > bw[i] {
16561            return false;
16562        }
16563    }
16564    false
16565}
16566
16567#[inline]
16568#[must_use]
16569const fn limbs_le_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16570    let aw = a.words();
16571    let bw = b.words();
16572    let mut i = 7;
16573    while i > 0 {
16574        i -= 1;
16575        if aw[i] < bw[i] {
16576            return true;
16577        }
16578        if aw[i] > bw[i] {
16579            return false;
16580        }
16581    }
16582    true
16583}
16584
16585#[inline]
16586#[must_use]
16587const fn limbs_lt_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16588    let aw = a.words();
16589    let bw = b.words();
16590    let mut i = 8;
16591    while i > 0 {
16592        i -= 1;
16593        if aw[i] < bw[i] {
16594            return true;
16595        }
16596        if aw[i] > bw[i] {
16597            return false;
16598        }
16599    }
16600    false
16601}
16602
16603#[inline]
16604#[must_use]
16605const fn limbs_le_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16606    let aw = a.words();
16607    let bw = b.words();
16608    let mut i = 8;
16609    while i > 0 {
16610        i -= 1;
16611        if aw[i] < bw[i] {
16612            return true;
16613        }
16614        if aw[i] > bw[i] {
16615            return false;
16616        }
16617    }
16618    true
16619}
16620
16621#[inline]
16622#[must_use]
16623const fn limbs_lt_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16624    let aw = a.words();
16625    let bw = b.words();
16626    let mut i = 9;
16627    while i > 0 {
16628        i -= 1;
16629        if aw[i] < bw[i] {
16630            return true;
16631        }
16632        if aw[i] > bw[i] {
16633            return false;
16634        }
16635    }
16636    false
16637}
16638
16639#[inline]
16640#[must_use]
16641const fn limbs_le_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16642    let aw = a.words();
16643    let bw = b.words();
16644    let mut i = 9;
16645    while i > 0 {
16646        i -= 1;
16647        if aw[i] < bw[i] {
16648            return true;
16649        }
16650        if aw[i] > bw[i] {
16651            return false;
16652        }
16653    }
16654    true
16655}
16656
16657#[inline]
16658#[must_use]
16659const fn limbs_lt_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16660    let aw = a.words();
16661    let bw = b.words();
16662    let mut i = 16;
16663    while i > 0 {
16664        i -= 1;
16665        if aw[i] < bw[i] {
16666            return true;
16667        }
16668        if aw[i] > bw[i] {
16669            return false;
16670        }
16671    }
16672    false
16673}
16674
16675#[inline]
16676#[must_use]
16677const fn limbs_le_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16678    let aw = a.words();
16679    let bw = b.words();
16680    let mut i = 16;
16681    while i > 0 {
16682        i -= 1;
16683        if aw[i] < bw[i] {
16684            return true;
16685        }
16686        if aw[i] > bw[i] {
16687            return false;
16688        }
16689    }
16690    true
16691}
16692
16693#[inline]
16694#[must_use]
16695const fn limbs_lt_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16696    let aw = a.words();
16697    let bw = b.words();
16698    let mut i = 32;
16699    while i > 0 {
16700        i -= 1;
16701        if aw[i] < bw[i] {
16702            return true;
16703        }
16704        if aw[i] > bw[i] {
16705            return false;
16706        }
16707    }
16708    false
16709}
16710
16711#[inline]
16712#[must_use]
16713const fn limbs_le_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16714    let aw = a.words();
16715    let bw = b.words();
16716    let mut i = 32;
16717    while i > 0 {
16718        i -= 1;
16719        if aw[i] < bw[i] {
16720            return true;
16721        }
16722        if aw[i] > bw[i] {
16723            return false;
16724        }
16725    }
16726    true
16727}
16728
16729#[inline]
16730#[must_use]
16731const fn limbs_lt_64(a: Limbs<64>, b: Limbs<64>) -> bool {
16732    let aw = a.words();
16733    let bw = b.words();
16734    let mut i = 64;
16735    while i > 0 {
16736        i -= 1;
16737        if aw[i] < bw[i] {
16738            return true;
16739        }
16740        if aw[i] > bw[i] {
16741            return false;
16742        }
16743    }
16744    false
16745}
16746
16747#[inline]
16748#[must_use]
16749const fn limbs_le_64(a: Limbs<64>, b: Limbs<64>) -> bool {
16750    let aw = a.words();
16751    let bw = b.words();
16752    let mut i = 64;
16753    while i > 0 {
16754        i -= 1;
16755        if aw[i] < bw[i] {
16756            return true;
16757        }
16758        if aw[i] > bw[i] {
16759            return false;
16760        }
16761    }
16762    true
16763}
16764
16765#[inline]
16766#[must_use]
16767const fn limbs_lt_128(a: Limbs<128>, b: Limbs<128>) -> bool {
16768    let aw = a.words();
16769    let bw = b.words();
16770    let mut i = 128;
16771    while i > 0 {
16772        i -= 1;
16773        if aw[i] < bw[i] {
16774            return true;
16775        }
16776        if aw[i] > bw[i] {
16777            return false;
16778        }
16779    }
16780    false
16781}
16782
16783#[inline]
16784#[must_use]
16785const fn limbs_le_128(a: Limbs<128>, b: Limbs<128>) -> bool {
16786    let aw = a.words();
16787    let bw = b.words();
16788    let mut i = 128;
16789    while i > 0 {
16790        i -= 1;
16791        if aw[i] < bw[i] {
16792            return true;
16793        }
16794        if aw[i] > bw[i] {
16795            return false;
16796        }
16797    }
16798    true
16799}
16800
16801#[inline]
16802#[must_use]
16803const fn limbs_lt_192(a: Limbs<192>, b: Limbs<192>) -> bool {
16804    let aw = a.words();
16805    let bw = b.words();
16806    let mut i = 192;
16807    while i > 0 {
16808        i -= 1;
16809        if aw[i] < bw[i] {
16810            return true;
16811        }
16812        if aw[i] > bw[i] {
16813            return false;
16814        }
16815    }
16816    false
16817}
16818
16819#[inline]
16820#[must_use]
16821const fn limbs_le_192(a: Limbs<192>, b: Limbs<192>) -> bool {
16822    let aw = a.words();
16823    let bw = b.words();
16824    let mut i = 192;
16825    while i > 0 {
16826        i -= 1;
16827        if aw[i] < bw[i] {
16828            return true;
16829        }
16830        if aw[i] > bw[i] {
16831            return false;
16832        }
16833    }
16834    true
16835}
16836
16837#[inline]
16838#[must_use]
16839const fn limbs_lt_256(a: Limbs<256>, b: Limbs<256>) -> bool {
16840    let aw = a.words();
16841    let bw = b.words();
16842    let mut i = 256;
16843    while i > 0 {
16844        i -= 1;
16845        if aw[i] < bw[i] {
16846            return true;
16847        }
16848        if aw[i] > bw[i] {
16849            return false;
16850        }
16851    }
16852    false
16853}
16854
16855#[inline]
16856#[must_use]
16857const fn limbs_le_256(a: Limbs<256>, b: Limbs<256>) -> bool {
16858    let aw = a.words();
16859    let bw = b.words();
16860    let mut i = 256;
16861    while i > 0 {
16862        i -= 1;
16863        if aw[i] < bw[i] {
16864            return true;
16865        }
16866        if aw[i] > bw[i] {
16867            return false;
16868        }
16869    }
16870    true
16871}
16872
16873#[inline]
16874#[must_use]
16875const fn limbs_lt_512(a: Limbs<512>, b: Limbs<512>) -> bool {
16876    let aw = a.words();
16877    let bw = b.words();
16878    let mut i = 512;
16879    while i > 0 {
16880        i -= 1;
16881        if aw[i] < bw[i] {
16882            return true;
16883        }
16884        if aw[i] > bw[i] {
16885            return false;
16886        }
16887    }
16888    false
16889}
16890
16891#[inline]
16892#[must_use]
16893const fn limbs_le_512(a: Limbs<512>, b: Limbs<512>) -> bool {
16894    let aw = a.words();
16895    let bw = b.words();
16896    let mut i = 512;
16897    while i > 0 {
16898        i -= 1;
16899        if aw[i] < bw[i] {
16900            return true;
16901        }
16902        if aw[i] > bw[i] {
16903            return false;
16904        }
16905    }
16906    true
16907}
16908
16909/// ADR-053: zero-check, binary-long-division, and square-and-multiply
16910/// helpers used by the const-fn `Div`/`Mod`/`Pow` arms of `const_ring_eval_w{n}`.
16911#[inline]
16912#[must_use]
16913const fn limbs_is_zero_3(a: Limbs<3>) -> bool {
16914    let aw = a.words();
16915    let mut i = 0usize;
16916    while i < 3 {
16917        if aw[i] != 0 {
16918            return false;
16919        }
16920        i += 1;
16921    }
16922    true
16923}
16924
16925#[inline]
16926#[must_use]
16927const fn limbs_shl1_3(a: Limbs<3>) -> Limbs<3> {
16928    let aw = a.words();
16929    let mut out = [0u64; 3];
16930    let mut carry: u64 = 0;
16931    let mut i = 0usize;
16932    while i < 3 {
16933        let v = aw[i];
16934        out[i] = (v << 1) | carry;
16935        carry = v >> 63;
16936        i += 1;
16937    }
16938    Limbs::<3>::from_words(out)
16939}
16940
16941#[inline]
16942#[must_use]
16943const fn limbs_set_bit0_3(a: Limbs<3>) -> Limbs<3> {
16944    let aw = a.words();
16945    let mut out = [0u64; 3];
16946    let mut i = 0usize;
16947    while i < 3 {
16948        out[i] = aw[i];
16949        i += 1;
16950    }
16951    out[0] |= 1u64;
16952    Limbs::<3>::from_words(out)
16953}
16954
16955#[inline]
16956#[must_use]
16957const fn limbs_bit_msb_3(a: Limbs<3>, msb_index: usize) -> u64 {
16958    let aw = a.words();
16959    let total_bits = 3 * 64;
16960    let lsb_index = total_bits - 1 - msb_index;
16961    let word = lsb_index / 64;
16962    let bit = lsb_index % 64;
16963    (aw[word] >> bit) & 1u64
16964}
16965
16966#[inline]
16967#[must_use]
16968const fn limbs_divmod_3(a: Limbs<3>, b: Limbs<3>) -> (Limbs<3>, Limbs<3>) {
16969    let mut q = Limbs::<3>::zero();
16970    let mut r = Limbs::<3>::zero();
16971    let total_bits = 3 * 64;
16972    let mut i = 0usize;
16973    while i < total_bits {
16974        r = limbs_shl1_3(r);
16975        if limbs_bit_msb_3(a, i) == 1 {
16976            r = limbs_set_bit0_3(r);
16977        }
16978        if limbs_le_3(b, r) {
16979            r = r.wrapping_sub(b);
16980            q = limbs_shl1_3(q);
16981            q = limbs_set_bit0_3(q);
16982        } else {
16983            q = limbs_shl1_3(q);
16984        }
16985        i += 1;
16986    }
16987    (q, r)
16988}
16989
16990#[inline]
16991#[must_use]
16992const fn limbs_div_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
16993    let (q, _) = limbs_divmod_3(a, b);
16994    q
16995}
16996
16997#[inline]
16998#[must_use]
16999const fn limbs_mod_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
17000    let (_, r) = limbs_divmod_3(a, b);
17001    r
17002}
17003
17004#[inline]
17005#[must_use]
17006const fn limbs_pow_3(base: Limbs<3>, exp: Limbs<3>) -> Limbs<3> {
17007    let mut result = limbs_one_3();
17008    let mut b = base;
17009    let ew = exp.words();
17010    let mut word = 0usize;
17011    while word < 3 {
17012        let mut bit = 0u32;
17013        while bit < 64 {
17014            if ((ew[word] >> bit) & 1u64) == 1u64 {
17015                result = result.wrapping_mul(b);
17016            }
17017            b = b.wrapping_mul(b);
17018            bit += 1;
17019        }
17020        word += 1;
17021    }
17022    result
17023}
17024
17025#[inline]
17026#[must_use]
17027const fn limbs_is_zero_4(a: Limbs<4>) -> bool {
17028    let aw = a.words();
17029    let mut i = 0usize;
17030    while i < 4 {
17031        if aw[i] != 0 {
17032            return false;
17033        }
17034        i += 1;
17035    }
17036    true
17037}
17038
17039#[inline]
17040#[must_use]
17041const fn limbs_shl1_4(a: Limbs<4>) -> Limbs<4> {
17042    let aw = a.words();
17043    let mut out = [0u64; 4];
17044    let mut carry: u64 = 0;
17045    let mut i = 0usize;
17046    while i < 4 {
17047        let v = aw[i];
17048        out[i] = (v << 1) | carry;
17049        carry = v >> 63;
17050        i += 1;
17051    }
17052    Limbs::<4>::from_words(out)
17053}
17054
17055#[inline]
17056#[must_use]
17057const fn limbs_set_bit0_4(a: Limbs<4>) -> Limbs<4> {
17058    let aw = a.words();
17059    let mut out = [0u64; 4];
17060    let mut i = 0usize;
17061    while i < 4 {
17062        out[i] = aw[i];
17063        i += 1;
17064    }
17065    out[0] |= 1u64;
17066    Limbs::<4>::from_words(out)
17067}
17068
17069#[inline]
17070#[must_use]
17071const fn limbs_bit_msb_4(a: Limbs<4>, msb_index: usize) -> u64 {
17072    let aw = a.words();
17073    let total_bits = 4 * 64;
17074    let lsb_index = total_bits - 1 - msb_index;
17075    let word = lsb_index / 64;
17076    let bit = lsb_index % 64;
17077    (aw[word] >> bit) & 1u64
17078}
17079
17080#[inline]
17081#[must_use]
17082const fn limbs_divmod_4(a: Limbs<4>, b: Limbs<4>) -> (Limbs<4>, Limbs<4>) {
17083    let mut q = Limbs::<4>::zero();
17084    let mut r = Limbs::<4>::zero();
17085    let total_bits = 4 * 64;
17086    let mut i = 0usize;
17087    while i < total_bits {
17088        r = limbs_shl1_4(r);
17089        if limbs_bit_msb_4(a, i) == 1 {
17090            r = limbs_set_bit0_4(r);
17091        }
17092        if limbs_le_4(b, r) {
17093            r = r.wrapping_sub(b);
17094            q = limbs_shl1_4(q);
17095            q = limbs_set_bit0_4(q);
17096        } else {
17097            q = limbs_shl1_4(q);
17098        }
17099        i += 1;
17100    }
17101    (q, r)
17102}
17103
17104#[inline]
17105#[must_use]
17106const fn limbs_div_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17107    let (q, _) = limbs_divmod_4(a, b);
17108    q
17109}
17110
17111#[inline]
17112#[must_use]
17113const fn limbs_mod_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17114    let (_, r) = limbs_divmod_4(a, b);
17115    r
17116}
17117
17118#[inline]
17119#[must_use]
17120const fn limbs_pow_4(base: Limbs<4>, exp: Limbs<4>) -> Limbs<4> {
17121    let mut result = limbs_one_4();
17122    let mut b = base;
17123    let ew = exp.words();
17124    let mut word = 0usize;
17125    while word < 4 {
17126        let mut bit = 0u32;
17127        while bit < 64 {
17128            if ((ew[word] >> bit) & 1u64) == 1u64 {
17129                result = result.wrapping_mul(b);
17130            }
17131            b = b.wrapping_mul(b);
17132            bit += 1;
17133        }
17134        word += 1;
17135    }
17136    result
17137}
17138
17139#[inline]
17140#[must_use]
17141const fn limbs_is_zero_6(a: Limbs<6>) -> bool {
17142    let aw = a.words();
17143    let mut i = 0usize;
17144    while i < 6 {
17145        if aw[i] != 0 {
17146            return false;
17147        }
17148        i += 1;
17149    }
17150    true
17151}
17152
17153#[inline]
17154#[must_use]
17155const fn limbs_shl1_6(a: Limbs<6>) -> Limbs<6> {
17156    let aw = a.words();
17157    let mut out = [0u64; 6];
17158    let mut carry: u64 = 0;
17159    let mut i = 0usize;
17160    while i < 6 {
17161        let v = aw[i];
17162        out[i] = (v << 1) | carry;
17163        carry = v >> 63;
17164        i += 1;
17165    }
17166    Limbs::<6>::from_words(out)
17167}
17168
17169#[inline]
17170#[must_use]
17171const fn limbs_set_bit0_6(a: Limbs<6>) -> Limbs<6> {
17172    let aw = a.words();
17173    let mut out = [0u64; 6];
17174    let mut i = 0usize;
17175    while i < 6 {
17176        out[i] = aw[i];
17177        i += 1;
17178    }
17179    out[0] |= 1u64;
17180    Limbs::<6>::from_words(out)
17181}
17182
17183#[inline]
17184#[must_use]
17185const fn limbs_bit_msb_6(a: Limbs<6>, msb_index: usize) -> u64 {
17186    let aw = a.words();
17187    let total_bits = 6 * 64;
17188    let lsb_index = total_bits - 1 - msb_index;
17189    let word = lsb_index / 64;
17190    let bit = lsb_index % 64;
17191    (aw[word] >> bit) & 1u64
17192}
17193
17194#[inline]
17195#[must_use]
17196const fn limbs_divmod_6(a: Limbs<6>, b: Limbs<6>) -> (Limbs<6>, Limbs<6>) {
17197    let mut q = Limbs::<6>::zero();
17198    let mut r = Limbs::<6>::zero();
17199    let total_bits = 6 * 64;
17200    let mut i = 0usize;
17201    while i < total_bits {
17202        r = limbs_shl1_6(r);
17203        if limbs_bit_msb_6(a, i) == 1 {
17204            r = limbs_set_bit0_6(r);
17205        }
17206        if limbs_le_6(b, r) {
17207            r = r.wrapping_sub(b);
17208            q = limbs_shl1_6(q);
17209            q = limbs_set_bit0_6(q);
17210        } else {
17211            q = limbs_shl1_6(q);
17212        }
17213        i += 1;
17214    }
17215    (q, r)
17216}
17217
17218#[inline]
17219#[must_use]
17220const fn limbs_div_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17221    let (q, _) = limbs_divmod_6(a, b);
17222    q
17223}
17224
17225#[inline]
17226#[must_use]
17227const fn limbs_mod_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17228    let (_, r) = limbs_divmod_6(a, b);
17229    r
17230}
17231
17232#[inline]
17233#[must_use]
17234const fn limbs_pow_6(base: Limbs<6>, exp: Limbs<6>) -> Limbs<6> {
17235    let mut result = limbs_one_6();
17236    let mut b = base;
17237    let ew = exp.words();
17238    let mut word = 0usize;
17239    while word < 6 {
17240        let mut bit = 0u32;
17241        while bit < 64 {
17242            if ((ew[word] >> bit) & 1u64) == 1u64 {
17243                result = result.wrapping_mul(b);
17244            }
17245            b = b.wrapping_mul(b);
17246            bit += 1;
17247        }
17248        word += 1;
17249    }
17250    result
17251}
17252
17253#[inline]
17254#[must_use]
17255const fn limbs_is_zero_7(a: Limbs<7>) -> bool {
17256    let aw = a.words();
17257    let mut i = 0usize;
17258    while i < 7 {
17259        if aw[i] != 0 {
17260            return false;
17261        }
17262        i += 1;
17263    }
17264    true
17265}
17266
17267#[inline]
17268#[must_use]
17269const fn limbs_shl1_7(a: Limbs<7>) -> Limbs<7> {
17270    let aw = a.words();
17271    let mut out = [0u64; 7];
17272    let mut carry: u64 = 0;
17273    let mut i = 0usize;
17274    while i < 7 {
17275        let v = aw[i];
17276        out[i] = (v << 1) | carry;
17277        carry = v >> 63;
17278        i += 1;
17279    }
17280    Limbs::<7>::from_words(out)
17281}
17282
17283#[inline]
17284#[must_use]
17285const fn limbs_set_bit0_7(a: Limbs<7>) -> Limbs<7> {
17286    let aw = a.words();
17287    let mut out = [0u64; 7];
17288    let mut i = 0usize;
17289    while i < 7 {
17290        out[i] = aw[i];
17291        i += 1;
17292    }
17293    out[0] |= 1u64;
17294    Limbs::<7>::from_words(out)
17295}
17296
17297#[inline]
17298#[must_use]
17299const fn limbs_bit_msb_7(a: Limbs<7>, msb_index: usize) -> u64 {
17300    let aw = a.words();
17301    let total_bits = 7 * 64;
17302    let lsb_index = total_bits - 1 - msb_index;
17303    let word = lsb_index / 64;
17304    let bit = lsb_index % 64;
17305    (aw[word] >> bit) & 1u64
17306}
17307
17308#[inline]
17309#[must_use]
17310const fn limbs_divmod_7(a: Limbs<7>, b: Limbs<7>) -> (Limbs<7>, Limbs<7>) {
17311    let mut q = Limbs::<7>::zero();
17312    let mut r = Limbs::<7>::zero();
17313    let total_bits = 7 * 64;
17314    let mut i = 0usize;
17315    while i < total_bits {
17316        r = limbs_shl1_7(r);
17317        if limbs_bit_msb_7(a, i) == 1 {
17318            r = limbs_set_bit0_7(r);
17319        }
17320        if limbs_le_7(b, r) {
17321            r = r.wrapping_sub(b);
17322            q = limbs_shl1_7(q);
17323            q = limbs_set_bit0_7(q);
17324        } else {
17325            q = limbs_shl1_7(q);
17326        }
17327        i += 1;
17328    }
17329    (q, r)
17330}
17331
17332#[inline]
17333#[must_use]
17334const fn limbs_div_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17335    let (q, _) = limbs_divmod_7(a, b);
17336    q
17337}
17338
17339#[inline]
17340#[must_use]
17341const fn limbs_mod_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17342    let (_, r) = limbs_divmod_7(a, b);
17343    r
17344}
17345
17346#[inline]
17347#[must_use]
17348const fn limbs_pow_7(base: Limbs<7>, exp: Limbs<7>) -> Limbs<7> {
17349    let mut result = limbs_one_7();
17350    let mut b = base;
17351    let ew = exp.words();
17352    let mut word = 0usize;
17353    while word < 7 {
17354        let mut bit = 0u32;
17355        while bit < 64 {
17356            if ((ew[word] >> bit) & 1u64) == 1u64 {
17357                result = result.wrapping_mul(b);
17358            }
17359            b = b.wrapping_mul(b);
17360            bit += 1;
17361        }
17362        word += 1;
17363    }
17364    result
17365}
17366
17367#[inline]
17368#[must_use]
17369const fn limbs_is_zero_8(a: Limbs<8>) -> bool {
17370    let aw = a.words();
17371    let mut i = 0usize;
17372    while i < 8 {
17373        if aw[i] != 0 {
17374            return false;
17375        }
17376        i += 1;
17377    }
17378    true
17379}
17380
17381#[inline]
17382#[must_use]
17383const fn limbs_shl1_8(a: Limbs<8>) -> Limbs<8> {
17384    let aw = a.words();
17385    let mut out = [0u64; 8];
17386    let mut carry: u64 = 0;
17387    let mut i = 0usize;
17388    while i < 8 {
17389        let v = aw[i];
17390        out[i] = (v << 1) | carry;
17391        carry = v >> 63;
17392        i += 1;
17393    }
17394    Limbs::<8>::from_words(out)
17395}
17396
17397#[inline]
17398#[must_use]
17399const fn limbs_set_bit0_8(a: Limbs<8>) -> Limbs<8> {
17400    let aw = a.words();
17401    let mut out = [0u64; 8];
17402    let mut i = 0usize;
17403    while i < 8 {
17404        out[i] = aw[i];
17405        i += 1;
17406    }
17407    out[0] |= 1u64;
17408    Limbs::<8>::from_words(out)
17409}
17410
17411#[inline]
17412#[must_use]
17413const fn limbs_bit_msb_8(a: Limbs<8>, msb_index: usize) -> u64 {
17414    let aw = a.words();
17415    let total_bits = 8 * 64;
17416    let lsb_index = total_bits - 1 - msb_index;
17417    let word = lsb_index / 64;
17418    let bit = lsb_index % 64;
17419    (aw[word] >> bit) & 1u64
17420}
17421
17422#[inline]
17423#[must_use]
17424const fn limbs_divmod_8(a: Limbs<8>, b: Limbs<8>) -> (Limbs<8>, Limbs<8>) {
17425    let mut q = Limbs::<8>::zero();
17426    let mut r = Limbs::<8>::zero();
17427    let total_bits = 8 * 64;
17428    let mut i = 0usize;
17429    while i < total_bits {
17430        r = limbs_shl1_8(r);
17431        if limbs_bit_msb_8(a, i) == 1 {
17432            r = limbs_set_bit0_8(r);
17433        }
17434        if limbs_le_8(b, r) {
17435            r = r.wrapping_sub(b);
17436            q = limbs_shl1_8(q);
17437            q = limbs_set_bit0_8(q);
17438        } else {
17439            q = limbs_shl1_8(q);
17440        }
17441        i += 1;
17442    }
17443    (q, r)
17444}
17445
17446#[inline]
17447#[must_use]
17448const fn limbs_div_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17449    let (q, _) = limbs_divmod_8(a, b);
17450    q
17451}
17452
17453#[inline]
17454#[must_use]
17455const fn limbs_mod_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17456    let (_, r) = limbs_divmod_8(a, b);
17457    r
17458}
17459
17460#[inline]
17461#[must_use]
17462const fn limbs_pow_8(base: Limbs<8>, exp: Limbs<8>) -> Limbs<8> {
17463    let mut result = limbs_one_8();
17464    let mut b = base;
17465    let ew = exp.words();
17466    let mut word = 0usize;
17467    while word < 8 {
17468        let mut bit = 0u32;
17469        while bit < 64 {
17470            if ((ew[word] >> bit) & 1u64) == 1u64 {
17471                result = result.wrapping_mul(b);
17472            }
17473            b = b.wrapping_mul(b);
17474            bit += 1;
17475        }
17476        word += 1;
17477    }
17478    result
17479}
17480
17481#[inline]
17482#[must_use]
17483const fn limbs_is_zero_9(a: Limbs<9>) -> bool {
17484    let aw = a.words();
17485    let mut i = 0usize;
17486    while i < 9 {
17487        if aw[i] != 0 {
17488            return false;
17489        }
17490        i += 1;
17491    }
17492    true
17493}
17494
17495#[inline]
17496#[must_use]
17497const fn limbs_shl1_9(a: Limbs<9>) -> Limbs<9> {
17498    let aw = a.words();
17499    let mut out = [0u64; 9];
17500    let mut carry: u64 = 0;
17501    let mut i = 0usize;
17502    while i < 9 {
17503        let v = aw[i];
17504        out[i] = (v << 1) | carry;
17505        carry = v >> 63;
17506        i += 1;
17507    }
17508    Limbs::<9>::from_words(out)
17509}
17510
17511#[inline]
17512#[must_use]
17513const fn limbs_set_bit0_9(a: Limbs<9>) -> Limbs<9> {
17514    let aw = a.words();
17515    let mut out = [0u64; 9];
17516    let mut i = 0usize;
17517    while i < 9 {
17518        out[i] = aw[i];
17519        i += 1;
17520    }
17521    out[0] |= 1u64;
17522    Limbs::<9>::from_words(out)
17523}
17524
17525#[inline]
17526#[must_use]
17527const fn limbs_bit_msb_9(a: Limbs<9>, msb_index: usize) -> u64 {
17528    let aw = a.words();
17529    let total_bits = 9 * 64;
17530    let lsb_index = total_bits - 1 - msb_index;
17531    let word = lsb_index / 64;
17532    let bit = lsb_index % 64;
17533    (aw[word] >> bit) & 1u64
17534}
17535
17536#[inline]
17537#[must_use]
17538const fn limbs_divmod_9(a: Limbs<9>, b: Limbs<9>) -> (Limbs<9>, Limbs<9>) {
17539    let mut q = Limbs::<9>::zero();
17540    let mut r = Limbs::<9>::zero();
17541    let total_bits = 9 * 64;
17542    let mut i = 0usize;
17543    while i < total_bits {
17544        r = limbs_shl1_9(r);
17545        if limbs_bit_msb_9(a, i) == 1 {
17546            r = limbs_set_bit0_9(r);
17547        }
17548        if limbs_le_9(b, r) {
17549            r = r.wrapping_sub(b);
17550            q = limbs_shl1_9(q);
17551            q = limbs_set_bit0_9(q);
17552        } else {
17553            q = limbs_shl1_9(q);
17554        }
17555        i += 1;
17556    }
17557    (q, r)
17558}
17559
17560#[inline]
17561#[must_use]
17562const fn limbs_div_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17563    let (q, _) = limbs_divmod_9(a, b);
17564    q
17565}
17566
17567#[inline]
17568#[must_use]
17569const fn limbs_mod_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17570    let (_, r) = limbs_divmod_9(a, b);
17571    r
17572}
17573
17574#[inline]
17575#[must_use]
17576const fn limbs_pow_9(base: Limbs<9>, exp: Limbs<9>) -> Limbs<9> {
17577    let mut result = limbs_one_9();
17578    let mut b = base;
17579    let ew = exp.words();
17580    let mut word = 0usize;
17581    while word < 9 {
17582        let mut bit = 0u32;
17583        while bit < 64 {
17584            if ((ew[word] >> bit) & 1u64) == 1u64 {
17585                result = result.wrapping_mul(b);
17586            }
17587            b = b.wrapping_mul(b);
17588            bit += 1;
17589        }
17590        word += 1;
17591    }
17592    result
17593}
17594
17595#[inline]
17596#[must_use]
17597const fn limbs_is_zero_16(a: Limbs<16>) -> bool {
17598    let aw = a.words();
17599    let mut i = 0usize;
17600    while i < 16 {
17601        if aw[i] != 0 {
17602            return false;
17603        }
17604        i += 1;
17605    }
17606    true
17607}
17608
17609#[inline]
17610#[must_use]
17611const fn limbs_shl1_16(a: Limbs<16>) -> Limbs<16> {
17612    let aw = a.words();
17613    let mut out = [0u64; 16];
17614    let mut carry: u64 = 0;
17615    let mut i = 0usize;
17616    while i < 16 {
17617        let v = aw[i];
17618        out[i] = (v << 1) | carry;
17619        carry = v >> 63;
17620        i += 1;
17621    }
17622    Limbs::<16>::from_words(out)
17623}
17624
17625#[inline]
17626#[must_use]
17627const fn limbs_set_bit0_16(a: Limbs<16>) -> Limbs<16> {
17628    let aw = a.words();
17629    let mut out = [0u64; 16];
17630    let mut i = 0usize;
17631    while i < 16 {
17632        out[i] = aw[i];
17633        i += 1;
17634    }
17635    out[0] |= 1u64;
17636    Limbs::<16>::from_words(out)
17637}
17638
17639#[inline]
17640#[must_use]
17641const fn limbs_bit_msb_16(a: Limbs<16>, msb_index: usize) -> u64 {
17642    let aw = a.words();
17643    let total_bits = 16 * 64;
17644    let lsb_index = total_bits - 1 - msb_index;
17645    let word = lsb_index / 64;
17646    let bit = lsb_index % 64;
17647    (aw[word] >> bit) & 1u64
17648}
17649
17650#[inline]
17651#[must_use]
17652const fn limbs_divmod_16(a: Limbs<16>, b: Limbs<16>) -> (Limbs<16>, Limbs<16>) {
17653    let mut q = Limbs::<16>::zero();
17654    let mut r = Limbs::<16>::zero();
17655    let total_bits = 16 * 64;
17656    let mut i = 0usize;
17657    while i < total_bits {
17658        r = limbs_shl1_16(r);
17659        if limbs_bit_msb_16(a, i) == 1 {
17660            r = limbs_set_bit0_16(r);
17661        }
17662        if limbs_le_16(b, r) {
17663            r = r.wrapping_sub(b);
17664            q = limbs_shl1_16(q);
17665            q = limbs_set_bit0_16(q);
17666        } else {
17667            q = limbs_shl1_16(q);
17668        }
17669        i += 1;
17670    }
17671    (q, r)
17672}
17673
17674#[inline]
17675#[must_use]
17676const fn limbs_div_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17677    let (q, _) = limbs_divmod_16(a, b);
17678    q
17679}
17680
17681#[inline]
17682#[must_use]
17683const fn limbs_mod_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17684    let (_, r) = limbs_divmod_16(a, b);
17685    r
17686}
17687
17688#[inline]
17689#[must_use]
17690const fn limbs_pow_16(base: Limbs<16>, exp: Limbs<16>) -> Limbs<16> {
17691    let mut result = limbs_one_16();
17692    let mut b = base;
17693    let ew = exp.words();
17694    let mut word = 0usize;
17695    while word < 16 {
17696        let mut bit = 0u32;
17697        while bit < 64 {
17698            if ((ew[word] >> bit) & 1u64) == 1u64 {
17699                result = result.wrapping_mul(b);
17700            }
17701            b = b.wrapping_mul(b);
17702            bit += 1;
17703        }
17704        word += 1;
17705    }
17706    result
17707}
17708
17709#[inline]
17710#[must_use]
17711const fn limbs_is_zero_32(a: Limbs<32>) -> bool {
17712    let aw = a.words();
17713    let mut i = 0usize;
17714    while i < 32 {
17715        if aw[i] != 0 {
17716            return false;
17717        }
17718        i += 1;
17719    }
17720    true
17721}
17722
17723#[inline]
17724#[must_use]
17725const fn limbs_shl1_32(a: Limbs<32>) -> Limbs<32> {
17726    let aw = a.words();
17727    let mut out = [0u64; 32];
17728    let mut carry: u64 = 0;
17729    let mut i = 0usize;
17730    while i < 32 {
17731        let v = aw[i];
17732        out[i] = (v << 1) | carry;
17733        carry = v >> 63;
17734        i += 1;
17735    }
17736    Limbs::<32>::from_words(out)
17737}
17738
17739#[inline]
17740#[must_use]
17741const fn limbs_set_bit0_32(a: Limbs<32>) -> Limbs<32> {
17742    let aw = a.words();
17743    let mut out = [0u64; 32];
17744    let mut i = 0usize;
17745    while i < 32 {
17746        out[i] = aw[i];
17747        i += 1;
17748    }
17749    out[0] |= 1u64;
17750    Limbs::<32>::from_words(out)
17751}
17752
17753#[inline]
17754#[must_use]
17755const fn limbs_bit_msb_32(a: Limbs<32>, msb_index: usize) -> u64 {
17756    let aw = a.words();
17757    let total_bits = 32 * 64;
17758    let lsb_index = total_bits - 1 - msb_index;
17759    let word = lsb_index / 64;
17760    let bit = lsb_index % 64;
17761    (aw[word] >> bit) & 1u64
17762}
17763
17764#[inline]
17765#[must_use]
17766const fn limbs_divmod_32(a: Limbs<32>, b: Limbs<32>) -> (Limbs<32>, Limbs<32>) {
17767    let mut q = Limbs::<32>::zero();
17768    let mut r = Limbs::<32>::zero();
17769    let total_bits = 32 * 64;
17770    let mut i = 0usize;
17771    while i < total_bits {
17772        r = limbs_shl1_32(r);
17773        if limbs_bit_msb_32(a, i) == 1 {
17774            r = limbs_set_bit0_32(r);
17775        }
17776        if limbs_le_32(b, r) {
17777            r = r.wrapping_sub(b);
17778            q = limbs_shl1_32(q);
17779            q = limbs_set_bit0_32(q);
17780        } else {
17781            q = limbs_shl1_32(q);
17782        }
17783        i += 1;
17784    }
17785    (q, r)
17786}
17787
17788#[inline]
17789#[must_use]
17790const fn limbs_div_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
17791    let (q, _) = limbs_divmod_32(a, b);
17792    q
17793}
17794
17795#[inline]
17796#[must_use]
17797const fn limbs_mod_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
17798    let (_, r) = limbs_divmod_32(a, b);
17799    r
17800}
17801
17802#[inline]
17803#[must_use]
17804const fn limbs_pow_32(base: Limbs<32>, exp: Limbs<32>) -> Limbs<32> {
17805    let mut result = limbs_one_32();
17806    let mut b = base;
17807    let ew = exp.words();
17808    let mut word = 0usize;
17809    while word < 32 {
17810        let mut bit = 0u32;
17811        while bit < 64 {
17812            if ((ew[word] >> bit) & 1u64) == 1u64 {
17813                result = result.wrapping_mul(b);
17814            }
17815            b = b.wrapping_mul(b);
17816            bit += 1;
17817        }
17818        word += 1;
17819    }
17820    result
17821}
17822
17823#[inline]
17824#[must_use]
17825const fn limbs_is_zero_64(a: Limbs<64>) -> bool {
17826    let aw = a.words();
17827    let mut i = 0usize;
17828    while i < 64 {
17829        if aw[i] != 0 {
17830            return false;
17831        }
17832        i += 1;
17833    }
17834    true
17835}
17836
17837#[inline]
17838#[must_use]
17839const fn limbs_shl1_64(a: Limbs<64>) -> Limbs<64> {
17840    let aw = a.words();
17841    let mut out = [0u64; 64];
17842    let mut carry: u64 = 0;
17843    let mut i = 0usize;
17844    while i < 64 {
17845        let v = aw[i];
17846        out[i] = (v << 1) | carry;
17847        carry = v >> 63;
17848        i += 1;
17849    }
17850    Limbs::<64>::from_words(out)
17851}
17852
17853#[inline]
17854#[must_use]
17855const fn limbs_set_bit0_64(a: Limbs<64>) -> Limbs<64> {
17856    let aw = a.words();
17857    let mut out = [0u64; 64];
17858    let mut i = 0usize;
17859    while i < 64 {
17860        out[i] = aw[i];
17861        i += 1;
17862    }
17863    out[0] |= 1u64;
17864    Limbs::<64>::from_words(out)
17865}
17866
17867#[inline]
17868#[must_use]
17869const fn limbs_bit_msb_64(a: Limbs<64>, msb_index: usize) -> u64 {
17870    let aw = a.words();
17871    let total_bits = 64 * 64;
17872    let lsb_index = total_bits - 1 - msb_index;
17873    let word = lsb_index / 64;
17874    let bit = lsb_index % 64;
17875    (aw[word] >> bit) & 1u64
17876}
17877
17878#[inline]
17879#[must_use]
17880const fn limbs_divmod_64(a: Limbs<64>, b: Limbs<64>) -> (Limbs<64>, Limbs<64>) {
17881    let mut q = Limbs::<64>::zero();
17882    let mut r = Limbs::<64>::zero();
17883    let total_bits = 64 * 64;
17884    let mut i = 0usize;
17885    while i < total_bits {
17886        r = limbs_shl1_64(r);
17887        if limbs_bit_msb_64(a, i) == 1 {
17888            r = limbs_set_bit0_64(r);
17889        }
17890        if limbs_le_64(b, r) {
17891            r = r.wrapping_sub(b);
17892            q = limbs_shl1_64(q);
17893            q = limbs_set_bit0_64(q);
17894        } else {
17895            q = limbs_shl1_64(q);
17896        }
17897        i += 1;
17898    }
17899    (q, r)
17900}
17901
17902#[inline]
17903#[must_use]
17904const fn limbs_div_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
17905    let (q, _) = limbs_divmod_64(a, b);
17906    q
17907}
17908
17909#[inline]
17910#[must_use]
17911const fn limbs_mod_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
17912    let (_, r) = limbs_divmod_64(a, b);
17913    r
17914}
17915
17916#[inline]
17917#[must_use]
17918const fn limbs_pow_64(base: Limbs<64>, exp: Limbs<64>) -> Limbs<64> {
17919    let mut result = limbs_one_64();
17920    let mut b = base;
17921    let ew = exp.words();
17922    let mut word = 0usize;
17923    while word < 64 {
17924        let mut bit = 0u32;
17925        while bit < 64 {
17926            if ((ew[word] >> bit) & 1u64) == 1u64 {
17927                result = result.wrapping_mul(b);
17928            }
17929            b = b.wrapping_mul(b);
17930            bit += 1;
17931        }
17932        word += 1;
17933    }
17934    result
17935}
17936
17937#[inline]
17938#[must_use]
17939const fn limbs_is_zero_128(a: Limbs<128>) -> bool {
17940    let aw = a.words();
17941    let mut i = 0usize;
17942    while i < 128 {
17943        if aw[i] != 0 {
17944            return false;
17945        }
17946        i += 1;
17947    }
17948    true
17949}
17950
17951#[inline]
17952#[must_use]
17953const fn limbs_shl1_128(a: Limbs<128>) -> Limbs<128> {
17954    let aw = a.words();
17955    let mut out = [0u64; 128];
17956    let mut carry: u64 = 0;
17957    let mut i = 0usize;
17958    while i < 128 {
17959        let v = aw[i];
17960        out[i] = (v << 1) | carry;
17961        carry = v >> 63;
17962        i += 1;
17963    }
17964    Limbs::<128>::from_words(out)
17965}
17966
17967#[inline]
17968#[must_use]
17969const fn limbs_set_bit0_128(a: Limbs<128>) -> Limbs<128> {
17970    let aw = a.words();
17971    let mut out = [0u64; 128];
17972    let mut i = 0usize;
17973    while i < 128 {
17974        out[i] = aw[i];
17975        i += 1;
17976    }
17977    out[0] |= 1u64;
17978    Limbs::<128>::from_words(out)
17979}
17980
17981#[inline]
17982#[must_use]
17983const fn limbs_bit_msb_128(a: Limbs<128>, msb_index: usize) -> u64 {
17984    let aw = a.words();
17985    let total_bits = 128 * 64;
17986    let lsb_index = total_bits - 1 - msb_index;
17987    let word = lsb_index / 64;
17988    let bit = lsb_index % 64;
17989    (aw[word] >> bit) & 1u64
17990}
17991
17992#[inline]
17993#[must_use]
17994const fn limbs_divmod_128(a: Limbs<128>, b: Limbs<128>) -> (Limbs<128>, Limbs<128>) {
17995    let mut q = Limbs::<128>::zero();
17996    let mut r = Limbs::<128>::zero();
17997    let total_bits = 128 * 64;
17998    let mut i = 0usize;
17999    while i < total_bits {
18000        r = limbs_shl1_128(r);
18001        if limbs_bit_msb_128(a, i) == 1 {
18002            r = limbs_set_bit0_128(r);
18003        }
18004        if limbs_le_128(b, r) {
18005            r = r.wrapping_sub(b);
18006            q = limbs_shl1_128(q);
18007            q = limbs_set_bit0_128(q);
18008        } else {
18009            q = limbs_shl1_128(q);
18010        }
18011        i += 1;
18012    }
18013    (q, r)
18014}
18015
18016#[inline]
18017#[must_use]
18018const fn limbs_div_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18019    let (q, _) = limbs_divmod_128(a, b);
18020    q
18021}
18022
18023#[inline]
18024#[must_use]
18025const fn limbs_mod_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18026    let (_, r) = limbs_divmod_128(a, b);
18027    r
18028}
18029
18030#[inline]
18031#[must_use]
18032const fn limbs_pow_128(base: Limbs<128>, exp: Limbs<128>) -> Limbs<128> {
18033    let mut result = limbs_one_128();
18034    let mut b = base;
18035    let ew = exp.words();
18036    let mut word = 0usize;
18037    while word < 128 {
18038        let mut bit = 0u32;
18039        while bit < 64 {
18040            if ((ew[word] >> bit) & 1u64) == 1u64 {
18041                result = result.wrapping_mul(b);
18042            }
18043            b = b.wrapping_mul(b);
18044            bit += 1;
18045        }
18046        word += 1;
18047    }
18048    result
18049}
18050
18051#[inline]
18052#[must_use]
18053const fn limbs_is_zero_192(a: Limbs<192>) -> bool {
18054    let aw = a.words();
18055    let mut i = 0usize;
18056    while i < 192 {
18057        if aw[i] != 0 {
18058            return false;
18059        }
18060        i += 1;
18061    }
18062    true
18063}
18064
18065#[inline]
18066#[must_use]
18067const fn limbs_shl1_192(a: Limbs<192>) -> Limbs<192> {
18068    let aw = a.words();
18069    let mut out = [0u64; 192];
18070    let mut carry: u64 = 0;
18071    let mut i = 0usize;
18072    while i < 192 {
18073        let v = aw[i];
18074        out[i] = (v << 1) | carry;
18075        carry = v >> 63;
18076        i += 1;
18077    }
18078    Limbs::<192>::from_words(out)
18079}
18080
18081#[inline]
18082#[must_use]
18083const fn limbs_set_bit0_192(a: Limbs<192>) -> Limbs<192> {
18084    let aw = a.words();
18085    let mut out = [0u64; 192];
18086    let mut i = 0usize;
18087    while i < 192 {
18088        out[i] = aw[i];
18089        i += 1;
18090    }
18091    out[0] |= 1u64;
18092    Limbs::<192>::from_words(out)
18093}
18094
18095#[inline]
18096#[must_use]
18097const fn limbs_bit_msb_192(a: Limbs<192>, msb_index: usize) -> u64 {
18098    let aw = a.words();
18099    let total_bits = 192 * 64;
18100    let lsb_index = total_bits - 1 - msb_index;
18101    let word = lsb_index / 64;
18102    let bit = lsb_index % 64;
18103    (aw[word] >> bit) & 1u64
18104}
18105
18106#[inline]
18107#[must_use]
18108const fn limbs_divmod_192(a: Limbs<192>, b: Limbs<192>) -> (Limbs<192>, Limbs<192>) {
18109    let mut q = Limbs::<192>::zero();
18110    let mut r = Limbs::<192>::zero();
18111    let total_bits = 192 * 64;
18112    let mut i = 0usize;
18113    while i < total_bits {
18114        r = limbs_shl1_192(r);
18115        if limbs_bit_msb_192(a, i) == 1 {
18116            r = limbs_set_bit0_192(r);
18117        }
18118        if limbs_le_192(b, r) {
18119            r = r.wrapping_sub(b);
18120            q = limbs_shl1_192(q);
18121            q = limbs_set_bit0_192(q);
18122        } else {
18123            q = limbs_shl1_192(q);
18124        }
18125        i += 1;
18126    }
18127    (q, r)
18128}
18129
18130#[inline]
18131#[must_use]
18132const fn limbs_div_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18133    let (q, _) = limbs_divmod_192(a, b);
18134    q
18135}
18136
18137#[inline]
18138#[must_use]
18139const fn limbs_mod_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18140    let (_, r) = limbs_divmod_192(a, b);
18141    r
18142}
18143
18144#[inline]
18145#[must_use]
18146const fn limbs_pow_192(base: Limbs<192>, exp: Limbs<192>) -> Limbs<192> {
18147    let mut result = limbs_one_192();
18148    let mut b = base;
18149    let ew = exp.words();
18150    let mut word = 0usize;
18151    while word < 192 {
18152        let mut bit = 0u32;
18153        while bit < 64 {
18154            if ((ew[word] >> bit) & 1u64) == 1u64 {
18155                result = result.wrapping_mul(b);
18156            }
18157            b = b.wrapping_mul(b);
18158            bit += 1;
18159        }
18160        word += 1;
18161    }
18162    result
18163}
18164
18165#[inline]
18166#[must_use]
18167const fn limbs_is_zero_256(a: Limbs<256>) -> bool {
18168    let aw = a.words();
18169    let mut i = 0usize;
18170    while i < 256 {
18171        if aw[i] != 0 {
18172            return false;
18173        }
18174        i += 1;
18175    }
18176    true
18177}
18178
18179#[inline]
18180#[must_use]
18181const fn limbs_shl1_256(a: Limbs<256>) -> Limbs<256> {
18182    let aw = a.words();
18183    let mut out = [0u64; 256];
18184    let mut carry: u64 = 0;
18185    let mut i = 0usize;
18186    while i < 256 {
18187        let v = aw[i];
18188        out[i] = (v << 1) | carry;
18189        carry = v >> 63;
18190        i += 1;
18191    }
18192    Limbs::<256>::from_words(out)
18193}
18194
18195#[inline]
18196#[must_use]
18197const fn limbs_set_bit0_256(a: Limbs<256>) -> Limbs<256> {
18198    let aw = a.words();
18199    let mut out = [0u64; 256];
18200    let mut i = 0usize;
18201    while i < 256 {
18202        out[i] = aw[i];
18203        i += 1;
18204    }
18205    out[0] |= 1u64;
18206    Limbs::<256>::from_words(out)
18207}
18208
18209#[inline]
18210#[must_use]
18211const fn limbs_bit_msb_256(a: Limbs<256>, msb_index: usize) -> u64 {
18212    let aw = a.words();
18213    let total_bits = 256 * 64;
18214    let lsb_index = total_bits - 1 - msb_index;
18215    let word = lsb_index / 64;
18216    let bit = lsb_index % 64;
18217    (aw[word] >> bit) & 1u64
18218}
18219
18220#[inline]
18221#[must_use]
18222const fn limbs_divmod_256(a: Limbs<256>, b: Limbs<256>) -> (Limbs<256>, Limbs<256>) {
18223    let mut q = Limbs::<256>::zero();
18224    let mut r = Limbs::<256>::zero();
18225    let total_bits = 256 * 64;
18226    let mut i = 0usize;
18227    while i < total_bits {
18228        r = limbs_shl1_256(r);
18229        if limbs_bit_msb_256(a, i) == 1 {
18230            r = limbs_set_bit0_256(r);
18231        }
18232        if limbs_le_256(b, r) {
18233            r = r.wrapping_sub(b);
18234            q = limbs_shl1_256(q);
18235            q = limbs_set_bit0_256(q);
18236        } else {
18237            q = limbs_shl1_256(q);
18238        }
18239        i += 1;
18240    }
18241    (q, r)
18242}
18243
18244#[inline]
18245#[must_use]
18246const fn limbs_div_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18247    let (q, _) = limbs_divmod_256(a, b);
18248    q
18249}
18250
18251#[inline]
18252#[must_use]
18253const fn limbs_mod_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18254    let (_, r) = limbs_divmod_256(a, b);
18255    r
18256}
18257
18258#[inline]
18259#[must_use]
18260const fn limbs_pow_256(base: Limbs<256>, exp: Limbs<256>) -> Limbs<256> {
18261    let mut result = limbs_one_256();
18262    let mut b = base;
18263    let ew = exp.words();
18264    let mut word = 0usize;
18265    while word < 256 {
18266        let mut bit = 0u32;
18267        while bit < 64 {
18268            if ((ew[word] >> bit) & 1u64) == 1u64 {
18269                result = result.wrapping_mul(b);
18270            }
18271            b = b.wrapping_mul(b);
18272            bit += 1;
18273        }
18274        word += 1;
18275    }
18276    result
18277}
18278
18279#[inline]
18280#[must_use]
18281const fn limbs_is_zero_512(a: Limbs<512>) -> bool {
18282    let aw = a.words();
18283    let mut i = 0usize;
18284    while i < 512 {
18285        if aw[i] != 0 {
18286            return false;
18287        }
18288        i += 1;
18289    }
18290    true
18291}
18292
18293#[inline]
18294#[must_use]
18295const fn limbs_shl1_512(a: Limbs<512>) -> Limbs<512> {
18296    let aw = a.words();
18297    let mut out = [0u64; 512];
18298    let mut carry: u64 = 0;
18299    let mut i = 0usize;
18300    while i < 512 {
18301        let v = aw[i];
18302        out[i] = (v << 1) | carry;
18303        carry = v >> 63;
18304        i += 1;
18305    }
18306    Limbs::<512>::from_words(out)
18307}
18308
18309#[inline]
18310#[must_use]
18311const fn limbs_set_bit0_512(a: Limbs<512>) -> Limbs<512> {
18312    let aw = a.words();
18313    let mut out = [0u64; 512];
18314    let mut i = 0usize;
18315    while i < 512 {
18316        out[i] = aw[i];
18317        i += 1;
18318    }
18319    out[0] |= 1u64;
18320    Limbs::<512>::from_words(out)
18321}
18322
18323#[inline]
18324#[must_use]
18325const fn limbs_bit_msb_512(a: Limbs<512>, msb_index: usize) -> u64 {
18326    let aw = a.words();
18327    let total_bits = 512 * 64;
18328    let lsb_index = total_bits - 1 - msb_index;
18329    let word = lsb_index / 64;
18330    let bit = lsb_index % 64;
18331    (aw[word] >> bit) & 1u64
18332}
18333
18334#[inline]
18335#[must_use]
18336const fn limbs_divmod_512(a: Limbs<512>, b: Limbs<512>) -> (Limbs<512>, Limbs<512>) {
18337    let mut q = Limbs::<512>::zero();
18338    let mut r = Limbs::<512>::zero();
18339    let total_bits = 512 * 64;
18340    let mut i = 0usize;
18341    while i < total_bits {
18342        r = limbs_shl1_512(r);
18343        if limbs_bit_msb_512(a, i) == 1 {
18344            r = limbs_set_bit0_512(r);
18345        }
18346        if limbs_le_512(b, r) {
18347            r = r.wrapping_sub(b);
18348            q = limbs_shl1_512(q);
18349            q = limbs_set_bit0_512(q);
18350        } else {
18351            q = limbs_shl1_512(q);
18352        }
18353        i += 1;
18354    }
18355    (q, r)
18356}
18357
18358#[inline]
18359#[must_use]
18360const fn limbs_div_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18361    let (q, _) = limbs_divmod_512(a, b);
18362    q
18363}
18364
18365#[inline]
18366#[must_use]
18367const fn limbs_mod_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18368    let (_, r) = limbs_divmod_512(a, b);
18369    r
18370}
18371
18372#[inline]
18373#[must_use]
18374const fn limbs_pow_512(base: Limbs<512>, exp: Limbs<512>) -> Limbs<512> {
18375    let mut result = limbs_one_512();
18376    let mut b = base;
18377    let ew = exp.words();
18378    let mut word = 0usize;
18379    while word < 512 {
18380        let mut bit = 0u32;
18381        while bit < 64 {
18382            if ((ew[word] >> bit) & 1u64) == 1u64 {
18383                result = result.wrapping_mul(b);
18384            }
18385            b = b.wrapping_mul(b);
18386            bit += 1;
18387        }
18388        word += 1;
18389    }
18390    result
18391}
18392
18393/// Sealed marker trait for fragment classifiers (Is2SatShape, IsHornShape,
18394/// IsResidualFragment) emitted parametrically from the predicate individuals
18395/// referenced by `predicate:InhabitanceDispatchTable`.
18396pub trait FragmentMarker: fragment_sealed::Sealed {}
18397
18398mod fragment_sealed {
18399    /// Private supertrait.
18400    pub trait Sealed {}
18401    impl Sealed for super::Is2SatShape {}
18402    impl Sealed for super::IsHornShape {}
18403    impl Sealed for super::IsResidualFragment {}
18404}
18405
18406/// Fragment marker for `predicate:Is2SatShape`. Zero-sized.
18407#[derive(Debug, Default, Clone, Copy)]
18408pub struct Is2SatShape;
18409impl FragmentMarker for Is2SatShape {}
18410
18411/// Fragment marker for `predicate:IsHornShape`. Zero-sized.
18412#[derive(Debug, Default, Clone, Copy)]
18413pub struct IsHornShape;
18414impl FragmentMarker for IsHornShape {}
18415
18416/// Fragment marker for `predicate:IsResidualFragment`. Zero-sized.
18417#[derive(Debug, Default, Clone, Copy)]
18418pub struct IsResidualFragment;
18419impl FragmentMarker for IsResidualFragment {}
18420
18421/// A single dispatch rule entry pairing a predicate IRI, a target resolver
18422/// name, and an evaluation priority.
18423#[derive(Debug, Clone, Copy)]
18424pub struct DispatchRule {
18425    /// IRI of the predicate that selects this rule.
18426    pub predicate_iri: &'static str,
18427    /// IRI of the target resolver class invoked when the predicate holds.
18428    pub target_resolver_iri: &'static str,
18429    /// Evaluation order; lower values evaluate first.
18430    pub priority: u32,
18431}
18432
18433/// A static dispatch table — an ordered slice of `DispatchRule` entries.
18434pub type DispatchTable = &'static [DispatchRule];
18435
18436/// v0.2.1 dispatch table generated from `predicate:InhabitanceDispatchTable`.
18437pub const INHABITANCE_DISPATCH_TABLE: DispatchTable = &[
18438    DispatchRule {
18439        predicate_iri: "https://uor.foundation/predicate/Is2SatShape",
18440        target_resolver_iri: "https://uor.foundation/resolver/TwoSatDecider",
18441        priority: 0,
18442    },
18443    DispatchRule {
18444        predicate_iri: "https://uor.foundation/predicate/IsHornShape",
18445        target_resolver_iri: "https://uor.foundation/resolver/HornSatDecider",
18446        priority: 1,
18447    },
18448    DispatchRule {
18449        predicate_iri: "https://uor.foundation/predicate/IsResidualFragment",
18450        target_resolver_iri: "https://uor.foundation/resolver/ResidualVerdictResolver",
18451        priority: 2,
18452    },
18453];
18454
18455/// v0.2.1 `Deref` impl for `Validated<T: OntologyTarget>` so consumers can call
18456/// certificate methods directly: `cert.target_level()` rather than
18457/// `cert.inner().target_level()`. The bound `T: OntologyTarget` keeps the
18458/// auto-deref scoped to foundation-produced types.
18459impl<T: OntologyTarget> core::ops::Deref for Validated<T> {
18460    type Target = T;
18461    #[inline]
18462    fn deref(&self) -> &T {
18463        &self.inner
18464    }
18465}
18466
18467mod bound_constraint_sealed {
18468    /// Sealed supertrait for the closed Observable catalogue.
18469    pub trait ObservableSealed {}
18470    /// Sealed supertrait for the closed BoundShape catalogue.
18471    pub trait BoundShapeSealed {}
18472}
18473
18474/// Sealed marker trait identifying the closed catalogue of observables
18475/// admissible in BoundConstraint. Implemented by unit structs emitted
18476/// below per `observable:Observable` subclass referenced by a
18477/// BoundConstraint kind individual.
18478pub trait Observable: bound_constraint_sealed::ObservableSealed {
18479    /// Ontology IRI of this observable class.
18480    const IRI: &'static str;
18481}
18482
18483/// Sealed marker trait identifying the closed catalogue of bound shapes.
18484/// Exactly six individuals: EqualBound, LessEqBound, GreaterEqBound,
18485/// RangeContainBound, ResidueClassBound, AffineEqualBound.
18486pub trait BoundShape: bound_constraint_sealed::BoundShapeSealed {
18487    /// Ontology IRI of this bound shape individual.
18488    const IRI: &'static str;
18489}
18490
18491/// Observes a Datum's value modulo a configurable modulus.
18492#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18493pub struct ValueModObservable;
18494impl bound_constraint_sealed::ObservableSealed for ValueModObservable {}
18495impl Observable for ValueModObservable {
18496    const IRI: &'static str = "https://uor.foundation/observable/ValueModObservable";
18497}
18498
18499/// Distance between two ring elements under the Hamming metric.
18500#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18501pub struct HammingMetric;
18502impl bound_constraint_sealed::ObservableSealed for HammingMetric {}
18503impl Observable for HammingMetric {
18504    const IRI: &'static str = "https://uor.foundation/observable/HammingMetric";
18505}
18506
18507/// Observes the derivation depth of a Datum.
18508#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18509pub struct DerivationDepthObservable;
18510impl bound_constraint_sealed::ObservableSealed for DerivationDepthObservable {}
18511impl Observable for DerivationDepthObservable {
18512    const IRI: &'static str = "https://uor.foundation/derivation/DerivationDepthObservable";
18513}
18514
18515/// Observes the carry depth of a Datum in the W₂ tower.
18516#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18517pub struct CarryDepthObservable;
18518impl bound_constraint_sealed::ObservableSealed for CarryDepthObservable {}
18519impl Observable for CarryDepthObservable {
18520    const IRI: &'static str = "https://uor.foundation/carry/CarryDepthObservable";
18521}
18522
18523/// Observes the free-rank of the partition associated with a Datum.
18524#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18525pub struct FreeRankObservable;
18526impl bound_constraint_sealed::ObservableSealed for FreeRankObservable {}
18527impl Observable for FreeRankObservable {
18528    const IRI: &'static str = "https://uor.foundation/partition/FreeRankObservable";
18529}
18530
18531/// Predicate form: `observable(datum) == target`.
18532#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18533pub struct EqualBound;
18534impl bound_constraint_sealed::BoundShapeSealed for EqualBound {}
18535impl BoundShape for EqualBound {
18536    const IRI: &'static str = "https://uor.foundation/type/EqualBound";
18537}
18538
18539/// Predicate form: `observable(datum) <= bound`.
18540#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18541pub struct LessEqBound;
18542impl bound_constraint_sealed::BoundShapeSealed for LessEqBound {}
18543impl BoundShape for LessEqBound {
18544    const IRI: &'static str = "https://uor.foundation/type/LessEqBound";
18545}
18546
18547/// Predicate form: `observable(datum) >= bound`.
18548#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18549pub struct GreaterEqBound;
18550impl bound_constraint_sealed::BoundShapeSealed for GreaterEqBound {}
18551impl BoundShape for GreaterEqBound {
18552    const IRI: &'static str = "https://uor.foundation/type/GreaterEqBound";
18553}
18554
18555/// Predicate form: `lo <= observable(datum) <= hi`.
18556#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18557pub struct RangeContainBound;
18558impl bound_constraint_sealed::BoundShapeSealed for RangeContainBound {}
18559impl BoundShape for RangeContainBound {
18560    const IRI: &'static str = "https://uor.foundation/type/RangeContainBound";
18561}
18562
18563/// Predicate form: `observable(datum) ≡ residue (mod modulus)`.
18564#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18565pub struct ResidueClassBound;
18566impl bound_constraint_sealed::BoundShapeSealed for ResidueClassBound {}
18567impl BoundShape for ResidueClassBound {
18568    const IRI: &'static str = "https://uor.foundation/type/ResidueClassBound";
18569}
18570
18571/// Predicate form: `observable(datum) == offset + affine combination`.
18572#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18573pub struct AffineEqualBound;
18574impl bound_constraint_sealed::BoundShapeSealed for AffineEqualBound {}
18575impl BoundShape for AffineEqualBound {
18576    const IRI: &'static str = "https://uor.foundation/type/AffineEqualBound";
18577}
18578
18579/// Parameter value type for `BoundConstraint` arguments.
18580/// Sealed enum over the closed set of primitive kinds the bound-shape
18581/// catalogue requires. No heap, no `String`.
18582#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18583pub enum BoundArgValue {
18584    /// Unsigned 64-bit integer.
18585    U64(u64),
18586    /// Signed 64-bit integer.
18587    I64(i64),
18588    /// Fixed 32-byte content-addressed value.
18589    Bytes32([u8; 32]),
18590}
18591
18592/// Fixed-size arguments carrier for a `BoundConstraint`.
18593/// Holds up to eight `(name, value)` pairs inline. The closed
18594/// bound-shape catalogue requires at most three parameters per kind;
18595/// the extra slots are reserved for future kind additions without
18596/// changing the carrier layout.
18597#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18598pub struct BoundArguments {
18599    entries: [Option<BoundArgEntry>; 8],
18600}
18601
18602/// A single named parameter in a `BoundArguments` table.
18603#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18604pub struct BoundArgEntry {
18605    /// Parameter name (a `&'static str` intentional over heap-owned).
18606    pub name: &'static str,
18607    /// Parameter value.
18608    pub value: BoundArgValue,
18609}
18610
18611impl BoundArguments {
18612    /// Construct an empty argument table.
18613    #[inline]
18614    #[must_use]
18615    pub const fn empty() -> Self {
18616        Self { entries: [None; 8] }
18617    }
18618
18619    /// Construct a table with a single `(name, value)` pair.
18620    #[inline]
18621    #[must_use]
18622    pub const fn single(name: &'static str, value: BoundArgValue) -> Self {
18623        let mut entries = [None; 8];
18624        entries[0] = Some(BoundArgEntry { name, value });
18625        Self { entries }
18626    }
18627
18628    /// Construct a table with two `(name, value)` pairs.
18629    #[inline]
18630    #[must_use]
18631    pub const fn pair(
18632        first: (&'static str, BoundArgValue),
18633        second: (&'static str, BoundArgValue),
18634    ) -> Self {
18635        let mut entries = [None; 8];
18636        entries[0] = Some(BoundArgEntry {
18637            name: first.0,
18638            value: first.1,
18639        });
18640        entries[1] = Some(BoundArgEntry {
18641            name: second.0,
18642            value: second.1,
18643        });
18644        Self { entries }
18645    }
18646
18647    /// Access the stored entries.
18648    #[inline]
18649    #[must_use]
18650    pub const fn entries(&self) -> &[Option<BoundArgEntry>; 8] {
18651        &self.entries
18652    }
18653}
18654
18655/// Parametric constraint carrier (v0.2.2 Phase D).
18656/// Generic over `O: Observable` and `B: BoundShape`. The seven
18657/// legacy constraint kinds are preserved as type aliases over this
18658/// carrier; see `ResidueConstraint`, `HammingConstraint`, etc. below.
18659#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18660pub struct BoundConstraint<O: Observable, B: BoundShape> {
18661    observable: O,
18662    bound: B,
18663    args: BoundArguments,
18664    _sealed: (),
18665}
18666
18667impl<O: Observable, B: BoundShape> BoundConstraint<O, B> {
18668    /// Crate-internal constructor. Downstream obtains values through
18669    /// the per-type-alias `pub const fn new` constructors.
18670    #[inline]
18671    #[must_use]
18672    pub(crate) const fn from_parts(observable: O, bound: B, args: BoundArguments) -> Self {
18673        Self {
18674            observable,
18675            bound,
18676            args,
18677            _sealed: (),
18678        }
18679    }
18680
18681    /// Access the bound observable.
18682    #[inline]
18683    #[must_use]
18684    pub const fn observable(&self) -> &O {
18685        &self.observable
18686    }
18687
18688    /// Access the bound shape.
18689    #[inline]
18690    #[must_use]
18691    pub const fn bound(&self) -> &B {
18692        &self.bound
18693    }
18694
18695    /// Access the bound arguments.
18696    #[inline]
18697    #[must_use]
18698    pub const fn args(&self) -> &BoundArguments {
18699        &self.args
18700    }
18701}
18702
18703/// Parametric conjunction of `BoundConstraint` kinds (v0.2.2 Phase D).
18704/// Replaces the v0.2.1 `CompositeConstraint` enumeration; the legacy
18705/// name survives as the type alias `CompositeConstraint<N>` below.
18706#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18707pub struct Conjunction<const N: usize> {
18708    len: usize,
18709    _sealed: (),
18710}
18711
18712impl<const N: usize> Conjunction<N> {
18713    /// Construct a new Conjunction with `len` conjuncts.
18714    #[inline]
18715    #[must_use]
18716    pub const fn new(len: usize) -> Self {
18717        Self { len, _sealed: () }
18718    }
18719
18720    /// The number of conjuncts in this Conjunction.
18721    #[inline]
18722    #[must_use]
18723    pub const fn len(&self) -> usize {
18724        self.len
18725    }
18726
18727    /// Whether the Conjunction is empty.
18728    #[inline]
18729    #[must_use]
18730    pub const fn is_empty(&self) -> bool {
18731        self.len == 0
18732    }
18733}
18734
18735/// v0.2.1 legacy type alias: a `BoundConstraint` kind asserting
18736/// residue-class membership (`value mod m == r`).
18737pub type ResidueConstraint = BoundConstraint<ValueModObservable, ResidueClassBound>;
18738
18739impl ResidueConstraint {
18740    /// Construct a residue constraint with the given modulus and residue.
18741    #[inline]
18742    #[must_use]
18743    pub const fn new(modulus: u64, residue: u64) -> Self {
18744        let args = BoundArguments::pair(
18745            ("modulus", BoundArgValue::U64(modulus)),
18746            ("residue", BoundArgValue::U64(residue)),
18747        );
18748        BoundConstraint::from_parts(ValueModObservable, ResidueClassBound, args)
18749    }
18750}
18751
18752/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18753/// Hamming weight of the Datum (`weight <= bound`).
18754pub type HammingConstraint = BoundConstraint<HammingMetric, LessEqBound>;
18755
18756impl HammingConstraint {
18757    /// Construct a Hamming constraint with the given upper bound.
18758    #[inline]
18759    #[must_use]
18760    pub const fn new(bound: u64) -> Self {
18761        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
18762        BoundConstraint::from_parts(HammingMetric, LessEqBound, args)
18763    }
18764}
18765
18766/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18767/// derivation depth of the Datum.
18768pub type DepthConstraint = BoundConstraint<DerivationDepthObservable, LessEqBound>;
18769
18770impl DepthConstraint {
18771    /// Construct a depth constraint with min and max depths.
18772    #[inline]
18773    #[must_use]
18774    pub const fn new(min_depth: u64, max_depth: u64) -> Self {
18775        let args = BoundArguments::pair(
18776            ("min_depth", BoundArgValue::U64(min_depth)),
18777            ("max_depth", BoundArgValue::U64(max_depth)),
18778        );
18779        BoundConstraint::from_parts(DerivationDepthObservable, LessEqBound, args)
18780    }
18781}
18782
18783/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18784/// carry depth of the Datum in the W₂ tower.
18785pub type CarryConstraint = BoundConstraint<CarryDepthObservable, LessEqBound>;
18786
18787impl CarryConstraint {
18788    /// Construct a carry constraint with the given upper bound.
18789    #[inline]
18790    #[must_use]
18791    pub const fn new(bound: u64) -> Self {
18792        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
18793        BoundConstraint::from_parts(CarryDepthObservable, LessEqBound, args)
18794    }
18795}
18796
18797/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning a
18798/// single site coordinate.
18799pub type SiteConstraint = BoundConstraint<FreeRankObservable, LessEqBound>;
18800
18801impl SiteConstraint {
18802    /// Construct a site constraint with the given site index.
18803    #[inline]
18804    #[must_use]
18805    pub const fn new(site_index: u64) -> Self {
18806        let args = BoundArguments::single("site_index", BoundArgValue::U64(site_index));
18807        BoundConstraint::from_parts(FreeRankObservable, LessEqBound, args)
18808    }
18809}
18810
18811/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning an
18812/// affine relationship on the Datum's value projection.
18813pub type AffineConstraint = BoundConstraint<ValueModObservable, AffineEqualBound>;
18814
18815impl AffineConstraint {
18816    /// Construct an affine constraint with the given offset.
18817    #[inline]
18818    #[must_use]
18819    pub const fn new(offset: u64) -> Self {
18820        let args = BoundArguments::single("offset", BoundArgValue::U64(offset));
18821        BoundConstraint::from_parts(ValueModObservable, AffineEqualBound, args)
18822    }
18823}
18824
18825/// v0.2.1 legacy type alias: a `Conjunction` over `N` BoundConstraint
18826/// kinds (`CompositeConstraint<3>` = 3-way conjunction).
18827pub type CompositeConstraint<const N: usize> = Conjunction<N>;
18828
18829/// v0.2.2 Phase E: sealed query handle.
18830#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18831pub struct Query {
18832    address: ContentAddress,
18833    _sealed: (),
18834}
18835
18836impl Query {
18837    /// Returns the content-hashed query address.
18838    #[inline]
18839    #[must_use]
18840    pub const fn address(&self) -> ContentAddress {
18841        self.address
18842    }
18843
18844    /// Crate-internal constructor.
18845    #[inline]
18846    #[must_use]
18847    #[allow(dead_code)]
18848    pub(crate) const fn new(address: ContentAddress) -> Self {
18849        Self {
18850            address,
18851            _sealed: (),
18852        }
18853    }
18854}
18855
18856/// v0.2.2 Phase E: typed query coordinate parametric over WittLevel.
18857#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18858pub struct Coordinate<L> {
18859    stratum: u64,
18860    spectrum: u64,
18861    address: u64,
18862    _level: PhantomData<L>,
18863    _sealed: (),
18864}
18865
18866impl<L> Coordinate<L> {
18867    /// Returns the stratum coordinate.
18868    #[inline]
18869    #[must_use]
18870    pub const fn stratum(&self) -> u64 {
18871        self.stratum
18872    }
18873
18874    /// Returns the spectrum coordinate.
18875    #[inline]
18876    #[must_use]
18877    pub const fn spectrum(&self) -> u64 {
18878        self.spectrum
18879    }
18880
18881    /// Returns the address coordinate.
18882    #[inline]
18883    #[must_use]
18884    pub const fn address(&self) -> u64 {
18885        self.address
18886    }
18887
18888    /// Crate-internal constructor.
18889    #[inline]
18890    #[must_use]
18891    #[allow(dead_code)]
18892    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
18893        Self {
18894            stratum,
18895            spectrum,
18896            address,
18897            _level: PhantomData,
18898            _sealed: (),
18899        }
18900    }
18901}
18902
18903/// v0.2.2 Phase E: sealed binding query handle.
18904#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18905pub struct BindingQuery {
18906    address: ContentAddress,
18907    _sealed: (),
18908}
18909
18910impl BindingQuery {
18911    /// Returns the content-hashed binding query address.
18912    #[inline]
18913    #[must_use]
18914    pub const fn address(&self) -> ContentAddress {
18915        self.address
18916    }
18917
18918    /// Crate-internal constructor.
18919    #[inline]
18920    #[must_use]
18921    #[allow(dead_code)]
18922    pub(crate) const fn new(address: ContentAddress) -> Self {
18923        Self {
18924            address,
18925            _sealed: (),
18926        }
18927    }
18928}
18929
18930/// v0.2.2 Phase E: sealed Partition handle over the bridge:partition
18931/// component classification produced during grounding.
18932#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18933pub struct Partition {
18934    component: PartitionComponent,
18935    _sealed: (),
18936}
18937
18938impl Partition {
18939    /// Returns the component classification.
18940    #[inline]
18941    #[must_use]
18942    pub const fn component(&self) -> PartitionComponent {
18943        self.component
18944    }
18945
18946    /// Crate-internal constructor.
18947    #[inline]
18948    #[must_use]
18949    #[allow(dead_code)]
18950    pub(crate) const fn new(component: PartitionComponent) -> Self {
18951        Self {
18952            component,
18953            _sealed: (),
18954        }
18955    }
18956}
18957
18958/// v0.2.2 Phase E: a single event in a derivation Trace.
18959/// Fixed-size event; content-addressed so Trace replays are stable
18960/// across builds. The verifier in `uor-foundation-verify` (Phase H)
18961/// reconstructs the witness chain by walking a `Trace` iterator.
18962#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18963pub struct TraceEvent {
18964    /// Step index in the derivation.
18965    step_index: u32,
18966    /// Primitive op applied at this step.
18967    op: PrimitiveOp,
18968    /// Content-hashed target address the op produced.
18969    target: ContentAddress,
18970    /// Sealing marker.
18971    _sealed: (),
18972}
18973
18974impl TraceEvent {
18975    /// Returns the step index.
18976    #[inline]
18977    #[must_use]
18978    pub const fn step_index(&self) -> u32 {
18979        self.step_index
18980    }
18981
18982    /// Returns the primitive op applied at this step.
18983    #[inline]
18984    #[must_use]
18985    pub const fn op(&self) -> PrimitiveOp {
18986        self.op
18987    }
18988
18989    /// Returns the content-hashed target address.
18990    #[inline]
18991    #[must_use]
18992    pub const fn target(&self) -> ContentAddress {
18993        self.target
18994    }
18995
18996    /// Crate-internal constructor.
18997    #[inline]
18998    #[must_use]
18999    #[allow(dead_code)]
19000    pub(crate) const fn new(step_index: u32, op: PrimitiveOp, target: ContentAddress) -> Self {
19001        Self {
19002            step_index,
19003            op,
19004            target,
19005            _sealed: (),
19006        }
19007    }
19008}
19009
19010/// Fixed-capacity derivation trace. Holds up to `TR_MAX` events inline;
19011/// no heap. Produced by `Derivation::replay()` and consumed by
19012/// `uor-foundation-verify`. `TR_MAX` is the const-generic that carries
19013/// the application's selected `<MyBounds as HostBounds>::TRACE_MAX_EVENTS`;
19014/// the default const-generic resolves to `DefaultHostBounds`'s 256.
19015/// Carries `witt_level_bits` and `content_fingerprint` so `verify_trace`
19016/// can reconstruct the source `GroundingCertificate` via structural-
19017/// validation + fingerprint passthrough (no hash recomputation).
19018#[derive(Debug, Clone, Copy)]
19019pub struct Trace<const TR_MAX: usize = 256> {
19020    events: [Option<TraceEvent>; TR_MAX],
19021    len: u16,
19022    /// Witt level the source grounding was minted at, packed
19023    /// by `Derivation::replay` from the parent `Grounded::witt_level_bits`.
19024    /// `verify_trace` reads this back to populate the certificate.
19025    witt_level_bits: u16,
19026    /// Parametric content fingerprint of the source unit's full state,
19027    /// computed at grounding time by the consumer-supplied `Hasher` and
19028    /// packed in by `Derivation::replay`. `verify_trace` passes it through
19029    /// unchanged. The fingerprint's `FP_MAX` follows the application's
19030    /// selected `<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES`; this
19031    /// field uses the default-bound `ContentFingerprint`.
19032    content_fingerprint: ContentFingerprint,
19033    _sealed: (),
19034}
19035
19036impl<const TR_MAX: usize> Trace<TR_MAX> {
19037    /// An empty Trace.
19038    #[inline]
19039    #[must_use]
19040    pub const fn empty() -> Self {
19041        Self {
19042            events: [None; TR_MAX],
19043            len: 0,
19044            witt_level_bits: 0,
19045            content_fingerprint: ContentFingerprint::zero(),
19046            _sealed: (),
19047        }
19048    }
19049
19050    /// Crate-internal ctor for `Derivation::replay()` only.
19051    /// Bypasses validation because `replay()` constructs events from
19052    /// foundation-guaranteed-valid state (monotonic, contiguous, non-zero
19053    /// seed). No public path reaches this constructor; downstream uses the
19054    /// validating `try_from_events` instead.
19055    #[inline]
19056    #[must_use]
19057    #[allow(dead_code)]
19058    pub(crate) const fn from_replay_events_const(
19059        events: [Option<TraceEvent>; TR_MAX],
19060        len: u16,
19061        witt_level_bits: u16,
19062        content_fingerprint: ContentFingerprint,
19063    ) -> Self {
19064        Self {
19065            events,
19066            len,
19067            witt_level_bits,
19068            content_fingerprint,
19069            _sealed: (),
19070        }
19071    }
19072
19073    /// Number of events recorded.
19074    #[inline]
19075    #[must_use]
19076    pub const fn len(&self) -> u16 {
19077        self.len
19078    }
19079
19080    /// Whether the Trace is empty.
19081    #[inline]
19082    #[must_use]
19083    pub const fn is_empty(&self) -> bool {
19084        self.len == 0
19085    }
19086
19087    /// Access the event at the given index, or `None` if out of range.
19088    #[inline]
19089    #[must_use]
19090    pub fn event(&self, index: usize) -> Option<&TraceEvent> {
19091        self.events.get(index).and_then(|e| e.as_ref())
19092    }
19093
19094    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
19095    /// Carried through replay so `verify_trace` can populate the certificate.
19096    #[inline]
19097    #[must_use]
19098    pub const fn witt_level_bits(&self) -> u16 {
19099        self.witt_level_bits
19100    }
19101
19102    /// v0.2.2 T5: returns the parametric content fingerprint of the source
19103    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
19104    /// `verify_trace` passes this through unchanged into the re-derived
19105    /// certificate, upholding the round-trip property.
19106    #[inline]
19107    #[must_use]
19108    pub const fn content_fingerprint(&self) -> ContentFingerprint {
19109        self.content_fingerprint
19110    }
19111
19112    /// Validating constructor. Checks every invariant the verify path
19113    /// relies on: events are contiguous from index 0, no event has a zero
19114    /// target, and the slice fits within `TR_MAX` events.
19115    /// # Errors
19116    /// - `ReplayError::EmptyTrace` if `events.is_empty()`.
19117    /// - `ReplayError::CapacityExceeded { declared, provided }` if the
19118    ///   slice exceeds `TR_MAX`.
19119    /// - `ReplayError::OutOfOrderEvent { index }` if the event at `index`
19120    ///   has a `step_index` not equal to `index` (strict contiguity).
19121    /// - `ReplayError::ZeroTarget { index }` if any event carries a zero
19122    ///   `ContentAddress` target.
19123    pub fn try_from_events(
19124        events: &[TraceEvent],
19125        witt_level_bits: u16,
19126        content_fingerprint: ContentFingerprint,
19127    ) -> Result<Self, ReplayError> {
19128        if events.is_empty() {
19129            return Err(ReplayError::EmptyTrace);
19130        }
19131        if events.len() > TR_MAX {
19132            return Err(ReplayError::CapacityExceeded {
19133                declared: TR_MAX as u16,
19134                provided: events.len() as u32,
19135            });
19136        }
19137        let mut i = 0usize;
19138        while i < events.len() {
19139            let e = &events[i];
19140            if e.step_index() as usize != i {
19141                return Err(ReplayError::OutOfOrderEvent { index: i });
19142            }
19143            if e.target().is_zero() {
19144                return Err(ReplayError::ZeroTarget { index: i });
19145            }
19146            i += 1;
19147        }
19148        let mut arr = [None; TR_MAX];
19149        let mut j = 0usize;
19150        while j < events.len() {
19151            arr[j] = Some(events[j]);
19152            j += 1;
19153        }
19154        Ok(Self {
19155            events: arr,
19156            len: events.len() as u16,
19157            witt_level_bits,
19158            content_fingerprint,
19159            _sealed: (),
19160        })
19161    }
19162}
19163
19164impl<const TR_MAX: usize> Default for Trace<TR_MAX> {
19165    #[inline]
19166    fn default() -> Self {
19167        Self::empty()
19168    }
19169}
19170
19171/// v0.2.2 Phase E / T2.6: `Derivation::replay()` produces a content-addressed
19172/// Trace the verifier can re-walk without invoking the deciders. The trace
19173/// length matches the derivation's `step_count()`, and each event's
19174/// `step_index` reflects its position in the derivation.
19175impl Derivation {
19176    /// Replay this derivation as a fixed-size `Trace<TR_MAX>` whose length matches
19177    /// `self.step_count()` (capped at the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19178    /// Callers either annotate the binding (`let trace: Trace = ...;` picks
19179    /// `DefaultHostBounds`'s 256) or use turbofish (`derivation.replay::<1024>()`).
19180    /// # Example
19181    /// ```no_run
19182    /// use uor_foundation::enforcement::{
19183    ///     replay, CompileUnitBuilder, ConstrainedTypeInput, Grounded, Term, Trace,
19184    /// };
19185    /// use uor_foundation::pipeline::run;
19186    /// use uor_foundation::{VerificationDomain, WittLevel};
19187    /// # use uor_foundation::enforcement::Hasher;
19188    /// # struct H; impl Hasher for H {
19189    /// #     const OUTPUT_BYTES: usize = 16;
19190    /// #     fn initial() -> Self { Self }
19191    /// #     fn fold_byte(self, _: u8) -> Self { self }
19192    /// #     fn finalize(self) -> [u8; 32] { [0; 32] } }
19193    /// static TERMS: &[Term] = &[uor_foundation::pipeline::literal_u64(7, WittLevel::W8)];
19194    /// static DOMS: &[VerificationDomain] = &[VerificationDomain::Enumerative];
19195    /// let unit = CompileUnitBuilder::new()
19196    ///     .root_term(TERMS).witt_level_ceiling(WittLevel::W32)
19197    ///     .thermodynamic_budget(1024).target_domains(DOMS)
19198    ///     .result_type::<ConstrainedTypeInput>()
19199    ///     .validate().expect("unit well-formed");
19200    /// let grounded: Grounded<ConstrainedTypeInput> =
19201    ///     run::<ConstrainedTypeInput, _, H>(unit).expect("grounds");
19202    /// // Replay → round-trip verification. The trace's event-count
19203    /// // capacity comes from the application's `HostBounds`; here the
19204    /// // type-annotated binding inherits `DefaultHostBounds`'s 256.
19205    /// let trace: Trace = grounded.derivation().replay();
19206    /// let recert = replay::certify_from_trace(&trace).expect("valid trace");
19207    /// assert_eq!(recert.certificate().content_fingerprint(),
19208    ///            grounded.content_fingerprint());
19209    /// ```
19210    #[inline]
19211    #[must_use]
19212    pub fn replay<const TR_MAX: usize>(&self) -> Trace<TR_MAX> {
19213        let steps = self.step_count() as usize;
19214        let len = if steps > TR_MAX { TR_MAX } else { steps };
19215        let mut events = [None; TR_MAX];
19216        // Seed targets from the leading 8 bytes of the source
19217        // `content_fingerprint` (substrate-computed). Combined with `| 1` so
19218        // the first event's target is guaranteed nonzero even when the
19219        // leading bytes are all zero, and XOR with `(i + 1)` keeps the
19220        // sequence non-degenerate.
19221        let fp = self.content_fingerprint.as_bytes();
19222        let seed =
19223            u64::from_be_bytes([fp[0], fp[1], fp[2], fp[3], fp[4], fp[5], fp[6], fp[7]]) as u128;
19224        let nonzero_seed = seed | 1u128;
19225        let mut i = 0usize;
19226        while i < len {
19227            let target_raw = nonzero_seed ^ ((i as u128) + 1u128);
19228            events[i] = Some(TraceEvent::new(
19229                i as u32,
19230                crate::PrimitiveOp::Add,
19231                ContentAddress::from_u128(target_raw),
19232            ));
19233            i += 1;
19234        }
19235        // Pack the source `witt_level_bits` and `content_fingerprint`
19236        // into the Trace so `verify_trace` can reproduce the source certificate
19237        // via passthrough. The fingerprint was computed at grounding time by the
19238        // consumer-supplied Hasher and stored on the parent Grounded; the
19239        // Derivation accessor read it through.
19240        Trace::from_replay_events_const(
19241            events,
19242            len as u16,
19243            self.witt_level_bits,
19244            self.content_fingerprint,
19245        )
19246    }
19247}
19248
19249/// v0.2.2 T5: errors emitted by the trace-replay re-derivation path.
19250#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19251#[non_exhaustive]
19252pub enum ReplayError {
19253    /// The trace was empty; nothing to replay.
19254    EmptyTrace,
19255    /// Event at `index` has a non-monotonic step_index.
19256    OutOfOrderEvent {
19257        /// The event index that was out of order.
19258        index: usize,
19259    },
19260    /// Event at `index` carries a zero ContentAddress (forbidden in well-formed traces).
19261    ZeroTarget {
19262        /// The event index that carried a zero target.
19263        index: usize,
19264    },
19265    /// v0.2.2 T5.8: event step indices do not form a contiguous sequence
19266    /// `[0, 1, ..., len-1]`. Replaces the misleadingly-named v0.2.1
19267    /// `LengthMismatch` variant. The trace has the right number of
19268    /// events, but their step indices skip values (e.g., `[0, 2, 5]`
19269    /// with `len = 3`).
19270    NonContiguousSteps {
19271        /// The trace's declared length (number of events).
19272        declared: u16,
19273        /// The largest step_index observed in the event sequence.
19274        /// Always strictly greater than `declared - 1` when this
19275        /// variant fires.
19276        last_step: u32,
19277    },
19278    /// A caller attempted to construct a `Trace<TR_MAX>` whose event count
19279    /// exceeds `TR_MAX` (the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19280    /// Distinct from `NonContiguousSteps` because the recovery is different
19281    /// (truncate vs. close gaps). Returned by `Trace::try_from_events`,
19282    /// never by `verify_trace` (the verifier reads from an existing `Trace`
19283    /// whose capacity is already enforced by the type's storage).
19284    CapacityExceeded {
19285        /// The trace's hard capacity (`TR_MAX`).
19286        declared: u16,
19287        /// The actual event count the caller attempted to pack in.
19288        provided: u32,
19289    },
19290}
19291
19292impl core::fmt::Display for ReplayError {
19293    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19294        match self {
19295            Self::EmptyTrace => f.write_str("trace was empty; nothing to replay"),
19296            Self::OutOfOrderEvent { index } => write!(
19297                f,
19298                "event at index {index} has out-of-order step index",
19299            ),
19300            Self::ZeroTarget { index } => write!(
19301                f,
19302                "event at index {index} has a zero ContentAddress target",
19303            ),
19304            Self::NonContiguousSteps { declared, last_step } => write!(
19305                f,
19306                "trace declares {declared} events but step indices skip values \
19307                 (last step {last_step})",
19308            ),
19309            Self::CapacityExceeded { declared, provided } => write!(
19310                f,
19311                "trace capacity exceeded: tried to pack {provided} events into a buffer of {declared}",
19312            ),
19313        }
19314    }
19315}
19316
19317impl core::error::Error for ReplayError {}
19318
19319/// v0.2.2 T5: trace-replay re-derivation module.
19320/// The foundation owns the certificate-construction boundary; the
19321/// `uor-foundation-verify` crate is a thin facade that delegates to
19322/// `replay::certify_from_trace`. This preserves sealing discipline:
19323/// `Certified::new` stays `pub(crate)` and no external crate can mint a
19324/// certificate.
19325pub mod replay {
19326    use super::{Certified, GroundingCertificate, ReplayError, Trace};
19327
19328    /// Re-derive the `Certified<GroundingCertificate>` that the foundation
19329    /// grounding path produced for the source unit.
19330    /// Validates the trace's structural invariants (monotonic, contiguous
19331    /// step indices; no zero targets; no None slots in the populated
19332    /// prefix) and re-packages the trace's stored `ContentFingerprint` and
19333    /// `witt_level_bits` into a fresh certificate. The verifier does NOT
19334    /// invoke a hash function: the fingerprint is *data carried by the
19335    /// Trace*, computed at mint time by the consumer-supplied `Hasher` and
19336    /// passed through unchanged.
19337    /// # Round-trip property
19338    /// For every `Grounded<T>` produced by `pipeline::run::<T, _, H>` with
19339    /// a conforming substrate `H: Hasher`:
19340    /// ```text
19341    /// verify_trace(&grounded.derivation().replay()).certificate()
19342    ///     == grounded.certificate()
19343    /// ```
19344    /// holds bit-identically. The contract is orthogonal to the substrate
19345    /// hasher choice and to the chosen `OUTPUT_BYTES` width.
19346    /// # Errors
19347    /// Returns:
19348    /// - `ReplayError::EmptyTrace` if `trace.is_empty()`.
19349    /// - `ReplayError::OutOfOrderEvent { index }` if step indices are not
19350    ///   strictly monotonic at position `index`.
19351    /// - `ReplayError::ZeroTarget { index }` if any event carries
19352    ///   `ContentAddress::zero()`.
19353    /// - `ReplayError::NonContiguousSteps { declared, last_step }` if
19354    ///   the event step indices skip values.
19355    pub fn certify_from_trace<const TR_MAX: usize>(
19356        trace: &Trace<TR_MAX>,
19357    ) -> Result<Certified<GroundingCertificate>, ReplayError> {
19358        let len = trace.len() as usize;
19359        if len == 0 {
19360            return Err(ReplayError::EmptyTrace);
19361        }
19362        // Structural validation: monotonic step indices, contiguous from 0,
19363        // no zero targets, no None slots in the populated prefix.
19364        let mut last_step: i64 = -1;
19365        let mut max_step_index: u32 = 0;
19366        let mut i = 0usize;
19367        while i < len {
19368            let event = match trace.event(i) {
19369                Some(e) => e,
19370                None => return Err(ReplayError::OutOfOrderEvent { index: i }),
19371            };
19372            let step_index = event.step_index();
19373            if (step_index as i64) <= last_step {
19374                return Err(ReplayError::OutOfOrderEvent { index: i });
19375            }
19376            if event.target().is_zero() {
19377                return Err(ReplayError::ZeroTarget { index: i });
19378            }
19379            if step_index > max_step_index {
19380                max_step_index = step_index;
19381            }
19382            last_step = step_index as i64;
19383            i += 1;
19384        }
19385        if (max_step_index as u16).saturating_add(1) != trace.len() {
19386            return Err(ReplayError::NonContiguousSteps {
19387                declared: trace.len(),
19388                last_step: max_step_index,
19389            });
19390        }
19391        // v0.2.2 T5: fingerprint passthrough. The trace was minted by the
19392        // foundation pipeline with a `ContentFingerprint` already computed by
19393        // the consumer-supplied `Hasher`. The verifier does not invoke any
19394        // hash function; it copies the fingerprint through unchanged. The
19395        // round-trip property holds by construction. v0.2.2 T6.5: the
19396        // FingerprintMissing variant is removed because under T6.3 / T6.10,
19397        // no public path can produce a Trace with a zero fingerprint.
19398        Ok(Certified::new(
19399            GroundingCertificate::with_level_and_fingerprint_const(
19400                trace.witt_level_bits(),
19401                trace.content_fingerprint(),
19402            ),
19403        ))
19404    }
19405}
19406
19407/// v0.2.2 Phase E: sealed builder for an InteractionDeclaration.
19408/// Validates the peer protocol, convergence predicate, and
19409/// commutator state class required by `conformance:InteractionShape`.
19410/// Phase F wires the full `InteractionDriver` on top of this builder.
19411#[derive(Debug, Clone, Copy, Default)]
19412pub struct InteractionDeclarationBuilder {
19413    peer_protocol: Option<u128>,
19414    convergence_predicate: Option<u128>,
19415    commutator_state_class: Option<u128>,
19416}
19417
19418impl InteractionDeclarationBuilder {
19419    /// Construct a new builder.
19420    #[inline]
19421    #[must_use]
19422    pub const fn new() -> Self {
19423        Self {
19424            peer_protocol: None,
19425            convergence_predicate: None,
19426            commutator_state_class: None,
19427        }
19428    }
19429
19430    /// Set the peer protocol content address.
19431    #[inline]
19432    #[must_use]
19433    pub const fn peer_protocol(mut self, address: u128) -> Self {
19434        self.peer_protocol = Some(address);
19435        self
19436    }
19437
19438    /// Set the convergence predicate content address.
19439    #[inline]
19440    #[must_use]
19441    pub const fn convergence_predicate(mut self, address: u128) -> Self {
19442        self.convergence_predicate = Some(address);
19443        self
19444    }
19445
19446    /// Set the commutator state class content address.
19447    #[inline]
19448    #[must_use]
19449    pub const fn commutator_state_class(mut self, address: u128) -> Self {
19450        self.commutator_state_class = Some(address);
19451        self
19452    }
19453
19454    /// Phase E.6: validate against `conformance:InteractionShape`.
19455    /// # Errors
19456    /// Returns `ShapeViolation` if any of the three required fields is missing.
19457    pub fn validate(&self) -> Result<Validated<InteractionShape>, ShapeViolation> {
19458        self.validate_common().map(|_| {
19459            Validated::new(InteractionShape {
19460                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19461            })
19462        })
19463    }
19464
19465    /// Phase E.6 + C.1: const-fn companion.
19466    /// # Errors
19467    /// Returns `ShapeViolation` if any required field is missing.
19468    pub const fn validate_const(
19469        &self,
19470    ) -> Result<Validated<InteractionShape, CompileTime>, ShapeViolation> {
19471        if self.peer_protocol.is_none() {
19472            return Err(ShapeViolation {
19473                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19474                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19475                property_iri: "https://uor.foundation/interaction/peerProtocol",
19476                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19477                min_count: 1,
19478                max_count: 1,
19479                kind: ViolationKind::Missing,
19480            });
19481        }
19482        if self.convergence_predicate.is_none() {
19483            return Err(ShapeViolation {
19484                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19485                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19486                property_iri: "https://uor.foundation/interaction/convergencePredicate",
19487                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19488                min_count: 1,
19489                max_count: 1,
19490                kind: ViolationKind::Missing,
19491            });
19492        }
19493        if self.commutator_state_class.is_none() {
19494            return Err(ShapeViolation {
19495                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19496                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19497                property_iri: "https://uor.foundation/interaction/commutatorStateClass",
19498                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19499                min_count: 1,
19500                max_count: 1,
19501                kind: ViolationKind::Missing,
19502            });
19503        }
19504        Ok(Validated::new(InteractionShape {
19505            shape_iri: "https://uor.foundation/conformance/InteractionShape",
19506        }))
19507    }
19508
19509    fn validate_common(&self) -> Result<(), ShapeViolation> {
19510        self.validate_const().map(|_| ())
19511    }
19512}
19513
19514/// Phase E.6: validated InteractionDeclaration per `conformance:InteractionShape`.
19515#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19516pub struct InteractionShape {
19517    /// Shape IRI this declaration was validated against.
19518    pub shape_iri: &'static str,
19519}
19520
19521/// Phase E.5 (target §7.4): observability subscribe API.
19522/// When the `observability` feature is enabled, downstream may call
19523/// `subscribe_trace_events` with a handler closure that receives each
19524/// `TraceEvent` as the pipeline emits it. When the feature is off, this
19525/// function is entirely absent from the public API.
19526#[cfg(feature = "observability")]
19527pub fn subscribe_trace_events<F>(handler: F) -> ObservabilitySubscription<F>
19528where
19529    F: FnMut(&TraceEvent),
19530{
19531    ObservabilitySubscription {
19532        handler,
19533        _sealed: (),
19534    }
19535}
19536
19537#[cfg(feature = "observability")]
19538/// Phase E.5: sealed subscription handle returned by `subscribe_trace_events`.
19539#[cfg(feature = "observability")]
19540pub struct ObservabilitySubscription<F: FnMut(&TraceEvent)> {
19541    handler: F,
19542    _sealed: (),
19543}
19544
19545#[cfg(feature = "observability")]
19546impl<F: FnMut(&TraceEvent)> ObservabilitySubscription<F> {
19547    /// Dispatch a TraceEvent through the subscribed handler.
19548    pub fn emit(&mut self, event: &TraceEvent) {
19549        (self.handler)(event);
19550    }
19551}
19552
19553/// Phase F.2 (target §4.7): closed enumeration of the six constraint kinds.
19554/// `type-decl` bodies enumerate exactly these six kinds per `uor_term.ebnf`'s
19555/// `constraint-decl` production. `CompositeConstraint` — the implicit shape of
19556/// a multi-decl body — has no syntactic constructor and is therefore not a
19557/// variant of this enum.
19558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19559#[non_exhaustive]
19560pub enum ConstraintKind {
19561    /// `type:ResidueConstraint` — value is congruent to `r (mod m)`.
19562    Residue,
19563    /// `type:CarryConstraint` — bounded carry depth.
19564    Carry,
19565    /// `type:DepthConstraint` — bounded derivation depth.
19566    Depth,
19567    /// `type:HammingConstraint` — bounded Hamming distance from a reference.
19568    Hamming,
19569    /// `type:SiteConstraint` — per-site cardinality or containment.
19570    Site,
19571    /// `type:AffineConstraint` — linear inequality over site values.
19572    Affine,
19573}
19574
19575/// Phase F.3 (target §4.7 carry): sealed per-ring-op carry profile.
19576#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19577pub struct CarryProfile {
19578    chain_length: u32,
19579    max_depth: u32,
19580    _sealed: (),
19581}
19582
19583impl CarryProfile {
19584    /// Length of the longest carry chain observed.
19585    #[inline]
19586    #[must_use]
19587    pub const fn chain_length(&self) -> u32 {
19588        self.chain_length
19589    }
19590
19591    /// Maximum carry depth across the op.
19592    #[inline]
19593    #[must_use]
19594    pub const fn max_depth(&self) -> u32 {
19595        self.max_depth
19596    }
19597
19598    /// Crate-internal constructor.
19599    #[inline]
19600    #[must_use]
19601    #[allow(dead_code)]
19602    pub(crate) const fn new(chain_length: u32, max_depth: u32) -> Self {
19603        Self {
19604            chain_length,
19605            max_depth,
19606            _sealed: (),
19607        }
19608    }
19609}
19610
19611/// Phase F.3 (target §4.7 carry): sealed carry-event witness — records the ring op
19612/// and two `Datum<L>` witt widths involved.
19613#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19614pub struct CarryEvent {
19615    left_bits: u16,
19616    right_bits: u16,
19617    _sealed: (),
19618}
19619
19620impl CarryEvent {
19621    /// Witt bit-width of the left operand.
19622    #[inline]
19623    #[must_use]
19624    pub const fn left_bits(&self) -> u16 {
19625        self.left_bits
19626    }
19627
19628    /// Witt bit-width of the right operand.
19629    #[inline]
19630    #[must_use]
19631    pub const fn right_bits(&self) -> u16 {
19632        self.right_bits
19633    }
19634
19635    /// Crate-internal constructor.
19636    #[inline]
19637    #[must_use]
19638    #[allow(dead_code)]
19639    pub(crate) const fn new(left_bits: u16, right_bits: u16) -> Self {
19640        Self {
19641            left_bits,
19642            right_bits,
19643            _sealed: (),
19644        }
19645    }
19646}
19647
19648/// Phase F.3 (target §4.7 convergence): sealed convergence-level witness at `L`.
19649#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19650pub struct ConvergenceLevel<L> {
19651    valuation: u32,
19652    _level: PhantomData<L>,
19653    _sealed: (),
19654}
19655
19656impl<L> ConvergenceLevel<L> {
19657    /// The v₂ valuation of the datum at this convergence level.
19658    #[inline]
19659    #[must_use]
19660    pub const fn valuation(&self) -> u32 {
19661        self.valuation
19662    }
19663
19664    /// Crate-internal constructor.
19665    #[inline]
19666    #[must_use]
19667    #[allow(dead_code)]
19668    pub(crate) const fn new(valuation: u32) -> Self {
19669        Self {
19670            valuation,
19671            _level: PhantomData,
19672            _sealed: (),
19673        }
19674    }
19675}
19676
19677/// Phase F.3 (target §4.7 division): sealed enum over the four normed division
19678/// algebras from Cayley-Dickson. No other admissible algebra exists (Hurwitz's theorem).
19679#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19680#[non_exhaustive]
19681pub enum DivisionAlgebraWitness {
19682    /// Real numbers ℝ (dimension 1).
19683    Real,
19684    /// Complex numbers ℂ (dimension 2).
19685    Complex,
19686    /// Quaternions ℍ (dimension 4, non-commutative).
19687    Quaternion,
19688    /// Octonions 𝕆 (dimension 8, non-commutative, non-associative).
19689    Octonion,
19690}
19691
19692/// Phase F.3 (target §4.7 monoidal): sealed monoidal-product witness.
19693#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19694pub struct MonoidalProduct<L, R> {
19695    _left: PhantomData<L>,
19696    _right: PhantomData<R>,
19697    _sealed: (),
19698}
19699
19700impl<L, R> MonoidalProduct<L, R> {
19701    /// Crate-internal constructor.
19702    #[inline]
19703    #[must_use]
19704    #[allow(dead_code)]
19705    pub(crate) const fn new() -> Self {
19706        Self {
19707            _left: PhantomData,
19708            _right: PhantomData,
19709            _sealed: (),
19710        }
19711    }
19712}
19713
19714/// Phase F.3 (target §4.7 monoidal): sealed monoidal-unit witness at `L`.
19715#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19716pub struct MonoidalUnit<L> {
19717    _level: PhantomData<L>,
19718    _sealed: (),
19719}
19720
19721impl<L> MonoidalUnit<L> {
19722    /// Crate-internal constructor.
19723    #[inline]
19724    #[must_use]
19725    #[allow(dead_code)]
19726    pub(crate) const fn new() -> Self {
19727        Self {
19728            _level: PhantomData,
19729            _sealed: (),
19730        }
19731    }
19732}
19733
19734/// Phase F.1 (target §4.7 operad): sealed operad-composition witness.
19735/// Every `type-app` form in the term grammar materializes a fresh `OperadComposition`
19736/// carrying the outer/inner type IRIs and composed site count, per `operad:` ontology.
19737#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19738pub struct OperadComposition {
19739    outer_type_iri: &'static str,
19740    inner_type_iri: &'static str,
19741    composed_site_count: u32,
19742    _sealed: (),
19743}
19744
19745impl OperadComposition {
19746    /// IRI of the outer `type:TypeDefinition`.
19747    #[inline]
19748    #[must_use]
19749    pub const fn outer_type_iri(&self) -> &'static str {
19750        self.outer_type_iri
19751    }
19752
19753    /// IRI of the inner `type:TypeDefinition`.
19754    #[inline]
19755    #[must_use]
19756    pub const fn inner_type_iri(&self) -> &'static str {
19757        self.inner_type_iri
19758    }
19759
19760    /// Site count of the composed type.
19761    #[inline]
19762    #[must_use]
19763    pub const fn composed_site_count(&self) -> u32 {
19764        self.composed_site_count
19765    }
19766
19767    /// Crate-internal constructor.
19768    #[inline]
19769    #[must_use]
19770    #[allow(dead_code)]
19771    pub(crate) const fn new(
19772        outer_type_iri: &'static str,
19773        inner_type_iri: &'static str,
19774        composed_site_count: u32,
19775    ) -> Self {
19776        Self {
19777            outer_type_iri,
19778            inner_type_iri,
19779            composed_site_count,
19780            _sealed: (),
19781        }
19782    }
19783}
19784
19785/// Phase F.3 (target §4.7 recursion): maximum depth of the recursion trace
19786/// witness. Bounded by the declared descent budget at builder-validate time;
19787/// the constant is a size-budget cap matching other foundation arenas.
19788/// Wiki ADR-037: alias of [`crate::HostBounds::RECURSION_TRACE_DEPTH_MAX`] via
19789/// [`crate::DefaultHostBounds`].
19790pub const RECURSION_TRACE_MAX_DEPTH: usize =
19791    <crate::DefaultHostBounds as crate::HostBounds>::RECURSION_TRACE_DEPTH_MAX;
19792
19793/// Phase F.3 (target §4.7 recursion): sealed recursion trace with fixed-capacity
19794/// descent-measure sequence.
19795#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19796pub struct RecursionTrace {
19797    depth: u32,
19798    measure: [u32; RECURSION_TRACE_MAX_DEPTH],
19799    _sealed: (),
19800}
19801
19802impl RecursionTrace {
19803    /// Number of recursive descents in this trace.
19804    #[inline]
19805    #[must_use]
19806    pub const fn depth(&self) -> u32 {
19807        self.depth
19808    }
19809
19810    /// Descent-measure sequence.
19811    #[inline]
19812    #[must_use]
19813    pub const fn measure(&self) -> &[u32; RECURSION_TRACE_MAX_DEPTH] {
19814        &self.measure
19815    }
19816
19817    /// Crate-internal constructor.
19818    #[inline]
19819    #[must_use]
19820    #[allow(dead_code)]
19821    pub(crate) const fn new(depth: u32, measure: [u32; RECURSION_TRACE_MAX_DEPTH]) -> Self {
19822        Self {
19823            depth,
19824            measure,
19825            _sealed: (),
19826        }
19827    }
19828}
19829
19830/// Phase F.3 (target §4.7 region): sealed address-region witness.
19831#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19832pub struct AddressRegion {
19833    base: u128,
19834    extent: u64,
19835    _sealed: (),
19836}
19837
19838impl AddressRegion {
19839    /// Base address of the region.
19840    #[inline]
19841    #[must_use]
19842    pub const fn base(&self) -> u128 {
19843        self.base
19844    }
19845
19846    /// Extent (number of addressable cells).
19847    #[inline]
19848    #[must_use]
19849    pub const fn extent(&self) -> u64 {
19850        self.extent
19851    }
19852
19853    /// Crate-internal constructor.
19854    #[inline]
19855    #[must_use]
19856    #[allow(dead_code)]
19857    pub(crate) const fn new(base: u128, extent: u64) -> Self {
19858        Self {
19859            base,
19860            extent,
19861            _sealed: (),
19862        }
19863    }
19864}
19865
19866/// Phase F.3 (target §4.7 linear): sealed linear-resource budget.
19867#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19868pub struct LinearBudget {
19869    sites_remaining: u64,
19870    _sealed: (),
19871}
19872
19873impl LinearBudget {
19874    /// Number of linear sites still available for allocation.
19875    #[inline]
19876    #[must_use]
19877    pub const fn sites_remaining(&self) -> u64 {
19878        self.sites_remaining
19879    }
19880
19881    /// Crate-internal constructor.
19882    #[inline]
19883    #[must_use]
19884    #[allow(dead_code)]
19885    pub(crate) const fn new(sites_remaining: u64) -> Self {
19886        Self {
19887            sites_remaining,
19888            _sealed: (),
19889        }
19890    }
19891}
19892
19893/// Phase F.3 (target §4.7 linear): sealed lease-allocation witness.
19894#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19895pub struct LeaseAllocation {
19896    site_count: u32,
19897    scope_hash: u128,
19898    _sealed: (),
19899}
19900
19901impl LeaseAllocation {
19902    /// Number of linear sites taken by this allocation.
19903    #[inline]
19904    #[must_use]
19905    pub const fn site_count(&self) -> u32 {
19906        self.site_count
19907    }
19908
19909    /// Content-hash of the lease scope identifier.
19910    #[inline]
19911    #[must_use]
19912    pub const fn scope_hash(&self) -> u128 {
19913        self.scope_hash
19914    }
19915
19916    /// Crate-internal constructor.
19917    #[inline]
19918    #[must_use]
19919    #[allow(dead_code)]
19920    pub(crate) const fn new(site_count: u32, scope_hash: u128) -> Self {
19921        Self {
19922            site_count,
19923            scope_hash,
19924            _sealed: (),
19925        }
19926    }
19927}
19928
19929/// v0.2.2 Phase J: zero-sized token identifying the `Total` marker.
19930#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19931pub struct TotalMarker;
19932
19933/// v0.2.2 Phase J: zero-sized token identifying the `Invertible` marker.
19934#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19935pub struct InvertibleMarker;
19936
19937/// v0.2.2 Phase J: zero-sized token identifying the `PreservesStructure` marker.
19938#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19939pub struct PreservesStructureMarker;
19940
19941mod marker_tuple_sealed {
19942    /// Private supertrait. Not implementable outside this crate.
19943    pub trait Sealed {}
19944}
19945
19946/// v0.2.2 Phase J: sealed marker-tuple trait. Implemented exhaustively by
19947/// the closed catalogue of six admissible marker tuples in canonical order
19948/// (Total, Invertible, PreservesStructure). Downstream cannot add new
19949/// marker tuples; the seal anchors Phase J's compile-time correctness claim.
19950pub trait MarkerTuple: marker_tuple_sealed::Sealed {}
19951
19952impl marker_tuple_sealed::Sealed for () {}
19953impl MarkerTuple for () {}
19954impl marker_tuple_sealed::Sealed for (TotalMarker,) {}
19955impl MarkerTuple for (TotalMarker,) {}
19956impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker) {}
19957impl MarkerTuple for (TotalMarker, InvertibleMarker) {}
19958impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
19959impl MarkerTuple for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
19960impl marker_tuple_sealed::Sealed for (InvertibleMarker,) {}
19961impl MarkerTuple for (InvertibleMarker,) {}
19962impl marker_tuple_sealed::Sealed for (InvertibleMarker, PreservesStructureMarker) {}
19963impl MarkerTuple for (InvertibleMarker, PreservesStructureMarker) {}
19964
19965/// v0.2.2 Phase J: type-level set intersection of two marker tuples.
19966/// Implemented exhaustively for every ordered pair in the closed catalogue.
19967/// Composition combinators (`then`, `and_then`) use this trait to compute
19968/// the output marker tuple of a composed primitive as the intersection of
19969/// its two inputs' tuples. Because the catalogue is closed, the result is
19970/// always another tuple in the catalogue — no open-world hazards.
19971pub trait MarkerIntersection<Other: MarkerTuple>: MarkerTuple {
19972    /// The intersection of `Self` and `Other` in the closed catalogue.
19973    type Output: MarkerTuple;
19974}
19975
19976impl MarkerIntersection<()> for () {
19977    type Output = ();
19978}
19979impl MarkerIntersection<(TotalMarker,)> for () {
19980    type Output = ();
19981}
19982impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for () {
19983    type Output = ();
19984}
19985impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)> for () {
19986    type Output = ();
19987}
19988impl MarkerIntersection<(InvertibleMarker,)> for () {
19989    type Output = ();
19990}
19991impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for () {
19992    type Output = ();
19993}
19994impl MarkerIntersection<()> for (TotalMarker,) {
19995    type Output = ();
19996}
19997impl MarkerIntersection<(TotalMarker,)> for (TotalMarker,) {
19998    type Output = (TotalMarker,);
19999}
20000impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker,) {
20001    type Output = (TotalMarker,);
20002}
20003impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20004    for (TotalMarker,)
20005{
20006    type Output = (TotalMarker,);
20007}
20008impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker,) {
20009    type Output = ();
20010}
20011impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (TotalMarker,) {
20012    type Output = ();
20013}
20014impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker) {
20015    type Output = ();
20016}
20017impl MarkerIntersection<(TotalMarker,)> for (TotalMarker, InvertibleMarker) {
20018    type Output = (TotalMarker,);
20019}
20020impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker, InvertibleMarker) {
20021    type Output = (TotalMarker, InvertibleMarker);
20022}
20023impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20024    for (TotalMarker, InvertibleMarker)
20025{
20026    type Output = (TotalMarker, InvertibleMarker);
20027}
20028impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker, InvertibleMarker) {
20029    type Output = (InvertibleMarker,);
20030}
20031impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20032    for (TotalMarker, InvertibleMarker)
20033{
20034    type Output = (InvertibleMarker,);
20035}
20036impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {
20037    type Output = ();
20038}
20039impl MarkerIntersection<(TotalMarker,)>
20040    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20041{
20042    type Output = (TotalMarker,);
20043}
20044impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20045    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20046{
20047    type Output = (TotalMarker, InvertibleMarker);
20048}
20049impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20050    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20051{
20052    type Output = (TotalMarker, InvertibleMarker, PreservesStructureMarker);
20053}
20054impl MarkerIntersection<(InvertibleMarker,)>
20055    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20056{
20057    type Output = (InvertibleMarker,);
20058}
20059impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20060    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20061{
20062    type Output = (InvertibleMarker, PreservesStructureMarker);
20063}
20064impl MarkerIntersection<()> for (InvertibleMarker,) {
20065    type Output = ();
20066}
20067impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker,) {
20068    type Output = ();
20069}
20070impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (InvertibleMarker,) {
20071    type Output = (InvertibleMarker,);
20072}
20073impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20074    for (InvertibleMarker,)
20075{
20076    type Output = (InvertibleMarker,);
20077}
20078impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker,) {
20079    type Output = (InvertibleMarker,);
20080}
20081impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (InvertibleMarker,) {
20082    type Output = (InvertibleMarker,);
20083}
20084impl MarkerIntersection<()> for (InvertibleMarker, PreservesStructureMarker) {
20085    type Output = ();
20086}
20087impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20088    type Output = ();
20089}
20090impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20091    for (InvertibleMarker, PreservesStructureMarker)
20092{
20093    type Output = (InvertibleMarker,);
20094}
20095impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20096    for (InvertibleMarker, PreservesStructureMarker)
20097{
20098    type Output = (InvertibleMarker, PreservesStructureMarker);
20099}
20100impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20101    type Output = (InvertibleMarker,);
20102}
20103impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20104    for (InvertibleMarker, PreservesStructureMarker)
20105{
20106    type Output = (InvertibleMarker, PreservesStructureMarker);
20107}
20108
20109/// v0.2.2 Phase J: compile-time check that a combinator's marker tuple
20110/// carries every property declared by the `GroundingMapKind` a program
20111/// claims. Implemented exhaustively by codegen for every valid `(tuple,
20112/// map)` pair; absent impls reject the mismatched declaration at the
20113/// `GroundingProgram::from_primitive` call site.
20114pub trait MarkersImpliedBy<Map: GroundingMapKind>: MarkerTuple {}
20115
20116/// v0.2.2 Phase J: bitmask encoding of a combinator's marker set.
20117/// Bit 0 = Total, bit 1 = Invertible, bit 2 = PreservesStructure.
20118#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20119pub struct MarkerBits(u8);
20120
20121impl MarkerBits {
20122    /// The `Total` marker bit.
20123    pub const TOTAL: Self = Self(1);
20124    /// The `Invertible` marker bit.
20125    pub const INVERTIBLE: Self = Self(2);
20126    /// The `PreservesStructure` marker bit.
20127    pub const PRESERVES_STRUCTURE: Self = Self(4);
20128    /// An empty marker set.
20129    pub const NONE: Self = Self(0);
20130
20131    /// Construct a marker bitmask from raw u8.
20132    #[inline]
20133    #[must_use]
20134    pub const fn from_u8(bits: u8) -> Self {
20135        Self(bits)
20136    }
20137
20138    /// Access the raw bitmask.
20139    #[inline]
20140    #[must_use]
20141    pub const fn as_u8(&self) -> u8 {
20142        self.0
20143    }
20144
20145    /// Bitwise OR of two marker bitmasks.
20146    #[inline]
20147    #[must_use]
20148    pub const fn union(self, other: Self) -> Self {
20149        Self(self.0 | other.0)
20150    }
20151
20152    /// Bitwise AND of two marker bitmasks (marker intersection).
20153    #[inline]
20154    #[must_use]
20155    pub const fn intersection(self, other: Self) -> Self {
20156        Self(self.0 & other.0)
20157    }
20158
20159    /// Whether this set contains all marker bits of `other`.
20160    #[inline]
20161    #[must_use]
20162    pub const fn contains(&self, other: Self) -> bool {
20163        (self.0 & other.0) == other.0
20164    }
20165}
20166
20167/// v0.2.2 Phase J: closed catalogue of grounding primitives.
20168/// Exactly 12 operations — read_bytes, interpret_le_integer,
20169/// interpret_be_integer, digest, decode_utf8, decode_json, select_field,
20170/// select_index, const_value, then, map_err, and_then. Adding a new
20171/// primitive is an ontology+grammar+codegen edit, not a Rust patch.
20172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20173#[non_exhaustive]
20174pub enum GroundingPrimitiveOp {
20175    /// Read a fixed-size byte slice from the input.
20176    ReadBytes,
20177    /// Interpret bytes as a little-endian integer at the target WittLevel.
20178    InterpretLeInteger,
20179    /// Interpret bytes as a big-endian integer.
20180    InterpretBeInteger,
20181    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`.
20182    /// # Scope
20183    /// `interpret_leaf_op` returns the first byte of the blake3 32-byte digest.
20184    /// The full digest is produced by `Datum<W256>` composition of 32 `Digest` leaves —
20185    /// the leaf-level output is the single-byte projection.
20186    Digest,
20187    /// Decode UTF-8 bytes; rejects malformed input.
20188    /// # Scope
20189    /// Only single-byte ASCII (`b < 0x80`) is decoded by `interpret_leaf_op`.
20190    /// Multi-byte UTF-8 is not decoded by this leaf; multi-byte sequences traverse the
20191    /// foundation via `GroundedTuple<N>` composition of single-byte leaves.
20192    DecodeUtf8,
20193    /// Decode JSON bytes; rejects malformed input.
20194    /// # Scope
20195    /// Only the leading byte of a JSON number scalar (`-` or ASCII digit) is parsed
20196    /// by `interpret_leaf_op`. Structured JSON values (objects, arrays, strings,
20197    /// multi-byte numbers) are not parsed by this leaf.
20198    DecodeJson,
20199    /// Select a field from a structured value.
20200    SelectField,
20201    /// Select an indexed element.
20202    SelectIndex,
20203    /// Inject a foundation-known constant.
20204    /// # Scope
20205    /// `interpret_leaf_op` returns `GroundedCoord::w8(0)` — the foundation-canonical
20206    /// zero constant. Non-zero constants are materialized through the const-fn frontier
20207    /// (`validate_const` paths) rather than through this leaf.
20208    ConstValue,
20209    /// Compose two combinators sequentially.
20210    Then,
20211    /// Map the error variant of a fallible combinator.
20212    MapErr,
20213    /// Conditional composition (and_then).
20214    AndThen,
20215}
20216
20217/// Max depth of a composed op chain retained inline inside
20218/// `GroundingPrimitive`. Depth-2 composites (`Then(leaf, leaf)`,
20219/// `AndThen(leaf, leaf)`) are the exercised shape today; 8 gives headroom
20220/// for nested composition while keeping `Copy` and `no_std` without alloc.
20221/// Wiki ADR-037: alias of [`crate::HostBounds::OP_CHAIN_DEPTH_MAX`] via
20222/// [`crate::DefaultHostBounds`].
20223pub const MAX_OP_CHAIN_DEPTH: usize =
20224    <crate::DefaultHostBounds as crate::HostBounds>::OP_CHAIN_DEPTH_MAX;
20225
20226/// v0.2.2 Phase J: a single grounding primitive parametric over its output
20227/// type `Out` and its type-level marker tuple `Markers`.
20228/// Constructed only by the 12 enumerated combinator functions below;
20229/// downstream cannot construct one directly. The `Markers` parameter
20230/// defaults to `()` for backwards-compatible call sites, but each
20231/// combinator returns a specific tuple — see `combinators::digest` etc.
20232/// For leaf primitives `chain_len == 0`. For `Then`/`AndThen`/`MapErr`
20233/// composites, `chain[..chain_len as usize]` is the linearized post-order
20234/// sequence of leaf primitive ops the interpreter walks.
20235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20236pub struct GroundingPrimitive<Out, Markers: MarkerTuple = ()> {
20237    op: GroundingPrimitiveOp,
20238    markers: MarkerBits,
20239    chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20240    chain_len: u8,
20241    _out: PhantomData<Out>,
20242    _markers: PhantomData<Markers>,
20243    _sealed: (),
20244}
20245
20246impl<Out, Markers: MarkerTuple> GroundingPrimitive<Out, Markers> {
20247    /// Access the primitive op.
20248    #[inline]
20249    #[must_use]
20250    pub const fn op(&self) -> GroundingPrimitiveOp {
20251        self.op
20252    }
20253
20254    /// Access the runtime marker bitmask (mirrors the type-level tuple).
20255    #[inline]
20256    #[must_use]
20257    pub const fn markers(&self) -> MarkerBits {
20258        self.markers
20259    }
20260
20261    /// Access the recorded composition chain. Empty for leaf primitives;
20262    /// the post-order leaf-op sequence for `Then`/`AndThen`/`MapErr`.
20263    #[inline]
20264    #[must_use]
20265    pub fn chain(&self) -> &[GroundingPrimitiveOp] {
20266        &self.chain[..self.chain_len as usize]
20267    }
20268
20269    /// Crate-internal constructor for a leaf primitive (no recorded chain).
20270    /// The type-level `Markers` tuple is selected via turbofish at call
20271    /// sites inside the combinator functions.
20272    #[inline]
20273    #[must_use]
20274    #[allow(dead_code)]
20275    pub(crate) const fn from_parts(op: GroundingPrimitiveOp, markers: MarkerBits) -> Self {
20276        Self {
20277            op,
20278            markers,
20279            chain: [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH],
20280            chain_len: 0,
20281            _out: PhantomData,
20282            _markers: PhantomData,
20283            _sealed: (),
20284        }
20285    }
20286
20287    /// Crate-internal constructor for a composite primitive. Stores
20288    /// `chain[..chain_len]` inline; accessors expose only the prefix.
20289    #[inline]
20290    #[must_use]
20291    #[allow(dead_code)]
20292    pub(crate) const fn from_parts_with_chain(
20293        op: GroundingPrimitiveOp,
20294        markers: MarkerBits,
20295        chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20296        chain_len: u8,
20297    ) -> Self {
20298        Self {
20299            op,
20300            markers,
20301            chain,
20302            chain_len,
20303            _out: PhantomData,
20304            _markers: PhantomData,
20305            _sealed: (),
20306        }
20307    }
20308}
20309
20310/// v0.2.2 Phase J: closed 12-combinator surface for building grounding
20311/// programs. See `GroundingProgram` for composition. Each leaf combinator
20312/// returns a `GroundingPrimitive<Out, M>` carrying a specific marker tuple;
20313/// the type parameter is what `GroundingProgram::from_primitive`'s
20314/// `MarkersImpliedBy<Map>` bound checks at compile time.
20315pub mod combinators {
20316    use super::{
20317        GroundingPrimitive, GroundingPrimitiveOp, InvertibleMarker, MarkerBits, MarkerIntersection,
20318        MarkerTuple, PreservesStructureMarker, TotalMarker, MAX_OP_CHAIN_DEPTH,
20319    };
20320
20321    /// Build the post-order leaf-op chain for a sequential composite:
20322    /// `first.chain ++ [first.op] ++ second.chain ++ [second.op]`.
20323    /// Saturated to `MAX_OP_CHAIN_DEPTH`.
20324    fn compose_chain<A, B, MA: MarkerTuple, MB: MarkerTuple>(
20325        first: &GroundingPrimitive<A, MA>,
20326        second: &GroundingPrimitive<B, MB>,
20327    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20328        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20329        let mut len: usize = 0;
20330        for &op in first.chain() {
20331            if len >= MAX_OP_CHAIN_DEPTH {
20332                return (chain, len as u8);
20333            }
20334            chain[len] = op;
20335            len += 1;
20336        }
20337        if len < MAX_OP_CHAIN_DEPTH {
20338            chain[len] = first.op();
20339            len += 1;
20340        }
20341        for &op in second.chain() {
20342            if len >= MAX_OP_CHAIN_DEPTH {
20343                return (chain, len as u8);
20344            }
20345            chain[len] = op;
20346            len += 1;
20347        }
20348        if len < MAX_OP_CHAIN_DEPTH {
20349            chain[len] = second.op();
20350            len += 1;
20351        }
20352        (chain, len as u8)
20353    }
20354
20355    /// Build the chain for `map_err(first)`: `first.chain ++ [first.op]`.
20356    fn map_err_chain<A, M: MarkerTuple>(
20357        first: &GroundingPrimitive<A, M>,
20358    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20359        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20360        let mut len: usize = 0;
20361        for &op in first.chain() {
20362            if len >= MAX_OP_CHAIN_DEPTH {
20363                return (chain, len as u8);
20364            }
20365            chain[len] = op;
20366            len += 1;
20367        }
20368        if len < MAX_OP_CHAIN_DEPTH {
20369            chain[len] = first.op();
20370            len += 1;
20371        }
20372        (chain, len as u8)
20373    }
20374
20375    /// Read a fixed-size byte slice from the input. `(Total, Invertible)`.
20376    #[inline]
20377    #[must_use]
20378    pub const fn read_bytes<Out>() -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker)> {
20379        GroundingPrimitive::from_parts(
20380            GroundingPrimitiveOp::ReadBytes,
20381            MarkerBits::TOTAL.union(MarkerBits::INVERTIBLE),
20382        )
20383    }
20384
20385    /// Interpret bytes as a little-endian integer at the target WittLevel.
20386    #[inline]
20387    #[must_use]
20388    pub const fn interpret_le_integer<Out>(
20389    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20390        GroundingPrimitive::from_parts(
20391            GroundingPrimitiveOp::InterpretLeInteger,
20392            MarkerBits::TOTAL
20393                .union(MarkerBits::INVERTIBLE)
20394                .union(MarkerBits::PRESERVES_STRUCTURE),
20395        )
20396    }
20397
20398    /// Interpret bytes as a big-endian integer.
20399    #[inline]
20400    #[must_use]
20401    pub const fn interpret_be_integer<Out>(
20402    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20403        GroundingPrimitive::from_parts(
20404            GroundingPrimitiveOp::InterpretBeInteger,
20405            MarkerBits::TOTAL
20406                .union(MarkerBits::INVERTIBLE)
20407                .union(MarkerBits::PRESERVES_STRUCTURE),
20408        )
20409    }
20410
20411    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`. `(Total,)` only.
20412    #[inline]
20413    #[must_use]
20414    pub const fn digest<Out>() -> GroundingPrimitive<Out, (TotalMarker,)> {
20415        GroundingPrimitive::from_parts(GroundingPrimitiveOp::Digest, MarkerBits::TOTAL)
20416    }
20417
20418    /// Decode UTF-8 bytes. `(Invertible, PreservesStructure)` — not Total.
20419    #[inline]
20420    #[must_use]
20421    pub const fn decode_utf8<Out>(
20422    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20423        GroundingPrimitive::from_parts(
20424            GroundingPrimitiveOp::DecodeUtf8,
20425            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20426        )
20427    }
20428
20429    /// Decode JSON bytes. `(Invertible, PreservesStructure)` — not Total.
20430    #[inline]
20431    #[must_use]
20432    pub const fn decode_json<Out>(
20433    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20434        GroundingPrimitive::from_parts(
20435            GroundingPrimitiveOp::DecodeJson,
20436            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20437        )
20438    }
20439
20440    /// Select a field from a structured value. `(Invertible,)` — not Total.
20441    #[inline]
20442    #[must_use]
20443    pub const fn select_field<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20444        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectField, MarkerBits::INVERTIBLE)
20445    }
20446
20447    /// Select an indexed element. `(Invertible,)` — not Total.
20448    #[inline]
20449    #[must_use]
20450    pub const fn select_index<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20451        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectIndex, MarkerBits::INVERTIBLE)
20452    }
20453
20454    /// Inject a foundation-known constant. `(Total, Invertible, PreservesStructure)`.
20455    #[inline]
20456    #[must_use]
20457    pub const fn const_value<Out>(
20458    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20459        GroundingPrimitive::from_parts(
20460            GroundingPrimitiveOp::ConstValue,
20461            MarkerBits::TOTAL
20462                .union(MarkerBits::INVERTIBLE)
20463                .union(MarkerBits::PRESERVES_STRUCTURE),
20464        )
20465    }
20466
20467    /// Compose two combinators sequentially. Markers are intersected at
20468    /// the type level via the `MarkerIntersection` trait. The recorded
20469    /// leaf-op chain lets the foundation's interpreter walk the operands
20470    /// at runtime.
20471    #[inline]
20472    #[must_use]
20473    pub fn then<A, B, MA, MB>(
20474        first: GroundingPrimitive<A, MA>,
20475        second: GroundingPrimitive<B, MB>,
20476    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20477    where
20478        MA: MarkerTuple + MarkerIntersection<MB>,
20479        MB: MarkerTuple,
20480    {
20481        let (chain, chain_len) = compose_chain(&first, &second);
20482        GroundingPrimitive::from_parts_with_chain(
20483            GroundingPrimitiveOp::Then,
20484            first.markers().intersection(second.markers()),
20485            chain,
20486            chain_len,
20487        )
20488    }
20489
20490    /// Map an error variant of a fallible combinator. Marker tuple
20491    /// is preserved. The operand's op is recorded so the interpreter's
20492    /// `MapErr` arm can forward the success value.
20493    #[inline]
20494    #[must_use]
20495    pub fn map_err<A, M: MarkerTuple>(first: GroundingPrimitive<A, M>) -> GroundingPrimitive<A, M> {
20496        let (chain, chain_len) = map_err_chain(&first);
20497        GroundingPrimitive::from_parts_with_chain(
20498            GroundingPrimitiveOp::MapErr,
20499            first.markers(),
20500            chain,
20501            chain_len,
20502        )
20503    }
20504
20505    /// Conditional composition (and_then). Markers are intersected; the
20506    /// recorded chain mirrors `then` so the interpreter walks operands.
20507    #[inline]
20508    #[must_use]
20509    pub fn and_then<A, B, MA, MB>(
20510        first: GroundingPrimitive<A, MA>,
20511        second: GroundingPrimitive<B, MB>,
20512    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20513    where
20514        MA: MarkerTuple + MarkerIntersection<MB>,
20515        MB: MarkerTuple,
20516    {
20517        let (chain, chain_len) = compose_chain(&first, &second);
20518        GroundingPrimitive::from_parts_with_chain(
20519            GroundingPrimitiveOp::AndThen,
20520            first.markers().intersection(second.markers()),
20521            chain,
20522            chain_len,
20523        )
20524    }
20525}
20526
20527/// v0.2.2 Phase J: sealed grounding program.
20528/// A composition of combinators with a statically tracked marker tuple.
20529/// Constructed only via `GroundingProgram::from_primitive`, which requires
20530/// via the `MarkersImpliedBy<Map>` trait bound that the primitive's marker
20531/// tuple carries every property declared by `Map: GroundingMapKind`.
20532#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20533pub struct GroundingProgram<Out, Map: GroundingMapKind> {
20534    primitive: GroundingPrimitive<Out>,
20535    _map: PhantomData<Map>,
20536    _sealed: (),
20537}
20538
20539impl<Out, Map: GroundingMapKind> GroundingProgram<Out, Map> {
20540    /// Foundation-verified constructor. Accepts a primitive whose marker
20541    /// tuple satisfies `MarkersImpliedBy<Map>`. Programs built from
20542    /// combinators whose marker tuple lacks a property `Map` requires are
20543    /// rejected at compile time — this is Phase J's marquee correctness
20544    /// claim: misdeclarations fail to compile.
20545    /// # Example: valid program
20546    /// ```
20547    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20548    /// let prog: GroundingProgram<u64, IntegerGroundingMap> =
20549    ///     GroundingProgram::from_primitive(combinators::interpret_le_integer::<u64>());
20550    /// let _ = prog;
20551    /// ```
20552    /// # Example: rejected misdeclaration
20553    /// ```compile_fail
20554    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20555    /// // digest returns (TotalMarker,) which does NOT satisfy
20556    /// // MarkersImpliedBy<IntegerGroundingMap> — the line below fails to compile.
20557    /// let prog: GroundingProgram<[u8; 32], IntegerGroundingMap> =
20558    ///     GroundingProgram::from_primitive(combinators::digest::<[u8; 32]>());
20559    /// let _ = prog;
20560    /// ```
20561    #[inline]
20562    #[must_use]
20563    pub fn from_primitive<Markers>(primitive: GroundingPrimitive<Out, Markers>) -> Self
20564    where
20565        Markers: MarkerTuple + MarkersImpliedBy<Map>,
20566    {
20567        // Preserve the composition chain so the interpreter can walk
20568        // operands of Then/AndThen/MapErr composites.
20569        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20570        let src = primitive.chain();
20571        let mut i = 0;
20572        while i < src.len() && i < MAX_OP_CHAIN_DEPTH {
20573            chain[i] = src[i];
20574            i += 1;
20575        }
20576        let erased = GroundingPrimitive::<Out, ()>::from_parts_with_chain(
20577            primitive.op(),
20578            primitive.markers(),
20579            chain,
20580            i as u8,
20581        );
20582        Self {
20583            primitive: erased,
20584            _map: PhantomData,
20585            _sealed: (),
20586        }
20587    }
20588
20589    /// Access the underlying primitive (erased marker tuple).
20590    #[inline]
20591    #[must_use]
20592    pub const fn primitive(&self) -> &GroundingPrimitive<Out> {
20593        &self.primitive
20594    }
20595}
20596
20597/// Phase K (target §4.3 / §9 criterion 1): foundation-supplied interpreter for
20598/// grounding programs whose `Out` is `GroundedCoord`. Handles every op in
20599/// the closed 12-combinator catalogue: leaf ops (`ReadBytes`,
20600/// `InterpretLeInteger`, `InterpretBeInteger`, `Digest`, `DecodeUtf8`,
20601/// `DecodeJson`, `ConstValue`, `SelectField`, `SelectIndex`) call
20602/// `interpret_leaf_op` directly; composition ops (`Then`, `AndThen`,
20603/// `MapErr`) walk the chain recorded in the primitive and thread
20604/// `external` through each leaf step. The interpreter surfaces
20605/// `GroundedCoord::w8(byte)` values; richer outputs compose through
20606/// combinator chains producing `GroundedTuple<N>`. No `ground()`
20607/// override exists after W4 closure — downstream provides only
20608/// `program()`, and `GroundingExt::ground` is foundation-authored.
20609impl<Map: GroundingMapKind> GroundingProgram<GroundedCoord, Map> {
20610    /// Run this program on external bytes, producing a `GroundedCoord`.
20611    /// Returns `None` if the input is malformed/undersized for the
20612    /// program's op chain.
20613    #[inline]
20614    #[must_use]
20615    pub fn run(&self, external: &[u8]) -> Option<GroundedCoord> {
20616        match self.primitive.op() {
20617            GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20618                let chain = self.primitive.chain();
20619                if chain.is_empty() {
20620                    return None;
20621                }
20622                let mut last: Option<GroundedCoord> = None;
20623                for &op in chain {
20624                    match interpret_leaf_op(op, external) {
20625                        Some(c) => last = Some(c),
20626                        None => return None,
20627                    }
20628                }
20629                last
20630            }
20631            GroundingPrimitiveOp::MapErr => self
20632                .primitive
20633                .chain()
20634                .first()
20635                .and_then(|&op| interpret_leaf_op(op, external)),
20636            leaf => interpret_leaf_op(leaf, external),
20637        }
20638    }
20639}
20640
20641/// W4 closure (target §4.3 + §9 criterion 1): foundation-supplied
20642/// interpreter for programs producing `GroundedTuple<N>`. Splits
20643/// `external` into `N` equal windows and runs the same dispatch
20644/// that `GroundingProgram<GroundedCoord, Map>::run` performs on
20645/// each window. Returns `None` if `N == 0`, the input is empty,
20646/// the input length isn't divisible by `N`, or any window fails.
20647impl<const N: usize, Map: GroundingMapKind> GroundingProgram<GroundedTuple<N>, Map> {
20648    /// Run this program on external bytes, producing a `GroundedTuple<N>`.
20649    #[inline]
20650    #[must_use]
20651    pub fn run(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
20652        if N == 0 || external.is_empty() || external.len() % N != 0 {
20653            return None;
20654        }
20655        let window = external.len() / N;
20656        let mut coords: [GroundedCoord; N] = [const { GroundedCoord::w8(0) }; N];
20657        let mut i = 0usize;
20658        while i < N {
20659            let start = i * window;
20660            let end = start + window;
20661            let sub = &external[start..end];
20662            // Walk this window through the same leaf/composition
20663            // dispatch as the GroundedCoord interpreter above. A
20664            // helper that runs the chain is reused via the same
20665            // primitive accessors.
20666            let outcome = match self.primitive.op() {
20667                GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20668                    let chain = self.primitive.chain();
20669                    if chain.is_empty() {
20670                        return None;
20671                    }
20672                    let mut last: Option<GroundedCoord> = None;
20673                    for &op in chain {
20674                        match interpret_leaf_op(op, sub) {
20675                            Some(c) => last = Some(c),
20676                            None => return None,
20677                        }
20678                    }
20679                    last
20680                }
20681                GroundingPrimitiveOp::MapErr => self
20682                    .primitive
20683                    .chain()
20684                    .first()
20685                    .and_then(|&op| interpret_leaf_op(op, sub)),
20686                leaf => interpret_leaf_op(leaf, sub),
20687            };
20688            match outcome {
20689                Some(c) => {
20690                    coords[i] = c;
20691                }
20692                None => {
20693                    return None;
20694                }
20695            }
20696            i += 1;
20697        }
20698        Some(GroundedTuple::new(coords))
20699    }
20700}
20701
20702/// Foundation-canonical leaf-op interpreter. Called directly by
20703/// `GroundingProgram::run` for leaf primitives and step-by-step for
20704/// composition ops.
20705#[inline]
20706fn interpret_leaf_op(op: GroundingPrimitiveOp, external: &[u8]) -> Option<GroundedCoord> {
20707    match op {
20708        GroundingPrimitiveOp::ReadBytes | GroundingPrimitiveOp::InterpretLeInteger => {
20709            external.first().map(|&b| GroundedCoord::w8(b))
20710        }
20711        GroundingPrimitiveOp::InterpretBeInteger => external.last().map(|&b| GroundedCoord::w8(b)),
20712        GroundingPrimitiveOp::Digest => {
20713            // Foundation-canonical digest: first byte as `GroundedCoord` —
20714            // the full 32-byte digest requires a Datum<W256> sink that does
20715            // not fit in `GroundedCoord`. Downstream that needs the full
20716            // digest composes a richer program via Then/AndThen chains over
20717            // the 12 closed combinators — no `ground()` override exists after
20718            // W4 closure.
20719            external.first().map(|&b| GroundedCoord::w8(b))
20720        }
20721        GroundingPrimitiveOp::DecodeUtf8 => {
20722            // ASCII single-byte path — the canonical v0.2.2 semantics for
20723            // `Grounding::ground` over `GroundedCoord` outputs. Multi-byte
20724            // UTF-8 sequences are out of scope for w8-sized leaves; a richer
20725            // structured output composes via combinator chains into
20726            // `GroundedTuple<N>`.
20727            match external.first() {
20728                Some(&b) if b < 0x80 => Some(GroundedCoord::w8(b)),
20729                _ => None,
20730            }
20731        }
20732        GroundingPrimitiveOp::DecodeJson => {
20733            // Accept JSON number scalars (leading `-` or ASCII digit).
20734            match external.first() {
20735                Some(&b) if b == b'-' || b.is_ascii_digit() => Some(GroundedCoord::w8(b)),
20736                _ => None,
20737            }
20738        }
20739        GroundingPrimitiveOp::ConstValue => Some(GroundedCoord::w8(0)),
20740        GroundingPrimitiveOp::SelectField | GroundingPrimitiveOp::SelectIndex => {
20741            // Selector ops are composition-only in normal use; if invoked
20742            // directly, forward the first byte as a GroundedCoord.
20743            external.first().map(|&b| GroundedCoord::w8(b))
20744        }
20745        GroundingPrimitiveOp::Then
20746        | GroundingPrimitiveOp::AndThen
20747        | GroundingPrimitiveOp::MapErr => {
20748            // Composite ops are dispatched by `run()` through the chain;
20749            // they never reach the leaf interpreter.
20750            None
20751        }
20752    }
20753}
20754
20755/// v0.2.2 Phase J: MarkersImpliedBy impls for the closed catalogue of valid
20756/// (marker tuple, GroundingMapKind) pairs. These are the compile-time
20757/// witnesses the foundation accepts; every absent pair is a rejection.
20758impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker,) {}
20759impl MarkersImpliedBy<BinaryGroundingMap> for (TotalMarker, InvertibleMarker) {}
20760impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker, InvertibleMarker) {}
20761impl MarkersImpliedBy<BinaryGroundingMap>
20762    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20763{
20764}
20765impl MarkersImpliedBy<DigestGroundingMap>
20766    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20767{
20768}
20769impl MarkersImpliedBy<IntegerGroundingMap>
20770    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20771{
20772}
20773impl MarkersImpliedBy<JsonGroundingMap>
20774    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20775{
20776}
20777impl MarkersImpliedBy<Utf8GroundingMap>
20778    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20779{
20780}
20781impl MarkersImpliedBy<JsonGroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
20782impl MarkersImpliedBy<Utf8GroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
20783
20784/// v0.2.2 T2.5: foundation-private test-only back-door module.
20785/// Exposes crate-internal constructors for `Trace`, `TraceEvent`, and
20786/// `MulContext` to the `uor-foundation-test-helpers` workspace member, which
20787/// re-exports them under stable test-only names. Not part of the public API.
20788#[doc(hidden)]
20789pub mod __test_helpers {
20790    use super::{ContentAddress, ContentFingerprint, MulContext, Trace, TraceEvent, Validated};
20791
20792    /// Test-only ctor: build a Trace from a slice of events with a
20793    /// `ContentFingerprint::zero()` placeholder. Tests that need a non-zero
20794    /// fingerprint use `trace_with_fingerprint` instead. Parametric in
20795    /// `TR_MAX` per the wiki's ADR-018; callers pick the trace event-count
20796    /// ceiling from their selected `HostBounds`.
20797    #[must_use]
20798    pub fn trace_from_events<const TR_MAX: usize>(events: &[TraceEvent]) -> Trace<TR_MAX> {
20799        trace_with_fingerprint(events, 0, ContentFingerprint::zero())
20800    }
20801
20802    /// Test-only ctor that takes an explicit `witt_level_bits` and
20803    /// `ContentFingerprint`. Used by round-trip tests that need to verify
20804    /// the verify-trace fingerprint passthrough invariant.
20805    #[must_use]
20806    pub fn trace_with_fingerprint<const TR_MAX: usize>(
20807        events: &[TraceEvent],
20808        witt_level_bits: u16,
20809        content_fingerprint: ContentFingerprint,
20810    ) -> Trace<TR_MAX> {
20811        let mut arr = [None; TR_MAX];
20812        let n = events.len().min(TR_MAX);
20813        let mut i = 0;
20814        while i < n {
20815            arr[i] = Some(events[i]);
20816            i += 1;
20817        }
20818        // The test-helpers back-door uses the foundation-private
20819        // `from_replay_events_const` to build malformed fixtures for error-path
20820        // tests. Downstream code uses `Trace::try_from_events` (validating).
20821        Trace::from_replay_events_const(arr, n as u16, witt_level_bits, content_fingerprint)
20822    }
20823
20824    /// Test-only ctor: build a TraceEvent.
20825    #[must_use]
20826    pub fn trace_event(step_index: u32, target: u128) -> TraceEvent {
20827        TraceEvent::new(
20828            step_index,
20829            crate::PrimitiveOp::Add,
20830            ContentAddress::from_u128(target),
20831        )
20832    }
20833
20834    /// Test-only ctor: build a MulContext.
20835    #[must_use]
20836    pub fn mul_context(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> MulContext {
20837        MulContext::new(stack_budget_bytes, const_eval, limb_count)
20838    }
20839
20840    /// Test-only ctor: wrap any T in a Runtime-phase Validated. Used by
20841    /// integration tests to construct `Validated<Decl, P>` values that
20842    /// the public API otherwise can't construct directly.
20843    #[must_use]
20844    pub fn validated_runtime<T>(inner: T) -> Validated<T> {
20845        Validated::new(inner)
20846    }
20847}
20848
20849/// Tolerance for entropy equality checks in the Product/Coproduct
20850/// Completion Amendment mint primitives. Returns an absolute-error bound
20851/// scaled to the magnitude of `expected`, so PT_4 / ST_2 / CPT_5
20852/// verifications are robust to floating-point rounding accumulated through
20853/// Künneth products and componentwise sums. The default-host (f64) backing
20854/// is hidden behind the `DefaultDecimal` alias so the function signature
20855/// reads as host-typed; downstream that swaps `H::Decimal` reaches the
20856/// same surface via the alias rebind.
20857type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
20858
20859#[inline]
20860const fn pc_entropy_tolerance(expected: DefaultDecimal) -> DefaultDecimal {
20861    let magnitude = if expected < 0.0 { -expected } else { expected };
20862    let scale = if magnitude > 1.0 { magnitude } else { 1.0 };
20863    1024.0 * <DefaultDecimal>::EPSILON * scale
20864}
20865
20866/// Validate an entropy value before participating in additivity checks.
20867/// Rejects NaN, ±∞, and negative values — the foundation's
20868/// `primitive_descent_metrics` produces `residual × LN_2` with
20869/// `residual: u32`, so valid entropies are non-negative finite Decimals.
20870#[inline]
20871fn pc_entropy_input_is_valid(value: DefaultDecimal) -> bool {
20872    value.is_finite() && value >= 0.0
20873}
20874
20875/// Check that `actual` matches `expected` within tolerance and that both
20876/// inputs are valid entropy values. Returns `false` if either input is
20877/// non-finite, negative, or differs from `expected` by more than
20878/// `pc_entropy_tolerance(expected)`.
20879#[inline]
20880fn pc_entropy_additivity_holds(actual: DefaultDecimal, expected: DefaultDecimal) -> bool {
20881    if !pc_entropy_input_is_valid(actual) || !pc_entropy_input_is_valid(expected) {
20882        return false;
20883    }
20884    let diff = actual - expected;
20885    let diff_abs = if diff < 0.0 { -diff } else { diff };
20886    diff_abs <= pc_entropy_tolerance(expected)
20887}
20888
20889/// Evidence bundle for `PartitionProductWitness`. Carries the PT_1 / PT_3 /
20890/// PT_4 input values used at mint time. Derives `PartialEq` only because
20891/// `f64` entropy fields exclude `Eq` / `Hash`; this is the auditing surface,
20892/// not a hash-map key.
20893#[derive(Debug, Clone, Copy, PartialEq)]
20894pub struct PartitionProductEvidence {
20895    /// Left operand `siteBudget` (data sites only, PT_1 input).
20896    pub left_site_budget: u16,
20897    /// Right operand `siteBudget`.
20898    pub right_site_budget: u16,
20899    /// Left operand `SITE_COUNT` (layout width, layout-invariant input).
20900    pub left_total_site_count: u16,
20901    /// Right operand `SITE_COUNT`.
20902    pub right_total_site_count: u16,
20903    /// Left operand Euler characteristic (PT_3 input).
20904    pub left_euler: i32,
20905    /// Right operand Euler characteristic.
20906    pub right_euler: i32,
20907    /// Left operand entropy in nats (PT_4 input).
20908    pub left_entropy_nats_bits: u64,
20909    /// Right operand entropy in nats.
20910    pub right_entropy_nats_bits: u64,
20911    /// Fingerprint of the source witness the evidence belongs to.
20912    pub source_witness_fingerprint: ContentFingerprint,
20913}
20914
20915/// Evidence bundle for `PartitionCoproductWitness`. Carries the
20916/// ST_1 / ST_2 / ST_9 / ST_10 input values used at mint time.
20917#[derive(Debug, Clone, Copy, PartialEq)]
20918pub struct PartitionCoproductEvidence {
20919    pub left_site_budget: u16,
20920    pub right_site_budget: u16,
20921    pub left_total_site_count: u16,
20922    pub right_total_site_count: u16,
20923    pub left_euler: i32,
20924    pub right_euler: i32,
20925    pub left_entropy_nats_bits: u64,
20926    pub right_entropy_nats_bits: u64,
20927    pub left_betti: [u32; MAX_BETTI_DIMENSION],
20928    pub right_betti: [u32; MAX_BETTI_DIMENSION],
20929    pub source_witness_fingerprint: ContentFingerprint,
20930}
20931
20932/// Evidence bundle for `CartesianProductWitness`. Carries the
20933/// CPT_1 / CPT_3 / CPT_4 / CPT_5 input values used at mint time, plus
20934/// `combined_entropy_nats` — the CartesianProductWitness itself does not
20935/// store entropy (see §1a), so the evidence sidecar preserves the
20936/// verification target value for re-audit.
20937#[derive(Debug, Clone, Copy, PartialEq)]
20938pub struct CartesianProductEvidence {
20939    pub left_site_budget: u16,
20940    pub right_site_budget: u16,
20941    pub left_total_site_count: u16,
20942    pub right_total_site_count: u16,
20943    pub left_euler: i32,
20944    pub right_euler: i32,
20945    pub left_betti: [u32; MAX_BETTI_DIMENSION],
20946    pub right_betti: [u32; MAX_BETTI_DIMENSION],
20947    pub left_entropy_nats_bits: u64,
20948    pub right_entropy_nats_bits: u64,
20949    pub combined_entropy_nats_bits: u64,
20950    pub source_witness_fingerprint: ContentFingerprint,
20951}
20952
20953/// Inputs to `PartitionProductWitness::mint_verified`. Mirrors the
20954/// underlying primitive's parameter list; each field is supplied by the
20955/// caller (typically a `product_shape!` macro expansion or a manual
20956/// construction following the amendment's Gap 2 pattern). Derives
20957/// `PartialEq` only because of the `f64` entropy fields.
20958#[derive(Debug, Clone, Copy, PartialEq)]
20959pub struct PartitionProductMintInputs {
20960    pub witt_bits: u16,
20961    pub left_fingerprint: ContentFingerprint,
20962    pub right_fingerprint: ContentFingerprint,
20963    pub left_site_budget: u16,
20964    pub right_site_budget: u16,
20965    pub left_total_site_count: u16,
20966    pub right_total_site_count: u16,
20967    pub left_euler: i32,
20968    pub right_euler: i32,
20969    pub left_entropy_nats_bits: u64,
20970    pub right_entropy_nats_bits: u64,
20971    pub combined_site_budget: u16,
20972    pub combined_site_count: u16,
20973    pub combined_euler: i32,
20974    pub combined_entropy_nats_bits: u64,
20975    pub combined_fingerprint: ContentFingerprint,
20976}
20977
20978/// Inputs to `PartitionCoproductWitness::mint_verified`. Adds three
20979/// structural fields beyond the other two MintInputs: the combined
20980/// constraint array, the boundary index between L and R regions, and the
20981/// tag site layout index. These feed `validate_coproduct_structure` at
20982/// mint time so ST_6 / ST_7 / ST_8 are verified numerically rather than
20983/// trusted from the caller.
20984/// Derives `Debug`, `Clone`, `Copy` only — no `PartialEq`. `ConstraintRef`
20985/// does not implement `PartialEq`, so deriving equality on a struct with a
20986/// `&[ConstraintRef]` field would not compile. MintInputs is not used as
20987/// an equality target in practice; downstream consumers compare the minted
20988/// witness (which derives `Eq` + `Hash`) instead.
20989#[derive(Debug, Clone, Copy)]
20990pub struct PartitionCoproductMintInputs {
20991    pub witt_bits: u16,
20992    pub left_fingerprint: ContentFingerprint,
20993    pub right_fingerprint: ContentFingerprint,
20994    pub left_site_budget: u16,
20995    pub right_site_budget: u16,
20996    pub left_total_site_count: u16,
20997    pub right_total_site_count: u16,
20998    pub left_euler: i32,
20999    pub right_euler: i32,
21000    pub left_entropy_nats_bits: u64,
21001    pub right_entropy_nats_bits: u64,
21002    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21003    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21004    pub combined_site_budget: u16,
21005    pub combined_site_count: u16,
21006    pub combined_euler: i32,
21007    pub combined_entropy_nats_bits: u64,
21008    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21009    pub combined_fingerprint: ContentFingerprint,
21010    pub combined_constraints: &'static [crate::pipeline::ConstraintRef],
21011    pub left_constraint_count: usize,
21012    pub tag_site: u16,
21013}
21014
21015/// Inputs to `CartesianProductWitness::mint_verified`. Matches the
21016/// CartesianProduct mint primitive's parameter list.
21017#[derive(Debug, Clone, Copy, PartialEq)]
21018pub struct CartesianProductMintInputs {
21019    pub witt_bits: u16,
21020    pub left_fingerprint: ContentFingerprint,
21021    pub right_fingerprint: ContentFingerprint,
21022    pub left_site_budget: u16,
21023    pub right_site_budget: u16,
21024    pub left_total_site_count: u16,
21025    pub right_total_site_count: u16,
21026    pub left_euler: i32,
21027    pub right_euler: i32,
21028    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21029    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21030    pub left_entropy_nats_bits: u64,
21031    pub right_entropy_nats_bits: u64,
21032    pub combined_site_budget: u16,
21033    pub combined_site_count: u16,
21034    pub combined_euler: i32,
21035    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21036    pub combined_entropy_nats_bits: u64,
21037    pub combined_fingerprint: ContentFingerprint,
21038}
21039
21040/// Sealed PartitionProduct witness — content-addressed assertion that a
21041/// partition decomposes as `PartitionProduct(left, right)` per PT_2a.
21042/// Minting is gated on PT_1, PT_3, PT_4, and the foundation
21043/// `ProductLayoutWidth` invariant being verified against component
21044/// shapes. Existence of an instance is the attestation — there is no
21045/// partial or unverified form.
21046#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21047pub struct PartitionProductWitness {
21048    witt_bits: u16,
21049    content_fingerprint: ContentFingerprint,
21050    left_fingerprint: ContentFingerprint,
21051    right_fingerprint: ContentFingerprint,
21052    combined_site_budget: u16,
21053    combined_site_count: u16,
21054}
21055
21056impl PartitionProductWitness {
21057    /// Witt level at which the witness was minted.
21058    #[inline]
21059    #[must_use]
21060    pub const fn witt_bits(&self) -> u16 {
21061        self.witt_bits
21062    }
21063    /// Content fingerprint of the combined (A × B) shape.
21064    #[inline]
21065    #[must_use]
21066    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21067        self.content_fingerprint
21068    }
21069    /// Content fingerprint of the left factor A.
21070    #[inline]
21071    #[must_use]
21072    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21073        self.left_fingerprint
21074    }
21075    /// Content fingerprint of the right factor B.
21076    #[inline]
21077    #[must_use]
21078    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21079        self.right_fingerprint
21080    }
21081    /// `siteBudget(A × B)` per PT_1.
21082    #[inline]
21083    #[must_use]
21084    pub const fn combined_site_budget(&self) -> u16 {
21085        self.combined_site_budget
21086    }
21087    /// `SITE_COUNT(A × B)` — the foundation layout width.
21088    #[inline]
21089    #[must_use]
21090    pub const fn combined_site_count(&self) -> u16 {
21091        self.combined_site_count
21092    }
21093    /// Crate-internal mint entry. Only the verified mint primitive may call this.
21094    #[inline]
21095    #[must_use]
21096    #[allow(clippy::too_many_arguments)]
21097    pub(crate) const fn with_level_fingerprints_and_sites(
21098        witt_bits: u16,
21099        content_fingerprint: ContentFingerprint,
21100        left_fingerprint: ContentFingerprint,
21101        right_fingerprint: ContentFingerprint,
21102        combined_site_budget: u16,
21103        combined_site_count: u16,
21104    ) -> Self {
21105        Self {
21106            witt_bits,
21107            content_fingerprint,
21108            left_fingerprint,
21109            right_fingerprint,
21110            combined_site_budget,
21111            combined_site_count,
21112        }
21113    }
21114}
21115
21116/// Sealed PartitionCoproduct witness — content-addressed assertion that a
21117/// partition decomposes as `PartitionCoproduct(left, right)` per PT_2b.
21118/// Minting verifies ST_1, ST_2, ST_6, ST_7, ST_8, ST_9, ST_10, the
21119/// foundation `CoproductLayoutWidth` invariant, and — for ST_6/ST_7/ST_8 —
21120/// walks the supplied constraint array through `validate_coproduct_structure`.
21121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21122pub struct PartitionCoproductWitness {
21123    witt_bits: u16,
21124    content_fingerprint: ContentFingerprint,
21125    left_fingerprint: ContentFingerprint,
21126    right_fingerprint: ContentFingerprint,
21127    combined_site_budget: u16,
21128    combined_site_count: u16,
21129    tag_site_index: u16,
21130}
21131
21132impl PartitionCoproductWitness {
21133    #[inline]
21134    #[must_use]
21135    pub const fn witt_bits(&self) -> u16 {
21136        self.witt_bits
21137    }
21138    #[inline]
21139    #[must_use]
21140    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21141        self.content_fingerprint
21142    }
21143    #[inline]
21144    #[must_use]
21145    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21146        self.left_fingerprint
21147    }
21148    #[inline]
21149    #[must_use]
21150    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21151        self.right_fingerprint
21152    }
21153    /// `siteBudget(A + B)` per ST_1 = max(siteBudget(A), siteBudget(B)).
21154    #[inline]
21155    #[must_use]
21156    pub const fn combined_site_budget(&self) -> u16 {
21157        self.combined_site_budget
21158    }
21159    /// `SITE_COUNT(A + B)` — the foundation layout width including the new tag site.
21160    #[inline]
21161    #[must_use]
21162    pub const fn combined_site_count(&self) -> u16 {
21163        self.combined_site_count
21164    }
21165    /// Index of the tag site in the layout convention of §4b'.
21166    /// Equals `max(SITE_COUNT(A), SITE_COUNT(B))`.
21167    #[inline]
21168    #[must_use]
21169    pub const fn tag_site_index(&self) -> u16 {
21170        self.tag_site_index
21171    }
21172    #[inline]
21173    #[must_use]
21174    #[allow(clippy::too_many_arguments)]
21175    pub(crate) const fn with_level_fingerprints_sites_and_tag(
21176        witt_bits: u16,
21177        content_fingerprint: ContentFingerprint,
21178        left_fingerprint: ContentFingerprint,
21179        right_fingerprint: ContentFingerprint,
21180        combined_site_budget: u16,
21181        combined_site_count: u16,
21182        tag_site_index: u16,
21183    ) -> Self {
21184        Self {
21185            witt_bits,
21186            content_fingerprint,
21187            left_fingerprint,
21188            right_fingerprint,
21189            combined_site_budget,
21190            combined_site_count,
21191            tag_site_index,
21192        }
21193    }
21194}
21195
21196/// Sealed CartesianPartitionProduct witness — content-addressed
21197/// assertion that a shape is `CartesianPartitionProduct(left, right)`
21198/// per CPT_2a. Minting verifies CPT_1, CPT_3, CPT_4, CPT_5, and the
21199/// foundation `CartesianLayoutWidth` invariant. The witness stores
21200/// a snapshot of the combined topological invariants (χ, Betti profile)
21201/// because the construction is axiomatic at the invariant level per §3c.
21202/// Entropy is not stored here (f64 has no Eq/Hash); use the paired
21203/// `CartesianProductEvidence` for entropy re-audit.
21204#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21205pub struct CartesianProductWitness {
21206    witt_bits: u16,
21207    content_fingerprint: ContentFingerprint,
21208    left_fingerprint: ContentFingerprint,
21209    right_fingerprint: ContentFingerprint,
21210    combined_site_budget: u16,
21211    combined_site_count: u16,
21212    combined_euler: i32,
21213    combined_betti: [u32; MAX_BETTI_DIMENSION],
21214}
21215
21216impl CartesianProductWitness {
21217    #[inline]
21218    #[must_use]
21219    pub const fn witt_bits(&self) -> u16 {
21220        self.witt_bits
21221    }
21222    #[inline]
21223    #[must_use]
21224    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21225        self.content_fingerprint
21226    }
21227    #[inline]
21228    #[must_use]
21229    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21230        self.left_fingerprint
21231    }
21232    #[inline]
21233    #[must_use]
21234    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21235        self.right_fingerprint
21236    }
21237    #[inline]
21238    #[must_use]
21239    pub const fn combined_site_budget(&self) -> u16 {
21240        self.combined_site_budget
21241    }
21242    #[inline]
21243    #[must_use]
21244    pub const fn combined_site_count(&self) -> u16 {
21245        self.combined_site_count
21246    }
21247    #[inline]
21248    #[must_use]
21249    pub const fn combined_euler(&self) -> i32 {
21250        self.combined_euler
21251    }
21252    #[inline]
21253    #[must_use]
21254    pub const fn combined_betti(&self) -> [u32; MAX_BETTI_DIMENSION] {
21255        self.combined_betti
21256    }
21257    #[inline]
21258    #[must_use]
21259    #[allow(clippy::too_many_arguments)]
21260    pub(crate) const fn with_level_fingerprints_and_invariants(
21261        witt_bits: u16,
21262        content_fingerprint: ContentFingerprint,
21263        left_fingerprint: ContentFingerprint,
21264        right_fingerprint: ContentFingerprint,
21265        combined_site_budget: u16,
21266        combined_site_count: u16,
21267        combined_euler: i32,
21268        combined_betti: [u32; MAX_BETTI_DIMENSION],
21269    ) -> Self {
21270        Self {
21271            witt_bits,
21272            content_fingerprint,
21273            left_fingerprint,
21274            right_fingerprint,
21275            combined_site_budget,
21276            combined_site_count,
21277            combined_euler,
21278            combined_betti,
21279        }
21280    }
21281}
21282
21283impl Certificate for PartitionProductWitness {
21284    const IRI: &'static str = "https://uor.foundation/partition/PartitionProduct";
21285    type Evidence = PartitionProductEvidence;
21286}
21287
21288impl Certificate for PartitionCoproductWitness {
21289    const IRI: &'static str = "https://uor.foundation/partition/PartitionCoproduct";
21290    type Evidence = PartitionCoproductEvidence;
21291}
21292
21293impl Certificate for CartesianProductWitness {
21294    const IRI: &'static str = "https://uor.foundation/partition/CartesianPartitionProduct";
21295    type Evidence = CartesianProductEvidence;
21296}
21297
21298impl core::fmt::Display for PartitionProductWitness {
21299    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21300        f.write_str("PartitionProductWitness")
21301    }
21302}
21303impl core::error::Error for PartitionProductWitness {}
21304
21305impl core::fmt::Display for PartitionCoproductWitness {
21306    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21307        f.write_str("PartitionCoproductWitness")
21308    }
21309}
21310impl core::error::Error for PartitionCoproductWitness {}
21311
21312impl core::fmt::Display for CartesianProductWitness {
21313    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21314        f.write_str("CartesianProductWitness")
21315    }
21316}
21317impl core::error::Error for CartesianProductWitness {}
21318
21319/// Sealed mint path for certificates that require multi-theorem verification
21320/// before minting. Introduced by the Product/Coproduct Completion Amendment
21321/// §1c; distinct from `MintWithLevelFingerprint` (which is the generic
21322/// partial-mint path for sealed shims). `VerifiedMint` implementors are
21323/// the three partition-algebra witnesses, each routing through a
21324/// foundation-internal mint primitive that verifies the relevant theorems.
21325/// The trait is public so external callers can invoke `mint_verified`
21326/// directly, but the `Certificate` supertrait's `certificate_sealed::Sealed`
21327/// bound keeps the implementor set closed to this crate.
21328pub trait VerifiedMint: Certificate {
21329    /// Caller-supplied input bundle — one `*MintInputs` struct per witness.
21330    type Inputs;
21331    /// Failure kind — always `GenericImpossibilityWitness` citing the
21332    /// specific op-namespace theorem or foundation-namespace layout
21333    /// invariant that was violated.
21334    type Error;
21335    /// Verify the theorems and invariants against `inputs`, then mint a
21336    /// witness or return a typed impossibility witness.
21337    /// # Errors
21338    /// Returns a `GenericImpossibilityWitness::for_identity(iri)` when any
21339    /// of the gated theorems or foundation invariants fails. The IRI
21340    /// identifies exactly which identity failed — `op/PT_*`, `op/ST_*`,
21341    /// `op/CPT_*`, or `foundation/*LayoutWidth` / `foundation/CoproductTagEncoding`.
21342    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error>
21343    where
21344        Self: Sized;
21345}
21346
21347/// Recursive classifier used by `validate_coproduct_structure`. Inspects
21348/// one `ConstraintRef`, tallies tag-pinner sightings via mutable references,
21349/// and recurses into `Conjunction` conjuncts up to `max_depth` levels. See
21350/// plan §A4 for the depth bound rationale.
21351#[allow(clippy::too_many_arguments)]
21352fn pc_classify_constraint(
21353    c: &crate::pipeline::ConstraintRef,
21354    in_left_region: bool,
21355    tag_site: u16,
21356    max_depth: u32,
21357    left_pins: &mut u32,
21358    right_pins: &mut u32,
21359    left_bias_ok: &mut bool,
21360    right_bias_ok: &mut bool,
21361) -> Result<(), GenericImpossibilityWitness> {
21362    match c {
21363        crate::pipeline::ConstraintRef::Site { position } => {
21364            if (*position as u16) >= tag_site {
21365                return Err(GenericImpossibilityWitness::for_identity(
21366                    "https://uor.foundation/op/ST_6",
21367                ));
21368            }
21369        }
21370        crate::pipeline::ConstraintRef::Carry { site } => {
21371            if (*site as u16) >= tag_site {
21372                return Err(GenericImpossibilityWitness::for_identity(
21373                    "https://uor.foundation/op/ST_6",
21374                ));
21375            }
21376        }
21377        crate::pipeline::ConstraintRef::Affine { coefficients, coefficient_count, bias } => {
21378            let count = *coefficient_count as usize;
21379            let mut nonzero_count: u32 = 0;
21380            let mut nonzero_index: usize = 0;
21381            let mut max_nonzero_index: usize = 0;
21382            let mut i: usize = 0;
21383            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
21384                if coefficients[i] != 0 {
21385                    nonzero_count = nonzero_count.saturating_add(1);
21386                    nonzero_index = i;
21387                    if i > max_nonzero_index { max_nonzero_index = i; }
21388                }
21389                i += 1;
21390            }
21391            let touches_tag_site = nonzero_count > 0
21392                && (max_nonzero_index as u16) >= tag_site;
21393            let is_canonical_tag_pinner = nonzero_count == 1
21394                && (nonzero_index as u16) == tag_site
21395                && coefficients[nonzero_index] == 1;
21396            if is_canonical_tag_pinner {
21397                if *bias != 0 && *bias != -1 {
21398                    return Err(GenericImpossibilityWitness::for_identity(
21399                        "https://uor.foundation/foundation/CoproductTagEncoding",
21400                    ));
21401                }
21402                if in_left_region {
21403                    *left_pins = left_pins.saturating_add(1);
21404                    if *bias != 0 { *left_bias_ok = false; }
21405                } else {
21406                    *right_pins = right_pins.saturating_add(1);
21407                    if *bias != -1 { *right_bias_ok = false; }
21408                }
21409            } else if touches_tag_site {
21410                let nonzero_only_at_tag_site = nonzero_count == 1
21411                    && (nonzero_index as u16) == tag_site;
21412                if nonzero_only_at_tag_site {
21413                    return Err(GenericImpossibilityWitness::for_identity(
21414                        "https://uor.foundation/foundation/CoproductTagEncoding",
21415                    ));
21416                } else {
21417                    return Err(GenericImpossibilityWitness::for_identity(
21418                        "https://uor.foundation/op/ST_6",
21419                    ));
21420                }
21421            }
21422        }
21423        crate::pipeline::ConstraintRef::Conjunction { conjuncts, conjunct_count } => {
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        // ADR-057: Recurse references a shape by content-addressed IRI;
21452        // no site references at this level to check.
21453        | crate::pipeline::ConstraintRef::Recurse { .. } => {
21454            // No site references at this level; nothing to check.
21455        }
21456    }
21457    Ok(())
21458}
21459
21460/// Validates ST_6 / ST_7 / ST_8 for a PartitionCoproduct construction by
21461/// walking the emitted constraint array. Recurses into
21462/// `ConstraintRef::Conjunction` conjuncts up to depth 8 (bounded by
21463/// `NERVE_CONSTRAINTS_CAP`) so nested constructions are audited without
21464/// unbounded recursion.
21465/// # Errors
21466/// Returns `GenericImpossibilityWitness::for_identity(...)` citing the
21467/// specific failed identity: `op/ST_6`, `op/ST_7`, or
21468/// `foundation/CoproductTagEncoding`. ST_8 is implied by ST_6 ∧ ST_7 and
21469/// is not cited separately on failure.
21470pub(crate) fn validate_coproduct_structure(
21471    combined_constraints: &[crate::pipeline::ConstraintRef],
21472    left_constraint_count: usize,
21473    tag_site: u16,
21474) -> Result<(), GenericImpossibilityWitness> {
21475    let mut left_pins: u32 = 0;
21476    let mut right_pins: u32 = 0;
21477    let mut left_bias_ok: bool = true;
21478    let mut right_bias_ok: bool = true;
21479    let mut idx: usize = 0;
21480    while idx < combined_constraints.len() {
21481        let in_left_region = idx < left_constraint_count;
21482        pc_classify_constraint(
21483            &combined_constraints[idx],
21484            in_left_region,
21485            tag_site,
21486            NERVE_CONSTRAINTS_CAP as u32,
21487            &mut left_pins,
21488            &mut right_pins,
21489            &mut left_bias_ok,
21490            &mut right_bias_ok,
21491        )?;
21492        idx += 1;
21493    }
21494    if left_pins != 1 || right_pins != 1 {
21495        return Err(GenericImpossibilityWitness::for_identity(
21496            "https://uor.foundation/op/ST_6",
21497        ));
21498    }
21499    if !left_bias_ok || !right_bias_ok {
21500        return Err(GenericImpossibilityWitness::for_identity(
21501            "https://uor.foundation/op/ST_7",
21502        ));
21503    }
21504    Ok(())
21505}
21506
21507/// Mint a `PartitionProductWitness` after verifying PT_1, PT_3, PT_4, and
21508/// the `ProductLayoutWidth` layout invariant. PT_2a is structural (the
21509/// witness existing is the claim); no separate check is needed once the
21510/// invariants match.
21511#[allow(clippy::too_many_arguments)]
21512pub(crate) fn pc_primitive_partition_product(
21513    witt_bits: u16,
21514    left_fingerprint: ContentFingerprint,
21515    right_fingerprint: ContentFingerprint,
21516    left_site_budget: u16,
21517    right_site_budget: u16,
21518    left_total_site_count: u16,
21519    right_total_site_count: u16,
21520    left_euler: i32,
21521    right_euler: i32,
21522    left_entropy_nats_bits: u64,
21523    right_entropy_nats_bits: u64,
21524    combined_site_budget: u16,
21525    combined_site_count: u16,
21526    combined_euler: i32,
21527    combined_entropy_nats_bits: u64,
21528    combined_fingerprint: ContentFingerprint,
21529) -> Result<PartitionProductWitness, GenericImpossibilityWitness> {
21530    let left_entropy_nats =
21531        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21532    let right_entropy_nats =
21533        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21534    let combined_entropy_nats =
21535        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21536    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21537        return Err(GenericImpossibilityWitness::for_identity(
21538            "https://uor.foundation/op/PT_1",
21539        ));
21540    }
21541    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21542        return Err(GenericImpossibilityWitness::for_identity(
21543            "https://uor.foundation/foundation/ProductLayoutWidth",
21544        ));
21545    }
21546    if combined_euler != left_euler.saturating_add(right_euler) {
21547        return Err(GenericImpossibilityWitness::for_identity(
21548            "https://uor.foundation/op/PT_3",
21549        ));
21550    }
21551    if !pc_entropy_input_is_valid(left_entropy_nats)
21552        || !pc_entropy_input_is_valid(right_entropy_nats)
21553        || !pc_entropy_input_is_valid(combined_entropy_nats)
21554    {
21555        return Err(GenericImpossibilityWitness::for_identity(
21556            "https://uor.foundation/op/PT_4",
21557        ));
21558    }
21559    let expected_entropy = left_entropy_nats + right_entropy_nats;
21560    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21561        return Err(GenericImpossibilityWitness::for_identity(
21562            "https://uor.foundation/op/PT_4",
21563        ));
21564    }
21565    Ok(PartitionProductWitness::with_level_fingerprints_and_sites(
21566        witt_bits,
21567        combined_fingerprint,
21568        left_fingerprint,
21569        right_fingerprint,
21570        combined_site_budget,
21571        combined_site_count,
21572    ))
21573}
21574
21575/// Mint a `PartitionCoproductWitness` after verifying ST_1, ST_2, ST_6,
21576/// ST_7, ST_8, ST_9, ST_10, the `CoproductLayoutWidth` layout invariant,
21577/// the tag-site alignment against §4b', and running
21578/// `validate_coproduct_structure` over the supplied constraint array.
21579#[allow(clippy::too_many_arguments)]
21580pub(crate) fn pc_primitive_partition_coproduct(
21581    witt_bits: u16,
21582    left_fingerprint: ContentFingerprint,
21583    right_fingerprint: ContentFingerprint,
21584    left_site_budget: u16,
21585    right_site_budget: u16,
21586    left_total_site_count: u16,
21587    right_total_site_count: u16,
21588    left_euler: i32,
21589    right_euler: i32,
21590    left_entropy_nats_bits: u64,
21591    right_entropy_nats_bits: u64,
21592    left_betti: [u32; MAX_BETTI_DIMENSION],
21593    right_betti: [u32; MAX_BETTI_DIMENSION],
21594    combined_site_budget: u16,
21595    combined_site_count: u16,
21596    combined_euler: i32,
21597    combined_entropy_nats_bits: u64,
21598    combined_betti: [u32; MAX_BETTI_DIMENSION],
21599    combined_fingerprint: ContentFingerprint,
21600    combined_constraints: &[crate::pipeline::ConstraintRef],
21601    left_constraint_count: usize,
21602    tag_site: u16,
21603) -> Result<PartitionCoproductWitness, GenericImpossibilityWitness> {
21604    let left_entropy_nats =
21605        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21606    let right_entropy_nats =
21607        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21608    let combined_entropy_nats =
21609        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21610    let expected_budget = if left_site_budget > right_site_budget {
21611        left_site_budget
21612    } else {
21613        right_site_budget
21614    };
21615    if combined_site_budget != expected_budget {
21616        return Err(GenericImpossibilityWitness::for_identity(
21617            "https://uor.foundation/op/ST_1",
21618        ));
21619    }
21620    let max_total = if left_total_site_count > right_total_site_count {
21621        left_total_site_count
21622    } else {
21623        right_total_site_count
21624    };
21625    let expected_total = max_total.saturating_add(1);
21626    if combined_site_count != expected_total {
21627        return Err(GenericImpossibilityWitness::for_identity(
21628            "https://uor.foundation/foundation/CoproductLayoutWidth",
21629        ));
21630    }
21631    if !pc_entropy_input_is_valid(left_entropy_nats)
21632        || !pc_entropy_input_is_valid(right_entropy_nats)
21633        || !pc_entropy_input_is_valid(combined_entropy_nats)
21634    {
21635        return Err(GenericImpossibilityWitness::for_identity(
21636            "https://uor.foundation/op/ST_2",
21637        ));
21638    }
21639    let max_operand_entropy = if left_entropy_nats > right_entropy_nats {
21640        left_entropy_nats
21641    } else {
21642        right_entropy_nats
21643    };
21644    let expected_entropy = core::f64::consts::LN_2 + max_operand_entropy;
21645    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21646        return Err(GenericImpossibilityWitness::for_identity(
21647            "https://uor.foundation/op/ST_2",
21648        ));
21649    }
21650    if tag_site != max_total {
21651        return Err(GenericImpossibilityWitness::for_identity(
21652            "https://uor.foundation/foundation/CoproductLayoutWidth",
21653        ));
21654    }
21655    validate_coproduct_structure(combined_constraints, left_constraint_count, tag_site)?;
21656    if combined_euler != left_euler.saturating_add(right_euler) {
21657        return Err(GenericImpossibilityWitness::for_identity(
21658            "https://uor.foundation/op/ST_9",
21659        ));
21660    }
21661    let mut k: usize = 0;
21662    while k < MAX_BETTI_DIMENSION {
21663        if combined_betti[k] != left_betti[k].saturating_add(right_betti[k]) {
21664            return Err(GenericImpossibilityWitness::for_identity(
21665                "https://uor.foundation/op/ST_10",
21666            ));
21667        }
21668        k += 1;
21669    }
21670    Ok(
21671        PartitionCoproductWitness::with_level_fingerprints_sites_and_tag(
21672            witt_bits,
21673            combined_fingerprint,
21674            left_fingerprint,
21675            right_fingerprint,
21676            combined_site_budget,
21677            combined_site_count,
21678            max_total,
21679        ),
21680    )
21681}
21682
21683/// Mint a `CartesianProductWitness` after verifying CPT_1, CPT_3, CPT_4,
21684/// CPT_5, and the `CartesianLayoutWidth` layout invariant. Checks
21685/// caller-supplied Künneth-composed invariants against the component
21686/// values (the witness defines these axiomatically per §3c).
21687#[allow(clippy::too_many_arguments)]
21688pub(crate) fn pc_primitive_cartesian_product(
21689    witt_bits: u16,
21690    left_fingerprint: ContentFingerprint,
21691    right_fingerprint: ContentFingerprint,
21692    left_site_budget: u16,
21693    right_site_budget: u16,
21694    left_total_site_count: u16,
21695    right_total_site_count: u16,
21696    left_euler: i32,
21697    right_euler: i32,
21698    left_betti: [u32; MAX_BETTI_DIMENSION],
21699    right_betti: [u32; MAX_BETTI_DIMENSION],
21700    left_entropy_nats_bits: u64,
21701    right_entropy_nats_bits: u64,
21702    combined_site_budget: u16,
21703    combined_site_count: u16,
21704    combined_euler: i32,
21705    combined_betti: [u32; MAX_BETTI_DIMENSION],
21706    combined_entropy_nats_bits: u64,
21707    combined_fingerprint: ContentFingerprint,
21708) -> Result<CartesianProductWitness, GenericImpossibilityWitness> {
21709    let left_entropy_nats =
21710        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21711    let right_entropy_nats =
21712        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21713    let combined_entropy_nats =
21714        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21715    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21716        return Err(GenericImpossibilityWitness::for_identity(
21717            "https://uor.foundation/op/CPT_1",
21718        ));
21719    }
21720    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21721        return Err(GenericImpossibilityWitness::for_identity(
21722            "https://uor.foundation/foundation/CartesianLayoutWidth",
21723        ));
21724    }
21725    if combined_euler != left_euler.saturating_mul(right_euler) {
21726        return Err(GenericImpossibilityWitness::for_identity(
21727            "https://uor.foundation/op/CPT_3",
21728        ));
21729    }
21730    let kunneth = crate::pipeline::kunneth_compose(&left_betti, &right_betti);
21731    let mut k: usize = 0;
21732    while k < MAX_BETTI_DIMENSION {
21733        if combined_betti[k] != kunneth[k] {
21734            return Err(GenericImpossibilityWitness::for_identity(
21735                "https://uor.foundation/op/CPT_4",
21736            ));
21737        }
21738        k += 1;
21739    }
21740    if !pc_entropy_input_is_valid(left_entropy_nats)
21741        || !pc_entropy_input_is_valid(right_entropy_nats)
21742        || !pc_entropy_input_is_valid(combined_entropy_nats)
21743    {
21744        return Err(GenericImpossibilityWitness::for_identity(
21745            "https://uor.foundation/op/CPT_5",
21746        ));
21747    }
21748    let expected_entropy = left_entropy_nats + right_entropy_nats;
21749    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21750        return Err(GenericImpossibilityWitness::for_identity(
21751            "https://uor.foundation/op/CPT_5",
21752        ));
21753    }
21754    Ok(
21755        CartesianProductWitness::with_level_fingerprints_and_invariants(
21756            witt_bits,
21757            combined_fingerprint,
21758            left_fingerprint,
21759            right_fingerprint,
21760            combined_site_budget,
21761            combined_site_count,
21762            combined_euler,
21763            combined_betti,
21764        ),
21765    )
21766}
21767
21768impl VerifiedMint for PartitionProductWitness {
21769    type Inputs = PartitionProductMintInputs;
21770    type Error = GenericImpossibilityWitness;
21771    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21772        pc_primitive_partition_product(
21773            inputs.witt_bits,
21774            inputs.left_fingerprint,
21775            inputs.right_fingerprint,
21776            inputs.left_site_budget,
21777            inputs.right_site_budget,
21778            inputs.left_total_site_count,
21779            inputs.right_total_site_count,
21780            inputs.left_euler,
21781            inputs.right_euler,
21782            inputs.left_entropy_nats_bits,
21783            inputs.right_entropy_nats_bits,
21784            inputs.combined_site_budget,
21785            inputs.combined_site_count,
21786            inputs.combined_euler,
21787            inputs.combined_entropy_nats_bits,
21788            inputs.combined_fingerprint,
21789        )
21790    }
21791}
21792
21793impl VerifiedMint for PartitionCoproductWitness {
21794    type Inputs = PartitionCoproductMintInputs;
21795    type Error = GenericImpossibilityWitness;
21796    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21797        pc_primitive_partition_coproduct(
21798            inputs.witt_bits,
21799            inputs.left_fingerprint,
21800            inputs.right_fingerprint,
21801            inputs.left_site_budget,
21802            inputs.right_site_budget,
21803            inputs.left_total_site_count,
21804            inputs.right_total_site_count,
21805            inputs.left_euler,
21806            inputs.right_euler,
21807            inputs.left_entropy_nats_bits,
21808            inputs.right_entropy_nats_bits,
21809            inputs.left_betti,
21810            inputs.right_betti,
21811            inputs.combined_site_budget,
21812            inputs.combined_site_count,
21813            inputs.combined_euler,
21814            inputs.combined_entropy_nats_bits,
21815            inputs.combined_betti,
21816            inputs.combined_fingerprint,
21817            inputs.combined_constraints,
21818            inputs.left_constraint_count,
21819            inputs.tag_site,
21820        )
21821    }
21822}
21823
21824impl VerifiedMint for CartesianProductWitness {
21825    type Inputs = CartesianProductMintInputs;
21826    type Error = GenericImpossibilityWitness;
21827    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21828        pc_primitive_cartesian_product(
21829            inputs.witt_bits,
21830            inputs.left_fingerprint,
21831            inputs.right_fingerprint,
21832            inputs.left_site_budget,
21833            inputs.right_site_budget,
21834            inputs.left_total_site_count,
21835            inputs.right_total_site_count,
21836            inputs.left_euler,
21837            inputs.right_euler,
21838            inputs.left_betti,
21839            inputs.right_betti,
21840            inputs.left_entropy_nats_bits,
21841            inputs.right_entropy_nats_bits,
21842            inputs.combined_site_budget,
21843            inputs.combined_site_count,
21844            inputs.combined_euler,
21845            inputs.combined_betti,
21846            inputs.combined_entropy_nats_bits,
21847            inputs.combined_fingerprint,
21848        )
21849    }
21850}
21851
21852/// Data record of a partition's runtime-queried properties. Produced at
21853/// witness-mint time and consulted by consumer code that holds a
21854/// `PartitionHandle` and a `PartitionResolver`. Phase 9 stores entropy
21855/// as the IEEE-754 `u64` bit-pattern (`entropy_nats_bits`) so the record
21856/// derives `Eq + Hash` cleanly; consumers project to `H::Decimal` via
21857/// `<H::Decimal as DecimalTranscendental>::from_bits`.
21858#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21859pub struct PartitionRecord<H: crate::HostTypes> {
21860    /// Data sites only — the partition's `siteBudget`, not its layout width.
21861    pub site_budget: u16,
21862    /// Euler characteristic of the partition's nerve.
21863    pub euler: i32,
21864    /// Betti profile of the partition's nerve, padded to `MAX_BETTI_DIMENSION`.
21865    pub betti: [u32; MAX_BETTI_DIMENSION],
21866    /// Shannon entropy in nats (matches `LandauerBudget::nats()` convention).
21867    pub entropy_nats_bits: u64,
21868    _phantom: core::marker::PhantomData<H>,
21869}
21870
21871impl<H: crate::HostTypes> PartitionRecord<H> {
21872    /// Construct a new record. The phantom marker ensures records are
21873    /// parameterized by the host types they originate from.
21874    #[inline]
21875    #[must_use]
21876    pub const fn new(
21877        site_budget: u16,
21878        euler: i32,
21879        betti: [u32; MAX_BETTI_DIMENSION],
21880        entropy_nats_bits: u64,
21881    ) -> Self {
21882        Self {
21883            site_budget,
21884            euler,
21885            betti,
21886            entropy_nats_bits,
21887            _phantom: core::marker::PhantomData,
21888        }
21889    }
21890}
21891
21892/// Resolver mapping content fingerprints to `PartitionRecord`s. Provided
21893/// by the host application — typically a persistent store, an in-memory
21894/// registry populated from witness mint-time data, or a chain-of-witnesses
21895/// trail that can reconstruct properties.
21896pub trait PartitionResolver<H: crate::HostTypes> {
21897    /// Look up partition data by fingerprint. Returns `None` if the
21898    /// resolver has no record for the handle. Handles remain valid as
21899    /// identity tokens regardless of resolver presence.
21900    fn resolve(&self, fp: ContentFingerprint) -> Option<PartitionRecord<H>>;
21901}
21902
21903/// Content-addressed identity token for a partition. Carries only a
21904/// fingerprint; partition data is recovered by pairing the handle with a
21905/// `PartitionResolver` via `resolve_with`. Handles compare and hash by
21906/// fingerprint, so they can serve as keys in content-addressed indices
21907/// without resolver access.
21908#[derive(Debug)]
21909pub struct PartitionHandle<H: crate::HostTypes> {
21910    fingerprint: ContentFingerprint,
21911    _phantom: core::marker::PhantomData<H>,
21912}
21913impl<H: crate::HostTypes> Copy for PartitionHandle<H> {}
21914impl<H: crate::HostTypes> Clone for PartitionHandle<H> {
21915    #[inline]
21916    fn clone(&self) -> Self {
21917        *self
21918    }
21919}
21920impl<H: crate::HostTypes> PartialEq for PartitionHandle<H> {
21921    #[inline]
21922    fn eq(&self, other: &Self) -> bool {
21923        self.fingerprint == other.fingerprint
21924    }
21925}
21926impl<H: crate::HostTypes> Eq for PartitionHandle<H> {}
21927impl<H: crate::HostTypes> core::hash::Hash for PartitionHandle<H> {
21928    #[inline]
21929    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
21930        self.fingerprint.hash(state);
21931    }
21932}
21933
21934impl<H: crate::HostTypes> PartitionHandle<H> {
21935    /// Construct a handle from a content fingerprint.
21936    #[inline]
21937    #[must_use]
21938    pub const fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
21939        Self {
21940            fingerprint,
21941            _phantom: core::marker::PhantomData,
21942        }
21943    }
21944    /// Return the content fingerprint this handle references.
21945    #[inline]
21946    #[must_use]
21947    pub const fn fingerprint(&self) -> ContentFingerprint {
21948        self.fingerprint
21949    }
21950    /// Resolve this handle against a consumer-supplied resolver.
21951    /// Returns `None` if the resolver has no record for this fingerprint.
21952    #[inline]
21953    pub fn resolve_with<R: PartitionResolver<H>>(
21954        &self,
21955        resolver: &R,
21956    ) -> Option<PartitionRecord<H>> {
21957        resolver.resolve(self.fingerprint)
21958    }
21959}
21960
21961/// Resolver-absent default `Element<H>`. Returns empty defaults via the
21962/// `HostTypes::EMPTY_*` constants — used by `NullDatum<H>` and
21963/// `NullTypeDefinition<H>` to satisfy their `Element` associated types.
21964#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21965pub struct NullElement<H: HostTypes> {
21966    _phantom: core::marker::PhantomData<H>,
21967}
21968impl<H: HostTypes> Default for NullElement<H> {
21969    fn default() -> Self {
21970        Self {
21971            _phantom: core::marker::PhantomData,
21972        }
21973    }
21974}
21975impl<H: HostTypes> crate::kernel::address::Element<H> for NullElement<H> {
21976    fn length(&self) -> u64 {
21977        0
21978    }
21979    fn addresses(&self) -> &H::HostString {
21980        H::EMPTY_HOST_STRING
21981    }
21982    fn digest(&self) -> &H::HostString {
21983        H::EMPTY_HOST_STRING
21984    }
21985    fn digest_algorithm(&self) -> &H::HostString {
21986        H::EMPTY_HOST_STRING
21987    }
21988    fn canonical_bytes(&self) -> &H::WitnessBytes {
21989        H::EMPTY_WITNESS_BYTES
21990    }
21991    fn witt_length(&self) -> u64 {
21992        0
21993    }
21994}
21995
21996/// Resolver-absent default `Datum<H>`. All numeric methods return 0.
21997#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21998pub struct NullDatum<H: HostTypes> {
21999    element: NullElement<H>,
22000    _phantom: core::marker::PhantomData<H>,
22001}
22002impl<H: HostTypes> Default for NullDatum<H> {
22003    fn default() -> Self {
22004        Self {
22005            element: NullElement::default(),
22006            _phantom: core::marker::PhantomData,
22007        }
22008    }
22009}
22010impl<H: HostTypes> crate::kernel::schema::Datum<H> for NullDatum<H> {
22011    fn value(&self) -> u64 {
22012        0
22013    }
22014    fn witt_length(&self) -> u64 {
22015        0
22016    }
22017    fn stratum(&self) -> u64 {
22018        0
22019    }
22020    fn spectrum(&self) -> u64 {
22021        0
22022    }
22023    type Element = NullElement<H>;
22024    fn element(&self) -> &Self::Element {
22025        &self.element
22026    }
22027}
22028
22029/// Resolver-absent default `TermExpression<H>`. Empty marker trait, no methods.
22030#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22031pub struct NullTermExpression<H: HostTypes> {
22032    _phantom: core::marker::PhantomData<H>,
22033}
22034impl<H: HostTypes> Default for NullTermExpression<H> {
22035    fn default() -> Self {
22036        Self {
22037            _phantom: core::marker::PhantomData,
22038        }
22039    }
22040}
22041impl<H: HostTypes> crate::kernel::schema::TermExpression<H> for NullTermExpression<H> {}
22042
22043/// Resolver-absent default `SiteIndex<H>`. Self-recursive: `ancilla_site()`
22044/// returns `&self` (no ancilla pairing in the default).
22045#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22046pub struct NullSiteIndex<H: HostTypes> {
22047    _phantom: core::marker::PhantomData<H>,
22048}
22049impl<H: HostTypes> Default for NullSiteIndex<H> {
22050    fn default() -> Self {
22051        Self {
22052            _phantom: core::marker::PhantomData,
22053        }
22054    }
22055}
22056impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullSiteIndex<H> {
22057    fn site_position(&self) -> u64 {
22058        0
22059    }
22060    fn site_state(&self) -> u64 {
22061        0
22062    }
22063    type SiteIndexTarget = NullSiteIndex<H>;
22064    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22065        self
22066    }
22067}
22068
22069/// Resolver-absent default `TagSite<H>`. Embeds an inline `NullSiteIndex`
22070/// field so the inherited `ancilla_site()` accessor returns a valid
22071/// reference; `tag_value()` returns false.
22072#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22073pub struct NullTagSite<H: HostTypes> {
22074    ancilla: NullSiteIndex<H>,
22075}
22076impl<H: HostTypes> Default for NullTagSite<H> {
22077    fn default() -> Self {
22078        Self {
22079            ancilla: NullSiteIndex::default(),
22080        }
22081    }
22082}
22083impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullTagSite<H> {
22084    fn site_position(&self) -> u64 {
22085        0
22086    }
22087    fn site_state(&self) -> u64 {
22088        0
22089    }
22090    type SiteIndexTarget = NullSiteIndex<H>;
22091    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22092        &self.ancilla
22093    }
22094}
22095impl<H: HostTypes> crate::bridge::partition::TagSite<H> for NullTagSite<H> {
22096    fn tag_value(&self) -> bool {
22097        false
22098    }
22099}
22100
22101/// Resolver-absent default `SiteBinding<H>`. Embeds inline `NullConstraint`
22102/// and `NullSiteIndex` so the trait's reference accessors work via &self.field.
22103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22104pub struct NullSiteBinding<H: HostTypes> {
22105    constraint: NullConstraint<H>,
22106    site_index: NullSiteIndex<H>,
22107}
22108impl<H: HostTypes> Default for NullSiteBinding<H> {
22109    fn default() -> Self {
22110        Self {
22111            constraint: NullConstraint::default(),
22112            site_index: NullSiteIndex::default(),
22113        }
22114    }
22115}
22116impl<H: HostTypes> crate::bridge::partition::SiteBinding<H> for NullSiteBinding<H> {
22117    type Constraint = NullConstraint<H>;
22118    fn pinned_by(&self) -> &Self::Constraint {
22119        &self.constraint
22120    }
22121    type SiteIndex = NullSiteIndex<H>;
22122    fn pins_coordinate(&self) -> &Self::SiteIndex {
22123        &self.site_index
22124    }
22125}
22126
22127/// Resolver-absent default `Constraint<H>`. Returns Vertical metric axis,
22128/// empty pinned-sites slice, and zero crossing cost.
22129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22130pub struct NullConstraint<H: HostTypes> {
22131    _phantom: core::marker::PhantomData<H>,
22132}
22133impl<H: HostTypes> Default for NullConstraint<H> {
22134    fn default() -> Self {
22135        Self {
22136            _phantom: core::marker::PhantomData,
22137        }
22138    }
22139}
22140impl<H: HostTypes> crate::user::type_::Constraint<H> for NullConstraint<H> {
22141    fn metric_axis(&self) -> MetricAxis {
22142        MetricAxis::Vertical
22143    }
22144    type SiteIndex = NullSiteIndex<H>;
22145    fn pins_sites(&self) -> &[Self::SiteIndex] {
22146        &[]
22147    }
22148    fn crossing_cost(&self) -> u64 {
22149        0
22150    }
22151}
22152
22153/// Resolver-absent default `FreeRank<H>`. Empty budget — `is_closed()` true,
22154/// zero counts. Empty `has_site` / `has_binding` slices.
22155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22156pub struct NullFreeRank<H: HostTypes> {
22157    _phantom: core::marker::PhantomData<H>,
22158}
22159impl<H: HostTypes> Default for NullFreeRank<H> {
22160    fn default() -> Self {
22161        Self {
22162            _phantom: core::marker::PhantomData,
22163        }
22164    }
22165}
22166impl<H: HostTypes> crate::bridge::partition::FreeRank<H> for NullFreeRank<H> {
22167    fn total_sites(&self) -> u64 {
22168        0
22169    }
22170    fn pinned_count(&self) -> u64 {
22171        0
22172    }
22173    fn free_rank(&self) -> u64 {
22174        0
22175    }
22176    fn is_closed(&self) -> bool {
22177        true
22178    }
22179    type SiteIndex = NullSiteIndex<H>;
22180    fn has_site(&self) -> &[Self::SiteIndex] {
22181        &[]
22182    }
22183    type SiteBinding = NullSiteBinding<H>;
22184    fn has_binding(&self) -> &[Self::SiteBinding] {
22185        &[]
22186    }
22187    fn reversible_strategy(&self) -> bool {
22188        false
22189    }
22190}
22191
22192/// Resolver-absent default `IrreducibleSet<H>`. Implements `Component<H>` with empty
22193/// `member` slice and zero `cardinality`.
22194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22195pub struct NullIrreducibleSet<H: HostTypes> {
22196    _phantom: core::marker::PhantomData<H>,
22197}
22198impl<H: HostTypes> Default for NullIrreducibleSet<H> {
22199    fn default() -> Self {
22200        Self {
22201            _phantom: core::marker::PhantomData,
22202        }
22203    }
22204}
22205impl<H: HostTypes> crate::bridge::partition::Component<H> for NullIrreducibleSet<H> {
22206    type Datum = NullDatum<H>;
22207    fn member(&self) -> &[Self::Datum] {
22208        &[]
22209    }
22210    fn cardinality(&self) -> u64 {
22211        0
22212    }
22213}
22214impl<H: HostTypes> crate::bridge::partition::IrreducibleSet<H> for NullIrreducibleSet<H> {}
22215
22216/// Resolver-absent default `ReducibleSet<H>`. Implements `Component<H>` with empty
22217/// `member` slice and zero `cardinality`.
22218#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22219pub struct NullReducibleSet<H: HostTypes> {
22220    _phantom: core::marker::PhantomData<H>,
22221}
22222impl<H: HostTypes> Default for NullReducibleSet<H> {
22223    fn default() -> Self {
22224        Self {
22225            _phantom: core::marker::PhantomData,
22226        }
22227    }
22228}
22229impl<H: HostTypes> crate::bridge::partition::Component<H> for NullReducibleSet<H> {
22230    type Datum = NullDatum<H>;
22231    fn member(&self) -> &[Self::Datum] {
22232        &[]
22233    }
22234    fn cardinality(&self) -> u64 {
22235        0
22236    }
22237}
22238impl<H: HostTypes> crate::bridge::partition::ReducibleSet<H> for NullReducibleSet<H> {}
22239
22240/// Resolver-absent default `UnitGroup<H>`. Implements `Component<H>` with empty
22241/// `member` slice and zero `cardinality`.
22242#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22243pub struct NullUnitGroup<H: HostTypes> {
22244    _phantom: core::marker::PhantomData<H>,
22245}
22246impl<H: HostTypes> Default for NullUnitGroup<H> {
22247    fn default() -> Self {
22248        Self {
22249            _phantom: core::marker::PhantomData,
22250        }
22251    }
22252}
22253impl<H: HostTypes> crate::bridge::partition::Component<H> for NullUnitGroup<H> {
22254    type Datum = NullDatum<H>;
22255    fn member(&self) -> &[Self::Datum] {
22256        &[]
22257    }
22258    fn cardinality(&self) -> u64 {
22259        0
22260    }
22261}
22262impl<H: HostTypes> crate::bridge::partition::UnitGroup<H> for NullUnitGroup<H> {}
22263
22264/// Resolver-absent default `Complement<H>`. Implements `Component<H>` plus
22265/// the `exterior_criteria()` accessor returning a reference to an embedded
22266/// `NullTermExpression`.
22267#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22268pub struct NullComplement<H: HostTypes> {
22269    term: NullTermExpression<H>,
22270}
22271impl<H: HostTypes> Default for NullComplement<H> {
22272    fn default() -> Self {
22273        Self {
22274            term: NullTermExpression::default(),
22275        }
22276    }
22277}
22278impl<H: HostTypes> crate::bridge::partition::Component<H> for NullComplement<H> {
22279    type Datum = NullDatum<H>;
22280    fn member(&self) -> &[Self::Datum] {
22281        &[]
22282    }
22283    fn cardinality(&self) -> u64 {
22284        0
22285    }
22286}
22287impl<H: HostTypes> crate::bridge::partition::Complement<H> for NullComplement<H> {
22288    type TermExpression = NullTermExpression<H>;
22289    fn exterior_criteria(&self) -> &Self::TermExpression {
22290        &self.term
22291    }
22292}
22293
22294/// Resolver-absent default `TypeDefinition<H>`. Embeds inline `NullElement`
22295/// for the content_address accessor.
22296#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22297pub struct NullTypeDefinition<H: HostTypes> {
22298    element: NullElement<H>,
22299}
22300impl<H: HostTypes> Default for NullTypeDefinition<H> {
22301    fn default() -> Self {
22302        Self {
22303            element: NullElement::default(),
22304        }
22305    }
22306}
22307impl<H: HostTypes> crate::user::type_::TypeDefinition<H> for NullTypeDefinition<H> {
22308    type Element = NullElement<H>;
22309    fn content_address(&self) -> &Self::Element {
22310        &self.element
22311    }
22312}
22313
22314/// Resolver-absent default `Partition<H>`. Embeds inline stubs for every
22315/// sub-trait associated type so `Partition<H>` accessors return references
22316/// to fields rather than to statics. The only meaningful state is the
22317/// `fingerprint`; everything else uses `HostTypes::EMPTY_*` defaults.
22318/// Returned by the three witness trait impls' `left_factor` / `right_factor`
22319/// / `left_summand` / etc. accessors as the resolver-absent value pathway.
22320/// Consumers needing real partition data pair the sibling `PartitionHandle`
22321/// with a `PartitionResolver` instead.
22322#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22323pub struct NullPartition<H: HostTypes> {
22324    irreducibles: NullIrreducibleSet<H>,
22325    reducibles: NullReducibleSet<H>,
22326    units: NullUnitGroup<H>,
22327    exterior: NullComplement<H>,
22328    free_rank: NullFreeRank<H>,
22329    tag_site: NullTagSite<H>,
22330    source_type: NullTypeDefinition<H>,
22331    fingerprint: ContentFingerprint,
22332}
22333
22334impl<H: HostTypes> NullPartition<H> {
22335    /// Construct a NullPartition with the given content fingerprint.
22336    /// All other fields are resolver-absent defaults.
22337    #[inline]
22338    #[must_use]
22339    pub fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
22340        Self {
22341            irreducibles: NullIrreducibleSet::default(),
22342            reducibles: NullReducibleSet::default(),
22343            units: NullUnitGroup::default(),
22344            exterior: NullComplement::default(),
22345            free_rank: NullFreeRank::default(),
22346            tag_site: NullTagSite::default(),
22347            source_type: NullTypeDefinition::default(),
22348            fingerprint,
22349        }
22350    }
22351    /// Returns the content fingerprint identifying which Partition this stub stands in for.
22352    #[inline]
22353    #[must_use]
22354    pub const fn fingerprint(&self) -> ContentFingerprint {
22355        self.fingerprint
22356    }
22357    /// Phase 2 (orphan-closure): absent-value sentinel used by Null stubs
22358    /// in other namespaces to satisfy `&Self::Partition` return borrows.
22359    pub const ABSENT: NullPartition<H> = NullPartition {
22360        irreducibles: NullIrreducibleSet {
22361            _phantom: core::marker::PhantomData,
22362        },
22363        reducibles: NullReducibleSet {
22364            _phantom: core::marker::PhantomData,
22365        },
22366        units: NullUnitGroup {
22367            _phantom: core::marker::PhantomData,
22368        },
22369        exterior: NullComplement {
22370            term: NullTermExpression {
22371                _phantom: core::marker::PhantomData,
22372            },
22373        },
22374        free_rank: NullFreeRank {
22375            _phantom: core::marker::PhantomData,
22376        },
22377        tag_site: NullTagSite {
22378            ancilla: NullSiteIndex {
22379                _phantom: core::marker::PhantomData,
22380            },
22381        },
22382        source_type: NullTypeDefinition {
22383            element: NullElement {
22384                _phantom: core::marker::PhantomData,
22385            },
22386        },
22387        fingerprint: ContentFingerprint::zero(),
22388    };
22389}
22390
22391impl<H: HostTypes> crate::bridge::partition::Partition<H> for NullPartition<H> {
22392    type IrreducibleSet = NullIrreducibleSet<H>;
22393    fn irreducibles(&self) -> &Self::IrreducibleSet {
22394        &self.irreducibles
22395    }
22396    type ReducibleSet = NullReducibleSet<H>;
22397    fn reducibles(&self) -> &Self::ReducibleSet {
22398        &self.reducibles
22399    }
22400    type UnitGroup = NullUnitGroup<H>;
22401    fn units(&self) -> &Self::UnitGroup {
22402        &self.units
22403    }
22404    type Complement = NullComplement<H>;
22405    fn exterior(&self) -> &Self::Complement {
22406        &self.exterior
22407    }
22408    fn density(&self) -> H::Decimal {
22409        H::EMPTY_DECIMAL
22410    }
22411    type TypeDefinition = NullTypeDefinition<H>;
22412    fn source_type(&self) -> &Self::TypeDefinition {
22413        &self.source_type
22414    }
22415    fn witt_length(&self) -> u64 {
22416        0
22417    }
22418    type FreeRank = NullFreeRank<H>;
22419    fn site_budget(&self) -> &Self::FreeRank {
22420        &self.free_rank
22421    }
22422    fn is_exhaustive(&self) -> bool {
22423        true
22424    }
22425    type TagSite = NullTagSite<H>;
22426    fn tag_site_of(&self) -> &Self::TagSite {
22427        &self.tag_site
22428    }
22429    fn product_category_level(&self) -> &H::HostString {
22430        H::EMPTY_HOST_STRING
22431    }
22432}
22433
22434impl<H: HostTypes> crate::bridge::partition::PartitionProduct<H> for PartitionProductWitness {
22435    type Partition = NullPartition<H>;
22436    fn left_factor(&self) -> Self::Partition {
22437        NullPartition::from_fingerprint(self.left_fingerprint)
22438    }
22439    fn right_factor(&self) -> Self::Partition {
22440        NullPartition::from_fingerprint(self.right_fingerprint)
22441    }
22442}
22443
22444impl<H: HostTypes> crate::bridge::partition::PartitionCoproduct<H> for PartitionCoproductWitness {
22445    type Partition = NullPartition<H>;
22446    fn left_summand(&self) -> Self::Partition {
22447        NullPartition::from_fingerprint(self.left_fingerprint)
22448    }
22449    fn right_summand(&self) -> Self::Partition {
22450        NullPartition::from_fingerprint(self.right_fingerprint)
22451    }
22452}
22453
22454impl<H: HostTypes> crate::bridge::partition::CartesianPartitionProduct<H>
22455    for CartesianProductWitness
22456{
22457    type Partition = NullPartition<H>;
22458    fn left_cartesian_factor(&self) -> Self::Partition {
22459        NullPartition::from_fingerprint(self.left_fingerprint)
22460    }
22461    fn right_cartesian_factor(&self) -> Self::Partition {
22462        NullPartition::from_fingerprint(self.right_fingerprint)
22463    }
22464}
22465
22466/// v0.2.1 ergonomics prelude. Re-exports the core symbols downstream crates
22467/// need for the consumer-facing one-liners.
22468/// Ontology-driven: the set of certificate / type / builder symbols is
22469/// sourced from `conformance:PreludeExport` individuals. Adding a new
22470/// symbol to the prelude is an ontology edit, verified against the
22471/// codegen's known-name mapping at build time.
22472pub mod prelude {
22473    pub use super::calibrations;
22474    pub use super::Add;
22475    pub use super::And;
22476    pub use super::BNot;
22477    pub use super::BinaryGroundingMap;
22478    pub use super::BindingEntry;
22479    pub use super::BindingsTable;
22480    pub use super::BornRuleVerification;
22481    pub use super::Calibration;
22482    pub use super::CalibrationError;
22483    pub use super::CanonicalTimingPolicy;
22484    pub use super::Certificate;
22485    pub use super::Certified;
22486    pub use super::ChainAuditTrail;
22487    pub use super::CompileTime;
22488    pub use super::CompileUnit;
22489    pub use super::CompileUnitBuilder;
22490    pub use super::CompletenessAuditTrail;
22491    pub use super::CompletenessCertificate;
22492    pub use super::ConstrainedTypeInput;
22493    pub use super::ContentAddress;
22494    pub use super::ContentFingerprint;
22495    pub use super::Datum;
22496    pub use super::DigestGroundingMap;
22497    pub use super::Embed;
22498    pub use super::FragmentMarker;
22499    pub use super::GenericImpossibilityWitness;
22500    pub use super::GeodesicCertificate;
22501    pub use super::GeodesicEvidenceBundle;
22502    pub use super::Grounded;
22503    pub use super::GroundedCoord;
22504    pub use super::GroundedShape;
22505    pub use super::GroundedTuple;
22506    pub use super::GroundedValue;
22507    pub use super::Grounding;
22508    pub use super::GroundingCertificate;
22509    pub use super::GroundingExt;
22510    pub use super::GroundingMapKind;
22511    pub use super::GroundingProgram;
22512    pub use super::Hasher;
22513    pub use super::ImpossibilityWitnessKind;
22514    pub use super::InhabitanceCertificate;
22515    pub use super::InhabitanceImpossibilityWitness;
22516    pub use super::IntegerGroundingMap;
22517    pub use super::Invertible;
22518    pub use super::InvolutionCertificate;
22519    pub use super::IsometryCertificate;
22520    pub use super::JsonGroundingMap;
22521    pub use super::LandauerBudget;
22522    pub use super::LiftChainCertificate;
22523    pub use super::MeasurementCertificate;
22524    pub use super::Mul;
22525    pub use super::Nanos;
22526    pub use super::Neg;
22527    pub use super::OntologyTarget;
22528    pub use super::Or;
22529    pub use super::PipelineFailure;
22530    pub use super::PreservesMetric;
22531    pub use super::PreservesStructure;
22532    pub use super::RingOp;
22533    pub use super::Runtime;
22534    pub use super::ShapeViolation;
22535    pub use super::Sub;
22536    pub use super::Succ;
22537    pub use super::Term;
22538    pub use super::TermArena;
22539    pub use super::TimingPolicy;
22540    pub use super::Total;
22541    pub use super::TransformCertificate;
22542    pub use super::Triad;
22543    pub use super::UnaryRingOp;
22544    pub use super::UorTime;
22545    pub use super::Utf8GroundingMap;
22546    pub use super::ValidLevelEmbedding;
22547    pub use super::Validated;
22548    pub use super::ValidationPhase;
22549    pub use super::Xor;
22550    pub use super::W16;
22551    pub use super::W8;
22552    pub use crate::pipeline::empty_bindings_table;
22553    pub use crate::pipeline::{
22554        validate_constrained_type, validate_constrained_type_const, ConstrainedTypeShape,
22555        ConstraintRef, FragmentKind,
22556    };
22557    pub use crate::{DecimalTranscendental, DefaultHostTypes, HostTypes, WittLevel};
22558}