Documentation

Std.WP.Triple.SpecLemmas

Hoare triple specifications for select functions #

This module contains Hoare triple specifications for some functions in Core. The specifications follow the Triple x pre post epost argument order, program first.

Monad #

theorem Std.WP.Spec.pure {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} (a : α) :
⦃ post a ⦄ Pure.pure a ⦃ post; epost ⦄
theorem Std.WP.Spec.bind {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α β : Type u} {post : β → Pred} {epost : EPred} (x : m α) (f : α → m β) :
⦃ wp x (fun (a : α) => binderNameHint a f (wp (f a) post epost)) epost ⦄ x >>= f ⦃ post; epost ⦄
theorem Std.WP.Spec.map {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α β : Type u} {post : β → Pred} {epost : EPred} (f : α → β) (x : m α) :
⦃ wp x (fun (a : α) => post (f a)) epost ⦄ f <$> x ⦃ post; epost ⦄
theorem Std.WP.Spec.seq {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α β : Type u} {post : β → Pred} {epost : EPred} (x : m (α → β)) (y : m α) :
⦃ wp x (fun (f : α → β) => wp y (fun (a : α) => post (f a)) epost) epost ⦄ x <*> y ⦃ post; epost ⦄

MonadLift #

theorem Std.WP.Spec.monadLift_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α σ : Type u} {epost : EPred} (x : m α) (post : α → σ → Pred) :
⦃ fun (s : σ) => wp x (fun (a : α) => post a s) epost ⦄ MonadLift.monadLift x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadLift_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α ρ : Type u} {epost : EPred} (x : m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp x (fun (a : α) => post a r) epost ⦄ MonadLift.monadLift x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadLift_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α ε : Type u} (x : m α) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp x post epost.snd ⦄ MonadLift.monadLift x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadLift_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (x : m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp x post epost.snd ⦄ MonadLift.monadLift x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadLift_Id {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} (x : Id α) :
⦃ post x.run ⦄ monadLift x ⦃ post; epost ⦄

MonadLiftT #

theorem Std.WP.Spec.UnfoldLift.monadLift_trans {m : Type u → Type v} {n : Type u → Type u_1} {o : Type u → Type u_2} {α : Type u} [MonadLift n o] [MonadLiftT m n] (x : m α) :
theorem Std.WP.Spec.UnfoldLift.monadLift_refl {m : Type u → Type v} {α : Type u} (x : m α) :

MonadFunctor #

theorem Std.WP.Spec.monadMap_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {σ : Type u} {epost : EPred} (f : {β : Type u} → m β → m β) {α : Type u} (x : StateT σ m α) (post : α → σ → Pred) :
⦃ fun (s : σ) => wp (f (x.run s)) (fun (x : α × σ) => match x with | (a, s') => post a s') epost ⦄ MonadFunctor.monadMap (fun {β : Type u} => f) x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadMap_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ : Type u} {epost : EPred} (f : {β : Type u} → m β → m β) {α : Type u} (x : ReaderT ρ m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp (f (x.run r)) (fun (a : α) => post a r) epost ⦄ MonadFunctor.monadMap (fun {β : Type u} => f) x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadMap_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u} (f : {β : Type u} → m β → m β) {α : Type u} (x : ExceptT ε m α) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp (f x.run) (Lean.Order.pushExcept post epost.fst) epost.snd ⦄ MonadFunctor.monadMap (fun {β : Type u} => f) x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadMap_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] (f : {β : Type u} → m β → m β) {α : Type u} (x : OptionT m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp (f x.run) (Lean.Order.pushOption post epost.fst) epost.snd ⦄ MonadFunctor.monadMap (fun {β : Type u} => f) x ⦃ post; epost ⦄
theorem Std.WP.Spec.monadMap_refl {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {f : {β : Type u} → m β → m β} {post : α → Pred} {epost : EPred} (x : m α) :
⦃ wp (f x) post epost ⦄ monadMap f x ⦃ post; epost ⦄

MonadControl #

theorem Std.WP.Spec.liftWith_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {σ α : Type u} {epost : EPred} (f : ({β : Type u} → StateT σ m β → m (β × σ)) → m α) (post : α → σ → Pred) :
⦃ fun (s : σ) => wp (f fun {β : Type u} (x : StateT σ m β) => x.run s) (fun (a : α) => post a s) epost ⦄ MonadControl.liftWith f ⦃ post; epost ⦄
theorem Std.WP.Spec.liftWith_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ α : Type u} {epost : EPred} (f : ({β : Type u} → ReaderT ρ m β → m β) → m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp (f fun {β : Type u} (x : ReaderT ρ m β) => x.run r) (fun (a : α) => post a r) epost ⦄ MonadControl.liftWith f ⦃ post; epost ⦄
theorem Std.WP.Spec.liftWith_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} (f : ({β : Type u} → ExceptT ε m β → m (Except ε β)) → m α) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp (f fun {β : Type u} (x : ExceptT ε m β) => x.run) post epost.snd ⦄ MonadControl.liftWith f ⦃ post; epost ⦄
theorem Std.WP.Spec.liftWith_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (f : ({β : Type u} → OptionT m β → m (Option β)) → m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp (f fun {β : Type u} (x : OptionT m β) => x.run) post epost.snd ⦄ MonadControl.liftWith f ⦃ post; epost ⦄
theorem Std.WP.Spec.restoreM_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α σ : Type u} {epost : EPred} (x : m (α × σ)) (post : α → σ → Pred) :
⦃ fun (x_1 : σ) => wp x (fun (x : α × σ) => match x with | (a, s) => post a s) epost ⦄ MonadControl.restoreM x ⦃ post; epost ⦄
theorem Std.WP.Spec.restoreM_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α ρ : Type u} {epost : EPred} (x : m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp x (fun (a : α) => post a r) epost ⦄ MonadControl.restoreM x ⦃ post; epost ⦄
theorem Std.WP.Spec.restoreM_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} (x : m (Except ε α)) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp x (Lean.Order.pushExcept post epost.fst) epost.snd ⦄ MonadControl.restoreM x ⦃ post; epost ⦄
theorem Std.WP.Spec.restoreM_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (x : m (Option α)) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp x (Lean.Order.pushOption post epost.fst) epost.snd ⦄ MonadControl.restoreM x ⦃ post; epost ⦄

MonadControlT #

theorem Std.WP.Spec.liftWith_refl {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} (f : ({β : Type u} → m β → m β) → m α) :
⦃ wp (f fun {β : Type u} (x : m β) => x) post epost ⦄ liftWith f ⦃ post; epost ⦄
theorem Std.WP.Spec.restoreM_refl {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} (x : stM m m α) :
⦃ wp (Pure.pure x) post epost ⦄ restoreM x ⦃ post; epost ⦄

ReaderT #

theorem Std.WP.Spec.read_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ : Type u} {epost : EPred} (post : ρ → ρ → Pred) :
⦃ fun (r : ρ) => post r r ⦄ MonadReaderOf.read ⦃ post; epost ⦄
theorem Std.WP.Spec.withReader_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ α : Type u} {epost : EPred} (f : ρ → ρ) (x : ReaderT ρ m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp x (fun (a : α) (x : ρ) => post a r) epost (f r) ⦄ MonadWithReaderOf.withReader f x ⦃ post; epost ⦄
theorem Std.WP.Spec.adapt_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ ρ' α : Type u} {epost : EPred} (f : ρ → ρ') (x : ReaderT ρ' m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp x (fun (a : α) (x : ρ') => post a r) epost (f r) ⦄ ReaderT.adapt f x ⦃ post; epost ⦄

StateT #

theorem Std.WP.Spec.get_StateT {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {epost : EPred} {σ : Type u} (post : σ → σ → Pred) :
⦃ fun (s : σ) => post s s ⦄ MonadStateOf.get ⦃ post; epost ⦄
theorem Std.WP.Spec.set_StateT {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {epost : EPred} {σ : Type u} (s : σ) (post : PUnit → σ → Pred) :
⦃ fun (x : σ) => post PUnit.unit s ⦄ set s ⦃ post; epost ⦄
theorem Std.WP.Spec.modifyGet_StateT {m : Type u → Type v} [Monad m] {Pred : Type w} {EPred : Type w'} [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {epost : EPred} {σ α : Type u} (f : σ → α × σ) (post : α → σ → Pred) :
⦃ fun (s : σ) => post (f s).fst (f s).snd ⦄ MonadStateOf.modifyGet f ⦃ post; epost ⦄

Lifting MonadStateOf #

theorem Std.WP.Spec.UnfoldLift.set {m : Type u → Type v} {n : Type u → Type u_1} {σ : Type u} [MonadLift m n] [MonadStateOf σ m] (s : σ) :
theorem Std.WP.Spec.UnfoldLift.modifyGet {m : Type u → Type v} {n : Type u → Type u_1} {σ α : Type u} [MonadLift m n] [MonadStateOf σ m] (f : σ → α × σ) :

Lifting MonadReaderOf #

ExceptT #

theorem Std.WP.Spec.run_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} (x : ExceptT ε m α) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp x post epost ⦄ x.run ⦃ Lean.Order.pushExcept post epost.fst; epost.snd ⦄
theorem Std.WP.Spec.throw_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} (err : ε) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ epost.fst err ⦄ MonadExceptOf.throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} (x : ExceptT ε m α) (h : ε → ExceptT ε m α) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp x post (fun (e : ε) => wp (h e) post epost, epost.snd) ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.orElse_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} (x : ExceptT ε m α) (h : Unit → ExceptT ε m α) (post : α → Pred) (epost : (ε → Pred) × EPred) :
⦃ wp x post (fun (x : ε) => wp (h ()) post epost, epost.snd) ⦄ OrElse.orElse x h ⦃ post; epost ⦄
theorem Std.WP.Spec.adapt_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε ε' α : Type u} (f : ε → ε') (x : ExceptT ε m α) (post : α → Pred) (epost : (ε' → Pred) × EPred) :
⦃ wp x post (fun (e : ε) => epost.fst (f e), epost.snd) ⦄ ExceptT.adapt f x ⦃ post; epost ⦄

Except #

theorem Std.WP.Spec.throw_Except {ε : Type u_1} {α : Type u_2} {epost : ε → Prop} {post : α → Prop} (err : ε) :
⦃ epost err ⦄ MonadExceptOf.throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_Except {ε : Type u_1} {α : Type u_2} {post : α → Prop} {epost : ε → Prop} (x : Except ε α) (h : ε → Except ε α) :
⦃ wp x post fun (e : ε) => wp (h e) post epost ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.orElse_Except {ε : Type u_1} {α : Type u_2} {post : α → Prop} {epost : ε → Prop} (x : Except ε α) (h : Unit → Except ε α) :
⦃ wp x post fun (x : ε) => wp (h ()) post epost ⦄ OrElse.orElse x h ⦃ post; epost ⦄

OptionT #

theorem Std.WP.Spec.run_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (x : OptionT m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp x post epost ⦄ x.run ⦃ Lean.Order.pushOption post epost.fst; epost.snd ⦄
theorem Std.WP.Spec.throw_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (err : PUnit) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ epost.fst () ⦄ MonadExceptOf.throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (x : OptionT m α) (h : PUnit → OptionT m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp x post (fun (x : Unit) => wp (h PUnit.unit) post epost, epost.snd) ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.orElse_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} (x : OptionT m α) (h : Unit → OptionT m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
⦃ wp x post (fun (x : Unit) => wp (h ()) post epost, epost.snd) ⦄ OrElse.orElse x h ⦃ post; epost ⦄

Option #

theorem Std.WP.Spec.throw_Option {α : Type u_1} {epost : Unit → Prop} {post : α → Prop} (err : PUnit) :
⦃ epost () ⦄ MonadExceptOf.throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_Option {α : Type u_1} {post : α → Prop} {epost : Unit → Prop} (x : Option α) (h : PUnit → Option α) :
⦃ wp x post fun (x : Unit) => wp (h PUnit.unit) post epost ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.orElse_Option {α : Type u_1} (x : Option α) (h : Unit → Option α) (post : α → Prop) (epost : Unit → Prop) :
⦃ wp x post fun (x : Unit) => wp (h ()) post epost ⦄ OrElse.orElse x h ⦃ post; epost ⦄

EStateM #

theorem Std.WP.Spec.get_EStateM {σ ε : Type} (post : σ → σ → Prop) (epost : ε → σ → Prop) :
⦃ fun (s : σ) => post s s ⦄ MonadStateOf.get ⦃ post; epost ⦄
theorem Std.WP.Spec.set_EStateM {σ ε : Type} (s : σ) (post : PUnit → σ → Prop) (epost : ε → σ → Prop) :
⦃ fun (x : σ) => post PUnit.unit s ⦄ set s ⦃ post; epost ⦄
theorem Std.WP.Spec.modifyGet_EStateM {σ α ε : Type} (f : σ → α × σ) (post : α → σ → Prop) (epost : ε → σ → Prop) :
⦃ fun (s : σ) => post (f s).fst (f s).snd ⦄ MonadStateOf.modifyGet f ⦃ post; epost ⦄
theorem Std.WP.Spec.throw_EStateM {ε α σ : Type} (err : ε) (post : α → σ → Prop) (epost : ε → σ → Prop) :
⦃ epost err ⦄ MonadExceptOf.throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_EStateM {ε σ α : Type} (x : EStateM ε σ α) (h : ε → EStateM ε σ α) (post : α → σ → Prop) (epost : ε → σ → Prop) :
⦃ fun (s : σ) => wp x post (fun (e : ε) (s' : σ) => wp (h e) post epost s') s ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.orElse_EStateM {ε σ α : Type} (x : EStateM ε σ α) (h : Unit → EStateM ε σ α) (post : α → σ → Prop) (epost : ε → σ → Prop) :
⦃ fun (s : σ) => wp x post (fun (x : ε) (s' : σ) => wp (h ()) post epost s') s ⦄ OrElse.orElse x h ⦃ post; epost ⦄
theorem Std.WP.Spec.adaptExcept_EStateM {ε ε' σ α : Type} (f : ε → ε') (x : EStateM ε σ α) (post : α → σ → Prop) (epost : ε' → σ → Prop) :
⦃ wp x post fun (e : ε) => epost (f e) ⦄ EStateM.adaptExcept f x ⦃ post; epost ⦄

Lifting MonadExceptOf #

theorem Std.WP.Spec.throw_MonadExcept {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u_1} {α : Type u} {post : α → Pred} {epost : EPred} [MonadExceptOf ε m] (err : ε) :
⦃ wp (MonadExceptOf.throw err) post epost ⦄ throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_MonadExcept {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u_1} {α : Type u} {post : α → Pred} {epost : EPred} [MonadExceptOf ε m] (x : m α) (h : ε → m α) :
⦃ wp (MonadExceptOf.tryCatch x h) post epost ⦄ tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.throw_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u_1} {α ρ : Type u} {epost : EPred} [MonadExceptOf ε m] (err : ε) (post : α → ρ → Pred) :
theorem Std.WP.Spec.throw_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u_1} {α σ : Type u} {epost : EPred} [MonadExceptOf ε m] (err : ε) (post : α → σ → Pred) :
theorem Std.WP.Spec.throw_ExceptT_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α ε' : Type u} [MonadExceptOf ε m] (err : ε) (post : α → Pred) (epost : (ε' → Pred) × EPred) :
⦃ wp (MonadExceptOf.throw err) (fun (r : Except ε' α) => match r with | Except.ok a => post a | Except.error e => epost.fst e) epost.snd ⦄ MonadExceptOf.throw err ⦃ post; epost ⦄
theorem Std.WP.Spec.throw_Option_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} [MonadExceptOf ε m] (err : ε) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
theorem Std.WP.Spec.tryCatch_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u_1} {ρ α : Type u} {epost : EPred} [MonadExceptOf ε m] (x : ReaderT ρ m α) (h : ε → ReaderT ρ m α) (post : α → ρ → Pred) :
⦃ fun (r : ρ) => wp (MonadExceptOf.tryCatch (x.run r) fun (e : ε) => (h e).run r) (fun (a : α) => post a r) epost ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε : Type u_1} {σ α : Type u} {epost : EPred} [MonadExceptOf ε m] (x : StateT σ m α) (h : ε → StateT σ m α) (post : α → σ → Pred) :
⦃ 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 ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_ExceptT_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε ε' α : Type u} [MonadExceptOf ε m] (x : ExceptT ε' m α) (h : ε → ExceptT ε' m α) (post : α → Pred) (epost : (ε' → Pred) × EPred) :
⦃ wp (MonadExceptOf.tryCatch x h) (fun (x : Except ε' α) => match x with | Except.ok a => post a | Except.error e => epost.fst e) epost.snd ⦄ MonadExceptOf.tryCatch x h ⦃ post; epost ⦄
theorem Std.WP.Spec.tryCatch_OptionT_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ε α : Type u} [MonadExceptOf ε m] (x : OptionT m α) (h : ε → OptionT m α) (post : α → Pred) (epost : (Unit → Pred) × EPred) :
theorem Std.WP.Spec.monadMap_trans {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} {n₁ n₂ : Type u → Type v} [MonadFunctor n₁ m] [MonadFunctorT n₂ n₁] {f : {β : Type u} → n₂ β → n₂ β} (x : m α) :
⦃ wp (MonadFunctor.monadMap (fun {β : Type u} => monadMap fun {β : Type u} => f) x) post epost ⦄ monadMap (fun {β : Type u} => f) x ⦃ post; epost ⦄
theorem Std.WP.Spec.liftWith_trans {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} {n₁ n₂ : Type u → Type v} [MonadControl n₁ m] [MonadControlT n₂ n₁] (f : ({β : Type u} → m β → n₂ (stM n₂ m β)) → n₂ α) :
⦃ wp (MonadControl.liftWith fun (x₂ : {β : Type u} → m β → n₁ (MonadControl.stM n₁ m β)) => liftWith fun (x₁ : {β : Type u} → n₁ β → n₂ (stM n₂ n₁ β)) => f fun {β : Type u} => x₁ ∘ x₂) post epost ⦄ liftWith f ⦃ post; epost ⦄
theorem Std.WP.Spec.restoreM_trans {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {α : Type u} {post : α → Pred} {epost : EPred} {n₁ n₂ : Type u → Type v} [MonadControl n₁ m] [MonadControlT n₂ n₁] (x : stM n₂ m α) :
⦃ wp (MonadControl.restoreM (restoreM x)) post epost ⦄ restoreM x ⦃ post; epost ⦄
def Std.WP.Invariant (α : Type u₁) (β : Type u₂) (Pred : Type uₚ) :
Type (max (max u₂ uₚ) u₁)

The type of loop invariants used by the specifications of for ... in ... loops. A loop invariant maps the elements consumed so far, the elements remaining, and the accumulator state to an assertion.

Equations
Instances For
    @[reducible, inline]
    noncomputable abbrev Std.WP.Invariant.withEarlyReturnNewDo {α : Type u₁} {β γ : Type u₂} (Pred : Type u_1) [Assertion Pred] (onContinue : List α → List α → β → Pred) (onReturn : γ → β → Pred) :
    Invariant α (Option γ × β) Pred

    An invariant combinator for loops with early return, for the new do elaborator which uses Prod for the state tuple: onContinue is the invariant while iterating, onReturn holds once the loop returned early with a value.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem Std.WP.Spec.forIn'_list {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : List α} {init : β} {f : (a : α) → a ∈ xs → β → m (ForInStep β)} (inv : Invariant α β Pred) {epost : EPred} (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), ⦃ inv pref (cur :: suff) b ⦄ f cur ⋯ b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv (pref ++ [cur]) suff b' | ForInStep.done b' => inv xs [] b'; epost ⦄) :
      ⦃ inv [] xs init ⦄ forIn' xs init f ⦃ fun (b : β) => inv xs [] b; epost ⦄
      theorem Std.WP.Spec.forIn'_list_const_inv {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : List α} {init : β} {f : (a : α) → a ∈ xs → β → m (ForInStep β)} {inv : β → Pred} {epost : EPred} (step : ∀ (x : α) (hx : x ∈ xs) (b : β), ⦃ inv b ⦄ f x hx b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv b' | ForInStep.done b' => inv b'; epost ⦄) :
      ⦃ inv init ⦄ forIn' xs init f ⦃ inv; epost ⦄
      theorem Std.WP.Spec.forIn_list {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : List α} {init : β} {f : α → β → m (ForInStep β)} (inv : Invariant α β Pred) {epost : EPred} (step : ∀ (pref : List α) (cur : α) (suff : List α), xs = pref ++ cur :: suff → ∀ (b : β), ⦃ inv pref (cur :: suff) b ⦄ f cur b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv (pref ++ [cur]) suff b' | ForInStep.done b' => inv xs [] b'; epost ⦄) :
      ⦃ inv [] xs init ⦄ forIn xs init f ⦃ fun (b : β) => inv xs [] b; epost ⦄
      theorem Std.WP.Spec.forIn_list_const_inv {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : List α} {init : β} {f : α → β → m (ForInStep β)} {inv : β → Pred} {epost : EPred} (step : ∀ (hd : α) (b : β), ⦃ inv b ⦄ f hd b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv b' | ForInStep.done b' => inv b'; epost ⦄) :
      ⦃ inv init ⦄ forIn xs init f ⦃ inv; epost ⦄
      theorem Std.WP.Spec.foldlM_list {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : List α} {init : β} {f : β → α → m β} (inv : Invariant α β Pred) {epost : EPred} (step : ∀ (pref : List α) (cur : α) (suff : List α), xs = pref ++ cur :: suff → ∀ (b : β), ⦃ inv pref (cur :: suff) b ⦄ f b cur ⦃ fun (b' : β) => inv (pref ++ [cur]) suff b'; epost ⦄) :
      ⦃ inv [] xs init ⦄ List.foldlM f init xs ⦃ fun (b : β) => inv xs [] b; epost ⦄
      theorem Std.WP.Spec.foldlM_list_const_inv {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : List α} {init : β} {f : β → α → m β} {inv : β → Pred} {epost : EPred} (step : ∀ (hd : α) (b : β), ⦃ inv b ⦄ f b hd ⦃ fun (b' : β) => inv b'; epost ⦄) :
      ⦃ inv init ⦄ List.foldlM f init xs ⦃ inv; epost ⦄
      theorem Std.WP.Spec.forIn'_pure {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ : Type w} {d : Membership α ρ} [ForIn' m ρ α d] [ForIn Id ρ α] [Internal.LawfulMemForInId ρ α] [Internal.PureForIn' m ρ α] {xs : ρ} {init : β} {f : (a : α) → a ∈ xs → β → m (ForInStep β)} (inv : Invariant α β Pred) {epost : EPred} (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : ForIn.toList xs = pref ++ cur :: suff) (b : β), ⦃ inv pref (cur :: suff) b ⦄ f cur ⋯ b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv (pref ++ [cur]) suff b' | ForInStep.done b' => inv (ForIn.toList xs) [] b'; epost ⦄) :
      ⦃ inv [] (ForIn.toList xs) init ⦄ forIn' xs init f ⦃ fun (b : β) => inv (ForIn.toList xs) [] b; epost ⦄

      Every container with a PureForIn' instance iterates over ForIn.toList, so one specification covers them all.

      theorem Std.WP.Spec.forIn_pure {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {ρ : Type w} [ForIn m ρ α] [ForIn Id ρ α] [Internal.PureForIn m ρ α] {xs : ρ} {init : β} {f : α → β → m (ForInStep β)} (inv : Invariant α β Pred) {epost : EPred} (step : ∀ (pref : List α) (cur : α) (suff : List α), ForIn.toList xs = pref ++ cur :: suff → ∀ (b : β), ⦃ inv pref (cur :: suff) b ⦄ f cur b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv (pref ++ [cur]) suff b' | ForInStep.done b' => inv (ForIn.toList xs) [] b'; epost ⦄) :
      ⦃ inv [] (ForIn.toList xs) init ⦄ forIn xs init f ⦃ fun (b : β) => inv (ForIn.toList xs) [] b; epost ⦄

      Every container with a PureForIn instance iterates over ForIn.toList, so one specification covers them all.

      theorem Std.WP.Spec.foldM_iter {α β γ : Type u} {m : Type u → Type w} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] {it : Iter β} {init : γ} {f : γ → β → m γ} (inv : Invariant β γ Pred) {epost : EPred} (step : ∀ (pref : List β) (cur : β) (suff : List β), it.toList = pref ++ cur :: suff → ∀ (b : γ), ⦃ inv pref (cur :: suff) b ⦄ f b cur ⦃ fun (b' : γ) => inv (pref ++ [cur]) suff b'; epost ⦄) :
      ⦃ inv [] it.toList init ⦄ Iter.foldM f init it ⦃ fun (b : γ) => inv it.toList [] b; epost ⦄
      theorem Std.WP.Spec.foldM_iterM_id {α β γ : Type u} {m : Type u → Type w} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] {it : IterM Id β} {init : γ} {f : γ → β → m γ} (inv : Invariant β γ Pred) {epost : EPred} (step : ∀ (pref : List β) (cur : β) (suff : List β), it.toList.run = pref ++ cur :: suff → ∀ (b : γ), ⦃ inv pref (cur :: suff) b ⦄ f b cur ⦃ fun (b' : γ) => inv (pref ++ [cur]) suff b'; epost ⦄) :
      ⦃ inv [] it.toList.run init ⦄ IterM.foldM f init it ⦃ fun (b : γ) => inv it.toList.run [] b; epost ⦄
      theorem Std.WP.Spec.IterM.forIn_filterMapWithPostcondition {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadLiftT m n] [LawfulMonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m o] [LawfulIteratorLoop α m o] {it : IterM m β} {f : β → Iterators.PostconditionT n (Option β₂)} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out).run match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.forIn_filterMapM {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadAttach n] [WeaklyLawfulMonadAttach n] [MonadLiftT m n] [LawfulMonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m o] [LawfulIteratorLoop α m o] {it : IterM m β} {f : β → n (Option β₂)} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out) match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (IterM.filterMapM f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.forIn_filterMap {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [MonadLiftT m n] [LawfulMonadLiftT m n] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m n] [LawfulIteratorLoop α m n] {it : IterM m β} {f : β → Option β₂} {init : γ} {g : β₂ → γ → n (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => match f out with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (IterM.filterMap f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.forIn_mapWithPostcondition {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadLiftT m n] [LawfulMonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m o] [LawfulIteratorLoop α m o] {it : IterM m β} {f : β → Iterators.PostconditionT n β₂} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out).run g __do_lift acc ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.forIn_mapM {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadAttach n] [WeaklyLawfulMonadAttach n] [MonadLiftT m n] [LawfulMonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m o] [LawfulIteratorLoop α m o] {it : IterM m β} {f : β → n β₂} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out) g __do_lift acc ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (IterM.mapM f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.forIn_map {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [MonadLiftT m n] [LawfulMonadLiftT m n] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m n] [LawfulIteratorLoop α m n] {it : IterM m β} {f : β → β₂} {init : γ} {g : β₂ → γ → n (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => g (f out) acc ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (IterM.map f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.forIn_filterWithPostcondition {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadLiftT m n] [LawfulMonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m o] [LawfulIteratorLoop α m o] {it : IterM m β} {f : β → Iterators.PostconditionT n (ULift Bool)} {init : γ} {g : β → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out).run if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.forIn_filterM {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadAttach n] [WeaklyLawfulMonadAttach n] [MonadLiftT m n] [LawfulMonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m o] [LawfulIteratorLoop α m o] {it : IterM m β} {f : β → n (ULift Bool)} {init : γ} {g : β → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out) if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (IterM.filterM f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.forIn_filter {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [LawfulMonad m] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [MonadLiftT m n] [LawfulMonadLiftT m n] [Iterator α m β] [Iterators.Finite α m] [IteratorLoop α m n] [LawfulIteratorLoop α m n] {it : IterM m β} {f : β → Bool} {init : γ} {g : β → γ → n (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => if f out = true then g out acc else Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (IterM.filter f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.foldM_filterMapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α m n] [IteratorLoop α m o] [LawfulIteratorLoop α m n] [LawfulIteratorLoop α m o] [MonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT m n] [LawfulMonadLiftT n o] {f : β → Iterators.PostconditionT n (Option γ)} {g : δ → γ → o δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __x ← liftM (f b).run match __x with | some c => g d c | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.foldM_filterMapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α m n] [IteratorLoop α m o] [LawfulIteratorLoop α m n] [LawfulIteratorLoop α m o] [MonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT m n] [LawfulMonadLiftT n o] {f : β → n (Option γ)} {g : δ → γ → o δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __x ← liftM (f b) match __x with | some c => g d c | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.foldM_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α m n] [IteratorLoop α m o] [LawfulIteratorLoop α m n] [LawfulIteratorLoop α m o] [MonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT m n] [LawfulMonadLiftT n o] {f : β → Iterators.PostconditionT n γ} {g : δ → γ → o δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let c ← liftM (f b).run g d c) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.foldM_mapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α m n] [IteratorLoop α m o] [LawfulIteratorLoop α m n] [LawfulIteratorLoop α m o] [MonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT m n] [LawfulMonadLiftT n o] {f : β → n γ} {g : δ → γ → o δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let c ← liftM (f b) g d c) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (IterM.mapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.foldM_filterWithPostcondition {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α m n] [IteratorLoop α m o] [LawfulIteratorLoop α m n] [LawfulIteratorLoop α m o] [MonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT m n] [LawfulMonadLiftT n o] {f : β → Iterators.PostconditionT n (ULift Bool)} {g : δ → β → o δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __do_lift ← liftM (f b).run if __do_lift.down = true then g d b else Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.foldM_filterM {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α m n] [IteratorLoop α m o] [LawfulIteratorLoop α m n] [LawfulIteratorLoop α m o] [MonadLiftT m n] [MonadLiftT n o] [LawfulMonadLiftT m n] [LawfulMonadLiftT n o] {f : β → n (ULift Bool)} {g : δ → β → o δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __do_lift ← liftM (f b) if __do_lift.down = true then g d b else Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (IterM.filterM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.foldM_filterMap {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → Option γ} {g : δ → γ → n δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => match f b with | some c => g d c | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (IterM.filterMap f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.foldM_map {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → γ} {g : δ → γ → n δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => g d (f b)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (IterM.map f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.foldM_filter {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → Bool} {g : δ → β → n δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => if f b = true then g d b else Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (IterM.filter f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.fold_filterMapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → Iterators.PostconditionT n (Option γ)} {g : δ → γ → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __x ← (f b).run match __x with | some c => Pure.pure (g d c) | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.fold_filterMapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → n (Option γ)} {g : δ → γ → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __x ← f b match __x with | some c => Pure.pure (g d c) | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (IterM.filterMapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.fold_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → Iterators.PostconditionT n γ} {g : δ → γ → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let c ← (f b).run Pure.pure (g d c)) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.fold_mapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → n γ} {g : δ → γ → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let c ← f b Pure.pure (g d c)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (IterM.mapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.fold_filterWithPostcondition {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → Iterators.PostconditionT n (ULift Bool)} {g : δ → β → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __do_lift ← (f b).run Pure.pure (if __do_lift.down = true then g d b else d)) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.IterM.fold_filterM {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : β → n (ULift Bool)} {g : δ → β → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.foldM (fun (d : δ) (b : β) => do let __do_lift ← f b Pure.pure (if __do_lift.down = true then g d b else d)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (IterM.filterM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.fold_filterMap {α β γ δ : Type w} {m : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : β → Option γ} {g : δ → γ → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.fold (fun (d : δ) (b : β) => match f b with | some c => g d c | x => d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (IterM.filterMap f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.fold_map {α β γ δ : Type w} {m : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : β → γ} {g : δ → γ → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.fold (fun (d : δ) (b : β) => g d (f b)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (IterM.map f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.IterM.fold_filter {α β δ : Type w} {m : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : β → Bool} {g : δ → β → δ} {init : δ} {it : IterM m β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ IterM.fold (fun (d : δ) (b : β) => if f b = true then g d b else d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (IterM.filter f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.forIn_filterMapWithPostcondition {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterators.Finite α Id] [IteratorLoop α Id o] [LawfulIteratorLoop α Id o] {it : Iter β} {f : β → Iterators.PostconditionT n (Option β₂)} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out).run match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.forIn_filterMapM {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadAttach n] [WeaklyLawfulMonadAttach n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterators.Finite α Id] [IteratorLoop α Id o] [LawfulIteratorLoop α Id o] {it : Iter β} {f : β → n (Option β₂)} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out) match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (Iter.filterMapM f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.forIn_filterMap {α β β₂ γ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {f : β → Option β₂} {init : γ} {g : β₂ → γ → n (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => match f out with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (Iter.filterMap f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.forIn_mapWithPostcondition {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterators.Finite α Id] [IteratorLoop α Id o] [LawfulIteratorLoop α Id o] {it : Iter β} {f : β → Iterators.PostconditionT n β₂} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out).run g __do_lift acc ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.forIn_mapM {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadAttach n] [WeaklyLawfulMonadAttach n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterators.Finite α Id] [IteratorLoop α Id o] [LawfulIteratorLoop α Id o] {it : Iter β} {f : β → n β₂} {init : γ} {g : β₂ → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out) g __do_lift acc ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (Iter.mapM f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.forIn_map {α β β₂ γ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {f : β → β₂} {init : γ} {g : β₂ → γ → n (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => g (f out) acc ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (Iter.map f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.forIn_filterWithPostcondition {α β γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterators.Finite α Id] [IteratorLoop α Id o] [LawfulIteratorLoop α Id o] {it : Iter β} {f : β → Iterators.PostconditionT n (ULift Bool)} {init : γ} {g : β → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out).run if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.forIn_filterM {α β γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [MonadAttach n] [WeaklyLawfulMonadAttach n] [MonadLiftT n o] [LawfulMonadLiftT n o] [Iterators.Finite α Id] [IteratorLoop α Id o] [LawfulIteratorLoop α Id o] {it : Iter β} {f : β → n (ULift Bool)} {init : γ} {g : β → γ → o (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => do let __do_lift ← liftM (f out) if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (Iter.filterM f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.forIn_filter {α β γ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {f : β → Bool} {init : γ} {g : β → γ → n (ForInStep γ)} {P : Pred} {Q : γ → Pred} {eQ : EPred} (h : ⦃ P ⦄ forIn it init fun (out : β) (acc : γ) => if f out = true then g out acc else Pure.pure (ForInStep.yield acc) ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ forIn (Iter.filter f it) init g ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.foldM_filterMapWithPostcondition {α β γ δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Monad o] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α Id n] [IteratorLoop α Id o] [LawfulIteratorLoop α Id n] [LawfulIteratorLoop α Id o] [MonadLiftT n o] [LawfulMonadLiftT n o] {f : β → Iterators.PostconditionT n (Option γ)} {g : δ → γ → o δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __x ← liftM (f b).run match __x with | some c => g d c | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.foldM_filterMapM {α β γ δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α Id n] [IteratorLoop α Id o] [LawfulIteratorLoop α Id n] [LawfulIteratorLoop α Id o] [MonadLiftT n o] [LawfulMonadLiftT n o] {f : β → n (Option γ)} {g : δ → γ → o δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __x ← liftM (f b) match __x with | some c => g d c | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (Iter.filterMapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.foldM_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'''} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α Id n] [IteratorLoop α Id o] [LawfulIteratorLoop α Id n] [LawfulIteratorLoop α Id o] [MonadLiftT n o] [LawfulMonadLiftT n o] {f : β → Iterators.PostconditionT n γ} {g : δ → γ → o δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let c ← liftM (f b).run g d c) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.foldM_mapM {α β γ δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α Id n] [IteratorLoop α Id o] [LawfulIteratorLoop α Id n] [LawfulIteratorLoop α Id o] [MonadLiftT n o] [LawfulMonadLiftT n o] {f : β → n γ} {g : δ → γ → o δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let c ← liftM (f b) g d c) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (Iter.mapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.foldM_filterWithPostcondition {α β δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Monad o] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α Id n] [IteratorLoop α Id o] [LawfulIteratorLoop α Id n] [LawfulIteratorLoop α Id o] [MonadLiftT n o] [LawfulMonadLiftT n o] {f : β → Iterators.PostconditionT n (ULift Bool)} {g : δ → β → o δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __do_lift ← liftM (f b).run if __do_lift.down = true then g d b else Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.foldM_filterM {α β δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [Assertion Pred] [Assertion EPred] [WPMonad o Pred EPred] [IteratorLoop α Id n] [IteratorLoop α Id o] [LawfulIteratorLoop α Id n] [LawfulIteratorLoop α Id o] [MonadLiftT n o] [LawfulMonadLiftT n o] {f : β → n (ULift Bool)} {g : δ → β → o δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __do_lift ← liftM (f b) if __do_lift.down = true then g d b else Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.foldM g init (Iter.filterM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.foldM_filterMap {α β γ δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → Option γ} {g : δ → γ → n δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => match f b with | some c => g d c | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ Iter.foldM g init (Iter.filterMap f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.foldM_map {α β γ δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → γ} {g : δ → γ → n δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => g d (f b)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ Iter.foldM g init (Iter.map f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.foldM_filter {α β δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → Bool} {g : δ → β → n δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => if f b = true then g d b else Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ Iter.foldM g init (Iter.filter f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.fold_filterMapWithPostcondition {α β γ δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → Iterators.PostconditionT n (Option γ)} {g : δ → γ → δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __x ← (f b).run match __x with | some c => Pure.pure (g d c) | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.fold_filterMapM {α β γ δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → n (Option γ)} {g : δ → γ → δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __x ← f b match __x with | some c => Pure.pure (g d c) | x => Pure.pure d) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (Iter.filterMapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.fold_mapWithPostcondition {α β γ δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → Iterators.PostconditionT n γ} {g : δ → γ → δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let c ← (f b).run Pure.pure (g d c)) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.fold_mapM {α β γ δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → n γ} {g : δ → γ → δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let c ← f b Pure.pure (g d c)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (Iter.mapM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.Iter.fold_filterWithPostcondition {α β δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → Iterators.PostconditionT n (ULift Bool)} {g : δ → β → δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __do_lift ← (f b).run Pure.pure (if __do_lift.down = true then g d b else d)) init it ⦃ Q; eQ ⦄) :
      theorem Std.WP.Spec.Iter.fold_filterM {α β δ : Type w} {n : Type w → Type w'} {Pred : Type uₚ} {EPred : Type uₑ} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WPMonad n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : β → n (ULift Bool)} {g : δ → β → δ} {init : δ} {it : Iter β} {P : Pred} {Q : δ → Pred} {eQ : EPred} (h : ⦃ P ⦄ Iter.foldM (fun (d : δ) (b : β) => do let __do_lift ← f b Pure.pure (if __do_lift.down = true then g d b else d)) init it ⦃ Q; eQ ⦄) :
      ⦃ P ⦄ IterM.fold g init (Iter.filterM f it) ⦃ Q; eQ ⦄
      theorem Std.WP.Spec.foldlM_array {α : Type u₁} {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {xs : Array α} {init : β} {f : β → α → m β} (inv : Invariant α β Pred) {epost : EPred} (step : ∀ (pref : List α) (cur : α) (suff : List α), xs.toList = pref ++ cur :: suff → ∀ (b : β), ⦃ inv pref (cur :: suff) b ⦄ f b cur ⦃ fun (b' : β) => inv (pref ++ [cur]) suff b'; epost ⦄) :
      ⦃ inv [] xs.toList init ⦄ Array.foldlM f init xs ⦃ fun (b : β) => inv xs.toList [] b; epost ⦄
      def Std.WP.StringInvariant (s : String) (β : Type u) (Pred : Type uₚ) :
      Type (max u uₚ)

      The type of loop invariants used by the specifications of for ... in ... loops over strings. A loop invariant is a function mapping the current position and state to a lattice element.

      Equations
      Instances For
        @[reducible, inline]
        noncomputable abbrev Std.WP.StringInvariant.withEarlyReturnNewDo {s : String} {β γ : Type u} (Pred : Type uₚ) [Assertion Pred] (onContinue : s.Pos → β → Pred) (onReturn : γ → β → Pred) :
        StringInvariant s (Option γ × β) Pred

        An invariant combinator for String loops with early return, for the new do elaborator which uses Prod for the state tuple: onContinue is the invariant while iterating, onReturn holds once the loop returned early with a value.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For
          theorem Std.WP.Spec.forIn_string {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {s : String} {init : β} {f : Char → β → m (ForInStep β)} (inv : StringInvariant s β Pred) {epost : EPred} (step : ∀ (pos : s.Pos) (b : β) (h : pos ≠ s.endPos), ⦃ inv pos b ⦄ f (pos.get h) b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv (pos.next h) b' | ForInStep.done b' => inv s.endPos b'; epost ⦄) :
          ⦃ inv s.startPos init ⦄ forIn s init f ⦃ fun (b : β) => inv s.endPos b; epost ⦄
          def Std.WP.StringSliceInvariant (s : String.Slice) (β : Type u) (Pred : Type uₚ) :
          Type (max u uₚ)

          The type of loop invariants used by the specifications of for ... in ... loops over string slices. A loop invariant is a function mapping the current position and state to a lattice element.

          Equations
          Instances For
            @[reducible, inline]
            noncomputable abbrev Std.WP.StringSliceInvariant.withEarlyReturnNewDo {s : String.Slice} {β γ : Type u} (Pred : Type uₚ) [Assertion Pred] (onContinue : s.Pos → β → Pred) (onReturn : γ → β → Pred) :

            An invariant combinator for String.Slice loops with early return, for the new do elaborator which uses Prod for the state tuple: onContinue is the invariant while iterating, onReturn holds once the loop returned early with a value.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              theorem Std.WP.Spec.forIn_stringSlice {β : Type u₂} {m : Type u₂ → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {s : String.Slice} {init : β} {f : Char → β → m (ForInStep β)} (inv : StringSliceInvariant s β Pred) {epost : EPred} (step : ∀ (pos : s.Pos) (b : β) (h : pos ≠ s.endPos), ⦃ inv pos b ⦄ f (pos.get h) b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv (pos.next h) b' | ForInStep.done b' => inv s.endPos b'; epost ⦄) :
              ⦃ inv s.startPos init ⦄ forIn s init f ⦃ fun (b : β) => inv s.endPos b; epost ⦄
              def Std.WP.RepeatInvariant (α β : Type u) (Pred : Type uₚ) :
              Type (max uₚ u)

              An invariant for a repeatM loop, given as a predicate over the α ⊕ β cursor: .inl a is the continue case at a; .inr b is the break case with result b.

              Equations
              Instances For
                def Std.WP.RepeatInvariant.mk {α β : Type u} {Pred : Type uₚ} (inv : α ⊕ β → Pred) :
                RepeatInvariant α β Pred

                State the invariant of a repeatM loop, keeping RepeatInvariant on the term that carries it so that a specification matches it without unfolding the definition.

                Equations
                Instances For
                  @[simp]
                  theorem Std.WP.RepeatInvariant.mk_apply {α β : Type u} {Pred : Type uₚ} (inv : α ⊕ β → Pred) (c : α ⊕ β) :
                  mk inv c = inv c
                  def Std.WP.WhileInvariant (α : Type u) (Pred : Type uₚ) :
                  Type (max u uₚ)

                  An invariant for a while loop, given as a predicate over the loop's exit flag and its state: inv false a is the continue case at a; inv true a is the break case with result a.

                  Equations
                  Instances For
                    def Std.WP.WhileInvariant.mk {α : Type u} {Pred : Type uₚ} (inv : Bool → α → Pred) :

                    State the invariant of a while loop, keeping WhileInvariant on the term that carries it so that a specification matches it without unfolding the definition.

                    Equations
                    Instances For
                      @[simp]
                      theorem Std.WP.WhileInvariant.mk_apply {α : Type u} {Pred : Type uₚ} (inv : Bool → α → Pred) (exit : Bool) (a : α) :
                      mk inv exit a = inv exit a
                      def Std.WP.WhileInvariant.toRepeatInvariant {α : Type u} {Pred : Type uₚ} (inv : WhileInvariant α Pred) :
                      RepeatInvariant α α Pred

                      Read a WhileInvariant as the invariant of the repeatM loop that a while loop unfolds to, where the exit flag is the cursor's tag.

                      Equations
                      Instances For
                        @[simp]
                        theorem Std.WP.WhileInvariant.toRepeatInvariant_inl {α : Type u} {Pred : Type uₚ} (inv : WhileInvariant α Pred) (a : α) :
                        @[simp]
                        theorem Std.WP.WhileInvariant.toRepeatInvariant_inr {α : Type u} {Pred : Type uₚ} (inv : WhileInvariant α Pred) (a : α) :
                        structure Std.WP.Variant (α : Type uα) (Pred : Type u) [Assertion Pred] :
                        Type (max uα (uγ + 1) u)

                        A termination measure for a repeatM loop: a type γ of measure values equipped with a well-founded relation, and a lattice-embedded evaluation of the measure at each cursor. Build one from a measure function with Variant.ofMeasure.

                        • γ : Type uγ

                          The type of measure values.

                        • wfRel : WellFoundedRelation self.γ

                          The well-founded relation that measure values decrease along.

                        • EvalsTo : α → self.γ → Pred

                          Relates the measure at cursor a to a value n inside the assertion lattice.

                        • total (a : α) : (Lean.Order.iSup fun (n : self.γ) => self.EvalsTo a n) = Lean.Order.top

                          The measure evaluates to some value.

                        Instances For
                          def Std.WP.Variant.rel {Pred : Type uₚ} [Assertion Pred] {α : Type uα} (v : Variant α Pred) :
                          v.γ → v.γ → Prop

                          The relation that measure values decrease along.

                          Equations
                          Instances For
                            theorem Std.WP.Variant.wf {Pred : Type uₚ} [Assertion Pred] {α : Type uα} (v : Variant α Pred) :
                            theorem Std.WP.Variant.le_of_total_le {Pred : Type uₚ} [Assertion Pred] {α : Type uα} (v : Variant α Pred) (a : α) {P Q : Pred} [Lean.Order.PreservesSup (Lean.Order.meet P)] (h : Lean.Order.PartialOrder.rel (Lean.Order.iSup fun (n : v.γ) => Lean.Order.meet (v.EvalsTo a n) P) Q) :

                            Eliminate the covering join of EvalsTo from the left of an entailment.

                            @[instance_reducible]
                            def Std.WP.Variant.ofMeasure {Pred : Type uₚ} [Assertion Pred] {α : Type uα} {γ : Type uγ} {Fun : Type v'} [Assertion.NondetFun Pred Fun γ] [WellFoundedRelation γ] (f : α → Fun) :
                            Variant α Pred

                            Build a Variant from a measure function f. The measure's value type γ (its codomain through any NondetFun state layers) provides the well-founded relation, e.g. < for Nat and the lexicographic order for products.

                            Equations
                            Instances For
                              @[simp]
                              theorem Std.WP.Variant.γ_ofMeasure {Pred : Type uₚ} [Assertion Pred] {α : Type uα} {γ : Type uγ} {Fun : Type v'} [Assertion.NondetFun Pred Fun γ] [WellFoundedRelation γ] (f : α → Fun) :
                              (ofMeasure f).γ = γ
                              @[simp]
                              theorem Std.WP.Variant.evalsTo_ofMeasure {Pred : Type uₚ} [Assertion Pred] {α : Type uα} {γ : Type uγ} {Fun : Type v'} [Assertion.NondetFun Pred Fun γ] [WellFoundedRelation γ] (f : α → Fun) (a : α) (n : γ) :

                              Fixed-arity specializations of evalsTo_ofMeasure at a lattice tower ending in Prop, in the manner of CompleteLattice.ofProp_apply_1 and its siblings: the ground instances leave every parameter recoverable from the trigger, so these are usable @[grind =] lemmas where the general NondetFun.evalsTo_apply is not. The pure family is for a measure whose value depends on the cursor alone, as in ofMeasure fun i => n - i, which NondetFun interprets as that value.

                              theorem Std.WP.Variant.evalsTo_ofMeasure_apply_1 {α σ₁ γ : Type} [WellFoundedRelation γ] (f : α → σ₁ → γ) (a : α) (n : γ) (s₁ : σ₁) :
                              (ofMeasure f).EvalsTo a n s₁ = (f a s₁ = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_apply_2 {α σ₁ σ₂ γ : Type} [WellFoundedRelation γ] (f : α → σ₁ → σ₂ → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ = (f a s₁ s₂ = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_apply_3 {α σ₁ σ₂ σ₃ γ : Type} [WellFoundedRelation γ] (f : α → σ₁ → σ₂ → σ₃ → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ s₃ = (f a s₁ s₂ s₃ = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_apply_4 {α σ₁ σ₂ σ₃ σ₄ γ : Type} [WellFoundedRelation γ] (f : α → σ₁ → σ₂ → σ₃ → σ₄ → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ s₃ s₄ = (f a s₁ s₂ s₃ s₄ = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_apply_5 {α σ₁ σ₂ σ₃ σ₄ σ₅ γ : Type} [WellFoundedRelation γ] (f : α → σ₁ → σ₂ → σ₃ → σ₄ → σ₅ → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) (s₅ : σ₅) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ s₃ s₄ s₅ = (f a s₁ s₂ s₃ s₄ s₅ = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_pure_apply_1 {α σ₁ γ : Type} [WellFoundedRelation γ] (f : α → γ) (a : α) (n : γ) (s₁ : σ₁) :
                              (ofMeasure f).EvalsTo a n s₁ = (f a = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_pure_apply_2 {α σ₁ σ₂ γ : Type} [WellFoundedRelation γ] (f : α → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ = (f a = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_pure_apply_3 {α σ₁ σ₂ σ₃ γ : Type} [WellFoundedRelation γ] (f : α → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ s₃ = (f a = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_pure_apply_4 {α σ₁ σ₂ σ₃ σ₄ γ : Type} [WellFoundedRelation γ] (f : α → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ s₃ s₄ = (f a = n)
                              theorem Std.WP.Variant.evalsTo_ofMeasure_pure_apply_5 {α σ₁ σ₂ σ₃ σ₄ σ₅ γ : Type} [WellFoundedRelation γ] (f : α → γ) (a : α) (n : γ) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) (s₅ : σ₅) :
                              (ofMeasure f).EvalsTo a n s₁ s₂ s₃ s₄ s₅ = (f a = n)
                              theorem Std.WP.Variant.rel_ofMeasure {Pred : Type uₚ} [Assertion Pred] {α : Type uα} {γ : Type uγ} {Fun : Type v'} [Assertion.NondetFun Pred Fun γ] [WellFoundedRelation γ] (f : α → Fun) (n' n : γ) :

                              Decrease along ofMeasure is decrease of measure values along the well-founded relation of γ. Rewriting with this lemma brings a decrease proof obligation into the shape produced by termination_by, so that decreasing_tactic applies.

                              @[simp]
                              theorem Std.WP.Variant.rel_ofMeasure_nat {α Pred : Type} [Assertion Pred] {Fun : Type} [Assertion.NondetFun Pred Fun Nat] (f : α → Fun) (n' n : Nat) :
                              (ofMeasure f).rel n' n ↔ n' < n
                              noncomputable def Std.WP.Variant.EvalsBelow {Pred : Type uₚ} [Assertion Pred] {α : Type uα} (v : Variant α Pred) (a' : α) (ma : v.γ) :
                              Pred

                              The measure at cursor a' evaluates to a value strictly below ma.

                              Equations
                              Instances For
                                theorem Std.WP.Variant.evalsBelow_ofMeasure {Pred : Type uₚ} [Assertion Pred] {α : Type uα} {γ : Type uγ} [WellFoundedRelation γ] (f : α → γ) (a' : α) (ma : γ) :

                                For a state-independent measure the pinned value is the measure itself, so the join collapses to a decrease along the well-founded relation of γ. The proof obligation has the shape produced by termination_by, so that decreasing_tactic applies.

                                @[simp]
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_nat {α Pred : Type} [Assertion Pred] (f : α → Nat) (a' : α) (ma : Nat) :
                                @[simp]
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_apply {α : Type uα} {σ : Type s} {Pred : Type u} [Assertion Pred] {γ : Type uγ} {Fun : Type v'} [Assertion.NondetFun Pred Fun γ] [WellFoundedRelation γ] (f : α → σ → Fun) (a' : α) (ma : γ) (s : σ) :
                                (ofMeasure f).EvalsBelow a' ma s = (ofMeasure fun (x : α) => f x s).EvalsBelow a' ma

                                Pointwise characterization of EvalsBelow on a function lattice, for ofMeasure measures.

                                Fixed-arity specializations of evalsBelow_ofMeasure_apply for Nat-valued measures at a lattice tower ending in Prop, in the manner of CompleteLattice.ofProp_apply_1 and its siblings: the ground instances leave every parameter recoverable from the trigger, so these are usable @[grind =] lemmas where the general evalsBelow_ofMeasure_apply is not.

                                theorem Std.WP.Variant.evalsBelow_ofMeasure_apply_1 {α σ₁ : Type} (f : α → σ₁ → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) :
                                (ofMeasure f).EvalsBelow a' ma s₁ = (f a' s₁ < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_apply_2 {α σ₁ σ₂ : Type} (f : α → σ₁ → σ₂ → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ = (f a' s₁ s₂ < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_apply_3 {α σ₁ σ₂ σ₃ : Type} (f : α → σ₁ → σ₂ → σ₃ → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ s₃ = (f a' s₁ s₂ s₃ < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_apply_4 {α σ₁ σ₂ σ₃ σ₄ : Type} (f : α → σ₁ → σ₂ → σ₃ → σ₄ → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ s₃ s₄ = (f a' s₁ s₂ s₃ s₄ < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_apply_5 {α σ₁ σ₂ σ₃ σ₄ σ₅ : Type} (f : α → σ₁ → σ₂ → σ₃ → σ₄ → σ₅ → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) (s₅ : σ₅) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ s₃ s₄ s₅ = (f a' s₁ s₂ s₃ s₄ s₅ < ma)

                                The same specializations for a measure whose value depends on the cursor alone.

                                theorem Std.WP.Variant.evalsBelow_ofMeasure_pure_apply_1 {α σ₁ : Type} (f : α → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) :
                                (ofMeasure f).EvalsBelow a' ma s₁ = (f a' < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_pure_apply_2 {α σ₁ σ₂ : Type} (f : α → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ = (f a' < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_pure_apply_3 {α σ₁ σ₂ σ₃ : Type} (f : α → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ s₃ = (f a' < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_pure_apply_4 {α σ₁ σ₂ σ₃ σ₄ : Type} (f : α → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ s₃ s₄ = (f a' < ma)
                                theorem Std.WP.Variant.evalsBelow_ofMeasure_pure_apply_5 {α σ₁ σ₂ σ₃ σ₄ σ₅ : Type} (f : α → Nat) (a' : α) (ma : Nat) (s₁ : σ₁) (s₂ : σ₂) (s₃ : σ₃) (s₄ : σ₄) (s₅ : σ₅) :
                                (ofMeasure f).EvalsBelow a' ma s₁ s₂ s₃ s₄ s₅ = (f a' < ma)
                                theorem Std.WP.Spec.repeatM {α β : Type u} {m : Type u → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Lean.Order.MonadTail m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {init : α} {f : α → m (α ⊕ β)} [Nonempty β] [∀ (P : Pred), Lean.Order.PreservesSup (Lean.Order.meet P)] (measure : Variant α Pred) (inv : RepeatInvariant α β Pred) (einv : EPred) (step : ∀ (a : α) (ma : measure.γ), ⦃ Lean.Order.meet (measure.EvalsTo a ma) (inv (Sum.inl a)) ⦄ f a ⦃ fun (r : α ⊕ β) => match r with | Sum.inl a' => Lean.Order.meet (measure.EvalsBelow a' ma) (inv (Sum.inl a')) | Sum.inr b => inv (Sum.inr b); einv ⦄) :
                                ⦃ inv (Sum.inl init) ⦄ _root_.repeatM f init ⦃ fun (b : β) => inv (Sum.inr b); einv ⦄

                                Specification for repeatM. The user supplies a termination measure, an invariant, and a step Triple whose pre asserts the measure evaluates to ma and the in-progress invariant holds, and whose post either continues with a measure value below ma (the invariant still holding) or finishes with the .inr invariant.

                                @[reducible, inline]
                                noncomputable abbrev Std.WP.WhileInvariant.ofInvariantAndBreak {α Pred : Type u} [Assertion Pred] (inv onBreak : α → Pred) :

                                Construct an invariant from a loop invariant inv and a break condition onBreak.

                                inv holds at the end of every loop iteration (including the breaking one), and onBreak holds in addition to inv once the loop is done. For a normal while loop onBreak can be taken as the negation of the loop condition.

                                Equations
                                Instances For
                                  theorem Std.WP.Spec.forIn_loop {β : Type u} {m : Type u → Type v} {Pred : Type uₚ} {EPred : Type uₑ} [Monad m] [Lean.Order.MonadTail m] [Assertion Pred] [Assertion EPred] [WPMonad m Pred EPred] {l : Lean.Loop} {init : β} {f : Unit → β → m (ForInStep β)} [∀ (P : Pred), Lean.Order.PreservesSup (Lean.Order.meet P)] (measure : Variant β Pred) (inv : WhileInvariant β Pred) (einv : EPred) (step : ∀ (b : β) (mb : measure.γ), ⦃ Lean.Order.meet (measure.EvalsTo b mb) (inv false b) ⦄ f () b ⦃ fun (r : ForInStep β) => match r with | ForInStep.yield b' => Lean.Order.meet (measure.EvalsBelow b' mb) (inv false b') | ForInStep.done b' => inv true b'; einv ⦄) :
                                  ⦃ inv false init ⦄ forIn l init f ⦃ fun (b : β) => inv true b; einv ⦄

                                  Specification for forIn over a Lean.Loop. The invariant takes the loop's exit flag: inv false b means "still iterating with b", inv true b means "finished with result b".