Documentation

Std.Do.Triple.SpecLemmas

Hoare triple specifications for select functions #

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

@[reducible, inline]

Converts a range to the list of all numbers in the range.

Equations
Instances For
    structure List.Cursor {α : Type u} (l : List α) :

    A pointer at a specific location in a list. List cursors are used in loop invariants for the mvcgen tactic.

    Moving the cursor to the left or right takes time linear in the current position of the cursor, so this data structure is not appropriate for run-time code.

    • prefix : List α

      The elements before to the current position in the list.

    • suffix : List α

      The elements starting at the current position. If the position is after the last element of the list, then the suffix is empty; otherwise, the first element of the suffix is the current element that the cursor points to.

    • property : self.prefix ++ self.suffix = l

      Appending the prefix to the suffix yields the original list.

    Instances For
      theorem List.Cursor.ext_iff {α : Type u} {l : List α} {x y : l.Cursor} :
      theorem List.Cursor.ext {α : Type u} {l : List α} {x y : l.Cursor} («prefix» : x.prefix = y.prefix) (suffix : x.suffix = y.suffix) :
      x = y
      def List.Cursor.at {α : Type u_1} (l : List α) (n : Nat) :

      Creates a cursor at position n in the list l. The prefix contains the first n elements, and the suffix contains the remaining elements. If n is larger than the length of the list, the cursor is positioned at the end of the list.

      Equations
      Instances For
        @[reducible, inline]
        abbrev List.Cursor.begin {α : Type u_1} (l : List α) :

        Creates a cursor at the beginning of the list (position 0). The prefix is empty and the suffix is the entire list.

        Equations
        Instances For
          @[reducible, inline]
          abbrev List.Cursor.end {α : Type u_1} (l : List α) :

          Creates a cursor at the end of the list. The prefix is the entire list and the suffix is empty.

          Equations
          Instances For
            def List.Cursor.current {α : Type u_1} {l : List α} (c : l.Cursor) (h : 0 < c.suffix.length := by get_elem_tactic) :
            α

            Returns the element at the current cursor position.

            Requires that is a current element: the suffix must be non-empty, so the cursor is not at the end of the list.

            Equations
            Instances For
              def List.Cursor.tail {α✝ : Type u_1} {l : List α✝} (s : l.Cursor) (h : 0 < s.suffix.length := by get_elem_tactic) :

              Advances the cursor by one position, moving the current element from the suffix to the prefix.

              Requires that the cursor is not already at the end of the list.

              Equations
              Instances For
                @[simp]
                theorem List.Cursor.prefix_at {α : Type u_1} {n : Nat} (l : List α) :
                («at» l n).prefix = take n l
                @[simp]
                theorem List.Cursor.suffix_at {α : Type u_1} {n : Nat} (l : List α) :
                («at» l n).suffix = drop n l
                @[simp]
                theorem List.Cursor.current_at {α : Type u_1} {n : Nat} (l : List α) (h : n < l.length) :
                («at» l n).current = l[n]
                @[simp]
                theorem List.Cursor.tail_at {α : Type u_1} {n : Nat} (l : List α) (h : n < l.length) :
                («at» l n).tail = «at» l (n + 1)
                @[reducible, inline]
                abbrev List.Cursor.pos {α✝ : Type u_1} {l : List α✝} (c : l.Cursor) :

                The position of the cursor in the list. It's a shortcut for the number of elements in the prefix.

                Equations
                Instances For
                  @[simp]
                  theorem List.Cursor.pos_at {α : Type u_1} {l : List α} {n : Nat} (h : n < l.length) :
                  («at» l n).pos = n
                  @[simp]
                  theorem List.Cursor.pos_mk {α : Type u_1} {l pre suff : List α} (h : pre ++ suff = l) :
                  { «prefix» := pre, suffix := suff, property := h }.pos = pre.length
                  theorem List.eq_of_range'_eq_append_cons {s n step : Nat} {xs : List Nat} {cur : Nat} {ys : List Nat} (h : range' s n step = xs ++ cur :: ys) :
                  cur = s + step * xs.length
                  theorem List.length_of_range'_eq_append_cons {s n step : Nat} {xs : List Nat} {cur : Nat} {ys : List Nat} (h : range' s n step = xs ++ cur :: ys) :
                  n = xs.length + ys.length + 1
                  theorem List.mem_of_range'_eq_append_cons {s n step : Nat} {xs : List Nat} {i : Nat} {ys : List Nat} (h : range' s n step = xs ++ i :: ys) :
                  i range' s n step
                  theorem List.gt_of_range'_eq_append_cons {s n step : Nat} {xs : List Nat} {i : Nat} {ys : List Nat} {j : Nat} (h : range' s n step = xs ++ i :: ys) (hstep : 0 < step) (hj : j xs) :
                  j < i
                  theorem List.lt_of_range'_eq_append_cons {s n step : Nat} {xs : List Nat} {i : Nat} {ys : List Nat} {j : Nat} (h : range' s n step = xs ++ i :: ys) (hstep : 0 < step) (hj : j ys) :
                  i < j

                  Monad #

                  theorem Std.Do.Spec.pure' {m : Type u → Type v} {ps : PostShape} {α : Type u} {a : α} [Monad m] [WPMonad m ps] {P : Assertion ps} {Q : PostCond α ps} (h : P ⊢ₛ Q.fst a) :
                  theorem Std.Do.Spec.pure {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {α : Type u} {a : α} {Q : PostCond α ps} :
                  theorem Std.Do.Spec.bind' {m : Type u → Type v} {ps : PostShape} {α β : Type u} [Monad m] [WPMonad m ps] {x : m α} {f : αm β} {P : Assertion ps} {Q : PostCond β ps} (h : P x (fun (a : α) => wp⟦f a Q, Q.snd)) :
                  P (x >>= f) Q
                  theorem Std.Do.Spec.bind {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {α β : Type u} {x : m α} {f : αm β} {Q : PostCond β ps} :
                  wp⟦x (fun (a : α) => wp⟦f a Q, Q.snd) (x >>= f) Q
                  theorem Std.Do.Spec.map {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {α β : Type u} {x : m α} {f : αβ} {Q : PostCond β ps} :
                  wp⟦x (fun (a : α) => Q.fst (f a), Q.snd) (f <$> x) Q
                  theorem Std.Do.Spec.seq {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {α β : Type u} {x : m (αβ)} {y : m α} {Q : PostCond β ps} :
                  wp⟦x (fun (f : αβ) => wp⟦y (fun (a : α) => Q.fst (f a), Q.snd), Q.snd) (x <*> y) Q

                  MonadLift #

                  theorem Std.Do.Spec.monadLift_StateT {m : Type u → Type v} {ps : PostShape} {α σ : Type u} [Monad m] [WPMonad m ps] (x : m α) (Q : PostCond α (PostShape.arg σ ps)) :
                  fun (s : σ) => wp⟦x (fun (a : α) => Q.fst a s, Q.snd) MonadLift.monadLift x Q
                  theorem Std.Do.Spec.monadLift_ReaderT {m : Type u → Type v} {ps : PostShape} {α ρ : Type u} [Monad m] [WPMonad m ps] (x : m α) (Q : PostCond α (PostShape.arg ρ ps)) :
                  fun (s : ρ) => wp⟦x (fun (a : α) => Q.fst a s, Q.snd) MonadLift.monadLift x Q
                  theorem Std.Do.Spec.monadLift_ExceptT {m : Type u → Type v} {ps : PostShape} {α ε : Type u} [Monad m] [WPMonad m ps] (x : m α) (Q : PostCond α (PostShape.except ε ps)) :
                  theorem Std.Do.Spec.monadLift_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} [Monad m] [WPMonad m ps] (x : m α) (Q : PostCond α (PostShape.except PUnit ps)) :

                  MonadLiftT #

                  MonadFunctor #

                  theorem Std.Do.Spec.monadMap_StateT {m : Type u → Type v} {ps : PostShape} {σ : Type u} [Monad m] [WP m ps] (f : {β : Type u} → m βm β) {α : Type u} (x : StateT σ m α) (Q : PostCond α (PostShape.arg σ ps)) :
                  fun (s : σ) => wp⟦f (x.run s) (fun (x : α × σ) => match x with | (a, s) => Q.fst a s, Q.snd) MonadFunctor.monadMap (fun {β : Type u} => f) x Q
                  theorem Std.Do.Spec.monadMap_ReaderT {m : Type u → Type v} {ps : PostShape} {ρ : Type u} [Monad m] [WP m ps] (f : {β : Type u} → m βm β) {α : Type u} (x : ReaderT ρ m α) (Q : PostCond α (PostShape.arg ρ ps)) :
                  fun (s : ρ) => wp⟦f (x.run s) (fun (a : α) => Q.fst a s, Q.snd) MonadFunctor.monadMap (fun {β : Type u} => f) x Q
                  theorem Std.Do.Spec.monadMap_ExceptT {m : Type u → Type v} {ps : PostShape} {ε : Type u} [Monad m] [WP m ps] (f : {β : Type u} → m βm β) {α : Type u} (x : ExceptT ε m α) (Q : PostCond α (PostShape.except ε ps)) :
                  wp⟦f x.run (fun (e : Except ε α) => Except.casesOn e Q.snd.fst Q.fst, Q.snd.snd) MonadFunctor.monadMap (fun {β : Type u} => f) x Q
                  theorem Std.Do.Spec.monadMap_OptionT {m : Type u → Type v} {ps : PostShape} [Monad m] [WP m ps] (f : {β : Type u} → m βm β) {α : Type u} (x : OptionT m α) (Q : PostCond α (PostShape.except PUnit ps)) :
                  wp⟦f x.run (fun (o : Option α) => Option.casesOn o (Q.snd.fst PUnit.unit) Q.fst, Q.snd.snd) MonadFunctor.monadMap (fun {β : Type u} => f) x Q

                  MonadFunctorT #

                  theorem Std.Do.Spec.monadMap_trans {m : Type u → Type v} {ps : PostShape} {o : Type u → Type u_1} {n : Type u → Type u_2} {α : Type u} {f : {β : Type u} → m βm β} {x : o α} {Q : PostCond α ps} [WP o ps] [MonadFunctor n o] [MonadFunctorT m n] :
                  wp⟦MonadFunctor.monadMap (fun {β : Type u} => monadMap fun {β : Type u} => f) x Q monadMap f x Q
                  theorem Std.Do.Spec.monadMap_refl {m : Type u → Type v} {ps : PostShape} {α : Type u} {f : {β : Type u} → m βm β} {x : m α} {Q : PostCond α ps} [WP m ps] :

                  MonadControl #

                  theorem Std.Do.Spec.liftWith_StateT {m : Type u → Type v} {ps : PostShape} {σ α : Type u} {Q : PostCond α (PostShape.arg σ ps)} [Monad m] [WPMonad m ps] (f : ({β : Type u} → StateT σ m βm (β × σ))m α) :
                  fun (s : σ) => wp⟦f fun {β : Type u} (x : StateT σ m β) => x.run s (fun (a : α) => Q.fst a s, Q.snd) MonadControl.liftWith f Q
                  theorem Std.Do.Spec.liftWith_ReaderT {m : Type u → Type v} {ps : PostShape} {ρ α : Type u} {Q : PostCond α (PostShape.arg ρ ps)} [Monad m] [WPMonad m ps] (f : ({β : Type u} → ReaderT ρ m βm β)m α) :
                  fun (s : ρ) => wp⟦f fun {β : Type u} (x : ReaderT ρ m β) => x.run s (fun (a : α) => Q.fst a s, Q.snd) MonadControl.liftWith f Q
                  theorem Std.Do.Spec.liftWith_ExceptT {m : Type u → Type v} {ps : PostShape} {ε α : Type u} {Q : PostCond α (PostShape.except ε ps)} [Monad m] [WPMonad m ps] (f : ({β : Type u} → ExceptT ε m βm (Except ε β))m α) :
                  wp⟦f fun {β : Type u} (x : ExceptT ε m β) => x.run (Q.fst, Q.snd.snd) MonadControl.liftWith f Q
                  theorem Std.Do.Spec.liftWith_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} {Q : PostCond α (PostShape.except PUnit ps)} [Monad m] [WPMonad m ps] (f : ({β : Type u} → OptionT m βm (Option β))m α) :
                  wp⟦f fun {β : Type u} (x : OptionT m β) => x.run (Q.fst, Q.snd.snd) MonadControl.liftWith f Q
                  theorem Std.Do.Spec.restoreM_StateT {m : Type u → Type v} {ps : PostShape} {α σ : Type u} {Q : PostCond α (PostShape.arg σ ps)} [Monad m] [WPMonad m ps] (x : m (α × σ)) :
                  fun (x_1 : σ) => wp⟦x (fun (x : α × σ) => match x with | (a, s) => Q.fst a s, Q.snd) MonadControl.restoreM do let ax Pure.pure a Q
                  theorem Std.Do.Spec.restoreM_ReaderT {m : Type u → Type v} {ps : PostShape} {α ρ : Type u} {Q : PostCond α (PostShape.arg ρ ps)} [Monad m] [WPMonad m ps] (x : m α) :
                  fun (s : ρ) => wp⟦x (fun (a : α) => Q.fst a s, Q.snd) MonadControl.restoreM x Q
                  theorem Std.Do.Spec.restoreM_ExceptT {m : Type u → Type v} {ps : PostShape} {ε α : Type u} {Q : PostCond α (PostShape.except ε ps)} [Monad m] [WPMonad m ps] (x : m (Except ε α)) :
                  theorem Std.Do.Spec.restoreM_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} {Q : PostCond α (PostShape.except PUnit ps)} [Monad m] [WPMonad m ps] (x : m (Option α)) :

                  MonadControlT #

                  theorem Std.Do.Spec.liftWith_trans {m : Type u → Type v} {ps : PostShape} {o : Type u → Type u_1} {n : Type u → Type u_2} {α : Type u} {Q : PostCond α ps} [WP o ps] [MonadControl n o] [MonadControlT m n] (f : ({β : Type u} → o βm (stM m o β))m α) :
                  wp⟦MonadControl.liftWith fun (x₂ : {β : Type u} → o βn (MonadControl.stM n o β)) => liftWith fun (x₁ : {β : Type u} → n βm (stM m n β)) => f fun {β : Type u} => x₁ x₂ Q liftWith f Q
                  theorem Std.Do.Spec.liftWith_refl {m : Type u → Type v} {ps : PostShape} {α : Type u} {Q : PostCond α ps} [WP m ps] [Pure m] (f : ({β : Type u} → m βm β)m α) :
                  wp⟦f fun {β : Type u} (x : m β) => x Q liftWith f Q
                  theorem Std.Do.Spec.restoreM_trans {m : Type u → Type v} {ps : PostShape} {o : Type u → Type u_1} {n : Type u → Type u_2} {α : Type u} {Q : PostCond α ps} [WP o ps] [MonadControl n o] [MonadControlT m n] (x : stM m o α) :
                  theorem Std.Do.Spec.restoreM_refl {m : Type u → Type v} {ps : PostShape} {α : Type u} {Q : PostCond α ps} [WP m ps] [Pure m] (x : stM m m α) :

                  ReaderT #

                  theorem Std.Do.Spec.read_ReaderT {m : Type u → Type v} {psm : PostShape} {ρ : Type u} {Q : PostCond ρ (PostShape.arg ρ psm)} [Monad m] [WPMonad m psm] :
                  theorem Std.Do.Spec.withReader_ReaderT {m : Type u → Type v} {psm : PostShape} {ρ α : Type u} {f : ρρ} {x : ReaderT ρ m α} {Q : PostCond α (PostShape.arg ρ psm)} [WP m psm] :
                  fun (r : ρ) => wp⟦x (fun (a : α) (x : ρ) => Q.fst a r, Q.snd) (f r) MonadWithReaderOf.withReader f x Q
                  theorem Std.Do.Spec.adapt_ReaderT {m : Type u → Type v} {ps : PostShape} {ρ ρ' α : Type u} {x : ReaderT ρ' m α} {Q : PostCond α (PostShape.arg ρ ps)} [WP m ps] (f : ρρ') :
                  fun (r : ρ) => wp⟦x (fun (a : α) (x : ρ') => Q.fst a r, Q.snd) (f r) ReaderT.adapt f x Q

                  StateT #

                  theorem Std.Do.Spec.get_StateT {m : Type u → Type v} {psm : PostShape} {σ : Type u} {Q : PostCond σ (PostShape.arg σ psm)} [Monad m] [WPMonad m psm] :
                  theorem Std.Do.Spec.set_StateT {m : Type u → Type v} {psm : PostShape} {σ : Type u} {s : σ} {Q : PostCond PUnit (PostShape.arg σ psm)} [Monad m] [WPMonad m psm] :
                  theorem Std.Do.Spec.modifyGet_StateT {m : Type u → Type v} {ps : PostShape} {σ α : Type u} {f : σα × σ} {Q : PostCond α (PostShape.arg σ ps)} [Monad m] [WPMonad m ps] :
                  fun (s : σ) => have t := f s; Q.fst t.fst t.snd MonadStateOf.modifyGet f Q

                  ExceptT #

                  theorem Std.Do.Spec.run_ExceptT {m : Type u → Type v} {ps : PostShape} {ε α : Type u} {Q : PostCond (Except ε α) ps} [WP m ps] (x : ExceptT ε m α) :
                  wp⟦x (fun (a : α) => Q.fst (Except.ok a), fun (e : ε) => Q.fst (Except.error e), Q.snd) x.run Q
                  theorem Std.Do.Spec.throw_ExceptT {m : Type u → Type v} {ps : PostShape} {ε α : Type u} {e : ε} {Q : PostCond α (PostShape.except ε ps)} [Monad m] [WPMonad m ps] :
                  theorem Std.Do.Spec.tryCatch_ExceptT {m : Type u → Type v} {ps : PostShape} {α ε : Type u} {x : ExceptT ε m α} {h : εExceptT ε m α} [Monad m] [WPMonad m ps] (Q : PostCond α (PostShape.except ε ps)) :
                  theorem Std.Do.Spec.orElse_ExceptT {m : Type u → Type v} {ps : PostShape} {α ε : Type u} {x : ExceptT ε m α} {h : UnitExceptT ε m α} [Monad m] [WPMonad m ps] (Q : PostCond α (PostShape.except ε ps)) :
                  theorem Std.Do.Spec.adapt_ExceptT {m : Type u → Type v} {ps : PostShape} {ε ε' α : Type u} {x : ExceptT ε m α} [Monad m] [WPMonad m ps] (f : εε') (Q : PostCond α (PostShape.except ε' ps)) :
                  wp⟦x (Q.fst, fun (e : ε) => Q.snd.fst (f e), Q.snd.snd) ExceptT.adapt f x Q

                  Except #

                  theorem Std.Do.Spec.throw_Except {m : Type u → Type v} {ps : PostShape} {ε α : Type u_1} {e : ε} {Q : PostCond α (PostShape.except ε PostShape.pure)} [Monad m] [WPMonad m ps] :
                  theorem Std.Do.Spec.tryCatch_Except {α ε : Type u_1} {x : Except ε α} {h : εExcept ε α} (Q : PostCond α (PostShape.except ε PostShape.pure)) :
                  theorem Std.Do.Spec.orElse_Except {α ε : Type u_1} {x : Except ε α} {h : UnitExcept ε α} (Q : PostCond α (PostShape.except ε PostShape.pure)) :

                  OptionT #

                  theorem Std.Do.Spec.run_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} {Q : PostCond (Option α) ps} [WP m ps] (x : OptionT m α) :
                  wp⟦x (fun (a : α) => Q.fst (some a), fun (x : PUnit) => Q.fst none, Q.snd) x.run Q
                  theorem Std.Do.Spec.throw_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} {e : PUnit} {Q : PostCond α (PostShape.except PUnit ps)} [Monad m] [WPMonad m ps] :
                  theorem Std.Do.Spec.tryCatch_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} {x : OptionT m α} {h : PUnitOptionT m α} [Monad m] [WPMonad m ps] (Q : PostCond α (PostShape.except PUnit ps)) :
                  theorem Std.Do.Spec.orElse_OptionT {m : Type u → Type v} {ps : PostShape} {α : Type u} {x : OptionT m α} {h : UnitOptionT m α} [Monad m] [WPMonad m ps] (Q : PostCond α (PostShape.except PUnit ps)) :

                  Option #

                  EStateM #

                  theorem Std.Do.Spec.modifyGet_EStateM {ε σ α : Type u_1} {f : σα × σ} {Q : PostCond α (PostShape.except ε (PostShape.arg σ PostShape.pure))} :
                  fun (s : σ) => have t := f s; Q.fst t.fst t.snd MonadStateOf.modifyGet f Q
                  theorem Std.Do.Spec.tryCatch_EStateM {α ε σ : Type u_1} {x : EStateM ε σ α} {h : εEStateM ε σ α} (Q : PostCond α (PostShape.except ε (PostShape.arg σ PostShape.pure))) :
                  theorem Std.Do.Spec.orElse_EStateM {α ε σ : Type u_1} {x : EStateM ε σ α} {h : UnitEStateM ε σ α} (Q : PostCond α (PostShape.except ε (PostShape.arg σ PostShape.pure))) :
                  theorem Std.Do.Spec.adaptExcept_EStateM {ε ε' α σ : Type u_1} {x : EStateM ε σ α} (f : εε') (Q : PostCond α (PostShape.except ε' (PostShape.arg σ PostShape.pure))) :
                  wp⟦x (Q.fst, fun (e : ε) => Q.snd.fst (f e), Q.snd.snd) EStateM.adaptExcept f x Q

                  Lifting MonadStateOf #

                  Lifting MonadReaderOf #

                  Lifting MonadExceptOf #

                  theorem Std.Do.Spec.throw_MonadExcept {m : Type u → Type v} {ε : Type u_1} {α : Type u} {e : ε} {ps✝ : PostShape} {Q : PostCond α ps✝} [MonadExceptOf ε m] [WP m ps✝] :
                  theorem Std.Do.Spec.tryCatch_MonadExcept {m : Type u → Type v} {ps : PostShape} {ε : Type u_1} {α : Type u} {x : m α} {h : εm α} [MonadExceptOf ε m] [WP m ps] (Q : PostCond α ps) :
                  theorem Std.Do.Spec.throw_ReaderT {m : Type u → Type v} {sh : PostShape} {ε : Type u_1} {ρ α : Type u} {e : ε} {Q : PostCond α (PostShape.arg ρ sh)} [WP m sh] [MonadExceptOf ε m] :
                  theorem Std.Do.Spec.throw_StateT {m : Type u → Type v} {ps : PostShape} {ε : Type u_1} {α σ : Type u} {e : ε} [WP m ps] [Monad m] [MonadExceptOf ε m] (Q : PostCond α (PostShape.arg σ ps)) :
                  theorem Std.Do.Spec.throw_ExceptT_lift {m : Type u → Type v} {ps : PostShape} {ε α ε' : Type u} {e : ε} [WP m ps] [MonadExceptOf ε m] (Q : PostCond α (PostShape.except ε' ps)) :
                  theorem Std.Do.Spec.tryCatch_ReaderT {m : Type u → Type v} {ps : PostShape} {ε : Type u_1} {α ρ : Type u} {x : ReaderT ρ m α} {h : εReaderT ρ m α} [WP m ps] [MonadExceptOf ε m] (Q : PostCond α (PostShape.arg ρ ps)) :
                  fun (r : ρ) => wp⟦MonadExceptOf.tryCatch (x.run r) fun (e : ε) => (h e).run r (fun (a : α) => Q.fst a r, Q.snd) MonadExceptOf.tryCatch x h Q
                  theorem Std.Do.Spec.tryCatch_StateT {m : Type u → Type v} {ps : PostShape} {ε : Type u_1} {α σ : Type u} {x : StateT σ m α} {h : εStateT σ m α} [WP m ps] [Monad m] [MonadExceptOf ε m] (Q : PostCond α (PostShape.arg σ ps)) :
                  fun (s : σ) => wp⟦MonadExceptOf.tryCatch (x.run s) fun (e : ε) => (h e).run s (fun (xs : α × σ) => Q.fst xs.fst xs.snd, Q.snd) MonadExceptOf.tryCatch x h Q
                  theorem Std.Do.Spec.tryCatch_ExceptT_lift {m : Type u → Type v} {ps : PostShape} {ε α ε' : Type u} {x : ExceptT ε' m α} {h : εExceptT ε' m α} [WP m ps] [MonadExceptOf ε m] (Q : PostCond α (PostShape.except ε' ps)) :
                  theorem Std.Do.Spec.tryCatch_OptionT_lift {m : Type u → Type v} {ps : PostShape} {ε α : Type u} {x : OptionT m α} {h : εOptionT m α} [WP m ps] [MonadExceptOf ε m] (Q : PostCond α (PostShape.except PUnit ps)) :

                  Lifting OrElse #

                  ForIn #

                  @[reducible, inline]
                  abbrev Std.Do.Invariant {α : Type u₁} (xs : List α) (β : Type u₂) (ps : PostShape) :
                  Type (max u₂ u₁)

                  The type of loop invariants used by the specifications of for ... in ... loops. A loop invariant is a PostCond that takes as parameters

                  • A List.Cursor xs representing the iteration state of the loop. It is parameterized by the list of elements xs that the for loop iterates over.
                  • A state tuple of type β, which will be a nesting of MProds representing the elaboration of let mut variables and early return.

                  The loop specification lemmas will use this in the following way: Before entering the loop, the cursor's prefix is empty and the suffix is xs. After leaving the loop, the cursor's prefix is xs and the suffix is empty. During the induction step, the invariant holds for a suffix with head element x. After running the loop body, the invariant then holds after shifting x to the prefix.

                  Equations
                  Instances For
                    @[reducible, inline]
                    abbrev Std.Do.Invariant.withEarlyReturn {β : Type (max u₁ u₂)} {ps : PostShape} {α✝ : Type (max u₁ u₂)} {xs : List α✝} {γ : Type (max u₁ u₂)} (onContinue : xs.CursorβAssertion ps) (onReturn : γβAssertion ps) (onExcept : ExceptConds ps := ExceptConds.false) :
                    Invariant xs (MProd (Option γ) β) ps

                    Helper definition for specifying loop invariants for loops with early return.

                    for ... in ... loops with early return of type γ elaborate to a call like this:

                    forIn (β := MProd (Option γ) ...) (b := ⟨none, ...⟩) collection loopBody
                    

                    Note that the first component of the MProd state tuple is the optional early return value. It is none as long as there was no early return and some r if the loop returned early with r.

                    This function allows to specify different invariants for the loop body depending on whether the loop terminated early or not. When there was an early return, the loop has effectively finished, which is encoded by the additional ⌜xs.suffix = []⌝ assertion in the invariant. This assertion is vital for successfully proving the induction step, as it contradicts with the assumption that xs.suffix = x::rest of the inductive hypothesis at the start of the loop body, meaning that users won't need to prove anything about the bogus case where the loop has returned early yet takes another iteration of the loop body.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      theorem Std.Do.Spec.forIn'_list {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : List α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_list_const_inv {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : List α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} {inv : PostCond β ps} (step : ∀ (x : α) (hx : x xs) (b : β), inv.fst b f x hx b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst b' | ForInStep.done b' => inv.fst b', inv.snd)) :
                      inv.fst init forIn' xs init f inv
                      theorem Std.Do.Spec.forIn_list {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : List α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_list_const_inv {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : List α} {init : β} {f : αβm (ForInStep β)} {inv : PostCond β ps} (step : ∀ (hd : α) (b : β), inv.fst b f hd b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst b' | ForInStep.done b' => inv.fst b', inv.snd)) :
                      inv.fst init forIn xs init f inv
                      theorem Std.Do.Spec.foldlM_list {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : List α} {init : β} {f : βαm β} (inv : Invariant xs β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f b cur (fun (b' : β) => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs, property := }, init) List.foldlM f init xs (fun (b : β) => inv.fst ({ «prefix» := xs, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.foldlM_list_const_inv {α : Type u₁} {β : Type (max u₁ u₂)} {m : Type (max u₁ u₂) → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : List α} {init : β} {f : βαm β} {inv : PostCond β ps} (step : ∀ (hd : α) (b : β), inv.fst b f b hd (fun (b' : β) => inv.fst b', inv.snd)) :
                      inv.fst init List.foldlM f init xs inv
                      theorem Std.Do.Spec.forIn'_range {β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : Legacy.Range} {init : β} {f : (a : Nat) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List Nat) (cur : Nat) (suff : List Nat) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_range {β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : Legacy.Range} {init : β} {f : Natβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List Nat) (cur : Nat) (suff : List Nat) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_rcc {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rcc α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_rcc {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rcc α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_rco {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [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 β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_rco {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LE α] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] [PRange.LawfulUpwardEnumerableLT α] {xs : Rco α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_rci {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LE α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rci α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_rci {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LE α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] {xs : Rci α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_roc {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [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 β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_roc {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LE α] [DecidableLE α] [LT α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLE α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roc α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_roo {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roo α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_roo {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roo α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_roi {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roi α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_roi {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLT α] {xs : Roi α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_ric {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [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 β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_ric {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [PRange.Least? α] [LE α] [DecidableLE α] [PRange.UpwardEnumerable α] [Rxc.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] [PRange.LawfulUpwardEnumerableLE α] {xs : Ric α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_rio {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [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 β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_rio {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [PRange.Least? α] [LT α] [DecidableLT α] [PRange.UpwardEnumerable α] [Rxo.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] [PRange.LawfulUpwardEnumerableLT α] {xs : Rio α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn'_rii {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [PRange.Least? α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] {xs : Rii α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_rii {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] [PRange.Least? α] [PRange.UpwardEnumerable α] [Rxi.IsAlwaysFinite α] [PRange.LawfulUpwardEnumerable α] [PRange.LawfulUpwardEnumerableLeast? α] {xs : Rii α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_slice {m : Type w → Type x} {ps : PostShape} [Monad m] [WPMonad m ps] {γ : Type u} {α β : Type w} [LawfulMonad m] {δ : Type w} [ToIterator (Slice γ) Id α β] [Iterator α Id β] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m] [Iterators.Finite α Id] {init : δ} {f : βδm (ForInStep δ)} {xs : Slice γ} (inv : Invariant xs.toList δ ps) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : xs.toList = pref ++ cur :: suff) (b : δ), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep δ) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : δ) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_iter {n : Type (max u_1 u_2) → Type u_3} {ps : PostShape} [Monad n] [WPMonad n ps] {α β : Type u_2} {γ : Type (max u_1 u_2)} [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {init : γ} {f : βγn (ForInStep γ)} {it : Iter β} (inv : Invariant it.toList γ ps) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList = pref ++ cur :: suff) (b : γ), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep γ) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := it.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := it.toList, property := }, init) forIn it init f (fun (b : γ) => inv.fst ({ «prefix» := it.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_iterM_id {n : Type (max u_1 u_2) → Type u_3} {ps : PostShape} [Monad n] [WPMonad n ps] {α β γ : Type (max u_1 u_2)} [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {init : γ} {f : βγn (ForInStep γ)} {it : IterM Id β} (inv : Invariant it.toList.run γ ps) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList.run = pref ++ cur :: suff) (b : γ), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep γ) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := it.toList.run, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := it.toList.run, property := }, init) forIn it init f (fun (b : γ) => inv.fst ({ «prefix» := it.toList.run, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.foldM_iter {n : Type (max u_1 u_2) → Type u_3} {ps : PostShape} [Monad n] [WPMonad n ps] {α β : Type u_2} {γ : Type (max u_1 u_2)} [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {init : γ} {f : γβn γ} (inv : Invariant it.toList γ ps) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList = pref ++ cur :: suff) (b : γ), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f b cur (fun (b' : γ) => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := it.toList, property := }, init) Iter.foldM f init it (fun (b : γ) => inv.fst ({ «prefix» := it.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.foldM_iterM_id {n : Type (max u_1 u_2) → Type u_3} {ps : PostShape} [Monad n] [WPMonad n ps] {α β γ : Type (max u_1 u_2)} [Iterator α Id β] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : IterM Id β} {init : γ} {f : γβn γ} (inv : Invariant it.toList.run γ ps) (step : ∀ (pref : List β) (cur : β) (suff : List β) (h : it.toList.run = pref ++ cur :: suff) (b : γ), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f b cur (fun (b' : γ) => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := it.toList.run, property := }, init) IterM.foldM f init it (fun (b : γ) => inv.fst ({ «prefix» := it.toList.run, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.IterM.forIn_filterMapWithPostcondition {α : Type u₁} {n : Type u₁ → Type u_1} {o : Type u₁ → Type u_2} {β₂ γ : Type u₁} {m : Type u₁ → Type u_3} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.forIn_filterMapM {α : Type u₁} {n : Type u₁ → Type u_1} {o : Type u₁ → Type u_2} {β₂ γ : Type u₁} {m : Type u₁ → Type u_3} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.forIn_filterMap {α : Type u₁} {n : Type u₁ → Type u_1} {β₂ γ : Type u₁} {m : Type u₁ → Type u_2} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [WPMonad n ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => match f out with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) Q) :
                      theorem Std.Do.Spec.IterM.forIn_mapWithPostcondition {α : Type u₁} {n : Type u₁ → Type u_1} {o : Type u₁ → Type u_2} {β₂ γ : Type u₁} {m : Type u₁ → Type u_3} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run g __do_lift acc Q) :
                      theorem Std.Do.Spec.IterM.forIn_mapM {α : Type u₁} {n : Type u₁ → Type u_1} {o : Type u₁ → Type u_2} {β₂ γ : Type u₁} {m : Type u₁ → Type u_3} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) g __do_lift acc Q) :
                      P forIn (IterM.mapM f it) init g Q
                      theorem Std.Do.Spec.IterM.forIn_map {α : Type u₁} {n : Type u₁ → Type u_1} {β₂ γ : Type u₁} {m : Type u₁ → Type u_2} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [WPMonad n ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => g (f out) acc Q) :
                      P forIn (IterM.map f it) init g Q
                      theorem Std.Do.Spec.IterM.forIn_filterWithPostcondition {α : Type u₁} {n : Type u₁ → Type u_1} {o : Type u₁ → Type u_2} {γ : Type u₁} {m : Type u₁ → Type u_3} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.forIn_filterM {α : Type u₁} {n : Type u₁ → Type u_1} {o : Type u₁ → Type u_2} {γ : Type u₁} {m : Type u₁ → Type u_3} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.forIn_filter {α : Type u₁} {n : Type u₁ → Type u_1} {γ : Type u₁} {m : Type u₁ → Type u_2} {β : Type u₁} {ps : PostShape} [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [WPMonad n ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => if f out = true then g out acc else Pure.pure (ForInStep.yield acc) Q) :
                      theorem Std.Do.Spec.IterM.foldM_filterMapWithPostcondition {α β γ δ : Type w} {ps : PostShape} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.foldM_filterMapM {α β γ δ : Type w} {ps : PostShape} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.foldM_mapWithPostcondition {α β γ δ : Type w} {ps : PostShape} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => do let cliftM (f b).run g d c) init it Q) :
                      theorem Std.Do.Spec.IterM.foldM_mapM {α β γ δ : Type w} {ps : PostShape} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => do let cliftM (f b) g d c) init it Q) :
                      theorem Std.Do.Spec.IterM.foldM_filterWithPostcondition {α β δ : Type w} {ps : PostShape} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.foldM_filterM {α β δ : Type w} {ps : PostShape} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.foldM_filterMap {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βOption γ} {g : δγn δ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => match f b with | some c => g d c | x => Pure.pure d) init it Q) :
                      theorem Std.Do.Spec.IterM.foldM_map {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βγ} {g : δγn δ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => g d (f b)) init it Q) :
                      theorem Std.Do.Spec.IterM.foldM_filter {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [Monad n] [LawfulMonad m] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βBool} {g : δβn δ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => if f b = true then g d b else Pure.pure d) init it Q) :
                      theorem Std.Do.Spec.IterM.fold_filterMapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {ps : PostShape} {n : Type w → Type w''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βIterators.PostconditionT n (Option γ)} {g : δγδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.fold_filterMapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βn (Option γ)} {g : δγδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.fold_mapWithPostcondition {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βIterators.PostconditionT n γ} {g : δγδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => do let c(f b).run Pure.pure (g d c)) init it Q) :
                      theorem Std.Do.Spec.IterM.fold_mapM {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βn γ} {g : δγδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.foldM (fun (d : δ) (b : β) => do let cf b Pure.pure (g d c)) init it Q) :
                      theorem Std.Do.Spec.IterM.fold_filterWithPostcondition {α β δ : Type w} {m : Type w → Type w'} {ps : PostShape} {n : Type w → Type w''} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βIterators.PostconditionT n (ULift Bool)} {g : δβδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (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) :
                      theorem Std.Do.Spec.IterM.fold_filterM {α β δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [WPMonad n ps] [IteratorLoop α m n] [LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n] {f : βn (ULift Bool)} {g : δβδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : 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) :
                      theorem Std.Do.Spec.IterM.fold_filterMap {α β γ δ : Type w} {m : Type w → Type w'} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [WPMonad m ps] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : βOption γ} {g : δγδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.fold (fun (d : δ) (b : β) => match f b with | some c => g d c | x => d) init it Q) :
                      theorem Std.Do.Spec.IterM.fold_map {α β γ δ : Type w} {m : Type w → Type w'} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [WPMonad m ps] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : βγ} {g : δγδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.fold (fun (d : δ) (b : β) => g d (f b)) init it Q) :
                      theorem Std.Do.Spec.IterM.fold_filter {α β δ : Type w} {m : Type w → Type w'} {ps : PostShape} [Iterator α m β] [Iterators.Finite α m] [Monad m] [LawfulMonad m] [WPMonad m ps] [IteratorLoop α m m] [LawfulIteratorLoop α m m] {f : βBool} {g : δβδ} {init : δ} {it : IterM m β} {P : Assertion ps} {Q : PostCond δ ps} (h : P IterM.fold (fun (d : δ) (b : β) => if f b = true then g d b else d) init it Q) :
                      theorem Std.Do.Spec.Iter.forIn_filterMapWithPostcondition {α β β₂ γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} {o : Type w → Type u_2} [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.Iter.forIn_filterMapM {α β β₂ γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} {o : Type w → Type u_2} [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.Iter.forIn_filterMap {α β β₂ γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} [Monad n] [LawfulMonad n] [WPMonad n ps] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {f : βOption β₂} {init : γ} {g : β₂γn (ForInStep γ)} {P : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => match f out with | some c => g c acc | none => Pure.pure (ForInStep.yield acc) Q) :
                      theorem Std.Do.Spec.Iter.forIn_mapWithPostcondition {α β β₂ γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} {o : Type w → Type u_2} [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out).run g __do_lift acc Q) :
                      theorem Std.Do.Spec.Iter.forIn_mapM {α β β₂ γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} {o : Type w → Type u_2} [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => do let __do_liftliftM (f out) g __do_lift acc Q) :
                      P forIn (Iter.mapM f it) init g Q
                      theorem Std.Do.Spec.Iter.forIn_map {α β β₂ γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} [Monad n] [LawfulMonad n] [WPMonad n ps] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {f : ββ₂} {init : γ} {g : β₂γn (ForInStep γ)} {P : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => g (f out) acc Q) :
                      P forIn (Iter.map f it) init g Q
                      theorem Std.Do.Spec.Iter.forIn_filterWithPostcondition {α β γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} {o : Type w → Type u_2} [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.Iter.forIn_filterM {α β γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} {o : Type w → Type u_2} [Monad n] [LawfulMonad n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond γ ps} (h : 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) :
                      theorem Std.Do.Spec.Iter.forIn_filter {α β γ : Type w} [Iterator α Id β] {ps : PostShape} {n : Type w → Type u_1} [Monad n] [LawfulMonad n] [WPMonad n ps] [Iterators.Finite α Id] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {it : Iter β} {f : βBool} {init : γ} {g : βγn (ForInStep γ)} {P : Assertion ps} {Q : PostCond γ ps} (h : P forIn it init fun (out : β) (acc : γ) => if f out = true then g out acc else Pure.pure (ForInStep.yield acc) Q) :
                      P forIn (Iter.filter f it) init g Q
                      theorem Std.Do.Iter.foldM_filterMapWithPostcondition {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Monad o] [LawfulMonad n] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __discrliftM (f b).run match __discr with | some c => g d c | x => pure d) init it Q) :
                      theorem Std.Do.Iter.foldM_filterMapM {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __discrliftM (f b) match __discr with | some c => g d c | x => pure d) init it Q) :
                      theorem Std.Do.Iter.foldM_mapWithPostcondition {ps : PostShape} {α β γ δ : Type w} {m : Type w → Type w'} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α Id β] [Iterators.Finite α Id] [Monad m] [Monad n] [Monad o] [LawfulMonad m] [LawfulMonad n] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let cliftM (f b).run g d c) init it Q) :
                      theorem Std.Do.Iter.foldM_mapM {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let cliftM (f b) g d c) init it Q) :
                      theorem Std.Do.Iter.foldM_filterWithPostcondition {ps : PostShape} {α β δ : Type w} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [Monad o] [LawfulMonad n] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __do_liftliftM (f b).run if __do_lift.down = true then g d b else pure d) init it Q) :
                      theorem Std.Do.Iter.foldM_filterM {ps : PostShape} {α β δ : Type w} {n : Type w → Type w''} {o : Type w → Type w'''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [Monad o] [LawfulMonad o] [WPMonad o ps] [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 : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __do_liftliftM (f b) if __do_lift.down = true then g d b else pure d) init it Q) :
                      theorem Std.Do.Iter.foldM_filterMap {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βOption γ} {g : δγn δ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => match f b with | some c => g d c | x => pure d) init it Q) :
                      theorem Std.Do.Iter.foldM_map {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βγ} {g : δγn δ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => g d (f b)) init it Q) :
                      theorem Std.Do.Iter.foldM_filter {ps : PostShape} {α β δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βBool} {g : δβn δ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => if f b = true then g d b else pure d) init it Q) :
                      theorem Std.Do.Iter.fold_filterMapWithPostcondition {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βIterators.PostconditionT n (Option γ)} {g : δγδ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __discr(f b).run match __discr with | some c => pure (g d c) | x => pure d) init it Q) :
                      theorem Std.Do.Iter.fold_filterMapM {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βn (Option γ)} {g : δγδ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __discrf b match __discr with | some c => pure (g d c) | x => pure d) init it Q) :
                      theorem Std.Do.Iter.fold_mapWithPostcondition {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βIterators.PostconditionT n γ} {g : δγδ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let c(f b).run pure (g d c)) init it Q) :
                      theorem Std.Do.Iter.fold_mapM {ps : PostShape} {α β γ δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βn γ} {g : δγδ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let cf b pure (g d c)) init it Q) :
                      theorem Std.Do.Iter.fold_filterWithPostcondition {ps : PostShape} {α β δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [LawfulMonad n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βIterators.PostconditionT n (ULift Bool)} {g : δβδ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __do_lift(f b).run pure (if __do_lift.down = true then g d b else d)) init it Q) :
                      theorem Std.Do.Iter.fold_filterM {ps : PostShape} {α β δ : Type w} {n : Type w → Type w''} [Iterator α Id β] [Iterators.Finite α Id] [Monad n] [MonadAttach n] [LawfulMonad n] [WeaklyLawfulMonadAttach n] [WPMonad n ps] [IteratorLoop α Id n] [LawfulIteratorLoop α Id n] {f : βn (ULift Bool)} {g : δβδ} {init : δ} {it : Iter β} {P : Assertion ps} {Q : PostCond δ ps} (h : P Iter.foldM (fun (d : δ) (b : β) => do let __do_liftf b pure (if __do_lift.down = true then g d b else d)) init it Q) :
                      theorem Std.Do.Spec.forIn'_array {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : Array α} {init : β} {f : (a : α) → a xsβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn' xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.forIn_array {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : Array α} {init : β} {f : αβm (ForInStep β)} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f cur b (fun (r : ForInStep β) => match r with | ForInStep.yield b' => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b') | ForInStep.done b' => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) forIn xs init f (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)
                      theorem Std.Do.Spec.foldlM_array {α β : Type u} {m : Type u → Type v} {ps : PostShape} [Monad m] [WPMonad m ps] {xs : Array α} {init : β} {f : βαm β} (inv : Invariant xs.toList β ps) (step : ∀ (pref : List α) (cur : α) (suff : List α) (h : xs.toList = pref ++ cur :: suff) (b : β), inv.fst ({ «prefix» := pref, suffix := cur :: suff, property := }, b) f b cur (fun (b' : β) => inv.fst ({ «prefix» := pref ++ [cur], suffix := suff, property := }, b'), inv.snd)) :
                      inv.fst ({ «prefix» := [], suffix := xs.toList, property := }, init) Array.foldlM f init xs (fun (b : β) => inv.fst ({ «prefix» := xs.toList, suffix := [], property := }, b), inv.snd)