[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aptos-move-prove":3,"mdc--h3vfec-key":29,"related-repo-aptos-move-prove":3827,"related-org-aptos-move-prove":3895},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":20,"topics":24,"repo":25,"sourceUrl":27,"mdContent":28},"move-prove","verify Move specifications with Move Prover","Run the Move Prover to formally verify specifications",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aptos","Aptos Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faptos.png","aptos-labs",[13,17],{"name":14,"slug":15,"type":16},"Web3","web3","tag",{"name":18,"slug":19,"type":16},"Testing","testing",0,"https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-ai","2026-07-19T06:03:10.663492",null,[],{"repoUrl":21,"stars":20,"forks":20,"topics":26,"description":23},[],"https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-ai\u002Ftree\u002FHEAD\u002Fplugins\u002Fmove-flow\u002Fskills\u002Fmove-prove","---\nname: move-prove\ndescription: Run the Move Prover to formally verify specifications\n---\n\nBefore doing any work, use TaskCreate to create one task for each\n`**Task:**` entry listed below. Then execute them in order, marking\neach in_progress when you start it and completed when you finish.\n\n\n\n\n## Verification Tasks — Execute In Order\n\n**Task: Full-scope verification run.** Run verification for the full requested scope\nwith `timeout` set to 5. This gives an\noverview of all failures — both logical errors and timeouts.\n\n**Task: Fix logical errors.** If there are any logical errors, iterate to fix them\nusing the `exclude` parameter of the verify tool to exclude functions whose\nverification timed out. Only continue once all non-timeouts cleanly pass.\n\n**Task: Resolve timeouts.** Resolve timeouts one by one calling the prover with a\nfunction-level filter and `timeout` set to 10.\nApply the timeout resolution strategies from the reference material below\n(spec helpers, lemmas, proofs). If a function cannot be resolved after\n2 attempts and the user did not request\notherwise, add `pragma verify_duration_estimate = N;` where `N` is the exact\ntimeout at which you observed verification succeed. If verification never\nsucceeded, use `pragma verify = false;` instead.\n\n**Task: Final full-scope verification.** Run the prover for the full requested scope\nusing `timeout` 10 to verify success. Functions\nwith `pragma verify_duration_estimate = N;` where `N` exceeds the timeout will\nbe automatically skipped — this is expected.\n\n\n\n\nThe reference material below supports the tasks above.\n\n\n## Move Language\n\nMove on Aptos is a safe, resource-oriented programming language for smart contracts on the\nAptos blockchain. It uses a linear type system to enforce ownership and prevent\ndouble-spending at compile time.\n\n## Move Language Basics\n\n- **Modules** are the unit of code organization, published at an address.\n- **Structs** define data types; abilities (`key`, `store`, `copy`, `drop`) control what\n  operations are permitted.\n- **Entry functions** (`entry fun`) are transaction entry points callable from outside Move.\n- **View functions** (`#[view]`) are read-only queries that do not modify state.\n- **Global storage** stores resources (structs with `key`) at addresses.\n- **Move 2 syntax** (required):\n    - Read resource: `&T[addr]` (not `borrow_global\u003CT>(addr)`)\n    - Mutate resource: `&mut T[addr]` (not `borrow_global_mut\u003CT>(addr)`)\n    - Access field: `T[addr].field` directly (the compiler inserts the ref op)\n    - `acquires` annotations are no longer needed — do not add them.\n- **Error codes**: Use named constants for abort codes (`const E_NOT_FOUND: u64 = 1;`) and\n  document them.\n- **Comments**: Use `\u002F\u002F` for regular comments. `\u002F\u002F\u002F` is a **doc comment** and is only valid\n  directly before a `module`, `struct`, `enum`, `fun`, or `const` declaration.\n- **Edit hook**: The edit hook auto-runs on `.move` files after edits. If it reports\n  compilation errors, fix them before proceeding with further changes.\n\n\n### Links\n\n- [The Move Book](https:\u002F\u002Faptos-labs.github.io\u002Fmove-book\u002F)\n- [Aptos Framework Book](https:\u002F\u002Faptos-labs.github.io\u002Fframework-book\u002F)\n\n\n\n## Checking Move Code\n\nUse the `move_package_status` MCP tool to check for compilation errors and warnings.\n\n- Call `move_package_status` with `package_path` set to the package directory.\n- The tool sets error and returns detailed error messages if the package does not compile.\n\nNotice that like with a build system, the tool is idempotent, and does not cause recompilation\nif the compilation result and sources are up-to-date.\n\n\n## Package Manifest\n\nUse the `move_package_manifest` MCP tool to discover source files and dependencies\nof a Move package:\n\n- Call `move_package_manifest` with `package_path` set to the package directory.\n- The result includes `source_paths` (target modules) and `dep_paths` (dependencies).\n\n\n## Querying Package Structure\n\nUse the `move_package_query` MCP tool to inspect the structure of a Move package.\n\nParameters:\n\n- **`package_path`** (required) — path to the Move package directory.\n- **`query`** (required) — one of the query types below.\n- **`function`** (required for `function_usage`) — function name in the form `module_name::function_name`.\n\n### Query Types\n\n- **`dep_graph`** — returns a map from each module to the modules it depends on.\n  Useful for understanding module layering and import structure.\n- **`module_summary`** — returns a summary of each module's constants, structs,\n  and functions. Useful for getting an overview without reading all source files.\n- **`call_graph`** — returns a function-level call graph as a map from each\n  function to the functions it calls.\n- **`function_usage`** — returns direct and transitive calls\u002Fuses for a given\n  function. \"called\" = direct calls; \"used\" = direct calls + closure captures.\n  Requires the `function` parameter.\n\n\n\n## Move Specification Language\n\nMove specifications use `spec` blocks to express formal properties that are checked\nby the Move Prover.\n\n### Function spec clauses\n\nThese appear in `spec fun_name { ... }` blocks. Spec blocks always appear after the function\ndefinition. If `fun_name` clashes with a soft keyword (e.g. `lemma`), use `spec @fun_name { ... }`\nto escape it.\n\n- `ensures \u003Cexpr>`: Postcondition that must hold when the function returns normally.\n  Evaluated in the **post-state**. Use `old(expr)` to refer to pre-state values.\n- `aborts_if \u003Cexpr>`: Condition under which the function may abort. **Evaluated in the\n  pre-state** — do not use `old()` (see `old()` usage rules below). If any\n  `aborts_if` conditions are present, the function must abort if and only if one of the\n  conditions holds. Omitting all `aborts_if` clauses means abort behavior is *unspecified*\n  (any abort is allowed). To express that a function never aborts, write `aborts_if false;`.\n- `requires \u003Cexpr>`: Precondition that callers must satisfy. **Evaluated in the pre-state** —\n  Do not use `old()` (see `old()` usage rules below).\n- `modifies \u003Cresource>`: Declares which global resources the function may modify.\n\n### Loop invariants\n\nLoop invariants appear in a `spec` block after the loop body:\n\n```move\nwhile (cond) {\n    \u002F\u002F body\n} spec {\n    invariant \u003Cexpr>;\n};\n```\n\n- `invariant \u003Cexpr>`: A property that holds before the first iteration and is preserved by\n  each iteration. `old(x)` is only allowed on function parameters (see `old()` usage rules below.)\n\nLoops without invariants cause the prover to *havoc* all loop-modified variables, which can\nproduce vacuous, incorrect, or overly weak specifications. Every loop needs an invariant —\nexamine the actual `while` loops in function bodies to find all loops that lack one.\n\nA good invariant:\n1. Holds before the first iteration (initial values satisfy it).\n2. Is preserved by each iteration (inductive step).\n3. Relates loop-modified variables to function parameters and constants\n   (e.g., bounds like `i \u003C= n`, accumulators like `sum == i * step`).\n\n### Expressions in specs\n\n- `old(expr)`: Value of `expr` at function entry. See `old()` usage rules below for\n  where this is allowed.\n- `result`: Return value. Only valid in `ensures`.\n- `global\u003CT>(addr)`: Global resource of type `T` at address `addr`.\n- `exists\u003CT>(addr)`: True if a resource of type `T` exists at address `addr`.\n- Numeric type bounds: `MAX_U8`, `MAX_U16`, `MAX_U32`, `MAX_U64`, `MAX_U128`, `MAX_U256`.\n- **No dereference or borrow**: `*e` and `&e` are not allowed in spec\n  expressions. Spec expressions operate on values, not references — access\n  fields directly (e.g. `v.field`, not `(*v).field` or `(&v).field`).\n\n### `old()` usage rules\n\n`old(expr)` means \"value of `expr` at function entry.\" It is only valid in specific contexts:\n\n**Wrong \u002F Right examples:**\n\n```move\n\u002F\u002F WRONG: old() in aborts_if — compilation error\naborts_if old(x) + old(y) > MAX_U64;\n\u002F\u002F RIGHT: aborts_if is pre-state, just use the variables directly\naborts_if x + y > MAX_U64;\n\n\u002F\u002F WRONG: old() in requires — compilation error\nrequires old(len(v)) > 0;\n\u002F\u002F RIGHT: requires is pre-state\nrequires len(v) > 0;\n\n\u002F\u002F WRONG: old(local) in loop invariant — compilation error\ninvariant old(sum) \u003C= old(n) * MAX_U64;\n\u002F\u002F RIGHT: sum is a local — use it directly; n is a parameter — old(n) is ok\ninvariant sum \u003C= old(n) * MAX_U64;\n\n\u002F\u002F WRONG: old(resource) in loop invariant — compilation error\ninvariant old(global\u003CT>(addr)).field == 0;\n\u002F\u002F RIGHT: use resource directly\ninvariant global\u003CT>(addr).field == 0;\n```\n\n### Referring to Behavior of other Functions\n\nWhen specifying a function that calls other functions **which are not inline functions**, you\ncan use **behavioral predicates** to abstract the callee's specification without inlining its\ndetails. These built-in predicates lift a function's spec clauses into expressions:\n\n- `requires_of\u003Cf>(args)` — true when `f`'s `requires` clauses hold for `args`.\n- `aborts_of\u003Cf>(args)` — true when `f`'s `aborts_if` clauses hold for `args`.\n- `ensures_of\u003Cf>(args, result)` — true when `f`'s `ensures` clauses hold for\n  `args` and the given `result` value(s). For functions returning unit, omit\n  the result argument. For multiple return values, pass `result_1, result_2, ...`.\n- `result_of\u003Cf>(args)` — the return value of `f` when called with `args`,\n  usable in `let` bindings and expressions inside spec blocks.\n\nThe `\u003Cf>` target can be:\n- A **function parameter** of function type: `ensures_of\u003Cf>(x, result)` where\n  `f` is a parameter with type `|u64| u64`.\n- A **named function** (same module or cross-module): `ensures_of\u003Cincrement>(x, result)`\n  or `ensures_of\u003CM::increment>(x, result)`.\n- A **generic function** with explicit or inferred type arguments:\n  `ensures_of\u003Cidentity\u003Cu64>>(x, result)` or `ensures_of\u003Cidentity>(x, result)`.\n\n**Examples:**\n\nSpecifying a higher-order function that applies a callback:\n\n```move\nfun apply(f: |u64| u64, x: u64): u64 { f(x) }\nspec apply {\n    aborts_if aborts_of\u003Cf>(x);\n    ensures ensures_of\u003Cf>(x, result);\n}\n```\n\nUsing `result_of` to chain calls in a spec (e.g. `f(f(x))`):\n\n```move\nfun apply_seq(f: |u64| u64 has copy, x: u64): u64 { f(f(x)) }\nspec apply_seq {\n    let y = result_of\u003Cf>(x);\n    requires requires_of\u003Cf>(x) && requires_of\u003Cf>(y);\n    aborts_if aborts_of\u003Cf>(x) || aborts_of\u003Cf>(y);\n    ensures result == result_of\u003Cf>(y);\n}\n```\n\nReferring to a named function's behavior from a caller:\n\n```move\nspec bar {\n    ensures ensures_of\u003Cincrement>(x, result);\n}\n```\n\nUsing `result_of` inside loop invariants with closures:\n\n```move\nspec {\n    invariant forall j in 0..i: !result_of\u003Cpred>(v[j]);\n};\n```\n\n### Property markers\n\nThe `[inferred]` property marks conditions that were not written by the user. Its value indicates\nthe origin or quality:\n\n- `[inferred]`: Automatically inferred by weakest-precondition (WP) analysis. It may be overly complex, redundant,\n  or occasionally incorrect.\n- `[inferred = vacuous]`: Inferred by WP but detected as potentially vacuous (trivially true)\n  due to unconstrained quantifier variables. Typically results from missing loop invariants.\n- `[inferred = sathard]`: Inferred by WP but contains quantifier patterns that are hard for\n  SMT solvers. Likely to cause verification timeouts — should be simplified or reformulated.\n\n\n### Links\n\n- [Move Specification Language](https:\u002F\u002Faptos.dev\u002Fen\u002Fbuild\u002Fsmart-contracts\u002Fprover\u002Fspec-lang)\n\n\n\n\n\n\n\n\n\n\n## Writing and Editing Specs\n\nWhen writing or editing specifications:\n\n1. Use `move_package_manifest` to discover source files.\n2. Read the function body to understand its behavior and abort conditions.\n3. Write `spec fun_name { ... }` blocks after each function, following the Move Specification\n   Language rules above.\n4. Write `spec lemma lemma_name ...` block after the function for which they are introduced.\n5. Spec functions are put into a `spec fun` declarations.\n6. If the project already uses `.spec.move` files, put new specs into that file instead of the \n   main Move file.\n\n**`.spec.move` files:** A `.spec.move` file is compiled as part of the same module\nas the corresponding source file. Use `spec module { }` (the keyword `module`,\nnot a module name) to declare module-level spec items (helper functions, lemmas).\nUse `spec fun_name { }` to add conditions to functions defined in the main source.\nThere is no `spec \u003Cmodule_name> { }` syntax — `spec name { }` always targets a\nfunction named `name`.\n\n### Simplifying Specifications\n\nWork through the following in order when cleaning up inferred or hand-written specs.\n\n**Remove vacuous conditions.** Delete every condition marked `[inferred = vacuous]`.\nThese arise from havoced loop variables without sufficient invariants and are\nsemantically meaningless (e.g.\n`ensures [inferred = vacuous] forall x: u64: result == x`).\n\n**Eliminate quantifiers.** Conditions with quantifiers over unbounded types\n(`forall x: u64`, `exists x: u64`, `forall x: address`) cause SMT solver timeouts.\nThey are often marked `[inferred = sathard]` but not always. Replace each with an\nequivalent **non-quantified** expression:\n\n- `exists x: u64: x \u003C n && f(x)` — replace with a concrete bound or closed-form\n  expression derived from the loop logic.\n- `forall x: address: x != a ==> g(x)` — this expresses a frame condition (\"nothing\n  else changed\"). Replace with an explicit `modifies` clause or enumerate the affected\n  addresses.\n\n**Ensure quantifiers have triggers.** Quantifiers without triggers must be avoided. Move \nsupports lists of triggers as in `Q x: T, y: R {p1, .., pn}..{q1, .., qn}: e`, where each outer \nlist is an alternative where all inner patterns must match. Notice that only triggers over \nuninterpreted functions are allowed, not over builtin operators.\n\n**Simplify `update_field` expressions.** The WP engine uses\n`update_field(s, field, val)` for struct mutations. Rewrite to direct struct\nconstruction when all fields are determined, e.g.:\n\n- `update_field(old(global\u003CT>(addr)), value, v)` becomes\n  `T { value: v, ..old(global\u003CT>(addr)) }`, or when the struct has a single field,\n  simply `T { value: v }`.\n- Nested `update_field(update_field(old(p), x, a), y, b)` becomes\n  `Point { x: a, y: b }` when all fields are covered.\n\n**Consolidate unrolled specs.** When `pragma unroll` is used, the WP produces one\ncondition per unrolling step (e.g. `n == 0 ==> ...`, `n == 1 ==> ...`, ...,\n`k \u003C n ==> ...`). If there is a closed-form generalization, replace the case list\nwith a single condition. Remove the `pragma unroll` once the closed-form is in place.\n\n**General cleanup:**\n\n- Fix `old()` usage: `old()` in `aborts_if` or `requires` is invalid — those\n  clauses are already evaluated in the pre-state. Remove `old()` wrappers.\n- Remove redundant conditions implied by others or by language guarantees (e.g. an\n  `aborts_if` subsumed by a stronger one).\n- Simplify arithmetic. The WP engine mirrors the computation steps, producing\n  expressions that can be algebraically reduced:\n  - Combine terms: `(n - 1) * n \u002F 2 + n` simplifies to `n * (n + 1) \u002F 2`.\n  - Flatten nested offsets: `old(v) + 1 + 1` becomes `old(v) + 2`.\n  - Simplify overflow bounds: `v + (n - 1) > MAX_U64 - 1` becomes `v + n > MAX_U64`.\n  - Specs use mathematical (unbounded) integers, so unlike Move code there is no\n    risk of underflow in spec expressions — reorder freely for clarity.\n- **Keep `[inferred]` markers** on all inferred conditions — they distinguish\n  inferred specs from user-written ones and are needed for WP re-runs.\n  Remove `[inferred = vacuous]` and `[inferred = sathard]` conditions entirely\n  (as described above), but keep plain `[inferred]` on conditions you retain.\n- **Keep `pragma opaque = true;`** — never remove it. It is essential for\n  verification performance, not an inference artifact. If a function with\n  `pragma opaque` fails verification, add `pragma verify = false;` rather\n  than removing the opaque pragma.\n\n### Additional Rules for Editing Specs\n\n1. **Do not change function bodies.** Only modify `spec` blocks and their contents.\n2. **Preserve** any user-written (non-inferred) specifications exactly as they are.\n3. **Never drop `aborts_if` conditions.** Every function that can abort must have\n   `aborts_if` conditions. The WP tool infers both `ensures` and `aborts_if` —\n   simplify them but never remove them just because they are complex or hard to\n   verify. If an `aborts_if` needs rewriting, replace it with a semantically\n   equivalent expression, do not delete it.\n4. **Never remove `pragma opaque`.** The WP tool marks inferred specs as opaque\n   so the prover uses the spec contract instead of inlining the function body.\n   Removing it causes verification to re-analyze the implementation, leading to\n   timeouts. Preserve `pragma opaque = true;` in every spec block that has it.\n   If verification fails on an opaque function (e.g., the prover cannot reason\n   about closure side effects), add `pragma verify = false;` to disable\n   verification while keeping the spec contract intact for callers.\n5. **Never duplicate conditions.** Before adding any condition to a spec block,\n   check whether an equivalent condition already exists. Do not create a condition\n   that is semantically identical to one already present in the same spec block.\n6. **No empty spec blocks.** Never create or leave behind an empty\n   `spec fun_name {}` block. If removing inferred conditions would leave a spec\n   block with no conditions or pragmas, delete the entire block instead.\n\n\n\n\n\n\n\n\n\n\n## Proofs and Lemmas\n\n### Example\n\n```move\nspec fun sum(n: u64): u64 {\n    if (n == 0) { 0 } else { n + sum(n - 1) }\n}\n\nspec lemma monotonicity(x: num, y: num) {\n    requires x \u003C= y;\n    ensures sum(x) \u003C= sum(y);\n} proof {\n    if (x \u003C y) {\n        assert sum(y - 1) \u003C= sum(y);\n        apply monotonicity(x, y - 1);\n    }\n}\n\n\nfun sum_up_to(n: u64): u64 { \u002F* iterative impl *\u002F }\nspec sum_up_to {\n    requires n \u003C= 5;\n    ensures result == sum(n);\n} proof {\n   forall x,y {sum(x), sum(y)} apply monotonicity(x, y);\n}\n```\n\n### Proofs\n\nA proof consists of a sequence of\nproof statements together with if-then-else and let bindings.\n\nProof statements: `let name = Expr`, `if (Expr) Proof else Proof`,\n`assert Expr`, `assume Expr`, `apply LemmaInstance`,\n`forall QuantifierDecls [Patterns] apply LemmaInstance`,\n`calc (Expr { RelOp Expr })`.\n\nA proof block can be attached to any specification block as postfix to that block, for example:\n\n```\nspec sum_to_n {\n  ensures result == sum(n);\n} proof {\n  forall x: u64, y: u64 apply Monotonicity(x, y);\n}  \n```\n\nA proof is translated by mapping it to a sequence of assumes\u002Fasserts at the\nverification entry points of a function.\n\n- The split statement is translated by creating different verification variants for each value split \n  with according assumptions of the value at the split point and otherwise identical content.\n- The apply statement is translated by injecting pre\u002Fpost conditions of the (expected to be proven) lemma.\n  This is very similar like calling an opaque function in Move code.\n\n### Lemmas\n\nA Lemma is a member of a specification block, similar like a spec function. Its\nuser syntax is:\n\n```\nspec fun sum(n: u64): u64 {\n    if (n == 0) { 0 } else { n + sum(n - 1) }\n}\nspec lemma sum_monotonicity(x: num, y: num) {\n    requires x \u003C= y;\n    ensures sum(x) \u003C= sum(y);\n} proof {\n    if (x \u003C y) {\n        assert sum(y - 1) \u003C= sum(y);\n        apply sum_monotonicity(x, y - 1);\n    }\n}\n```\n\nOr inside a `spec module { }` block (the keyword `module`, not a module name):\n\n```\nspec module {\n  fun sum ...\n  lemma sum_monotonicity ...\n}\n```\n\n**Important:** `spec name { }` always targets a *function* named `name`.\nThere is no `spec \u003Cmodule_name> { }` syntax. Module-level items (helper\nfunctions, lemmas) go inside `spec module { }`. Lemmas are **not valid**\ninside function spec blocks (`spec fun_name { }`).\n\nThe `spec lemma` shortcut is sugar for `spec module { lemma ... }`, analogous\nto the `spec fun` shortcut for helper functions.\n\nIt has a parameter list like a spec function (but no return value) followed by a\nspecification block (with requires, ensures, and pragmas the only allowed conditions).\nAttached to this is an (optional) proof.\n\nLemma names are in a separate namespace. They are scoped to modules,\nsimilar like specification functions. They can only be referenced from\nproof 'apply' statements.\n\n\n\n\n## Verification \n\n### Verification Tool\n\nUse `move_package_verify` to run the Move Prover on a package and\nformally verify its specifications:\n\n- Call with `package_path` set to the package directory and `timeout` set to\n  5.\n- The tool returns \"verification succeeded\" when all specs hold, or a diagnostic with a\n  counterexample when a spec fails.\n\n#### Narrowing scope with filters\n\nUse the `filter` parameter to restrict the verification scope:\n\n- **Single function:** set `filter` to `module_name::function_name`.\n- **Single module:** set `filter` to `module_name`.\n\n#### Excluding targets\n\nUse the `exclude` parameter to skip specific functions or modules while\nverifying the rest of the scope:\n\n- **Exclude function(s):** set `exclude` to `[\"module_name::function_name\"]`.\n- **Exclude module(s):** set `exclude` to `[\"module_name\"]`.\n\nExclusions take precedence over the `filter` scope — a target that matches both\n`filter` and `exclude` is excluded. This is useful in the \"Fix logical errors\" task to skip timed-out\nfunctions without modifying source files.\n\n#### Setting timeout\n\nVerification can be long-running (10 seconds or more). Always explicitly specify a timeout. \nStart with a low timeout of 5 to get quick feedback.\nIncrease the timeout to not more than 10 in the case of \ninvestigating difficult verification problems. \n\n### Diagnosing Verification Failures\n\nWhen the prover reports a counterexample or error:\n\n- **Postcondition failure**: The `ensures` clause doesn't hold for some execution path.\n  Check whether an edge case is missing or the condition is too strong.\n- **Abort condition failure**: An abort path is not covered by `aborts_if`. Trace which\n  operations can abort (arithmetic overflow, missing resource, vector out-of-bounds) and\n  add the missing condition.\n- **Wrong `old()` usage**: Using `old()` in `aborts_if` or `requires` causes a compilation\n  error. Remove it — those clauses are already evaluated in the pre-state.\n- **Loop-related failures**: Missing or too-weak loop invariants cause havoced variables.\n  Strengthen the invariant to constrain all loop-modified variables.\n- **Timeout (\"out of resources\")**:\n\n  Do not delete, comment out, or weaken any `aborts_if` or `ensures`\n  condition to resolve a timeout. This includes adding\n  `pragma aborts_if_is_partial;`, which silently suppresses uncovered abort\n  paths. Every condition is assumed semantically correct; removing one hides\n  real properties and makes the specification unsound.\n\n  Timeout resolution strategies — try these in order, and iterate\n  aggressively before resorting to `pragma verify_duration_estimate`:\n\n  1. **Add data invariants and global update invariants** to constrain\n     resource state. These are checked once per modifying function and then\n     assumed at every call site (including inside loops), giving the prover\n     facts for free without recursive helpers. See the inference reference\n     for details on when to use each kind.\n\n  2. **Introduce spec helper functions** that capture intermediate properties.\n     Factor complex `ensures` into compositions of simpler helpers. Each\n     helper should express one logical step the solver can verify independently.\n\n  3. **Add lemmas** to establish properties about spec helpers\n     (e.g. monotonicity, induction steps) that the solver cannot discover\n     on its own. Lemmas are proven propositions — do not introduce axioms.\n\n  4. **Add `proof { ... }` blocks** to function specs or lemmas to guide\n     the verifier with `assert`, `apply`, and `calc` steps. Use `apply`\n     to instantiate lemmas at specific points in the proof.\n\n  5. **Rewrite spec expressions** while preserving their meaning — factor\n     out common sub-expressions into `let` bindings, reorder conjuncts,\n     or replace a complex closed-form with a recursive helper connected\n     by a lemma.\n\n  When you use universal lemma application, always add triggers, as\n  in `forall x: u64 {f(x)} apply lemma_for_f(x)`.\n\n  **Avoid non-linear arithmetic in spec helpers.** SMT solvers handle linear\n  arithmetic well but struggle with multiplication, division, or modulo between\n  two non-constant expressions. Prefer additive recurrences over closed-form\n  products. If a non-linear closed form is needed, connect it to a recursive\n  helper via a lemma so the solver reasons about each step linearly.\n\n  **Do not redefine built-in operations as spec helpers.** The SMT solver\n  already understands `*`, `\u002F`, `%`, comparisons, and bitwise operations\n  natively. Only introduce a spec helper when it encodes logic the solver\n  does not have built in — such as a loop accumulation pattern or a\n  recursive data-structure traversal.\n\n  **Document every function and lemma.** Add a `\u002F\u002F\u002F` doc comment explaining\n  what property it captures and why it is needed. Place new spec helper\n  functions below the Move function that introduces them. Place lemmas\n  directly beneath their helper's declaration.\n\n\n\n\n\n## Task\n\nRun the Move Prover to verify the current package.\n",{"data":30,"body":31},{"name":4,"description":6},{"type":32,"children":33},"root",[34,51,58,77,95,136,166,171,177,182,188,478,485,510,516,529,557,562,568,580,620,626,638,643,703,709,774,780,793,799,836,970,976,988,1046,1075,1095,1100,1135,1141,1333,1344,1361,1369,1541,1547,1566,1708,1721,1809,1817,1822,1869,1890,1952,1957,1987,1998,2028,2034,2046,2081,2086,2098,2104,2109,2179,2247,2253,2258,2282,2328,2361,2379,2405,2454,2502,2510,2703,2709,2841,2847,2853,3032,3038,3043,3098,3103,3113,3118,3131,3137,3142,3151,3170,3179,3236,3263,3268,3273,3279,3285,3297,3324,3331,3343,3391,3397,3408,3455,3480,3486,3491,3497,3502,3810,3816,3821],{"type":35,"tag":36,"props":37,"children":38},"element","p",{},[39,42,49],{"type":40,"value":41},"text","Before doing any work, use TaskCreate to create one task for each\n",{"type":35,"tag":43,"props":44,"children":46},"code",{"className":45},[],[47],{"type":40,"value":48},"**Task:**",{"type":40,"value":50}," entry listed below. Then execute them in order, marking\neach in_progress when you start it and completed when you finish.",{"type":35,"tag":52,"props":53,"children":55},"h2",{"id":54},"verification-tasks-execute-in-order",[56],{"type":40,"value":57},"Verification Tasks — Execute In Order",{"type":35,"tag":36,"props":59,"children":60},{},[61,67,69,75],{"type":35,"tag":62,"props":63,"children":64},"strong",{},[65],{"type":40,"value":66},"Task: Full-scope verification run.",{"type":40,"value":68}," Run verification for the full requested scope\nwith ",{"type":35,"tag":43,"props":70,"children":72},{"className":71},[],[73],{"type":40,"value":74},"timeout",{"type":40,"value":76}," set to 5. This gives an\noverview of all failures — both logical errors and timeouts.",{"type":35,"tag":36,"props":78,"children":79},{},[80,85,87,93],{"type":35,"tag":62,"props":81,"children":82},{},[83],{"type":40,"value":84},"Task: Fix logical errors.",{"type":40,"value":86}," If there are any logical errors, iterate to fix them\nusing the ",{"type":35,"tag":43,"props":88,"children":90},{"className":89},[],[91],{"type":40,"value":92},"exclude",{"type":40,"value":94}," parameter of the verify tool to exclude functions whose\nverification timed out. Only continue once all non-timeouts cleanly pass.",{"type":35,"tag":36,"props":96,"children":97},{},[98,103,105,110,112,118,120,126,128,134],{"type":35,"tag":62,"props":99,"children":100},{},[101],{"type":40,"value":102},"Task: Resolve timeouts.",{"type":40,"value":104}," Resolve timeouts one by one calling the prover with a\nfunction-level filter and ",{"type":35,"tag":43,"props":106,"children":108},{"className":107},[],[109],{"type":40,"value":74},{"type":40,"value":111}," set to 10.\nApply the timeout resolution strategies from the reference material below\n(spec helpers, lemmas, proofs). If a function cannot be resolved after\n2 attempts and the user did not request\notherwise, add ",{"type":35,"tag":43,"props":113,"children":115},{"className":114},[],[116],{"type":40,"value":117},"pragma verify_duration_estimate = N;",{"type":40,"value":119}," where ",{"type":35,"tag":43,"props":121,"children":123},{"className":122},[],[124],{"type":40,"value":125},"N",{"type":40,"value":127}," is the exact\ntimeout at which you observed verification succeed. If verification never\nsucceeded, use ",{"type":35,"tag":43,"props":129,"children":131},{"className":130},[],[132],{"type":40,"value":133},"pragma verify = false;",{"type":40,"value":135}," instead.",{"type":35,"tag":36,"props":137,"children":138},{},[139,144,146,151,153,158,159,164],{"type":35,"tag":62,"props":140,"children":141},{},[142],{"type":40,"value":143},"Task: Final full-scope verification.",{"type":40,"value":145}," Run the prover for the full requested scope\nusing ",{"type":35,"tag":43,"props":147,"children":149},{"className":148},[],[150],{"type":40,"value":74},{"type":40,"value":152}," 10 to verify success. Functions\nwith ",{"type":35,"tag":43,"props":154,"children":156},{"className":155},[],[157],{"type":40,"value":117},{"type":40,"value":119},{"type":35,"tag":43,"props":160,"children":162},{"className":161},[],[163],{"type":40,"value":125},{"type":40,"value":165}," exceeds the timeout will\nbe automatically skipped — this is expected.",{"type":35,"tag":36,"props":167,"children":168},{},[169],{"type":40,"value":170},"The reference material below supports the tasks above.",{"type":35,"tag":52,"props":172,"children":174},{"id":173},"move-language",[175],{"type":40,"value":176},"Move Language",{"type":35,"tag":36,"props":178,"children":179},{},[180],{"type":40,"value":181},"Move on Aptos is a safe, resource-oriented programming language for smart contracts on the\nAptos blockchain. It uses a linear type system to enforce ownership and prevent\ndouble-spending at compile time.",{"type":35,"tag":52,"props":183,"children":185},{"id":184},"move-language-basics",[186],{"type":40,"value":187},"Move Language Basics",{"type":35,"tag":189,"props":190,"children":191},"ul",{},[192,203,243,261,278,295,372,390,460],{"type":35,"tag":193,"props":194,"children":195},"li",{},[196,201],{"type":35,"tag":62,"props":197,"children":198},{},[199],{"type":40,"value":200},"Modules",{"type":40,"value":202}," are the unit of code organization, published at an address.",{"type":35,"tag":193,"props":204,"children":205},{},[206,211,213,219,221,227,228,234,235,241],{"type":35,"tag":62,"props":207,"children":208},{},[209],{"type":40,"value":210},"Structs",{"type":40,"value":212}," define data types; abilities (",{"type":35,"tag":43,"props":214,"children":216},{"className":215},[],[217],{"type":40,"value":218},"key",{"type":40,"value":220},", ",{"type":35,"tag":43,"props":222,"children":224},{"className":223},[],[225],{"type":40,"value":226},"store",{"type":40,"value":220},{"type":35,"tag":43,"props":229,"children":231},{"className":230},[],[232],{"type":40,"value":233},"copy",{"type":40,"value":220},{"type":35,"tag":43,"props":236,"children":238},{"className":237},[],[239],{"type":40,"value":240},"drop",{"type":40,"value":242},") control what\noperations are permitted.",{"type":35,"tag":193,"props":244,"children":245},{},[246,251,253,259],{"type":35,"tag":62,"props":247,"children":248},{},[249],{"type":40,"value":250},"Entry functions",{"type":40,"value":252}," (",{"type":35,"tag":43,"props":254,"children":256},{"className":255},[],[257],{"type":40,"value":258},"entry fun",{"type":40,"value":260},") are transaction entry points callable from outside Move.",{"type":35,"tag":193,"props":262,"children":263},{},[264,269,270,276],{"type":35,"tag":62,"props":265,"children":266},{},[267],{"type":40,"value":268},"View functions",{"type":40,"value":252},{"type":35,"tag":43,"props":271,"children":273},{"className":272},[],[274],{"type":40,"value":275},"#[view]",{"type":40,"value":277},") are read-only queries that do not modify state.",{"type":35,"tag":193,"props":279,"children":280},{},[281,286,288,293],{"type":35,"tag":62,"props":282,"children":283},{},[284],{"type":40,"value":285},"Global storage",{"type":40,"value":287}," stores resources (structs with ",{"type":35,"tag":43,"props":289,"children":291},{"className":290},[],[292],{"type":40,"value":218},{"type":40,"value":294},") at addresses.",{"type":35,"tag":193,"props":296,"children":297},{},[298,303,305],{"type":35,"tag":62,"props":299,"children":300},{},[301],{"type":40,"value":302},"Move 2 syntax",{"type":40,"value":304}," (required):\n",{"type":35,"tag":189,"props":306,"children":307},{},[308,329,348,361],{"type":35,"tag":193,"props":309,"children":310},{},[311,313,319,321,327],{"type":40,"value":312},"Read resource: ",{"type":35,"tag":43,"props":314,"children":316},{"className":315},[],[317],{"type":40,"value":318},"&T[addr]",{"type":40,"value":320}," (not ",{"type":35,"tag":43,"props":322,"children":324},{"className":323},[],[325],{"type":40,"value":326},"borrow_global\u003CT>(addr)",{"type":40,"value":328},")",{"type":35,"tag":193,"props":330,"children":331},{},[332,334,340,341,347],{"type":40,"value":333},"Mutate resource: ",{"type":35,"tag":43,"props":335,"children":337},{"className":336},[],[338],{"type":40,"value":339},"&mut T[addr]",{"type":40,"value":320},{"type":35,"tag":43,"props":342,"children":344},{"className":343},[],[345],{"type":40,"value":346},"borrow_global_mut\u003CT>(addr)",{"type":40,"value":328},{"type":35,"tag":193,"props":349,"children":350},{},[351,353,359],{"type":40,"value":352},"Access field: ",{"type":35,"tag":43,"props":354,"children":356},{"className":355},[],[357],{"type":40,"value":358},"T[addr].field",{"type":40,"value":360}," directly (the compiler inserts the ref op)",{"type":35,"tag":193,"props":362,"children":363},{},[364,370],{"type":35,"tag":43,"props":365,"children":367},{"className":366},[],[368],{"type":40,"value":369},"acquires",{"type":40,"value":371}," annotations are no longer needed — do not add them.",{"type":35,"tag":193,"props":373,"children":374},{},[375,380,382,388],{"type":35,"tag":62,"props":376,"children":377},{},[378],{"type":40,"value":379},"Error codes",{"type":40,"value":381},": Use named constants for abort codes (",{"type":35,"tag":43,"props":383,"children":385},{"className":384},[],[386],{"type":40,"value":387},"const E_NOT_FOUND: u64 = 1;",{"type":40,"value":389},") and\ndocument them.",{"type":35,"tag":193,"props":391,"children":392},{},[393,398,400,406,408,414,416,421,423,429,430,436,437,443,444,450,452,458],{"type":35,"tag":62,"props":394,"children":395},{},[396],{"type":40,"value":397},"Comments",{"type":40,"value":399},": Use ",{"type":35,"tag":43,"props":401,"children":403},{"className":402},[],[404],{"type":40,"value":405},"\u002F\u002F",{"type":40,"value":407}," for regular comments. ",{"type":35,"tag":43,"props":409,"children":411},{"className":410},[],[412],{"type":40,"value":413},"\u002F\u002F\u002F",{"type":40,"value":415}," is a ",{"type":35,"tag":62,"props":417,"children":418},{},[419],{"type":40,"value":420},"doc comment",{"type":40,"value":422}," and is only valid\ndirectly before a ",{"type":35,"tag":43,"props":424,"children":426},{"className":425},[],[427],{"type":40,"value":428},"module",{"type":40,"value":220},{"type":35,"tag":43,"props":431,"children":433},{"className":432},[],[434],{"type":40,"value":435},"struct",{"type":40,"value":220},{"type":35,"tag":43,"props":438,"children":440},{"className":439},[],[441],{"type":40,"value":442},"enum",{"type":40,"value":220},{"type":35,"tag":43,"props":445,"children":447},{"className":446},[],[448],{"type":40,"value":449},"fun",{"type":40,"value":451},", or ",{"type":35,"tag":43,"props":453,"children":455},{"className":454},[],[456],{"type":40,"value":457},"const",{"type":40,"value":459}," declaration.",{"type":35,"tag":193,"props":461,"children":462},{},[463,468,470,476],{"type":35,"tag":62,"props":464,"children":465},{},[466],{"type":40,"value":467},"Edit hook",{"type":40,"value":469},": The edit hook auto-runs on ",{"type":35,"tag":43,"props":471,"children":473},{"className":472},[],[474],{"type":40,"value":475},".move",{"type":40,"value":477}," files after edits. If it reports\ncompilation errors, fix them before proceeding with further changes.",{"type":35,"tag":479,"props":480,"children":482},"h3",{"id":481},"links",[483],{"type":40,"value":484},"Links",{"type":35,"tag":189,"props":486,"children":487},{},[488,500],{"type":35,"tag":193,"props":489,"children":490},{},[491],{"type":35,"tag":492,"props":493,"children":497},"a",{"href":494,"rel":495},"https:\u002F\u002Faptos-labs.github.io\u002Fmove-book\u002F",[496],"nofollow",[498],{"type":40,"value":499},"The Move Book",{"type":35,"tag":193,"props":501,"children":502},{},[503],{"type":35,"tag":492,"props":504,"children":507},{"href":505,"rel":506},"https:\u002F\u002Faptos-labs.github.io\u002Fframework-book\u002F",[496],[508],{"type":40,"value":509},"Aptos Framework Book",{"type":35,"tag":52,"props":511,"children":513},{"id":512},"checking-move-code",[514],{"type":40,"value":515},"Checking Move Code",{"type":35,"tag":36,"props":517,"children":518},{},[519,521,527],{"type":40,"value":520},"Use the ",{"type":35,"tag":43,"props":522,"children":524},{"className":523},[],[525],{"type":40,"value":526},"move_package_status",{"type":40,"value":528}," MCP tool to check for compilation errors and warnings.",{"type":35,"tag":189,"props":530,"children":531},{},[532,552],{"type":35,"tag":193,"props":533,"children":534},{},[535,537,542,544,550],{"type":40,"value":536},"Call ",{"type":35,"tag":43,"props":538,"children":540},{"className":539},[],[541],{"type":40,"value":526},{"type":40,"value":543}," with ",{"type":35,"tag":43,"props":545,"children":547},{"className":546},[],[548],{"type":40,"value":549},"package_path",{"type":40,"value":551}," set to the package directory.",{"type":35,"tag":193,"props":553,"children":554},{},[555],{"type":40,"value":556},"The tool sets error and returns detailed error messages if the package does not compile.",{"type":35,"tag":36,"props":558,"children":559},{},[560],{"type":40,"value":561},"Notice that like with a build system, the tool is idempotent, and does not cause recompilation\nif the compilation result and sources are up-to-date.",{"type":35,"tag":52,"props":563,"children":565},{"id":564},"package-manifest",[566],{"type":40,"value":567},"Package Manifest",{"type":35,"tag":36,"props":569,"children":570},{},[571,572,578],{"type":40,"value":520},{"type":35,"tag":43,"props":573,"children":575},{"className":574},[],[576],{"type":40,"value":577},"move_package_manifest",{"type":40,"value":579}," MCP tool to discover source files and dependencies\nof a Move package:",{"type":35,"tag":189,"props":581,"children":582},{},[583,599],{"type":35,"tag":193,"props":584,"children":585},{},[586,587,592,593,598],{"type":40,"value":536},{"type":35,"tag":43,"props":588,"children":590},{"className":589},[],[591],{"type":40,"value":577},{"type":40,"value":543},{"type":35,"tag":43,"props":594,"children":596},{"className":595},[],[597],{"type":40,"value":549},{"type":40,"value":551},{"type":35,"tag":193,"props":600,"children":601},{},[602,604,610,612,618],{"type":40,"value":603},"The result includes ",{"type":35,"tag":43,"props":605,"children":607},{"className":606},[],[608],{"type":40,"value":609},"source_paths",{"type":40,"value":611}," (target modules) and ",{"type":35,"tag":43,"props":613,"children":615},{"className":614},[],[616],{"type":40,"value":617},"dep_paths",{"type":40,"value":619}," (dependencies).",{"type":35,"tag":52,"props":621,"children":623},{"id":622},"querying-package-structure",[624],{"type":40,"value":625},"Querying Package Structure",{"type":35,"tag":36,"props":627,"children":628},{},[629,630,636],{"type":40,"value":520},{"type":35,"tag":43,"props":631,"children":633},{"className":632},[],[634],{"type":40,"value":635},"move_package_query",{"type":40,"value":637}," MCP tool to inspect the structure of a Move package.",{"type":35,"tag":36,"props":639,"children":640},{},[641],{"type":40,"value":642},"Parameters:",{"type":35,"tag":189,"props":644,"children":645},{},[646,659,673],{"type":35,"tag":193,"props":647,"children":648},{},[649,657],{"type":35,"tag":62,"props":650,"children":651},{},[652],{"type":35,"tag":43,"props":653,"children":655},{"className":654},[],[656],{"type":40,"value":549},{"type":40,"value":658}," (required) — path to the Move package directory.",{"type":35,"tag":193,"props":660,"children":661},{},[662,671],{"type":35,"tag":62,"props":663,"children":664},{},[665],{"type":35,"tag":43,"props":666,"children":668},{"className":667},[],[669],{"type":40,"value":670},"query",{"type":40,"value":672}," (required) — one of the query types below.",{"type":35,"tag":193,"props":674,"children":675},{},[676,685,687,693,695,701],{"type":35,"tag":62,"props":677,"children":678},{},[679],{"type":35,"tag":43,"props":680,"children":682},{"className":681},[],[683],{"type":40,"value":684},"function",{"type":40,"value":686}," (required for ",{"type":35,"tag":43,"props":688,"children":690},{"className":689},[],[691],{"type":40,"value":692},"function_usage",{"type":40,"value":694},") — function name in the form ",{"type":35,"tag":43,"props":696,"children":698},{"className":697},[],[699],{"type":40,"value":700},"module_name::function_name",{"type":40,"value":702},".",{"type":35,"tag":479,"props":704,"children":706},{"id":705},"query-types",[707],{"type":40,"value":708},"Query Types",{"type":35,"tag":189,"props":710,"children":711},{},[712,726,740,754],{"type":35,"tag":193,"props":713,"children":714},{},[715,724],{"type":35,"tag":62,"props":716,"children":717},{},[718],{"type":35,"tag":43,"props":719,"children":721},{"className":720},[],[722],{"type":40,"value":723},"dep_graph",{"type":40,"value":725}," — returns a map from each module to the modules it depends on.\nUseful for understanding module layering and import structure.",{"type":35,"tag":193,"props":727,"children":728},{},[729,738],{"type":35,"tag":62,"props":730,"children":731},{},[732],{"type":35,"tag":43,"props":733,"children":735},{"className":734},[],[736],{"type":40,"value":737},"module_summary",{"type":40,"value":739}," — returns a summary of each module's constants, structs,\nand functions. Useful for getting an overview without reading all source files.",{"type":35,"tag":193,"props":741,"children":742},{},[743,752],{"type":35,"tag":62,"props":744,"children":745},{},[746],{"type":35,"tag":43,"props":747,"children":749},{"className":748},[],[750],{"type":40,"value":751},"call_graph",{"type":40,"value":753}," — returns a function-level call graph as a map from each\nfunction to the functions it calls.",{"type":35,"tag":193,"props":755,"children":756},{},[757,765,767,772],{"type":35,"tag":62,"props":758,"children":759},{},[760],{"type":35,"tag":43,"props":761,"children":763},{"className":762},[],[764],{"type":40,"value":692},{"type":40,"value":766}," — returns direct and transitive calls\u002Fuses for a given\nfunction. \"called\" = direct calls; \"used\" = direct calls + closure captures.\nRequires the ",{"type":35,"tag":43,"props":768,"children":770},{"className":769},[],[771],{"type":40,"value":684},{"type":40,"value":773}," parameter.",{"type":35,"tag":52,"props":775,"children":777},{"id":776},"move-specification-language",[778],{"type":40,"value":779},"Move Specification Language",{"type":35,"tag":36,"props":781,"children":782},{},[783,785,791],{"type":40,"value":784},"Move specifications use ",{"type":35,"tag":43,"props":786,"children":788},{"className":787},[],[789],{"type":40,"value":790},"spec",{"type":40,"value":792}," blocks to express formal properties that are checked\nby the Move Prover.",{"type":35,"tag":479,"props":794,"children":796},{"id":795},"function-spec-clauses",[797],{"type":40,"value":798},"Function spec clauses",{"type":35,"tag":36,"props":800,"children":801},{},[802,804,810,812,818,820,826,828,834],{"type":40,"value":803},"These appear in ",{"type":35,"tag":43,"props":805,"children":807},{"className":806},[],[808],{"type":40,"value":809},"spec fun_name { ... }",{"type":40,"value":811}," blocks. Spec blocks always appear after the function\ndefinition. If ",{"type":35,"tag":43,"props":813,"children":815},{"className":814},[],[816],{"type":40,"value":817},"fun_name",{"type":40,"value":819}," clashes with a soft keyword (e.g. ",{"type":35,"tag":43,"props":821,"children":823},{"className":822},[],[824],{"type":40,"value":825},"lemma",{"type":40,"value":827},"), use ",{"type":35,"tag":43,"props":829,"children":831},{"className":830},[],[832],{"type":40,"value":833},"spec @fun_name { ... }",{"type":40,"value":835},"\nto escape it.",{"type":35,"tag":189,"props":837,"children":838},{},[839,865,928,959],{"type":35,"tag":193,"props":840,"children":841},{},[842,848,850,855,857,863],{"type":35,"tag":43,"props":843,"children":845},{"className":844},[],[846],{"type":40,"value":847},"ensures \u003Cexpr>",{"type":40,"value":849},": Postcondition that must hold when the function returns normally.\nEvaluated in the ",{"type":35,"tag":62,"props":851,"children":852},{},[853],{"type":40,"value":854},"post-state",{"type":40,"value":856},". Use ",{"type":35,"tag":43,"props":858,"children":860},{"className":859},[],[861],{"type":40,"value":862},"old(expr)",{"type":40,"value":864}," to refer to pre-state values.",{"type":35,"tag":193,"props":866,"children":867},{},[868,874,876,881,883,889,891,896,898,904,906,911,913,919,921,927],{"type":35,"tag":43,"props":869,"children":871},{"className":870},[],[872],{"type":40,"value":873},"aborts_if \u003Cexpr>",{"type":40,"value":875},": Condition under which the function may abort. ",{"type":35,"tag":62,"props":877,"children":878},{},[879],{"type":40,"value":880},"Evaluated in the\npre-state",{"type":40,"value":882}," — do not use ",{"type":35,"tag":43,"props":884,"children":886},{"className":885},[],[887],{"type":40,"value":888},"old()",{"type":40,"value":890}," (see ",{"type":35,"tag":43,"props":892,"children":894},{"className":893},[],[895],{"type":40,"value":888},{"type":40,"value":897}," usage rules below). If any\n",{"type":35,"tag":43,"props":899,"children":901},{"className":900},[],[902],{"type":40,"value":903},"aborts_if",{"type":40,"value":905}," conditions are present, the function must abort if and only if one of the\nconditions holds. Omitting all ",{"type":35,"tag":43,"props":907,"children":909},{"className":908},[],[910],{"type":40,"value":903},{"type":40,"value":912}," clauses means abort behavior is ",{"type":35,"tag":914,"props":915,"children":916},"em",{},[917],{"type":40,"value":918},"unspecified",{"type":40,"value":920},"\n(any abort is allowed). To express that a function never aborts, write ",{"type":35,"tag":43,"props":922,"children":924},{"className":923},[],[925],{"type":40,"value":926},"aborts_if false;",{"type":40,"value":702},{"type":35,"tag":193,"props":929,"children":930},{},[931,937,939,944,946,951,952,957],{"type":35,"tag":43,"props":932,"children":934},{"className":933},[],[935],{"type":40,"value":936},"requires \u003Cexpr>",{"type":40,"value":938},": Precondition that callers must satisfy. ",{"type":35,"tag":62,"props":940,"children":941},{},[942],{"type":40,"value":943},"Evaluated in the pre-state",{"type":40,"value":945}," —\nDo not use ",{"type":35,"tag":43,"props":947,"children":949},{"className":948},[],[950],{"type":40,"value":888},{"type":40,"value":890},{"type":35,"tag":43,"props":953,"children":955},{"className":954},[],[956],{"type":40,"value":888},{"type":40,"value":958}," usage rules below).",{"type":35,"tag":193,"props":960,"children":961},{},[962,968],{"type":35,"tag":43,"props":963,"children":965},{"className":964},[],[966],{"type":40,"value":967},"modifies \u003Cresource>",{"type":40,"value":969},": Declares which global resources the function may modify.",{"type":35,"tag":479,"props":971,"children":973},{"id":972},"loop-invariants",[974],{"type":40,"value":975},"Loop invariants",{"type":35,"tag":36,"props":977,"children":978},{},[979,981,986],{"type":40,"value":980},"Loop invariants appear in a ",{"type":35,"tag":43,"props":982,"children":984},{"className":983},[],[985],{"type":40,"value":790},{"type":40,"value":987}," block after the loop body:",{"type":35,"tag":989,"props":990,"children":995},"pre",{"className":991,"code":992,"language":993,"meta":994,"style":994},"language-move shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","while (cond) {\n    \u002F\u002F body\n} spec {\n    invariant \u003Cexpr>;\n};\n","move","",[996],{"type":35,"tag":43,"props":997,"children":998},{"__ignoreMap":994},[999,1010,1019,1028,1037],{"type":35,"tag":1000,"props":1001,"children":1004},"span",{"class":1002,"line":1003},"line",1,[1005],{"type":35,"tag":1000,"props":1006,"children":1007},{},[1008],{"type":40,"value":1009},"while (cond) {\n",{"type":35,"tag":1000,"props":1011,"children":1013},{"class":1002,"line":1012},2,[1014],{"type":35,"tag":1000,"props":1015,"children":1016},{},[1017],{"type":40,"value":1018},"    \u002F\u002F body\n",{"type":35,"tag":1000,"props":1020,"children":1022},{"class":1002,"line":1021},3,[1023],{"type":35,"tag":1000,"props":1024,"children":1025},{},[1026],{"type":40,"value":1027},"} spec {\n",{"type":35,"tag":1000,"props":1029,"children":1031},{"class":1002,"line":1030},4,[1032],{"type":35,"tag":1000,"props":1033,"children":1034},{},[1035],{"type":40,"value":1036},"    invariant \u003Cexpr>;\n",{"type":35,"tag":1000,"props":1038,"children":1040},{"class":1002,"line":1039},5,[1041],{"type":35,"tag":1000,"props":1042,"children":1043},{},[1044],{"type":40,"value":1045},"};\n",{"type":35,"tag":189,"props":1047,"children":1048},{},[1049],{"type":35,"tag":193,"props":1050,"children":1051},{},[1052,1058,1060,1066,1068,1073],{"type":35,"tag":43,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":40,"value":1057},"invariant \u003Cexpr>",{"type":40,"value":1059},": A property that holds before the first iteration and is preserved by\neach iteration. ",{"type":35,"tag":43,"props":1061,"children":1063},{"className":1062},[],[1064],{"type":40,"value":1065},"old(x)",{"type":40,"value":1067}," is only allowed on function parameters (see ",{"type":35,"tag":43,"props":1069,"children":1071},{"className":1070},[],[1072],{"type":40,"value":888},{"type":40,"value":1074}," usage rules below.)",{"type":35,"tag":36,"props":1076,"children":1077},{},[1078,1080,1085,1087,1093],{"type":40,"value":1079},"Loops without invariants cause the prover to ",{"type":35,"tag":914,"props":1081,"children":1082},{},[1083],{"type":40,"value":1084},"havoc",{"type":40,"value":1086}," all loop-modified variables, which can\nproduce vacuous, incorrect, or overly weak specifications. Every loop needs an invariant —\nexamine the actual ",{"type":35,"tag":43,"props":1088,"children":1090},{"className":1089},[],[1091],{"type":40,"value":1092},"while",{"type":40,"value":1094}," loops in function bodies to find all loops that lack one.",{"type":35,"tag":36,"props":1096,"children":1097},{},[1098],{"type":40,"value":1099},"A good invariant:",{"type":35,"tag":1101,"props":1102,"children":1103},"ol",{},[1104,1109,1114],{"type":35,"tag":193,"props":1105,"children":1106},{},[1107],{"type":40,"value":1108},"Holds before the first iteration (initial values satisfy it).",{"type":35,"tag":193,"props":1110,"children":1111},{},[1112],{"type":40,"value":1113},"Is preserved by each iteration (inductive step).",{"type":35,"tag":193,"props":1115,"children":1116},{},[1117,1119,1125,1127,1133],{"type":40,"value":1118},"Relates loop-modified variables to function parameters and constants\n(e.g., bounds like ",{"type":35,"tag":43,"props":1120,"children":1122},{"className":1121},[],[1123],{"type":40,"value":1124},"i \u003C= n",{"type":40,"value":1126},", accumulators like ",{"type":35,"tag":43,"props":1128,"children":1130},{"className":1129},[],[1131],{"type":40,"value":1132},"sum == i * step",{"type":40,"value":1134},").",{"type":35,"tag":479,"props":1136,"children":1138},{"id":1137},"expressions-in-specs",[1139],{"type":40,"value":1140},"Expressions in specs",{"type":35,"tag":189,"props":1142,"children":1143},{},[1144,1169,1187,1213,1237,1284],{"type":35,"tag":193,"props":1145,"children":1146},{},[1147,1152,1154,1160,1162,1167],{"type":35,"tag":43,"props":1148,"children":1150},{"className":1149},[],[1151],{"type":40,"value":862},{"type":40,"value":1153},": Value of ",{"type":35,"tag":43,"props":1155,"children":1157},{"className":1156},[],[1158],{"type":40,"value":1159},"expr",{"type":40,"value":1161}," at function entry. See ",{"type":35,"tag":43,"props":1163,"children":1165},{"className":1164},[],[1166],{"type":40,"value":888},{"type":40,"value":1168}," usage rules below for\nwhere this is allowed.",{"type":35,"tag":193,"props":1170,"children":1171},{},[1172,1178,1180,1186],{"type":35,"tag":43,"props":1173,"children":1175},{"className":1174},[],[1176],{"type":40,"value":1177},"result",{"type":40,"value":1179},": Return value. Only valid in ",{"type":35,"tag":43,"props":1181,"children":1183},{"className":1182},[],[1184],{"type":40,"value":1185},"ensures",{"type":40,"value":702},{"type":35,"tag":193,"props":1188,"children":1189},{},[1190,1196,1198,1204,1206,1212],{"type":35,"tag":43,"props":1191,"children":1193},{"className":1192},[],[1194],{"type":40,"value":1195},"global\u003CT>(addr)",{"type":40,"value":1197},": Global resource of type ",{"type":35,"tag":43,"props":1199,"children":1201},{"className":1200},[],[1202],{"type":40,"value":1203},"T",{"type":40,"value":1205}," at address ",{"type":35,"tag":43,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":40,"value":1211},"addr",{"type":40,"value":702},{"type":35,"tag":193,"props":1214,"children":1215},{},[1216,1222,1224,1229,1231,1236],{"type":35,"tag":43,"props":1217,"children":1219},{"className":1218},[],[1220],{"type":40,"value":1221},"exists\u003CT>(addr)",{"type":40,"value":1223},": True if a resource of type ",{"type":35,"tag":43,"props":1225,"children":1227},{"className":1226},[],[1228],{"type":40,"value":1203},{"type":40,"value":1230}," exists at address ",{"type":35,"tag":43,"props":1232,"children":1234},{"className":1233},[],[1235],{"type":40,"value":1211},{"type":40,"value":702},{"type":35,"tag":193,"props":1238,"children":1239},{},[1240,1242,1248,1249,1255,1256,1262,1263,1269,1270,1276,1277,1283],{"type":40,"value":1241},"Numeric type bounds: ",{"type":35,"tag":43,"props":1243,"children":1245},{"className":1244},[],[1246],{"type":40,"value":1247},"MAX_U8",{"type":40,"value":220},{"type":35,"tag":43,"props":1250,"children":1252},{"className":1251},[],[1253],{"type":40,"value":1254},"MAX_U16",{"type":40,"value":220},{"type":35,"tag":43,"props":1257,"children":1259},{"className":1258},[],[1260],{"type":40,"value":1261},"MAX_U32",{"type":40,"value":220},{"type":35,"tag":43,"props":1264,"children":1266},{"className":1265},[],[1267],{"type":40,"value":1268},"MAX_U64",{"type":40,"value":220},{"type":35,"tag":43,"props":1271,"children":1273},{"className":1272},[],[1274],{"type":40,"value":1275},"MAX_U128",{"type":40,"value":220},{"type":35,"tag":43,"props":1278,"children":1280},{"className":1279},[],[1281],{"type":40,"value":1282},"MAX_U256",{"type":40,"value":702},{"type":35,"tag":193,"props":1285,"children":1286},{},[1287,1292,1294,1300,1302,1308,1310,1316,1318,1324,1326,1332],{"type":35,"tag":62,"props":1288,"children":1289},{},[1290],{"type":40,"value":1291},"No dereference or borrow",{"type":40,"value":1293},": ",{"type":35,"tag":43,"props":1295,"children":1297},{"className":1296},[],[1298],{"type":40,"value":1299},"*e",{"type":40,"value":1301}," and ",{"type":35,"tag":43,"props":1303,"children":1305},{"className":1304},[],[1306],{"type":40,"value":1307},"&e",{"type":40,"value":1309}," are not allowed in spec\nexpressions. Spec expressions operate on values, not references — access\nfields directly (e.g. ",{"type":35,"tag":43,"props":1311,"children":1313},{"className":1312},[],[1314],{"type":40,"value":1315},"v.field",{"type":40,"value":1317},", not ",{"type":35,"tag":43,"props":1319,"children":1321},{"className":1320},[],[1322],{"type":40,"value":1323},"(*v).field",{"type":40,"value":1325}," or ",{"type":35,"tag":43,"props":1327,"children":1329},{"className":1328},[],[1330],{"type":40,"value":1331},"(&v).field",{"type":40,"value":1134},{"type":35,"tag":479,"props":1334,"children":1336},{"id":1335},"old-usage-rules",[1337,1342],{"type":35,"tag":43,"props":1338,"children":1340},{"className":1339},[],[1341],{"type":40,"value":888},{"type":40,"value":1343}," usage rules",{"type":35,"tag":36,"props":1345,"children":1346},{},[1347,1352,1354,1359],{"type":35,"tag":43,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":40,"value":862},{"type":40,"value":1353}," means \"value of ",{"type":35,"tag":43,"props":1355,"children":1357},{"className":1356},[],[1358],{"type":40,"value":1159},{"type":40,"value":1360}," at function entry.\" It is only valid in specific contexts:",{"type":35,"tag":36,"props":1362,"children":1363},{},[1364],{"type":35,"tag":62,"props":1365,"children":1366},{},[1367],{"type":40,"value":1368},"Wrong \u002F Right examples:",{"type":35,"tag":989,"props":1370,"children":1372},{"className":991,"code":1371,"language":993,"meta":994,"style":994},"\u002F\u002F WRONG: old() in aborts_if — compilation error\naborts_if old(x) + old(y) > MAX_U64;\n\u002F\u002F RIGHT: aborts_if is pre-state, just use the variables directly\naborts_if x + y > MAX_U64;\n\n\u002F\u002F WRONG: old() in requires — compilation error\nrequires old(len(v)) > 0;\n\u002F\u002F RIGHT: requires is pre-state\nrequires len(v) > 0;\n\n\u002F\u002F WRONG: old(local) in loop invariant — compilation error\ninvariant old(sum) \u003C= old(n) * MAX_U64;\n\u002F\u002F RIGHT: sum is a local — use it directly; n is a parameter — old(n) is ok\ninvariant sum \u003C= old(n) * MAX_U64;\n\n\u002F\u002F WRONG: old(resource) in loop invariant — compilation error\ninvariant old(global\u003CT>(addr)).field == 0;\n\u002F\u002F RIGHT: use resource directly\ninvariant global\u003CT>(addr).field == 0;\n",[1373],{"type":35,"tag":43,"props":1374,"children":1375},{"__ignoreMap":994},[1376,1384,1392,1400,1408,1417,1426,1435,1444,1453,1461,1470,1479,1488,1497,1505,1514,1523,1532],{"type":35,"tag":1000,"props":1377,"children":1378},{"class":1002,"line":1003},[1379],{"type":35,"tag":1000,"props":1380,"children":1381},{},[1382],{"type":40,"value":1383},"\u002F\u002F WRONG: old() in aborts_if — compilation error\n",{"type":35,"tag":1000,"props":1385,"children":1386},{"class":1002,"line":1012},[1387],{"type":35,"tag":1000,"props":1388,"children":1389},{},[1390],{"type":40,"value":1391},"aborts_if old(x) + old(y) > MAX_U64;\n",{"type":35,"tag":1000,"props":1393,"children":1394},{"class":1002,"line":1021},[1395],{"type":35,"tag":1000,"props":1396,"children":1397},{},[1398],{"type":40,"value":1399},"\u002F\u002F RIGHT: aborts_if is pre-state, just use the variables directly\n",{"type":35,"tag":1000,"props":1401,"children":1402},{"class":1002,"line":1030},[1403],{"type":35,"tag":1000,"props":1404,"children":1405},{},[1406],{"type":40,"value":1407},"aborts_if x + y > MAX_U64;\n",{"type":35,"tag":1000,"props":1409,"children":1410},{"class":1002,"line":1039},[1411],{"type":35,"tag":1000,"props":1412,"children":1414},{"emptyLinePlaceholder":1413},true,[1415],{"type":40,"value":1416},"\n",{"type":35,"tag":1000,"props":1418,"children":1420},{"class":1002,"line":1419},6,[1421],{"type":35,"tag":1000,"props":1422,"children":1423},{},[1424],{"type":40,"value":1425},"\u002F\u002F WRONG: old() in requires — compilation error\n",{"type":35,"tag":1000,"props":1427,"children":1429},{"class":1002,"line":1428},7,[1430],{"type":35,"tag":1000,"props":1431,"children":1432},{},[1433],{"type":40,"value":1434},"requires old(len(v)) > 0;\n",{"type":35,"tag":1000,"props":1436,"children":1438},{"class":1002,"line":1437},8,[1439],{"type":35,"tag":1000,"props":1440,"children":1441},{},[1442],{"type":40,"value":1443},"\u002F\u002F RIGHT: requires is pre-state\n",{"type":35,"tag":1000,"props":1445,"children":1447},{"class":1002,"line":1446},9,[1448],{"type":35,"tag":1000,"props":1449,"children":1450},{},[1451],{"type":40,"value":1452},"requires len(v) > 0;\n",{"type":35,"tag":1000,"props":1454,"children":1456},{"class":1002,"line":1455},10,[1457],{"type":35,"tag":1000,"props":1458,"children":1459},{"emptyLinePlaceholder":1413},[1460],{"type":40,"value":1416},{"type":35,"tag":1000,"props":1462,"children":1464},{"class":1002,"line":1463},11,[1465],{"type":35,"tag":1000,"props":1466,"children":1467},{},[1468],{"type":40,"value":1469},"\u002F\u002F WRONG: old(local) in loop invariant — compilation error\n",{"type":35,"tag":1000,"props":1471,"children":1473},{"class":1002,"line":1472},12,[1474],{"type":35,"tag":1000,"props":1475,"children":1476},{},[1477],{"type":40,"value":1478},"invariant old(sum) \u003C= old(n) * MAX_U64;\n",{"type":35,"tag":1000,"props":1480,"children":1482},{"class":1002,"line":1481},13,[1483],{"type":35,"tag":1000,"props":1484,"children":1485},{},[1486],{"type":40,"value":1487},"\u002F\u002F RIGHT: sum is a local — use it directly; n is a parameter — old(n) is ok\n",{"type":35,"tag":1000,"props":1489,"children":1491},{"class":1002,"line":1490},14,[1492],{"type":35,"tag":1000,"props":1493,"children":1494},{},[1495],{"type":40,"value":1496},"invariant sum \u003C= old(n) * MAX_U64;\n",{"type":35,"tag":1000,"props":1498,"children":1500},{"class":1002,"line":1499},15,[1501],{"type":35,"tag":1000,"props":1502,"children":1503},{"emptyLinePlaceholder":1413},[1504],{"type":40,"value":1416},{"type":35,"tag":1000,"props":1506,"children":1508},{"class":1002,"line":1507},16,[1509],{"type":35,"tag":1000,"props":1510,"children":1511},{},[1512],{"type":40,"value":1513},"\u002F\u002F WRONG: old(resource) in loop invariant — compilation error\n",{"type":35,"tag":1000,"props":1515,"children":1517},{"class":1002,"line":1516},17,[1518],{"type":35,"tag":1000,"props":1519,"children":1520},{},[1521],{"type":40,"value":1522},"invariant old(global\u003CT>(addr)).field == 0;\n",{"type":35,"tag":1000,"props":1524,"children":1526},{"class":1002,"line":1525},18,[1527],{"type":35,"tag":1000,"props":1528,"children":1529},{},[1530],{"type":40,"value":1531},"\u002F\u002F RIGHT: use resource directly\n",{"type":35,"tag":1000,"props":1533,"children":1535},{"class":1002,"line":1534},19,[1536],{"type":35,"tag":1000,"props":1537,"children":1538},{},[1539],{"type":40,"value":1540},"invariant global\u003CT>(addr).field == 0;\n",{"type":35,"tag":479,"props":1542,"children":1544},{"id":1543},"referring-to-behavior-of-other-functions",[1545],{"type":40,"value":1546},"Referring to Behavior of other Functions",{"type":35,"tag":36,"props":1548,"children":1549},{},[1550,1552,1557,1559,1564],{"type":40,"value":1551},"When specifying a function that calls other functions ",{"type":35,"tag":62,"props":1553,"children":1554},{},[1555],{"type":40,"value":1556},"which are not inline functions",{"type":40,"value":1558},", you\ncan use ",{"type":35,"tag":62,"props":1560,"children":1561},{},[1562],{"type":40,"value":1563},"behavioral predicates",{"type":40,"value":1565}," to abstract the callee's specification without inlining its\ndetails. These built-in predicates lift a function's spec clauses into expressions:",{"type":35,"tag":189,"props":1567,"children":1568},{},[1569,1603,1631,1675],{"type":35,"tag":193,"props":1570,"children":1571},{},[1572,1578,1580,1586,1588,1594,1596,1602],{"type":35,"tag":43,"props":1573,"children":1575},{"className":1574},[],[1576],{"type":40,"value":1577},"requires_of\u003Cf>(args)",{"type":40,"value":1579}," — true when ",{"type":35,"tag":43,"props":1581,"children":1583},{"className":1582},[],[1584],{"type":40,"value":1585},"f",{"type":40,"value":1587},"'s ",{"type":35,"tag":43,"props":1589,"children":1591},{"className":1590},[],[1592],{"type":40,"value":1593},"requires",{"type":40,"value":1595}," clauses hold for ",{"type":35,"tag":43,"props":1597,"children":1599},{"className":1598},[],[1600],{"type":40,"value":1601},"args",{"type":40,"value":702},{"type":35,"tag":193,"props":1604,"children":1605},{},[1606,1612,1613,1618,1619,1624,1625,1630],{"type":35,"tag":43,"props":1607,"children":1609},{"className":1608},[],[1610],{"type":40,"value":1611},"aborts_of\u003Cf>(args)",{"type":40,"value":1579},{"type":35,"tag":43,"props":1614,"children":1616},{"className":1615},[],[1617],{"type":40,"value":1585},{"type":40,"value":1587},{"type":35,"tag":43,"props":1620,"children":1622},{"className":1621},[],[1623],{"type":40,"value":903},{"type":40,"value":1595},{"type":35,"tag":43,"props":1626,"children":1628},{"className":1627},[],[1629],{"type":40,"value":1601},{"type":40,"value":702},{"type":35,"tag":193,"props":1632,"children":1633},{},[1634,1640,1641,1646,1647,1652,1654,1659,1661,1666,1668,1674],{"type":35,"tag":43,"props":1635,"children":1637},{"className":1636},[],[1638],{"type":40,"value":1639},"ensures_of\u003Cf>(args, result)",{"type":40,"value":1579},{"type":35,"tag":43,"props":1642,"children":1644},{"className":1643},[],[1645],{"type":40,"value":1585},{"type":40,"value":1587},{"type":35,"tag":43,"props":1648,"children":1650},{"className":1649},[],[1651],{"type":40,"value":1185},{"type":40,"value":1653}," clauses hold for\n",{"type":35,"tag":43,"props":1655,"children":1657},{"className":1656},[],[1658],{"type":40,"value":1601},{"type":40,"value":1660}," and the given ",{"type":35,"tag":43,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":40,"value":1177},{"type":40,"value":1667}," value(s). For functions returning unit, omit\nthe result argument. For multiple return values, pass ",{"type":35,"tag":43,"props":1669,"children":1671},{"className":1670},[],[1672],{"type":40,"value":1673},"result_1, result_2, ...",{"type":40,"value":702},{"type":35,"tag":193,"props":1676,"children":1677},{},[1678,1684,1686,1691,1693,1698,1700,1706],{"type":35,"tag":43,"props":1679,"children":1681},{"className":1680},[],[1682],{"type":40,"value":1683},"result_of\u003Cf>(args)",{"type":40,"value":1685}," — the return value of ",{"type":35,"tag":43,"props":1687,"children":1689},{"className":1688},[],[1690],{"type":40,"value":1585},{"type":40,"value":1692}," when called with ",{"type":35,"tag":43,"props":1694,"children":1696},{"className":1695},[],[1697],{"type":40,"value":1601},{"type":40,"value":1699},",\nusable in ",{"type":35,"tag":43,"props":1701,"children":1703},{"className":1702},[],[1704],{"type":40,"value":1705},"let",{"type":40,"value":1707}," bindings and expressions inside spec blocks.",{"type":35,"tag":36,"props":1709,"children":1710},{},[1711,1713,1719],{"type":40,"value":1712},"The ",{"type":35,"tag":43,"props":1714,"children":1716},{"className":1715},[],[1717],{"type":40,"value":1718},"\u003Cf>",{"type":40,"value":1720}," target can be:",{"type":35,"tag":189,"props":1722,"children":1723},{},[1724,1758,1784],{"type":35,"tag":193,"props":1725,"children":1726},{},[1727,1729,1734,1736,1742,1744,1749,1751,1757],{"type":40,"value":1728},"A ",{"type":35,"tag":62,"props":1730,"children":1731},{},[1732],{"type":40,"value":1733},"function parameter",{"type":40,"value":1735}," of function type: ",{"type":35,"tag":43,"props":1737,"children":1739},{"className":1738},[],[1740],{"type":40,"value":1741},"ensures_of\u003Cf>(x, result)",{"type":40,"value":1743}," where\n",{"type":35,"tag":43,"props":1745,"children":1747},{"className":1746},[],[1748],{"type":40,"value":1585},{"type":40,"value":1750}," is a parameter with type ",{"type":35,"tag":43,"props":1752,"children":1754},{"className":1753},[],[1755],{"type":40,"value":1756},"|u64| u64",{"type":40,"value":702},{"type":35,"tag":193,"props":1759,"children":1760},{},[1761,1762,1767,1769,1775,1777,1783],{"type":40,"value":1728},{"type":35,"tag":62,"props":1763,"children":1764},{},[1765],{"type":40,"value":1766},"named function",{"type":40,"value":1768}," (same module or cross-module): ",{"type":35,"tag":43,"props":1770,"children":1772},{"className":1771},[],[1773],{"type":40,"value":1774},"ensures_of\u003Cincrement>(x, result)",{"type":40,"value":1776},"\nor ",{"type":35,"tag":43,"props":1778,"children":1780},{"className":1779},[],[1781],{"type":40,"value":1782},"ensures_of\u003CM::increment>(x, result)",{"type":40,"value":702},{"type":35,"tag":193,"props":1785,"children":1786},{},[1787,1788,1793,1795,1801,1802,1808],{"type":40,"value":1728},{"type":35,"tag":62,"props":1789,"children":1790},{},[1791],{"type":40,"value":1792},"generic function",{"type":40,"value":1794}," with explicit or inferred type arguments:\n",{"type":35,"tag":43,"props":1796,"children":1798},{"className":1797},[],[1799],{"type":40,"value":1800},"ensures_of\u003Cidentity\u003Cu64>>(x, result)",{"type":40,"value":1325},{"type":35,"tag":43,"props":1803,"children":1805},{"className":1804},[],[1806],{"type":40,"value":1807},"ensures_of\u003Cidentity>(x, result)",{"type":40,"value":702},{"type":35,"tag":36,"props":1810,"children":1811},{},[1812],{"type":35,"tag":62,"props":1813,"children":1814},{},[1815],{"type":40,"value":1816},"Examples:",{"type":35,"tag":36,"props":1818,"children":1819},{},[1820],{"type":40,"value":1821},"Specifying a higher-order function that applies a callback:",{"type":35,"tag":989,"props":1823,"children":1825},{"className":991,"code":1824,"language":993,"meta":994,"style":994},"fun apply(f: |u64| u64, x: u64): u64 { f(x) }\nspec apply {\n    aborts_if aborts_of\u003Cf>(x);\n    ensures ensures_of\u003Cf>(x, result);\n}\n",[1826],{"type":35,"tag":43,"props":1827,"children":1828},{"__ignoreMap":994},[1829,1837,1845,1853,1861],{"type":35,"tag":1000,"props":1830,"children":1831},{"class":1002,"line":1003},[1832],{"type":35,"tag":1000,"props":1833,"children":1834},{},[1835],{"type":40,"value":1836},"fun apply(f: |u64| u64, x: u64): u64 { f(x) }\n",{"type":35,"tag":1000,"props":1838,"children":1839},{"class":1002,"line":1012},[1840],{"type":35,"tag":1000,"props":1841,"children":1842},{},[1843],{"type":40,"value":1844},"spec apply {\n",{"type":35,"tag":1000,"props":1846,"children":1847},{"class":1002,"line":1021},[1848],{"type":35,"tag":1000,"props":1849,"children":1850},{},[1851],{"type":40,"value":1852},"    aborts_if aborts_of\u003Cf>(x);\n",{"type":35,"tag":1000,"props":1854,"children":1855},{"class":1002,"line":1030},[1856],{"type":35,"tag":1000,"props":1857,"children":1858},{},[1859],{"type":40,"value":1860},"    ensures ensures_of\u003Cf>(x, result);\n",{"type":35,"tag":1000,"props":1862,"children":1863},{"class":1002,"line":1039},[1864],{"type":35,"tag":1000,"props":1865,"children":1866},{},[1867],{"type":40,"value":1868},"}\n",{"type":35,"tag":36,"props":1870,"children":1871},{},[1872,1874,1880,1882,1888],{"type":40,"value":1873},"Using ",{"type":35,"tag":43,"props":1875,"children":1877},{"className":1876},[],[1878],{"type":40,"value":1879},"result_of",{"type":40,"value":1881}," to chain calls in a spec (e.g. ",{"type":35,"tag":43,"props":1883,"children":1885},{"className":1884},[],[1886],{"type":40,"value":1887},"f(f(x))",{"type":40,"value":1889},"):",{"type":35,"tag":989,"props":1891,"children":1893},{"className":991,"code":1892,"language":993,"meta":994,"style":994},"fun apply_seq(f: |u64| u64 has copy, x: u64): u64 { f(f(x)) }\nspec apply_seq {\n    let y = result_of\u003Cf>(x);\n    requires requires_of\u003Cf>(x) && requires_of\u003Cf>(y);\n    aborts_if aborts_of\u003Cf>(x) || aborts_of\u003Cf>(y);\n    ensures result == result_of\u003Cf>(y);\n}\n",[1894],{"type":35,"tag":43,"props":1895,"children":1896},{"__ignoreMap":994},[1897,1905,1913,1921,1929,1937,1945],{"type":35,"tag":1000,"props":1898,"children":1899},{"class":1002,"line":1003},[1900],{"type":35,"tag":1000,"props":1901,"children":1902},{},[1903],{"type":40,"value":1904},"fun apply_seq(f: |u64| u64 has copy, x: u64): u64 { f(f(x)) }\n",{"type":35,"tag":1000,"props":1906,"children":1907},{"class":1002,"line":1012},[1908],{"type":35,"tag":1000,"props":1909,"children":1910},{},[1911],{"type":40,"value":1912},"spec apply_seq {\n",{"type":35,"tag":1000,"props":1914,"children":1915},{"class":1002,"line":1021},[1916],{"type":35,"tag":1000,"props":1917,"children":1918},{},[1919],{"type":40,"value":1920},"    let y = result_of\u003Cf>(x);\n",{"type":35,"tag":1000,"props":1922,"children":1923},{"class":1002,"line":1030},[1924],{"type":35,"tag":1000,"props":1925,"children":1926},{},[1927],{"type":40,"value":1928},"    requires requires_of\u003Cf>(x) && requires_of\u003Cf>(y);\n",{"type":35,"tag":1000,"props":1930,"children":1931},{"class":1002,"line":1039},[1932],{"type":35,"tag":1000,"props":1933,"children":1934},{},[1935],{"type":40,"value":1936},"    aborts_if aborts_of\u003Cf>(x) || aborts_of\u003Cf>(y);\n",{"type":35,"tag":1000,"props":1938,"children":1939},{"class":1002,"line":1419},[1940],{"type":35,"tag":1000,"props":1941,"children":1942},{},[1943],{"type":40,"value":1944},"    ensures result == result_of\u003Cf>(y);\n",{"type":35,"tag":1000,"props":1946,"children":1947},{"class":1002,"line":1428},[1948],{"type":35,"tag":1000,"props":1949,"children":1950},{},[1951],{"type":40,"value":1868},{"type":35,"tag":36,"props":1953,"children":1954},{},[1955],{"type":40,"value":1956},"Referring to a named function's behavior from a caller:",{"type":35,"tag":989,"props":1958,"children":1960},{"className":991,"code":1959,"language":993,"meta":994,"style":994},"spec bar {\n    ensures ensures_of\u003Cincrement>(x, result);\n}\n",[1961],{"type":35,"tag":43,"props":1962,"children":1963},{"__ignoreMap":994},[1964,1972,1980],{"type":35,"tag":1000,"props":1965,"children":1966},{"class":1002,"line":1003},[1967],{"type":35,"tag":1000,"props":1968,"children":1969},{},[1970],{"type":40,"value":1971},"spec bar {\n",{"type":35,"tag":1000,"props":1973,"children":1974},{"class":1002,"line":1012},[1975],{"type":35,"tag":1000,"props":1976,"children":1977},{},[1978],{"type":40,"value":1979},"    ensures ensures_of\u003Cincrement>(x, result);\n",{"type":35,"tag":1000,"props":1981,"children":1982},{"class":1002,"line":1021},[1983],{"type":35,"tag":1000,"props":1984,"children":1985},{},[1986],{"type":40,"value":1868},{"type":35,"tag":36,"props":1988,"children":1989},{},[1990,1991,1996],{"type":40,"value":1873},{"type":35,"tag":43,"props":1992,"children":1994},{"className":1993},[],[1995],{"type":40,"value":1879},{"type":40,"value":1997}," inside loop invariants with closures:",{"type":35,"tag":989,"props":1999,"children":2001},{"className":991,"code":2000,"language":993,"meta":994,"style":994},"spec {\n    invariant forall j in 0..i: !result_of\u003Cpred>(v[j]);\n};\n",[2002],{"type":35,"tag":43,"props":2003,"children":2004},{"__ignoreMap":994},[2005,2013,2021],{"type":35,"tag":1000,"props":2006,"children":2007},{"class":1002,"line":1003},[2008],{"type":35,"tag":1000,"props":2009,"children":2010},{},[2011],{"type":40,"value":2012},"spec {\n",{"type":35,"tag":1000,"props":2014,"children":2015},{"class":1002,"line":1012},[2016],{"type":35,"tag":1000,"props":2017,"children":2018},{},[2019],{"type":40,"value":2020},"    invariant forall j in 0..i: !result_of\u003Cpred>(v[j]);\n",{"type":35,"tag":1000,"props":2022,"children":2023},{"class":1002,"line":1021},[2024],{"type":35,"tag":1000,"props":2025,"children":2026},{},[2027],{"type":40,"value":1045},{"type":35,"tag":479,"props":2029,"children":2031},{"id":2030},"property-markers",[2032],{"type":40,"value":2033},"Property markers",{"type":35,"tag":36,"props":2035,"children":2036},{},[2037,2038,2044],{"type":40,"value":1712},{"type":35,"tag":43,"props":2039,"children":2041},{"className":2040},[],[2042],{"type":40,"value":2043},"[inferred]",{"type":40,"value":2045}," property marks conditions that were not written by the user. Its value indicates\nthe origin or quality:",{"type":35,"tag":189,"props":2047,"children":2048},{},[2049,2059,2070],{"type":35,"tag":193,"props":2050,"children":2051},{},[2052,2057],{"type":35,"tag":43,"props":2053,"children":2055},{"className":2054},[],[2056],{"type":40,"value":2043},{"type":40,"value":2058},": Automatically inferred by weakest-precondition (WP) analysis. It may be overly complex, redundant,\nor occasionally incorrect.",{"type":35,"tag":193,"props":2060,"children":2061},{},[2062,2068],{"type":35,"tag":43,"props":2063,"children":2065},{"className":2064},[],[2066],{"type":40,"value":2067},"[inferred = vacuous]",{"type":40,"value":2069},": Inferred by WP but detected as potentially vacuous (trivially true)\ndue to unconstrained quantifier variables. Typically results from missing loop invariants.",{"type":35,"tag":193,"props":2071,"children":2072},{},[2073,2079],{"type":35,"tag":43,"props":2074,"children":2076},{"className":2075},[],[2077],{"type":40,"value":2078},"[inferred = sathard]",{"type":40,"value":2080},": Inferred by WP but contains quantifier patterns that are hard for\nSMT solvers. Likely to cause verification timeouts — should be simplified or reformulated.",{"type":35,"tag":479,"props":2082,"children":2084},{"id":2083},"links-1",[2085],{"type":40,"value":484},{"type":35,"tag":189,"props":2087,"children":2088},{},[2089],{"type":35,"tag":193,"props":2090,"children":2091},{},[2092],{"type":35,"tag":492,"props":2093,"children":2096},{"href":2094,"rel":2095},"https:\u002F\u002Faptos.dev\u002Fen\u002Fbuild\u002Fsmart-contracts\u002Fprover\u002Fspec-lang",[496],[2097],{"type":40,"value":779},{"type":35,"tag":52,"props":2099,"children":2101},{"id":2100},"writing-and-editing-specs",[2102],{"type":40,"value":2103},"Writing and Editing Specs",{"type":35,"tag":36,"props":2105,"children":2106},{},[2107],{"type":40,"value":2108},"When writing or editing specifications:",{"type":35,"tag":1101,"props":2110,"children":2111},{},[2112,2124,2129,2141,2153,2166],{"type":35,"tag":193,"props":2113,"children":2114},{},[2115,2117,2122],{"type":40,"value":2116},"Use ",{"type":35,"tag":43,"props":2118,"children":2120},{"className":2119},[],[2121],{"type":40,"value":577},{"type":40,"value":2123}," to discover source files.",{"type":35,"tag":193,"props":2125,"children":2126},{},[2127],{"type":40,"value":2128},"Read the function body to understand its behavior and abort conditions.",{"type":35,"tag":193,"props":2130,"children":2131},{},[2132,2134,2139],{"type":40,"value":2133},"Write ",{"type":35,"tag":43,"props":2135,"children":2137},{"className":2136},[],[2138],{"type":40,"value":809},{"type":40,"value":2140}," blocks after each function, following the Move Specification\nLanguage rules above.",{"type":35,"tag":193,"props":2142,"children":2143},{},[2144,2145,2151],{"type":40,"value":2133},{"type":35,"tag":43,"props":2146,"children":2148},{"className":2147},[],[2149],{"type":40,"value":2150},"spec lemma lemma_name ...",{"type":40,"value":2152}," block after the function for which they are introduced.",{"type":35,"tag":193,"props":2154,"children":2155},{},[2156,2158,2164],{"type":40,"value":2157},"Spec functions are put into a ",{"type":35,"tag":43,"props":2159,"children":2161},{"className":2160},[],[2162],{"type":40,"value":2163},"spec fun",{"type":40,"value":2165}," declarations.",{"type":35,"tag":193,"props":2167,"children":2168},{},[2169,2171,2177],{"type":40,"value":2170},"If the project already uses ",{"type":35,"tag":43,"props":2172,"children":2174},{"className":2173},[],[2175],{"type":40,"value":2176},".spec.move",{"type":40,"value":2178}," files, put new specs into that file instead of the\nmain Move file.",{"type":35,"tag":36,"props":2180,"children":2181},{},[2182,2192,2194,2199,2201,2207,2209,2214,2216,2222,2224,2230,2232,2238,2240,2246],{"type":35,"tag":62,"props":2183,"children":2184},{},[2185,2190],{"type":35,"tag":43,"props":2186,"children":2188},{"className":2187},[],[2189],{"type":40,"value":2176},{"type":40,"value":2191}," files:",{"type":40,"value":2193}," A ",{"type":35,"tag":43,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":40,"value":2176},{"type":40,"value":2200}," file is compiled as part of the same module\nas the corresponding source file. Use ",{"type":35,"tag":43,"props":2202,"children":2204},{"className":2203},[],[2205],{"type":40,"value":2206},"spec module { }",{"type":40,"value":2208}," (the keyword ",{"type":35,"tag":43,"props":2210,"children":2212},{"className":2211},[],[2213],{"type":40,"value":428},{"type":40,"value":2215},",\nnot a module name) to declare module-level spec items (helper functions, lemmas).\nUse ",{"type":35,"tag":43,"props":2217,"children":2219},{"className":2218},[],[2220],{"type":40,"value":2221},"spec fun_name { }",{"type":40,"value":2223}," to add conditions to functions defined in the main source.\nThere is no ",{"type":35,"tag":43,"props":2225,"children":2227},{"className":2226},[],[2228],{"type":40,"value":2229},"spec \u003Cmodule_name> { }",{"type":40,"value":2231}," syntax — ",{"type":35,"tag":43,"props":2233,"children":2235},{"className":2234},[],[2236],{"type":40,"value":2237},"spec name { }",{"type":40,"value":2239}," always targets a\nfunction named ",{"type":35,"tag":43,"props":2241,"children":2243},{"className":2242},[],[2244],{"type":40,"value":2245},"name",{"type":40,"value":702},{"type":35,"tag":479,"props":2248,"children":2250},{"id":2249},"simplifying-specifications",[2251],{"type":40,"value":2252},"Simplifying Specifications",{"type":35,"tag":36,"props":2254,"children":2255},{},[2256],{"type":40,"value":2257},"Work through the following in order when cleaning up inferred or hand-written specs.",{"type":35,"tag":36,"props":2259,"children":2260},{},[2261,2266,2268,2273,2275,2281],{"type":35,"tag":62,"props":2262,"children":2263},{},[2264],{"type":40,"value":2265},"Remove vacuous conditions.",{"type":40,"value":2267}," Delete every condition marked ",{"type":35,"tag":43,"props":2269,"children":2271},{"className":2270},[],[2272],{"type":40,"value":2067},{"type":40,"value":2274},".\nThese arise from havoced loop variables without sufficient invariants and are\nsemantically meaningless (e.g.\n",{"type":35,"tag":43,"props":2276,"children":2278},{"className":2277},[],[2279],{"type":40,"value":2280},"ensures [inferred = vacuous] forall x: u64: result == x",{"type":40,"value":1134},{"type":35,"tag":36,"props":2283,"children":2284},{},[2285,2290,2292,2298,2299,2305,2306,2312,2314,2319,2321,2326],{"type":35,"tag":62,"props":2286,"children":2287},{},[2288],{"type":40,"value":2289},"Eliminate quantifiers.",{"type":40,"value":2291}," Conditions with quantifiers over unbounded types\n(",{"type":35,"tag":43,"props":2293,"children":2295},{"className":2294},[],[2296],{"type":40,"value":2297},"forall x: u64",{"type":40,"value":220},{"type":35,"tag":43,"props":2300,"children":2302},{"className":2301},[],[2303],{"type":40,"value":2304},"exists x: u64",{"type":40,"value":220},{"type":35,"tag":43,"props":2307,"children":2309},{"className":2308},[],[2310],{"type":40,"value":2311},"forall x: address",{"type":40,"value":2313},") cause SMT solver timeouts.\nThey are often marked ",{"type":35,"tag":43,"props":2315,"children":2317},{"className":2316},[],[2318],{"type":40,"value":2078},{"type":40,"value":2320}," but not always. Replace each with an\nequivalent ",{"type":35,"tag":62,"props":2322,"children":2323},{},[2324],{"type":40,"value":2325},"non-quantified",{"type":40,"value":2327}," expression:",{"type":35,"tag":189,"props":2329,"children":2330},{},[2331,2342],{"type":35,"tag":193,"props":2332,"children":2333},{},[2334,2340],{"type":35,"tag":43,"props":2335,"children":2337},{"className":2336},[],[2338],{"type":40,"value":2339},"exists x: u64: x \u003C n && f(x)",{"type":40,"value":2341}," — replace with a concrete bound or closed-form\nexpression derived from the loop logic.",{"type":35,"tag":193,"props":2343,"children":2344},{},[2345,2351,2353,2359],{"type":35,"tag":43,"props":2346,"children":2348},{"className":2347},[],[2349],{"type":40,"value":2350},"forall x: address: x != a ==> g(x)",{"type":40,"value":2352}," — this expresses a frame condition (\"nothing\nelse changed\"). Replace with an explicit ",{"type":35,"tag":43,"props":2354,"children":2356},{"className":2355},[],[2357],{"type":40,"value":2358},"modifies",{"type":40,"value":2360}," clause or enumerate the affected\naddresses.",{"type":35,"tag":36,"props":2362,"children":2363},{},[2364,2369,2371,2377],{"type":35,"tag":62,"props":2365,"children":2366},{},[2367],{"type":40,"value":2368},"Ensure quantifiers have triggers.",{"type":40,"value":2370}," Quantifiers without triggers must be avoided. Move\nsupports lists of triggers as in ",{"type":35,"tag":43,"props":2372,"children":2374},{"className":2373},[],[2375],{"type":40,"value":2376},"Q x: T, y: R {p1, .., pn}..{q1, .., qn}: e",{"type":40,"value":2378},", where each outer\nlist is an alternative where all inner patterns must match. Notice that only triggers over\nuninterpreted functions are allowed, not over builtin operators.",{"type":35,"tag":36,"props":2380,"children":2381},{},[2382,2395,2397,2403],{"type":35,"tag":62,"props":2383,"children":2384},{},[2385,2387,2393],{"type":40,"value":2386},"Simplify ",{"type":35,"tag":43,"props":2388,"children":2390},{"className":2389},[],[2391],{"type":40,"value":2392},"update_field",{"type":40,"value":2394}," expressions.",{"type":40,"value":2396}," The WP engine uses\n",{"type":35,"tag":43,"props":2398,"children":2400},{"className":2399},[],[2401],{"type":40,"value":2402},"update_field(s, field, val)",{"type":40,"value":2404}," for struct mutations. Rewrite to direct struct\nconstruction when all fields are determined, e.g.:",{"type":35,"tag":189,"props":2406,"children":2407},{},[2408,2434],{"type":35,"tag":193,"props":2409,"children":2410},{},[2411,2417,2419,2425,2427,2433],{"type":35,"tag":43,"props":2412,"children":2414},{"className":2413},[],[2415],{"type":40,"value":2416},"update_field(old(global\u003CT>(addr)), value, v)",{"type":40,"value":2418}," becomes\n",{"type":35,"tag":43,"props":2420,"children":2422},{"className":2421},[],[2423],{"type":40,"value":2424},"T { value: v, ..old(global\u003CT>(addr)) }",{"type":40,"value":2426},", or when the struct has a single field,\nsimply ",{"type":35,"tag":43,"props":2428,"children":2430},{"className":2429},[],[2431],{"type":40,"value":2432},"T { value: v }",{"type":40,"value":702},{"type":35,"tag":193,"props":2435,"children":2436},{},[2437,2439,2445,2446,2452],{"type":40,"value":2438},"Nested ",{"type":35,"tag":43,"props":2440,"children":2442},{"className":2441},[],[2443],{"type":40,"value":2444},"update_field(update_field(old(p), x, a), y, b)",{"type":40,"value":2418},{"type":35,"tag":43,"props":2447,"children":2449},{"className":2448},[],[2450],{"type":40,"value":2451},"Point { x: a, y: b }",{"type":40,"value":2453}," when all fields are covered.",{"type":35,"tag":36,"props":2455,"children":2456},{},[2457,2462,2464,2470,2472,2478,2479,2485,2487,2493,2495,2500],{"type":35,"tag":62,"props":2458,"children":2459},{},[2460],{"type":40,"value":2461},"Consolidate unrolled specs.",{"type":40,"value":2463}," When ",{"type":35,"tag":43,"props":2465,"children":2467},{"className":2466},[],[2468],{"type":40,"value":2469},"pragma unroll",{"type":40,"value":2471}," is used, the WP produces one\ncondition per unrolling step (e.g. ",{"type":35,"tag":43,"props":2473,"children":2475},{"className":2474},[],[2476],{"type":40,"value":2477},"n == 0 ==> ...",{"type":40,"value":220},{"type":35,"tag":43,"props":2480,"children":2482},{"className":2481},[],[2483],{"type":40,"value":2484},"n == 1 ==> ...",{"type":40,"value":2486},", ...,\n",{"type":35,"tag":43,"props":2488,"children":2490},{"className":2489},[],[2491],{"type":40,"value":2492},"k \u003C n ==> ...",{"type":40,"value":2494},"). If there is a closed-form generalization, replace the case list\nwith a single condition. Remove the ",{"type":35,"tag":43,"props":2496,"children":2498},{"className":2497},[],[2499],{"type":40,"value":2469},{"type":40,"value":2501}," once the closed-form is in place.",{"type":35,"tag":36,"props":2503,"children":2504},{},[2505],{"type":35,"tag":62,"props":2506,"children":2507},{},[2508],{"type":40,"value":2509},"General cleanup:",{"type":35,"tag":189,"props":2511,"children":2512},{},[2513,2552,2564,2636,2673],{"type":35,"tag":193,"props":2514,"children":2515},{},[2516,2518,2523,2525,2530,2532,2537,2538,2543,2545,2550],{"type":40,"value":2517},"Fix ",{"type":35,"tag":43,"props":2519,"children":2521},{"className":2520},[],[2522],{"type":40,"value":888},{"type":40,"value":2524}," usage: ",{"type":35,"tag":43,"props":2526,"children":2528},{"className":2527},[],[2529],{"type":40,"value":888},{"type":40,"value":2531}," in ",{"type":35,"tag":43,"props":2533,"children":2535},{"className":2534},[],[2536],{"type":40,"value":903},{"type":40,"value":1325},{"type":35,"tag":43,"props":2539,"children":2541},{"className":2540},[],[2542],{"type":40,"value":1593},{"type":40,"value":2544}," is invalid — those\nclauses are already evaluated in the pre-state. Remove ",{"type":35,"tag":43,"props":2546,"children":2548},{"className":2547},[],[2549],{"type":40,"value":888},{"type":40,"value":2551}," wrappers.",{"type":35,"tag":193,"props":2553,"children":2554},{},[2555,2557,2562],{"type":40,"value":2556},"Remove redundant conditions implied by others or by language guarantees (e.g. an\n",{"type":35,"tag":43,"props":2558,"children":2560},{"className":2559},[],[2561],{"type":40,"value":903},{"type":40,"value":2563}," subsumed by a stronger one).",{"type":35,"tag":193,"props":2565,"children":2566},{},[2567,2569],{"type":40,"value":2568},"Simplify arithmetic. The WP engine mirrors the computation steps, producing\nexpressions that can be algebraically reduced:\n",{"type":35,"tag":189,"props":2570,"children":2571},{},[2572,2592,2612,2631],{"type":35,"tag":193,"props":2573,"children":2574},{},[2575,2577,2583,2585,2591],{"type":40,"value":2576},"Combine terms: ",{"type":35,"tag":43,"props":2578,"children":2580},{"className":2579},[],[2581],{"type":40,"value":2582},"(n - 1) * n \u002F 2 + n",{"type":40,"value":2584}," simplifies to ",{"type":35,"tag":43,"props":2586,"children":2588},{"className":2587},[],[2589],{"type":40,"value":2590},"n * (n + 1) \u002F 2",{"type":40,"value":702},{"type":35,"tag":193,"props":2593,"children":2594},{},[2595,2597,2603,2605,2611],{"type":40,"value":2596},"Flatten nested offsets: ",{"type":35,"tag":43,"props":2598,"children":2600},{"className":2599},[],[2601],{"type":40,"value":2602},"old(v) + 1 + 1",{"type":40,"value":2604}," becomes ",{"type":35,"tag":43,"props":2606,"children":2608},{"className":2607},[],[2609],{"type":40,"value":2610},"old(v) + 2",{"type":40,"value":702},{"type":35,"tag":193,"props":2613,"children":2614},{},[2615,2617,2623,2624,2630],{"type":40,"value":2616},"Simplify overflow bounds: ",{"type":35,"tag":43,"props":2618,"children":2620},{"className":2619},[],[2621],{"type":40,"value":2622},"v + (n - 1) > MAX_U64 - 1",{"type":40,"value":2604},{"type":35,"tag":43,"props":2625,"children":2627},{"className":2626},[],[2628],{"type":40,"value":2629},"v + n > MAX_U64",{"type":40,"value":702},{"type":35,"tag":193,"props":2632,"children":2633},{},[2634],{"type":40,"value":2635},"Specs use mathematical (unbounded) integers, so unlike Move code there is no\nrisk of underflow in spec expressions — reorder freely for clarity.",{"type":35,"tag":193,"props":2637,"children":2638},{},[2639,2651,2653,2658,2659,2664,2666,2671],{"type":35,"tag":62,"props":2640,"children":2641},{},[2642,2644,2649],{"type":40,"value":2643},"Keep ",{"type":35,"tag":43,"props":2645,"children":2647},{"className":2646},[],[2648],{"type":40,"value":2043},{"type":40,"value":2650}," markers",{"type":40,"value":2652}," on all inferred conditions — they distinguish\ninferred specs from user-written ones and are needed for WP re-runs.\nRemove ",{"type":35,"tag":43,"props":2654,"children":2656},{"className":2655},[],[2657],{"type":40,"value":2067},{"type":40,"value":1301},{"type":35,"tag":43,"props":2660,"children":2662},{"className":2661},[],[2663],{"type":40,"value":2078},{"type":40,"value":2665}," conditions entirely\n(as described above), but keep plain ",{"type":35,"tag":43,"props":2667,"children":2669},{"className":2668},[],[2670],{"type":40,"value":2043},{"type":40,"value":2672}," on conditions you retain.",{"type":35,"tag":193,"props":2674,"children":2675},{},[2676,2686,2688,2694,2696,2701],{"type":35,"tag":62,"props":2677,"children":2678},{},[2679,2680],{"type":40,"value":2643},{"type":35,"tag":43,"props":2681,"children":2683},{"className":2682},[],[2684],{"type":40,"value":2685},"pragma opaque = true;",{"type":40,"value":2687}," — never remove it. It is essential for\nverification performance, not an inference artifact. If a function with\n",{"type":35,"tag":43,"props":2689,"children":2691},{"className":2690},[],[2692],{"type":40,"value":2693},"pragma opaque",{"type":40,"value":2695}," fails verification, add ",{"type":35,"tag":43,"props":2697,"children":2699},{"className":2698},[],[2700],{"type":40,"value":133},{"type":40,"value":2702}," rather\nthan removing the opaque pragma.",{"type":35,"tag":479,"props":2704,"children":2706},{"id":2705},"additional-rules-for-editing-specs",[2707],{"type":40,"value":2708},"Additional Rules for Editing Specs",{"type":35,"tag":1101,"props":2710,"children":2711},{},[2712,2729,2739,2783,2813,2823],{"type":35,"tag":193,"props":2713,"children":2714},{},[2715,2720,2722,2727],{"type":35,"tag":62,"props":2716,"children":2717},{},[2718],{"type":40,"value":2719},"Do not change function bodies.",{"type":40,"value":2721}," Only modify ",{"type":35,"tag":43,"props":2723,"children":2725},{"className":2724},[],[2726],{"type":40,"value":790},{"type":40,"value":2728}," blocks and their contents.",{"type":35,"tag":193,"props":2730,"children":2731},{},[2732,2737],{"type":35,"tag":62,"props":2733,"children":2734},{},[2735],{"type":40,"value":2736},"Preserve",{"type":40,"value":2738}," any user-written (non-inferred) specifications exactly as they are.",{"type":35,"tag":193,"props":2740,"children":2741},{},[2742,2754,2756,2761,2763,2768,2769,2774,2776,2781],{"type":35,"tag":62,"props":2743,"children":2744},{},[2745,2747,2752],{"type":40,"value":2746},"Never drop ",{"type":35,"tag":43,"props":2748,"children":2750},{"className":2749},[],[2751],{"type":40,"value":903},{"type":40,"value":2753}," conditions.",{"type":40,"value":2755}," Every function that can abort must have\n",{"type":35,"tag":43,"props":2757,"children":2759},{"className":2758},[],[2760],{"type":40,"value":903},{"type":40,"value":2762}," conditions. The WP tool infers both ",{"type":35,"tag":43,"props":2764,"children":2766},{"className":2765},[],[2767],{"type":40,"value":1185},{"type":40,"value":1301},{"type":35,"tag":43,"props":2770,"children":2772},{"className":2771},[],[2773],{"type":40,"value":903},{"type":40,"value":2775}," —\nsimplify them but never remove them just because they are complex or hard to\nverify. If an ",{"type":35,"tag":43,"props":2777,"children":2779},{"className":2778},[],[2780],{"type":40,"value":903},{"type":40,"value":2782}," needs rewriting, replace it with a semantically\nequivalent expression, do not delete it.",{"type":35,"tag":193,"props":2784,"children":2785},{},[2786,2797,2799,2804,2806,2811],{"type":35,"tag":62,"props":2787,"children":2788},{},[2789,2791,2796],{"type":40,"value":2790},"Never remove ",{"type":35,"tag":43,"props":2792,"children":2794},{"className":2793},[],[2795],{"type":40,"value":2693},{"type":40,"value":702},{"type":40,"value":2798}," The WP tool marks inferred specs as opaque\nso the prover uses the spec contract instead of inlining the function body.\nRemoving it causes verification to re-analyze the implementation, leading to\ntimeouts. Preserve ",{"type":35,"tag":43,"props":2800,"children":2802},{"className":2801},[],[2803],{"type":40,"value":2685},{"type":40,"value":2805}," in every spec block that has it.\nIf verification fails on an opaque function (e.g., the prover cannot reason\nabout closure side effects), add ",{"type":35,"tag":43,"props":2807,"children":2809},{"className":2808},[],[2810],{"type":40,"value":133},{"type":40,"value":2812}," to disable\nverification while keeping the spec contract intact for callers.",{"type":35,"tag":193,"props":2814,"children":2815},{},[2816,2821],{"type":35,"tag":62,"props":2817,"children":2818},{},[2819],{"type":40,"value":2820},"Never duplicate conditions.",{"type":40,"value":2822}," Before adding any condition to a spec block,\ncheck whether an equivalent condition already exists. Do not create a condition\nthat is semantically identical to one already present in the same spec block.",{"type":35,"tag":193,"props":2824,"children":2825},{},[2826,2831,2833,2839],{"type":35,"tag":62,"props":2827,"children":2828},{},[2829],{"type":40,"value":2830},"No empty spec blocks.",{"type":40,"value":2832}," Never create or leave behind an empty\n",{"type":35,"tag":43,"props":2834,"children":2836},{"className":2835},[],[2837],{"type":40,"value":2838},"spec fun_name {}",{"type":40,"value":2840}," block. If removing inferred conditions would leave a spec\nblock with no conditions or pragmas, delete the entire block instead.",{"type":35,"tag":52,"props":2842,"children":2844},{"id":2843},"proofs-and-lemmas",[2845],{"type":40,"value":2846},"Proofs and Lemmas",{"type":35,"tag":479,"props":2848,"children":2850},{"id":2849},"example",[2851],{"type":40,"value":2852},"Example",{"type":35,"tag":989,"props":2854,"children":2856},{"className":991,"code":2855,"language":993,"meta":994,"style":994},"spec fun sum(n: u64): u64 {\n    if (n == 0) { 0 } else { n + sum(n - 1) }\n}\n\nspec lemma monotonicity(x: num, y: num) {\n    requires x \u003C= y;\n    ensures sum(x) \u003C= sum(y);\n} proof {\n    if (x \u003C y) {\n        assert sum(y - 1) \u003C= sum(y);\n        apply monotonicity(x, y - 1);\n    }\n}\n\n\nfun sum_up_to(n: u64): u64 { \u002F* iterative impl *\u002F }\nspec sum_up_to {\n    requires n \u003C= 5;\n    ensures result == sum(n);\n} proof {\n   forall x,y {sum(x), sum(y)} apply monotonicity(x, y);\n}\n",[2857],{"type":35,"tag":43,"props":2858,"children":2859},{"__ignoreMap":994},[2860,2868,2876,2883,2890,2898,2906,2914,2922,2930,2938,2946,2954,2961,2968,2975,2983,2991,2999,3007,3015,3024],{"type":35,"tag":1000,"props":2861,"children":2862},{"class":1002,"line":1003},[2863],{"type":35,"tag":1000,"props":2864,"children":2865},{},[2866],{"type":40,"value":2867},"spec fun sum(n: u64): u64 {\n",{"type":35,"tag":1000,"props":2869,"children":2870},{"class":1002,"line":1012},[2871],{"type":35,"tag":1000,"props":2872,"children":2873},{},[2874],{"type":40,"value":2875},"    if (n == 0) { 0 } else { n + sum(n - 1) }\n",{"type":35,"tag":1000,"props":2877,"children":2878},{"class":1002,"line":1021},[2879],{"type":35,"tag":1000,"props":2880,"children":2881},{},[2882],{"type":40,"value":1868},{"type":35,"tag":1000,"props":2884,"children":2885},{"class":1002,"line":1030},[2886],{"type":35,"tag":1000,"props":2887,"children":2888},{"emptyLinePlaceholder":1413},[2889],{"type":40,"value":1416},{"type":35,"tag":1000,"props":2891,"children":2892},{"class":1002,"line":1039},[2893],{"type":35,"tag":1000,"props":2894,"children":2895},{},[2896],{"type":40,"value":2897},"spec lemma monotonicity(x: num, y: num) {\n",{"type":35,"tag":1000,"props":2899,"children":2900},{"class":1002,"line":1419},[2901],{"type":35,"tag":1000,"props":2902,"children":2903},{},[2904],{"type":40,"value":2905},"    requires x \u003C= y;\n",{"type":35,"tag":1000,"props":2907,"children":2908},{"class":1002,"line":1428},[2909],{"type":35,"tag":1000,"props":2910,"children":2911},{},[2912],{"type":40,"value":2913},"    ensures sum(x) \u003C= sum(y);\n",{"type":35,"tag":1000,"props":2915,"children":2916},{"class":1002,"line":1437},[2917],{"type":35,"tag":1000,"props":2918,"children":2919},{},[2920],{"type":40,"value":2921},"} proof {\n",{"type":35,"tag":1000,"props":2923,"children":2924},{"class":1002,"line":1446},[2925],{"type":35,"tag":1000,"props":2926,"children":2927},{},[2928],{"type":40,"value":2929},"    if (x \u003C y) {\n",{"type":35,"tag":1000,"props":2931,"children":2932},{"class":1002,"line":1455},[2933],{"type":35,"tag":1000,"props":2934,"children":2935},{},[2936],{"type":40,"value":2937},"        assert sum(y - 1) \u003C= sum(y);\n",{"type":35,"tag":1000,"props":2939,"children":2940},{"class":1002,"line":1463},[2941],{"type":35,"tag":1000,"props":2942,"children":2943},{},[2944],{"type":40,"value":2945},"        apply monotonicity(x, y - 1);\n",{"type":35,"tag":1000,"props":2947,"children":2948},{"class":1002,"line":1472},[2949],{"type":35,"tag":1000,"props":2950,"children":2951},{},[2952],{"type":40,"value":2953},"    }\n",{"type":35,"tag":1000,"props":2955,"children":2956},{"class":1002,"line":1481},[2957],{"type":35,"tag":1000,"props":2958,"children":2959},{},[2960],{"type":40,"value":1868},{"type":35,"tag":1000,"props":2962,"children":2963},{"class":1002,"line":1490},[2964],{"type":35,"tag":1000,"props":2965,"children":2966},{"emptyLinePlaceholder":1413},[2967],{"type":40,"value":1416},{"type":35,"tag":1000,"props":2969,"children":2970},{"class":1002,"line":1499},[2971],{"type":35,"tag":1000,"props":2972,"children":2973},{"emptyLinePlaceholder":1413},[2974],{"type":40,"value":1416},{"type":35,"tag":1000,"props":2976,"children":2977},{"class":1002,"line":1507},[2978],{"type":35,"tag":1000,"props":2979,"children":2980},{},[2981],{"type":40,"value":2982},"fun sum_up_to(n: u64): u64 { \u002F* iterative impl *\u002F }\n",{"type":35,"tag":1000,"props":2984,"children":2985},{"class":1002,"line":1516},[2986],{"type":35,"tag":1000,"props":2987,"children":2988},{},[2989],{"type":40,"value":2990},"spec sum_up_to {\n",{"type":35,"tag":1000,"props":2992,"children":2993},{"class":1002,"line":1525},[2994],{"type":35,"tag":1000,"props":2995,"children":2996},{},[2997],{"type":40,"value":2998},"    requires n \u003C= 5;\n",{"type":35,"tag":1000,"props":3000,"children":3001},{"class":1002,"line":1534},[3002],{"type":35,"tag":1000,"props":3003,"children":3004},{},[3005],{"type":40,"value":3006},"    ensures result == sum(n);\n",{"type":35,"tag":1000,"props":3008,"children":3010},{"class":1002,"line":3009},20,[3011],{"type":35,"tag":1000,"props":3012,"children":3013},{},[3014],{"type":40,"value":2921},{"type":35,"tag":1000,"props":3016,"children":3018},{"class":1002,"line":3017},21,[3019],{"type":35,"tag":1000,"props":3020,"children":3021},{},[3022],{"type":40,"value":3023},"   forall x,y {sum(x), sum(y)} apply monotonicity(x, y);\n",{"type":35,"tag":1000,"props":3025,"children":3027},{"class":1002,"line":3026},22,[3028],{"type":35,"tag":1000,"props":3029,"children":3030},{},[3031],{"type":40,"value":1868},{"type":35,"tag":479,"props":3033,"children":3035},{"id":3034},"proofs",[3036],{"type":40,"value":3037},"Proofs",{"type":35,"tag":36,"props":3039,"children":3040},{},[3041],{"type":40,"value":3042},"A proof consists of a sequence of\nproof statements together with if-then-else and let bindings.",{"type":35,"tag":36,"props":3044,"children":3045},{},[3046,3048,3054,3055,3061,3063,3069,3070,3076,3077,3083,3084,3090,3091,3097],{"type":40,"value":3047},"Proof statements: ",{"type":35,"tag":43,"props":3049,"children":3051},{"className":3050},[],[3052],{"type":40,"value":3053},"let name = Expr",{"type":40,"value":220},{"type":35,"tag":43,"props":3056,"children":3058},{"className":3057},[],[3059],{"type":40,"value":3060},"if (Expr) Proof else Proof",{"type":40,"value":3062},",\n",{"type":35,"tag":43,"props":3064,"children":3066},{"className":3065},[],[3067],{"type":40,"value":3068},"assert Expr",{"type":40,"value":220},{"type":35,"tag":43,"props":3071,"children":3073},{"className":3072},[],[3074],{"type":40,"value":3075},"assume Expr",{"type":40,"value":220},{"type":35,"tag":43,"props":3078,"children":3080},{"className":3079},[],[3081],{"type":40,"value":3082},"apply LemmaInstance",{"type":40,"value":3062},{"type":35,"tag":43,"props":3085,"children":3087},{"className":3086},[],[3088],{"type":40,"value":3089},"forall QuantifierDecls [Patterns] apply LemmaInstance",{"type":40,"value":3062},{"type":35,"tag":43,"props":3092,"children":3094},{"className":3093},[],[3095],{"type":40,"value":3096},"calc (Expr { RelOp Expr })",{"type":40,"value":702},{"type":35,"tag":36,"props":3099,"children":3100},{},[3101],{"type":40,"value":3102},"A proof block can be attached to any specification block as postfix to that block, for example:",{"type":35,"tag":989,"props":3104,"children":3108},{"className":3105,"code":3107,"language":40},[3106],"language-text","spec sum_to_n {\n  ensures result == sum(n);\n} proof {\n  forall x: u64, y: u64 apply Monotonicity(x, y);\n}  \n",[3109],{"type":35,"tag":43,"props":3110,"children":3111},{"__ignoreMap":994},[3112],{"type":40,"value":3107},{"type":35,"tag":36,"props":3114,"children":3115},{},[3116],{"type":40,"value":3117},"A proof is translated by mapping it to a sequence of assumes\u002Fasserts at the\nverification entry points of a function.",{"type":35,"tag":189,"props":3119,"children":3120},{},[3121,3126],{"type":35,"tag":193,"props":3122,"children":3123},{},[3124],{"type":40,"value":3125},"The split statement is translated by creating different verification variants for each value split\nwith according assumptions of the value at the split point and otherwise identical content.",{"type":35,"tag":193,"props":3127,"children":3128},{},[3129],{"type":40,"value":3130},"The apply statement is translated by injecting pre\u002Fpost conditions of the (expected to be proven) lemma.\nThis is very similar like calling an opaque function in Move code.",{"type":35,"tag":479,"props":3132,"children":3134},{"id":3133},"lemmas",[3135],{"type":40,"value":3136},"Lemmas",{"type":35,"tag":36,"props":3138,"children":3139},{},[3140],{"type":40,"value":3141},"A Lemma is a member of a specification block, similar like a spec function. Its\nuser syntax is:",{"type":35,"tag":989,"props":3143,"children":3146},{"className":3144,"code":3145,"language":40},[3106],"spec fun sum(n: u64): u64 {\n    if (n == 0) { 0 } else { n + sum(n - 1) }\n}\nspec lemma sum_monotonicity(x: num, y: num) {\n    requires x \u003C= y;\n    ensures sum(x) \u003C= sum(y);\n} proof {\n    if (x \u003C y) {\n        assert sum(y - 1) \u003C= sum(y);\n        apply sum_monotonicity(x, y - 1);\n    }\n}\n",[3147],{"type":35,"tag":43,"props":3148,"children":3149},{"__ignoreMap":994},[3150],{"type":40,"value":3145},{"type":35,"tag":36,"props":3152,"children":3153},{},[3154,3156,3161,3163,3168],{"type":40,"value":3155},"Or inside a ",{"type":35,"tag":43,"props":3157,"children":3159},{"className":3158},[],[3160],{"type":40,"value":2206},{"type":40,"value":3162}," block (the keyword ",{"type":35,"tag":43,"props":3164,"children":3166},{"className":3165},[],[3167],{"type":40,"value":428},{"type":40,"value":3169},", not a module name):",{"type":35,"tag":989,"props":3171,"children":3174},{"className":3172,"code":3173,"language":40},[3106],"spec module {\n  fun sum ...\n  lemma sum_monotonicity ...\n}\n",[3175],{"type":35,"tag":43,"props":3176,"children":3177},{"__ignoreMap":994},[3178],{"type":40,"value":3173},{"type":35,"tag":36,"props":3180,"children":3181},{},[3182,3187,3189,3194,3196,3200,3202,3207,3209,3214,3216,3221,3223,3228,3230,3235],{"type":35,"tag":62,"props":3183,"children":3184},{},[3185],{"type":40,"value":3186},"Important:",{"type":40,"value":3188}," ",{"type":35,"tag":43,"props":3190,"children":3192},{"className":3191},[],[3193],{"type":40,"value":2237},{"type":40,"value":3195}," always targets a ",{"type":35,"tag":914,"props":3197,"children":3198},{},[3199],{"type":40,"value":684},{"type":40,"value":3201}," named ",{"type":35,"tag":43,"props":3203,"children":3205},{"className":3204},[],[3206],{"type":40,"value":2245},{"type":40,"value":3208},".\nThere is no ",{"type":35,"tag":43,"props":3210,"children":3212},{"className":3211},[],[3213],{"type":40,"value":2229},{"type":40,"value":3215}," syntax. Module-level items (helper\nfunctions, lemmas) go inside ",{"type":35,"tag":43,"props":3217,"children":3219},{"className":3218},[],[3220],{"type":40,"value":2206},{"type":40,"value":3222},". Lemmas are ",{"type":35,"tag":62,"props":3224,"children":3225},{},[3226],{"type":40,"value":3227},"not valid",{"type":40,"value":3229},"\ninside function spec blocks (",{"type":35,"tag":43,"props":3231,"children":3233},{"className":3232},[],[3234],{"type":40,"value":2221},{"type":40,"value":1134},{"type":35,"tag":36,"props":3237,"children":3238},{},[3239,3240,3246,3248,3254,3256,3261],{"type":40,"value":1712},{"type":35,"tag":43,"props":3241,"children":3243},{"className":3242},[],[3244],{"type":40,"value":3245},"spec lemma",{"type":40,"value":3247}," shortcut is sugar for ",{"type":35,"tag":43,"props":3249,"children":3251},{"className":3250},[],[3252],{"type":40,"value":3253},"spec module { lemma ... }",{"type":40,"value":3255},", analogous\nto the ",{"type":35,"tag":43,"props":3257,"children":3259},{"className":3258},[],[3260],{"type":40,"value":2163},{"type":40,"value":3262}," shortcut for helper functions.",{"type":35,"tag":36,"props":3264,"children":3265},{},[3266],{"type":40,"value":3267},"It has a parameter list like a spec function (but no return value) followed by a\nspecification block (with requires, ensures, and pragmas the only allowed conditions).\nAttached to this is an (optional) proof.",{"type":35,"tag":36,"props":3269,"children":3270},{},[3271],{"type":40,"value":3272},"Lemma names are in a separate namespace. They are scoped to modules,\nsimilar like specification functions. They can only be referenced from\nproof 'apply' statements.",{"type":35,"tag":52,"props":3274,"children":3276},{"id":3275},"verification",[3277],{"type":40,"value":3278},"Verification",{"type":35,"tag":479,"props":3280,"children":3282},{"id":3281},"verification-tool",[3283],{"type":40,"value":3284},"Verification Tool",{"type":35,"tag":36,"props":3286,"children":3287},{},[3288,3289,3295],{"type":40,"value":2116},{"type":35,"tag":43,"props":3290,"children":3292},{"className":3291},[],[3293],{"type":40,"value":3294},"move_package_verify",{"type":40,"value":3296}," to run the Move Prover on a package and\nformally verify its specifications:",{"type":35,"tag":189,"props":3298,"children":3299},{},[3300,3319],{"type":35,"tag":193,"props":3301,"children":3302},{},[3303,3305,3310,3312,3317],{"type":40,"value":3304},"Call with ",{"type":35,"tag":43,"props":3306,"children":3308},{"className":3307},[],[3309],{"type":40,"value":549},{"type":40,"value":3311}," set to the package directory and ",{"type":35,"tag":43,"props":3313,"children":3315},{"className":3314},[],[3316],{"type":40,"value":74},{"type":40,"value":3318}," set to\n5.",{"type":35,"tag":193,"props":3320,"children":3321},{},[3322],{"type":40,"value":3323},"The tool returns \"verification succeeded\" when all specs hold, or a diagnostic with a\ncounterexample when a spec fails.",{"type":35,"tag":3325,"props":3326,"children":3328},"h4",{"id":3327},"narrowing-scope-with-filters",[3329],{"type":40,"value":3330},"Narrowing scope with filters",{"type":35,"tag":36,"props":3332,"children":3333},{},[3334,3335,3341],{"type":40,"value":520},{"type":35,"tag":43,"props":3336,"children":3338},{"className":3337},[],[3339],{"type":40,"value":3340},"filter",{"type":40,"value":3342}," parameter to restrict the verification scope:",{"type":35,"tag":189,"props":3344,"children":3345},{},[3346,3369],{"type":35,"tag":193,"props":3347,"children":3348},{},[3349,3354,3356,3361,3363,3368],{"type":35,"tag":62,"props":3350,"children":3351},{},[3352],{"type":40,"value":3353},"Single function:",{"type":40,"value":3355}," set ",{"type":35,"tag":43,"props":3357,"children":3359},{"className":3358},[],[3360],{"type":40,"value":3340},{"type":40,"value":3362}," to ",{"type":35,"tag":43,"props":3364,"children":3366},{"className":3365},[],[3367],{"type":40,"value":700},{"type":40,"value":702},{"type":35,"tag":193,"props":3370,"children":3371},{},[3372,3377,3378,3383,3384,3390],{"type":35,"tag":62,"props":3373,"children":3374},{},[3375],{"type":40,"value":3376},"Single module:",{"type":40,"value":3355},{"type":35,"tag":43,"props":3379,"children":3381},{"className":3380},[],[3382],{"type":40,"value":3340},{"type":40,"value":3362},{"type":35,"tag":43,"props":3385,"children":3387},{"className":3386},[],[3388],{"type":40,"value":3389},"module_name",{"type":40,"value":702},{"type":35,"tag":3325,"props":3392,"children":3394},{"id":3393},"excluding-targets",[3395],{"type":40,"value":3396},"Excluding targets",{"type":35,"tag":36,"props":3398,"children":3399},{},[3400,3401,3406],{"type":40,"value":520},{"type":35,"tag":43,"props":3402,"children":3404},{"className":3403},[],[3405],{"type":40,"value":92},{"type":40,"value":3407}," parameter to skip specific functions or modules while\nverifying the rest of the scope:",{"type":35,"tag":189,"props":3409,"children":3410},{},[3411,3433],{"type":35,"tag":193,"props":3412,"children":3413},{},[3414,3419,3420,3425,3426,3432],{"type":35,"tag":62,"props":3415,"children":3416},{},[3417],{"type":40,"value":3418},"Exclude function(s):",{"type":40,"value":3355},{"type":35,"tag":43,"props":3421,"children":3423},{"className":3422},[],[3424],{"type":40,"value":92},{"type":40,"value":3362},{"type":35,"tag":43,"props":3427,"children":3429},{"className":3428},[],[3430],{"type":40,"value":3431},"[\"module_name::function_name\"]",{"type":40,"value":702},{"type":35,"tag":193,"props":3434,"children":3435},{},[3436,3441,3442,3447,3448,3454],{"type":35,"tag":62,"props":3437,"children":3438},{},[3439],{"type":40,"value":3440},"Exclude module(s):",{"type":40,"value":3355},{"type":35,"tag":43,"props":3443,"children":3445},{"className":3444},[],[3446],{"type":40,"value":92},{"type":40,"value":3362},{"type":35,"tag":43,"props":3449,"children":3451},{"className":3450},[],[3452],{"type":40,"value":3453},"[\"module_name\"]",{"type":40,"value":702},{"type":35,"tag":36,"props":3456,"children":3457},{},[3458,3460,3465,3467,3472,3473,3478],{"type":40,"value":3459},"Exclusions take precedence over the ",{"type":35,"tag":43,"props":3461,"children":3463},{"className":3462},[],[3464],{"type":40,"value":3340},{"type":40,"value":3466}," scope — a target that matches both\n",{"type":35,"tag":43,"props":3468,"children":3470},{"className":3469},[],[3471],{"type":40,"value":3340},{"type":40,"value":1301},{"type":35,"tag":43,"props":3474,"children":3476},{"className":3475},[],[3477],{"type":40,"value":92},{"type":40,"value":3479}," is excluded. This is useful in the \"Fix logical errors\" task to skip timed-out\nfunctions without modifying source files.",{"type":35,"tag":3325,"props":3481,"children":3483},{"id":3482},"setting-timeout",[3484],{"type":40,"value":3485},"Setting timeout",{"type":35,"tag":36,"props":3487,"children":3488},{},[3489],{"type":40,"value":3490},"Verification can be long-running (10 seconds or more). Always explicitly specify a timeout.\nStart with a low timeout of 5 to get quick feedback.\nIncrease the timeout to not more than 10 in the case of\ninvestigating difficult verification problems.",{"type":35,"tag":479,"props":3492,"children":3494},{"id":3493},"diagnosing-verification-failures",[3495],{"type":40,"value":3496},"Diagnosing Verification Failures",{"type":35,"tag":36,"props":3498,"children":3499},{},[3500],{"type":40,"value":3501},"When the prover reports a counterexample or error:",{"type":35,"tag":189,"props":3503,"children":3504},{},[3505,3522,3539,3575,3585],{"type":35,"tag":193,"props":3506,"children":3507},{},[3508,3513,3515,3520],{"type":35,"tag":62,"props":3509,"children":3510},{},[3511],{"type":40,"value":3512},"Postcondition failure",{"type":40,"value":3514},": The ",{"type":35,"tag":43,"props":3516,"children":3518},{"className":3517},[],[3519],{"type":40,"value":1185},{"type":40,"value":3521}," clause doesn't hold for some execution path.\nCheck whether an edge case is missing or the condition is too strong.",{"type":35,"tag":193,"props":3523,"children":3524},{},[3525,3530,3532,3537],{"type":35,"tag":62,"props":3526,"children":3527},{},[3528],{"type":40,"value":3529},"Abort condition failure",{"type":40,"value":3531},": An abort path is not covered by ",{"type":35,"tag":43,"props":3533,"children":3535},{"className":3534},[],[3536],{"type":40,"value":903},{"type":40,"value":3538},". Trace which\noperations can abort (arithmetic overflow, missing resource, vector out-of-bounds) and\nadd the missing condition.",{"type":35,"tag":193,"props":3540,"children":3541},{},[3542,3554,3556,3561,3562,3567,3568,3573],{"type":35,"tag":62,"props":3543,"children":3544},{},[3545,3547,3552],{"type":40,"value":3546},"Wrong ",{"type":35,"tag":43,"props":3548,"children":3550},{"className":3549},[],[3551],{"type":40,"value":888},{"type":40,"value":3553}," usage",{"type":40,"value":3555},": Using ",{"type":35,"tag":43,"props":3557,"children":3559},{"className":3558},[],[3560],{"type":40,"value":888},{"type":40,"value":2531},{"type":35,"tag":43,"props":3563,"children":3565},{"className":3564},[],[3566],{"type":40,"value":903},{"type":40,"value":1325},{"type":35,"tag":43,"props":3569,"children":3571},{"className":3570},[],[3572],{"type":40,"value":1593},{"type":40,"value":3574}," causes a compilation\nerror. Remove it — those clauses are already evaluated in the pre-state.",{"type":35,"tag":193,"props":3576,"children":3577},{},[3578,3583],{"type":35,"tag":62,"props":3579,"children":3580},{},[3581],{"type":40,"value":3582},"Loop-related failures",{"type":40,"value":3584},": Missing or too-weak loop invariants cause havoced variables.\nStrengthen the invariant to constrain all loop-modified variables.",{"type":35,"tag":193,"props":3586,"children":3587},{},[3588,3593,3595,3599,3601,3606,3607,3612,3614,3620,3622,3625,3627,3633,3634,3739,3742,3744,3750,3751,3754,3759,3761,3764,3769,3771,3777,3778,3784,3785,3791,3793,3796,3801,3803,3808],{"type":35,"tag":62,"props":3589,"children":3590},{},[3591],{"type":40,"value":3592},"Timeout (\"out of resources\")",{"type":40,"value":3594},":",{"type":35,"tag":3596,"props":3597,"children":3598},"br",{},[],{"type":40,"value":3600},"Do not delete, comment out, or weaken any ",{"type":35,"tag":43,"props":3602,"children":3604},{"className":3603},[],[3605],{"type":40,"value":903},{"type":40,"value":1325},{"type":35,"tag":43,"props":3608,"children":3610},{"className":3609},[],[3611],{"type":40,"value":1185},{"type":40,"value":3613},"\ncondition to resolve a timeout. This includes adding\n",{"type":35,"tag":43,"props":3615,"children":3617},{"className":3616},[],[3618],{"type":40,"value":3619},"pragma aborts_if_is_partial;",{"type":40,"value":3621},", which silently suppresses uncovered abort\npaths. Every condition is assumed semantically correct; removing one hides\nreal properties and makes the specification unsound.",{"type":35,"tag":3596,"props":3623,"children":3624},{},[],{"type":40,"value":3626},"Timeout resolution strategies — try these in order, and iterate\naggressively before resorting to ",{"type":35,"tag":43,"props":3628,"children":3630},{"className":3629},[],[3631],{"type":40,"value":3632},"pragma verify_duration_estimate",{"type":40,"value":3594},{"type":35,"tag":1101,"props":3635,"children":3636},{},[3637,3647,3664,3674,3722],{"type":35,"tag":193,"props":3638,"children":3639},{},[3640,3645],{"type":35,"tag":62,"props":3641,"children":3642},{},[3643],{"type":40,"value":3644},"Add data invariants and global update invariants",{"type":40,"value":3646}," to constrain\nresource state. These are checked once per modifying function and then\nassumed at every call site (including inside loops), giving the prover\nfacts for free without recursive helpers. See the inference reference\nfor details on when to use each kind.",{"type":35,"tag":193,"props":3648,"children":3649},{},[3650,3655,3657,3662],{"type":35,"tag":62,"props":3651,"children":3652},{},[3653],{"type":40,"value":3654},"Introduce spec helper functions",{"type":40,"value":3656}," that capture intermediate properties.\nFactor complex ",{"type":35,"tag":43,"props":3658,"children":3660},{"className":3659},[],[3661],{"type":40,"value":1185},{"type":40,"value":3663}," into compositions of simpler helpers. Each\nhelper should express one logical step the solver can verify independently.",{"type":35,"tag":193,"props":3665,"children":3666},{},[3667,3672],{"type":35,"tag":62,"props":3668,"children":3669},{},[3670],{"type":40,"value":3671},"Add lemmas",{"type":40,"value":3673}," to establish properties about spec helpers\n(e.g. monotonicity, induction steps) that the solver cannot discover\non its own. Lemmas are proven propositions — do not introduce axioms.",{"type":35,"tag":193,"props":3675,"children":3676},{},[3677,3690,3692,3698,3699,3705,3707,3713,3715,3720],{"type":35,"tag":62,"props":3678,"children":3679},{},[3680,3682,3688],{"type":40,"value":3681},"Add ",{"type":35,"tag":43,"props":3683,"children":3685},{"className":3684},[],[3686],{"type":40,"value":3687},"proof { ... }",{"type":40,"value":3689}," blocks",{"type":40,"value":3691}," to function specs or lemmas to guide\nthe verifier with ",{"type":35,"tag":43,"props":3693,"children":3695},{"className":3694},[],[3696],{"type":40,"value":3697},"assert",{"type":40,"value":220},{"type":35,"tag":43,"props":3700,"children":3702},{"className":3701},[],[3703],{"type":40,"value":3704},"apply",{"type":40,"value":3706},", and ",{"type":35,"tag":43,"props":3708,"children":3710},{"className":3709},[],[3711],{"type":40,"value":3712},"calc",{"type":40,"value":3714}," steps. Use ",{"type":35,"tag":43,"props":3716,"children":3718},{"className":3717},[],[3719],{"type":40,"value":3704},{"type":40,"value":3721},"\nto instantiate lemmas at specific points in the proof.",{"type":35,"tag":193,"props":3723,"children":3724},{},[3725,3730,3732,3737],{"type":35,"tag":62,"props":3726,"children":3727},{},[3728],{"type":40,"value":3729},"Rewrite spec expressions",{"type":40,"value":3731}," while preserving their meaning — factor\nout common sub-expressions into ",{"type":35,"tag":43,"props":3733,"children":3735},{"className":3734},[],[3736],{"type":40,"value":1705},{"type":40,"value":3738}," bindings, reorder conjuncts,\nor replace a complex closed-form with a recursive helper connected\nby a lemma.",{"type":35,"tag":3596,"props":3740,"children":3741},{},[],{"type":40,"value":3743},"When you use universal lemma application, always add triggers, as\nin ",{"type":35,"tag":43,"props":3745,"children":3747},{"className":3746},[],[3748],{"type":40,"value":3749},"forall x: u64 {f(x)} apply lemma_for_f(x)",{"type":40,"value":702},{"type":35,"tag":3596,"props":3752,"children":3753},{},[],{"type":35,"tag":62,"props":3755,"children":3756},{},[3757],{"type":40,"value":3758},"Avoid non-linear arithmetic in spec helpers.",{"type":40,"value":3760}," SMT solvers handle linear\narithmetic well but struggle with multiplication, division, or modulo between\ntwo non-constant expressions. Prefer additive recurrences over closed-form\nproducts. If a non-linear closed form is needed, connect it to a recursive\nhelper via a lemma so the solver reasons about each step linearly.",{"type":35,"tag":3596,"props":3762,"children":3763},{},[],{"type":35,"tag":62,"props":3765,"children":3766},{},[3767],{"type":40,"value":3768},"Do not redefine built-in operations as spec helpers.",{"type":40,"value":3770}," The SMT solver\nalready understands ",{"type":35,"tag":43,"props":3772,"children":3774},{"className":3773},[],[3775],{"type":40,"value":3776},"*",{"type":40,"value":220},{"type":35,"tag":43,"props":3779,"children":3781},{"className":3780},[],[3782],{"type":40,"value":3783},"\u002F",{"type":40,"value":220},{"type":35,"tag":43,"props":3786,"children":3788},{"className":3787},[],[3789],{"type":40,"value":3790},"%",{"type":40,"value":3792},", comparisons, and bitwise operations\nnatively. Only introduce a spec helper when it encodes logic the solver\ndoes not have built in — such as a loop accumulation pattern or a\nrecursive data-structure traversal.",{"type":35,"tag":3596,"props":3794,"children":3795},{},[],{"type":35,"tag":62,"props":3797,"children":3798},{},[3799],{"type":40,"value":3800},"Document every function and lemma.",{"type":40,"value":3802}," Add a ",{"type":35,"tag":43,"props":3804,"children":3806},{"className":3805},[],[3807],{"type":40,"value":413},{"type":40,"value":3809}," doc comment explaining\nwhat property it captures and why it is needed. Place new spec helper\nfunctions below the Move function that introduces them. Place lemmas\ndirectly beneath their helper's declaration.",{"type":35,"tag":52,"props":3811,"children":3813},{"id":3812},"task",[3814],{"type":40,"value":3815},"Task",{"type":35,"tag":36,"props":3817,"children":3818},{},[3819],{"type":40,"value":3820},"Run the Move Prover to verify the current package.",{"type":35,"tag":3822,"props":3823,"children":3824},"style",{},[3825],{"type":40,"value":3826},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3828,"total":1428},[3829,3839,3850,3861,3872,3877,3886],{"slug":993,"name":993,"fn":3830,"description":3831,"org":3832,"tags":3833,"stars":20,"repoUrl":21,"updatedAt":3838},"develop applications on Aptos","Move development on Aptos",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3834,3837],{"name":3835,"slug":3836,"type":16},"Blockchain","blockchain",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:46.40898",{"slug":3840,"name":3840,"fn":3841,"description":3842,"org":3843,"tags":3844,"stars":20,"repoUrl":21,"updatedAt":3849},"move-check","check Move packages for compilation errors","Check a Move package for compilation errors",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3845,3848],{"name":3846,"slug":3847,"type":16},"Debugging","debugging",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:09.843322",{"slug":3851,"name":3851,"fn":3852,"description":3853,"org":3854,"tags":3855,"stars":20,"repoUrl":21,"updatedAt":3860},"move-inf","infer specifications for Move packages","Infer specifications for a Move package",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3856,3859],{"name":3857,"slug":3858,"type":16},"Data Modeling","data-modeling",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:10.203983",{"slug":3862,"name":3862,"fn":3863,"description":3864,"org":3865,"tags":3866,"stars":20,"repoUrl":21,"updatedAt":3871},"move-init","initialize Move workflow routing","Initialize Move workflow routing in the project CLAUDE.md",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3867,3870],{"name":3868,"slug":3869,"type":16},"Configuration","configuration",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:48.382736",{"slug":4,"name":4,"fn":5,"description":6,"org":3873,"tags":3874,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3875,3876],{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"slug":3878,"name":3878,"fn":3879,"description":3880,"org":3881,"tags":3882,"stars":20,"repoUrl":21,"updatedAt":3885},"move-replay","replay and debug Aptos transactions","Replay a committed on-chain Aptos transaction locally to debug its outcome. Use when investigating a failed or unexpected transaction, reproducing an abort, or testing a local Move patch against a historical transaction.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3883,3884],{"name":3846,"slug":3847,"type":16},{"name":14,"slug":15,"type":16},"2026-07-19T06:03:11.562048",{"slug":3887,"name":3887,"fn":3888,"description":3889,"org":3890,"tags":3891,"stars":20,"repoUrl":21,"updatedAt":3894},"move-test","generate unit tests for Move code","Generate unit tests for Move code. Use for test generation, writing tests, or improving coverage.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3892,3893],{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-07-19T06:03:11.019744",{"items":3896,"total":4057},[3897,3912,3929,3943,3955,3969,3983,3998,4012,4027,4037,4047],{"slug":3898,"name":3898,"fn":3899,"description":3900,"org":3901,"tags":3902,"stars":1525,"repoUrl":3910,"updatedAt":3911},"analyze-gas-optimization","optimize Aptos Move contracts for gas","Analyze and optimize Aptos Move contracts for gas efficiency, identifying expensive operations and suggesting optimizations. Triggers on: 'optimize gas', 'reduce gas costs', 'gas analysis', 'make contract cheaper', 'gas efficiency', 'analyze gas usage', 'reduce transaction costs'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3903,3904,3907],{"name":3835,"slug":3836,"type":16},{"name":3905,"slug":3906,"type":16},"Performance","performance",{"name":3908,"slug":3909,"type":16},"Smart Contracts","smart-contracts","https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-agent-skills","2026-07-12T08:07:14.117466",{"slug":3913,"name":3913,"fn":3914,"description":3915,"org":3916,"tags":3917,"stars":1525,"repoUrl":3910,"updatedAt":3928},"create-aptos-project","scaffold new Aptos dApp projects","Scaffolds new Aptos projects using npx create-aptos-dapp. Supports fullstack (Vite or Next.js) and contract-only templates with network selection and optional API key. Triggers on: 'build app', 'create app', 'make app', 'new app', 'build dApp', 'create dApp', 'new dApp', 'build project', 'new project', 'create project', 'scaffold', 'start project', 'set up project', 'build me a', 'I want to build', 'make me a', 'help me build'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3918,3921,3924,3927],{"name":3919,"slug":3920,"type":16},"Next.js","next-js",{"name":3922,"slug":3923,"type":16},"TypeScript","typescript",{"name":3925,"slug":3926,"type":16},"Vite","vite",{"name":14,"slug":15,"type":16},"2026-07-12T08:07:30.595111",{"slug":3930,"name":3930,"fn":3931,"description":3932,"org":3933,"tags":3934,"stars":1525,"repoUrl":3910,"updatedAt":3942},"deploy-contracts","deploy Move contracts to Aptos networks","Safely deploys Move contracts to Aptos networks (devnet, testnet, mainnet) with pre-deployment verification. Triggers on: 'deploy contract', 'publish to testnet', 'deploy to mainnet', 'how to deploy', 'publish module', 'deployment checklist', 'deploy to devnet'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3935,3938,3941],{"name":3936,"slug":3937,"type":16},"Deployment","deployment",{"name":3939,"slug":3940,"type":16},"Engineering","engineering",{"name":3908,"slug":3909,"type":16},"2026-07-12T08:07:16.798352",{"slug":3944,"name":3944,"fn":3945,"description":3946,"org":3947,"tags":3948,"stars":1525,"repoUrl":3910,"updatedAt":3954},"generate-tests","generate test suites for Move contracts","Creates comprehensive test suites for Move contracts with 100% coverage requirement. Triggers on: 'generate tests', 'create tests', 'write test suite', 'test this contract', 'how to test', 'add test coverage', 'write unit tests'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3949,3950,3953],{"name":3939,"slug":3940,"type":16},{"name":3951,"slug":3952,"type":16},"QA","qa",{"name":18,"slug":19,"type":16},"2026-07-12T08:07:18.0205",{"slug":3956,"name":3956,"fn":3957,"description":3958,"org":3959,"tags":3960,"stars":1525,"repoUrl":3910,"updatedAt":3968},"modernize-move","modernize Move V1 contracts to V2","Detects and modernizes outdated Move V1 syntax, patterns, and APIs to Move V2+. Use when upgrading legacy contracts, migrating to modern syntax, or converting old patterns to current best practices. NOT for writing new contracts (use write-contracts) or fixing bugs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3961,3964,3965],{"name":3962,"slug":3963,"type":16},"Code Analysis","code-analysis",{"name":3939,"slug":3940,"type":16},{"name":3966,"slug":3967,"type":16},"Migration","migration","2026-07-12T08:07:10.226223",{"slug":3970,"name":3970,"fn":3971,"description":3972,"org":3973,"tags":3974,"stars":1525,"repoUrl":3910,"updatedAt":3982},"search-aptos-examples","search Aptos reference implementations","Searches aptos-core and daily-move for reference implementations before writing contracts. Triggers on: 'search examples', 'find example', 'check aptos-core', 'is there an example', 'reference implementation', 'how does aptos implement', 'similar contract', 'daily-move'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3975,3976,3979],{"name":3835,"slug":3836,"type":16},{"name":3977,"slug":3978,"type":16},"Documentation","documentation",{"name":3980,"slug":3981,"type":16},"Search","search","2026-07-12T08:07:15.382039",{"slug":3984,"name":3984,"fn":3985,"description":3986,"org":3987,"tags":3988,"stars":1525,"repoUrl":3910,"updatedAt":3997},"security-audit","audit Move smart contracts for security","Audits Move contracts for security vulnerabilities before deployment using 7-category checklist. Triggers on: 'audit contract', 'security check', 'review security', 'check for vulnerabilities', 'security audit', 'is this secure', 'find security issues'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3989,3992,3993,3996],{"name":3990,"slug":3991,"type":16},"Audit","audit",{"name":3962,"slug":3963,"type":16},{"name":3994,"slug":3995,"type":16},"Security","security",{"name":3908,"slug":3909,"type":16},"2026-07-12T08:07:11.680215",{"slug":3999,"name":3999,"fn":4000,"description":4001,"org":4002,"tags":4003,"stars":1525,"repoUrl":3910,"updatedAt":4011},"smoothsend-gasless","sponsor gas fees for Aptos dApps","How to sponsor gas fees for Aptos dApp users using SmoothSend. Paid commercial service: free on testnet, credit-based on mainnet. Covers 3-line wallet adapter integration (transactionSubmitter), Script Composer for fee-in-token stablecoin transfers. Triggers on: 'gasless', 'sponsor gas', 'users pay no APT', 'transactionSubmitter', 'SmoothSend', 'fee payer', 'pay gas for users', 'no gas required'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4004,4007,4010],{"name":4005,"slug":4006,"type":16},"API Development","api-development",{"name":4008,"slug":4009,"type":16},"Payments","payments",{"name":14,"slug":15,"type":16},"2026-07-12T08:07:31.843242",{"slug":4013,"name":4013,"fn":4014,"description":4015,"org":4016,"tags":4017,"stars":1525,"repoUrl":3910,"updatedAt":4026},"ts-sdk-account","manage Aptos accounts with TS SDK","How to create and use Account (signer) in @aptos-labs\u002Fts-sdk. Covers Account.generate(), fromPrivateKey(), fromDerivationPath(), Ed25519 vs SingleKey vs MultiKey vs Keyless, serialization (fromHex\u002FtoHex). Triggers on: 'Account.generate', 'Account.fromPrivateKey', 'Ed25519PrivateKey', 'SDK account', 'mnemonic', 'SingleKeyAccount', 'KeylessAccount'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4018,4021,4022,4025],{"name":4019,"slug":4020,"type":16},"Auth","auth",{"name":3835,"slug":3836,"type":16},{"name":4023,"slug":4024,"type":16},"SDK","sdk",{"name":3922,"slug":3923,"type":16},"2026-07-12T08:07:29.297415",{"slug":4028,"name":4028,"fn":4029,"description":4030,"org":4031,"tags":4032,"stars":1525,"repoUrl":3910,"updatedAt":4036},"ts-sdk-address","manage AccountAddress in Aptos TypeScript SDK","How to create and use AccountAddress in @aptos-labs\u002Fts-sdk. Covers address format (AIP-40), from\u002FfromString\u002FfromStrict, special addresses, LONG vs SHORT form, and derived addresses (object, resource, token, user-derived). Triggers on: 'AccountAddress', 'AccountAddress.from', 'AIP-40', 'derived address', 'createObjectAddress', 'createResourceAddress', 'createTokenAddress'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4033,4034,4035],{"name":3835,"slug":3836,"type":16},{"name":4023,"slug":4024,"type":16},{"name":3922,"slug":3923,"type":16},"2026-07-12T08:07:26.430378",{"slug":4038,"name":4038,"fn":4039,"description":4040,"org":4041,"tags":4042,"stars":1525,"repoUrl":3910,"updatedAt":4046},"ts-sdk-client","configure Aptos SDK clients","How to create and configure the Aptos client (Aptos, AptosConfig) in @aptos-labs\u002Fts-sdk. Covers Network, fullnode\u002Findexer\u002Ffaucet URLs, singleton pattern, and Bun compatibility. Triggers on: 'Aptos client', 'AptosConfig', 'SDK client', 'client setup', 'new Aptos(', 'Network.TESTNET', 'Network.MAINNET'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4043,4044,4045],{"name":4005,"slug":4006,"type":16},{"name":4023,"slug":4024,"type":16},{"name":3922,"slug":3923,"type":16},"2026-07-12T08:07:21.933342",{"slug":4048,"name":4048,"fn":4049,"description":4050,"org":4051,"tags":4052,"stars":1525,"repoUrl":3910,"updatedAt":4056},"ts-sdk-transactions","manage Aptos blockchain transactions","How to build, sign, submit, and simulate transactions in @aptos-labs\u002Fts-sdk. Covers build.simple(), signAndSubmitTransaction(), waitForTransaction(), simulate, sponsored (fee payer), and multi-agent. Triggers on: 'build.simple', 'signAndSubmitTransaction', 'transaction.build', 'waitForTransaction', 'signAsFeePayer', 'SDK transaction', 'sponsored transaction', 'multi-agent transaction'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4053,4054,4055],{"name":4005,"slug":4006,"type":16},{"name":3922,"slug":3923,"type":16},{"name":14,"slug":15,"type":16},"2026-07-12T08:07:23.774257",24]