Skip to content

proof(#2080): derive contract naming invariant from compiled internal table#2118

Merged
Th0rgal merged 1 commit into
paloma/issue-2080-selector-dispatch-withinternalsfrom
paloma/issue-2080-compiled-internal-naming
Jul 7, 2026
Merged

proof(#2080): derive contract naming invariant from compiled internal table#2118
Th0rgal merged 1 commit into
paloma/issue-2080-selector-dispatch-withinternalsfrom
paloma/issue-2080-compiled-internal-naming

Conversation

@Th0rgal

@Th0rgal Th0rgal commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary

Threads the runtime contract's internal-table naming invariant into the whole-contract dispatch seam by deriving it from the structural compilation fact — every internal-table statement is a compileInternalFunction output — instead of taking InternalTableNamesInternalPrefixed as an opaque hypothesis.

Stacked on top of paloma/issue-2080-selector-dispatch-withinternals (PR #2117's WithInternals selector seam).

New lemmas (Compiler/Proofs/IRGeneration/Function.lean)

  • internalFunctionYulName_take_prefix — a compiled internal helper's Yul name carries the internal_ prefix.
  • compileInternalFunction_isFuncDef_internalNamed — a compileInternalFunction output is a FunctionDefinition whose name is internal_-prefixed.
  • InternalTableNamesInternalPrefixed_of_all_compiledInternal — lifts the above to the whole runtime internal table.

New consumer seam (Compiler/Proofs/IRGeneration/Contract.lean)

  • compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_compiledInternalTable — takes the structural "all internal-table stmts are compiled internal helpers" premise, derives the naming invariant, and delegates to the _of_internalNamesPrefixed sibling. The body is a single term application; the length is entirely the mirrored premise list (allowlisted in check_proof_length.py).

Validation

  • lean-slot lake build Compiler.Proofs.IRGeneration.Function — green
  • lean-slot lake build Compiler.Proofs.IRGeneration.Contract — green (1144/1144, with the new seam)
  • lean-slot lake build Compiler.Proofs.HelperStepProofs — green (1139/1139)
  • python3 scripts/generate_print_axioms.py --check — OK (5551 -> 5555 theorems, 0 sorry'd)
  • python3 scripts/check_proof_length.py — pass
  • git diff --check — clean
  • No new sorry/admit/axiom in touched proof files
  • lake build PrintAxioms — running in CI (constructive proofs only; no new axioms expected)

Test plan

  • CI green (full lake build, PrintAxioms axiom footprint, proof-length gate)

Do not merge until the base PR lands.


Note

Low Risk
Lean proof-only changes with no runtime or auth logic; risk is limited to proof maintenance and CI gates (PrintAxioms, proof length).

Overview
Adds proof plumbing so whole-contract helper-aware correctness can assume every runtime internal-table stmt came from compileInternalFunction, instead of supplying InternalTableNamesInternalPrefixed by hand.

In Function.lean, three lemmas chain compilation shape to naming: internalFunctionYulName_take_prefix, compileInternalFunction_isFuncDef_internalNamed, and InternalTableNamesInternalPrefixed_of_all_compiledInternal.

In Contract.lean, compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_compiledInternalTable mirrors the _of_internalNamesPrefixed wrapper but takes hcompiledTable and derives the naming invariant before delegating to execIRFunctionWithInternals (no manual param-load disjointness witness).

PrintAxioms.lean and check_proof_length.py register the new public theorem (+4 lemmas, allowlist entry).

Reviewed by Cursor Bugbot for commit 455906f. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds the structural lemmas that let the whole-contract dispatch seam
discharge the internal-table naming invariant instead of taking it as an
opaque premise:

- internalFunctionYulName_take_prefix: a compiled internal helper's Yul
  name carries the `internal_` prefix.
- compileInternalFunction_isFuncDef_internalNamed: a compileInternalFunction
  output is a FunctionDefinition whose name is internal_-prefixed.
- InternalTableNamesInternalPrefixed_of_all_compiledInternal: lifts those to
  the whole runtime internal table.

Contract.lean gains the consumer seam
compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_compiledInternalTable,
which derives the naming invariant from the structural fact that every
internal-table statement is a compileInternalFunction output, then delegates
to the _of_internalNamesPrefixed sibling. Body is a single term application;
allowlisted in check_proof_length.py for the mirrored premise list.

PrintAxioms.lean regenerated: 5551 -> 5555 theorems, 0 sorry'd.
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
verity Ready Ready Preview, Comment Jul 7, 2026 6:07pm

Request Review

@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_92a49885-92f5-4b23-b053-80ff107b34ad)

@Th0rgal

Th0rgal commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

Review (automated) — commit 455906ff

Reviewed the single-commit diff in an isolated worktree. Proof content looks sound and merge-ready in isolation:

  • Function.lean — three new lemmas are coherent and non-vacuous:
    • internalFunctionYulName_take_prefix — structural fact that a compiled helper's Yul name carries the internal_ prefix.
    • compileInternalFunction_isFuncDef_internalNamed — mirrors compileInternalFunction_ok_components' case analysis to extract the emitted name.
    • InternalTableNamesInternalPrefixed_of_all_compiledInternal — lifts the above to the whole runtime internal table via filterMap/irInternalFunctionDefOfStmt?. This derives the naming invariant from the real compilation fact rather than hiding the proof(L2): Tier 2 — internal helper call preservation (close the 4 remaining interface goals) #2080 gate behind a vacuous/empty-table assumption.
  • Contract.lean..._of_compiledInternalTable is a single term application delegating to the existing ..._of_internalNamesPrefixed sibling; the new hcompiledTable premise is a genuine structural obligation, not a soundness hole.
  • check_proof_length.py — one narrow, justified allowlist entry (signature-dominated wrapper, single-term body).
  • PrintAxioms.lean — regeneration consistent: 5551 → 5555 (+4 public), 0 sorry'd. No new sorry/admit/axiom introduced; git diff --check clean.

Merge blocker: this PR is stacked on #2117 (paloma/issue-2080-selector-dispatch-withinternals), which is still open/unmerged (its own base is paloma/issue-2080-function-exec-withinternals). Per the stacked-PR policy this slice must not be merged into an open predecessor branch ahead of bottom-up landing. CI core checks (build, checks, changes) are green; build-audits and build-compiler-binaries were still running at review time. No review threads; Cursor Bugbot reported "couldn't run — usage limit reached" (no findings, not a resolvable thread).

Next step: land the predecessor stack (#2117 and below) first, then re-target/merge this slice.

@Th0rgal Th0rgal merged commit 58b02cf into paloma/issue-2080-selector-dispatch-withinternals Jul 7, 2026
21 checks passed
Th0rgal added a commit that referenced this pull request Jul 8, 2026
#2119)

Package the structural premise that a runtime contract's internal-function
table is generated by `compileInternalFunction`, then feed PR #2118's
`_of_body_goal_of_compiledInternalTable` seam with that premise derived from
the real compilation pipeline instead of taken as a hypothesis.

New lemmas (Compiler/Proofs/IRGeneration/Contract.lean):
- `compileInternalFunction_mapM_mem_exists`: every statement in the
  `internalFns.mapM compileInternalFunction` image is a `compileInternalFunction`
  output. Non-vacuous for a populated `internalFns`; no `internalFunctions = []`
  default-empty helper-world assumption.
- `compiledInternalTable_of_internalFunctions_eq_mapM`: packages that image into
  the exact existential shape of the seam's `hcompiledTable` premise.
- `compiledInternalTable_of_compileValidatedCore`: discharges the premise from a
  real `compileValidatedCore` output (currently via the SupportedSpec nil table).
- `compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_compileValidatedCore`:
  whole-contract dispatch consumer that invokes the #2118 seam with
  `hcompiledTable` discharged from the pipeline, so the runtime contract whose
  `execIRFunctionWithInternals` dispatch is proven is exactly the compiled one.

Regenerated PrintAxioms.lean and allowlisted the signature-dominated consumer in
check_proof_length.py (matching its `_of_compiledInternalTable` sibling).

Refs #2080
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant