Weakest Precondition Interpretation #
This module defines the weakest precondition interpretation WPMonad of monadic programs
in terms of predicate transformers PredTrans.
An instance WPMonad m Pred EPred determines a function wpTrans : m α → PredTrans Pred EPred α that
interprets a program x : m α as a predicate transformer. The function wp is the
user-facing wrapper: wp x post epost computes the weakest precondition for x to
satisfy normal postcondition post and exception postcondition epost.
Assertion Language Classes #
Assertion is an alias type class for CompleteLattice.
We use Assertion Pred for the assertion language of normal postconditions
and Assertion EPred for exception postconditions.
Pre-defined instances #
WPMonad Id Prop EPost.Nil— pure computations.WPMonad (StateT σ m) (σ → Pred) EPred— stateful computations.WPMonad (ExceptT ε m) Pred (EPost.Cons (ε → Pred) EPred)— computations with exceptions.WPMonad (ReaderT ρ m) (ρ → Pred) EPred— reader computations.WPMonad (Except ε) Prop EPost⟨ε → Prop⟩— concrete exception type.WPMonad (EStateM ε σ) (σ → Prop) (ε → σ → Prop)— concrete error-state monad.
WP and WPMonad Typeclasses #
The WP typeclass interprets a program type Prog whose results have type Value as a monotone
predicate transformer wpTrans : Prog → PredTrans Pred EPred Value.
The WPMonad typeclass adds soundness of the weakest precondition interpretation for the monadic
pure and bind of a monad m, on top of a WP (m α) α Pred EPred interpretation for every
result type α.
Weakest precondition interpretation of a program type Prog whose results have type Value,
as a monotone predicate transformer over assertion language Pred with exception postconditions
EPred.
- wpTrans : Prog → PredTrans Pred EPred Value
The weakest precondition transformer for a program.
Monotonicity: weaker postconditions yield weaker preconditions.
Instances
Weakest precondition of x for normal postcondition post and exception postcondition epost.
The WP interpretation can be supplied explicitly via dot notation (inst.wp x post epost).
Equations
- Std.Internal.Do.wp x post epost = (Std.Internal.Do.WP.wpTrans x).apply post epost
Instances For
Weakest precondition monad: a monad m whose weakest precondition interpretation is sound for
pure and bind. The interpretation for every result type is carried as the toWP field; an
instance exposes it as a WP (m α) … interpretation.
- seq_assoc {α β γ : Type u} (x : m α) (g : m (α → β)) (h : m (β → γ)) : h <*> (g <*> x) = Function.comp <$> h <*> g <*> x
The weakest precondition interpretation of
mat every result type.- pure_le_wp_pure {α : Type u} (x : α) (post : α → Pred) (epost : EPred) : Lean.Order.PartialOrder.rel (post x) (wp (pure x) post epost)
Soundness of
pure: the postcondition applied toximplies the weakest precondition ofpure x. - bind_le_wp_bind {α β : Type u} (x : m α) (f : α → m β) (post : β → Pred) (epost : EPred) : Lean.Order.PartialOrder.rel (wp x (fun (a : α) => wp (f a) post epost) epost) (wp (x >>= f) post epost)
Soundness of
bind: composing weakest preconditions is at least as strong as the weakest precondition of>>=.
Instances
A monadic WP interpretation is sourced from the monad's WPMonad instance. Low priority so a
program type with a bespoke WP instance (e.g. a non-monadic one) is preferred.
Rewriting the program of a weakest precondition along an equation x = y weakens it:
the precondition of y entails the precondition of x.
Derived WPMonad Lemmas #
One-directional consequences of the WPMonad axioms for pure, bind, map, and seq.
Soundness of Functor.map: mapping f over x preserves the WP.
Variant of map_le_wp_map with an explicit postcondition equality hypothesis.
Soundness of Seq.seq: sequencing f <*> x preserves the WP.
WPMonad Instances #
ExceptT's WP interpretation: lift the base interpretation by adding an exception
postcondition layer.
Equations
- Std.Internal.Do.ExceptT.wpInst = { wpTrans := fun (x : ExceptT ε m α) => (Std.Internal.Do.WP.wpTrans x.run).pushExcept, wp_trans_monotone := ⋯ }
Instances For
ExceptT lifts a WPMonad instance by adding an exception postcondition layer.
Equations
- Std.Internal.Do.ExceptT.instWPMonad = { toLawfulMonad := ⋯, toWP := fun (x : Type ?u.4) => Std.Internal.Do.ExceptT.wpInst, pure_le_wp_pure := ⋯, bind_le_wp_bind := ⋯ }
OptionT's WP interpretation: lift the base interpretation by adding a PUnit exception
postcondition layer.
Equations
- Std.Internal.Do.OptionT.wpInst = { wpTrans := fun (x : OptionT m α) => (Std.Internal.Do.WP.wpTrans x.run).pushOption, wp_trans_monotone := ⋯ }
Instances For
OptionT lifts a WPMonad instance by adding a PUnit exception postcondition layer.
Equations
- Std.Internal.Do.OptionT.instWPMonad = { toLawfulMonad := ⋯, toWP := fun (x : Type ?u.3) => Std.Internal.Do.OptionT.wpInst, pure_le_wp_pure := ⋯, bind_le_wp_bind := ⋯ }
StateT's WP interpretation: lift the base interpretation by adding a state argument.
Equations
- Std.Internal.Do.StateT.wpInst = { wpTrans := fun (x : StateT σ m α) => Std.Internal.Do.pushArg fun (x_1 : σ) => Std.Internal.Do.WP.wpTrans (x.run x_1), wp_trans_monotone := ⋯ }
Instances For
StateT lifts a WPMonad instance by adding a state argument.
Equations
- Std.Internal.Do.StateT.instWPMonad = { toLawfulMonad := ⋯, toWP := fun (x : Type ?u.4) => Std.Internal.Do.StateT.wpInst, pure_le_wp_pure := ⋯, bind_le_wp_bind := ⋯ }
ReaderT's WP interpretation: lift the base interpretation by adding a reader argument.
Equations
- One or more equations did not get rendered due to their size.
Instances For
ReaderT lifts a WPMonad instance by adding a reader argument.
Equations
- Std.Internal.Do.ReaderT.instWPMonad = { toLawfulMonad := ⋯, toWP := fun (x : Type ?u.4) => Std.Internal.Do.ReaderT.wpInst, pure_le_wp_pure := ⋯, bind_le_wp_bind := ⋯ }
Type Alias Instances #
WPMonad instances for concrete monads that are type aliases for transformer stacks.
Except ε is a WPMonad with Prop assertions and a single exception postcondition.
Equations
- Std.Internal.Do.Except.instWPMonad = { toLawfulMonad := ⋯, toWP := fun (x : Type ?u.1) => Std.Internal.Do.Except.wpInst, pure_le_wp_pure := ⋯, bind_le_wp_bind := ⋯ }
EStateM ε σ is a WPMonad combining state and exceptions.
Equations
- Std.Internal.Do.EStateM.instWPMonad = { toLawfulMonad := ⋯, toWP := fun (x : Type) => Std.Internal.Do.EStateM.wpInst, pure_le_wp_pure := ⋯, bind_le_wp_bind := ⋯ }
Soundness Lemmas #
These lemmas bridge wp reasoning to concrete program properties. Each one says:
if wp prog ... holds, then a property P holds of the program's result.
Soundness for EStateM: if wp prog P s holds, then P holds of (prog.run s).