m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
⊢ SatisfiesM (motive 0) (if 0 < size as then foldrM.fold f as 0 (size as) (_ : size as ≤ size as) init else pure init)
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
⊢ SatisfiesM (motive 0) (foldrM f init as (size as))
simp [foldrM]
case inl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h✝ : 0 < size as
⊢ SatisfiesM (motive 0) (foldrM.fold f as 0 (size as) (_ : size as ≤ size as) init)

case inr
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h✝ : ¬0 < size as
⊢ SatisfiesM (motive 0) (pure init)
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
⊢ SatisfiesM (motive 0) (if 0 < size as then foldrM.fold f as 0 (size as) (_ : size as ≤ size as) init else pure init)
split
case inr
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h✝ : ¬0 < size as
⊢ SatisfiesM (motive 0) (pure init)
case inl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h✝ : 0 < size as
⊢ SatisfiesM (motive 0) (foldrM.fold f as 0 (size as) (_ : size as ≤ size as) init)

case inr
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h✝ : ¬0 < size as
⊢ SatisfiesM (motive 0) (pure init)
{exact go _ h0}
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
⊢ SatisfiesM (motive 0)
    (if (i == 0) = true then pure b
    else
      match i, hi with
      | 0, x => pure b
      | Nat.succ i, h =>
        let_fun this := (_ : i < size as);
        do
        let __do_lift ← f as[i] b
        foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift)
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
⊢ SatisfiesM (motive 0) (foldrM.fold f as 0 i hi b)
unfold foldrM.fold
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
⊢ SatisfiesM (motive 0)
    (if i = 0 then pure b
    else
      match i, hi with
      | 0, x => pure b
      | Nat.succ i, h => do
        let __do_lift ← f as[i] b
        foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift)
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
⊢ SatisfiesM (motive 0)
    (if (i == 0) = true then pure b
    else
      match i, hi with
      | 0, x => pure b
      | Nat.succ i, h =>
        let_fun this := (_ : i < size as);
        do
        let __do_lift ← f as[i] b
        foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift)
simp
case inl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
h✝ : i = 0
⊢ SatisfiesM (motive 0) (pure b)

case inr
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
h✝ : ¬i = 0
⊢ SatisfiesM (motive 0)
    (match i, hi with
    | 0, x => pure b
    | Nat.succ i, h => do
      let __do_lift ← f as[i] b
      foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift)
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
⊢ SatisfiesM (motive 0)
    (if i = 0 then pure b
    else
      match i, hi with
      | 0, x => pure b
      | Nat.succ i, h => do
        let __do_lift ← f as[i] b
        foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift)
split
no goals
case inl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi : i ≤ size as
H : motive i b
h✝ : i = 0
⊢ SatisfiesM (motive 0) (pure b)
next hi => exact .pure (hi ▸ H)
no goals
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi✝ : i ≤ size as
H : motive i b
hi : i = 0
⊢ SatisfiesM (motive 0) (pure b)
exact .pure (hi ▸ H)
case h_1
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝ : Nat
h✝ : i✝ ≤ size as
x✝ : 0 ≤ size as
H : motive 0 b
hi : ¬0 = 0
⊢ SatisfiesM (motive 0) (pure b)

case h_2
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝¹ : Nat
h✝¹ : i✝¹ ≤ size as
i✝ : Nat
h✝ : i✝ + 1 ≤ size as
H : motive (Nat.succ i✝) b
hi : ¬Nat.succ i✝ = 0
⊢ SatisfiesM (motive 0) do
    let __do_lift ← f as[i✝] b
    foldrM.fold f as 0 i✝ (_ : i✝ ≤ size as) __do_lift
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
i : Nat
b : β
hi✝ : i ≤ size as
H : motive i b
hi : ¬i = 0
⊢ SatisfiesM (motive 0)
    (match i, hi✝ with
    | 0, x => pure b
    | Nat.succ i, h => do
      let __do_lift ← f as[i] b
      foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift)
split
case h_2
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝¹ : Nat
h✝¹ : i✝¹ ≤ size as
i✝ : Nat
h✝ : i✝ + 1 ≤ size as
H : motive (Nat.succ i✝) b
hi : ¬Nat.succ i✝ = 0
⊢ SatisfiesM (motive 0) do
    let __do_lift ← f as[i✝] b
    foldrM.fold f as 0 i✝ (_ : i✝ ≤ size as) __do_lift
case h_1
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝ : Nat
h✝ : i✝ ≤ size as
x✝ : 0 ≤ size as
H : motive 0 b
hi : ¬0 = 0
⊢ SatisfiesM (motive 0) (pure b)

case h_2
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝¹ : Nat
h✝¹ : i✝¹ ≤ size as
i✝ : Nat
h✝ : i✝ + 1 ≤ size as
H : motive (Nat.succ i✝) b
hi : ¬Nat.succ i✝ = 0
⊢ SatisfiesM (motive 0) do
    let __do_lift ← f as[i✝] b
    foldrM.fold f as 0 i✝ (_ : i✝ ≤ size as) __do_lift
{simp at hi}
no goals
case h_2
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝¹ : Nat
h✝¹ : i✝¹ ≤ size as
i✝ : Nat
h✝ : i✝ + 1 ≤ size as
H : motive (Nat.succ i✝) b
hi : ¬Nat.succ i✝ = 0
⊢ SatisfiesM (motive 0) do
    let __do_lift ← f as[i✝] b
    foldrM.fold f as 0 i✝ (_ : i✝ ≤ size as) __do_lift
next i hi' =>
exact (hf ⟨i, hi'⟩ b H).bind fun _ => go _
no goals
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
b : β
i✝ : Nat
h✝ : i✝ ≤ size as
i : Nat
hi' : i + 1 ≤ size as
H : motive (Nat.succ i) b
hi : ¬Nat.succ i = 0
⊢ SatisfiesM (motive 0) do
    let __do_lift ← f as[i] b
    foldrM.fold f as 0 i (_ : i ≤ size as) __do_lift
exact (hf ⟨i, hi'⟩ b H).bind fun _ => go _
no goals
case inr
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h✝ : ¬0 < size as
⊢ SatisfiesM (motive 0) (pure init)
next h => exact .pure (Nat.eq_zero_of_nonpos _ h ▸ h0)
no goals
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
motive : Nat → β → Prop
init : β
h0 : motive (size as) init
f : α → β → m β
hf : ∀ (i : Fin (size as)) (b : β), motive (i.val + 1) b → SatisfiesM (motive i.val) (f as[i] b)
h : ¬0 < size as
⊢ SatisfiesM (motive 0) (pure init)
exact .pure (Nat.eq_zero_of_nonpos _ h ▸ h0)