19.6. Numerical adequacy of the floating-point representation
A floating-point representation is numerically adequate for a model, given the input ranges and
uncertainties, exactly when evaluating it loses no information significant at the scale of those
uncertainties. The qualifier is what makes the notion checkable, and it is why this half of the
chapter shares Axis U's descriptor: the yardstick is the very c_i\,u_i and support the
uncertainty methods already carry. The textbook failure — adding a small floating-point number to
a large one and losing the small one — becomes precise: an input whose uncertainty contribution
c_i\,u_i falls below half a unit in the last place of the accumulated sum is numerically
invisible, a silent corruption of the uncertainty result. Its exact-cancellation dual (a
difference of near-equal quantities is exact by Sterbenz, yet amplifies relative uncertainty)
is the same two views — floating-point and uncertainty — meeting again.
The idiomatic realization is numerical adequacy as a carrier: because the model is WO1 over
[NumCarrier α], instantiating it at an analysis carrier that tracks each value's magnitude and
carried uncertainty, and checks each operation for swamping and cancellation, yields the adequacy
report for free — no model rewrite. The check is sound because the swamping threshold is exactly
half a unit in the last place, a fact proved on the rounding grid over ℝ and grounded in
TorchLean's binary32 FP32 unit-in-the-last-place lemmas (Adequacy.Fp32Grounding, which imports
the genuine — noncomputable — Flocq port); the executable carrier computes the same threshold over
Float.
The adequacy analysis carrier: a value carrying its magnitude, its propagated uncertainty, and an
accumulated report of adequacy violations. As a NumCarrier, any write-once model instantiates at it
and is analyzed for floating-point information loss with no rewrite — the runtime certificate, the
pragmatic first target of the numerical-adequacy layer.
Lean code for Definition19.6.1●1 definition
Associated Lean declarations
-
structuredefined in PropertyKindCalculus/Uncertainty/Adequacy.leancomplete
structure PropertyKindCalculus.Uncertainty.Adequacy : Type
structure PropertyKindCalculus.Uncertainty.Adequacy : Type
**The numerical-adequacy analysis carrier.** A value carries its `Float` magnitude, the absolute uncertainty propagated to it, and the accumulated `report` of adequacy violations. Instantiating a WO1 `[NumCarrier α]` model at `Adequacy` runs it once and emits the report — no model rewrite.
Fields
value : Float
The computed magnitude (over `Float`).
unc : Float
The absolute uncertainty contribution carried to this value.
report : PropertyKindCalculus.Uncertainty.AdequacyReport
The accumulated adequacy report.
Realized (Stage 3, Adequacy) over the Float carrier. Addition runs a swamping check (the
smaller-magnitude operand's uncertainty against half the sum's ulp), subtraction a cancellation check
(relative uncertainty reaching 100%); the NumCarrier instance closes with these plus the arithmetic
and MathCarrier fields, so the same kernel the earlier rungs evaluate runs here to emit the
report. The AdequacySwamping example flags a large-accumulator model and certifies its
small-accumulator variant clean — one WO1 kernel, checked for free.
Absorption (A1). On the rounding grid of spacing u (a ulp), a representable value perturbed by
strictly less than half a ulp rounds back unchanged: |y| < u/2 \Rightarrow
\mathrm{round}_u(x + y) = x. The perturbation carries no information into the result — floating-point
swamping made precise — and its converse (resolve) shows a perturbation of at least half a ulp does
move the result, so half a ulp is the exact absorption threshold.
Lean code for Theorem19.6.2●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/Absorption.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.absorb {u x y : ℝ} (hu : 0 < u) (hx : PropertyKindCalculus.Uncertainty.Adequacy.OnGrid u x) (hy : |y| < u / 2) : PropertyKindCalculus.Uncertainty.Adequacy.gridRound u (x + y) = x
theorem PropertyKindCalculus.Uncertainty.Adequacy.absorb {u x y : ℝ} (hu : 0 < u) (hx : PropertyKindCalculus.Uncertainty.Adequacy.OnGrid u x) (hy : |y| < u / 2) : PropertyKindCalculus.Uncertainty.Adequacy.gridRound u (x + y) = x
**A1 — absorption.** A representable value `x` perturbed by strictly less than half a ulp rounds back to `x`: the perturbation is *absorbed*, contributing nothing to the floating-point result. This is the mathematical content of swamping — `fl(x + y) = x` whenever `|y| < ½ ulp(x)`.
Realized over ℝ (Adequacy.Absorption.absorb, with resolve the converse): on the uniform grid
u·ℤ, round_u(x+y) = u·round((x+y)/u), and |y| < u/2 places (x+y)/u within a half-integer of
x/u, so it rounds to x/u. The binary32 realization is TorchLean's neuralRound nearest-point
optimality and neuralUlp (Adequacy.Fp32Grounding). Sorry-free.
Sterbenz (A2). The difference of two positive floating-point numbers representable at precision
p that lie within a factor of two of each other (y \le x \le 2y) is itself representable at
precision p — so near-equal subtraction is exact, introducing no rounding error. Its dual is the
uncertainty hazard: that exact difference can have relative uncertainty ≥ 100% (relUnc_amplifies).
Lean code for Theorem19.6.3●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/Sterbenz32.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.flx_sterbenz {p : ℕ} {x y : ℝ} (hy : 0 < y) (hyx : y ≤ x) (hx2y : x ≤ 2 * y) (hxr : PropertyKindCalculus.Uncertainty.Adequacy.FLX p x) (hyr : PropertyKindCalculus.Uncertainty.Adequacy.FLX p y) : PropertyKindCalculus.Uncertainty.Adequacy.FLX p (x - y)
theorem PropertyKindCalculus.Uncertainty.Adequacy.flx_sterbenz {p : ℕ} {x y : ℝ} (hy : 0 < y) (hyx : y ≤ x) (hx2y : x ≤ 2 * y) (hxr : PropertyKindCalculus.Uncertainty.Adequacy.FLX p x) (hyr : PropertyKindCalculus.Uncertainty.Adequacy.FLX p y) : PropertyKindCalculus.Uncertainty.Adequacy.FLX p (x - y)
**A2 — Sterbenz's theorem.** The difference of two positive numbers representable at precision `p`, when they lie within a factor of two of each other (`y ≤ x ≤ 2y`), is itself representable at precision `p` — so the subtraction is *exact*. This is why near-equal floating-point subtraction introduces no rounding error. The real-number analogue of TorchLean's `generic_format_FLX_sterbenz`.
Realized over ℝ (Adequacy.Sterbenz32.flx_sterbenz), the real-number analogue of TorchLean's
neural_generic_format_FLX_sterbenz: align both operands to the smaller exponent, and the factor-of-two
condition bounds the difference's mantissa below 2^p. sub_exact_on_grid gives the grid form (the
difference rounds to itself). Sorry-free. Stage 3.2 carries this to the FLT/fexp32 format binary32
actually uses (gradual underflow) — the genuine grounding is thm_uq_sterbenz_fp32.
Sterbenz at the binary32 format (A2, Stage 3.2). The same exactness at the format binary32 actually
uses — TorchLean's fexp32 = \mathrm{FLTExp}\,(-149)\,24, an FLT format with gradual underflow: for
representable binary32 u, v within a factor of two (u \le 2v, v \le 2u), the exact difference
is already on the grid, so \mathrm{round}_{32}(u - v) = u - v. This realizes the FLX-model
A2 at the real gradual-underflow format, and its FP32-typed corollary
sub32_exact_of_sterbenz makes a near-equal binary32 subtraction lossless.
Lean code for Theorem19.6.4●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/Fp32Grounding.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.round32_sterbenz_exact {u v : ℝ} (hu : FloatLib.Floats.Formats.Flocq.genericFormat FloatLib.Numerics.binaryRadix PropertyKindCalculus.Fp32.fexp32 u) (hv : FloatLib.Floats.Formats.Flocq.genericFormat FloatLib.Numerics.binaryRadix PropertyKindCalculus.Fp32.fexp32 v) (hupos : 0 < u) (hvpos : 0 < v) (huv : u ≤ 2 * v) (hvu : v ≤ 2 * u) : PropertyKindCalculus.Fp32.round32 (u - v) = u - v
theorem PropertyKindCalculus.Uncertainty.Adequacy.round32_sterbenz_exact {u v : ℝ} (hu : FloatLib.Floats.Formats.Flocq.genericFormat FloatLib.Numerics.binaryRadix PropertyKindCalculus.Fp32.fexp32 u) (hv : FloatLib.Floats.Formats.Flocq.genericFormat FloatLib.Numerics.binaryRadix PropertyKindCalculus.Fp32.fexp32 v) (hupos : 0 < u) (hvpos : 0 < v) (huv : u ≤ 2 * v) (hvu : v ≤ 2 * u) : PropertyKindCalculus.Fp32.round32 (u - v) = u - v
**A2 at the real binary32 format — Sterbenz as a theorem about `round32` (Stage 3.2).** For two representable binary32 values within a factor of two (`0 < u`, `0 < v`, `u ≤ 2v`, `v ≤ 2u`), the difference is *exactly* representable, so `round32` is the identity on it: `round32 (u − v) = u − v`. This is the genuine binary32 realization — over TorchLean's `fexp32 = FLTExp (−149) 24`, gradual underflow — of the grid model's self-contained `Sterbenz32.flx_sterbenz`, discharging Stage 3.2: near-equal binary32 subtraction is lossless at *the format the model actually uses*.
Realized over ℝ/FP32 (Stage 3.2, Adequacy.Fp32Grounding.round32_sterbenz_exact /
sub32_exact_of_sterbenz), grounded in the TorchLean PR's neural_generic_format_FLT_sterbenz. That
FLT Sterbenz lemma splits on the underflow boundary β^(prec+emin): on the subnormal side the fixed
emin grid subtracts exactly (FLT_to_FIX → FIX_sub → FIX_to_FLT), on the normal side it
transports through the unbounded FLX family (FLT_to_FLX → FLX_sterbenz → FLX_to_FLT_of_normal).
Composing it with neural_round_preserves_generic (rounding is the identity on representable reals)
gives \mathrm{round}_{32}(u - v) = u - v, so the per-op sub32_within_half_ulp half-ulp bound
collapses to zero in the Sterbenz regime. Sorry-free ([propext, Classical.choice, Quot.sound]),
exercised by the AdequacySterbenz32 example.
Adequacy verdict soundness (A3). At an addition site, the carrier's flag — the operand's uncertainty is below half the accumulator's ulp — holds if and only if the contribution is genuinely lost (the rounded sum is unchanged by that uncertainty). So the flag is sound (flag ⟹ lost) and complete (lost ⟹ flag): the theorem that makes the carrier's report trustworthy. Rests on absorption and its converse.
Lean code for Theorem19.6.5●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/Soundness.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.verdict_sound {u s unc : ℝ} (hu : 0 < u) (hs : PropertyKindCalculus.Uncertainty.Adequacy.OnGrid u s) (h0 : 0 ≤ unc) (h1 : unc < u) : PropertyKindCalculus.Uncertainty.Adequacy.AbsorptionFlag u unc ↔ PropertyKindCalculus.Uncertainty.Adequacy.gridRound u (s + unc) = s
theorem PropertyKindCalculus.Uncertainty.Adequacy.verdict_sound {u s unc : ℝ} (hu : 0 < u) (hs : PropertyKindCalculus.Uncertainty.Adequacy.OnGrid u s) (h0 : 0 ≤ unc) (h1 : unc < u) : PropertyKindCalculus.Uncertainty.Adequacy.AbsorptionFlag u unc ↔ PropertyKindCalculus.Uncertainty.Adequacy.gridRound u (s + unc) = s
**A3 — soundness of the absorption verdict.** For a representable accumulated value `s` (grid spacing `u = ulp`) and a nonnegative uncertainty within one ulp, the carrier flags absorption *iff* the contribution is genuinely lost: perturbing the accumulator by `unc` leaves the rounded result unchanged. So the flag `unc < ½ ulp` is *exactly* the condition "no information about this contribution survives into the floating-point result" — **sound** (flag ⟹ lost) and **complete** (lost ⟹ flag). This is the theorem that makes the `Adequacy` carrier's report trustworthy.
Realized over ℝ (Adequacy.Soundness.verdict_sound): the forward direction is A1 absorb, the
reverse is the contrapositive of resolve, giving the biconditional unc < ½ ulp ↔ fl(s + unc) = s
for a representable accumulator and an uncertainty within one ulp. The AdequacyLadder example applies
it to concrete values with a sorry-free axiom profile. This is the per-site soundness that grounds the
runtime carrier.
Universal adequacy soundness (A3′, the capstone). Abstract a write-once model as a binary32
evaluation DAG over the full operator class +/−/×/÷. For any two inputs — in particular
every input in a box around a nominal one — the FP32-computed measurand's variation reproduces the
exact ℝ-computed variation up to a proven, DAG-additive rounding budget; and when no site rounds
anywhere (flag-free — no absorption at any addition, every subtraction in the Sterbenz
A2 regime), the bound collapses to equality. This lifts the per-site
verdict A3 across a whole evaluation, and is the theorem that binds
the layer to R10's exec/spec refinement.
Lean code for Theorem19.6.6●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/DagBound.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.dag_fp32_box_faithful (e : PropertyKindCalculus.Uncertainty.Adequacy.Expr) (ρ σ : ℕ → TorchLean.Floats.FP32) (hρ : PropertyKindCalculus.Uncertainty.Adequacy.Regular e ρ) (hσ : PropertyKindCalculus.Uncertainty.Adequacy.Regular e σ) : |(PropertyKindCalculus.Uncertainty.Adequacy.evalFP32 e σ).val - (PropertyKindCalculus.Uncertainty.Adequacy.evalFP32 e ρ).val - (PropertyKindCalculus.Uncertainty.Adequacy.evalExact e σ - PropertyKindCalculus.Uncertainty.Adequacy.evalExact e ρ)| ≤ PropertyKindCalculus.Uncertainty.Adequacy.errBound e σ + PropertyKindCalculus.Uncertainty.Adequacy.errBound e ρ
theorem PropertyKindCalculus.Uncertainty.Adequacy.dag_fp32_box_faithful (e : PropertyKindCalculus.Uncertainty.Adequacy.Expr) (ρ σ : ℕ → TorchLean.Floats.FP32) (hρ : PropertyKindCalculus.Uncertainty.Adequacy.Regular e ρ) (hσ : PropertyKindCalculus.Uncertainty.Adequacy.Regular e σ) : |(PropertyKindCalculus.Uncertainty.Adequacy.evalFP32 e σ).val - (PropertyKindCalculus.Uncertainty.Adequacy.evalFP32 e ρ).val - (PropertyKindCalculus.Uncertainty.Adequacy.evalExact e σ - PropertyKindCalculus.Uncertainty.Adequacy.evalExact e ρ)| ≤ PropertyKindCalculus.Uncertainty.Adequacy.errBound e σ + PropertyKindCalculus.Uncertainty.Adequacy.errBound e ρ
**A3′ — box faithfulness of the floating-point measurand.** For a fixed model DAG `e`, a nominal input `ρ`, and *any* input `σ` (in particular every input in a box around `ρ`), the floating-point output *variation* `evalFP32 σ − evalFP32 ρ` reproduces the exact `ℝ` output variation `evalExact σ − evalExact ρ` up to the summed rounding budget `errBound σ + errBound ρ`. So the FP32 measurand's uncertainty — its spread over the input box — equals the `ℝ` one **up to a proven, DAG-additive bound**: the universal (whole-evaluation) lift of the per-site verdict A3.
Realized over ℝ/FP32 (Stage 3.1, Adequacy.DagBound). The forward-error accumulation
dag_fp32_error_bound composes the per-operation half-ulp bounds
(Adequacy.Fp32Grounding.{add32,sub32,mul32,div32}_within_half_ulp, the genuine
FP32.{add,sub,mul,div}_abs_error) with the triangle inequality and the first-order propagation of
operand errors along the DAG; applying it at both inputs and one more triangle step gives the
box-faithfulness bound dag_fp32_box_faithful, and dag_fp32_box_exact_of_flagFree is the flag-free
equality. The linear nodes +/− pass operand error through with coefficient one; the nonlinear
×/÷ carry the GUM magnitude factors (|b|, 1/|b|, |a|/|b|²), a div node's bound holding on
the nonzero-denominator side condition Regular (vacuous on ÷-free DAGs). Sorry-free (#print
axioms → [propext, Classical.choice, Quot.sound]), instantiated on concrete +/−/×/÷ DAGs in
the AdequacyDag example (the executable-carrier bridge is built, Stage
3.3).
Flag-freedom is a condition on the exact evaluation. The flag-free hypothesis of A3′ is phrased
about the floating-point intermediates, so settling it means evaluating in binary32 first. Asking
instead that every node's exact value be a binary32 number is a question about the ℝ model and
its inputs — and it cuts out the same inputs.
Lean code for Theorem19.6.7●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/DagBound.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.flagFree_iff_exactRepresentable (ρ : ℕ → TorchLean.Floats.FP32) (e : PropertyKindCalculus.Uncertainty.Adequacy.Expr) : PropertyKindCalculus.Uncertainty.Adequacy.FlagFree e ρ ↔ PropertyKindCalculus.Uncertainty.Adequacy.ExactRepresentable e ρ
theorem PropertyKindCalculus.Uncertainty.Adequacy.flagFree_iff_exactRepresentable (ρ : ℕ → TorchLean.Floats.FP32) (e : PropertyKindCalculus.Uncertainty.Adequacy.Expr) : PropertyKindCalculus.Uncertainty.Adequacy.FlagFree e ρ ↔ PropertyKindCalculus.Uncertainty.Adequacy.ExactRepresentable e ρ
**The two conditions cut out the same inputs.** Each direction needs the other condition on the operands first — which is what the induction supplies — because the node's own statement is about the operands' *values*, and it is exactly the operand-level equality that identifies the two readings of them.
Realized as ExactRepresentable and flagFree_iff_exactRepresentable (Stage 3.8,
Adequacy.DagBound). Both directions of the induction need the operand condition first, which is
what identifies the two readings of a node's operands; the node step is then
Fp32Grounding.round32_eq_self_iff, that round32 fixes exactly the representable reals. That
characterization is also what makes the relocated condition minimal for this conclusion: nothing
weaker on a node's exact value keeps that node from rounding.
The consequence worth stating is that the flag-free theorems are now about an inhabited regime.
AdequacyDag discharges ExactRepresentable on a doubling chain at two input assignments and
derives the box equality with no hypothesis left standing — where mix_box_exact and
prod_box_exact assume flag-freedom and nothing supplies it.
What is not done is the weaker regime the residual list still carries: a no-absorption condition
would allow rounding and ask only that a tracked contribution survive it, which makes equality of
the variations false and so requires a different conclusion — a resolution statement lifting A1's
converse resolve along the DAG, as dag_fp32_error_bound lifts the half-ulp bound.
Which bridge carries which half. Two routes connect the executable rung to the specification: the algebraic one, whose content is one equation per operator, and the per-operation error bounds, whose content is one bound per operator. They are not alternatives. The forward-error accumulation is metric and rests on the bounds; the exactness regime is algebraic and is a statement about the refinement's rounding — which this theorem proves by showing the two vocabularies pick out the same evaluations.
Lean code for Theorem19.6.8●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/RefinementBridge.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.refinementFixes_iff_exactRepresentable (ρ : ℕ → TorchLean.Floats.FP32) (e : PropertyKindCalculus.Uncertainty.Adequacy.Expr) : PropertyKindCalculus.Uncertainty.Adequacy.RefinementFixes e ρ ↔ PropertyKindCalculus.Uncertainty.Adequacy.ExactRepresentable e ρ
theorem PropertyKindCalculus.Uncertainty.Adequacy.refinementFixes_iff_exactRepresentable (ρ : ℕ → TorchLean.Floats.FP32) (e : PropertyKindCalculus.Uncertainty.Adequacy.Expr) : PropertyKindCalculus.Uncertainty.Adequacy.RefinementFixes e ρ ↔ PropertyKindCalculus.Uncertainty.Adequacy.ExactRepresentable e ρ
**The vocabularies agree.** Node by node, "the refinement's rounding fixes this value" and "this value is representable" are the same statement — `refinement_round_eq_self_iff` under an induction that does nothing else.
Realized in Adequacy.RefinementBridge. The identification is definitional — the refinement rounds
by the format's own rounding — so the induction does nothing but apply, at each node, that rounding
fixes exactly the representable reals.
The reason to keep both routes rather than consolidate is that their side conditions are about
different things. The division law is unconditional at the specification rung only because \mathbb{R}
totalizes division by zero, which is why the executable rung instead carries the divisor's nonzero
decoded mantissa — a question of definedness. The adequacy DAG's regularity condition is unrelated
to that: the per-operation bound for division has no hypothesis at all, and regularity guards the
propagation factors — a question of magnitude. Merging them would conflate the two, and the
weighted mean is where that would cost something: at its single
division node the two rungs' licenses are independent in both directions.
Executable↔spec bridge (Stage 3.3). The verdicts above are stated over the noncomputable ℝ/FP32
specification, but the runtime carrier must compute a verdict. Lean's host Float is an opaque FFI
type no theorem can constrain, so the certified executable check runs on TorchLean's computable
IEEE32Exec model instead. There the ULP is genuinely computed from a bit pattern (ulpExp?, matching
the spec ulp₃₂ whenever it answers — none on NaNs and infinities), and the kernel's absorption test absorbs s δ — the float32 sum is unchanged —
certifies the specification: the exact real sum rounds back under \mathrm{round}_{32}. So the
computed adequacy verdict is provably the specified A3 one, on the
finite fragment. The residual Float32 ↔ IEEE32Exec step is an upstream assumption typeclass, not an
axiom — the irreducible hardware trust boundary.
Lean code for Theorem19.6.9●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/Adequacy/ExecBridge.leancomplete
theorem PropertyKindCalculus.Uncertainty.Adequacy.exec_verdict_sound {s δ : FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_1 PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_2 PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_3 PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_4} (hfin : FloatLib.Floats.ExecFloat.Binary.isFinite (FloatLib.Floats.ExecFloat.add s δ) = true) (hverdict : TorchLean.Floats.IEEE754.IEEE32Exec.absorbs s δ = true) : PropertyKindCalculus.Fp32.round32 (s.toModel.toReal + δ.toModel.toReal) = s.toModel.toReal
theorem PropertyKindCalculus.Uncertainty.Adequacy.exec_verdict_sound {s δ : FloatLib.Floats.ExecFloat.Binary 8 23 FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee (FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.Encoding.ieee.defaultBias 8) PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_1 PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_2 PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_3 PropertyKindCalculus.Uncertainty.Adequacy.exec_ulp_grounds._proof_4} (hfin : FloatLib.Floats.ExecFloat.Binary.isFinite (FloatLib.Floats.ExecFloat.add s δ) = true) (hverdict : TorchLean.Floats.IEEE754.IEEE32Exec.absorbs s δ = true) : PropertyKindCalculus.Fp32.round32 (s.toModel.toReal + δ.toModel.toReal) = s.toModel.toReal
**A3/A1 at the executable binary32 kernel — Stage 3.3.** When the executable kernel reports an operand absorbed (`absorbs s δ = true`, i.e. the float32 sum equals `s` unchanged), the specification *agrees*: the exact real sum rounds back to `toReal s` under `round32`. This is the executable image of `Soundness.verdict_sound`'s flag ⟹ contribution-lost direction — the abstract grid `gridRound u` replaced by the genuine binary32 rounding `round32` — so the *computed* adequacy verdict is provably the *specified* one, on the finite fragment. The one finiteness hypothesis is the executable check `isFinite (ExecFloat.add s δ)`: a finite executable sum already forces finite operands, so a kernel driver discharges the whole theorem by running `isFinite` and `absorbs`.
Realized over ℝ/IEEE32Exec (Stage 3.3, Adequacy.ExecBridge), grounded in TorchLean's
IEEE32Exec.ulpExp? + bpow_eq_ulp_of_ulpExp?_eq_some (an executable ULP answer equals
ulp₃₂; the query answers on exactly the finite fragment) and round_add_eq_left_of_absorbs (a 3-line corollary of the
toReal_add_eq_round_of_isFinite op-level refinement, since FloatLib's Model.roundAt binary32 is round₃₂). exec_verdict_sound
composes them: when absorbs s δ fires, round₃₂(\mathrm{toReal}\,s + \mathrm{toReal}\,δ) =
\mathrm{toReal}\,s. Sorry-free ([propext, Classical.choice, Quot.sound]); the executable side is
run (#guard) at 2^{25} and 10^8 in the AdequacyExecBridge example, which also confirms the
axiom profile. The host-Float Adequacy carrier stays the fast, unverified mirror.
The Axis-U significance yardstick (Stage 3.4). Uncertainty propagation and numerical adequacy are
driven from one InputDist descriptor, and the GUM budget carries its metrological intent in the
types: an input standard uncertainty is a \mathrm{Quantity}\ k_i, a
sensitivity c_i = \partial f/\partial x_i a quotient
\mathrm{Quantity}\ (k_o/k_i), and their product — the contribution u_i(y) = |c_i|\,u(x_i),
the scale at which absorption becomes genuine information loss — a \mathrm{Quantity}\ k_o, formed by
a term gated on (k_o/k_i)\cdot k_i = k_o (the GUM units cancellation, a typechecking obligation).
analyzeQ instantiates one carrier-raw write-once kernel twice from that single descriptor list — at
the autograd carrier for the c_i, and at the adequacy carrier seeded from
the same descriptor — and returns a kind-typed budget, so a UQ-analyzed model is simultaneously
adequacy-checked at the scale its own uncertainty defines, with the roles kept distinct by kind.
Lean code for Definition19.6.10●1 definition
Associated Lean declarations
-
defdefined in PropertyKindCalculus/Uncertainty/Adequacy/Significance.leancomplete
def PropertyKindCalculus.Uncertainty.Adequacy.analyzeQ {kO kI kS : PropertyKindCalculus.KindOfProperty} (h : PropertyKindCalculus.ProductKind kS kI kO) (model : PropertyKindCalculus.Uncertainty.Adequacy.ListModel) (inputs : List (PropertyKindCalculus.Uncertainty.InputDist Float)) : Except String (PropertyKindCalculus.Uncertainty.Adequacy.CouplingResultQ kO)
def PropertyKindCalculus.Uncertainty.Adequacy.analyzeQ {kO kI kS : PropertyKindCalculus.KindOfProperty} (h : PropertyKindCalculus.ProductKind kS kI kO) (model : PropertyKindCalculus.Uncertainty.Adequacy.ListModel) (inputs : List (PropertyKindCalculus.Uncertainty.InputDist Float)) : Except String (PropertyKindCalculus.Uncertainty.Adequacy.CouplingResultQ kO)
**The Stage-3.4 driver (kind-typed).** For a model whose inputs share a kind `kᵢ` and whose output has kind `kₒ`, with the sensitivity kind `kₛ` satisfying `kₛ·kᵢ = kₒ` (the `ProductKind` witness — the GUM units cancellation), instantiate the model *twice* from one source: at `TapeBuilder .scalar` to read the sensitivities `cᵢ` by one reverse pass, and at `Adequacy` to run the numerical-adequacy verdict on inputs seeded from the *same* descriptors. The `cᵢ` are stamped `Quantity kₛ` at the boundary (`sensitivityQ`) and folded with the kinded input uncertainties (`stdUncQ`) into the kinded GUM budget (`contributionQ`/`combinedQ`). One descriptor, both areas, every quantity kinded.
Realized (Stage 3.4, Adequacy.Significance.analyzeQ over Uncertainty.Budget). The three budget
roles get kinds (stdUncQ, sensitivityQ, contributionQ gated by ProductKind kₛ kᵢ kₒ,
combinedQ); the model stays carrier-raw, so no kinded autograd is needed — the kinds are the
caller-declared overlay on the budget. On the Degenhardt descriptors the coupling reproduces
(c_i) = (5, 5, 2.25), the kinded contributions (c_i u_i) = (1.0, 1.30, 0.28) at \mathrm{
measurandY}, and their quadrature reproduces the GUM combined uncertainty u_c = 1.662359
exactly; #check_failure probes make the conflations (sensitivity↔uncertainty, heterogeneous
quadrature, field swap) type errors. A 10^8-accumulator swamps a contribution
(< \tfrac12\,\mathrm{ulp}_{32}(10^8) = 4); the flag's soundness is the
A3 verdict, and contribution_absorbed_at_scale applies it at the
contribution scale, sorry-free. (ProductKind.ofRatio is liberal, so the gate enforces the GUM shape
and forbids un-sanctioned mixing while the author asserts k_s = k_o/k_i.) The budget is
carrier-generic (Uncertainty.Budget over [NumCarrier R]) — the second axis, orthogonal to the
kind: the same combinedQ runs at ℝ (to prove laws), at Float (to run), and at the
adequacy carrier, where its quadrature \sqrt{\sum u_i^2} adequacy-checks
itself (the example flags a 10^{-3} contribution swamped beside a 10^8 one).
The kinded ×/÷ budget DAG (residual 2). The significance wiring
covers the homogeneous-input case — all inputs at one shared kind, one flat quadrature. A genuinely
heterogeneous multiply/divide model, each interior node with its own kind equation, needs the kind
gates threaded through the expression. BudgetExpr R k is a kinded ×/÷ expression whose every
mul/div node carries its \mathrm{ProductKind}/\mathrm{QuotientKind} witness as a
constructor field, so an ill-kinded expression is unwritable; and every interpretation — the plain
value valueQ, the node-local GUM propagation propagateQ, the flattened per-leaf contribsQ — is
built exclusively by the kind-gated \mathrm{Quantity.mul}/\mathrm{Quantity.div}, never a naked
carrier op re-stamped. The per-node GUM content is the product/quotient rows of GUM Table §4.4: at a
product the two quadrature terms are u_a|b| and |a|u_b, at a quotient u_a/|b| and
(|y|u_b)/|b|, the latter written through the transposed witness k = k_1/k_2 \Rightarrow k\cdot
k_2 = k_1 so the intermediate |y|u_b is itself a kinded product, not unkinded scratch.
Lean code for Definition19.6.11●1 definition
Associated Lean declarations
-
inductivedefined in PropertyKindCalculus/Uncertainty/BudgetDag.leancomplete
inductive PropertyKindCalculus.Uncertainty.BudgetExpr (R : Type) : PropertyKindCalculus.KindOfProperty → Type
inductive PropertyKindCalculus.Uncertainty.BudgetExpr (R : Type) : PropertyKindCalculus.KindOfProperty → Type
**A kinded ×/÷ uncertainty-budget expression** at output kind `k`. Every `mul`/`div` node carries its kind-law witness as a constructor field — the `ProductKind`/`QuotientKind` edges of `UNCERTAINTY.md` §4.4 residual item 2, threaded through the multi-node graph — so an ill-kinded expression is unwritable, and every interpretation below inherits the gates by construction. The expression is a *tree*: writing a shared subterm twice states, by construction, that its two occurrences are independent (the same independence assumption `combinedQ`'s flat quadrature makes globally).
Constructors
PropertyKindCalculus.Uncertainty.BudgetExpr.leaf {R : Type} {k : PropertyKindCalculus.KindOfProperty} (q : PropertyKindCalculus.Uncertainty.EstimateQ k R) : PropertyKindCalculus.Uncertainty.BudgetExpr R k
An input leaf: a point estimate with its standard uncertainty, at the leaf's kind.
PropertyKindCalculus.Uncertainty.BudgetExpr.mul {R : Type} {k1 k2 k : PropertyKindCalculus.KindOfProperty} (h : PropertyKindCalculus.ProductKind k1 k2 k) (a : PropertyKindCalculus.Uncertainty.BudgetExpr R k1) (b : PropertyKindCalculus.Uncertainty.BudgetExpr R k2) : PropertyKindCalculus.Uncertainty.BudgetExpr R k
A product node `y = a·b`, licensed by `ProductKind k1 k2 k`.
PropertyKindCalculus.Uncertainty.BudgetExpr.div {R : Type} {k1 k2 k : PropertyKindCalculus.KindOfProperty} (h : PropertyKindCalculus.QuotientKind k1 k2 k) (a : PropertyKindCalculus.Uncertainty.BudgetExpr R k1) (b : PropertyKindCalculus.Uncertainty.BudgetExpr R k2) : PropertyKindCalculus.Uncertainty.BudgetExpr R k
A quotient node `y = a/b`, licensed by `QuotientKind k1 k2 k`.
Realized (Stage 3.4 extension, residual 2; Uncertainty.BudgetDag, Mathlib/Torch-free,
carrier-generic over [NumCarrier R]). The transposed witness is QuotientKind.toProductKind
(QuantityClassification); the value component rides along unperturbed
(propagateQ_value_eq_valueQ). Deliberately no add/sub nodes — the homogeneous linear case is
already the flat kinded budget fed by autograd sensitivities, so tree
+/− would be a second authoring of the same quadrature. Exercised on the block-density model
\rho = m/((l\cdot w)\cdot h) (UncertaintyExamples.BudgetDagDensity): five distinct kinds through
one budget — untypeable under the significance wiring's single shared input kind — with #guards
reproducing \rho = 2500, the per-leaf contributions (1.0, 2.5, 5.0, 25.0), and
u_c = \sqrt{657.25} \approx 25.637, and #check_failure probes making the operand swap, the
heterogeneous quadrature, and the kind-misplaced leaf type errors.
The threaded propagation collapses to the flat quadrature. Over ℝ, the uncertainty the
budget DAG accumulates node-by-node — a \sqrt{\ } at every node,
re-squared by the parent — telescopes exactly, not up to a bound, to the flat
combinedQ quadrature over the flattened per-leaf-occurrence
contributions. Relative to the flat single-quadrature baseline the DAG machine therefore adds
threading only, never a second combination rule: it is a conservative generalization of the kinded
budget, not a second authority over the same GUM content.
Lean code for Theorem19.6.12●1 theorem
Associated Lean declarations
-
theoremdefined in PropertyKindCalculus/Uncertainty/BudgetDagLaws.leancomplete
theorem PropertyKindCalculus.Uncertainty.BudgetExpr.propagateQ_unc_eq_combinedQ {k : PropertyKindCalculus.KindOfProperty} (e : PropertyKindCalculus.Uncertainty.BudgetExpr ℝ k) (hne : e.NonnegUncs) : e.propagateQ.unc = PropertyKindCalculus.Uncertainty.combinedQ e.contribsQ
theorem PropertyKindCalculus.Uncertainty.BudgetExpr.propagateQ_unc_eq_combinedQ {k : PropertyKindCalculus.KindOfProperty} (e : PropertyKindCalculus.Uncertainty.BudgetExpr ℝ k) (hne : e.NonnegUncs) : e.propagateQ.unc = PropertyKindCalculus.Uncertainty.combinedQ e.contribsQ
**The collapse law.** For every expression with nonnegative leaf uncertainties, the uncertainty `propagateQ` accumulates node-by-node — `√` at every node, re-squared by the parent's quadrature — telescopes *exactly* to the flat `Budget.combinedQ` quadrature over the flattened per-leaf contributions `contribsQ`. Relative to the flat single-quadrature `Budget` baseline, the DAG machine therefore adds threading only, never a second combination rule: the faithful- generalization fact the `BudgetDag` design promises (faithful in the logical sense, not a statistical never-understates claim). Proof: structural induction; `Quantity.ext` reduces each case to a magnitude identity; the leaf case is `√(u·u) = u` — the one place the `NonnegUncs` hypothesis is spent; the node cases rewrite both sides into `Real.sqrt`-of-`sumSq` normal form (`combinedQ_magnitude_real`, `sumSq_append`, the `sumSq_map_*` family, with sub-values renamed through the core `propagateQ_value_eq_valueQ`), re-express each child radicand `S` as `√S·√S` (`Real.mul_self_sqrt`, licensed by `sumSq_nonneg`), and close by `ring`. There are **no divisor-nonzero hypotheses**: division is `ℝ`'s totalized `x / 0 = 0` and both sides degenerate identically at a zero divisor (`sumSq_map_div` holds there too). The statistical meaningfulness of the specified first-order linearization near a zero divisor is a caveat on the specification, not a hypothesis of this bookkeeping law.
Realized over ℝ (Uncertainty.BudgetExpr.propagateQ_unc_eq_combinedQ, in BudgetDagLaws), under a NonnegUncs
hypothesis (nonnegativity of every leaf uncertainty — statable only at the ordered proof carrier, the
core NumCarrier being deliberately branchless). Structural induction: Quantity.ext reduces each
node to a magnitude identity in the sumSq sum-of-squares vocabulary (sumSq_append, the scaled
families sumSq_map_mul_left/_right/_div), each child radicand re-expressed as \sqrt{S}\cdot
\sqrt{S} (Real.mul_self_sqrt) and closed by ring. No divisor-nonzero hypotheses — division is
ℝ's totalized x/0 = 0 and both sides degenerate identically. Sorry-free (#print axioms →
[propext, Classical.choice, Quot.sound], pinned in BudgetDagDensity). Two textbook
relative-uncertainty corollaries (mul_leaf_relative_quadrature, div_leaf_relative_quadrature)
give (u_y/|y|)^2 = (u_a/|a|)^2 + (u_b/|b|)^2 for single nodes, there needing the nonzero-value
hypotheses relative uncertainty divides by.