Laurel: avoid quantified modifies frames when using array theory#1374
Laurel: avoid quantified modifies frames when using array theory#1374julesmt wants to merge 12 commits into
Conversation
## Summary - Periodic merge of `main` into `main2` to keep main2 up to date with core improvements - 46 new commits from main since PR #1346 (mostly repo-removal PRs: #1339, #1351, #1343, #1329, #1334, plus code changes) - All conflicts resolved by keeping main2's versions (sub-repos stay local, no module migration, preserves main2-only features like Procedure.Body sum type, transparent procs, array axiomatization) - Fixed duplicate StrataDDM git entries that auto-merged into `docs/api/lake-manifest.json` and `docs/verso/lake-manifest.json` --------- Co-authored-by: Aaron Tomb <aarotomb@amazon.com> Co-authored-by: Michael Tautschnig <mt@debian.org> Co-authored-by: Kiro <kiro-agent@users.noreply.github.com> Co-authored-by: Juneyoung Lee <136006969+aqjune-aws@users.noreply.github.com> Co-authored-by: keyboardDrummer-bot <keyboardDrummer-bot@users.noreply.github.com> Co-authored-by: Mikaël Mayer <MikaelMayer@users.noreply.github.com> Co-authored-by: thanhnguyen-aws <ntson@amazon.com> Co-authored-by: Fabio Madge <fmadge@amazon.com> Co-authored-by: Joe Hendrix <joehx@amazon.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: June Lee <lebjuney@amazon.com> Co-authored-by: David Deng <daviddenghaotian@gmail.com> Co-authored-by: David Deng <htd@amazon.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Mikael Mayer <mimayere@amazon.com> Co-authored-by: Remy Willems <rwillems@amazon.com> Co-authored-by: keyboardDrummer-bot <keyboarddrummer.bot@gmail.com> Co-authored-by: Sagar Joshi <72283186+sagjoshi@users.noreply.github.com>
|
I found the term "array-theory" in this PR misleading because the PR does not directly use any SMT array theory. Instead, the PR relies on Core Map's which are not necessarily implemented using SMT array theory. In fact, I think Core is or at least was not using array theory for their maps, simply because it is or was not implemented yet. |
Each `LaurelPass.run` now receives `LaurelTranslateOptions`, instead of passes being parameterized at construction. `LaurelTranslateOptions` moves into `LaurelPass`, the pipeline threads the options into every pass, and the `comesBefore` lists no longer carry an arbitrary placeholder argument. No behavioural change: every pass ignores the new argument here.
Under `--use-array-theory` the heap `Map` is an SMT array, so for a `modifies` clause naming only individual references we can emit an enumerated, quantifier-free frame (`buildEnumeratedFrame`: overwrite the named rows) instead of the `∀`-based `buildPointwiseFrame`. The dispatch (`onlyIndividualRefs`) is restricted to bodiless procedures: a body that allocates cannot prove the whole-array equality, so bodies keep the pointwise frame, whose `< nextReference` guard tolerates allocation.
Structural #guards that the enumerated frame is quantifier-free while the pointwise frame is not (ModifiesFrameQuantifierFreeTest), the array-theory path including allocating bodies (T2c), and a perf/completeness regression for a chained spec procedure (T2e).
bf25905 to
d5ece2c
Compare
|
@keyboardDrummer-bot please resolve merge conflicts |
…laurel-modifies-array-theory
|
How come you can't make the enumerated encoding work with procedures that have a body? Suppose I have: then that would translate to something like: which has the curious implication that |
|
Yeah, I had pretty much the same example. The pointwise frame dodges this with the However to get it for bodies too, I split the jobs: callers assume the enumerated frame, and the body is checked separately by asserting the pointwise frame at every exit. what do you think (see next commit) ? @keyboardDrummer |
For an individual-ref modifies clause under array theory, callers now assume the quantifier-free enumerated frame as a free ensures, while the body proves the allocation-tolerant pointwise frame via asserts inserted before every exit, so callers never assume the quantifier. This drops the bodiless-only restriction: allocating bodies and writes-via-calls verify, and illegal writes are still rejected.
Brilliant! |
| /-- Build and attach `proc`'s modifies frame, then clear the clause. -/ | ||
| def transformModifiesClauses (model: SemanticModel) | ||
| (proc : Procedure) : Except (Array DiagnosticModel) Procedure := | ||
| (proc : Procedure) (useEnumeratedFrame : Bool := false) : Except (Array DiagnosticModel) Procedure := |
There was a problem hiding this comment.
Please remove the default values in the private methods. I think the only default should be in LaurelTranslateOptions
There was a problem hiding this comment.
Oh yeah sorry, I thought I had modified that, will do
Merge reviewed-kbd-will-merge-to-main into PR1374-kiro. Resolution kept the reviewed branch's generic LaurelPass/PassMeta pass framework, but threads the LaurelTranslateOptions argument as the first parameter of each pass's run (options-first), per review preference. Preserved the PR's enumeratedModifiesClauses option and its threading through modifiesClausesTransformPass. Dropped the PR's now-superseded translateInvokeOnAxiom (invokeOn-axiom generation is handled by ContractPass on the reviewed branch). Also documents that enumeratedModifiesClauses has no effect when the procedure's modifies clause contains sets.
cc440f0 to
5caabd8
Compare
Under
--use-array-theory, amodifiesclause naming only individual objectreferences is now encoded as a single quantifier-free heap equation instead of
a
∀-quantified frame, so the solver discharges it by array rewriting instead ofinstantiating a quantifier per object/field.
The
∀frame is unchanged for set-valued/emptymodifiesand when array theory isoff, so default behavior is untouched.