sep-logic ownership: make the pointsTo layer load-bearing (Part 1: soundness bridge) - #1
Closed
mfornet wants to merge 1 commit into
Closed
Conversation
Replace the decorative single-byte load_sound/store_sound with a verified
bridge that connects pointsTo_u64 ownership to Mem.read64/write64:
- WasmHeap: byte64/byte32 little-endian extractors matching Mem.write*'s
stored-byte form exactly; pointsTo_u64/u32 redefined to use them (so the
bridge closes by bv_decide instead of Nat-division reasoning). Ownership
is opaque to swap_ownership / arrayAt_*, so those proofs are unaffected.
- WasmRules:
- read64_of_digits / write64_byte / write64_bytes_ne — pure Mem facts.
- read64_sound (load): agreement + owning the 8 digit-bytes ⟹ read64 = v.
- write64_agree (store): updating exactly the 8 digit cells keeps agreement
with write64, with NO byte-range/disjointness hypotheses — disjointness
from other owned cells is automatic (distinct UInt32 keys + no wrap).
This is the lemma that will let the swap proof drop the manual
read64_write64_ne / hdisj framing.
codelib + programs/lean both build clean.
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.
Draft / WIP — stacked on top of cajal-technologies#133 (
sep-logic-swap). Review this as an incremental follow-up to that PR, not a replacement.Goal
Make the separation-logic ownership layer in cajal-technologies#133 actually load-bearing. Today
func2_terminatesreads/writesst.memdirectly and proves disjointness ofptr_a/ptr_b/scratchwith the manual byte-range lemmas (read64_write64_ne,write64_bytes_ne,hdisj) — the exact "manual byte-range lemmas" the PR description says∗replaces. ThepointsTo_u64/swap_ownership/load_sound/store_soundmachinery is defined but never consumed. This branch wires ownership in so the manual framing disappears.Status
Part 1 — verified soundness bridge (this commit,
1d067ed). Builds clean (codelib+programs/lean).WasmHeap: addedbyte64/byte32little-endian extractors that matchMem.write32/write64's stored-byte form exactly, and redefinedpointsTo_u64/pointsTo_u32in terms of them. Using the interpreter's own bit form (shift+mask) is what lets the bridge close bybv_decideinstead of intractablev.toNat / 256^i % 256Nat-division reasoning. Ownership is opaque toswap_ownership/arrayAt_*, so those proofs are untouched.WasmRules: replaced the decorative single-byteload_sound/store_soundwith the real bridge:read64_of_digits,write64_byte,write64_bytes_ne— pureMemfacts.read64_sound(load): agreement + owning the 8 digit-bytes ofv⟹mem.read64 addr = v.write64_agree(store): updating exactly the 8 digit cells keeps agreement withmem.write64 addr v, with no disjointness hypotheses — an owned cell distinct from the 8 written keys cannot lie in[addr, addr+8)(no-wraparound), sowrite64leaves it intact. This is the lemma that replacesread64_write64_ne.This directly resolves the "decorative soundness bridge" finding:
load_sound/store_soundare now real, tested, and shaped to be consumed by the WP rules.Remaining (Part 2 — plan is fully mapped; mechanics prototyped)
wp_wasm_F's general case becomes∀ σ, ⌜heapAgreesWithMem σ ws.st.mem⌝ -∗ genHeapInterp σ ==∗ ∃ σ' st' locals', ⌜execOne …⌝ ∗ ⌜heapAgreesWithMem σ' st'.mem⌝ ∗ genHeapInterp σ' ∗ Φ ….Cascades to
BIMonoPred.mono_pred,wp_wasm_step, andwasm_adequacy(each just threads the extra pureagreehyp/obligation — prototyped locally).wp_wasm_stepspecialises to memory-preserving instructions (extrahmem : st'.mem = st.mem), which is exactly why store instructions can no longer use it.load64/store64rules — mirror iris-lean HeapLangwp_load/wp_store(Iris/HeapLang/PrimitiveLaws.lean):icases genHeap_valid $$ [$Hσ $Hpt] with >%Heqextracts eachget? σ (addr+i) = some (some (byte64 v i))while retaininggenHeapInterp σ; feedread64_sound⇒ the loaded value isv.imod genHeap_update $$ [$Hσ $Hpt] with ⟨Hσ, Hpt⟩on each of the 8 cells; feedwrite64_agree⇒ new agreement, no disjointness side-conditions.Minor bookkeeping: bridge
pointsTo_u64's literal cell offsets (addr+1 … addr+7) toread64_sound/write64_agree'saddr + UInt32.ofNat i.wasm_heap_adequacyinit from memory — buildσfrom the program's footprint bytes and hand outpointsTo_u64viagenHeap_init(which already yields[∗map] l↦v, l ↦ v); HeapLang'sheap_adequacyadapted to the fixed byte array. This is the largest remaining piece.func2/func3to use the ownership rules and deleteread64_write64_ne/write64_bytes_ne/read64_write32_ne/hdisjfrom the swap proof. (store32/func3also needs the u32 analogueswrite32_byte/write32_agree/read32_sound, straight copies of the u64 ones.)🤖 Generated with Claude Code