Documentation

Loom.Triple.SpecLemmas

Hoare triple specifications for select functions #

This module contains Hoare triple specifications for some functions in Core.

Monad #

theorem Std.Do'.Spec.pure' {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} {pre : Pred} {post : αPred} {epost : EPred} (a : α) (h : Lean.Order.PartialOrder.rel pre (post a)) :
Triple pre (Pure.pure a) post epost
theorem Std.Do'.Spec.pure {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} {post : αPred} {epost : EPred} (a : α) :
Triple (post a) (Pure.pure a) post epost
theorem Std.Do'.Spec.bind' {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α β : Type u} {pre : Pred} {post : βPred} {epost : EPred} (x : m α) (f : αm β) (h : Triple pre x (fun (a : α) => wp (f a) post epost) epost) :
Triple pre (x >>= f) post epost
theorem Std.Do'.Spec.bind {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α β : Type u} {post : βPred} {epost : EPred} (x : m α) (f : αm β) :
Triple (wp x (fun (a : α) => wp (f a) post epost) epost) (x >>= f) post epost
theorem Std.Do'.Spec.map' {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α β : Type u} {pre : Pred} {post : βPred} {epost : EPred} (f : αβ) (x : m α) (h : Triple pre x (fun (a : α) => post (f a)) epost) :
Triple pre (f <$> x) post epost
theorem Std.Do'.Spec.map {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α β : Type u} {post : βPred} {epost : EPred} (f : αβ) (x : m α) :
Triple (wp x (fun (a : α) => post (f a)) epost) (f <$> x) post epost
theorem Std.Do'.Spec.seq' {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α β : Type u} {pre : Pred} {post : βPred} {epost : EPred} (x : m (αβ)) (y : m α) (h : Triple pre x (fun (f : αβ) => wp y (fun (a : α) => post (f a)) epost) epost) :
Triple pre (x <*> y) post epost
theorem Std.Do'.Spec.seq {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α β : Type u} {post : βPred} {epost : EPred} (x : m (αβ)) (y : m α) :
Triple (wp x (fun (f : αβ) => wp y (fun (a : α) => post (f a)) epost) epost) (x <*> y) post epost

MonadLift #

theorem Std.Do'.Spec.monadLift_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α σ : Type u} {epost : EPred} (x : m α) (post : ασPred) :
Triple (fun (s : σ) => wp x (fun (a : α) => post a s) epost) (MonadLift.monadLift x) post epost
theorem Std.Do'.Spec.monadLift_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α ρ : Type u} {epost : EPred} (x : m α) (post : αρPred) :
Triple (fun (r : ρ) => wp x (fun (a : α) => post a r) epost) (MonadLift.monadLift x) post epost
theorem Std.Do'.Spec.monadLift_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α ε : Type u} (x : m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp x post epost.tail) (MonadLift.monadLift x) post epost
theorem Std.Do'.Spec.monadLift_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (x : m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp x post epost.tail) (MonadLift.monadLift x) post epost

MonadFunctor #

theorem Std.Do'.Spec.monadMap_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {σ : Type u} {epost : EPred} (f : {β : Type u} → m βm β) {α : Type u} (x : StateT σ m α) (post : ασPred) :
Triple (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.Do'.Spec.monadMap_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ρ : Type u} {epost : EPred} (f : {β : Type u} → m βm β) {α : Type u} (x : ReaderT ρ m α) (post : αρPred) :
Triple (fun (r : ρ) => wp (f (x.run r)) (fun (a : α) => post a r) epost) (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost
theorem Std.Do'.Spec.monadMap_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u} (f : {β : Type u} → m βm β) {α : Type u} (x : ExceptT ε m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp (f x.run) (EPost.cons.pushExcept post epost) epost.tail) (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost
theorem Std.Do'.Spec.monadMap_OptionT {m : Type u → Type v} {Pred EPred : Type u} [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) :
Triple (wp (f x.run) (EPost.cons.pushOption post epost) epost.tail) (MonadFunctor.monadMap (fun {β : Type u} => f) x) post epost
theorem Std.Do'.Spec.monadMap_refl {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} {f : {β : Type u} → m βm β} {post : αPred} {epost : EPred} (x : m α) :
Triple (wp (f x) post epost) (monadMap f x) post epost

MonadControl #

theorem Std.Do'.Spec.liftWith_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {σ α : Type u} {epost : EPred} (f : ({β : Type u} → StateT σ m βm (β × σ))m α) (post : ασPred) :
Triple (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.Do'.Spec.liftWith_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ρ α : Type u} {epost : EPred} (f : ({β : Type u} → ReaderT ρ m βm β)m α) (post : αρPred) :
Triple (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.Do'.Spec.liftWith_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} (f : ({β : Type u} → ExceptT ε m βm (Except ε β))m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp (f fun {β : Type u} (x : ExceptT ε m β) => x.run) post epost.tail) (MonadControl.liftWith f) post epost
theorem Std.Do'.Spec.liftWith_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (f : ({β : Type u} → OptionT m βm (Option β))m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp (f fun {β : Type u} (x : OptionT m β) => x.run) post epost.tail) (MonadControl.liftWith f) post epost
theorem Std.Do'.Spec.restoreM_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α σ : Type u} {epost : EPred} (x : m (α × σ)) (post : ασPred) :
Triple (fun (x_1 : σ) => wp x (fun (x : α × σ) => match x with | (a, s) => post a s) epost) (MonadControl.restoreM x) post epost
theorem Std.Do'.Spec.restoreM_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α ρ : Type u} {epost : EPred} (x : m α) (post : αρPred) :
Triple (fun (r : ρ) => wp x (fun (a : α) => post a r) epost) (MonadControl.restoreM x) post epost
theorem Std.Do'.Spec.restoreM_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} (x : m (Except ε α)) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp x (EPost.cons.pushExcept post epost) epost.tail) (MonadControl.restoreM x) post epost
theorem Std.Do'.Spec.restoreM_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (x : m (Option α)) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp x (EPost.cons.pushOption post epost) epost.tail) (MonadControl.restoreM x) post epost

MonadControlT #

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

ReaderT #

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

StateT #

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

ExceptT #

theorem Std.Do'.Spec.run_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} (x : ExceptT ε m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp x post epost) x.run (EPost.cons.pushExcept post epost) epost.tail
theorem Std.Do'.Spec.throw_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} (err : ε) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (epost.head err) (MonadExceptOf.throw err) post epost
theorem Std.Do'.Spec.tryCatch_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} (x : ExceptT ε m α) (h : εExceptT ε m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp x post (EPost.cons.mk✝ (fun (e : ε) => wp (h e) post epost) epost.tail)) (MonadExceptOf.tryCatch x h) post epost
theorem Std.Do'.Spec.orElse_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} (x : ExceptT ε m α) (h : UnitExceptT ε m α) (post : αPred) (epost : EPost.cons✝ (εPred) EPred) :
Triple (wp x post (EPost.cons.mk✝ (fun (x : ε) => wp (h ()) post epost) epost.tail)) (OrElse.orElse x h) post epost
theorem Std.Do'.Spec.adapt_ExceptT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε ε' α : Type u} (f : εε') (x : ExceptT ε m α) (post : αPred) (epost : EPost.cons✝ (ε'Pred) EPred) :
Triple (wp x post (EPost.cons.mk✝ (fun (e : ε) => epost.head (f e)) epost.tail)) (ExceptT.adapt f x) post epost

Except #

theorem Std.Do'.Spec.throw_Except {ε α : Type} {post : αProp} {epost : EPost⟨εProp} (err : ε) :
Triple (epost.head err) (MonadExceptOf.throw err) post epost
theorem Std.Do'.Spec.tryCatch_Except {ε α : Type} {post : αProp} {epost : EPost⟨εProp} (x : Except ε α) (h : εExcept ε α) :
Triple (wp x post epost⟨fun (e : ε) => wp (h e) post epost) (MonadExceptOf.tryCatch x h) post epost
theorem Std.Do'.Spec.orElse_Except {ε α : Type} {post : αProp} {epost : EPost⟨εProp} (x : Except ε α) (h : UnitExcept ε α) :
Triple (wp x post epost⟨fun (x : ε) => wp (h ()) post epost) (OrElse.orElse x h) post epost

OptionT #

theorem Std.Do'.Spec.run_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (x : OptionT m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp x post epost) x.run (EPost.cons.pushOption post epost) epost.tail
theorem Std.Do'.Spec.throw_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (err : PUnit) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple epost.head (MonadExceptOf.throw err) post epost
theorem Std.Do'.Spec.tryCatch_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (x : OptionT m α) (h : PUnitOptionT m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp x post (EPost.cons.mk✝ (wp (h PUnit.unit) post epost) epost.tail)) (MonadExceptOf.tryCatch x h) post epost
theorem Std.Do'.Spec.orElse_OptionT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {α : Type u} (x : OptionT m α) (h : UnitOptionT m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp x post (EPost.cons.mk✝ (wp (h ()) post epost) epost.tail)) (OrElse.orElse x h) post epost

Option #

theorem Std.Do'.Spec.throw_Option {epost : Prop} {α : Type} {post : αProp} (err : PUnit) :
Triple epost (MonadExceptOf.throw err) post epost
theorem Std.Do'.Spec.tryCatch_Option {α : Type} {post : αProp} {epost : Prop} (x : Option α) (h : PUnitOption α) :
Triple (wp x post (wp (h PUnit.unit) post epost)) (MonadExceptOf.tryCatch x h) post epost
theorem Std.Do'.Spec.orElse_Option {α : Type} (x : Option α) (h : UnitOption α) (post : αProp) (epost : Prop) :
Triple (wp x post (wp (h ()) post epost)) (OrElse.orElse x h) post epost

EStateM #

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

Lifting MonadExceptOf #

theorem Std.Do'.Spec.throw_MonadExcept {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u_1} {α : Type u} {post : αPred} {epost : EPred} [MonadExceptOf ε m] (err : ε) :
Triple (wp (MonadExceptOf.throw err) post epost) (throw err) post epost
theorem Std.Do'.Spec.tryCatch_MonadExcept {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u_1} {α : Type u} {post : αPred} {epost : EPred} [MonadExceptOf ε m] (x : m α) (h : εm α) :
Triple (wp (MonadExceptOf.tryCatch x h) post epost) (tryCatch x h) post epost
theorem Std.Do'.Spec.throw_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u_1} {α ρ : Type u} {epost : EPred} [MonadExceptOf ε m] (err : ε) (post : αρPred) :
theorem Std.Do'.Spec.throw_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u_1} {α σ : Type u} {epost : EPred} [MonadExceptOf ε m] (err : ε) (post : ασPred) :
theorem Std.Do'.Spec.throw_ExceptT_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α ε' : Type u} [MonadExceptOf ε m] (err : ε) (post : αPred) (epost : EPost.cons✝ (ε'Pred) EPred) :
Triple (wp (MonadExceptOf.throw err) (fun (r : Except ε' α) => match r with | Except.ok a => post a | Except.error e => epost.head e) epost.tail) (MonadExceptOf.throw err) post epost
theorem Std.Do'.Spec.throw_Option_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} [MonadExceptOf ε m] (err : ε) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
Triple (wp (MonadExceptOf.throw err) (EPost.cons.pushOption post epost) epost.tail) (MonadExceptOf.throw err) post epost
theorem Std.Do'.Spec.tryCatch_ReaderT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u_1} {ρ α : Type u} {epost : EPred} [MonadExceptOf ε m] (x : ReaderT ρ m α) (h : εReaderT ρ m α) (post : αρPred) :
Triple (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.Do'.Spec.tryCatch_StateT {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε : Type u_1} {σ α : Type u} {epost : EPred} [MonadExceptOf ε m] (x : StateT σ m α) (h : εStateT σ m α) (post : ασPred) :
Triple (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.Do'.Spec.tryCatch_ExceptT_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε ε' α : Type u} [MonadExceptOf ε m] (x : ExceptT ε' m α) (h : εExceptT ε' m α) (post : αPred) (epost : EPost.cons✝ (ε'Pred) EPred) :
Triple (wp (MonadExceptOf.tryCatch x h) (fun (x : Except ε' α) => match x with | Except.ok a => post a | Except.error e => epost.head e) epost.tail) (MonadExceptOf.tryCatch x h) post epost
theorem Std.Do'.Spec.tryCatch_OptionT_lift {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {ε α : Type u} [MonadExceptOf ε m] (x : OptionT m α) (h : εOptionT m α) (post : αPred) (epost : EPost.cons✝ Pred EPred) :
theorem Std.Do'.Spec.monadMap_trans {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP 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 α) :
Triple (wp (MonadFunctor.monadMap (fun {β : Type u} => monadMap fun {β : Type u} => f) x) post epost) (monadMap (fun {β : Type u} => f) x) post epost
theorem Std.Do'.Spec.liftWith_trans {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP 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₂ α) :
Triple (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
@[reducible, inline]
abbrev Std.Do'.Invariant {α : Type u₁} (xs : List α) (β : Type u₂) (Pred : Type (max u₁ u₂)) :
Type (max u₁ u₂)

The type of loop invariants used by the specifications of for ... in ... loops. A loop invariant is a pair of:

  • A function List.Cursor xs × β → l mapping the iteration cursor and state to a lattice element.
  • An exception postcondition e.
Instances For
    @[reducible, inline]
    abbrev Std.Do'.eInvariant (EPred : Type u) :
    Instances For
      theorem Std.Do'.Spec.forIn'_list {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : List α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_list_const_inv {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : List α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} {inv : βPred} {eInv : EPred} (step : ∀ (x : α) (hx : x xs) (b : β), Triple (inv b) (f x hx b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv b' | ForInStep.done b' => inv b') eInv) :
      Triple (inv init) (forIn' xs init f) inv eInv
      theorem Std.Do'.Spec.forIn_list {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : List α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_list_const_inv {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : List α} {init : β} {f : αβm (ForInStep β)} {inv : βPred} {eInv : EPred} (step : ∀ (hd : α) (b : β), Triple (inv b) (f hd b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv b' | ForInStep.done b' => inv b') eInv) :
      Triple (inv init) (forIn xs init f) inv eInv
      theorem Std.Do'.Spec.foldlM_list {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] {xs : List α} {init : β} {f : βαm β} (inv : Invariant xs β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f b cur) (fun (b' : β) => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs, property := }, init)) (List.foldlM f init xs) (fun (b : β) => inv ({ «prefix» := xs, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.foldlM_list_const_inv {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] {xs : List α} {init : β} {f : βαm β} {inv : βPred} {eInv : EPred} (step : ∀ (hd : α) (b : β), Triple (inv b) (f b hd) (fun (b' : β) => inv b') eInv) :
      Triple (inv init) (List.foldlM f init xs) inv eInv
      theorem Std.Do'.Spec.forIn'_range {β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : Legacy.Range} {init : β} {f : (a : Nat) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List Nat) (cur : Nat) (suff : List Nat) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_range {β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : Legacy.Range} {init : β} {f : Natβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List Nat) (cur : Nat) (suff : List Nat) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_rcc {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rcc α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_rcc {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rcc α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_rco {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] [PRange.LawfulUpwardEnumerableLT α] {xs : Rco α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_rco {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] [PRange.LawfulUpwardEnumerableLT α] {xs : Rco α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_rci {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rci α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_rci {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rci α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_roc {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [DecidableLE α] [LT α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roc α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_roc {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LE α] [DecidableLE α] [LT α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roc α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_roo {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roo α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_roo {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roo α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_roi {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roi α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_roi {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roi α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_ric {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [PRange.Least? α] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] [PRange.LawfulUpwardEnumerableLE α] {xs : Ric α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_ric {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [PRange.Least? α] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] [PRange.LawfulUpwardEnumerableLE α] {xs : Ric α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_rio {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [PRange.Least? α] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] [PRange.LawfulUpwardEnumerableLT α] {xs : Rio α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_rio {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [PRange.Least? α] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] [PRange.LawfulUpwardEnumerableLT α] {xs : Rio α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn'_rii {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [PRange.Least? α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] {xs : Rii α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_rii {α β : Type u} {m : Type u → Type v} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [PRange.Least? α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] {xs : Rii α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_slice {δ : Type u} {m : Type u → Type w} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] {γ : Type u'} {α β : Type u} [ToIterator (Slice γ) Id α β] [Iterator α Id β] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] [Iterators.Finite α Id] {init : δ} {f : βδm (ForInStep δ)} {xs : Slice γ} (inv : Invariant xs.toList δ Pred) (eInv : EPred) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : xs.toList = pref ++ cur :: suff) (b : δ), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep δ) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : δ) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_iter {α β γ : Type u} {m : Type u → Type w} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] {init : γ} {f : βγm (ForInStep γ)} {it : Iter β} (inv : Invariant it.toList γ Pred) (eInv : EPred) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList = pref ++ cur :: suff) (b : γ), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep γ) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := it.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := it.toList, property := }, init)) (forIn it init f) (fun (b : γ) => inv ({ «prefix» := it.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_iterM_id {α β γ : Type u} {m : Type u → Type w} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] {init : γ} {f : βγm (ForInStep γ)} {it : IterM Id β} (inv : Invariant it.toList.run γ Pred) (eInv : EPred) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList.run = pref ++ cur :: suff) (b : γ), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep γ) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := it.toList.run, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := it.toList.run, property := }, init)) (forIn it init f) (fun (b : γ) => inv ({ «prefix» := it.toList.run, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.foldM_iter {α β γ : Type u} {m : Type u → Type w} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] {it : Iter β} {init : γ} {f : γβm γ} (inv : Invariant it.toList γ Pred) (eInv : EPred) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList = pref ++ cur :: suff) (b : γ), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f b cur) (fun (b' : γ) => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := it.toList, property := }, init)) (Iter.foldM f init it) (fun (b : γ) => inv ({ «prefix» := it.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.foldM_iterM_id {α β γ : Type u} {m : Type u → Type w} {Pred EPred : Type u} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] {it : IterM Id β} {init : γ} {f : γβm γ} (inv : Invariant it.toList.run γ Pred) (eInv : EPred) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList.run = pref ++ cur :: suff) (b : γ), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f b cur) (fun (b' : γ) => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := it.toList.run, property := }, init)) (IterM.foldM f init it) (fun (b : γ) => inv ({ «prefix» := it.toList.run, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.IterM.forIn_filterMapWithPostcondition {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc)) Q eQ) :
      theorem Std.Do'.Spec.IterM.forIn_filterMapM {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (IterM.filterMapM f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.forIn_filterMap {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => match f out with | some c => g c acc | none => Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (IterM.filterMap f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.forIn_mapWithPostcondition {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run g __do_lift acc) Q eQ) :
      Triple P (forIn (IterM.mapWithPostcondition f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.forIn_mapM {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) g __do_lift acc) Q eQ) :
      Triple P (forIn (IterM.mapM f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.forIn_map {α β β₂ γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => g (f out) acc) Q eQ) :
      Triple P (forIn (IterM.map f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.forIn_filterWithPostcondition {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc)) Q eQ) :
      theorem Std.Do'.Spec.IterM.forIn_filterM {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (IterM.filterM f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.forIn_filter {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => if f out = true then g out acc else Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (IterM.filter f it) init g) Q eQ
      theorem Std.Do'.Spec.IterM.foldM_filterMapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __discrliftM (f b).run match __discr with | some c => g d c | x => Pure.pure d) init it) Q eQ) :
      theorem Std.Do'.Spec.IterM.foldM_filterMapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __discrliftM (f b) match __discr with | some c => g d c | x => Pure.pure d) init it) Q eQ) :
      Triple P (IterM.foldM g init (IterM.filterMapM f it)) Q eQ
      theorem Std.Do'.Spec.IterM.foldM_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let cliftM (f b).run g d c) init it) Q eQ) :
      theorem Std.Do'.Spec.IterM.foldM_mapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let cliftM (f b) g d c) init it) Q eQ) :
      Triple P (IterM.foldM g init (IterM.mapM f it)) Q eQ
      theorem Std.Do'.Spec.IterM.foldM_filterWithPostcondition {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __do_liftliftM (f b).run if __do_lift.down = true then g d b else Pure.pure d) init it) Q eQ) :
      theorem Std.Do'.Spec.IterM.foldM_filterM {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __do_liftliftM (f b) if __do_lift.down = true then g d b else Pure.pure d) init it) Q eQ) :
      Triple P (IterM.foldM g init (IterM.filterM f it)) Q eQ
      theorem Std.Do'.Spec.IterM.foldM_filterMap {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => match f b with | some c => g d c | x => Pure.pure d) init it) Q eQ) :
      Triple P (IterM.foldM g init (IterM.filterMap f it)) Q eQ
      theorem Std.Do'.Spec.IterM.foldM_map {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => g d (f b)) init it) Q eQ) :
      Triple P (IterM.foldM g init (IterM.map f it)) Q eQ
      theorem Std.Do'.Spec.IterM.foldM_filter {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => if f b = true then g d b else Pure.pure d) init it) Q eQ) :
      Triple P (IterM.foldM g init (IterM.filter f it)) Q eQ
      theorem Std.Do'.Spec.IterM.fold_filterMapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __discr(f b).run match __discr with | some c => Pure.pure (g d c) | x => Pure.pure d) init it) Q eQ) :
      theorem Std.Do'.Spec.IterM.fold_filterMapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __discrf b match __discr with | some c => Pure.pure (g d c) | x => Pure.pure d) init it) Q eQ) :
      Triple P (IterM.fold g init (IterM.filterMapM f it)) Q eQ
      theorem Std.Do'.Spec.IterM.fold_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let c(f b).run Pure.pure (g d c)) init it) Q eQ) :
      theorem Std.Do'.Spec.IterM.fold_mapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let cf b Pure.pure (g d c)) init it) Q eQ) :
      Triple P (IterM.fold g init (IterM.mapM f it)) Q eQ
      theorem Std.Do'.Spec.IterM.fold_filterWithPostcondition {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple 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.Do'.Spec.IterM.fold_filterM {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (IterM.foldM (fun (d : δ) (b : β) => do let __do_liftf b Pure.pure (if __do_lift.down = true then g d b else d)) init it) Q eQ) :
      Triple P (IterM.fold g init (IterM.filterM f it)) Q eQ
      theorem Std.Do'.Spec.IterM.fold_filterMap {α β γ δ : Type w} {m : Type w → Type w'} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : βOption γ} {g : δγδ} {init : δ} {it : IterM m β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (IterM.fold (fun (d : δ) (b : β) => match f b with | some c => g d c | x => d) init it) Q eQ) :
      Triple P (IterM.fold g init (IterM.filterMap f it)) Q eQ
      theorem Std.Do'.Spec.IterM.fold_map {α β γ δ : Type w} {m : Type w → Type w'} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : βγ} {g : δγδ} {init : δ} {it : IterM m β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (IterM.fold (fun (d : δ) (b : β) => g d (f b)) init it) Q eQ) :
      Triple P (IterM.fold g init (IterM.map f it)) Q eQ
      theorem Std.Do'.Spec.IterM.fold_filter {α β δ : Type w} {m : Type w → Type w'} {Pred EPred : Type w} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : βBool} {g : δβδ} {init : δ} {it : IterM m β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (IterM.fold (fun (d : δ) (b : β) => if f b = true then g d b else d) init it) Q eQ) :
      Triple P (IterM.fold g init (IterM.filter f it)) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_filterMapWithPostcondition {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc)) Q eQ) :
      theorem Std.Do'.Spec.Iter.forIn_filterMapM {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) match __do_lift with | some c => g c acc | none => Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (Iter.filterMapM f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_filterMap {α β β₂ γ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => match f out with | some c => g c acc | none => Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (Iter.filterMap f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_mapWithPostcondition {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run g __do_lift acc) Q eQ) :
      Triple P (forIn (Iter.mapWithPostcondition f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_mapM {α β β₂ γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) g __do_lift acc) Q eQ) :
      Triple P (forIn (Iter.mapM f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_map {α β β₂ γ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => g (f out) acc) Q eQ) :
      Triple P (forIn (Iter.map f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_filterWithPostcondition {α β γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc)) Q eQ) :
      theorem Std.Do'.Spec.Iter.forIn_filterM {α β γ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) if __do_lift.down = true then g out acc else Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (Iter.filterM f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.forIn_filter {α β γ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (forIn it init fun (out : β) (acc : γ) => if f out = true then g out acc else Pure.pure (ForInStep.yield acc)) Q eQ) :
      Triple P (forIn (Iter.filter f it) init g) Q eQ
      theorem Std.Do'.Spec.Iter.foldM_filterMapWithPostcondition {α β γ δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Monad o] [LawfulMonad n] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __discrliftM (f b).run match __discr with | some c => g d c | x => Pure.pure d) init it) Q eQ) :
      theorem Std.Do'.Spec.Iter.foldM_filterMapM {α β γ δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __discrliftM (f b) match __discr with | some c => g d c | x => Pure.pure d) init it) Q eQ) :
      Triple P (IterM.foldM g init (Iter.filterMapM f it)) Q eQ
      theorem Std.Do'.Spec.Iter.foldM_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'''} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let cliftM (f b).run g d c) init it) Q eQ) :
      theorem Std.Do'.Spec.Iter.foldM_mapM {α β γ δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let cliftM (f b) g d c) init it) Q eQ) :
      Triple P (IterM.foldM g init (Iter.mapM f it)) Q eQ
      theorem Std.Do'.Spec.Iter.foldM_filterWithPostcondition {α β δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Monad o] [LawfulMonad n] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __do_liftliftM (f b).run if __do_lift.down = true then g d b else Pure.pure d) init it) Q eQ) :
      theorem Std.Do'.Spec.Iter.foldM_filterM {α β δ : Type w} {n : Type w → Type w'} {o : Type w → Type w''} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __do_liftliftM (f b) if __do_lift.down = true then g d b else Pure.pure d) init it) Q eQ) :
      Triple P (IterM.foldM g init (Iter.filterM f it)) Q eQ
      theorem Std.Do'.Spec.Iter.foldM_filterMap {α β γ δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βOption γ} {g : δγn δ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => match f b with | some c => g d c | x => Pure.pure d) init it) Q eQ) :
      Triple P (Iter.foldM g init (Iter.filterMap f it)) Q eQ
      theorem Std.Do'.Spec.Iter.foldM_map {α β γ δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βγ} {g : δγn δ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => g d (f b)) init it) Q eQ) :
      Triple P (Iter.foldM g init (Iter.map f it)) Q eQ
      theorem Std.Do'.Spec.Iter.foldM_filter {α β δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βBool} {g : δβn δ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => if f b = true then g d b else Pure.pure d) init it) Q eQ) :
      Triple P (Iter.foldM g init (Iter.filter f it)) Q eQ
      theorem Std.Do'.Spec.Iter.fold_filterMapWithPostcondition {α β γ δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __discr(f b).run match __discr with | some c => Pure.pure (g d c) | x => Pure.pure d) init it) Q eQ) :
      theorem Std.Do'.Spec.Iter.fold_filterMapM {α β γ δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βn (Option γ)} {g : δγδ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __discrf b match __discr with | some c => Pure.pure (g d c) | x => Pure.pure d) init it) Q eQ) :
      Triple P (IterM.fold g init (Iter.filterMapM f it)) Q eQ
      theorem Std.Do'.Spec.Iter.fold_mapWithPostcondition {α β γ δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βIterators.PostconditionT n γ} {g : δγδ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let c(f b).run Pure.pure (g d c)) init it) Q eQ) :
      theorem Std.Do'.Spec.Iter.fold_mapM {α β γ δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βn γ} {g : δγδ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let cf b Pure.pure (g d c)) init it) Q eQ) :
      Triple P (IterM.fold g init (Iter.mapM f it)) Q eQ
      theorem Std.Do'.Spec.Iter.fold_filterWithPostcondition {α β δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [Assertion Pred] [Assertion EPred] [WP 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 : Triple 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.Do'.Spec.Iter.fold_filterM {α β δ : Type w} {n : Type w → Type w'} {Pred EPred : Type w} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Assertion Pred] [Assertion EPred] [WP n Pred EPred] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βn (ULift Bool)} {g : δβδ} {init : δ} {it : Iter β} {P : Pred} {Q : δPred} {eQ : EPred} (h : Triple P (Iter.foldM (fun (d : δ) (b : β) => do let __do_liftf b Pure.pure (if __do_lift.down = true then g d b else d)) init it) Q eQ) :
      Triple P (IterM.fold g init (Iter.filterM f it)) Q eQ
      theorem Std.Do'.Spec.forIn'_array {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : Array α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn' xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.forIn_array {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] {xs : Array α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f cur b) (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv ({ «prefix» := xs.toList, suffix := [], property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (forIn xs init f) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv
      theorem Std.Do'.Spec.foldlM_array {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {Pred EPred : Type (max u₁ u₂)} [Monad m] [Assertion Pred] [Assertion EPred] [WP m Pred EPred] [LawfulMonad m] {xs : Array α} {init : β} {f : βαm β} (inv : Invariant xs.toList β Pred) (eInv : EPred) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), Triple (inv ({ «prefix» := pref, suffix := cur :: suff, property := }, b)) (f b cur) (fun (b' : β) => inv ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b')) eInv) :
      Triple (inv ({ «prefix» := [], suffix := xs.toList, property := }, init)) (Array.foldlM f init xs) (fun (b : β) => inv ({ «prefix» := xs.toList, suffix := [], property := }, b)) eInv