feat(formal): P-4 dynamic half — β-reduction preserves the QTT usage profile#637
Merged
Conversation
…profile Completes the static/dynamic pair for P-4. QttTyping.v proved the static side (usage_soundness: the typing context records exactly the usage); QttDynamic.v proves the dynamic side — a small-step β-reduction on the QTT term language carries the whole usage profile forward unchanged: step_preserves_usage : t -> t' -> forall z, usage z t' = usage z t so the quantity accounting is a dynamic invariant. Composed with usage_soundness this gives qtt_context_preserved: a well-typed term's QTT context stays valid across a reduction step. Also exposes the QTT scaling law usage z (subst x v b) = usage z b + usage x b . usage z v (via a new qof_mult x-homomorphism) on the binder-free fragment, plus affine_no_increase (an affine redex never increases any variable's usage) and linear_exact. Beta substitutes a closed value (the P2_Stlc closed-program convention), so the development is capture- and axiom-free — all three theorems report "Closed under the global context". Wired into _CoqProject / formal/justfile / .hypatia-ignore (.v is Coq, not V-lang) / formal/README.adoc. PROOF-NEEDS.adoc: P-4 row + section 6 Wave 2 updated; formal/ now 14 files, 23 axiom-free closure reports. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr
🔍 Hypatia Security ScanFindings: 41 issues detected
View findings[
{
"reason": "Action denoland/setup-deno@v2 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/packages/affinescript-cli/mod.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (2 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/packages/affine-vscode/mod.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/affinescript-vite/src/affine-plugin-improved.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "expect() in hot path (32 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/wasm_gen.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (29 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/affine_gen.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (2 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/panic.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (1 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/alloc.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (3 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jun 21, 2026
…e.v) (#640) ## What Climbs the **REAL-LIFT ladder** (`formal/REAL-LIFT.adoc`) from **R0 → R1**: the **first mechanized `⟦compile p⟧ = ⟦p⟧` on the *real* objects** — the actual `lib/wasm.ml` instruction IR and the real (resolved) `lib/ast.ml` expression core. This **retires the toy `K1`/`K1Let` on real objects**. ## `RealWasm.v` (grown for R1) Adds **locals** (`LocalGet`/`LocalSet`) and the comparison ops `I32Eq`/`I32LtS`, threading a mutable locals store through `wexec`. `wexec` is refactored through a per-instruction `step1`, so the sequencing lemmas `wexec_app` / `wexec_seq` (which the preservation proof composes with) are one line each. `wexec_sound` (R0) is retained for the pure (`no_local`) fragment. ## `RealCompile.v` (new, R1) - **`rexpr`** — the resolved int/bool/`let`/binary core of `lib/ast.ml` (de Bruijn **levels**; name resolution is a separate obligation, P-7; bool ≔ 0/1, int ≔ Z, so one observable); - **`eval`** — the reference dynamic semantics (mirrors `lib/interp.ml`); - **`compile`** — lowers `let` to `LocalSet d` into a pre-sized locals array (slot = binding depth `d`; siblings reuse slots), mirroring `lib/codegen.ml`; - **`compile_correct`** — the theorem: ```coq eval env e = Some v → agree env locals → |env| = d → d + depth e ≤ |locals| → ∃ locals', wexec (compile d e) locals st = Some (locals', v :: st) ∧ |locals'| = |locals| ∧ (∀ i < d, nth_error locals' i = nth_error locals i) ``` carrying an **env↔locals agreement** invariant with **fresh-slot allocation** and **low-slot preservation** through the induction (the genuine compiler-correctness simulation); - **`compile_program_correct`** — runs a closed program from the zero-initialised locals array. Concrete end-to-end check (`let x = 2+3 in x*4 ⇒ 20`): `r1_eval_demo` (source) and `r1_exec_demo` (`compile` then `wexec` ⇒ `[20]`). ## Honest scope R1 is the int/bool/`let`/binop fragment on de Bruijn-resolved source; `LocalTee`/i64, structured control, memory, floats, calls, and effects are later rungs (`REAL-LIFT.adoc` §4). **R2** (structured control on a fuel-indexed `wexec`) is next, and is the rung that **settles #601 concretely**. ## Verification All axiom-free — every `Print Assumptions` reports *Closed under the global context*. `formal/` now **17 files, 29 closure reports** (full dep-order recompile, no `Axioms:`). Wired into `_CoqProject` / `justfile` / `.hypatia-ignore`; `README.adoc`, `REAL-LIFT.adoc` (R1 landed, R2 next), and `PROOF-NEEDS.adoc` (K-1 row, §1, §6 Wave 3) updated. Follow-on to #638 (R0 + plan, merged). `QTT-dynamic #637 ✅ → F-5 + R0 #638 ✅ → **R1 (this)**`. 🤖 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: hyperpolymath <paraordinate@yahoo.co.uk> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.
What
Completes the static/dynamic pair for P-4 (QTT affine usage).
QttTyping.v(Wave 3) proved the static side —usage_soundness: the typing context records exactly the usage. This addsformal/QttDynamic.v, the dynamic side: a small-step β-reduction on the QTT term language (AffineUsage.tm) that carries the whole usage profile forward unchanged.Headline
The quantity accounting is a dynamic invariant. Composed with the Wave-3 static capstone it yields:
— a well-typed term's QTT context stays valid across a reduction step (static + dynamic ⇒ the quantity discipline is sound under evaluation).
Also
usage z (subst x v b) = usage z b + usage x b · usage z von the binder-free fragment, via a newqof_mult×-homomorphism (qof (m*n) = qmult (qof m) (qof n)) — the analogue ofQttSemiring.qof_plus. This is the multiplicity scaling that makes substructurality bite.affine_no_increase— an affine redex (usage x b ≤ 1) never increases any variable's usage: the dynamic face of the affine bound.linear_exact— a linear redex preserves usage exactly.β substitutes a closed value (the call-by-value, closed-program convention
P2_Stlc.valso uses), so capture cannot arise and the development is axiom-free — all threePrint Assumptionsreport Closed under the global context.Honest scope
This is the dynamic half on the same small QTT model as Wave 2/3, not the full language. The remaining lift is the quantity-preserving substitution lemma generalised past the binder-free / closed-value fragment onto the real AST (tracked in
PROOF-NEEDS.adoc§6 Wave 3 — the "real lift").Wiring / docs
formal/_CoqProject,formal/justfile(dep-order compile + axiom gate),.hypatia-ignore(.vis Coq, not V-lang — both rule names),formal/README.adoc(Contents row + Wave-2/3 prose).docs/PROOF-NEEDS.adoc: P-4 row + §6 Wave 2 updated (dynamic half no longer pending).formal/is now 14 files, 23 axiom-free closure reports.Verified locally: all 14 proofs recompile in dependency order with
coqc -Q . ASFormal; noAxioms:in anyPrint Assumptions.🤖 Generated with Claude Code
https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr
Generated by Claude Code