Skip to content

feat: new foundations for mvcgen tactic#12965

Open
volodeyka wants to merge 32 commits intomasterfrom
vova/new-do-foundations
Open

feat: new foundations for mvcgen tactic#12965
volodeyka wants to merge 32 commits intomasterfrom
vova/new-do-foundations

Conversation

@volodeyka
Copy link
Copy Markdown

@volodeyka volodeyka commented Mar 18, 2026

This PR Introduces new foundations for reasoning about monadic Lean code. Eventually we will port mvcgen on top of these new foundations, to make the framework more general and robust.

Key issues, new metatheory is supposed to solve are

  • It gives more flexibility over what an assertion language for pre-/post-conditions of monadic Hoare triples can be. In particular, any CompleteLattice might become a pre-/post-condtions language, not only SPred. It potentially gives an opportunity to reason about probabilistic monads, where assertion language are distributions. This also simplifies the metatheory of monadic Hoare triples, as it does not require defining the notion of SPred, and allows users to work in a fairly common interface of CompleteLattice
  • It splits the post-conditions of Hoare triples/ WPs into two: (1) post for post-conditions on terminating paths and (2) epost for post-conditions on abrupt paths. Current foundations always bundle them into a pair, which inevitably leads to constructing and eliminating such pairs everywhere in the code.
  • It relaxes some conditions that the current foundations require for instantiating WPMonad type class. In particular we do not require wp to distribute over bind any more. Instead, we require just wp x (fun x => wp (f x) post epost) epost ⊑ wp (x >>= f) post epost, i.e. the distributed wp must only imply the non-distributed one (and not necessarily vice versa). With this we can define WPMonad for Separation Logic, where wp only distributes over bind on local-footprint computations.
  • It solves some universe polymorphism issues. As now universe levels of assertion languages are independent of universe levels in the monad, one can define WPMonad Id.{u} Prop EPost⟨⟩, which means that for arbitrary level Id the language for pre-/post-conditions is going to be just Prop and the language for post-conditions on abrupt exits is idle.

Copy link
Copy Markdown
Contributor

@sgraf812 sgraf812 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally fine, but there are a couple of smaller things worth of cleanup that I didn't bother addressing. Let Claude have a second-opinion/review pass on this for cleanup.

Comment thread script/lean-toolchain Outdated
Comment thread src/Std/Internal/Do/Triple/Basic.lean
Comment thread src/Std/Do'/LatticeExt.lean Outdated
Comment thread src/Std/Do'/Frame.lean Outdated
Comment thread src/Std/Do'/Frame.lean Outdated
Comment thread tests/env_test.sh Outdated
Comment thread tests/lean-toolchain Outdated
Comment thread lean-toolchain Outdated
Comment thread src/Std/Do/Triple/SpecLemmas.lean
Comment thread src/Std/Do'/Triple/SpecLemmas.lean Outdated
@volodeyka volodeyka marked this pull request as draft March 25, 2026 08:48
@volodeyka volodeyka changed the title feat: New foundations for mvcgen tactic feat: new foundations for mvcgen tactic Mar 25, 2026
volodeyka added a commit that referenced this pull request Mar 27, 2026
…OptionT WP, remove dead code

Structural changes:
- Make PredTrans a structure with `apply` field, add extensionality lemma
- Add apply_* simp framework (apply_pure, apply_bind, apply_map, etc.)
- Add pushOption/EPost.cons.pushOption for OptionT support

Renames (per Sebastian Graf's review of PR #12965):
- WPMonad → WP (class name)
- wp_cons → wp_consequence (and derived names)
- wp_trans_pure/bind/monotone → wpTrans_pure/bind/monotone
- LawfulWPMonadLift → LawfulWPLift, etc.

Class merge and parameter renames:
- Merge AssertionLang + ExceptAssertionLang into single `Assertion`
- Rename type params: l → Pred, el/e → EPred

OptionT support:
- Add OptionT.instWP using pushOption with EPost.cons Pred EPred
- Uncomment all OptionT WP lemmas and Triple specs

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the changes-stage0 Contains stage0 changes, merge manually using rebase label Apr 16, 2026
volodeyka and others added 10 commits April 16, 2026 17:47
… args

Change AssertionLang and ExceptAssertionLang from standalone classes to
class abbrevs over CompleteLattice, and require them as class arguments
to WPMonad rather than using extends.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- LatticeExt: wrap in `namespace Lean.Order`, scope ⊤ ⊓ ⊔ ⌜⌝ notations
- Frame: move from `namespace Loom` to `namespace Lean.Order`, scope ⇨
- Frame: rename field `inf_sup` → `meet_sup`

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Convert `inductive EPost.nil` and `inductive EPost.cons` to `structure`
- Remove manual head/tail projections (now auto-generated)
- Simplify PartialOrder/CompleteLattice instances using PProd
- Rename `mk_rel` → `rel_mk`

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…OptionT WP, remove dead code

Structural changes:
- Make PredTrans a structure with `apply` field, add extensionality lemma
- Add apply_* simp framework (apply_pure, apply_bind, apply_map, etc.)
- Add pushOption/EPost.cons.pushOption for OptionT support

Renames (per Sebastian Graf's review of PR #12965):
- WPMonad → WP (class name)
- wp_cons → wp_consequence (and derived names)
- wp_trans_pure/bind/monotone → wpTrans_pure/bind/monotone
- LawfulWPMonadLift → LawfulWPLift, etc.

Class merge and parameter renames:
- Merge AssertionLang + ExceptAssertionLang into single `Assertion`
- Rename type params: l → Pred, el/e → EPred

OptionT support:
- Add OptionT.instWP using pushOption with EPost.cons Pred EPred
- Uncomment all OptionT WP lemmas and Triple specs

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@volodeyka volodeyka force-pushed the vova/new-do-foundations branch from b446ea9 to 847630b Compare April 16, 2026 09:52
@volodeyka volodeyka removed the changes-stage0 Contains stage0 changes, merge manually using rebase label Apr 16, 2026
…nts by removing redundant attributes. Introduce `open Classical` for improved readability.
…emmas.lean`. Update documentation for clarity and consistency, replacing `EPred` with `eInvariant EPred` in relevant theorem signatures.
Copy link
Copy Markdown
Contributor

@sgraf812 sgraf812 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More tomorrow. I'm slowly coming to think that it will be more efficient to merge soon and then guide an AI to do the changes that I request here rather then writing comments on GH to have you implement them.

Comment thread src/Std/Internal/Do/WP/Lemmas.lean
Comment thread src/Std/Experimental/Do/WP/Lemmas.lean Outdated
Comment thread src/Std/Internal/Do/Triple/Basic.lean Outdated
Comment on lines +39 to +42
/-- Hoare triple notation without exception postcondition (defaults to `⊥`). -/
notation:60 "⦃ " pre " ⦄ " x " ⦃ " post " ⦄" => Triple pre x post ⊥
/-- Hoare triple notation with a binder for the return value. -/
notation:60 "⦃ " pre " ⦄ " x " ⦃ " v ", " post " ⦄" => Triple pre x (fun v => post) ⊥
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change to every existing use of notation... We should ensure that it is actually better than what we currently have. Let's discuss this in our next meeting.

What I like about what we currently have is that ⦃pre⦄ x ⦃⇓r => post⦄ evokes similarity to Lean's fun r => post syntax. On the other hand, ⦃pre⦄ x ⦃r, post⦄ looks neater and is closer to what people might be used to from pen and paper proofs. However, it's quite un-Lean-ish.

Furthermore, ⦃pre⦄ x ⦃⇓? r => post⦄ can be used to say Triple $pre $x (fun r => $post) T and there presently is no notation to say this in your patch. Generally it seems that you lose notation whenever the epost is non-bottom.

Maybe the cleanest solution is:

  • ⦃pre⦄ x ⦃post⦄ => Triple pre x post ⊥ (your first notation)
  • ⦃pre⦄ x ⦃post⦄? => Triple pre x post T
  • ⦃pre⦄ x ⦃post⦄ ⦃eposts...⦄ => Triple pre x post epost<eposts...> (likely needs to be a macro)
  • ⦃pre⦄ x ⦃r => post⦄ => ⦃pre⦄ x ⦃fun r => post⦄ (compositional expansion; the fun is effectively optional. Not sure if that's worth it. I tend to think it isn't.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for my taste, I would want to avoid unicode whenever possible. I like and ⇓? symbols, but I feel it requires a little too much of a context. If we add it, it will be giving Coq-SSReflect vibes, where there are tons of conventions, which are really smart and useful, but make the overall framework highly exclusive. You really need to get into the head of developers to understand what's going on.

  • for , versus =>, I was thinking of it a lot, and finally deceid on , because it is already used in big operator notations. It is so standard in maths, that it kinda overrides Lean style for me sometimes.
    I think we should either use , or jut go with ⦃fun r => post⦄. Omitting fun might confuse people
  • I don't have any super strong opinion about ⦃pre⦄ x ⦃post⦄?. We can add it if you think it is going to be used
  • I would change ⦃pre⦄ x ⦃post⦄ ⦃eposts...⦄ into ⦃pre⦄ x ⦃post; eposts...⦄ and also separate eposts with ;. Then it would be somewhat uniform.

Copy link
Copy Markdown
Contributor

@sgraf812 sgraf812 Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on unicode. we should ensure that can be typed as {{ as well.

  • , sounds fine then.

  • ⦃post⦄? is useful because you can't really write T in the syntax I proposed

  • I would change ⦃pre⦄ x ⦃post⦄ ⦃eposts...⦄ into ⦃pre⦄ x ⦃post; eposts...⦄ and also separate eposts with ;

    Hmm, I fear that ; is not enough signalling. It is also ambiguous with ⦃v, match v with none => ...; some _ => ...; blah⦄. Note that Iris separates into two {{}} as well. Also do you expect users to write ⦃post; epost<e1,e2,e3>⦄ (note that we switched from , to ;) or is it more like ⦃post; e1; e2; e3⦄?

Comment thread src/Std/Experimental/Do/Triple/Basic.lean Outdated
Comment thread src/Std/Experimental/Do/Frame.lean Outdated
Comment thread src/Std/Experimental/Do/LatticeExt.lean Outdated
Comment thread src/Std/Experimental/Do/WP/Basic.lean Outdated
Comment thread src/Std/Experimental/Do/WP/Basic.lean Outdated
Comment thread src/Std/Experimental/Do/WP/Basic.lean Outdated
Comment thread src/Std/Internal/Do/WP/Basic.lean
…e CompleteLattice.pure to Assertion.ofProp

Move `class abbrev Assertion` and CCPO instance from WP/Basic.lean into
the renamed Assertion.lean. Rename `CompleteLattice.pure` to
`Assertion.ofProp` and rename all related lemmas (`trueE` →
`ofProp_true`, `falseE` → `ofProp_false`, `LE.pure_imp` →
`ofProp_imp`, `LE.pure_intro` → `ofProp_intro`, `pure_intro_l` →
`ofProp_intro_l`, `pure_intro_r` → `ofProp_intro_r`).
Add Gadget to Triple umbrella import. Remove duplicate List.Cursor and
Std.Legacy.Range.toList definitions from Experimental SpecLemmas,
importing them from the non-Experimental Std.Do.Triple.SpecLemmas
instead.
@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 Apr 17, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Apr 17, 2026
@github-actions github-actions Bot added the mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN label Apr 17, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Apr 17, 2026
leanprover-bot added a commit to leanprover/reference-manual that referenced this pull request Apr 17, 2026
@leanprover-bot leanprover-bot added the builds-manual CI has verified that the Lean Language Reference builds against this PR label Apr 17, 2026
@leanprover-bot
Copy link
Copy Markdown
Collaborator

leanprover-bot commented Apr 17, 2026

Reference manual CI status:

@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Apr 17, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

Mathlib CI status (docs):

@volodeyka volodeyka marked this pull request as ready for review April 17, 2026 10:59
mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Apr 17, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Apr 17, 2026
leanprover-bot added a commit to leanprover/reference-manual that referenced this pull request Apr 17, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

Mathlib CI status (docs):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builds-manual CI has verified that the Lean Language Reference builds against this PR builds-mathlib CI has verified that Mathlib builds against this PR changelog-library Library mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN 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.

3 participants