Semantic bridge ingredients for rich row-proof leaves #
This module deliberately does not yet add a PTree constructor. It records
the pointwise arithmetic facts which turn the executable W1--W5 receipts into
closed-face data. Keeping these facts independent of the tree is useful: a
rich leaf is evaluated at a single integral point before its block endpoints
are decoded into a DegSpec.PiecewiseData and its chips into a weighted
divisor.
The remaining assembly is not a matter of weakening the checker. It needs a
finite-list decoder which supplies PiecewiseData.covers,
PiecewiseData.ownsInterval, and PiecewiseData.balance, together with the
two residual comparison lemmas documented at the end of this file.
Evaluation of a named point. This is kept as an integer: W1 first proves
nonnegativity, after which the lowerer may take toNat to obtain a path
offset.
Equations
- w.pointValue x a e i = Utilities.Subdivision.ClosedRowProof.eval (w.point a e i) x
Instances For
Evaluation of a declared block length.
Equations
- w.blockLengthValue x a e i = Utilities.Subdivision.ClosedRowProof.eval (w.blockLength a e i) x
Instances For
Consecutive named points differ by the length of the intervening block.
This is the arithmetic form of the RPF convention that point i + 1 is the
right endpoint of block i.
W1 monotonicity receipts make the evaluated named points weakly ordered. The index bounds are explicit because a rich block list is only constrained on its declared finite prefix.
Every named point through the final endpoint is nonnegative. This is the
integer fact needed before W1 endpoints can be decoded with Int.toNat.
W1's final endpoint equality bounds every named point by the slot length.
A positive evaluated named point separates all earlier named points from the tail. This is the arithmetic W1 bridge used to bound a collapsed prefix.
The head-side counterpart: a named point strictly before the slot length separates every later point at the head.
W3 shape facts #
The physical chip decoder needs only the two structural consequences of W3:
every raw slot index is genuine, and for every anchor a chip is syntactically
one of that slot's named interior endpoints. The latter becomes an equality
of evaluated positions through eval_eq_of_formEq.
W3's syntactic named-point witness has the expected geometric meaning at every parameter point: the raw form evaluates to that named endpoint.
W1's final named endpoint is the coordinate form for its slot.
W1's monotonicity certificate says precisely that the evaluated block length is nonnegative. This is the local fact used to order the decoded block ends.
The lower W2 receipt gives the numerical lower endpoint-slope bound for one decoded block.
The upper W2 receipt gives the numerical upper endpoint-slope bound for one decoded block.
A zero-length block has zero declared rise. This is the W2 fact which allows repeated finite endpoints to be discarded by canonical interpolation without changing the total potential change.
Extract the two numerical W2 receipts for a declared block.
Indexed version of eval_foldl_addForm, matching the RPF representation
where a finite list of block indices selects the forms to add.
The ordered finite list range k computes the same additive sum as the
finite-set presentation used by the piecewise interpolation interface.
W2 closure, evaluated at a point, is the finite sum of all declared block
rises. This is the arithmetic input to piecewise_balance_of_total_rises.
On a zero-length slot, W1 collapses every block and W2 makes every rise zero; consequently the evaluated anchor potential agrees across the slot.
Equality along every edge of a contracted set transports along the census
reachability relation. This is the small graph-theoretic bridge from the
zero-slot lemma to DegSpec.RepInvariant.
The evaluated potential of a rich anchor is invariant on every contraction class of the census face.
W4: collapsed boundary runs #
At a named interior vertex the only possible negative contribution of the piecewise script is the jump from the last slope before a run of coincident named endpoints to the first slope after it. The checker deliberately uses the lower bound of the outgoing block and the upper bound of the incoming block, so its integer residual is a lower bound for the actual coefficient.
The lemmas in this section are phrased without a subdivision graph. This is intentional: decoding named forms into a closed-face vertex is the only graph-specific part of the eventual proof, while the W4 arithmetic is exactly the calculation below. In particular repeated endpoints (zero-length blocks) need no special case: they simply enlarge the run.
The chip sum used by W4, written in the same List.range/foldl form as
the executable checker.
Equations
- Utilities.Subdivision.ClosedRowProof.RichWitness.w4ChipSum chip i j = List.foldl (fun (z : ℤ) (t : ℕ) => z + chip (i + t)) 0 (List.range (j + 1 - i))
Instances For
This is definitionally the chip portion of the executable W4 residual.
Keeping the bridge explicit avoids a later proof depending on the particular
implementation of w4Residual.
The actual coefficient at a collapsed named-endpoint run: chips on the run plus outgoing slope minus incoming slope.
Equations
- Utilities.Subdivision.ClosedRowProof.RichWitness.w4Actual chip incoming outgoing i j = Utilities.Subdivision.ClosedRowProof.RichWitness.w4ChipSum chip i j + outgoing - incoming
Instances For
The numerical residual checked by W4 is a lower bound for the actual coefficient whenever W2 bounds the two bordering slopes.
A strict W4 separation receipt rules out the only situation in which its corresponding run has to be tested: all named endpoints of that run decoding to the same closed-face vertex.
The local W4 soundness step. If the endpoints collapse, the strict separation alternative is impossible, hence a nonnegative checked residual remains; W2 then promotes it to nonnegativity of the actual divisor coefficient.
Extract one of the two W4 alternatives for an admissible interior run.
The executable checker enumerates the run by q = i - 1 and r = j - i;
this lemma exposes the geometric indices directly, so the closed-face proof
can feed a collapsed run to w4_actual_nonneg_of_checked.
The finite endpoint list decoded from an evaluated rich slot. Its entry
i is named point i + 1, so it is the end of block i.
Equations
- w.endpointValues x a e k = List.map (fun (i : ℕ) => (w.pointValue x a e (i + 1)).toNat) (List.range k)
Instances For
W1's nonempty, monotone endpoint data decodes to the finite selector
required by canonical piecewise interpolation. The input hLast is the
evaluated W1 final-end equality; all block lengths are integral and the
nonnegative receipts make the Int.toNat conversion exact.
Equations
- w.finiteBlockEndsOfW1 x a e k L hNonempty hLast hLength = MarkedGraphs.Certificate.FiniteBlockEnds.ofOrderedLast (w.endpointValues x a e k) ⋯ ⋯ ⋯
Instances For
The finite endpoint selector decoded from an accepted rich W1 block list on a concrete closed face.
Equations
- Utilities.Subdivision.ClosedRowProof.RichWitness.richBlockEnds d w core Γ x hW1 hx hCoord a e = w.finiteBlockEndsOfW1 x (↑a) (↑e) (w.blockList ↑a ↑e).length (d.length e) ⋯ ⋯ ⋯
Instances For
On an actual rich block, the finite decoder's endpoint is exactly the
evaluated named right endpoint. Keeping this lookup lemma separate makes
the W2 empty-block bridge below independent of the proof fields stored in
FiniteBlockEnds.ofOrderedLast.
Beyond a declared rich block list, the fail-closed default block has zero rise, so it contributes nothing to the interpolation sum.
If an actual decoded rich block has an empty finite interval, then W1
makes its evaluated length zero and W2 forces its declared rise to vanish.
This is the exact bridge needed by PiecewiseData.empty_rise: repeated
finite endpoints are harmless even when their RPF block records remain in
the list.
Once W2 has made every collapsed block's rise zero, its closure equality
is exactly the balance field required by PiecewiseData. This is independent
of the RPF list encoding and is the final arithmetic conversion used by the
rich-leaf decoder.
The canonical piecewise interpolation data for one rich anchor on the census face selected by the current length vector.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The firing script denoted by the decoded rich block data.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The rich script's unit slopes are precisely its selected canonical block slopes; this is the entry point for the W4 interior coefficient calculation.
W4: selector changes on a rich closed face #
The finite selector sees a forward jump precisely when a consecutive run of
named endpoints has collapsed to the intervening subdivision vertex. The
two lemmas below isolate that geometric fact from the subsequent chip-divisor
accounting. Their indices agree with the checker: if the old selected block
is i, then its named right endpoint is i + 1, while the new block is j.
A forward change of the decoded rich block selector identifies the two named forms at the ends of the collapsed run. This is the geometric premise which rules out W4's strict-separation alternative.
W4 promotes its checked residual to the actual slope-jump coefficient at a forward rich-selector change, once W2 has supplied the bordering slope bounds. The caller supplies the two bounds so this lemma can be used with the canonical script as well as any extensionally equal slope presentation.
W5: finite endpoint minima #
The checker stores a conservative endpoint contribution as a finite minimum. The geometric part of the closed-face proof supplies a particular prefix (or suffix) length; this lemma is the deliberately small arithmetic bridge from that selected candidate to the stored minimum.
Required next bridge lemmas #
The following are the exact nontrivial obligations left before a theorem
richLeafChecks_sound can be assembled.
decode_piecewise: from the W1 monotonicity/final-end facts and the W2 receipts atx, constructd.PiecewiseData potential. Its proof requires a finite monotone-list selector (first block end strictly above a surviving step) and a telescoping lemma saying that the canonicalsteps over a block sum to its declared rise. The latter is not currently exported bySubdivisionArithmetic.w4_boundary_effective: identify a change of decoded block at an interior offset with a maximal run of named endpoints which evaluate to that offset. The W4 residual is the chip sum on this run plus the lower bound on the outgoing first slope minus the upper bound on the incoming last slope.DegSpec.prin_piecewiseScript_interiorVertex_nonneg_of_sameBlockalready handles the complementary (non-boundary) case.w5_core_effective: after a prefix/suffix of named points collapses into a core class, compare the actual first/last selected slopes and all chips which decode to that class withtailContribution/headContribution.w5Checksthen proves each uncontracted core summand nonnegative; summing it over a representative class and usingDegSpec.prin_piecewiseScript_coreVertexproves the quotient-core case.Current formal interface obstruction.
RichWitness.chipsis still a rawList (Nat × Form × Int), whereas the closed-face library's only chipwise divisor API isClosed.WeightedChip.divisorOf, which accepts boundedCodes from anExplicitPotential.CertificateData. A rich leaf has neither of those objects. Consequently the library has no definition for the rich chip divisor ond.graph, nor a coefficient theorem saying that chips which decode to the tail/head are exactly the C-faithful first-matchedchipPrefix/suffix sums. W3 is enough to prove the needed bounds after such a decoder exists, but cannot state that comparison. The necessary next artifact is a row-local decoder from the raw rich chips and evaluated named endpoints toCFDiv d.graph, with core/interior coefficient formulae. The checker now assigns a chip to its first matching named interior endpoint, matchingrpfcheck.c; the decoder theorem must preserve that convention when zero-length blocks duplicate endpoint forms.
The last two lemmas must use Closed.WeightedChip.divisorOf (or an equivalent
row-local decoder), because a named point may become either endpoint on a
closed face. Treating every declared chip as an interior vertex would be
incorrect when a block collapses.