Skip to content

feat: state the laws of Std.WP as Prop classes - #16451

Draft
sgraf812 wants to merge 3 commits into
sg/assertion-abbrevfrom
sg/wp-stripped
Draft

sgraf812 wants to merge 3 commits into
sg/assertion-abbrevfrom
sg/wp-stripped

Conversation

@sgraf812

@sgraf812 sgraf812 commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

This PR states the laws of Std.WP as Prop classes over predicate transformers. WP carries only the transformer trans, and MonadicWP (formerly WPMonad) carries only the interpretation of a monad. So wp and Triple take no orders, and an interpretation whose assertions form only a partial order, such as quantum effects under the Löwner order (Discovering formally verified quantum programs with AI), works with vcgen.

The laws:

  • PredTrans.IsMonotone t and PredTrans.IsConjunctive t for a transformer t, with instances for pure, >>=, pushArg, pushExceptT and pushOptionT.
  • WP.IsMonotone Prog and WP.IsConjunctive x: abbreviations for the transformer of every program of type Prog being monotone, and for the transformer of the program x being conjunctive. MonadicWP.IsMonotone m and MonadicWP.IsConjunctive m state the same for all programs of a monad m.
  • MonadicWP.IsLaxMonadMorphism m: pure and bind of the transformers lie below the transformers of pure and bind.
  • MonadicWP.IsMonadMorphism m: the transformer commutes with pure and bind.

A WP instance declares only trans. Its monotonicity is a separate instance WP.IsMonotone Prog, whose proof is the former trans_monotone field. WPMonad m Pred EPosts becomes [MonadicWP m Pred EPosts] [MonadicWP.IsMonotone m] [MonadicWP.IsLaxMonadMorphism m], WPConjunctive x becomes WP.IsConjunctive x, and Std.WP.Assertion is deprecated in favour of CompleteLattice.

Stacked on #16425.

🤖 Generated with Claude Code

`WP` carries the predicate transformer only, and `MonadicWP` carries the
interpretation of a monad only. The laws are `Prop` classes over
`PredTrans`: `PredTrans.IsMonotone` and `PredTrans.IsConjunctive`, with
instances for the transformer combinators. `WP.IsMonotone Prog` states
monotonicity for every program of type `Prog`.
`MonadicWP.IsLaxMonadMorphism` and `MonadicWP.IsMonadMorphism` state the
laws of `pure` and `bind` for an interpretation of a monad.

`wp` and `Triple` take no orders. `vcgen` synthesizes the orders and laws
that a spec needs when it builds the rule for the spec.

`WPMonad` becomes `MonadicWP`, `WPConjunctive x` becomes
`(WP.trans x).IsConjunctive`, and `Assertion` is deprecated in favour of
`CompleteLattice`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D74FF3YMbbk7yvips5ezWi
@sgraf812

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Nov 13, 2026 •

Copy link
Copy Markdown

Benchmark results for 61fe1b8 against 16f65a4 are in. There are significant results. @sgraf812

  • 🟥 build//instructions: +2.9G (+0.03%)

Large changes (2🟥)

  • 🟥 vcgen/AddSubCancelDeep/100/vcgen//wall-clock: +98ms (+391.82%)
  • 🟥 vcgen/AddSubCancelDeep/500/vcgen//wall-clock: +15ms (+19.75%)

Small changes (17✅, 20🟥)

  • ✅ build/profile/grind ac//wall-clock: -3ms (-62.83%)
  • 🟥 elab/big_deceq//instructions: +15.3M (+0.56%)
  • 🟥 elab/big_deceq_rec//instructions: +15.6M (+0.43%)
  • 🟥 elab/big_match//instructions: +17.8M (+0.23%)
  • 🟥 elab/big_match_nat//instructions: +15.3M (+0.48%)
  • ✅ vcgen/AddSubCancel/1200/vcgen//wall-clock: -9ms (-6.28%)
  • ✅ vcgen/AddSubCancel/2200/vcgen//wall-clock: -17ms (-5.78%)
  • ✅ vcgen/AddSubCancelDeep/100/kernel//wall-clock: -2ms (-9.84%)
  • 🟥 vcgen/AddSubCancelDeep/900/vcgen//wall-clock: +13ms (+9.71%)
  • 🟥 vcgen/GetThrowSet/200/vcgen//wall-clock: +9ms (+21.14%)
  • 🟥 vcgen/GetThrowSetGrind/100/vcgen//wall-clock: +8ms (+10.97%)
  • and 26 hidden

@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 Nov 13, 2026
sgraf812 and others added 2 commits November 13, 2026 18:00
`WP.IsConjunctive x` abbreviates `(WP.trans x).IsConjunctive`,
`MonadicWP.IsMonotone m` abbreviates `∀ α, WP.IsMonotone (m α)`, and
`MonadicWP.IsConjunctive m` abbreviates `∀ α (x : m α), WP.IsConjunctive x`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D74FF3YMbbk7yvips5ezWi
`vcgen` caches the law instances of spec rules per call, keyed by the law
class and its determining argument, and reads `WP.IsMonotone (m α)` off a
cached `MonadicWP.IsMonotone m`. The monotonicity lemmas are applied
without type checks, as before. `MonadicWP.IsMonotone` has instances for
the transformers, and their lax morphism instances have low priority, so
instance search derives the lax laws of a monad morphism directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D74FF3YMbbk7yvips5ezWi
@sgraf812

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Nov 14, 2026 •

Copy link
Copy Markdown

Benchmark results for 8059fce against 16f65a4 are in. There are significant results. @sgraf812

  • 🟥 build//instructions: +3.3G (+0.04%)

Large changes (7✅, 2🟥)

  • ✅ compiled/incr_header_save//maxrss: -82MiB (-4.45%)
  • 🟥 compiled/rbmap_checkpoint//task-clock: +460ms (+33.84%)
  • 🟥 compiled/rbmap_checkpoint//wall-clock: +472ms (+34.21%)
  • ✅ elab/bv_decide_incremental//maxrss: -125MiB (-6.28%)
  • ✅ lake/inundation/config/elab//maxrss: -42MiB (-5.10%)
  • ✅ lake/inundation/config/import//maxrss: -41MiB (-5.18%)
  • ✅ lake/inundation/config/tree//maxrss: -42MiB (-5.24%)
  • ✅ lake/inundation/env//maxrss: -41MiB (-5.14%)
  • ✅ lake/inundation/setups//maxrss: -41MiB (-4.85%)

Medium changes (2✅)

  • ✅ build/profile/grind ac//wall-clock: -3ms (-63.04%)
  • ✅ lake/inundation/build/no-op//maxrss: -45MiB (-5.58%)

Small changes (71✅, 16🟥)

  • ✅ elab/big_beq//maxrss: -39MiB (-2.24%)
  • ✅ elab/big_beq_rec//maxrss: -38MiB (-2.19%)
  • ✅ elab/big_deceq//maxrss: -39MiB (-2.24%)
  • ✅ elab/big_deceq_rec//maxrss: -38MiB (-2.20%)
  • ✅ elab/big_match//maxrss: -38MiB (-2.17%)
  • ✅ elab/big_match_nat//maxrss: -39MiB (-2.29%)
  • ✅ elab/big_match_nat_split//maxrss: -37MiB (-2.10%)
  • ✅ elab/big_match_partial//maxrss: -40MiB (-2.26%)
  • ✅ elab/cbv_decide//maxrss: -68MiB (-3.74%)
  • ✅ elab/cbv_divisors//maxrss: -70MiB (-4.05%)
  • ✅ elab/cbv_merge_sort//maxrss: -70MiB (-3.87%)
  • ✅ elab/charactersIn//maxrss: -18MiB (-1.85%)
  • ✅ elab/delayed_assign//maxrss: -66MiB (-3.83%)
  • ✅ elab/delayed_lift//maxrss: -67MiB (-3.81%)
  • ✅ elab/delayed_sharing//maxrss: -68MiB (-3.96%)
  • ✅ elab/deriving_mutual_block//maxrss: -67MiB (-3.45%)
  • ✅ elab/grind_cases_next//maxrss: -57MiB (-3.16%)
  • ✅ elab/inferTypeCache//maxrss: -18MiB (-1.95%)
  • ✅ elab/irDeclLookup//maxrss: -23MiB (-2.56%)
  • ✅ elab/let_to_have_chain//maxrss: -68MiB (-3.93%)
  • and 38 more
  • and 29 hidden

This branch has not been deployed

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

Labels

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