[Prover] Support map intrinsics and more bug fix in spec inference #19534
Merged
Conversation
This was referenced Apr 23, 2026
Contributor
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
ba4a2c4 to
d409f49
Compare
eb97ce2 to
48f2bf0
Compare
d409f49 to
23874fa
Compare
48f2bf0 to
12d1083
Compare
23874fa to
b3fc735
Compare
12d1083 to
3f6fc67
Compare
b3fc735 to
c33a347
Compare
3f6fc67 to
67353d1
Compare
c33a347 to
c90ee1e
Compare
3e7473d to
71cbbc2
Compare
71cbbc2 to
7cd67d3
Compare
67353d1 to
b1b22b4
Compare
b1b22b4 to
62a17d5
Compare
7cd67d3 to
a2d84ab
Compare
62a17d5 to
ff51ca1
Compare
a2d84ab to
209f85c
Compare
Merged
ff51ca1 to
321d11b
Compare
179ba4f to
68f5eec
Compare
68f5eec to
f35b176
Compare
f35b176 to
0fe7849
Compare
0fe7849 to
072afe6
Compare
072afe6 to
d1ded99
Compare
d1ded99 to
6a40536
Compare
6a40536 to
0a8791f
Compare
wrwg
approved these changes
May 26, 2026
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Contributor
✅ Forge suite
|
Contributor
✅ Forge suite
|
Contributor
✅ Forge suite
|
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.



Description
This PR extends the Move Prover's spec inference (WP/weakest-precondition) pipeline with support for intrinsic map functions and fixes several inference output bugs. It builds on PR #19493.
Closes #19512
Intrinsic map function support (
intrinsics.rs,pragmas.rs,spec_inference.rs, Boogie backend)WP previously treated all intrinsic map functions (
table::add,table::borrow,table::contains,table::remove, etc.) as opaque impure calls, producing unverifiable behavior predicates (result_of<f>). These functions have axiomatized spec counterparts (spec_set,spec_get,spec_contains_key,spec_len, etc.) declared in the Boogie prelude.Fix: the Move→Spec and Move→AbortSpec pairings are now encoded directly in
INTRINSIC_TYPE_MAP_ASSOC_FUNCTIONSvia the newIntrinsicFunDefstruct (replacing the former separate static tablesINTRINSIC_TYPE_MAP_MOVE_TO_SPEC_FUN/INTRINSIC_TYPE_MAP_MOVE_TO_ABORT_SPEC_FUN). Duringprocess_intrinsic_declarationthe pairings are materialized into two newIntrinsicDeclfields (move_to_spec_intrinsic,move_to_abort_spec_intrinsic), consistent with how vector intrinsics are handled.IntrinsicsAnnotation::get_spec_fun_for_move_funandget_abort_spec_fun_for_move_funread directly from these fields — no separate static table lookups at query time.The WP transfer function calls
try_as_intrinsic_map_spec_callto substitute the spec function directly — producing a verifiable pure spec call instead of a behavior predicate.mk_call_with_instrecords the call-site type instantiation so the sourcifier emits explicit type arguments (e.g.,spec_new<K, V>()instead ofspec_new()) — required for zero-argument spec functions whose type args cannot be inferred from the argument list.The Boogie backend's
$bp_AbortsOfemission was also extended:get_abort_spec_fun_for_move_funlooks up the abort-spec counterpart for a Move intrinsic and emits it as the abort body, rather than defaulting tofalse.Native vector function mapping (
spec_inference.rs)Native
std::vectorfunctions (empty,length,borrow) now have direct spec-language equivalents ([],len, index operator) instead of being compiled to uninterpreted behavior predicates.try_as_native_spec_exphandles this mapping.Spec inference output bug fixes (
sourcifier.rs,spec_inference.rs,inference.rs)vector<T>[]type annotation:Operation::Vectornow emitsvector<T>[]for empty vector literals (instead of barevector[]) so the compiler can infer the element type.rename_quant_vars_in_expnow excludes (a) variables free in range expressions and (b) binder names used by inner quantifiers when choosing a fresh name, preventing type errors likeforall x: BitVector: x >= amount.generate_fresh_spec_filenow reads the source.movefile to extract the exact address token used in themodule <addr>::<name>declaration, emittingspec std::bit_vectorrather thanspec 0x1::bit_vector. This ensuresmerge_spec_modulescan match the generated spec back to its source module.forallquantifier, the WP now distributes over top-level conjuncts so thatA(x) && B(where onlyA(x)mentions the bound variable) becomes(forall x: A(x)) && Brather thanforall x: A(x) && B.Framework spec changes
aptos-stdlib::pool_u64—pool_u64.spec.move(modified): re-enabled verification, ∀∀ struct invariants, opaque functions, fixed ensures/frames forbuy_in,redeem_shares,add_shares,DeductSharesEnsures, new specs fornew,create,amount_to_shares, etc.move-stdlib::bit_vector—bit_vector.spec.move(new): opaque spec forlength; frame conditions forset/unsetin source.move-stdlib::acl—acl.spec.move(new): full opaque specs withspec_containshelper, struct uniqueness invariant, aborts/ensures for all public functions.aptos-stdlib::math64—math64.spec.move(modified):pow,floor_log2,sqrtnow usepragma verify = false(replacing[abstract]annotations on individual conditions, which is the correct idiom when there is no paired[concrete]version). Also addspragma opaquetomax,min,clamp.How Has This Been Tested?
New inference test cases:
tests/inference/intrinsic_map— intrinsic map function WP supporttests/inference/nested_quant_rename— nested quantifier name collision fixtests/inference/vector_typing—vector<T>[]type annotation fixFramework specs verified with
move_package_verify(40s timeout) onbit_vectorandacl.Run inference tests with:
Key Areas to Review
pragmas.rs:IntrinsicFunDefstruct and updatedINTRINSIC_TYPE_MAP_ASSOC_FUNCTIONSintrinsics.rs: newIntrinsicDeclfields and updatedpopulate_intrinsic_decl/get_spec_fun_for_move_funspec_inference.rs:try_as_intrinsic_map_spec_call,try_as_native_spec_expmath64.spec.move:pragma verify = falseonpow/floor_log2/sqrtChecklist
Note
Medium Risk
Changes core prover inference, intrinsic wiring, and Boogie axiom generation; incorrect behavior could weaken or break verification, though scope is limited to the prover and spec files rather than on-chain execution.
Overview
Extends spec inference so intrinsic map (
SimpleMap) and nativestd::vectorcalls inline as pure spec expressions (spec_contains_key,spec_new,len,vector<T>[], etc.) instead of opaqueresult_of/aborts_ofbehavior predicates. Move↔spec and Move↔abort-spec pairings live inIntrinsicFunDef/INTRINSIC_TYPE_MAP_ASSOC_FUNCTIONS, with Boogie$bp_AbortsOfand map prelude hooks forspec_aborts_*functions.WP / output fixes: typed empty vectors in the sourcifier; fresher quantifier names (ranges + inner binders);
foralldistribution over top-level conjuncts for struct havoc; skip data/global invariant VC props in the WP; native/pure calls no longer advance memory labels; zero-arg axioms without emptyforall; generated.spec.moveheaders use the source file’s module address token (e.g.stdvs0x1).Boogie: native functions without Move specs can delegate
result_of/ensures_ofto$-specprelude functions.Framework / tests: stronger opaque specs and verification for
pool_u64,math64,acl,bit_vector; new inference tests (intrinsic_map,nested_quant_rename,vector_typing).Reviewed by Cursor Bugbot for commit 603158c. Bugbot is set up for automated code reviews on this repo. Configure here.