Skip to content

resalgebraNoAxioms: Verify global validity of ghost locations#43

Merged
jcp19 merged 9 commits intomainfrom
proof-remaining-assumption-resalgebra
Apr 27, 2026
Merged

resalgebraNoAxioms: Verify global validity of ghost locations#43
jcp19 merged 9 commits intomainfrom
proof-remaining-assumption-resalgebra

Conversation

@jcp19
Copy link
Copy Markdown
Collaborator

@jcp19 jcp19 commented Apr 25, 2026

Adds a product-of-in-use-values invariant to GlobalMem() and proves all four ghost operations maintain it. The new product.gobra builds up ProductOfSeq with the structural lemmas (Concat, AdjacentSwap, MoveFront, ExtractOne, ExtractThree) and the maintenance lemmas (ProductSplitEq, ProductMergeAt, ProductFPUEq).

jcp19 and others added 2 commits April 25, 2026 16:55
Adds a product-of-in-use-values invariant to GlobalMem() and proves all
four ghost operations maintain it. The new product.gobra builds up
ProductOfSeq with the structural lemmas (Concat, AdjacentSwap, MoveFront,
ExtractOne, ExtractThree) and the maintenance lemmas (ProductSplitEq,
ProductMergeAt, ProductFPUEq); the structural ones are pure so they can
be applied inside forall bodies via `let _ := lemma(...)`. The previous
`assume` in GhostOp2WI is replaced by an assert-forall that calls
ExtractThreeValid on the captured value seq.

Verified with `--noassumeInjectivityOnInhale` (CI flag).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread resalgebraNoAxioms/product.gobra Outdated
Comment thread resalgebraNoAxioms/product.gobra Outdated
Comment thread resalgebraNoAxioms/product.gobra Outdated
Comment thread resalgebraNoAxioms/product.gobra Outdated
Comment thread resalgebraNoAxioms/product.gobra Outdated
Comment thread resalgebraNoAxioms/loc.gobra Outdated
Comment thread resalgebraNoAxioms/loc.gobra Outdated
Comment thread resalgebraNoAxioms/loc.gobra Outdated
Comment thread resalgebraNoAxioms/loc.gobra Outdated
Comment thread resalgebraNoAxioms/loc.gobra Outdated
jcp19 and others added 5 commits April 25, 2026 22:09
- Trim docstrings (drop redundant "non-empty"/"pure so it can be used"/"Pure recursion on k" notes)
- Use `0 < len(...)` instead of `len(...) >= 1`
- Mark `pure func ... Unit` lemmas as `opaque` (cuts verification from ~35 min to ~2.5 min)
- Drop trailing `let _ := X in Unit{}` in favor of just `X` since `asserting`/RA-method calls already return Unit
- Drop redundant `len` and `IsElem` clauses already implied by other pre/postconditions

The `requires forall j :: IsElem(s[j])` in ExtractOneValid is kept because it's needed for well-formedness of the immediately-following `requires ra.IsValid(ProductOfSeq(s, ra))`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…perproject/gobra-libs into proof-remaining-assumption-resalgebra
- loc.gobra: drop wildcard `_` permission amounts in pure-func preconditions
  (`acc(&inUseIdx, _)` → `acc(&inUseIdx)`); idxPos: drop redundant
  `requires len(s) >= 1` (implied by `x elem s`).
- product.gobra: drop redundant `IsElem` ensures clauses in ExtractOneValid,
  ProductSplitEq, ProductMergeAt, and ProductFPUEq (callers can derive them
  from the input precondition / from RA.Compose's IsElem ensures).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread resalgebraNoAxioms/product.gobra Outdated
Co-authored-by: João Pereira <joaopereira.19@gmail.com>
Comment thread resalgebraNoAxioms/product.gobra Outdated
requires 0 < len(s1) && 0 < len(s2)
requires forall j int :: { s1[j] } 0 <= j && j < len(s1) ==> ra.IsElem(s1[j])
requires forall j int :: { s2[j] } 0 <= j && j < len(s2) ==> ra.IsElem(s2[j])
ensures forall j int :: { (s1 ++ s2)[j] } 0 <= j && j < len(s1 ++ s2) ==> ra.IsElem((s1 ++ s2)[j])
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postcondition may be unnecessary?

Comment thread resalgebraNoAxioms/product.gobra
Comment thread resalgebraNoAxioms/product.gobra
Comment thread resalgebraNoAxioms/product.gobra Outdated
ghost
opaque
requires ra != nil
requires len(s) >= 3
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precondition might be unnecessary? it is implied by

requires 0 <= p1 && p1 < len(s)
requires 0 <= p2 && p2 < len(s)
requires 0 <= p3 && p3 < len(s)
requires p1 != p2 && p1 != p3 && p2 != p3

Comment thread resalgebraNoAxioms/product.gobra Outdated
// (Non-pure variant retained for the lemma chain in maintenance proofs.)
ghost
requires ra != nil
requires 0 < len(s)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precondition unnecessary

Comment thread resalgebraNoAxioms/product.gobra
Comment thread resalgebraNoAxioms/product.gobra Outdated
// The merged value lives at min(p1, p2); max(p1, p2) is removed.
ghost
requires ra != nil
requires len(s) >= 2
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
requires len(s) >= 2

Comment thread resalgebraNoAxioms/product.gobra Outdated
let pmax := p1 < p2 ? p2 : p1 in
let merged := ra.Compose(s[p1], s[p2]) in
let s2 := s[:pmin] ++ seq[Elem]{merged} ++ s[pmin+1:pmax] ++ s[pmax+1:] in
len(s2) == len(s) - 1 &&
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop conjunct, probably unnecessary

Comment thread resalgebraNoAxioms/product.gobra Outdated
requires IsFramePreservingUpdate(ra, e1, e2)
requires ra.IsValid(ProductOfSeq(s, ra))
ensures let s2 := s[:posI] ++ seq[Elem]{e2} ++ s[posI+1:] in
len(s2) == len(s) &&
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conjunct probably unnecessary

- ProductOfSeqConcat: drop redundant `forall j .. IsElem((s1++s2)[j])` ensures
- ExtractThreeValid: drop `requires len(s) >= 3` (implied by the three position bounds with distinctness); reorder so the position requires precede `ra.IsValid(ProductOfSeq(s, ra))` (the latter calls ProductOfSeq, whose own precondition needs `0 < len(s)`, which Gobra derives from a position bound only if it appears earlier in the requires list)
- ExtractOneValid: drop `requires 0 < len(s)` (implied by `0 <= p && p < len(s)`); reorder for the same well-formedness reason
- ProductMergeAt: drop `requires len(s) >= 2` (implied by two distinct in-bounds positions)

The `len ==` ensures clauses on AdjacentSwapProduct, ProductOfSeqMoveFront, ExtractOneValid, ProductMergeAt, ProductFPUEq are kept — removing them caused `GhostOp1WI`/`GhostOp2WI`'s maintenance proofs to time out (Gobra needs the explicit length facts at the call sites; deriving them on the fly from the seq construction triggered exponential search).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jcp19 jcp19 marked this pull request as ready for review April 27, 2026 09:46
@jcp19 jcp19 changed the title resalgebraNoAxioms: discharge the remaining assume in GhostOp2WI resalgebraNoAxioms: Verify global validity of ghost locations Apr 27, 2026
@jcp19 jcp19 merged commit 8827154 into main Apr 27, 2026
1 check passed
@jcp19 jcp19 deleted the proof-remaining-assumption-resalgebra branch April 27, 2026 09:52
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