Skip to content

feat: footprint-based frame inference for vcgen via @[frameproc] - #14529

Merged
sgraf812 merged 1 commit into
masterfrom
sg/vcgen-seplogic-listrev
Jul 30, 2026
Merged

feat: footprint-based frame inference for vcgen via @[frameproc]#14529
sgraf812 merged 1 commit into
masterfrom
sg/vcgen-seplogic-listrev

Conversation

@sgraf812

@sgraf812 sgraf812 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

This PR reworks how a @[frameproc] procedure discharges its split verification condition so that frame inference scales to operators whose residual the built-in lattice split cannot decompose. A procedure for separating conjunction used to leave behind a that no split rule could discharge, halting vcgen; a procedure may now discharge its split VC however it wants, so separation-logic framing closes with vcgen … with finish.

A procedure builds its split VC pre ⊑ (op frame residualPre) s⃗ against a solver-owned metavariable residualPre that the solver fills with the weakest footprint once the frame rule applies, and returns a FrameSplit that either carries its own proof of that VC or defers it as a subgoal for the built-in lattice decomposition.

@sgraf812 sgraf812 added the changelog-tactics User facing tactics label Jul 24, 2026
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Jul 24, 2026
@mathlib-lean-pr-testing

mathlib-lean-pr-testing Bot commented Jul 24, 2026

Copy link
Copy Markdown

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 22ffba44b5d75f7a1353bb0265089c233eddd5e9 --onto 3259610687883ec1ea48c481aba2469f2f83facf. You can force Mathlib CI using the force-mathlib-ci label. (2026-07-24 11:02:11)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 76e5ec53d211e9c6d8aec071bb427bc482515d3d --onto 0bfc3acaef4ed0576307a77fbaa0c6e1a5dca402. You can force Mathlib CI using the force-mathlib-ci label. (2026-07-27 16:35:03)

@leanprover-bot

leanprover-bot commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 22ffba44b5d75f7a1353bb0265089c233eddd5e9 --onto 49ff95727f98d43984726b26742d17a1ceea9dd5. You can force reference manual CI using the force-manual-ci label. (2026-07-24 11:02:13)
  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 76e5ec53d211e9c6d8aec071bb427bc482515d3d --onto 0bfc3acaef4ed0576307a77fbaa0c6e1a5dca402. You can force reference manual CI using the force-manual-ci label. (2026-07-27 16:35:04)
  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 76e5ec53d211e9c6d8aec071bb427bc482515d3d --onto aa89d2777fb4342ff3084502e8f2d5a01aa17222. You can force reference manual CI using the force-manual-ci label. (2026-07-28 16:05:34)
  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 76e5ec53d211e9c6d8aec071bb427bc482515d3d --onto a39eab69e1eee9ad38f4efe507907b1026a77808. You can force reference manual CI using the force-manual-ci label. (2026-07-29 12:12:59)

@sgraf812
sgraf812 force-pushed the sg/vcgen-seplogic-listrev branch 26 times, most recently from 3218f69 to 4f1875f Compare July 30, 2026 09:54
This PR generalizes `vcgen` frame inference beyond the lattice meet: a `@[frameproc]` returns a `FrameSplit` naming the framed resource and a proof of the split VC, so separation-logic `∗` framing works with `vcgen … with finish`. The sep-logic test gains an in-place reverse of a doubly-linked list that frames an unrelated cell across the whole program.

`vcgen` applies a single frame rule, `WP.Frames.op_wp_upperAdjoint_le_wp`, with the framed resource `F` schematic and the weakest footprint `W = wp x (fun a => upperAdjoint (op F) (Q a)) E` baked in, so its premises are just the frame condition `WP.Frames op x F` and the split VC `pre ⊑ (op F W) s⃗`. A `@[frameproc]` takes a `FrameInferenceInfo` (the `wp` metadata plus the frame operator, the goal entailment, and the pre/spec/residual preconditions) and returns a `FrameSplit`, building its proof against a solver-owned placeholder for `W` that the solver fills by reading `W` off the applied rule. The meet default and the `DyLean` demo defer the split VC to the built-in meet decomposition; the separation-logic procedure proves it by AC-rearrangement of `∗`; the cost demo emits the `costConj`-reduced meet form. All frameproc term-building goes through the `SymM` builders. `solve` gains an `instantiateGoal?` step that canonicalizes the entailment's carrier and sides after rule application, and precondition normalization gains steps that lift a `⌜φ⌝ ⊓ P` guard (via `ofProp_meet_le`) and eliminate an `iSup` precondition (via `iSup_le`).
@sgraf812
sgraf812 force-pushed the sg/vcgen-seplogic-listrev branch from 4f1875f to ced713a Compare July 30, 2026 10:53
@sgraf812
sgraf812 marked this pull request as ready for review July 30, 2026 11:17
@sgraf812
sgraf812 requested a review from TwoFX as a code owner July 30, 2026 11:17
@sgraf812
sgraf812 added this pull request to the merge queue Jul 30, 2026
Merged via the queue into master with commit d19a5e5 Jul 30, 2026
28 checks passed
@sgraf812
sgraf812 deleted the sg/vcgen-seplogic-listrev branch July 30, 2026 12:18
sgraf812 added a commit that referenced this pull request Jul 30, 2026
This PR restores `vcgen` spec application performance regressed by #14529, up to +39% wall-clock on the `vcgen` benchmark suite. Frame inference inputs are computed only when a frame inference procedure consumes them, so applying a spec with no frame to infer costs what it did before frame inference.

The spec precondition now comes from `FrameInferenceInfo.specPre?`, a speculative, rolled-back application of the spec's cached backward rule that runs only when a procedure calls it; the solver previously ran the speculation for every spec application with a non-conjunctive precondition and then applied the spec a second time. The frame operator is likewise built only when a procedure constructs a split: `mkSplitVC` and `FrameSplit.withDeferredSplitVC` take it as an argument, and `defaultFrameInferenceProc` (renamed from `meetFrameInferenceProc`; it is agnostic of the operator) takes an operator builder invoked only for a pinned `frames` clause.

`FrameInferenceInfo` drops `op`, `le` and `pre` (the latter two become accessors of the new `goal` field), gains the spec's backward rule `specRule`, and replaces `FrameInferenceHint` with `providedFrame? : Option Expr`; `FrameProc.resourceTy` is renamed to `mkResourceTy`. On `PurePrecond(2400)` instruction counts return from 12.1G to 11.2G against a pre-#14529 baseline of 11.05G.
yermakoffivan pushed a commit to yermakoffivan/lean4 that referenced this pull request Jul 30, 2026
This PR restores `vcgen` spec application performance regressed by
leanprover#14529. Frame inference inputs are computed only when a frame inference
procedure consumes them, so applying a spec with no frame to infer costs
what it did before frame inference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-tactics User facing tactics toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants