Skip to content

Commit 156455f

Browse files
Phase 1b substrate: expression-evaluation invariants under a store (#113)
## What The layer the statement-execution relation sits on — three hole-free lemmas about how expression evaluation interacts with the runtime store. | Lemma | Statement | |---|---| | `step_store_invariant` | a single expression step never mutates `ρ` | | `multiStep_store_invariant` | the same for multi-step evaluation, by transitivity | | `hasType_lit_any` | literal typing is context-independent — a typing for `.lit v` in one context holds in any context | **Why these, in this order.** Per the agreed rule — *land the lowest-complexity, safe, **complete** unit first* — these are the substrate the next step (statement execution) rests on, strictly above the store-typing lemmas just merged (#112): - **Store invariance** is what lets statement execution compose: an expression sub-evaluation inside a statement cannot disturb the variable bindings the statement effect then acts on (base `Step` rules keep the store; congruence rules thread it unchanged; transitivity lifts it to `MultiStep`). - **`hasType_lit_any`** is the weakening that lifts `StoreWellTyped`'s `HasType emptyTypeEnv (.lit v) t` into the arbitrary context `Γ` that statement-level expression typing lives in — needed for the `sVar` case of the generalized, store-typed preservation that comes next. ## Correction to an earlier note The roadmap previously said the expression `Step` is "closed-term-only, so variable resolution needs design." That was wrong: `Step` has an `sVar` rule that resolves variables from `ρ` directly. The closed-context restriction was only ever in the `emptyTypeEnv`-stated `progress`/`preservation`. The roadmap is corrected, and the remaining Phase 1b path is now: generalized store-typed preservation (`HasType Γ e t` under `StoreWellTyped Γ ρ`) → statement-execution relation → statement preservation. ## Verification - `lean docs/proofs/verification/WokeLang.lean` exits 0 (Lean 4.30.0, Mathlib-free, single-file). - Hole-free: `step_store_invariant` / `multiStep_store_invariant` use the classical kernel base (`propext`, `Classical.choice`); **`hasType_lit_any` depends on no axioms**. No `sorryAx`, no project-specific assumptions. ## Scope `docs/proofs/verification/WokeLang.lean` (the three lemmas) and a Progress entry in `docs/proofs/VERIFICATION-ROADMAP.md`. No changes to existing proofs or to the shipping implementation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015oyMquf4daB6hMhmqB1wAL --- _Generated by [Claude Code](https://claude.ai/code/session_015oyMquf4daB6hMhmqB1wAL)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent c17b2ee commit 156455f

2 files changed

Lines changed: 65 additions & 4 deletions

File tree

docs/proofs/VERIFICATION-ROADMAP.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,19 @@ unlock Phases 1c / 3a / 4a.
141141
preservation proofs rest on: `store_wellTyped_empty` (empty store types against the
142142
empty context), `store_wellTyped_lookup` (a typed variable resolves to a value of its
143143
type), and `store_wellTyped_extend` (extending context+store in lockstep — exactly a
144-
`varDecl` — preserves store typing). Hole-free (axiom `propext` only). The statement
145-
*execution* relation itself is the next, higher-complexity step (the expression `Step`
146-
is closed-term-only, so variable resolution needs design); this foundation lands first.
147-
- [ ] Phase 1 (cont.: `[T-Call]` after 1b), 1b (exec relation + stmt preservation), 1c — type-safety + operational metatheory.
144+
`varDecl` — preserves store typing). Hole-free (axiom `propext` only).
145+
- [~] **Phase 1b (substrate)****expression-evaluation invariants under a store**, the
146+
layer the statement-execution relation sits on: `step_store_invariant` and
147+
`multiStep_store_invariant` (expression evaluation never mutates `ρ` — so a sub-evaluation
148+
inside a statement can't disturb the bindings the statement effect then acts on), and
149+
`hasType_lit_any` (literal typing is context-independent — the weakening that lifts
150+
`StoreWellTyped`'s `HasType emptyTypeEnv (.lit v) t` into the arbitrary `Γ` statement-level
151+
typing uses). Hole-free (`hasType_lit_any` needs **no** axioms). *Correction to the prior
152+
note:* the expression `Step` is **not** closed-term-only — it has an `sVar` rule that
153+
resolves variables from `ρ`; the closed-context use was only in the `emptyTypeEnv`-stated
154+
`progress`/`preservation`. So the remaining work is a generalized store-typed preservation
155+
(`HasType Γ e t` under `StoreWellTyped Γ ρ`), then the statement-execution relation itself.
156+
- [ ] Phase 1 (cont.: `[T-Call]` after 1b), 1b (store-typed preservation → exec relation → stmt preservation), 1c — type-safety + operational metatheory.
148157
- [ ] Phase 2b, 2c — consent + capability state machines.
149158
- [ ] Phase 3a (+3b) — HM inference.
150159
- [ ] Phase 4a–4c — compiler / parser / WASM.

docs/proofs/verification/WokeLang.lean

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,58 @@ theorem store_wellTyped_extend {Γ : TypeEnv} {ρ : Env} {x : String} {t : WokeT
15091509
refine ⟨v', ?_, hvt⟩
15101510
simp only [extendEnv]; rw [if_neg hxy]; exact hv'
15111511

1512+
-- =========================================================================
1513+
-- 7d. Expression-evaluation invariants under a store (Phase 1b substrate)
1514+
-- =========================================================================
1515+
1516+
/-- **Expression evaluation never mutates the store.** Every base reduction
1517+
returns the store it was given, and every congruence rule threads the
1518+
sub-step's store unchanged, so a single expression step leaves `ρ` fixed. This
1519+
is what lets statement execution compose: an expression sub-evaluation inside a
1520+
statement cannot disturb the variable bindings the statement effect then acts on. -/
1521+
theorem step_store_invariant {e e' : Expr} {ρ ρ' : Env}
1522+
(h : Step e ρ e' ρ') : ρ' = ρ := by
1523+
induction h with
1524+
| sBinOpLeft _ _ _ _ _ _ _ ih => exact ih
1525+
| sBinOpRight _ _ _ _ _ _ _ _ ih => exact ih
1526+
| sUnOpCong _ _ _ _ _ _ ih => exact ih
1527+
| sOkayCong _ _ _ _ _ ih => exact ih
1528+
| sOopsCong _ _ _ _ _ ih => exact ih
1529+
| sUnwrapCong _ _ _ _ _ ih => exact ih
1530+
| sArrayStep _ _ _ _ _ _ _ ih => exact ih
1531+
| _ => rfl
1532+
1533+
/-- Multi-step evaluation is store-preserving too, by transitivity. -/
1534+
theorem multiStep_store_invariant {e e' : Expr} {ρ ρ' : Env}
1535+
(h : MultiStep e ρ e' ρ') : ρ' = ρ := by
1536+
induction h with
1537+
| refl => rfl
1538+
| step _ _ _ _ _ _ hs _ ih => rw [ih]; exact step_store_invariant hs
1539+
1540+
/-- **Literal typing is context-independent.** A literal value's type is
1541+
determined structurally and never consults the type context, so a typing for
1542+
`.lit v` in one context holds in any context. This is the weakening that lifts
1543+
`StoreWellTyped`'s `HasType emptyTypeEnv (.lit v) t` into the arbitrary context
1544+
`Γ` that statement-level expression typing lives in. -/
1545+
theorem hasType_lit_any {Γ Γ' : TypeEnv} {v : Value} {t : WokeType}
1546+
(h : HasType Γ (.lit v) t) : HasType Γ' (.lit v) t := by
1547+
-- Generalise to a same-expression form so the `vOkay`/`vArray` recursions get
1548+
-- usable induction hypotheses; the `∃ w, e = .lit w` guard rules out the
1549+
-- non-literal typing rules (which `induction` still enumerates).
1550+
have gen : ∀ {Δ e t'}, HasType Δ e t' → ∀ {Δ'}, (∃ w, e = .lit w) → HasType Δ' e t' := by
1551+
intro Δ e t' hh
1552+
induction hh with
1553+
| tInt n => intro _ _; exact .tInt _ _
1554+
| tFloat f => intro _ _; exact .tFloat _ _
1555+
| tString s => intro _ _; exact .tString _ _
1556+
| tBool b => intro _ _; exact .tBool _ _
1557+
| tUnit => intro _ _; exact .tUnit _
1558+
| tOkayVal w t'' _ ih => intro _ _; exact .tOkayVal _ _ _ (ih ⟨w, rfl⟩)
1559+
| tOopsVal s t'' => intro _ _; exact .tOopsVal _ _ _
1560+
| tArrayVal vs t'' _ ih => intro _ _; exact .tArrayVal _ _ _ (fun w hw => ih w hw ⟨w, rfl⟩)
1561+
| _ => intro _ hlit; obtain ⟨w, hw⟩ := hlit; nomatch hw
1562+
exact gen h ⟨v, rfl⟩
1563+
15121564
-- =========================================================================
15131565
-- 8. TODO Stubs
15141566
-- =========================================================================

0 commit comments

Comments
 (0)