Theorem: Array.getElem_ofFn_go
File: Std/Data/Array/Lemmas.lean

tactic: simp [*]
state_before: n : Nat
α : Type ?u.131979
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
this : size acc + (n - size acc) = n
⊢ k < size (ofFn.go f i acc)

tactic: unfold ofFn.go
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
⊢ (ofFn.go f i acc)[k] = f { val := k, isLt := hki }

tactic: if hin : i < n then
  have : 1 + (n - (i + 1)) = n - i :=
    Nat.sub_sub .. ▸ Nat.add_sub_cancel' (Nat.le_sub_of_add_le (Nat.add_comm .. ▸ hin))
  simp only [dif_pos hin]
  rw [getElem_ofFn_go f (i+1) _ hin (by simp [*]) (fun j hj => ?hacc)]
  cases (Nat.lt_or_eq_of_le <| Nat.le_of_lt_succ (by simpa using hj)) with
  | inl hj => simp [get_push, hj, hacc j hj]
  | inr hj => simp [get_push, *]
else
  simp [hin, hacc k (Nat.lt_of_lt_of_le hki (Nat.le_of_not_lt (hi ▸ hin)))]
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
⊢ (if h : i < n then ofFn.go f (i + 1) (push acc (f { val := i, isLt := h })) else acc)[k] = f { val := k, isLt := hki }

tactic: have : 1 + (n - (i + 1)) = n - i :=
  Nat.sub_sub .. ▸ Nat.add_sub_cancel' (Nat.le_sub_of_add_le (Nat.add_comm .. ▸ hin))
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
⊢ (if h : i < n then ofFn.go f (i + 1) (push acc (f { val := i, isLt := h })) else acc)[k] = f { val := k, isLt := hki }

tactic: simp only [dif_pos hin]
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
⊢ (if h : i < n then ofFn.go f (i + 1) (push acc (f { val := i, isLt := h })) else acc)[k] = f { val := k, isLt := hki }

tactic: rw [getElem_ofFn_go f (i+1) _ hin (by simp [*]) (fun j hj => ?hacc)]
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
⊢ (ofFn.go f (i + 1) (push acc (f { val := i, isLt := hin })))[k] = f { val := k, isLt := hki }

tactic: cases (Nat.lt_or_eq_of_le <| Nat.le_of_lt_succ (by simpa using hj)) with
| inl hj => simp [get_push, hj, hacc j hj]
| inr hj => simp [get_push, *]
state_before: case hacc
n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
j : Nat
hj : j < size (push acc (f { val := i, isLt := hin }))
⊢ (push acc (f { val := i, isLt := hin }))[j] = f { val := j, isLt := (_ : j < n) }

tactic: simp [*]
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
⊢ i + 1 = size (push acc (f { val := i, isLt := hin }))

tactic: simpa using hj
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
j : Nat
hj : j < size (push acc (f { val := i, isLt := hin }))
⊢ ?m.134109 < Nat.succ ?m.134110

tactic: simp [get_push, hj, hacc j hj]
state_before: case hacc.inl
n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
j : Nat
hj✝ : j < size (push acc (f { val := i, isLt := hin }))
hj : j < size acc
⊢ (push acc (f { val := i, isLt := hin }))[j] = f { val := j, isLt := (_ : j < n) }

tactic: simp [get_push, *]
state_before: case hacc.inr
n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : i < n
this : 1 + (n - (i + 1)) = n - i
j : Nat
hj✝ : j < size (push acc (f { val := i, isLt := hin }))
hj : j = size acc
⊢ (push acc (f { val := i, isLt := hin }))[j] = f { val := j, isLt := (_ : j < n) }

tactic: simp [hin, hacc k (Nat.lt_of_lt_of_le hki (Nat.le_of_not_lt (hi ▸ hin)))]
state_before: n : Nat
α : Type u_1
f : Fin n → α
i : Nat
acc : Array α
k : Nat
hki : k < n
hin✝ : i ≤ n
hi : i = size acc
hacc : ∀ (j : Nat) (hj : j < size acc), acc[j] = f { val := j, isLt := (_ : j < n) }
hin : ¬i < n
⊢ (if h : i < n then ofFn.go f (i + 1) (push acc (f { val := i, isLt := h })) else acc)[k] = f { val := k, isLt := hki }