You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: port the mvcgen' tactic to the new Std.Internal.Do meta theory (#14015)
This PR ports the experimental `mvcgen'` tactic to the new
`Std.Internal.Do` meta theory, where verification-condition generation
works on lattice entailments `pre ⊑ wp x post epost`. Two changes are
visible at the proof surface: `mvcgen'` now eagerly introduces all state
components as local hypotheses, so more facts reach `grind`; and loop
invariants no longer have to restate the exceptional postcondition.
Previously the invariant for a loop that can throw had to repeat the
exception condition alongside the actual invariant:
```lean
theorem throwing_loop_spec :
⦃fun s => ⌜s = 4⌝⦄
throwing_loop
⦃post⟨fun _ _ => ⌜False⌝,
fun e s => ⌜e = 42 ∧ s = 4⌝⟩⦄ := by
mvcgen' [throwing_loop]
case inv1 => exact post⟨fun (xs, r) s => ⌜r ≤ 4 ∧ s = 4 ∧ r + xs.suffix.sum > 4⌝,
fun e s => ⌜e = 42 ∧ s = 4⌝⟩
```
Now the exceptional postcondition is taken from the surrounding
`Triple`, so the invariant case carries only the invariant:
```lean
theorem throwing_loop_spec :
⦃fun s => s = 4⦄
throwing_loop
⦃fun _ _ => False;
fun e s => e = 42 ∧ s = 4⦄ := by
mvcgen' [throwing_loop]
case inv1 => exact ⟨fun (xs, r) s => r ≤ 4 ∧ s = 4 ∧ r + xs.suffix.sum > 4⟩
```
The spec lemmas in `Std.Internal.Do.Triple.SpecLemmas` are registered
with `@[spec]` and populate the new spec database, which also gains the
`whileM`/`Lean.Loop` specifications, `Invariant.withEarlyReturnNewDo`,
and pointwise entailment lemmas for state introduction.
The port replays Vladimir Gladshtein's #13978 onto master's file
structure.
The solver diverges from the legacy algorithm in three points.
Reflexivity runs on every entailment before the pure-precondition lifts,
closing the leaf VCs where a spec precondition meets an identical goal
precondition (`Q x ⊑ wp (pure x) Q E` ends in `Q x ⊑ Q x`) and
instantiating spec parameters that occur only in rule premises.
Reflexivity no longer assigns synthetic opaque metavariables, so
function-typed invariant holes are not silently solved away. Pure
preconditions are lifted into the local context as soon as they arise;
the lifted hypothesis is cached in `Scope.lastLiftedPre?`, and a
targeted assumption step closes the handoff VCs of subsequent spec
applications against it.
This is the second of two steps that land `vova/new-mvcgen` onto master.
The first step (#13954) updated the `@[spec]` builtin attribute and
regenerated `stage0`, so this PR reuses master's `stage0` and contains
no generated C changes. Invariant suggestion (`invariants?`) yields no
suggestions on the new surface; porting the suggestion analysis is
deferred until `mvcgen'` replaces the legacy `mvcgen`.
---------
Co-authored-by: volodeyka <vovaglad00@gmail.com>
0 commit comments