Skip to content

Retarget public correctness toward native EVMYulLean#1822

Merged
Th0rgal merged 446 commits into
mainfrom
native-evmyullean-public-correctness
May 11, 2026
Merged

Retarget public correctness toward native EVMYulLean#1822
Th0rgal merged 446 commits into
mainfrom
native-evmyullean-public-correctness

Conversation

@Th0rgal
Copy link
Copy Markdown
Member

@Th0rgal Th0rgal commented May 3, 2026

Summary

Retargets Verity's public EVMYulLean correctness surface away from backend-parameterized oracle spellings and toward native EVMYulLean-named entry points, and lands the first wave of leaf ExecOnlyBridgeAtFuelRevived constructors so the Revived family covers every observational-no-op fn.body shape.

Public-surface retarget

  • Added interpretYulRuntimeEvmYulLean and interpretYulRuntimeEvmYulLeanFuel wrappers.
  • Retargeted the public Layer 3 and SimpleStorage EndToEnd theorem names to EVMYulLean conclusions.
  • Kept legacy/reference-oracle paths available under explicit ..._via_reference_oracle names; renamed the lower legacy Layer 3 theorem to yulCodegen_preserves_semantics_via_reference_oracle and guarded against restoring the bare oracle name.
  • Renamed native agreement seams from ...Interpreter to ...EvmYulLean.
  • Changed defaultBuiltinBackend to .evmYulLean; added legacyBuiltinBackend := .verity, legacyEvalBuiltinCallWithContext, and legacyExecYulFuel so old reference-oracle / bridge-comparison paths opt into legacy semantics explicitly.

Native EndToEnd surface

  • nativeResultsMatchOn, sourceResultMatchesNativeOn, source/native composition theorem over the result surface.
  • compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match, plus helper-free and mapping-helper lowering wrappers.
  • Concrete SimpleStorage native theorem; case freshness dispatcher adapters; mapping switch freshness wrappers.

Leaf Revived constructors (G1 increments S1–S4)

On NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived:

  • .of_block_emptyfn.body = [.block []]
  • .of_block_leavefn.body = [.block [.leave]]
  • .of_singleton_commentfn.body = [.comment text]

Together with the pre-existing .of_empty_body and .of_leave_body, the Revived family now covers every body of shape [], [.leave], [.block []], [.block [.leave]], [.comment text] — the full observational-no-op family. Concrete contracts whose user body is a label-only stub now have a direct Revived bridge without going through the halt path.

.of_comment_cons is intentionally deferred to the success-bridge wiring layer (per-leaf _with_label_prefix adapters); see docs/NATIVE_EVMYULLEAN_TRANSITION.md for the structural rationale.

Supporting infrastructure

  • New harness lemmas: exec_block_block_nil_ok_add_ten, exec_block_block_leave_ok_add_ten, exec_block_noop_block_head_eq, lowerStmtsNativeWithSwitchIds_comment_head_eq.
  • Source-side helpers: nativeResultsMatchOn_execIRFunction_block_empty_body_markedPrefix, ..._block_leave_body_markedPrefix, ..._singleton_comment_body_markedPrefix.
  • Updated native-transition guards/docs to enforce the new public surface and terminology.

Invariants

  • Zero sorry, zero new axioms.
  • lake build Compiler.Proofs.EndToEnd green.
  • make check validators (axioms, capability boundary, builtin boundary, doc check) pass.

Verification

  • lake build Compiler.Proofs.EndToEnd
  • lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeTest
  • python3 scripts/check_proof_length.py
  • python3 scripts/generate_print_axioms.py --check
  • python3 scripts/check_native_transition_doc.py
  • python3 scripts/test_check_native_transition_doc.py
  • python3 -m unittest scripts.test_evmyullean_capability
  • make check

Deferred to a follow-up PR

The composite body shapes and the final premise drop share heavy proof infrastructure (whole-block per-slot preservation, IR execIRStmts falling-through induction) that does not fit a single landable increment in this branch's budget. See docs/NATIVE_EVMYULLEAN_TRANSITION.md — the "G1 Incremental Plan" section has full constructor signatures, harness-lemma signatures, and proof sketches.

  • G1-S5 .of_nativePreservableStraightStmts_leave — bodies <straight-stmts>; leave. Companion lemma: execIRStmts_continue_of_nativePreservableStraightStmts_pre_leave (purely IR-side; recommended starting point for a follow-up worker).
  • G1-S6 .of_bridgedStraightStmts_falling_through — bodies <straight-stmts> (no terminator). Deepest case; requires aligning execIRFunction's fall-through extraction with the dispatcher's outer block exit.
  • G1-S7 Wire the five shipped leaves plus the two new constructors through NativeGeneratedSelectorHitSuccessBridge adapters, including per-leaf _with_label_prefix variants that strip a leading .comment "label" head via exec_block_noop_block_head_eq. Subsumes the deferred .of_comment_cons shape.
  • G1-S8 Drop hUserBodyHalt from compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher once S5–S7 land.

Long-standing items (orthogonal to this PR)

  • legacyExecYulFuel remains in ReferenceOracle/Semantics.lean for legacy/reference-oracle comparisons.
  • EvmYulLeanRetarget.lean still proves the EVMYulLean retarget by composing through yulCodegen_preserves_semantics_via_reference_oracle and backend comparison machinery.
  • The final native execution theorem path still has explicit bridge obligations and is not fully discharged for all compiler-generated contracts — the G1-S5..S8 follow-up is the path to discharging them.

Note

Medium Risk
Touches the public proof surface (arithmetic correctness lemmas) and CI caching/install logic; while semantics should be equivalent, regressions could break downstream proofs or CI reliability.

Overview
Retargets the public arithmetic proof surface to state wrapping/bitwise/shift facts directly in terms of the native evalPureBuiltinViaEvmYulLean evaluator, removing reliance on legacy oracle/bridge comparison lemmas while keeping historical theorem names.

Exposes compileMappingSlotRead and compileMappingSlotChain from ExpressionCompile.lean so proof modules can reference the exact lowering shapes, and trims top-level Compiler.lean imports to drop unused proof modules.

CI updates: adds a sticky-disk pruning step for stale Lake packages, increases verify.yml job timeout, and hardens setup-solc by caching per-version in-repo with PATH injection plus install/repair retries and version verification (instead of writing to /usr/local/bin).

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

\n### CI Failure Hints\n\nFailed jobs: `checks`\n\nCopy-paste local triage:\n```bash\nmake check\nlake build\nFOUNDRY_PROFILE=difftest forge test -vv\n```

Th0rgal and others added 25 commits May 9, 2026 08:38
Lays out an 8-step constructor pyramid for
NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived in the
remaining-work tracker. Each step is intended to land as a separately
green-buildable commit so that partial progress is durable even if the
deep generic BridgedStraightStmts step is not reached in one pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements G1 plan step 2: a generic constructor for
NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived covering selected
user bodies of the shape [.block [.leave]]. The native lowering produces
[.Block [.Leave]] which the outer dispatcher block wraps as
.Block [.Block [.Leave]] — closed by the new exec_block_block_leave_ok_add_ten
helper. The source side execIRFunction reduces the inner .block to its body
and a single .leave to .continue, observationally matching the native
post-reviveJump state.

This widens the success-side revived bridge surface by one shape without
modifying any existing constructor. lake build Compiler.Proofs.EndToEnd
remains green.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements G1 plan step 3: a generic constructor for
NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived covering selected
user bodies of the shape [.block []]. The native lowering produces
[.Block []] which the outer dispatcher block wraps as .Block [.Block []] —
closed by the new exec_block_block_nil_ok_add_ten helper. The source side
execIRFunction reduces the inner .block to its empty body returning
.continue stateWithParams, observationally matching the native post state
(no setLeave needed, so reviveJump is identity).

Mirrors .of_empty_body shape with one extra nested-block layer. No existing
constructor is modified. lake build Compiler.Proofs.EndToEnd remains green.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements G1 plan step 4: a generic constructor for
NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived covering selected
user bodies of the shape [.comment text]. The native lowering of .comment is
.Block [] (via lowerStmtGroupNativeWithSwitchIds_comment), so the
dispatcher-wrapped body becomes .Block [.Block []] — the same native shape
as .of_block_empty, closed by the existing exec_block_block_nil_ok_add_ten.
The source side execIRStmt of .comment is a no-op (.continue state), so the
observable projection matches the empty-body path. The text is existentially
extracted from the hypothesis so the constructor works for any concrete label.

Mirrors .of_block_empty native shape; no existing constructor is modified.
lake build Compiler.Proofs.EndToEnd remains green.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
A direct Revived-level .of_comment_cons recursive adapter is structurally
awkward: the Revived predicate's nativeGeneratedSelectorHitUserBodyFuel
depends on the full contract's fn.body size, so recursing into a stripped
tail body would require either a predicate refactor parameterizing over the
explicit body shape or duplicating the entire predicate logic inline.

Instead, the runtime dispatcher's `.comment "label" :: <real body>` shape
is handled at the NativeGeneratedSelectorHitSuccessBridge wiring (step 7):
each leaf Revived constructor pairs with a one-shot comment-prefix adapter
that strips the no-op label head, leaving <real body> to match an existing
leaf constructor.

Documentation-only change. lake build remains green.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the shipped Revived constructor family (.of_block_empty,
.of_block_leave, .of_singleton_comment, .of_leave_body, .of_empty_body) and
the technical sketches for the three deeper remaining steps:

- Step 5 (.of_nativePreservableStraightStmts_leave): cites the
  NativeBlockPreservesWord_lowerStmtsNativeWithSwitchIds_of_nativePreservableStraightStmts
  glue and proposes the execIRStmts_continue_of_nativePreservableStraightStmts_pre_leave
  companion lemma signature.
- Step 6 (.of_bridgedStraightStmts_falling_through): notes the
  function-end fall-through convention alignment between execIRFunction's
  post-execIRStmts extraction and the dispatcher outer block exit.
- Step 7 (success-bridge wiring + comment-prefix collapse).
- Step 8 (hUserBodyHalt premise drop).

Also regenerates PrintAxioms.lean to track the three new private theorems
added by .of_block_empty (commit fa980235), .of_singleton_comment (commit
f69044a1), and their source-side helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a top-level "PR 1822 — Achievement Summary" block to the native
EVMYulLean transition doc that calls out exactly what landed on
`native-evmyullean-public-correctness` (public-surface retarget, native
EndToEnd surface, leaf Revived constructors S1–S4 covering the full
observational-no-op body family, supporting harness lemmas, zero-sorry /
zero-axiom invariants) versus what is deferred to a follow-up PR (G1
steps S5–S8: the `<straight-stmts>; leave` and `<straight-stmts>`
falling-through constructors, success-bridge wiring with per-leaf
`_with_label_prefix` variants, and the final `hUserBodyHalt` premise
drop). Per-step status lines now read "shipped in PR 1822" or
"deferred to follow-up PR" so the document is self-contained as a
hand-off without consulting commit history.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test asserted that removing the canonical public-theorem mention from
the native transition doc makes `check_doc` report an error. It used
`replace(..., ..., 1)` (count=1), which only rewrote the first
occurrence. Once the doc grew a second backticked mention (introduced by
the G1 plan in `5535376f`, and again by the PR-1822 achievement summary),
the post-replace text still contained the canonical name elsewhere, so
`check_doc` found nothing missing and the assertion fired with an empty
error list.

Switch the test to a count-less `replace`, so every occurrence is
rewritten before invoking `check_doc`. The test now matches its intent —
"if no mention of the public theorem survives, the check must complain"
— and stays robust against future natural mentions in the same doc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Th0rgal Th0rgal marked this pull request as ready for review May 11, 2026 08:22
@Th0rgal Th0rgal merged commit d694305 into main May 11, 2026
22 checks passed
Th0rgal added a commit that referenced this pull request May 11, 2026
Captures concrete code-level facts gathered while reviewing the post-#1822
tree for the S5-S8 follow-up:

- Verified line numbers for every shipped Revived leaf constructor and
  the one shipped chain (`of_empty_body`).
- Corrected the original plan: the `of_leave_body` success-bridge chain
  is NOT pre-existing - it must be authored alongside E3, E4, E5.
- Documented the per-body-shape preservation status: `empty_block` and
  `comment` preservation lemmas already ship; `Leave` and
  `NativePreservableStraightStmts` preservation are net-new work.
- Pointed F1 readers at the redundancy with E5: F1 and E5 describe the
  same body shape `[.comment text]`, so F1 can be dropped once E5 lands.
- Listed concrete file insertion points for Layers A, B, D, and the
  call-site sweep required for Layer G.
- Revised the effort estimate to 5-9 senior-engineer days and noted
  why this scope is not compatible with a single autonomous coding
  session (prior worker attempts repeatedly stalled or fabricated
  phantom pushes).

No code changes; planning document only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Th0rgal added a commit that referenced this pull request May 14, 2026
…cade fix (#1826)

* Scaffold G1 S5–S8 follow-up plan

Adds docs/NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md as the planning document
for the follow-up PR after #1822. The doc decomposes the remaining G1
work (S5–S8 in NATIVE_EVMYULLEAN_TRANSITION.md) into a DAG of seven
node layers (A IR-side lemmas, B native harness lemmas, D Revived
constructors, E/F SelectorHitSuccessBridge chains and label-prefix
variants, G `hUserBodyHalt` premise drop), and proposes a four-wave
parallel orchestration strategy across eight worker tasks. Each node
has a clean per-file definition of done and a universal "zero sorry,
zero new axiom, build green" acceptance gate.

The doc also enumerates four alternative approaches (predicate
refactor, direct semantic equivalence, tactic-driven wiring,
dispatcher-shape normalization) with pros/cons, recommending the
straight-line plan as the safest path and revisiting ALT-1/ALT-3 as a
post-S8 cleanup.

No code changes; doc-only scaffolding for the next PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add implementation research addendum to G1 S5-S8 plan

Captures concrete code-level facts gathered while reviewing the post-#1822
tree for the S5-S8 follow-up:

- Verified line numbers for every shipped Revived leaf constructor and
  the one shipped chain (`of_empty_body`).
- Corrected the original plan: the `of_leave_body` success-bridge chain
  is NOT pre-existing - it must be authored alongside E3, E4, E5.
- Documented the per-body-shape preservation status: `empty_block` and
  `comment` preservation lemmas already ship; `Leave` and
  `NativePreservableStraightStmts` preservation are net-new work.
- Pointed F1 readers at the redundancy with E5: F1 and E5 describe the
  same body shape `[.comment text]`, so F1 can be dropped once E5 lands.
- Listed concrete file insertion points for Layers A, B, D, and the
  call-site sweep required for Layer G.
- Revised the effort estimate to 5-9 senior-engineer days and noted
  why this scope is not compatible with a single autonomous coding
  session (prior worker attempts repeatedly stalled or fabricated
  phantom pushes).

No code changes; planning document only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* G1 Layer B: harness append/leave equation helpers for switch-id dispatcher

Adds three lemmas to the native dispatcher harness that the consumer-side
Revived constructors in Compiler/Proofs/EndToEnd.lean (Layer D) will need
to thread a NativePreservableStraightStmts-derived prefix through a switch
case body:

* exec_block_append_eq_of_continue (B3): equation form of
  exec_block_append_ok; given the left prefix evaluates to .ok mid at
  fuel + left.length + k, executing left ++ right at the same total fuel
  coincides with executing right on mid at fuel + k. Used by B1.

* exec_block_lowerStmtsNativeWithSwitchIds_with_leave_ok_eq_of_NativeBlockPreservesWord
  (B1): splices a NativePreservableStraightStmts-derived prefix in front
  of .Leave at the canonical fuel + suffixLen + native.length + 10 budget
  used by the dispatcher harness, producing .ok mid.setLeave.

* exec_block_lowerStmtsNativeWithSwitchIds_ok_eq_of_NativeBlockPreservesWord
  (B2): trivial no-leave variant via List.append_nil; keeps consumers
  free of fuel-arithmetic plumbing.

These are pure facts about EvmYul.Yul.exec and the Block reduction rule,
matching the "Layer B — Native harness lemmas" specification in
docs/NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md (lines 69-85).

No new sorry, no new axiom. PrintAxioms registry regenerated
(5212 → 5215 entries). lake build green, make check green.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Layer A: IR-side observational-equality lemmas (G1 S5-S8 follow-up)

Adds A1, A2, A3 IR-side observational-equality lemmas in
Compiler/Proofs/IRGeneration/IRInterpreter.lean and registers them in
PrintAxioms.lean. Uses option (b) inline IR-side predicate
IRStmtPreservesObs to avoid the EvmYulLeanNativeHarness import cycle.

* Layer A: weaken IRStmtPreservesObs predicate (drop vacuous storage/events equality)

The original IRStmtPreservesObs required state'.storage = state.storage AND
state'.events = state.events. This is FALSE for most NativePreservableStraightStmt
constructors (sstore, log0..log4, tstore, mstore, etc., which all mutate state),
making the predicate unsatisfiable for any non-trivial prefix and rendering
A1/A2 vacuously true.

The corrected predicate just claims execIRStmt terminates in `.continue _`.
This is genuinely satisfiable by the 17 non-terminator constructors of
NativePreservableStraightStmt. Storage and event correspondence between IR
and native runs is properly the responsibility of the bridge-side machinery
(harness state projection), not a per-stmt IR invariant.

A1 and A2 keep the same names and structures, with the storage/events
conjuncts dropped from their conclusions. A3 unchanged.

Local validation:
  lake build           exit 0
  make check           exit 0 (802 tests passed)
  zero new sorry/axiom in Compiler/ vs cca8c5d (base)

* docs: addendum on Layer A predicate evaluability issue + recommended path

Records the architectural finding from the May 2026 implementation pass:
- Layer A's IRStmtPreservesObs (even after ade52b0 weakening) is only
  satisfied unconditionally by .comment text. For let_/assign/sstore/
  log/etc, IR semantics revert when expression evaluation fails, so the
  per-stmt predicate (∀ state, .continue _) is too strong.
- letMany unconditionally reverts in current IR semantics.
- Recommended forward path: state-relative predicate IRStmtPreservesObs
  (stmt) (state) so A1/A2 can thread state through the inductive proof.
- Substrate caveat: 4/4 worker spawns failed during this session.

Layer A's lemmas (A1, A2, A3) remain in the tree and compile; they
provide list-induction scaffolding usable by callers who can supply the
per-stmt witness via a different route. D1's full implementation will
need either the state-relative predicate or an inline per-stmt induction.

* Layer A scaffolding: LetManyFree + NotTerminator side-condition helpers

Adds two purely-syntactic predicates on YulStmt that Layer D's prefix
hypotheses need:

  - LetManyFree stmt — excludes Yul .letMany. Compiled internal/external
    calls emit .letMany (Compile.lean:270,276,282), but the simple IR
    executor execIRStmt returns .revert on .letMany by design — those
    bodies use the contract-aware execIRStmtsWithInternals path instead.
    D1/D2's "preStmts ++ [.leave]" prefix needs each stmt to actually
    .continue in IR, so .letMany must be excluded.

  - NotTerminator stmt — excludes the three IR-side terminators
    (expr_stop/return/revert). These are valid NativePreservableStraightStmt
    constructors but produce .stop/.return/.revert rather than .continue,
    so they break the prefix-then-leave shape.

Both predicates ship with @[simp] proofs for the common non-letMany /
non-terminator constructors so they discharge automatically in callers.

Validation:
  lake build           exit 0
  make check           exit 0 (802 tests, "All checks passed")
  PrintAxioms.lean regenerated to 5227 theorems (+9 public)
  zero new sorry, zero new axiom in Compiler/ vs cca8c5d

* Layer A: add state-relative IRStmtPreservesObsAt with unconditional comment/leave proofs

Adds a state-relative variant of IRStmtPreservesObs that pins the predicate
to a specific IRState. This is what Layer D's cross-cast actually needs:
constructors like let_/assign/sstore depend on evalIRExpr succeeding, which
is state-dependent. Only .comment / .leave / .funcDef satisfy the
state-quantified version unconditionally.

  - def IRStmtPreservesObsAt (state) (stmt) — state-relative version
  - theorem IRStmtPreservesObs_iff_forall_state — bridges to existing
    state-quantified predicate
  - @[simp] proofs IRStmtPreservesObsAt_comment, _leave (unconditional)

The non-trivial constructors (let_/assign/expr_*) will need additional
evaluability witnesses tying their expressions to the state's variable
bindings. That work is deferred to a future commit.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated to 5231 theorems (+4 public)
  zero new sorry, zero new axiom in Compiler/ vs cca8c5d

* Layer A: cross-cast lemmas for let_/assign/sstore (state-relative)

Adds three IRStmtPreservesObsAt cross-cast lemmas, each conditional on an
expression-evaluability witness:

  - IRStmtPreservesObsAt_of_let_      — let_ name value
  - IRStmtPreservesObsAt_of_assign    — assign name value
  - IRStmtPreservesObsAt_of_sstore_lit_expr — expr (sstore [lit slot, valExpr])

Each takes a hypothesis (∃ v, evalIRExpr state expr = some v) to discharge
the .revert branch of execIRStmt. Pattern is uniform; the remaining
constructors (log0..log4, tstore, mstore, mstore8, calldatacopy,
returndatacopy, sstore-of-mappingSlot, sstore-of-ident, sstore-of-add,
expr_call general) follow the same shape.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+3 public)
  zero new sorry, zero new axiom

* Layer A: remove iff_forall_state lemma (CI Lean 4.22.0 mis-parses identifier)

The lemma `IRStmtPreservesObs_iff_forall_state` (added in af6974e) caused
CI's stricter Lean (v4.22.0) to auto-bind `IRStmtPreservesObs` as a free
type variable in the theorem signature, failing with "Function expected"
at the use site. Local Lean was lenient. Removing the lemma — it was
not load-bearing for any downstream theorem; the two predicates
`IRStmtPreservesObs` and `IRStmtPreservesObsAt` stand alone.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (-1 public)
  zero new sorry, zero new axiom

* Layer A: cross-cast batch 2a (tstore, mstore)

Two more state-relative IRStmtPreservesObsAt cross-cast lemmas in the
same pattern as _of_sstore_lit_expr:

  - IRStmtPreservesObsAt_of_tstore  — expr (tstore [offsetExpr, valExpr])
  - IRStmtPreservesObsAt_of_mstore  — expr (mstore [offsetExpr, valExpr])

Each takes two evaluability hypotheses (offset + val), discharges the
.revert branches.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+2 public)
  zero new sorry, zero new axiom

* Layer A: cross-cast batch 2b (mstore8, calldatacopy, returndatacopy)

Three more IRStmtPreservesObsAt cross-casts. Unlike sstore/mstore/tstore
(which IR semantics models explicitly), these three fall through the
opaque `.continue state` branch in execIRStmt — the IR evaluator only
checks that the call's args evaluate, then leaves state unchanged.

  - IRStmtPreservesObsAt_of_mstore8
  - IRStmtPreservesObsAt_of_calldatacopy
  - IRStmtPreservesObsAt_of_returndatacopy

Each takes a single (∃ v, evalIRExpr state call = some v) witness for the
whole call expression. The IR model's lack of mstore8 byte-effect /
calldata-copy memory-write modeling is a known limitation; the bridge
to native handles those effects on the harness side via state projection.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+3 public)
  zero new sorry, zero new axiom

* Layer A: cross-cast batch 2c (log0..log4)

Five IRStmtPreservesObsAt cross-casts for the YulLog family. Each goes
through execIRStmt's `.call func args` branch with isYulLogName=true,
unfolding evalIRExprs over the arg list and applyYulLogCall? to bind the
new state via state.appendYulLog.

  - IRStmtPreservesObsAt_of_log0  (2 eval witnesses)
  - IRStmtPreservesObsAt_of_log1  (3)
  - IRStmtPreservesObsAt_of_log2  (4)
  - IRStmtPreservesObsAt_of_log3  (5)
  - IRStmtPreservesObsAt_of_log4  (6)

The proof structure is uniform: obtain each eval witness, refine with
state.appendYulLog as the continuation state, simp through execIRStmt /
evalIRExprs / applyYulLogCall? + Option.bind + rfl.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+5 public)
  zero new sorry, zero new axiom

* Layer A: cross-cast batch 3a (sstore_mappingSlot, sstore_ident)

Two more IRStmtPreservesObsAt cross-casts for sstore variants the
compiler emits:

  - IRStmtPreservesObsAt_of_sstore_mappingSlot — sstore at a slot
    computed via mappingSlot(base, key). Takes three eval witnesses.
  - IRStmtPreservesObsAt_of_sstore_ident — sstore at a slot read from
    a local variable. Takes an `IRState.getVar` witness for the ident
    plus an eval witness for the value.

These cover the bridged-straight sstore cases in BridgedStraightStmt
(line ~57-67 of EvmYulLeanBridgePredicates.lean) other than the
literal-slot case shipped earlier and the .add case still to come.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+2 public)
  zero new sorry, zero new axiom

* Layer A: cross-cast batch 3b (sstore_add + general expr_call_opaque)

Two more IRStmtPreservesObsAt cross-casts that complete the per-stmt
coverage for the bridged-straight fragment:

  - IRStmtPreservesObsAt_of_sstore_add — sstore at slot computed by
    add(left, right). Takes the slot-eval and val-eval witnesses.
  - IRStmtPreservesObsAt_of_expr_call_opaque — general-form catchall
    for any `.expr (.call func args)` whose `func` is not one of the
    special builtins (sstore/mstore/tstore/stop/return/revert/log*).
    Discharged by case-splitting on args shape and ruling out each
    structural pattern via the function-name hypotheses.

After this commit, all atomic NativePreservableStraightStmt
constructors (excluding letMany + the 3 terminators) have a
state-relative cross-cast lemma that produces IRStmtPreservesObsAt
given evaluability of the relevant sub-expressions.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+2 public)
  zero new sorry, zero new axiom

* Layer A: strengthen IRStmtPreservesObsAt + StmtsContinueFrom + state-threaded A1/A2

Substantial Layer A foundation work setting up next steps:

1. Strengthen IRStmtPreservesObsAt from ∀-∃ to ∃-∀ form:
     def IRStmtPreservesObsAt state stmt :=
       ∃ state', ∀ fuel, execIRStmt (fuel + 1) state stmt = .continue state'
   The witness state is now declared fuel-independent up front — this
   matches the actual proofs (each cross-cast computes a single state'
   that works for all fuels) and lets the predicate compose cleanly with
   list-induction without re-deriving fuel irrelevance at each step.

2. All 18 cross-cast proofs (comment, leave, let_, assign, sstore × 4,
   tstore, mstore, mstore8, calldatacopy, returndatacopy, log0..4,
   expr_call_opaque) updated to the new shape via `refine ⟨state',
   fun _ => ?_⟩` — same proofs, just reorder the quantifier handling.

3. Add `StmtsContinueFrom (state : IRState) : List YulStmt → Prop` —
   recursive state-threaded predicate carrying per-step continuation
   witnesses with fuel-independence.

4. Add state-threaded A1 / A2:
   - execIRStmts_continue_of_StmtsContinueFrom_pre_leave
   - execIRStmts_continue_of_StmtsContinueFrom_falling_through
   Both consume StmtsContinueFrom and produce existential continuation
   for execIRStmts at the right fuel budget. These are the versions D1
   and D2 will actually use (the original state-quantified A1/A2 only
   apply to comment/leave-prefix bodies; the threaded variants apply to
   ANY prefix whose per-stmt witnesses can be supplied by the dispatch
   theorem from NativePreservableStraightStmt + eval witnesses).

5. Shorten original `_pre_leave` proof (remove redundant `show` lines)
   so it no longer trips the 50-line proof-length audit.

Net change: +90 LoC. Sets up the dispatch theorem (next turn) which
will assemble `StmtsContinueFrom state stmts` from
`NativePreservableStraightStmts stmts + LetManyFree stmts +
NotTerminator stmts + per-stmt evaluability`.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated
  zero new sorry, zero new axiom

* Layer A: composition helpers for StmtsContinueFrom

Three small introduction lemmas to make D1/D2 builders cleaner:

  - @[simp] StmtsContinueFrom_nil — trivial nil case.
  - StmtsContinueFrom.cons_of_witness — cons given a per-step ∀-fuel
    witness and a tail witness.
  - StmtsContinueFrom.cons_of_IRStmtPreservesObsAt — cons given an
    IRStmtPreservesObsAt witness (destructures internally to expose
    the next-state binding to the tail continuation).

These mirror the shape produced by the 18 cross-cast lemmas, so D1's
construction of a StmtsContinueFrom witness for a NativePreservableStraightStmts
prefix becomes a list induction with `cons_of_IRStmtPreservesObsAt` at
each step.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated (+3 public)
  zero new sorry, zero new axiom

* Layer A: fix CI red on d333e45 (dedup + unused simp args)

Two issues from prior commit:
1. StmtsContinueFrom_nil declared twice (out-of-band push added a
   dot-notation set of helpers at line 1609+; my earlier underscore
   versions at line 1530+ conflicted). Removed my duplicates; kept
   the dot-notation set (StmtsContinueFrom.cons_of_witness,
   .cons_of_IRStmtPreservesObsAt).
2. _of_expr_call_opaque's [a, b] arm had three simp args
   (hReturnFalse, hRevertFalse, hNotLog) that CI's
   linter.unusedSimpArgs flagged. These were carry-over from earlier
   experimentation — the kernel reduces the match arms directly given
   hNotSStore/hNotMStore/hNotTStore. Removed.

Validation:
  lake build         exit 0
  make check         exit 0
  PrintAxioms.lean   regenerated
  zero new sorry, zero new axiom

* Layer A: remove final unused simp args in expr_call_opaque

CI linter.unusedSimpArgs flagged hNotSStore/hNotMStore/hNotTStore/hNotLog
across the four arms of _of_expr_call_opaque's args case analysis.
Simp's match-reduction discharges the special-case branches via
constructor inequality on string literals at the outer level, so the
explicit non-equality hypotheses are unused as rewrite rules. Hypothesis
parameters retained for caller-side documentation.

Validation:
  lake build         exit 0
  make check         exit 0
  zero new sorry, zero new axiom

* Layer A: fix CI strict-Lean unsolved-goals on opaque expr_call branches

Three Layer A cross-cast theorems for opaque fallthrough builtins
(`mstore8`, `calldatacopy`, `returndatacopy`) were failing on the
EVMYulLean fork probe (Lean 4.22.0, strict mode) because `simp only`
could not fully reduce the chained `match e with | .call "..." [...] =>
... | .call func args => if isYulLogName func then ... else ...` even
with the appropriate evaluation hypothesis. Full `simp` does reduce,
but `linter.unusedSimpArgs` then flags load-bearing simp args as
"unused" because they are consumed by match-reduction rather than
direct rewrites.

Resolution:
- Set `linter.unusedSimpArgs false` at file scope (matches the
  existing precedent in `Compiler.Proofs.IRGeneration.Function.lean:11`).
- Switch the three opaque-fallthrough cross-casts from `simp only` +
  `rfl` to plain `simp` with the same simp set; the linter no longer
  flags the auxiliary args as unused.
- Apply the same `simp` (vs `simp only`) shape to the five log
  cross-casts (`log0`..`log4`) for consistency.
- Delete `IRStmtPreservesObsAt_of_expr_call_opaque` (the catch-all
  cross-cast over generic call shapes); it was the source of the
  cascading linter failures and its case is covered by the per-builtin
  cross-casts that the Layer-D dispatch will actually consume.
- Regenerate `PrintAxioms.lean` (-1 theorem).

Local validation:
  make test-evmyullean-fork  →  "EVMYulLean fork conformance probe
  passed." (build 1134/1134 green, including
  Compiler.Proofs.IRGeneration.IRInterpreter and the full
  Compiler.Proofs.EndToEnd).

No new sorry, no new axiom. Layer-A constructor surface for Layer D is
unchanged except for the deletion of the generic-opaque entry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Layer A: restore expr_call_opaque cross-cast + add funcDef

Two additions to the Layer A cross-cast surface that the Layer D dispatch
will consume:

1. Restore IRStmtPreservesObsAt_of_expr_call_opaque (deleted in b7ed463
   to fix CI strict-Lean unsolved-goals). The proof now uses `cases args`
   to enumerate argument-list shapes (0/1/2/3+) before applying `simp`
   with the specific non-builtin hypotheses, avoiding the cascading-match
   reduction issue that motivated the original deletion. The hypotheses
   are simplified: hNotRevert and hNotReturn become plain inequalities
   (func ≠ "revert" / "return") rather than the awkward universally-
   quantified args-bound forms.

2. Add IRStmtPreservesObsAt_funcDef. Mirrors the structure of
   IRStmtPreservesObsAt_comment and IRStmtPreservesObsAt_leave: the IR
   semantics for `.funcDef _ _ _ _` is unconditional `.continue state`,
   so the cross-cast holds at every state. Used by the BridgedStraightStmt
   `.funcDef` constructor in the Layer D dispatch.

PrintAxioms.lean regenerated (+2 theorems: 5250 → 5252).

Local validation: `make test-evmyullean-fork` →
"EVMYulLean fork conformance probe passed" (1134/1134 green, including
the full Compiler.Proofs.EndToEnd target).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* upstream/main fix candidate: mulDiv512Down/Up missing cases in SupportedSpec.lean

Upstream main commit 6b2af37 (#1846, "Add mulDiv512Down / mulDiv512Up codegen
with FullMath Yul helper") introduced new Expr constructors `mulDiv512Down` /
`mulDiv512Up` but did not update the 9 helper functions in SupportedSpec.lean
that explicitly enumerate Expr cases. This results in CI build failure on
main 6b2af37 (run 25764352385) with 9 "Missing cases" errors at lines 556,
683, 724, 762, 804, 854, 898, 940, 983 — each citing "Expr.mulDiv512Up _ _ _".

This commit applies the conservative fix: add `| .mulDiv512Down a b c |
.mulDiv512Up a b c` to each affected pattern, sharing the body with the
existing `mulDivDown`/`mulDivUp` cases (which are semantically the same shape:
3 expression args, no new helper surface introduced).

Local validation: lake build now passes the "Missing cases" stage. A separate
upstream Lean elaborator bug (`enableRealizationsForConst` failure at
SupportedSpec.lean:5694) still blocks the SupportedSpec build, but that's an
unrelated issue.

This patch is intended to be cherry-picked into upstream main.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* upstream/main fix: paramDynamicHeadWord + wildcard expansion in SupportedSpec

Fixes a 2nd round of upstream main bugs that PR #1826's CI surfaces
(commits cf5cb84 + 6b2af37 added 3 new Expr constructors —
paramDynamicHeadWord, mulDiv512Down, mulDiv512Up — without updating
SupportedSpec.lean's exhaustive case-matches).

Three structural fixes:
- Add `.paramDynamicHeadWord _ _` case to 9 helper-surface functions
  (exprTouchesUnsupportedConstructorRawCalldataSurface,
   exprTouchesUnsupportedCoreSurface, exprTouchesUnsupportedStateSurface,
   exprTouchesUnsupportedCallSurface, exprTouchesUnsupportedHelperSurface,
   exprTouchesInternalHelperSurface, exprTouchesUnsupportedForeignSurface,
   exprTouchesUnsupportedLowLevelSurface, exprTouchesUnsupportedContractSurface).
  Conservative semantics: paramDynamicHeadWord returns true (touches
  unsupported surface) for the constructor-context, core, state, and
  contract surface checks, since it reads calldata; returns false (does
  not touch unsupported) for call/helper/foreign/lowLevel surfaces.

- Expand wildcard `| _ => []` in exprInternalHelperCallNames to explicit
  enumeration of all leaf Expr constructors plus the `adtConstruct`
  recursive case, matching the pattern of upstream commit 34063ed
  (#1842) which fixed the same eq_def heartbeat ceiling issue in
  ValidationCalls.lean and ValidationInterop.lean. Without this, Lean
  4.22.0's eq_def deriver hits the 200K-heartbeat ceiling because each
  new Expr constructor enlarges the wildcard's complement to enumerate.

- Add file-level `set_option maxHeartbeats 4000000` (cosmetic; doesn't
  propagate to eq_def deriver but provides headroom for normal proofs).

Local validation: build now progresses past the structural bugs to
downstream cascading "Alternative not provided" errors at lines 3133,
3523, 3722, 4092 (and several "unsolved goals" at 4352+) — these are
proofs that case-split on Expr and need the new constructors as
explicit cases. Those fixes are mechanical but tedious (~12+ case
additions across many proofs); deferring to the upstream maintainer
or a follow-up PR.

This commit is intended to be cherry-picked into upstream main
alongside #1843/#1846 to keep main's CI green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* upstream/main fix: add paramDynamicHeadWord/mulDiv512 to 6 cases-on-Expr proofs

Continues the cascade of fixes for upstream main commits cf5cb84 +
6b2af37 (which added paramDynamicHeadWord, mulDiv512Down, mulDiv512Up
without updating dependent code). Each `cases expr` proof in
SupportedSpec.lean that enumerates Expr constructors needs explicit
arms for the 3 new constructors.

Sites updated:
- exprTouchesInternalHelperSurface_eq_false_of_helperSurfaceClosed (3201)
  → mulDiv512Down/Up share the mulDivDown/Up arm; paramDynamicHeadWord
    is its own arm using `simp [exprTouchesInternalHelperSurface]`
- exprTouchesUnsupportedCallSurface_eq_featureOr (3605)
  → mulDiv512 share with mulDivDown/Up; paramDynamicHeadWord uses simp
- exprTouchesUnsupportedContractSurface_eq_false_of_featureClosed (3796)
  → mulDiv512 share; paramDynamicHeadWord falls into hcore-impossible
    (since exprTouchesUnsupportedCoreSurface paramDynamicHeadWord = true)
- exprTouchesUnsupportedCallSurface_eq_false_of_coreClosed (3878)
  → mulDiv512 share; paramDynamicHeadWord uses hcore-impossible
- exprTouchesUnsupportedHelperSurface_eq_false_of_contractSurfaceClosed
  (4146) → mulDiv512 share; paramDynamicHeadWord uses hsurface-impossible
- exprUsesArrayElement_eq_false_of_coreClosed (4351)
  → mulDiv512 share; paramDynamicHeadWord uses hcore-impossible
- exprUsesStorageArrayElement_eq_false_of_coreClosed (4401)
  → same pattern
- exprUsesDynamicBytesEq_eq_false_of_coreClosed (4453)
  → same pattern

Local validation: `lake build Compiler.Proofs.IRGeneration.SupportedSpec`
now passes. Subsequent build chain reveals the same upstream-bug
pattern in `Compiler/Proofs/IRGeneration/SourceSemantics.lean`
(evalExprWithHelpers/evalExprListWithHelpers/execStmtWithHelpers/
interpretInternalFunctionFuel mutual block, ~25 wildcards) — that's
the next file to patch, but is a separate, larger commit.

This is upstream main's work. Documented as a fix-candidate ready to
cherry-pick into upstream alongside #1843/#1846.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* allowlist: 2 SupportedSpec proofs that grew past 50 lines

The two proofs `exprUsesStorageArrayElement_eq_false_of_coreClosed`
and `exprUsesDynamicBytesEq_eq_false_of_coreClosed` grew to 51-52
lines after I added paramDynamicHeadWord/mulDiv512Down/Up arms in
commit dfdd124. Each new arm is a single mechanical case (`simp
[exprTouchesUnsupportedCoreSurface] at hcore`); splitting the proof
into smaller lemmas would just duplicate the same boilerplate.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* upstream/main fix: SourceSemantics — wildcard expansion + new constructor cases

Continues the cascade of upstream main fixes (commits cf5cb84 + 6b2af37
added paramDynamicHeadWord, mulDiv512Down, mulDiv512Up to Expr without
updating dependent code).

Three structural fixes in SourceSemantics.lean:

1. Expand wildcard `| _ => none` in evalExprWithHelpers (line 2691) into
   explicit enumeration of paramDynamicHeadWord, mulDiv512Down/Up, plus
   16 other previously-wildcarded constructors. This fixes the
   eq_def heartbeat ceiling that was triggering simp/realization
   failures at every downstream call site.

2. Apply the same wildcard expansion to the standalone `evalExpr`
   function (line 853) — same heartbeat issue, separate scope.

3. Add 3 new evalExpr_xxx rfl-lemmas (`evalExpr_mulDiv512Down`,
   `evalExpr_mulDiv512Up`, `evalExpr_paramDynamicHeadWord` — all `= none`
   by definition) so the cases-on-Expr proof at line 3577
   (evalExprWithHelpers_eq_evalExpr_of_helperSurfaceClosed) can use the
   `unfold + rw + reflective rewrite` pattern instead of running into
   heartbeat-prone `simp` recursion.

4. Add `set_option maxHeartbeats 1000000 in` before the mutual block
   at line 3557 to give the recursive proofs in that block more
   budget (defensive; current proofs fit in 200K but the budget is
   tight).

5. Add 3 new arms (`mulDiv512Down a b c`, `mulDiv512Up a b c`,
   `paramDynamicHeadWord name offset`) to the cases-on-Expr proof
   at line 3577 using the `unfold evalExprWithHelpers; rw [evalExpr_*]`
   pattern.

Local validation: `lake build Compiler.Proofs.IRGeneration.SourceSemantics`
now passes. Downstream files (ContractShape.lean and GenericInduction.lean)
still need similar treatment — those are separate, smaller commits.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* upstream/main fix: total defs + new SupportedSpec _eq_false lemmas + cascade

Cascade fixes for upstream commits cf5cb84 (paramDynamicHeadWord) and 6b2af37
(mulDiv512Down/Up) that added Expr constructors but broke downstream proofs.

UsageAnalysis.lean:
- Convert exprUsesParamDynamicHeadWord, stmtUsesParamDynamicHeadWord,
  exprUsesMulDiv512, stmtUsesMulDiv512 from `partial def` to total `def` with
  `mutual` blocks, helper exprList/stmtList/matchBranches functions, and
  `termination_by sizeOf`. Partial defs were kernel-opaque, blocking downstream
  proofs by induction.

SupportedSpec.lean:
- Mark `mulDiv512Down/Up` as touching unsupported Core+Contract surface
  (consistent with `paramDynamicHeadWord => true`); they have no
  `ExprCompileCore` constructor, so the surface predicate must reject them.
- Split four cases-on-Expr proofs (mulDivDown vs mulDiv512Down/Up) where the
  combined recursion no longer typechecks under the new surface semantics.
- Add 14 new lemmas: exprCompileCore_uses{ParamDynamicHeadWord,MulDiv512}_false,
  exprListCompileCore_…, stmtListCompileCore_…, stmtListTerminalCore_…,
  _eq_any bridges, supportedStmtList_…_false, and
  SupportedSpec[ExceptMappingWrites].contractUses{…}_eq_false.

ContractShape.lean / Contract.lean:
- Wire new flag-eq-false hypotheses into the three rfl-failing
  `compileValidatedCore_ok_yields_internalFunctions_nil` proofs.

GenericInduction.lean:
- Add `mulDiv512Down/Up` cases to
  `exprCompileCore_of_exprTouchesUnsupportedContractSurface_eq_false`.

CompilationModelFeatureTest.lean:
- Declare `external echo` in `adtAliasPayloadMemoizesExprSpec`. Upstream's
  Issue #732 validation now rejects undeclared external call targets.

scripts/check_proof_length.py:
- Allowlist 4 mechanical inductions whose case count is bounded by the number
  of SupportedStmtList constructors.

PrintAxioms.lean:
- Regenerated for the 4 new public theorems and 14 private helpers.

Local: lake build green, make check green, zero new sorry/axiom.

* G1 E3 + E5: success-bridge chains for of_block_empty and of_singleton_comment

Two new private theorems each in EndToEnd.lean (one preserves bridge, one
success bridge per leaf):

- NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_block_empty
- NativeGeneratedSelectorHitSuccessBridge.of_block_empty
- NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_singleton_comment
- NativeGeneratedSelectorHitSuccessBridge.of_singleton_comment

Both leaves lower to native shape `[.Block []]`, so the per-stmt
preservation half is discharged by the existing
`NativeStmtPreservesWord_empty_block` harness lemma (no new harness work).
The success bridge follows the standard chain template via
`of_selected_user_body_exec_only_and_preserves`, pairing the existing
`ExecOnlyBridgeAtFuelRevived.of_<leaf>` constructor with the new preserves
bridge.

E2 (`of_leave_body`) and E4 (`of_block_leave`) still blocked on a missing
`NativeStmtPreservesWord_leave` harness lemma (per plan §358). E6/E7
blocked on D1/D2.

PrintAxioms.lean regenerated (4 new private theorems).

Local: lake build green, make check green, zero new sorry/axiom.

* Add parallel _revived preservation predicates with leave-singleton bridge

Plan §358's proposed `NativeStmtPreservesWord_leave` is structurally false
because `state[name]!` via GetElem falls through the empty `default` Finmap
for Checkpoint states. The Leave-ending exec produces `Checkpoint (.Leave
shared store)` whose `[name]!` is ⟨0⟩, not the inner-store value.

Adds:
- 5 reviveJump simp lemmas (Ok, OutOfFuel, Leave, Continue, Break)
- NativeBlockPreservesWord_revived / NativeStmtPreservesWord_revived defs
  that read the inner store via `state.reviveJump[name]!`
- NativeStmtPreservesWord_revived_leave (provable in NEW form)
- NativeBlockPreservesWord_revived_nil/cons/singleton builders

The original NativeBlockPreservesWord/NativeStmtPreservesWord/Expr/EvalArgs
predicates are untouched, so 145+ existing usages in EndToEnd.lean and the
existing harness proofs remain unchanged.

Next: add NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel_revived
def and E2/E4 success-bridge chains in EndToEnd.lean using the _revived
predicates.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Add NativeStmtPreservesWord_revived_empty_block

Companion to NativeStmtPreservesWord_revived_leave from 5f8e602. The
empty-block case is trivial in the revived form: exec _ (.Block []) _ s
returns s unchanged, so final.reviveJump[name]! = state.reviveJump[name]!
follows directly from the hypothesis.

Useful for E1/E3 chains that wish to be expressed in _revived form
without going through the OLD-form predicate.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Regenerate PrintAxioms.lean for Path B revived predicates

Adds the new reviveJump simp lemmas and _revived predicates introduced
in 5f8e602 + 2f8a801 to the axiom audit roster. No new sorry, no new
axiom — these are all standard theorems.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Cascade fix for upstream Expr.arrayElementDynamicMember{Length,Element}

Upstream commits 041a783 (G1: length on struct-array elements) and
300fd81 (G2: arrayElementDynamicMemberElement constructor) added two
new Expr constructors but did not update SourceSemantics.lean's
evalExprWithHelpers unmodeled-list nor the
evalExprWithHelpers_eq_evalExpr_of_helperSurfaceClosed match.

Adds:
- evalExpr_arrayElementDynamicMember{Length,Element} eval lemmas (= none, rfl)
- New constructors in the unmodeled-list of evalExprWithHelpers
- Match cases in evalExprWithHelpers_eq_evalExpr_of_helperSurfaceClosed
- PrintAxioms.lean regenerated

lake build + make check both green locally.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Add _revived block adapter + .Block [.Leave] composition

Two small foundation lemmas building on the Path B core:
- NativeStmtPreservesWord_revived_block: trivial adapter mirroring the
  OLD-form NativeStmtPreservesWord_block (witness is the hypothesis)
- NativeStmtPreservesWord_revived_block_leave: composition for the
  lowered shape of IR [.block [.leave]] (E4 target body)

Both are pure compositions using the _revived predicates from 5f8e602.
PrintAxioms regenerated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Layer B Worker <worker@verity.lfg>
Co-authored-by: Claude Worker <claude-worker@anthropic.com>
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