feat(realizability): generalize and pre-upstream the VCVio polytime machine layer - #113
Open
dtumad wants to merge 3 commits into
Open
feat(realizability): generalize and pre-upstream the VCVio polytime machine layer#113dtumad wants to merge 3 commits into
dtumad wants to merge 3 commits into
Conversation
…e draft Adds the pieces VCVio's polytime draft (Verified-zkEVM/VCVio#500) carries locally with `-- upstream candidate for DynComputation` comments, plus one `FreeM` bound lemma they will need. `DynComputation`: * `ofStep` — build a returning computation from a raw one-step transition plus an initialization. Reducible, so `view` reads the supplied data back transparently; this is the primary constructor for a hand-built machine. * `setInit` — replace the initialization while keeping the dynamics. Reducible, so computations sharing `toMachine` share every derived step map definitionally. `DynComputation/Bounded`: * `unroll_setInit`, `unroll_mapResult`, `unroll_wrap` and their `run_*` corollaries. The `setInit` case needs a fuel induction rather than `rfl`, because `view` does not unify automatically across the input-type change. `PFunctor.Bound`: * `isTotalRollBound_mapLens` — a lens relabels positions and reindexes directions, leaving the number of rolls along each branch untouched. All additions; no existing declaration changes behaviour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lass New `PolyFun/Realizability/` subtree. Answers "can this `FreeM` program be run by a machine whose transition functions satisfy a given predicate?", generically in the predicate. `StepClass` is a wide subcategory of `Type u` presented pointwise: a representation structure `Str` on types plus an admissibility predicate `Hom` on functions, closed under identities and composition. With the `HasProd`, `HasSum` and `IsDistributive` mixins it is exactly a distributive category (Cockett 1993; Carboni–Lack–Walters 1993) presented concretely over `Type`. `HasOption` records that the flattened transition is partial. `Machine.lean` re-presents `DynComputation`'s dynamics as first-order maps a predicate on functions can constrain: `head` (definitionally the position map of the machine's lens) and the partial `update?`. `updateFlat`, `output`, `expose` and `stepD` are derived, for a machine-facing cost model. `ofStep_step_eq_of_flat_eq` shows the presentation is faithful. `Basic.lean` defines `Boundary`, `Realization`, `IsRealizableBy` and `IsRealizableWithin`. `Closure.lean` proves closure under `ofFn`, input precomposition, result postcomposition, `seqComp` (i.e. `FreeM.bind`, with budgets adding), interface transport along an admissible lens, and refinement of the ambient class. `Instances.lean` gives four classes: unconstrained (with a non-vacuity theorem), finite (finite-state realizability), computable (Mathlib `Primcodable` / `Computable`), and `WordClass` — the bridge from a monomorphic class of word functions, which is how external complexity libraries present themselves. Design note: `update?` is partial rather than total because the total convention does not compose across a state coproduct with a handoff. On a mismatched answer tag the composite stays in the left summand while the second phase alone would stay at its own initial state, and reconciling those junk values would require the class to contain a decidable equality test on interface positions — not derivable from products, coproducts and distributivity. With `none` both agree and `update?_seqComp_inl` holds unconditionally in the answer index. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dtumad
marked this pull request as ready for review
August 6, 2026 17:51
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a generic notion of "this
FreeMprogram can be run by a state machine whosetransition functions satisfy a given predicate", and upstreams the machine-side
helpers that VCVio#500 currently
carries locally with
-- upstream candidate for DynComputationcomments.Qualitative only: it constrains which machines are allowed, not how much they cost.
Commit 1 — additions to the existing dynamical layer
PolyFun/PFunctor/Dynamical/DynComputation.leanofStep (stepFn : S → β ⊕ p.Obj S) (init : α → S)—@[reducible], withofStep_State,ofStep_init,view_ofStep.setInit (M) (g : γ → M.State)—@[reducible], withsetInit_State,setInit_init,setInit_view,setInit_denote,contramapInput_eq_setInit.PolyFun/PFunctor/Dynamical/DynComputation/Bounded.leanunroll_setInit,unroll_mapResult,unroll_wrapandrun_setInit,run_mapResult,run_wrap.PolyFun/PFunctor/Bound.leanisTotalRollBound_mapLens.All additions; no existing declaration changes behaviour. Builds standalone.
Commit 2 — new
PolyFun/Realizability/subtreeEntered in the DAG after the
ITreeblock. Nothing underPFunctor/,ITree/orInteraction/depends on it.StepClass.leanStepClass;HasProd/HasSum/HasOption/IsDistributivemixins;Distributivebundle; derived combinators;RefinesMachine.leanhead,update?,updateFlat,output,expose,stepD; transport lemmas;seqCompstep lemmas;ofStep_step_eq_of_flat_eqBasic.leanBoundary(+withInput,withOut,withInterface,mid,Composable,mapRefines),Realization,IsRealizableBy,IsRealizableWithinClosure.leanLens.pullHeadIdx,Lens.IsAdmissibleInstances.leanunconstrained,finite,computable,WordClassThe class of admissible functions
Stris data, not a proposition: a resource bound only makes sense relative to achosen representation. Mixins are separate so each theorem asks for exactly what
it consumes —
HasProd,HasSum,HasOptionfor the core definition,IsDistributiveforseqComponly.Derived in
StepClass.lean:Hom.congr,HasProd.{map_mem, pairRight_mem, pairLeft_mem, diag_mem, withInput_mem, swap_mem, assoc_mem},HasSum.map_mem,codistrib_mem,IsDistributive.elimCtx_mem.The first-order step maps
DynComputation's dynamics live inview : State → β ⊕ p.Obj State, whose secondcomponent is function-valued and dependent — neither shape can be constrained by a
predicate on plain functions.
Machine.leanre-presents them as:headis definitionally the position map of the machine's underlying lens, sosetInit,mapResultandwraptransport it byrfl.updateFlat,output,expose,stepDare the derived accessors a machine-facing cost model consumes.ofStep_step_eq_of_flat_eq: a step function is determined by theheadandupdate?it induces, so these are a presentation rather than a projection.The predicate
A
Realizationbundles a machine, a representation of its hidden state, andadmissibility of
init,head,update?. Constraininginitis what forbidssmuggling precomputed advice into the initial state.
Boundarycollects the representations at the boundary and is always aparameter:
∃ bd, IsRealizableBy C bd programwould be vacuous, since arepresentation is only required to be admissible, not canonical. Only the state
representation is chosen by the realization.
Closure
isRealizableBy_ofFn,isRealizableBy_pureIsRealizableBy.precomp,IsRealizableWithin.precompIsRealizableBy.mapResult,IsRealizableWithin.mapResultIsRealizableBy.seqComp,IsRealizableWithin.seqComp[C.IsDistributive]; budgets addIsRealizableBy.wrap,IsRealizableWithin.wrapLens.IsAdmissibleIsRealizableBy.mono,IsRealizableWithin.mono'StepClass.RefinesPlus
IsRealizableWithin.{isRealizableBy, isTotalRollBound, mono}andcongrinBasic.lean.bindclosure is listed as out of scope in VCVio#500's model.Distributivity is consumed in exactly two places, both inside the composite
update?: splitting on the state summand, then on the first phase's readout. Thecomposite
headneeds no products at all.Instances
Str/HomunconstrainedPUnit/TrueisRealizableBy_unconstrained: realizability collapses to∃ M, M.Implements programfiniteFintype/TrueIsFiniteStateRealizableabbrevcomputablePrimcodable/ComputableWordClassW/ an intertwiningW → Win the classWordPairing,WordTagging,WordDistribTwo design points a reviewer should check
update?is partial. The total convention (identity on junk) does not composeacross a state coproduct with a handoff:
updateFlatSum.inr (M₂.updateFlat (M₂.init v, i))M₂'s exposed positionSum.inr (next₂ d)Sum.inr (next₂ d)✓Sum.inl s₁Sum.inr (M₂.init v)✗Reconciling those junk values needs the class to contain a decidable equality test
on interface positions, which is not derivable from products, coproducts and
distributivity. With
noneboth rows agree, the both-phases-returned case issubsumed, and
update?_seqComp_inlholds unconditionally in the answer index.updateFlatkeeps its name and meaning, so VCVio#500's four-witness cost model isunaffected.
headrather than anoutput/exposepair. VCVio#500 splits the readout,which forces a
defaultat resolved states; that convention breakscompositionality, since
(M.wrap lens).expose ≠ lens.toFunA ∘ M.exposeexactly atresolved states.
headhas no such wart.outputandexposeare still provided,derived.
Naming
With
HasProd,HasSumandIsDistributive, aStepClassis a distributivecategory (Cockett, MSCS 1993; Carboni–Lack–Walters, JPAA 1993) presented
concretely over
Type. The cogap direction of the canonical map is derivable fromproducts and sums alone and ships as
codistrib_mem, so both directions areadmissible and this is the standard axiom rather than a weakening.
Mathlib's
CategoryTheory.IsCartesianDistributivecites the same papers, butMorphismProperty (Type u)cannot type aHomindexed by representations, soonly the name and axiom are reused. Mathlib states the axiom in the cogap
orientation; our
distrib_memfield is the inverse, and says so.Not included
HomisProp-valued, so nothing here measuresrunning time or description size, which is what makes VCVio#500's model
quantitative. The successor needs
Homreplaced by aType-valued witnesscarrying measures in an ordered semiring. From the audit of #500, it needs
id,comp,copy(pointwise-equal transport, 9 call sites there),recode, withconst/ofFintypeas caller obligations — and no product or sum combinators.Responder,WiredRun,CoinFold,PolyTimeNontrivial,ToMathlib/Computability/) stays in VCVio.ImplementsWithinoff a uniformℕbudget.Validation
./scripts/validate.sh --lint --testgreen: build (2019 jobs), module scopes,umbrella imports, docs integrity,
lake lint,lake test.sorry; no disabled linters. Axiom footprints ofIsRealizableBy.seqComp,IsRealizableWithin.seqComp,IsRealizableBy.wrap,IsDistributive.elimCtx_mem,ofStep_step_eq_of_flat_eqare all within[propext, Classical.choice, Quot.sound]; several are axiom-free.PolyFunTest/Realizability/Examples.lean: a concrete two-state machine realizinga one-query program, two of them composed under
bindat budget1 + 1, and therfltransport lemmas pinned so a regression tomatchin a step-map definitionfails the test build.
docs/wiki/realizability.mdadded; DAG block indocs/wiki/repo-map.md;AGENTS.mdrepo map and Further Reading; sevenREFERENCES.mdentries.Open items
updateFlatkeeps its name and meaning, and#500's local
output/expose/stepD/ofStep/setInitcan be deletedin favour of these — wants confirming against a real checkout before merge.
Lens.IsAdmissiblehas no.idor.comp:pullHeadIdxcompares the incominganswer's tag against the position the lens exposes, so even the identity lens's
pullback performs an equality test on positions. Admissibility of a lens is a
hypothesis about the class, not derivable from the mixins — which is also why
wrapneeds it andseqCompdoes not.HasOption.none_memis the one constant map this layer assumes (a machine thathas returned takes no step). Everything else takes constant-admissibility as a
per-theorem hypothesis.
WordClassneedsWordDistribbecauseWordTagging.elimhands each branch onlythe untagged payload, so a tag cannot be moved past a pairing using
elimalone.Consequence for real clients: complexitylib has the pairing ingredients
(
Complexity.pair,unpair?,delimit) but exposes no class-level closureresult, and cslib's
PolyTimeComputablehasid/compbut no pairing orprojection machines, plus a
Monotoneside condition oncompwhose removal isstill a
TODOupstream. Neither plugs in today without upstream work.🤖 Generated with Claude Code