Skip to content

feat(control): bridge the program-logic kernel to core's lattice-generic WP stack - #187

Draft
dtumad wants to merge 1 commit into
tocslib/free-monad-slicefrom
kernel/upstream-wp-instances
Draft

feat(control): bridge the program-logic kernel to core's lattice-generic WP stack#187
dtumad wants to merge 1 commit into
tocslib/free-monad-slicefrom
kernel/upstream-wp-instances

Conversation

@dtumad

@dtumad dtumad commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on #185 (and #184, the draft rc2 base). Gives every PolyFun judgment a core Std.Internal.Do.WPMonad interpretation — the stack that becomes public Std.WP in v4.35 and that vcgen drives — so vcgen decomposes do programs through PolyFun's own semantics and core's Spec.* lemmas apply without re-proof.

  • Control/Monad/Algebra/WP.leanMAlgOrdered.toWP / toWPMonad: an ordered monad algebra over a Mathlib complete lattice as a WPMonad m l EPost.Nil (via the ToCslib.Order.LeanOrder bridge); wp agreement by rfl, toWP_triple_iff, wpConjunctiveOf, and lattice-operation transfer lemmas.
  • Control/Monad/Support/WP.leanMonadAttach.toWPMonadDemonic / toWPMonadAngelic (wp x post = AllOutputs post x, resp. SomeOutput): the angelic reading is expressible because the laws are inequalities. Demonic conjunctivity; a field-for-field mirror of master's LawfulWPMonadAttach (in the Std.Internal.Do namespace so the v4.35 rename deletes it); support_subset_of_wp / allOutputs_of_wp.
  • Control/Monad/Hom/WP.leanMonadHom.transportWP / transportWPMonad / unbundled transportWPMonadOf.

Nothing here is a global instance. The legacy Std.Do bridge is kept (renamed transportSPredWP(Monad), *_of_wpSPred) until the free-monad layer moves over in the next PR.

Findings worth knowing

  • The bridge modules import the Std.Internal.Do root: vcgen's @[spec] database (Spec.bind) lives in Triple.SpecLemmas, and importing only WP.Basic gives No spec found for program … on every do block. Recorded as a gotcha.
  • Projections/constructions of Triple, WPConjunctive, LawfulWPMonadAttach re-synthesize the instance-implicit WP; proofs about non-instance interpretations bind them with let inst := … first. Recorded as a gotcha.

Validation

  • ./scripts/validate.sh --lint --test --axioms — lint passes for PolyFun and ToCslib; 10970 declarations, zero sorry/axiom taint
  • PolyFunTest/Do/Algebra.lean: vcgen through MAlgOrdered.toWPMonad at carrier ℕ∞; PolyFunTest/Do/Support.lean: vcgen through the demonic reading of SetM and conversion back to AllOutputs

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nb4g3Vxgjhnhsca7BzAsFc

…ric WP stack

Give every PolyFun judgment a core `Std.Internal.Do.WPMonad` interpretation (the
stack that becomes public `Std.WP` in v4.35 and that `vcgen` drives), so that
`vcgen` decomposes `do` programs through PolyFun's own semantics and core's
`Spec.*` lemmas apply to them without re-proof:

- `Control/Monad/Algebra/WP.lean`: `MAlgOrdered.toWP` / `toWPMonad` turn an
  ordered monad algebra over a Mathlib complete lattice into a
  `WPMonad m l EPost.Nil` through the `ToCslib.Order.LeanOrder` bridge; `wp`
  agrees with `MAlgOrdered.wp` by `rfl`, core's `Triple` is PolyFun's
  (`toWP_triple_iff`), `wpConjunctiveOf` derives conjunctivity from meet
  preservation, and `top_eq_top` / `meet_eq_inf` / `join_eq_sup` move between
  core's and Mathlib's lattice operations on a bridged carrier;
- `Control/Monad/Support/WP.lean`: `MonadAttach.toWPMonadDemonic` and
  `toWPMonadAngelic` interpret exact support as `WPMonad m Prop EPost.Nil`
  (`wp x post = AllOutputs post x`, resp. `SomeOutput`); the angelic reading is
  expressible here because the laws are inequalities. The demonic reading is
  conjunctive and sound: `LawfulWPMonadAttach` mirrors, field for field, the
  soundness class on Lean master, declared in the `Std.Internal.Do` namespace
  so the v4.35 rename deletes it; `support_subset_of_wp` / `allOutputs_of_wp`
  turn any sound triple into a support fact;
- `Control/Monad/Hom/WP.lean`: `MonadHom.transportWP` / `transportWPMonad`
  and the unbundled `transportWPMonadOf` pull an interpretation back along a
  monad morphism.

None of these is a global instance; they are installed `local` or `scoped` at
the carrier. The legacy `Std.Do` bridge keeps working under the names
`MonadHom.transportSPredWP(Monad)` and
`MonadAttach.support_subset_of_wpSPred` / `allOutputs_of_wpSPred`, freeing
the canonical names.

The bridge modules import the `Std.Internal.Do` root: `vcgen` consults the
`@[spec]` database, whose `Spec.bind` lives in `Triple.SpecLemmas`, and
importing only the `WP` submodules yields `No spec found` on every `do`
block. `PolyFunTest/Do/Algebra.lean` and `PolyFunTest/Do/Support.lean` run
`vcgen` through a Mathlib-carrier algebra and through the demonic reading of
`SetM`, and convert the result back into an "always" judgment.

Docs: the program-logic page now describes the lattice-generic stack as
canonical, records the three practical rules (root import, binding a
non-instance interpretation with `let` before projecting, keeping transfer
lemmas out of the `Lean.Order` namespace) and the v4.35 rename table; the
landscape memo, repo map, AGENTS.md, and two new gotchas follow.

Validated with `./scripts/validate.sh --lint --test --axioms` (zero
sorry/axiom taint).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb4g3Vxgjhnhsca7BzAsFc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant