Documentation

Loom.WP.Lemmas

Simp lemmas for weakest preconditions #

This module provides simp lemmas for simplifying weakest precondition expressions. Unlike Std.Do, we use direct function application wp x post epost without notation.

Some lemmas prove only one direction () instead of equality because our wp_bind axiom only provides one direction.

MonadReaderOf simp lemmas #

theorem Std.Do'.WP.read_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (post : ρρPred) (epost : EPred) :
Lean.Order.PartialOrder.rel (fun (r : ρ) => post r r) (wp MonadReaderOf.read post epost)
@[simp]
theorem Std.Do'.WP.adapt_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ ρ' α : Type u} {post : αρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ρρ') (x : ReaderT ρ' m α) :
wp (ReaderT.adapt f x) post epost = fun (r : ρ) => wp x (fun (a : α) (x : ρ') => post a r) epost (f r)

MonadStateOf simp lemmas #

theorem Std.Do'.WP.get_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (post : σσPred) (epost : EPred) :
Lean.Order.PartialOrder.rel (fun (s : σ) => post s s) (wp MonadStateOf.get post epost)
theorem Std.Do'.WP.set_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : σ) (post : PUnitσPred) (epost : EPred) :
Lean.Order.PartialOrder.rel (fun (x_1 : σ) => post PUnit.unit x) (wp (set x) post epost)
theorem Std.Do'.WP.modifyGet_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ α : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : σα × σ) (post : ασPred) (epost : EPred) :
Lean.Order.PartialOrder.rel (fun (s : σ) => post (f s).fst (f s).snd) (wp (MonadStateOf.modifyGet f) post epost)
@[simp]
theorem Std.Do'.WP.get_EStateM_wp {ε σ : Type u_1} {post : σσProp} {epost : εσProp} :
wp MonadStateOf.get post epost = fun (s : σ) => post s s
@[simp]
theorem Std.Do'.WP.set_EStateM_wp {σ ε : Type u_1} {post : PUnitσProp} {epost : εσProp} (x : σ) :
wp (set x) post epost = fun (x_1 : σ) => post PUnit.unit x
@[simp]
theorem Std.Do'.WP.modifyGet_EStateM_wp {σ α ε : Type u_1} {post : ασProp} {epost : εσProp} (f : σα × σ) :
wp (MonadStateOf.modifyGet f) post epost = fun (s : σ) => post (f s).fst (f s).snd
@[simp]
theorem Std.Do'.WP.modify_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} {post : PUnitσPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : σσ) :
wp (modify f) post epost = wp (MonadStateOf.modifyGet fun (s : σ) => (PUnit.unit, f s)) post epost
@[simp]
theorem Std.Do'.WP.getModify_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} {post : σσPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : σσ) :
wp (getModify f) post epost = wp (MonadStateOf.modifyGet fun (s : σ) => (s, f s)) post epost
@[simp]
theorem Std.Do'.WP.modify_EStateM_wp {σ ε : Type u_1} {post : PUnitσProp} {epost : εσProp} (f : σσ) :
wp (modify f) post epost = wp (MonadStateOf.modifyGet fun (s : σ) => (PUnit.unit, f s)) post epost
@[simp]
theorem Std.Do'.WP.getModify_EStateM_wp {σ ε : Type u_1} {post : σσProp} {epost : εσProp} (f : σσ) :
wp (getModify f) post epost = wp (MonadStateOf.modifyGet fun (s : σ) => (s, f s)) post epost

MonadExceptOf simp lemmas #

@[simp]
theorem Std.Do'.WP.throwThe_wp {m : Type u → Type v} {ε : Type u_1} {Pred : Type u_2} {EPred : Type u_3} {α : Type u} {post : αPred} {epost : EPred} [MonadExceptOf ε m] [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (err : ε) :
wp (throwThe ε err) post epost = wp (MonadExceptOf.throw err) post epost
@[simp]
theorem Std.Do'.WP.throw_Except_wp {ε : Type u_1} {α : Type u_2} {post : αProp} {epost : EPost⟨εProp} (e : ε) :
wp (MonadExceptOf.throw e) post epost = epost.head e
theorem Std.Do'.WP.throw_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ (εPred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (err : ε) :
@[simp]
theorem Std.Do'.WP.throw_EStateM_wp {ε σ α : Type u_1} {post : ασProp} {epost : εσProp} (e : ε) :
wp (MonadExceptOf.throw e) post epost = epost e
@[simp]
theorem Std.Do'.WP.throw_Option_wp {α : Type u_1} {post : αProp} {epost : Prop} (e : PUnit) :
wp (MonadExceptOf.throw e) post epost = epost
theorem Std.Do'.WP.throw_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (err : PUnit) :
@[simp]
theorem Std.Do'.WP.tryCatch_MonadExcept_wp {m : Type u → Type v} {ε : Type u_1} {Pred : Type u_2} {EPred : Type u_3} {α : Type u} {post : αPred} {epost : EPred} [MonadExceptOf ε m] [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) (h : εm α) :
wp (tryCatch x h) post epost = wp (MonadExceptOf.tryCatch x h) post epost
@[simp]
theorem Std.Do'.WP.tryCatchThe_wp {m : Type u → Type v} {ε : Type u_1} {Pred : Type u_2} {EPred : Type u_3} {α : Type u} {post : αPred} {epost : EPred} [MonadExceptOf ε m] [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) (h : εm α) :
wp (tryCatchThe ε x h) post epost = wp (MonadExceptOf.tryCatch x h) post epost
@[simp]
theorem Std.Do'.WP.tryCatch_Except_wp {ε : Type u_1} {α : Type u_2} {post : αProp} {epost : EPost⟨εProp} (x : Except ε α) (h : εExcept ε α) :
wp (MonadExceptOf.tryCatch x h) post epost = wp x post epost⟨fun (e : ε) => wp (h e) post epost
@[simp]
theorem ExceptT.run_tryCatch {m : Type u → Type v} {ε α : Type u} [Monad m] [LawfulMonad m] (x : ExceptT ε m α) (h : εExceptT ε m α) :
(tryCatch x h).run = do let rx.run match r with | Except.ok a => pure (Except.ok a) | Except.error e => (h e).run
theorem Std.Do'.WP.tryCatch_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ (εPred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : ExceptT ε m α) (h : εExceptT ε m α) :
Lean.Order.PartialOrder.rel (wp x post (EPost.cons.mk✝ (fun (e : ε) => wp (h e) post epost) epost.tail)) (wp (MonadExceptOf.tryCatch x h) post epost)
@[simp]
theorem Std.Do'.WP.tryCatch_Option_wp {α : Type u_1} {post : αProp} {epost : Prop} (x : Option α) (h : PUnitOption α) :
wp (MonadExceptOf.tryCatch x h) post epost = wp x post (wp (h PUnit.unit) post epost)
theorem Std.Do'.WP.tryCatch_EStateM_wp {ε σ α : Type u_1} {post : ασProp} {epost : εσProp} (x : EStateM ε σ α) (h : εEStateM ε σ α) :
wp (MonadExceptOf.tryCatch x h) post epost = fun (s : σ) => wp x post (fun (e : ε) (s' : σ) => wp (h e) post epost s') s
@[simp]
theorem Std.Do'.WP.tryCatch_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : OptionT m α) (h : PUnitOptionT m α) :
Lean.Order.PartialOrder.rel (wp x post (EPost.cons.mk✝ (wp (h PUnit.unit) post epost) epost.tail)) (wp (MonadExceptOf.tryCatch x h) post epost)

Additional state operation lemmas #

@[simp]
theorem Std.Do'.WP.getThe_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} {post : σσPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] :
wp (getThe σ) post epost = wp MonadStateOf.get post epost
@[simp]
theorem Std.Do'.WP.modifyThe_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} {post : PUnitσPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : σσ) :
wp (modifyThe σ f) post epost = wp (MonadStateOf.modifyGet fun (s : σ) => (PUnit.unit, f s)) post epost
@[simp]
theorem Std.Do'.WP.modifyGetThe_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ α : Type u} {post : ασPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : σα × σ) :
wp (modifyGetThe σ f) post epost = wp (MonadStateOf.modifyGet f) post epost
@[simp]
theorem Std.Do'.WP.get_MonadState_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} {post : σPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [MonadStateOf σ m] :
wp get post epost = wp MonadStateOf.get post epost
@[simp]
theorem Std.Do'.WP.set_MonadState_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} {post : PUnitPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [MonadStateOf σ m] (x : σ) :
wp (MonadState.set x) post epost = wp (set x) post epost
@[simp]
theorem Std.Do'.WP.modifyGet_MonadState_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ α : Type u} {post : αPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [MonadStateOf σ m] (f : σα × σ) :
wp (modifyGet f) post epost = wp (MonadStateOf.modifyGet f) post epost
@[simp]
theorem Std.Do'.WP.read_MonadReader_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ : Type u} {post : ρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [MonadReaderOf ρ m] :
wp read post epost = wp MonadReaderOf.read post epost
@[simp]
theorem Std.Do'.WP.readThe_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ : Type u} {post : ρρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] :
wp (readThe ρ) post epost = wp MonadReaderOf.read post epost

MonadLift simp lemmas #

theorem Std.Do'.WP.monadLift_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α σ : Type u} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) (post : ασPred) :
Lean.Order.PartialOrder.rel (fun (s : σ) => wp x (fun (a : α) => post a s) epost) (wp (MonadLift.monadLift x) post epost)
@[simp]
theorem Std.Do'.WP.monadLift_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α ρ : Type u} {post : αρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) :
wp (MonadLift.monadLift x) post epost = fun (r : ρ) => wp x (fun (a : α) => post a r) epost
theorem Std.Do'.WP.monadLift_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α ε : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Lean.Order.PartialOrder.rel (wp x post epost.tail) (wp (MonadLift.monadLift x) post epost)
@[simp]
theorem Std.Do'.WP.lift_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α σ : Type u} {post : ασPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) :
wp (StateT.lift x) post epost = wp (MonadLift.monadLift x) post epost
@[simp]
theorem Std.Do'.WP.lift_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α ε : Type u} {post : αPred} {epost : EPost.cons✝ (εPred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) :
wp (ExceptT.lift x) post epost = wp (MonadLift.monadLift x) post epost
@[simp]
theorem Std.Do'.WP.monadLift_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) :
Lean.Order.PartialOrder.rel (wp x post epost.tail) (wp (MonadLift.monadLift x) post epost)
@[simp]
theorem Std.Do'.WP.lift_OptionT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [Assertion (EPost.cons✝ Pred EPred)] [WP (OptionT m) Pred (EPost.cons✝ Pred EPred)] (x : m α) :
wp (OptionT.lift x) post epost = wp (MonadLift.monadLift x) post epost

MonadFunctor simp lemmas #

@[simp]
theorem Std.Do'.WP.monadMap_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : {β : Type u} → m βm β) {α : Type u} (x : StateT σ m α) (post : ασPred) (epost : EPred) :
wp (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost = fun (s : σ) => wp (f (x.run s)) (fun (x : α × σ) => match x with | (a, s') => post a s') epost
@[simp]
theorem Std.Do'.WP.monadMap_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : {β : Type u} → m βm β) {α : Type u} (x : ReaderT ρ m α) (post : αρPred) (epost : EPred) :
wp (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost = fun (r : ρ) => wp (f (x.run r)) (fun (a : α) => post a r) epost
@[simp]
theorem Std.Do'.WP.monadMap_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : {β : Type u} → m βm β) {α : Type u} (x : ExceptT ε m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
wp (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost = wp (f x.run) (EPost.cons.pushExcept post epost) epost.tail
@[simp]
theorem Std.Do'.WP.monadMap_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : {β : Type u} → m βm β) {α : Type u} (x : OptionT m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
wp (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost = wp (f x.run) (EPost.cons.pushOption post epost) epost.tail
@[simp]
theorem Std.Do'.WP.withReader_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ α : Type u} {post : αρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ρρ) (x : ReaderT ρ m α) :
wp (MonadWithReaderOf.withReader f x) post epost = fun (r : ρ) => wp x (fun (a : α) (x : ρ) => post a r) epost (f r)
@[simp]
theorem Std.Do'.WP.withReader_MonadWithReader_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ α : Type u} {post : αPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [MonadWithReaderOf ρ m] (f : ρρ) (x : m α) :
wp (withReader f x) post epost = wp (MonadWithReaderOf.withReader f x) post epost
@[simp]
theorem Std.Do'.WP.withTheReader_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ α : Type u} {post : αρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ρρ) (x : ReaderT ρ m α) :
wp (withTheReader ρ f x) post epost = wp (MonadWithReaderOf.withReader f x) post epost

Transformer adapt lemmas #

theorem Std.Do'.WP.adapt_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε ε' α : Type u} {post : αPred} {epost : EPost.cons✝ (ε'Pred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : εε') (x : ExceptT ε m α) :
Lean.Order.PartialOrder.rel (wp x post (EPost.cons.mk✝ (fun (e : ε) => epost.head (f e)) epost.tail)) (wp (ExceptT.adapt f x) post epost)
@[simp]
theorem Std.Do'.WP.adaptExcept_EStateM_wp {ε ε' σ α : Type u_1} {post : ασProp} {epost : ε'σProp} (f : εε') (x : EStateM ε σ α) :
wp (EStateM.adaptExcept f x) post epost = wp x post fun (e : ε) => epost (f e)

MonadControl simp lemmas #

@[simp]
theorem Std.Do'.WP.liftWith_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {σ α : Type u} {post : ασPred} {epost : EPred} {s : σ} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ({β : Type u} → StateT σ m βm (β × σ))m α) :
wp (MonadControl.liftWith f) post epost s = wp ((fun (a : α) => (a, s)) <$> f fun {β : Type u} (x : StateT σ m β) => x.run s) (fun (x : α × σ) => match x with | (a, s) => post a s) epost
@[simp]
theorem Std.Do'.WP.liftWith_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ρ α : Type u} {post : αρPred} {epost : EPred} {r : ρ} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ({β : Type u} → ReaderT ρ m βm β)m α) :
wp (MonadControl.liftWith f) post epost r = wp (f fun {β : Type u} (x : ReaderT ρ m β) => x.run r) (fun (a : α) => post a r) epost
@[simp]
theorem ExceptT.run_liftM {m : Type u → Type v} {α ε : Type u} [Monad m] [LawfulMonad m] (x : m α) :
@[simp]
theorem Std.Do'.WP.liftWith_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ (εPred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ({β : Type u} → ExceptT ε m βm (Except ε β))m α) :
wp (MonadControl.liftWith f) post epost = wp (Except.ok <$> f fun {β : Type u} (x : ExceptT ε m β) => x.run) (EPost.cons.pushExcept post epost) epost.tail
@[simp]
theorem Std.Do'.WP.liftWith_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ({β : Type u} → OptionT m βm (Option β))m α) :
Lean.Order.PartialOrder.rel (wp (f fun {β : Type u} (x : OptionT m β) => x.run) post epost.tail) (wp (MonadControl.liftWith f) post epost)
theorem Std.Do'.WP.restoreM_StateT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α σ : Type u} {epost : EPred} {post : ασPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m (α × σ)) :
Lean.Order.PartialOrder.rel (fun (x_1 : σ) => wp x (fun (x : α × σ) => match x with | (a, s) => post a s) epost) (wp (MonadControl.restoreM x) post epost)
@[simp]
theorem Std.Do'.WP.restoreM_ReaderT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α ρ : Type u} {post : αρPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m α) :
wp (MonadControl.restoreM x) post epost = fun (r : ρ) => wp x (fun (a : α) => post a r) epost
@[simp]
theorem Std.Do'.WP.restoreM_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ (εPred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m (Except ε α)) :
wp (MonadControl.restoreM x) post epost = wp x (EPost.cons.pushExcept post epost) epost.tail
@[simp]
theorem Std.Do'.WP.restoreM_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : m (Option α)) :
wp (MonadControl.restoreM x) post epost = wp x (EPost.cons.pushOption post epost) epost.tail
@[simp]
theorem Std.Do'.WP.controlAt_wp {m : Type u → Type v} {n : Type u → Type u_1} {Pred : Type u_2} {EPred : Type u_3} {α : Type u} {post : αPred} {epost : EPred} [Bind n] [Monad n] [Monad m] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [MonadControlT m n] (f : ({β : Type u} → n βm (stM m n β))m (stM m n α)) :
wp (controlAt m f) post epost = wp (liftWith f >>= restoreM) post epost
@[simp]
theorem Std.Do'.WP.control_wp {m : Type u → Type v} {n : Type u → Type u_1} {Pred : Type u_2} {EPred : Type u_3} {α : Type u} {post : αPred} {epost : EPred} [Bind n] [Monad n] [Monad m] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [MonadControlT m n] (f : ({β : Type u} → n βm (stM m n β))m (stM m n α)) :
wp (control f) post epost = wp (liftWith f >>= restoreM) post epost

Transitive lift/map simp lemmas #

@[simp]
theorem Std.Do'.WP.monadLift_trans_wp {m : Type u → Type v} {o : Type u → Type u_1} {Pred : Type u_2} {EPred : Type u_3} {n : Type u → Type u_4} {α : Type u} {post : αPred} {epost : EPred} [Monad o] [Assertion Pred] [Assertion EPred] [WP o Pred EPred] [MonadLift n o] [MonadLiftT m n] (x : m α) :
wp (monadLift x) post epost = wp (MonadLift.monadLift (monadLift x)) post epost
@[simp]
theorem Std.Do'.WP.monadLift_refl_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α : Type u} {post : αPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [Pure m] (x : m α) :
wp (monadLift x) post epost = wp x post epost
@[simp]
theorem Std.Do'.WP.monadMap_trans_wp {m : Type u → Type v} {o : Type u → Type u_1} {Pred : Type u_2} {EPred : Type u_3} {n : Type u → Type u_4} {α : Type u} {f : {β : Type u} → m βm β} {post : αPred} {epost : EPred} [Monad o] [Assertion Pred] [Assertion EPred] [WP o Pred EPred] [MonadFunctor n o] [MonadFunctorT m n] (x : o α) :
wp (monadMap f x) post epost = wp (MonadFunctor.monadMap (fun {β : Type u} => monadMap fun {β : Type u} => f) x) post epost
@[simp]
theorem Std.Do'.WP.monadMap_refl_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α : Type u} {f : {β : Type u} → m βm β} {post : αPred} {epost : EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [Pure m] (x : m α) :
wp (monadMap f x) post epost = wp (f x) post epost

Lifted state/reader/except operations #

@[simp]
theorem Std.Do'.WP.get_MonadStateOf_lift_wp {m : Type u → Type v} {σ : Type u} {n : Type u → Type u_1} {Pred : Type u_2} {EPred' : Type u_3} {post : σPred} {epost : EPred'} [MonadStateOf σ m] [MonadLift m n] [Monad m] [Monad n] [Assertion Pred] [Assertion EPred'] [WP n Pred EPred'] :
@[simp]
theorem Std.Do'.WP.set_MonadStateOf_lift_wp {m : Type u → Type v} {σ : Type u} {n : Type u → Type u_1} {Pred : Type u_2} {EPred' : Type u_3} {post : PUnitPred} {epost : EPred'} [MonadStateOf σ m] [MonadLift m n] [Monad m] [Monad n] [Assertion Pred] [Assertion EPred'] [WP n Pred EPred'] (x : σ) :
wp (set x) post epost = wp (MonadLift.monadLift (set x)) post epost
@[simp]
theorem Std.Do'.WP.modifyGet_MonadStateOf_lift_wp {m : Type u → Type v} {σ : Type u} {n : Type u → Type u_1} {Pred : Type u_2} {EPred' : Type u_3} {α : Type u} {post : αPred} {epost : EPred'} [MonadStateOf σ m] [MonadLift m n] [Monad m] [Monad n] [Assertion Pred] [Assertion EPred'] [WP n Pred EPred'] (f : σα × σ) :
wp (MonadStateOf.modifyGet f) post epost = wp (MonadLift.monadLift (modifyGet f)) post epost
@[simp]
theorem Std.Do'.WP.read_MonadReaderOf_lift_wp {m : Type u → Type v} {ρ : Type u} {n : Type u → Type u_1} {Pred : Type u_2} {EPred' : Type u_3} {post : ρPred} {epost : EPred'} [MonadReaderOf ρ m] [MonadLift m n] [Monad m] [Monad n] [Assertion Pred] [Assertion EPred'] [WP n Pred EPred'] :
@[simp]
theorem Std.Do'.WP.throw_lift_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred' : Type u_2} {ε ε' α : Type u} {post : αPred} {epost : EPost.cons✝ (ε'Pred) EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (err : ε) :
wp (MonadExceptOf.throw err) post epost = wp (MonadExceptOf.throw err) (EPost.cons.pushExcept post epost) epost.tail
@[simp]
theorem Std.Do'.WP.throw_lift_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred' : Type u_1} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (err : ε) :
wp (MonadExceptOf.throw err) post epost = wp (MonadExceptOf.throw err) (EPost.cons.pushOption post epost) epost.tail
@[simp]
theorem Std.Do'.WP.tryCatch_lift_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred' : Type u_2} {ε ε' α : Type u} {post : αPred} {epost : EPost.cons✝ (ε'Pred) EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (x : ExceptT ε' m α) (h : εExceptT ε' m α) :
@[simp]
theorem Std.Do'.WP.tryCatch_lift_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred' : Type u_1} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (x : OptionT m α) (h : εOptionT m α) :
@[simp]
theorem Std.Do'.WP.throw_ReaderT_lift_wp {m : Type u → Type v} {Pred : Type u_1} {EPred' : Type u_2} {ε : Type u_3} {ρ α : Type u} {post : αρPred} {epost : EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (err : ε) :
@[simp]
theorem Std.Do'.WP.throw_StateT_lift_wp {m : Type u → Type v} {Pred : Type u_1} {EPred' : Type u_2} {ε : Type u_3} {σ α : Type u} {post : ασPred} {epost : EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (err : ε) :
@[simp]
theorem Std.Do'.WP.tryCatch_ReaderT_lift_wp {m : Type u → Type v} {Pred : Type u_1} {EPred' : Type u_2} {ε : Type u_3} {ρ α : Type u} {post : αρPred} {epost : EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (x : ReaderT ρ m α) (h : εReaderT ρ m α) :
wp (MonadExceptOf.tryCatch x h) post epost = fun (r : ρ) => wp (MonadExceptOf.tryCatch (x.run r) fun (e : ε) => (h e).run r) (fun (a : α) => post a r) epost
@[simp]
theorem Std.Do'.WP.tryCatch_StateT_lift_wp {m : Type u → Type v} {Pred : Type u_1} {EPred' : Type u_2} {ε : Type u_3} {σ α : Type u} {post : ασPred} {epost : EPred'} [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred'] [WP m Pred EPred'] [MonadExceptOf ε m] (x : StateT σ m α) (h : εStateT σ m α) :
wp (MonadExceptOf.tryCatch x h) post epost = fun (s : σ) => wp (MonadExceptOf.tryCatch (x.run s) fun (e : ε) => (h e).run s) (fun (x : α × σ) => match x with | (a, s') => post a s') epost

Transitive MonadControl lemmas #

@[simp]
theorem Std.Do'.WP.liftWith_trans_wp {m : Type u → Type v} {o : Type u → Type u_1} {Pred : Type u_2} {EPred : Type u_3} {n : Type u → Type u_4} {α : Type u} {post : αPred} {epost : EPred} [Monad o] [Assertion Pred] [Assertion EPred] [WP o Pred EPred] [MonadControl n o] [MonadControlT m n] (f : ({β : Type u} → o βm (stM m o β))m α) :
wp (liftWith f) post epost = wp (MonadControl.liftWith fun (x₂ : {β : Type u} → o βn (MonadControl.stM n o β)) => liftWith fun (x₁ : {β : Type u} → n βm (stM m n β)) => f fun {β : Type u} => x₁ x₂) post epost
@[simp]
theorem Std.Do'.WP.liftWith_refl_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α : Type u} {post : αPred} {epost : EPred} [Pure m] [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (f : ({β : Type u} → m βm β)m α) :
wp (liftWith f) post epost = wp (f fun {β : Type u} (x : m β) => x) post epost
@[simp]
theorem Std.Do'.WP.restoreM_trans_wp {m : Type u → Type v} {o : Type u → Type u_1} {Pred : Type u_2} {EPred : Type u_3} {n : Type u → Type u_4} {α : Type u} {post : αPred} {epost : EPred} [Monad o] [Assertion Pred] [Assertion EPred] [WP o Pred EPred] [MonadControl n o] [MonadControlT m n] (x : stM m o α) :
wp (restoreM x) post epost = wp (MonadControl.restoreM (restoreM x)) post epost
@[simp]
theorem Std.Do'.WP.restoreM_refl_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {α : Type u} {post : αPred} {epost : EPred} [Pure m] [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : stM m m α) :
wp (restoreM x) post epost = wp (pure x) post epost

OrElse simp lemmas #

@[simp]
theorem Std.Do'.WP.orElse_Except_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε : Type u_3} {α : Type u_4} {post : αProp} {epost : EPost⟨εProp} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : Except ε α) (h : UnitExcept ε α) :
wp (OrElse.orElse x h) post epost = wp x post epost⟨fun (x : ε) => wp (h ()) post epost
@[simp]
theorem ExceptT.run_orElse {m : Type u → Type v} {ε α : Type u} [Monad m] [LawfulMonad m] (x : ExceptT ε m α) (h : UnitExceptT ε m α) :
(OrElse.orElse x h).run = do let rx.run match r with | Except.ok a => pure (Except.ok a) | Except.error a => (h ()).run
theorem Std.Do'.WP.orElse_ExceptT_wp {m : Type u → Type v} {Pred : Type u_1} {EPred : Type u_2} {ε α : Type u} {post : αPred} {epost : EPost.cons✝ (εPred) EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : ExceptT ε m α) (h : UnitExceptT ε m α) :
Lean.Order.PartialOrder.rel (wp x post (EPost.cons.mk✝ (fun (x : ε) => wp (h ()) post epost) epost.tail)) (wp (OrElse.orElse x h) post epost)
@[simp]
theorem Std.Do'.WP.orElse_Option_wp {α : Type u_1} (x : Option α) (h : UnitOption α) (post : αProp) (epost : Prop) :
wp (OrElse.orElse x h) post epost = wp x post (wp (h ()) post epost)
@[simp]
theorem Std.Do'.WP.orElse_EStateM_wp {ε σ α : Type u_1} {post : ασProp} {epost : εσProp} (x : EStateM ε σ α) (h : UnitEStateM ε σ α) :
wp (OrElse.orElse x h) post epost = fun (s : σ) => wp x post (fun (x : ε) (s' : σ) => wp (h ()) post epost s') s
@[simp]
theorem Std.Do'.WP.orElse_OptionT_wp {m : Type u → Type v} {Pred : Type u} {EPred : Type u_1} {α : Type u} {post : αPred} {epost : EPost.cons✝ Pred EPred} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] (x : OptionT m α) (h : UnitOptionT m α) :
Lean.Order.PartialOrder.rel (wp x post (EPost.cons.mk✝ (wp (h ()) post epost) epost.tail)) (wp (OrElse.orElse x h) post epost)