Theorem: Array.SatisfiesM_mapM
File: .lake/packages/batteries/Batteries/Data/Array/Monadic.lean

tactic: rw [mapM_eq_foldlM]
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ SatisfiesM (fun arr => motive as.size ∧ ∃ eq, ∀ (i : Nat) (h : i < as.size), p ⟨i, h⟩ arr[i]) (mapM f as)
state_after: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ SatisfiesM (fun arr => motive as.size ∧ ∃ eq, ∀ (i : Nat) (h : i < as.size), p ⟨i, h⟩ arr[i])
    (foldlM (fun bs a => bs.push <$> f a) #[] as 0)

tactic: refine SatisfiesM_foldlM (m := m) (β := Array β)
  (motive := fun i arr => motive i ∧ arr.size = i ∧ ∀ i h2, p i (arr[i.1]'h2)) ?z ?s
  |>.imp fun ⟨h₁, eq, h₂⟩ => ⟨h₁, eq, fun _ _ => h₂ ..⟩
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ SatisfiesM (fun arr => motive as.size ∧ ∃ eq, ∀ (i : Nat) (h : i < as.size), p ⟨i, h⟩ arr[i])
    (foldlM (fun bs a => bs.push <$> f a) #[] as 0)
state_after: case z
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ (fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) 0 #[]

case s
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ ∀ (i : Fin as.size) (b : Array β),
    (fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑i) b →
      SatisfiesM
        ((fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑i + 1))
        (b.push <$> f as[i])

tactic: case z => exact ⟨h0, rfl, nofun⟩
state_before: case z
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ (fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) 0 #[]
state_after: no goals

tactic: exact ⟨h0, rfl, nofun⟩
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ (fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) 0 #[]
state_after: no goals

tactic: case s =>
intro ⟨i, hi⟩ arr ⟨ih₁, eq, ih₂⟩
refine (hs _ ih₁).map fun ⟨h₁, h₂⟩ => ⟨h₂, by simp [eq], fun j hj => ?_⟩
simp [get_push] at hj ⊢; split; {apply ih₂}
cases j; cases (Nat.le_or_eq_of_le_succ hj).resolve_left ‹_›; cases eq; exact h₁
state_before: case s
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ ∀ (i : Fin as.size) (b : Array β),
    (fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑i) b →
      SatisfiesM
        ((fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑i + 1))
        (b.push <$> f as[i])
state_after: no goals

tactic: intro ⟨i, hi⟩ arr ⟨ih₁, eq, ih₂⟩
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
⊢ ∀ (i : Fin as.size) (b : Array β),
    (fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑i) b →
      SatisfiesM
        ((fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑i + 1))
        (b.push <$> f as[i])
state_after: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
⊢ SatisfiesM
    ((fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑⟨i, hi⟩ + 1))
    (arr.push <$> f as[⟨i, hi⟩])

tactic: refine (hs _ ih₁).map fun ⟨h₁, h₂⟩ => ⟨h₂, by simp [eq], fun j hj => ?_⟩
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
⊢ SatisfiesM
    ((fun i arr => motive i ∧ arr.size = i ∧ ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]) (↑⟨i, hi⟩ + 1))
    (arr.push <$> f as[⟨i, hi⟩])
state_after: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < (arr.push a✝).size
⊢ p j (arr.push a✝)[↑j]

tactic: simp [get_push] at hj ⊢
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < (arr.push a✝).size
⊢ p j (arr.push a✝)[↑j]
state_after: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
⊢ p j (if h : ↑j < arr.size then arr[↑j] else a✝)

tactic: split
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
⊢ p j (if h : ↑j < arr.size then arr[↑j] else a✝)
state_after: case isTrue
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ↑j < arr.size
⊢ p j arr[↑j]

case isFalse
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ¬↑j < arr.size
⊢ p j a✝

tactic: {apply ih₂}
state_before: case isTrue
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ↑j < arr.size
⊢ p j arr[↑j]

case isFalse
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ¬↑j < arr.size
⊢ p j a✝
state_after: case isFalse
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ¬↑j < arr.size
⊢ p j a✝

tactic: cases j
state_before: case isFalse
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ¬↑j < arr.size
⊢ p j a✝
state_after: case isFalse.mk
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
val✝ : Nat
isLt✝ : val✝ < as.size
hj : ↑⟨val✝, isLt✝⟩ < arr.size + 1
h✝ : ¬↑⟨val✝, isLt✝⟩ < arr.size
⊢ p ⟨val✝, isLt✝⟩ a✝

tactic: cases (Nat.le_or_eq_of_le_succ hj).resolve_left ‹_›
state_before: case isFalse.mk
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
val✝ : Nat
isLt✝ : val✝ < as.size
hj : ↑⟨val✝, isLt✝⟩ < arr.size + 1
h✝ : ¬↑⟨val✝, isLt✝⟩ < arr.size
⊢ p ⟨val✝, isLt✝⟩ a✝
state_after: case isFalse.mk.refl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
isLt✝ : arr.data.length < as.size
hj : ↑⟨arr.data.length, isLt✝⟩ < arr.size + 1
h✝ : ¬↑⟨arr.data.length, isLt✝⟩ < arr.size
⊢ p ⟨arr.data.length, isLt✝⟩ a✝

tactic: cases eq
state_before: case isFalse.mk.refl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
isLt✝ : arr.data.length < as.size
hj : ↑⟨arr.data.length, isLt✝⟩ < arr.size + 1
h✝ : ¬↑⟨arr.data.length, isLt✝⟩ < arr.size
⊢ p ⟨arr.data.length, isLt✝⟩ a✝
state_after: case isFalse.mk.refl.refl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
arr : Array β
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
isLt✝ : arr.data.length < as.size
hj : ↑⟨arr.data.length, isLt✝⟩ < arr.size + 1
h✝ : ¬↑⟨arr.data.length, isLt✝⟩ < arr.size
hi : arr.data.length < as.size
ih₁ : motive ↑⟨arr.data.length, hi⟩
x✝ : p ⟨arr.data.length, hi⟩ a✝ ∧ motive (↑⟨arr.data.length, hi⟩ + 1)
h₁ : p ⟨arr.data.length, hi⟩ a✝
h₂ : motive (↑⟨arr.data.length, hi⟩ + 1)
⊢ p ⟨arr.data.length, isLt✝⟩ a✝

tactic: exact h₁
state_before: case isFalse.mk.refl.refl
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
arr : Array β
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
isLt✝ : arr.data.length < as.size
hj : ↑⟨arr.data.length, isLt✝⟩ < arr.size + 1
h✝ : ¬↑⟨arr.data.length, isLt✝⟩ < arr.size
hi : arr.data.length < as.size
ih₁ : motive ↑⟨arr.data.length, hi⟩
x✝ : p ⟨arr.data.length, hi⟩ a✝ ∧ motive (↑⟨arr.data.length, hi⟩ + 1)
h₁ : p ⟨arr.data.length, hi⟩ a✝
h₂ : motive (↑⟨arr.data.length, hi⟩ + 1)
⊢ p ⟨arr.data.length, isLt✝⟩ a✝
state_after: no goals

tactic: simp [eq]
state_before: m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
⊢ (arr.push a✝).size = ↑⟨i, hi⟩ + 1
state_after: no goals

tactic: apply ih₂
state_before: case isTrue
m : Type u_1 → Type u_2
α : Type u_3
β : Type u_1
inst✝¹ : Monad m
inst✝ : LawfulMonad m
as : Array α
f : α → m β
motive : Nat → Prop
h0 : motive 0
p : Fin as.size → β → Prop
hs : ∀ (i : Fin as.size), motive ↑i → SatisfiesM (fun x => p i x ∧ motive (↑i + 1)) (f as[i])
i : Nat
hi : i < as.size
arr : Array β
ih₁ : motive ↑⟨i, hi⟩
eq : arr.size = ↑⟨i, hi⟩
ih₂ : ∀ (i : Fin as.size) (h2 : ↑i < arr.size), p i arr[↑i]
a✝ : β
x✝ : p ⟨i, hi⟩ a✝ ∧ motive (↑⟨i, hi⟩ + 1)
h₁ : p ⟨i, hi⟩ a✝
h₂ : motive (↑⟨i, hi⟩ + 1)
j : Fin as.size
hj : ↑j < arr.size + 1
h✝ : ↑j < arr.size
⊢ p j arr[↑j]
state_after: no goals