You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fourth rung of the real lift (`formal/REAL-LIFT.adoc`): **structured
control with backward jumps**, and a source `while` whose lowering is
proved correct — settling the **#601** value-returning-tail question
concretely. Axiom-free throughout.
> Branch note: pushed to `claude/lucid-cray-4a22dp-r2loops` rather than
`claude/lucid-cray-4a22dp` — the latter is still present at the merged
#664 tip and is now protected against direct pushes (force/ff/delete all
blocked), so a fresh branch was the only push path. Diff is against
current `main` (post-#664), so it shows **only** the R2-loops changes.
## What landed
**Target IR (`RealWasm.v`)**
- Adds the faithful `lib/wasm.ml` structured-control instructions
`Block`, `Loop`, `Br k`, `BrIf k` to `instr` (+ dead `step1` arms).
**Zero blast radius** — the proven `wexec` and
`RealCompile.compile_correct` still compile unchanged.
**R2-loops (new file `RealLoop.v`)**
- The R2 executor `wexec : … → option (locals×stack)` can't express
*"this code branched to label k"*, so it cannot run `Br`. R2-loops
introduces a **branch-aware** executor `cexec` returning an `outcome`
(`ONormal` / `OBranch k` / `OTrap`). It reuses the *same fuel device* R2
used for forward control: a `Loop` consumed by `Br 0` re-enters by
recursing with decremented fuel, so `cexec` stays a structural
`Fixpoint` — definitional, so `cbn`/`reflexivity`/demos still compute (a
real countdown `while` evaluates by `reflexivity`).
- `cexec_le_S` / `cexec_mono` (more fuel never changes a `Some`) +
`cexec_app_normal` (additive sequencing when the prefix ends `Normal`).
- A *mutual* `instr`/`list instr` `branchfree` predicate is **rejected
by Coq's guard checker** (list recursion only decreases on the spine),
so instead of a `wexec→cexec` bridge over a flag, the R2 expression
compiler is re-proved directly into `cexec`: **`cexec_compile`** (the
`cexec` analogue of `compile_correct`).
- Source statements `SSkip` / `SSeq` / `SSet` / `SWhile` with a
fuel-indexed reference `run_stmt` (+ `run_stmt_mono`,
`run_stmt_length`), and a lowering `compile_stmt` taking `while` to
`Block[Loop[<cond>; I32Eqz; BrIf 1; <body>; Br 0]]`.
- **`cexec_loop`** — the loop-simulation lemma (induction on the while's
fuel: cond-false unwinds with `OBranch 1`, caught by the `Block`;
cond-true runs the body and re-enters via `OBranch 0`).
- **`compile_stmt_correct`** — a terminating statement's lowering runs
to the same locals, leaving the value stack **empty** (`cexec … = Some
(ONormal lo' [])`). A `while` is a *statement* (unit tail); this is
**#601 settled concretely** — the expression tail would instead keep its
value on the stack.
## Verification
`coqc` 8.18, whole `formal/` track re-audited against current `main`:
- **19 files compile**, **33 `Print Assumptions` reports**, every one
*"Closed under the global context"* — **zero axioms, no `Admitted`**.
## Docs
`formal/REAL-LIFT.adoc` (R2 row + §5 hard-parts + §8 status),
`formal/README.adoc` (RealLoop row + "real lift R0 → R2-loops"),
`docs/PROOF-NEEDS.adoc` (counts 18→19 / 31→33, K-1 row). `_CoqProject` /
`justfile` / `.hypatia-ignore` wire `RealLoop.v` in.
## Next
Rung **R-mem** (linear memory: load/store, tuples/arrays/records).
`for`/`break`/`continue` and a general source-divergence model reuse
this `cexec`.
Refs `REAL-LIFT.adoc`, `docs/PROOF-NEEDS.adoc` (K-1 row), #601.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr
---
_Generated by [Claude
Code](https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr)_
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments