Simp lemmas for working with weakest preconditions #
Many weakest preconditions are so simple that we can compute them directly or
express them in terms of "simpler" weakest preconditions.
This module provides simp lemmas targeting expressions of the form wp⟦x⟧ Q
and rewrites them to expressions of simpler weakest preconditions.
WP
#
WPMonad
#
MonadLift
#
The definitions that follow interpret liftM
and thus instances of, e.g., MonadStateOf
.
@[simp]
theorem
Std.Do.WP.lift_StateT
{m : Type → Type u}
{ps : PostShape}
{α σ : Type}
{Q : PostCond α (PostShape.arg σ ps)}
[WP m ps]
[Monad m]
(x : m α)
:
@[simp]
theorem
Std.Do.WP.lift_ExceptT
{m : Type → Type u}
{ps : PostShape}
{α ε : Type}
{Q : PostCond α (PostShape.except ε ps)}
[WP m ps]
[Monad m]
(x : m α)
:
@[simp]
theorem
Std.Do.WP.readThe
{m : Type → Type u}
{ps : PostShape}
{ρ : Type}
{Q : PostCond ρ ps}
[MonadReaderOf ρ m]
[WP m ps]
:
@[simp]
theorem
Std.Do.WP.modifyGetThe_MonadStateOf
{m : Type → Type u}
{ps : PostShape}
{σ α : Type}
{Q : PostCond α ps}
[WP m ps]
[MonadStateOf σ m]
(f : σ → α × σ)
:
@[simp]
theorem
Std.Do.WP.read_ReaderT
{m : Type → Type u}
{ps : PostShape}
{ρ : Type}
{Q : PostCond ρ (PostShape.arg ρ ps)}
[Monad m]
[WPMonad m ps]
:
@[simp]
theorem
Std.Do.WP.get_StateT
{m : Type → Type u}
{ps : PostShape}
{σ : Type}
{Q : PostCond σ (PostShape.arg σ ps)}
[Monad m]
[WPMonad m ps]
:
@[simp]
theorem
Std.Do.WP.get_EStateM
{ε σ : Type}
{Q : PostCond σ (PostShape.except ε (PostShape.arg σ PostShape.pure))}
:
@[simp]
theorem
Std.Do.WP.set_EStateM
{σ ε : Type}
{Q : PostCond PUnit (PostShape.except ε (PostShape.arg σ PostShape.pure))}
(x : σ)
:
@[simp]
theorem
Std.Do.WP.modifyGet_EStateM
{σ α ε : Type}
{Q : PostCond α (PostShape.except ε (PostShape.arg σ PostShape.pure))}
(f : σ → α × σ)
:
MonadFunctor
#
The definitions that follow interpret monadMap
and thus instances of, e.g., MonadReaderWithOf
.
@[simp]
theorem
Std.Do.WP.monadMap_trans
{m : Type → Type u}
{ps : PostShape}
{o : Type → Type u_1}
{n : Type → Type u_2}
{α : Type}
{f : {β : Type} → m β → m β}
{x : o α}
{Q : PostCond α ps}
[WP o ps]
[MonadFunctor n o]
[MonadFunctorT m n]
:
@[simp]
theorem
Std.Do.WP.withReader_MonadWithReaderOf
{m : Type → Type u}
{ρ : Type}
{n : Type → Type u}
{nsh : PostShape}
{α : Type}
{Q : PostCond α nsh}
[MonadWithReaderOf ρ m]
[WP n nsh]
[MonadFunctor m n]
(f : ρ → ρ)
(x : n α)
:
wp⟦MonadWithReaderOf.withReader f x⟧ Q = wp⟦MonadFunctor.monadMap (fun {β : Type} => MonadWithReaderOf.withReader f) x⟧ Q
@[simp]
theorem
Std.Do.WP.withReader_MonadWithReader
{m : Type → Type u}
{ps : PostShape}
{ρ α : Type}
{Q : PostCond α ps}
[MonadWithReaderOf ρ m]
[WP m ps]
(f : ρ → ρ)
(x : m α)
:
@[simp]
theorem
Std.Do.WP.withTheReader
{m : Type → Type u}
{ps : PostShape}
{ρ α : Type}
{Q : PostCond α ps}
[MonadWithReaderOf ρ m]
[WP m ps]
(f : ρ → ρ)
(x : m α)
:
MonadExceptOf
#
The definitions that follow interpret throw
, throwThe
, tryCatch
, etc.
Since MonadExceptOf
cannot be lifted through MonadLift
or MonadFunctor
, there is one lemma per
MonadExceptOf
operation and instance to lift through; the classic m*n instances problem.
@[simp]
theorem
Std.Do.WP.throwThe
{m : Type → Type u}
{ps : PostShape}
{ε : Type u_1}
{α : Type}
{e : ε}
{Q : PostCond α ps}
[MonadExceptOf ε m]
[WP m ps]
:
@[simp]
theorem
Std.Do.WP.throw_Except
{ε α : Type}
{e : ε}
{Q : PostCond α (PostShape.except ε PostShape.pure)}
:
@[simp]
theorem
Std.Do.WP.throw_EStateM
{ε σ α : Type}
{e : ε}
{Q : PostCond α (PostShape.except ε (PostShape.arg σ PostShape.pure))}
:
@[simp]
theorem
Std.Do.WP.throw_ReaderT
{m : Type → Type u}
{sh : PostShape}
{ε : Type u_1}
{ρ α : Type}
{e : ε}
{Q : PostCond α (PostShape.arg ρ sh)}
[WP m sh]
[Monad m]
[MonadExceptOf ε m]
:
@[simp]
theorem
Std.Do.WP.throw_StateT
{m : Type → Type u}
{sh : PostShape}
{ε : Type u_1}
{ρ α : Type}
{e : ε}
{Q : PostCond α (PostShape.arg ρ sh)}
[WP m sh]
[Monad m]
[MonadExceptOf ε m]
:
@[simp]
theorem
Std.Do.WP.throw_lift_ExceptT
{m : Type → Type u}
{sh : PostShape}
{ε ε' α : Type}
{e : ε}
{Q : PostCond α (PostShape.except ε' sh)}
[WP m sh]
[Monad m]
[MonadExceptOf ε m]
:
@[simp]
theorem
Std.Do.WP.tryCatchThe
{m : Type → Type u}
{ps : PostShape}
{ε : Type u_1}
{α : Type}
{x : m α}
{h : ε → m α}
{Q : PostCond α ps}
[MonadExceptOf ε m]
[WP m ps]
:
@[simp]
theorem
Std.Do.WP.tryCatch_EStateM
{ε σ δ α : Type}
{x : EStateM ε σ α}
{h : ε → EStateM ε σ α}
{Q : PostCond α (PostShape.except ε (PostShape.arg σ PostShape.pure))}
[EStateM.Backtrackable δ σ]
:
@[simp]
theorem
Std.Do.WP.tryCatch_ReaderT
{m : Type → Type u}
{sh : PostShape}
{ε : Type u_1}
{ρ α : Type}
{x : ReaderT ρ m α}
{h : ε → ReaderT ρ m α}
{Q : PostCond α (PostShape.arg ρ sh)}
[WP m sh]
[Monad m]
[MonadExceptOf ε m]
:
@[simp]
theorem
Std.Do.WP.tryCatch_StateT
{m : Type → Type u}
{sh : PostShape}
{ε : Type u_1}
{σ α : Type}
{x : StateT σ m α}
{h : ε → StateT σ m α}
{Q : PostCond α (PostShape.arg σ sh)}
[WP m sh]
[Monad m]
[MonadExceptOf ε m]
:
@[simp]
theorem
Std.Do.WP.tryCatch_lift_ExceptT
{m : Type → Type u}
{sh : PostShape}
{ε ε' α : Type}
{x : ExceptT ε' m α}
{h : ε → ExceptT ε' m α}
{Q : PostCond α (PostShape.except ε' sh)}
[WP m sh]
[Monad m]
[MonadExceptOf ε m]
: