[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : a ∈ b :: l
⊢ a = b ∨ a ≠ b ∧ a ∈ l
[PROOFSTEP]
by_cases hab : a = b
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : a ∈ b :: l
hab : a = b
⊢ a = b ∨ a ≠ b ∧ a ∈ l
[PROOFSTEP]
exact Or.inl hab
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : a ∈ b :: l
hab : ¬a = b
⊢ a = b ∨ a ≠ b ∧ a ∈ l
[PROOFSTEP]
exact ((List.mem_cons.1 h).elim Or.inl (fun h => Or.inr ⟨hab, h⟩))
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
h : a ∈ l
⊢ ∃ s t, l = s ++ a :: t
[PROOFSTEP]
induction' l with b l ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
h✝ : a ∈ l
h : a ∈ []
⊢ ∃ s t, [] = s ++ a :: t
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l✝ : List α
h✝ : a ∈ l✝
b : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
h : a ∈ b :: l
⊢ ∃ s t, b :: l = s ++ a :: t
[PROOFSTEP]
{cases h
}
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
h✝ : a ∈ l
h : a ∈ []
⊢ ∃ s t, [] = s ++ a :: t
[PROOFSTEP]
cases h
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l✝ : List α
h✝ : a ∈ l✝
b : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
h : a ∈ b :: l
⊢ ∃ s t, b :: l = s ++ a :: t
[PROOFSTEP]
rcases h with (_ | ⟨_, h⟩)
[GOAL]
case cons.head
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l✝ : List α
h : a ∈ l✝
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
⊢ ∃ s t, a :: l = s ++ a :: t
[PROOFSTEP]
exact ⟨[], l, rfl⟩
[GOAL]
case cons.tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l✝ : List α
h✝ : a ∈ l✝
b : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
h : Mem a l
⊢ ∃ s t, b :: l = s ++ a :: t
[PROOFSTEP]
rcases ih h with ⟨s, t, rfl⟩
[GOAL]
case cons.tail.intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
h✝ : a ∈ l
b : α
s t : List α
ih : a ∈ s ++ a :: t → ∃ s_1 t_1, s ++ a :: t = s_1 ++ a :: t_1
h : Mem a (s ++ a :: t)
⊢ ∃ s_1 t_1, b :: (s ++ a :: t) = s_1 ++ a :: t_1
[PROOFSTEP]
exact ⟨b :: s, t, rfl⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
hf : Involutive f
x : α
l : List α
⊢ (∃ y, y ∈ l ∧ f y = x) → f x ∈ l
[PROOFSTEP]
rintro ⟨y, h, rfl⟩
[GOAL]
case intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
hf : Involutive f
l : List α
y : α
h : y ∈ l
⊢ f (f y) ∈ l
[PROOFSTEP]
rwa [hf y]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
hf : Involutive f
a : α
l : List α
⊢ a ∈ map f l ↔ f a ∈ l
[PROOFSTEP]
rw [mem_map, hf.exists_mem_and_apply_eq_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
g : β → List γ
f : α → β
a : α
l : List α
⊢ List.bind (map f (a :: l)) g = List.bind (a :: l) fun a => g (f a)
[PROOFSTEP]
simp only [cons_bind, map_cons, map_bind _ _ l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ Injective length ↔ Subsingleton α
[PROOFSTEP]
constructor
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ Injective length → Subsingleton α
[PROOFSTEP]
intro h
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : Injective length
⊢ Subsingleton α
[PROOFSTEP]
refine ⟨fun x y => ?_⟩
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : Injective length
x y : α
⊢ x = y
[PROOFSTEP]
suffices [x] = [y] by simpa using this
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : Injective length
x y : α
this : [x] = [y]
⊢ x = y
[PROOFSTEP]
simpa using this
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : Injective length
x y : α
⊢ [x] = [y]
[PROOFSTEP]
apply h
[GOAL]
case mp.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : Injective length
x y : α
⊢ length [x] = length [y]
[PROOFSTEP]
rfl
[GOAL]
case mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ Subsingleton α → Injective length
[PROOFSTEP]
intros hα l1 l2 hl
[GOAL]
case mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
l1 l2 : List α
hl : length l1 = length l2
⊢ l1 = l2
[PROOFSTEP]
induction l1 generalizing l2
[GOAL]
case mpr.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
l2 : List α
hl : length [] = length l2
⊢ [] = l2
[PROOFSTEP]
cases l2
[GOAL]
case mpr.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ ⦃l2 : List α⦄, length tail✝ = length l2 → tail✝ = l2
l2 : List α
hl : length (head✝ :: tail✝) = length l2
⊢ head✝ :: tail✝ = l2
[PROOFSTEP]
cases l2
[GOAL]
case mpr.nil.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
hl : length [] = length []
⊢ [] = []
[PROOFSTEP]
rfl
[GOAL]
case mpr.nil.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝ : α
tail✝ : List α
hl : length [] = length (head✝ :: tail✝)
⊢ [] = head✝ :: tail✝
[PROOFSTEP]
cases hl
[GOAL]
case mpr.cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ ⦃l2 : List α⦄, length tail✝ = length l2 → tail✝ = l2
hl : length (head✝ :: tail✝) = length []
⊢ head✝ :: tail✝ = []
[PROOFSTEP]
cases hl
[GOAL]
case mpr.cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
tail_ih✝ : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ head✝¹ :: tail✝¹ = head✝ :: tail✝
[PROOFSTEP]
next ih _ _ =>
  congr
  · exact Subsingleton.elim _ _
  · apply ih; simpa using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ head✝¹ :: tail✝¹ = head✝ :: tail✝
[PROOFSTEP]
congr
[GOAL]
case e_head
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ head✝¹ = head✝
[PROOFSTEP]
exact Subsingleton.elim _ _
[GOAL]
case e_tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ tail✝¹ = tail✝
[PROOFSTEP]
apply ih
[GOAL]
case e_tail.hl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ length tail✝¹ = length tail✝
[PROOFSTEP]
simpa using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
x y : α
h : x ≠ y
⊢ {x, y} = [x, y]
[PROOFSTEP]
rw [insert_neg, singleton_eq]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
x y : α
h : x ≠ y
⊢ ¬x ∈ {y}
[PROOFSTEP]
rwa [singleton_eq, mem_singleton]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
a : α
l : List α
x✝ : ∃ x, x ∈ a :: l ∧ p x
x : α
xal : x ∈ a :: l
px : p x
h : x = a
⊢ p a ∨ ∃ x, x ∈ l ∧ p x
[PROOFSTEP]
rw [← h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
a : α
l : List α
x✝ : ∃ x, x ∈ a :: l ∧ p x
x : α
xal : x ∈ a :: l
px : p x
h : x = a
⊢ p x ∨ ∃ x, x ∈ l ∧ p x
[PROOFSTEP]
left
[GOAL]
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
a : α
l : List α
x✝ : ∃ x, x ∈ a :: l ∧ p x
x : α
xal : x ∈ a :: l
px : p x
h : x = a
⊢ p x
[PROOFSTEP]
exact px
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
⊢ map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂
[PROOFSTEP]
refine' ⟨_, map_subset f⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
⊢ map f l₁ ⊆ map f l₂ → l₁ ⊆ l₂
[PROOFSTEP]
intro h2 x hx
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
h2 : map f l₁ ⊆ map f l₂
x : α
hx : x ∈ l₁
⊢ x ∈ l₂
[PROOFSTEP]
rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩
[GOAL]
case intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
h2 : map f l₁ ⊆ map f l₂
x : α
hx : x ∈ l₁
x' : α
hx' : x' ∈ l₂
hxx' : f x' = f x
⊢ x ∈ l₂
[PROOFSTEP]
cases h hxx'
[GOAL]
case intro.intro.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
h2 : map f l₁ ⊆ map f l₂
x : α
hx : x ∈ l₁
hx' : x ∈ l₂
hxx' : f x = f x
⊢ x ∈ l₂
[PROOFSTEP]
exact hx'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ a b c : List α
x : α
⊢ a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b
[PROOFSTEP]
cases a
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ b c : List α
x : α
⊢ [] ++ b = x :: c ↔ [] = [] ∧ b = x :: c ∨ ∃ a', [] = x :: a' ∧ c = a' ++ b
[PROOFSTEP]
simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, cons.injEq, true_and_iff, false_and_iff, exists_false,
  false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ b c : List α
x head✝ : α
tail✝ : List α
⊢ head✝ :: tail✝ ++ b = x :: c ↔ head✝ :: tail✝ = [] ∧ b = x :: c ∨ ∃ a', head✝ :: tail✝ = x :: a' ∧ c = a' ++ b
[PROOFSTEP]
simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, cons.injEq, true_and_iff, false_and_iff, exists_false,
  false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ a b c : List α
x : α
⊢ x :: c = a ++ b ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b
[PROOFSTEP]
rw [eq_comm, append_eq_cons_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ [] = replicate (length []) a ↔ ∀ (b : α), b ∈ [] → b = a
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ b :: l = replicate (length (b :: l)) a ↔ ∀ (b_1 : α), b_1 ∈ b :: l → b_1 = a
[PROOFSTEP]
simp [eq_replicate_length]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n : ℕ
a : α
⊢ replicate (m + n) a = replicate m a ++ replicate n a
[PROOFSTEP]
induction m
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
⊢ replicate (zero + n) a = replicate zero a ++ replicate n a
[PROOFSTEP]
simp [*, zero_add, succ_add, replicate]
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
n✝ : ℕ
n_ih✝ : replicate (n✝ + n) a = replicate n✝ a ++ replicate n a
⊢ replicate (succ n✝ + n) a = replicate (succ n✝) a ++ replicate n a
[PROOFSTEP]
simp [*, zero_add, succ_add, replicate]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
L : List α
⊢ L ⊆ [a] ↔ ∃ n, L = replicate n a
[PROOFSTEP]
simp only [eq_replicate, subset_def, mem_singleton, exists_eq_left']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
n : ℕ
a : α
⊢ map f (replicate n a) = replicate n (f a)
[PROOFSTEP]
induction n <;> [rfl; simp only [*, replicate, map]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
n : ℕ
a : α
⊢ map f (replicate n a) = replicate n (f a)
[PROOFSTEP]
induction n
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
a : α
⊢ map f (replicate zero a) = replicate zero (f a)
[PROOFSTEP]
rfl
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
a : α
n✝ : ℕ
n_ih✝ : map f (replicate n✝ a) = replicate n✝ (f a)
⊢ map f (replicate (succ n✝) a) = replicate (succ n✝) (f a)
[PROOFSTEP]
simp only [*, replicate, map]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
⊢ tail (replicate n a) = replicate (n - 1) a
[PROOFSTEP]
cases n
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ tail (replicate zero a) = replicate (zero - 1) a
[PROOFSTEP]
rfl
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n✝ : ℕ
⊢ tail (replicate (succ n✝) a) = replicate (succ n✝ - 1) a
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
⊢ join (replicate n []) = []
[PROOFSTEP]
induction n <;> [rfl; simp only [*, replicate, join, append_nil]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
⊢ join (replicate n []) = []
[PROOFSTEP]
induction n
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ join (replicate zero []) = []
[PROOFSTEP]
rfl
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ : ℕ
n_ih✝ : join (replicate n✝ []) = []
⊢ join (replicate (succ n✝) []) = []
[PROOFSTEP]
simp only [*, replicate, join, append_nil]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
⊢ replicate 0 a = replicate 0 b ↔ 0 = 0 ∨ a = b
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
n : ℕ
⊢ a = b ↔ n + 1 = 0 ∨ a = b
[PROOFSTEP]
simp only [n.succ_ne_zero, false_or]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
x y : α
⊢ x ∈ [y] ↔ x = y
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
⊢ concat l₁ a = concat l₂ a → l₁ = l₂
[PROOFSTEP]
intro h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
h : concat l₁ a = concat l₂ a
⊢ l₁ = l₂
[PROOFSTEP]
rw [concat_eq_append, concat_eq_append] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
h : l₁ ++ [a] = l₂ ++ [a]
⊢ l₁ = l₂
[PROOFSTEP]
exact append_right_cancel h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ concat l a = concat l b → a = b
[PROOFSTEP]
intro h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : concat l a = concat l b
⊢ a = b
[PROOFSTEP]
rw [concat_eq_append, concat_eq_append] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : l ++ [a] = l ++ [b]
⊢ a = b
[PROOFSTEP]
exact head_eq_of_cons_eq (append_left_cancel h)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
⊢ concat l a ≠ []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
⊢ concat l₁ a ++ l₂ = l₁ ++ a :: l₂
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
⊢ length (concat l a) = succ (length l)
[PROOFSTEP]
simp only [concat_eq_append, length_append, length]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
⊢ l₁ ++ concat l₂ a = concat (l₁ ++ l₂) a
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
⊢ reverse (a :: l) = concat (reverse l) a
[PROOFSTEP]
simp only [reverse_cons, concat_eq_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
⊢ concat l a = reverse (a :: reverse l)
[PROOFSTEP]
simp only [concat_eq_append, reverse_cons, reverse_reverse]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
f : α → β
l₁ l₂ : List α
⊢ map f (reverseAux l₁ l₂) = reverseAux (map f l₁) (map f l₂)
[PROOFSTEP]
simp only [reverseAux_eq, map_append, map_reverse]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
⊢ length (reverse (replicate n a)) = n
[PROOFSTEP]
rw [length_reverse, length_replicate]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
⊢ isEmpty l = true ↔ l = []
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ isEmpty [] = true ↔ [] = []
[PROOFSTEP]
simp [isEmpty]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : α
tail✝ : List α
⊢ isEmpty (head✝ :: tail✝) = true ↔ head✝ :: tail✝ = []
[PROOFSTEP]
simp [isEmpty]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ length (dropLast (a :: b :: l)) = length (a :: b :: l) - 1
[PROOFSTEP]
rw [dropLast, length_cons, length_cons, length_dropLast (b :: l), succ_sub_one, length_cons, succ_sub_one]
[GOAL]
case x_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ b :: l = [] → False
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
⊢ ∀ (h : l ≠ []), getLast (a :: l) (_ : a :: l ≠ []) = getLast l h
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ ∀ (h : [] ≠ []), getLast [a] (_ : [a] ≠ []) = getLast [] h
[PROOFSTEP]
intros
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (h : tail✝ ≠ []), getLast (a :: tail✝) (_ : a :: tail✝ ≠ []) = getLast tail✝ h
⊢ ∀ (h : head✝ :: tail✝ ≠ []), getLast (a :: head✝ :: tail✝) (_ : a :: head✝ :: tail✝ ≠ []) = getLast (head✝ :: tail✝) h
[PROOFSTEP]
intros
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
h✝ : [] ≠ []
⊢ getLast [a] (_ : [a] ≠ []) = getLast [] h✝
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (h : tail✝ ≠ []), getLast (a :: tail✝) (_ : a :: tail✝ ≠ []) = getLast tail✝ h
h✝ : head✝ :: tail✝ ≠ []
⊢ getLast (a :: head✝ :: tail✝) (_ : a :: head✝ :: tail✝ ≠ []) = getLast (head✝ :: tail✝) h✝
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (h : tail✝ ≠ []), getLast (a :: tail✝) (_ : a :: tail✝ ≠ []) = getLast tail✝ h
h✝ : head✝ :: tail✝ ≠ []
⊢ getLast (a :: head✝ :: tail✝) (_ : a :: head✝ :: tail✝ ≠ []) = getLast (head✝ :: tail✝) h✝
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
⊢ getLast (l ++ [a]) (_ : l ++ [a] ≠ []) = a
[PROOFSTEP]
simp only [getLast_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
h : l₂ ≠ []
⊢ getLast (l₁ ++ l₂) (_ : l₁ ++ l₂ ≠ []) = getLast l₂ h
[PROOFSTEP]
induction' l₁ with _ _ ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
h : l₂ ≠ []
⊢ getLast ([] ++ l₂) (_ : [] ++ l₂ ≠ []) = getLast l₂ h
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
h : l₂ ≠ []
head✝ : α
tail✝ : List α
ih : getLast (tail✝ ++ l₂) (_ : tail✝ ++ l₂ ≠ []) = getLast l₂ h
⊢ getLast (head✝ :: tail✝ ++ l₂) (_ : head✝ :: tail✝ ++ l₂ ≠ []) = getLast l₂ h
[PROOFSTEP]
simp only [cons_append]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
h : l₂ ≠ []
head✝ : α
tail✝ : List α
ih : getLast (tail✝ ++ l₂) (_ : tail✝ ++ l₂ ≠ []) = getLast l₂ h
⊢ getLast (head✝ :: (tail✝ ++ l₂)) (_ : head✝ :: (tail✝ ++ l₂) ≠ []) = getLast l₂ h
[PROOFSTEP]
rw [List.getLast_cons]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
h : l₂ ≠ []
head✝ : α
tail✝ : List α
ih : getLast (tail✝ ++ l₂) (_ : tail✝ ++ l₂ ≠ []) = getLast l₂ h
⊢ getLast (tail✝ ++ l₂) ?cons = getLast l₂ h
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
h : l₂ ≠ []
head✝ : α
tail✝ : List α
ih : getLast (tail✝ ++ l₂) (_ : tail✝ ++ l₂ ≠ []) = getLast l₂ h
⊢ tail✝ ++ l₂ ≠ []
[PROOFSTEP]
exact ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : a :: b :: l ≠ []
⊢ dropLast (a :: b :: l) ++ [getLast (a :: b :: l) h] = a :: b :: l
[PROOFSTEP]
rw [dropLast_cons_cons, cons_append, getLast_cons (cons_ne_nil _ _)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : a :: b :: l ≠ []
⊢ a :: (dropLast (b :: l) ++ [getLast (b :: l) (_ : b :: l ≠ [])]) = a :: b :: l
[PROOFSTEP]
congr
[GOAL]
case e_tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : a :: b :: l ≠ []
⊢ dropLast (b :: l) ++ [getLast (b :: l) (_ : b :: l ≠ [])] = b :: l
[PROOFSTEP]
exact dropLast_append_getLast (cons_ne_nil b l)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
h₁ : l₁ ≠ []
h₂ : l₂ ≠ []
h₃ : l₁ = l₂
⊢ getLast l₁ h₁ = getLast l₂ h₂
[PROOFSTEP]
subst l₁
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
h₂ h₁ : l₂ ≠ []
⊢ getLast l₂ h₁ = getLast l₂ h₂
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
x✝ : [a] ≠ []
⊢ getLast [a] x✝ ∈ [a]
[PROOFSTEP]
simp only [getLast, mem_singleton]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : a :: b :: l ≠ []
⊢ getLast (a :: b :: l) h ∈ b :: l
[PROOFSTEP]
rw [getLast_cons_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
h : a :: b :: l ≠ []
⊢ getLast (b :: l) (_ : b :: l ≠ []) ∈ b :: l
[PROOFSTEP]
exact getLast_mem (cons_ne_nil b l)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : ℕ
a : α
⊢ getLast (replicate (m + 1) a) (_ : replicate (m + 1) a ≠ []) = a
[PROOFSTEP]
simp only [replicate_succ']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : ℕ
a : α
⊢ getLast (replicate m a ++ [a]) (_ : replicate m a ++ [a] ≠ []) = a
[PROOFSTEP]
exact getLast_append_singleton _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ Option.isNone (getLast? []) = true ↔ [] = []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ Option.isNone (getLast? [a]) = true ↔ [a] = []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ Option.isNone (getLast? (a :: b :: l)) = true ↔ a :: b :: l = []
[PROOFSTEP]
simp [@getLast?_isNone (b :: l)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ Option.isSome (getLast? []) = true ↔ [] ≠ []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ Option.isSome (getLast? [a]) = true ↔ [a] ≠ []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ Option.isSome (getLast? (a :: b :: l)) = true ↔ a :: b :: l ≠ []
[PROOFSTEP]
simp [@getLast?_isSome (b :: l)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
hx : x ∈ getLast? []
⊢ False
[PROOFSTEP]
simp at hx 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
hx : x ∈ getLast? [a]
⊢ a = x
[PROOFSTEP]
simpa using hx
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
x : α
hx : x ∈ getLast? (a :: b :: l)
⊢ ∃ h, x = getLast (a :: b :: l) h
[PROOFSTEP]
rw [getLast?_cons_cons] at hx 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
x : α
hx : x ∈ getLast? (b :: l)
⊢ ∃ h, x = getLast (a :: b :: l) h
[PROOFSTEP]
rcases mem_getLast?_eq_getLast hx with ⟨_, h₂⟩
[GOAL]
case intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
x : α
hx : x ∈ getLast? (b :: l)
w✝ : b :: l ≠ []
h₂ : x = getLast (b :: l) w✝
⊢ ∃ h, x = getLast (a :: b :: l) h
[PROOFSTEP]
use cons_ne_nil _ _
[GOAL]
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
x : α
hx : x ∈ getLast? (b :: l)
w✝ : b :: l ≠ []
h₂ : x = getLast (b :: l) w✝
⊢ x = getLast (a :: b :: l) (_ : a :: b :: l ≠ [])
[PROOFSTEP]
assumption
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x y : α
x✝ : x ∈ getLast? []
⊢ x ∈ getLast? [y]
[PROOFSTEP]
contradiction
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
c : α
hc : c ∈ getLast? (a :: b :: l)
⊢ dropLast (a :: b :: l) ++ [c] = a :: b :: l
[PROOFSTEP]
rw [getLast?_cons_cons] at hc 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
c : α
hc : c ∈ getLast? (b :: l)
⊢ dropLast (a :: b :: l) ++ [c] = a :: b :: l
[PROOFSTEP]
rw [dropLast_cons_cons, cons_append, dropLast_append_getLast? _ hc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
⊢ getLastI [] = Option.iget (getLast? [])
[PROOFSTEP]
simp [getLastI, Inhabited.default]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
head✝¹ head✝ c : α
l : List α
⊢ getLastI (head✝¹ :: head✝ :: c :: l) = Option.iget (getLast? (head✝¹ :: head✝ :: c :: l))
[PROOFSTEP]
simp [getLastI, getLastI_eq_getLast? (c :: l)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
b c : α
l₁ : List α
a : α
l₂ : List α
⊢ getLast? (b :: c :: l₁ ++ a :: l₂) = getLast? (a :: l₂)
[PROOFSTEP]
rw [cons_append, cons_append, getLast?_cons_cons, ← cons_append, getLast?_append_cons (c :: l₁)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ l₁ : List α
hl₂ : [] ≠ []
⊢ getLast? (l₁ ++ []) = getLast? []
[PROOFSTEP]
contradiction
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
x : α
h : x ∈ getLast? l₂
⊢ x ∈ getLast? (l₁ ++ l₂)
[PROOFSTEP]
cases l₂
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ l₁ : List α
x : α
h : x ∈ getLast? []
⊢ x ∈ getLast? (l₁ ++ [])
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ l₁ : List α
x head✝ : α
tail✝ : List α
h : x ∈ getLast? (head✝ :: tail✝)
⊢ x ∈ getLast? (l₁ ++ head✝ :: tail✝)
[PROOFSTEP]
rw [List.getLast?_append_cons]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ l₁ : List α
x head✝ : α
tail✝ : List α
h : x ∈ getLast? (head✝ :: tail✝)
⊢ x ∈ getLast? (head✝ :: tail✝)
[PROOFSTEP]
exact h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
⊢ head! l = Option.iget (head? l)
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
⊢ head! [] = Option.iget (head? [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
head✝ : α
tail✝ : List α
⊢ head! (head✝ :: tail✝) = Option.iget (head? (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x a : α
l : List α
h : x ∈ head? (a :: l)
⊢ a :: l = x :: tail (a :: l)
[PROOFSTEP]
simp only [head?, Option.mem_def, Option.some_inj] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x a : α
l : List α
h : a = x
⊢ a :: l = x :: tail (a :: l)
[PROOFSTEP]
exact h ▸ rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
t s : List α
h : s ≠ []
⊢ head! (s ++ t) = head! s
[PROOFSTEP]
induction s
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
t : List α
h : [] ≠ []
⊢ head! ([] ++ t) = head! []
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
t : List α
head✝ : α
tail✝ : List α
tail_ih✝ : tail✝ ≠ [] → head! (tail✝ ++ t) = head! tail✝
h : head✝ :: tail✝ ≠ []
⊢ head! (head✝ :: tail✝ ++ t) = head! (head✝ :: tail✝)
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
t : List α
head✝ : α
tail✝ : List α
tail_ih✝ : tail✝ ≠ [] → head! (tail✝ ++ t) = head! tail✝
h : head✝ :: tail✝ ≠ []
⊢ head! (head✝ :: tail✝ ++ t) = head! (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ s t : List α
x : α
h : x ∈ head? s
⊢ x ∈ head? (s ++ t)
[PROOFSTEP]
cases s
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ t : List α
x : α
h : x ∈ head? []
⊢ x ∈ head? ([] ++ t)
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ t : List α
x head✝ : α
tail✝ : List α
h : x ∈ head? (head✝ :: tail✝)
⊢ x ∈ head? (head✝ :: tail✝ ++ t)
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ t : List α
x head✝ : α
tail✝ : List α
h : x ∈ head? (head✝ :: tail✝)
⊢ x ∈ head? (head✝ :: tail✝ ++ t)
[PROOFSTEP]
exact h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
h : l ≠ []
⊢ tail (l ++ [a]) = tail l ++ [a]
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
h : [] ≠ []
⊢ tail ([] ++ [a]) = tail [] ++ [a]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
tail_ih✝ : tail✝ ≠ [] → tail (tail✝ ++ [a]) = tail tail✝ ++ [a]
h : head✝ :: tail✝ ≠ []
⊢ tail (head✝ :: tail✝ ++ [a]) = tail (head✝ :: tail✝) ++ [a]
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
tail_ih✝ : tail✝ ≠ [] → tail (tail✝ ++ [a]) = tail tail✝ ++ [a]
h : head✝ :: tail✝ ≠ []
⊢ tail (head✝ :: tail✝ ++ [a]) = tail (head✝ :: tail✝) ++ [a]
[PROOFSTEP]
rw [tail, cons_append, tail]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
h : a ∈ head? []
⊢ a :: tail [] = []
[PROOFSTEP]
contradiction
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
b : α
l : List α
a : α
h : a ∈ head? (b :: l)
⊢ a :: tail (b :: l) = b :: l
[PROOFSTEP]
simp at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
b : α
l : List α
a : α
h : b = a
⊢ a :: tail (b :: l) = b :: l
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
h : [] ≠ []
⊢ head! [] ∈ head? []
[PROOFSTEP]
contradiction
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
h : l ≠ []
⊢ head! l ∈ l
[PROOFSTEP]
have h' := mem_cons_self l.head! l.tail
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
h : l ≠ []
h' : head! l ∈ head! l :: tail l
⊢ head! l ∈ l
[PROOFSTEP]
rwa [cons_head!_tail h] at h' 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
⊢ head? (map f l) = Option.map f (head? l)
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ head? (map f []) = Option.map f (head? [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
head✝ : α
tail✝ : List α
⊢ head? (map f (head✝ :: tail✝)) = Option.map f (head? (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l l' : List α
h : l ≠ []
⊢ tail (l ++ l') = tail l ++ l'
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l' : List α
h : [] ≠ []
⊢ tail ([] ++ l') = tail [] ++ l'
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l' : List α
head✝ : α
tail✝ : List α
h : head✝ :: tail✝ ≠ []
⊢ tail (head✝ :: tail✝ ++ l') = tail (head✝ :: tail✝) ++ l'
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i : ℕ
h : i < length (tail l)
⊢ i + 1 < length l
[PROOFSTEP]
simpa [← lt_tsub_iff_right] using h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i : ℕ
h : i < length (tail l)
h' : optParam (i + 1 < length l) (_ : i + 1 < length l)
⊢ nthLe (tail l) i h = nthLe l (i + 1) h'
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
i : ℕ
h : i < length (tail [])
h' : optParam (i + 1 < length []) (_ : i + 1 < length [])
⊢ nthLe (tail []) i h = nthLe [] (i + 1) h'
[PROOFSTEP]
cases h
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
i : ℕ
head✝ : α
tail✝ : List α
h : i < length (tail (head✝ :: tail✝))
h' : optParam (i + 1 < length (head✝ :: tail✝)) (_ : i + 1 < length (head✝ :: tail✝))
⊢ nthLe (tail (head✝ :: tail✝)) i h = nthLe (head✝ :: tail✝) (i + 1) h'
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hn : n ≠ 0
h : n < length (a :: l)
⊢ n - 1 < length l
[PROOFSTEP]
contrapose! h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hn : n ≠ 0
h : length l ≤ n - 1
⊢ length (a :: l) ≤ n
[PROOFSTEP]
rw [length_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hn : n ≠ 0
h : length l ≤ n - 1
⊢ succ (length l) ≤ n
[PROOFSTEP]
convert succ_le_succ h
[GOAL]
case h.e'_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hn : n ≠ 0
h : length l ≤ n - 1
⊢ n = succ (n - 1)
[PROOFSTEP]
exact (Nat.succ_pred_eq_of_pos hn.bot_lt).symm
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hl : n < length (a :: l)
⊢ nthLe (a :: l) n hl = if hn : n = 0 then a else nthLe l (n - 1) (_ : n - 1 < length l)
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hl : n < length (a :: l)
h : n = 0
⊢ nthLe (a :: l) n hl = a
[PROOFSTEP]
simp [nthLe, h]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
hl : n < length (a :: l)
h : ¬n = 0
⊢ nthLe (a :: l) n hl = nthLe l (n - 1) (_ : n - 1 < length l)
[PROOFSTEP]
cases l
[GOAL]
case neg.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
h : ¬n = 0
hl : n < length [a]
⊢ nthLe [a] n hl = nthLe [] (n - 1) (_ : n - 1 < length [])
[PROOFSTEP]
rw [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at hl 
[GOAL]
case neg.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
h : ¬n = 0
hl✝ : n < length [a]
hl : n = 0
⊢ nthLe [a] n hl✝ = nthLe [] (n - 1) (_ : n - 1 < length [])
[PROOFSTEP]
contradiction
[GOAL]
case neg.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
h : ¬n = 0
head✝ : α
tail✝ : List α
hl : n < length (a :: head✝ :: tail✝)
⊢ nthLe (a :: head✝ :: tail✝) n hl = nthLe (head✝ :: tail✝) (n - 1) (_ : n - 1 < length (head✝ :: tail✝))
[PROOFSTEP]
cases n
[GOAL]
case neg.cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
h : ¬zero = 0
hl : zero < length (a :: head✝ :: tail✝)
⊢ nthLe (a :: head✝ :: tail✝) zero hl = nthLe (head✝ :: tail✝) (zero - 1) (_ : zero - 1 < length (head✝ :: tail✝))
[PROOFSTEP]
contradiction
[GOAL]
case neg.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
n✝ : ℕ
h : ¬succ n✝ = 0
hl : succ n✝ < length (a :: head✝ :: tail✝)
⊢ nthLe (a :: head✝ :: tail✝) (succ n✝) hl =
    nthLe (head✝ :: tail✝) (succ n✝ - 1) (_ : succ n✝ - 1 < length (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
f g : α → α
⊢ modifyHead g (modifyHead f l) = modifyHead (g ∘ f) l
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → α
⊢ modifyHead g (modifyHead f []) = modifyHead (g ∘ f) []
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → α
head✝ : α
tail✝ : List α
⊢ modifyHead g (modifyHead f (head✝ :: tail✝)) = modifyHead (g ∘ f) (head✝ :: tail✝)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
⊢ C l
[PROOFSTEP]
rw [← reverse_reverse l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
⊢ C (reverse (reverse l))
[PROOFSTEP]
match h : (reverse l) with
| [] => exact H0
|
head ::
    tail =>
  have : tail.length < l.length := by
    rw [← length_reverse l, h, length_cons]
    simp [Nat.lt_succ]
  let ih := reverseRecOn (reverse tail) H0 H1
  rw [reverse_cons]
  exact H1 _ _ ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
h : reverse l = []
⊢ C (reverse [])
[PROOFSTEP]
exact H0
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
head : α
tail : List α
h : reverse l = head :: tail
⊢ C (reverse (head :: tail))
[PROOFSTEP]
have : tail.length < l.length := by
  rw [← length_reverse l, h, length_cons]
  simp [Nat.lt_succ]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
head : α
tail : List α
h : reverse l = head :: tail
⊢ length tail < length l
[PROOFSTEP]
rw [← length_reverse l, h, length_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
head : α
tail : List α
h : reverse l = head :: tail
⊢ length tail < succ (length tail)
[PROOFSTEP]
simp [Nat.lt_succ]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
head : α
tail : List α
h : reverse l = head :: tail
this : length tail < length l
⊢ C (reverse (head :: tail))
[PROOFSTEP]
let ih := reverseRecOn (reverse tail) H0 H1
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
head : α
tail : List α
h : reverse l = head :: tail
this : length tail < length l
ih : C (reverse tail) := reverseRecOn (reverse tail) H0 H1
⊢ C (reverse (head :: tail))
[PROOFSTEP]
rw [reverse_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
l : List α
H0 : C []
H1 : (l : List α) → (a : α) → C l → C (l ++ [a])
head : α
tail : List α
h : reverse l = head :: tail
this : length tail < length l
ih : C (reverse tail) := reverseRecOn (reverse tail) H0 H1
⊢ C (reverse tail ++ [head])
[PROOFSTEP]
exact H1 _ _ ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
H0 : C []
H1 : (a : α) → C [a]
Hn : (a : α) → (l : List α) → (b : α) → C l → C (a :: (l ++ [b]))
a b : α
l : List α
⊢ C (a :: b :: l)
[PROOFSTEP]
let l' := dropLast (b :: l)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
H0 : C []
H1 : (a : α) → C [a]
Hn : (a : α) → (l : List α) → (b : α) → C l → C (a :: (l ++ [b]))
a b : α
l : List α
l' : List α := dropLast (b :: l)
⊢ C (a :: b :: l)
[PROOFSTEP]
let b' := getLast (b :: l) (cons_ne_nil _ _)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
H0 : C []
H1 : (a : α) → C [a]
Hn : (a : α) → (l : List α) → (b : α) → C l → C (a :: (l ++ [b]))
a b : α
l : List α
l' : List α := dropLast (b :: l)
b' : α := getLast (b :: l) (_ : b :: l ≠ [])
⊢ C (a :: b :: l)
[PROOFSTEP]
rw [← dropLast_append_getLast (cons_ne_nil b l)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
H0 : C []
H1 : (a : α) → C [a]
Hn : (a : α) → (l : List α) → (b : α) → C l → C (a :: (l ++ [b]))
a b : α
l : List α
l' : List α := dropLast (b :: l)
b' : α := getLast (b :: l) (_ : b :: l ≠ [])
⊢ C (a :: (dropLast (b :: l) ++ [getLast (b :: l) (_ : b :: l ≠ [])]))
[PROOFSTEP]
have : C l' := bidirectionalRec H0 H1 Hn l'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : List α → Sort u_2
H0 : C []
H1 : (a : α) → C [a]
Hn : (a : α) → (l : List α) → (b : α) → C l → C (a :: (l ++ [b]))
a b : α
l : List α
l' : List α := dropLast (b :: l)
b' : α := getLast (b :: l) (_ : b :: l ≠ [])
this : C l'
⊢ C (a :: (dropLast (b :: l) ++ [getLast (b :: l) (_ : b :: l ≠ [])]))
[PROOFSTEP]
exact Hn a l' b' this
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
n : ℕ
⊢ (∃ k, k ≤ n ∧ l = replicate k a) → l <+ replicate n a
[PROOFSTEP]
rintro ⟨k, h, rfl⟩
[GOAL]
case intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n k : ℕ
h : k ≤ n
⊢ replicate k a <+ replicate n a
[PROOFSTEP]
exact (replicate_sublist_replicate _).mpr h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l✝ : List α
p : α → Bool
l : List α
n : ℕ
⊢ findIdx.go p l (n + 1) = findIdx.go p l n + 1
[PROOFSTEP]
cases l with
| nil => unfold List.findIdx.go; exact Nat.succ_eq_add_one n
| cons head tail =>
  unfold List.findIdx.go
  cases p head <;> simp only [cond_false, cond_true]
  exact
    findIdx_go_succ p tail
      (n + 1)
        -- indexOf_cons_eq _ rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l✝ : List α
p : α → Bool
l : List α
n : ℕ
⊢ findIdx.go p l (n + 1) = findIdx.go p l n + 1
[PROOFSTEP]
cases l with
| nil => unfold List.findIdx.go; exact Nat.succ_eq_add_one n
| cons head tail =>
  unfold List.findIdx.go
  cases p head <;> simp only [cond_false, cond_true]
  exact
    findIdx_go_succ p tail
      (n + 1)
        -- indexOf_cons_eq _ rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
⊢ findIdx.go p [] (n + 1) = findIdx.go p [] n + 1
[PROOFSTEP]

| nil => unfold List.findIdx.go; exact Nat.succ_eq_add_one n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
⊢ findIdx.go p [] (n + 1) = findIdx.go p [] n + 1
[PROOFSTEP]
unfold List.findIdx.go
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
⊢ n + 1 = n + 1
[PROOFSTEP]
exact Nat.succ_eq_add_one n
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
head : α
tail : List α
⊢ findIdx.go p (head :: tail) (n + 1) = findIdx.go p (head :: tail) n + 1
[PROOFSTEP]

| cons head tail =>
  unfold List.findIdx.go
  cases p head <;> simp only [cond_false, cond_true]
  exact
    findIdx_go_succ p tail
      (n + 1)
        -- indexOf_cons_eq _ rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
head : α
tail : List α
⊢ findIdx.go p (head :: tail) (n + 1) = findIdx.go p (head :: tail) n + 1
[PROOFSTEP]
unfold List.findIdx.go
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
head : α
tail : List α
⊢ (bif p head then n + 1 else findIdx.go p tail (n + 1 + 1)) = (bif p head then n else findIdx.go p tail (n + 1)) + 1
[PROOFSTEP]
cases p head
[GOAL]
case cons.false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
head : α
tail : List α
⊢ (bif false then n + 1 else findIdx.go p tail (n + 1 + 1)) = (bif false then n else findIdx.go p tail (n + 1)) + 1
[PROOFSTEP]
simp only [cond_false, cond_true]
[GOAL]
case cons.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
head : α
tail : List α
⊢ (bif true then n + 1 else findIdx.go p tail (n + 1 + 1)) = (bif true then n else findIdx.go p tail (n + 1)) + 1
[PROOFSTEP]
simp only [cond_false, cond_true]
[GOAL]
case cons.false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p✝ : α → Bool
b : α
l : List α
p : α → Bool
n : ℕ
head : α
tail : List α
⊢ findIdx.go p tail (n + 1 + 1) = findIdx.go p tail (n + 1) + 1
[PROOFSTEP]
exact
  findIdx_go_succ p tail
    (n + 1)
      -- indexOf_cons_eq _ rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p : α → Bool
b : α
l : List α
⊢ findIdx p (b :: l) = bif p b then 0 else findIdx p l + 1
[PROOFSTEP]
cases H : p b with
| true => simp [H, findIdx, findIdx.go]
| false => simp [H, findIdx, findIdx.go, findIdx_go_succ]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p : α → Bool
b : α
l : List α
x✝ : Bool
H : p b = x✝
⊢ findIdx p (b :: l) = bif x✝ then 0 else findIdx p l + 1
[PROOFSTEP]
cases H : p b with
| true => simp [H, findIdx, findIdx.go]
| false => simp [H, findIdx, findIdx.go, findIdx_go_succ]
[GOAL]
case true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p : α → Bool
b : α
l : List α
H : p b = true
⊢ findIdx p (b :: l) = bif true then 0 else findIdx p l + 1
[PROOFSTEP]

| true => simp [H, findIdx, findIdx.go]
[GOAL]
case true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p : α → Bool
b : α
l : List α
H : p b = true
⊢ findIdx p (b :: l) = bif true then 0 else findIdx p l + 1
[PROOFSTEP]
simp [H, findIdx, findIdx.go]
[GOAL]
case false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p : α → Bool
b : α
l : List α
H : p b = false
⊢ findIdx p (b :: l) = bif false then 0 else findIdx p l + 1
[PROOFSTEP]

| false => simp [H, findIdx, findIdx.go, findIdx_go_succ]
[GOAL]
case false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
p : α → Bool
b : α
l : List α
H : p b = false
⊢ findIdx p (b :: l) = bif false then 0 else findIdx p l + 1
[PROOFSTEP]
simp [H, findIdx, findIdx.go, findIdx_go_succ]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
⊢ indexOf a (a :: l) = 0
[PROOFSTEP]
rw [indexOf, findIdx_cons, beq_self_eq_true, cond]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
x✝ : a = b
e : a = b := x✝
⊢ indexOf a (b :: l) = 0
[PROOFSTEP]
rw [e]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
x✝ : a = b
e : a = b := x✝
⊢ indexOf b (b :: l) = 0
[PROOFSTEP]
exact indexOf_cons_self b l
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
x✝ : a ≠ b
h : a ≠ b := x✝
⊢ indexOf a (b :: l) = succ (indexOf a l)
[PROOFSTEP]
simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq, h, ite_false]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
⊢ indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l)
[PROOFSTEP]
simp only [indexOf, findIdx_cons, Bool.cond_eq_ite, beq_iff_eq]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
⊢ indexOf a l = length l ↔ ¬a ∈ l
[PROOFSTEP]
induction' l with b l ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
⊢ indexOf a [] = length [] ↔ ¬a ∈ []
[PROOFSTEP]
exact iff_of_true rfl (not_mem_nil _)
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
⊢ indexOf a (b :: l) = length (b :: l) ↔ ¬a ∈ b :: l
[PROOFSTEP]
simp only [length, mem_cons, indexOf_cons]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
⊢ (if a = b then 0 else succ (indexOf a l)) = length l + 1 ↔ ¬(a = b ∨ a ∈ l)
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
h : a = b
⊢ 0 = length l + 1 ↔ ¬(a = b ∨ a ∈ l)
[PROOFSTEP]
exact iff_of_false (by rintro ⟨⟩) fun H => H <| Or.inl h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
h : a = b
⊢ ¬0 = length l + 1
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
h : ¬a = b
⊢ succ (indexOf a l) = length l + 1 ↔ ¬(a = b ∨ a ∈ l)
[PROOFSTEP]
simp only [h, false_or_iff]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
h : ¬a = b
⊢ succ (indexOf a l) = length l + 1 ↔ ¬a ∈ l
[PROOFSTEP]
rw [← ih]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l = length l ↔ ¬a ∈ l
h : ¬a = b
⊢ succ (indexOf a l) = length l + 1 ↔ indexOf a l = length l
[PROOFSTEP]
exact succ_inj'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
⊢ indexOf a l ≤ length l
[PROOFSTEP]
induction' l with b l ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
⊢ indexOf a [] ≤ length []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l ≤ length l
⊢ indexOf a (b :: l) ≤ length (b :: l)
[PROOFSTEP]
simp only [length, indexOf_cons]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l ≤ length l
⊢ (if a = b then 0 else succ (indexOf a l)) ≤ length l + 1
[PROOFSTEP]
by_cases h : a = b
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l ≤ length l
h : a = b
⊢ (if a = b then 0 else succ (indexOf a l)) ≤ length l + 1
[PROOFSTEP]
rw [if_pos h]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l ≤ length l
h : a = b
⊢ 0 ≤ length l + 1
[PROOFSTEP]
exact Nat.zero_le _
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l ≤ length l
h : ¬a = b
⊢ (if a = b then 0 else succ (indexOf a l)) ≤ length l + 1
[PROOFSTEP]
rw [if_neg h]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
ih : indexOf a l ≤ length l
h : ¬a = b
⊢ succ (indexOf a l) ≤ length l + 1
[PROOFSTEP]
exact succ_le_succ ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h : a ∈ l₁
⊢ indexOf a (l₁ ++ l₂) = indexOf a l₁
[PROOFSTEP]
induction' l₁ with d₁ t₁ ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
h : a ∈ []
⊢ indexOf a ([] ++ l₂) = indexOf a []
[PROOFSTEP]
exfalso
[GOAL]
case nil.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
h : a ∈ []
⊢ False
[PROOFSTEP]
exact not_mem_nil a h
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
d₁ : α
t₁ : List α
ih : a ∈ t₁ → indexOf a (t₁ ++ l₂) = indexOf a t₁
h : a ∈ d₁ :: t₁
⊢ indexOf a (d₁ :: t₁ ++ l₂) = indexOf a (d₁ :: t₁)
[PROOFSTEP]
rw [List.cons_append]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
d₁ : α
t₁ : List α
ih : a ∈ t₁ → indexOf a (t₁ ++ l₂) = indexOf a t₁
h : a ∈ d₁ :: t₁
⊢ indexOf a (d₁ :: (t₁ ++ l₂)) = indexOf a (d₁ :: t₁)
[PROOFSTEP]
by_cases hh : a = d₁
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
d₁ : α
t₁ : List α
ih : a ∈ t₁ → indexOf a (t₁ ++ l₂) = indexOf a t₁
h : a ∈ d₁ :: t₁
hh : a = d₁
⊢ indexOf a (d₁ :: (t₁ ++ l₂)) = indexOf a (d₁ :: t₁)
[PROOFSTEP]
iterate 2 rw [indexOf_cons_eq _ hh]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
d₁ : α
t₁ : List α
ih : a ∈ t₁ → indexOf a (t₁ ++ l₂) = indexOf a t₁
h : a ∈ d₁ :: t₁
hh : a = d₁
⊢ indexOf a (d₁ :: (t₁ ++ l₂)) = indexOf a (d₁ :: t₁)
[PROOFSTEP]
rw [indexOf_cons_eq _ hh]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
d₁ : α
t₁ : List α
ih : a ∈ t₁ → indexOf a (t₁ ++ l₂) = indexOf a t₁
h : a ∈ d₁ :: t₁
hh : a = d₁
⊢ 0 = indexOf a (d₁ :: t₁)
[PROOFSTEP]
rw [indexOf_cons_eq _ hh]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : a ∈ l₁
d₁ : α
t₁ : List α
ih : a ∈ t₁ → indexOf a (t₁ ++ l₂) = indexOf a t₁
h : a ∈ d₁ :: t₁
hh : ¬a = d₁
⊢ indexOf a (d₁ :: (t₁ ++ l₂)) = indexOf a (d₁ :: t₁)
[PROOFSTEP]
rw [indexOf_cons_ne _ hh, indexOf_cons_ne _ hh, ih (mem_of_ne_of_mem hh h)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h : ¬a ∈ l₁
⊢ indexOf a (l₁ ++ l₂) = length l₁ + indexOf a l₂
[PROOFSTEP]
induction' l₁ with d₁ t₁ ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : ¬a ∈ l₁
h : ¬a ∈ []
⊢ indexOf a ([] ++ l₂) = length [] + indexOf a l₂
[PROOFSTEP]
rw [List.nil_append, List.length, zero_add]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
h✝ : ¬a ∈ l₁
d₁ : α
t₁ : List α
ih : ¬a ∈ t₁ → indexOf a (t₁ ++ l₂) = length t₁ + indexOf a l₂
h : ¬a ∈ d₁ :: t₁
⊢ indexOf a (d₁ :: t₁ ++ l₂) = length (d₁ :: t₁) + indexOf a l₂
[PROOFSTEP]
rw [List.cons_append, indexOf_cons_ne _ (ne_of_not_mem_cons h), List.length, ih (not_mem_of_not_mem_cons h),
  Nat.succ_add]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
xs : List α
i j : ℕ
h₀ : i < length xs
h₁ : Nodup xs
h₂ : get? xs i = get? xs j
⊢ i = j
[PROOFSTEP]
induction xs generalizing i j with
| nil => cases h₀
| cons x xs tail_ih =>
  cases i <;> cases j
  case zero.zero => rfl
  case succ.succ =>
    congr; cases h₁
    apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
  all_goals (dsimp at h₂ ; cases' h₁ with _ _ h h')
  · cases (h x (mem_iff_get?.mpr ⟨_, h₂.symm⟩) rfl)
  · cases (h x (mem_iff_get?.mpr ⟨_, h₂⟩) rfl)
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
xs : List α
i j : ℕ
h₀ : i < length xs
h₁ : Nodup xs
h₂ : get? xs i = get? xs j
⊢ i = j
[PROOFSTEP]
induction xs generalizing i j with
| nil => cases h₀
| cons x xs tail_ih =>
  cases i <;> cases j
  case zero.zero => rfl
  case succ.succ =>
    congr; cases h₁
    apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
  all_goals (dsimp at h₂ ; cases' h₁ with _ _ h h')
  · cases (h x (mem_iff_get?.mpr ⟨_, h₂.symm⟩) rfl)
  · cases (h x (mem_iff_get?.mpr ⟨_, h₂⟩) rfl)
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
i j : ℕ
h₀ : i < length []
h₁ : Nodup []
h₂ : get? [] i = get? [] j
⊢ i = j
[PROOFSTEP]

| nil => cases h₀
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
i j : ℕ
h₀ : i < length []
h₁ : Nodup []
h₂ : get? [] i = get? [] j
⊢ i = j
[PROOFSTEP]
cases h₀
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
i j : ℕ
h₀ : i < length (x :: xs)
h₁ : Nodup (x :: xs)
h₂ : get? (x :: xs) i = get? (x :: xs) j
⊢ i = j
[PROOFSTEP]

| cons x xs tail_ih =>
  cases i <;> cases j
  case zero.zero => rfl
  case succ.succ =>
    congr; cases h₁
    apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
  all_goals (dsimp at h₂ ; cases' h₁ with _ _ h h')
  · cases (h x (mem_iff_get?.mpr ⟨_, h₂.symm⟩) rfl)
  · cases (h x (mem_iff_get?.mpr ⟨_, h₂⟩) rfl)
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
i j : ℕ
h₀ : i < length (x :: xs)
h₁ : Nodup (x :: xs)
h₂ : get? (x :: xs) i = get? (x :: xs) j
⊢ i = j
[PROOFSTEP]
cases i
[GOAL]
case cons.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
j : ℕ
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
h₂ : get? (x :: xs) zero = get? (x :: xs) j
⊢ zero = j
[PROOFSTEP]
cases j
[GOAL]
case cons.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
j : ℕ
h₁ : Nodup (x :: xs)
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? (x :: xs) (succ n✝) = get? (x :: xs) j
⊢ succ n✝ = j
[PROOFSTEP]
cases j
[GOAL]
case cons.zero.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
h₂ : get? (x :: xs) zero = get? (x :: xs) zero
⊢ zero = zero
case cons.zero.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) zero = get? (x :: xs) (succ n✝)
⊢ zero = succ n✝
case cons.succ.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? (x :: xs) (succ n✝) = get? (x :: xs) zero
⊢ succ n✝ = zero
case cons.succ.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
⊢ succ n✝¹ = succ n✝
[PROOFSTEP]
case zero.zero => rfl
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
h₂ : get? (x :: xs) zero = get? (x :: xs) zero
⊢ zero = zero
[PROOFSTEP]
case zero.zero => rfl
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
h₂ : get? (x :: xs) zero = get? (x :: xs) zero
⊢ zero = zero
[PROOFSTEP]
rfl
[GOAL]
case cons.zero.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) zero = get? (x :: xs) (succ n✝)
⊢ zero = succ n✝
case cons.succ.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? (x :: xs) (succ n✝) = get? (x :: xs) zero
⊢ succ n✝ = zero
case cons.succ.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
⊢ succ n✝¹ = succ n✝
[PROOFSTEP]
case succ.succ =>
  congr; cases h₁
  apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
⊢ succ n✝¹ = succ n✝
[PROOFSTEP]
case succ.succ =>
  congr; cases h₁
  apply tail_ih <;> solve_by_elim [lt_of_succ_lt_succ]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
⊢ succ n✝¹ = succ n✝
[PROOFSTEP]
congr
[GOAL]
case e_n
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
⊢ n✝¹ = n✝
[PROOFSTEP]
cases h₁
[GOAL]
case e_n.cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
a✝¹ : Pairwise (fun x x_1 => x ≠ x_1) xs
a✝ : ∀ (a' : α), a' ∈ xs → x ≠ a'
⊢ n✝¹ = n✝
[PROOFSTEP]
apply tail_ih
[GOAL]
case e_n.cons.h₀
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
a✝¹ : Pairwise (fun x x_1 => x ≠ x_1) xs
a✝ : ∀ (a' : α), a' ∈ xs → x ≠ a'
⊢ n✝¹ < length xs
[PROOFSTEP]
solve_by_elim [lt_of_succ_lt_succ]
[GOAL]
case e_n.cons.h₁
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
a✝¹ : Pairwise (fun x x_1 => x ≠ x_1) xs
a✝ : ∀ (a' : α), a' ∈ xs → x ≠ a'
⊢ Nodup xs
[PROOFSTEP]
solve_by_elim [lt_of_succ_lt_succ]
[GOAL]
case e_n.cons.h₂
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
n✝¹ : ℕ
h₀ : succ n✝¹ < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) (succ n✝¹) = get? (x :: xs) (succ n✝)
a✝¹ : Pairwise (fun x x_1 => x ≠ x_1) xs
a✝ : ∀ (a' : α), a' ∈ xs → x ≠ a'
⊢ get? xs n✝¹ = get? xs n✝
[PROOFSTEP]
solve_by_elim [lt_of_succ_lt_succ]
[GOAL]
case cons.zero.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) zero = get? (x :: xs) (succ n✝)
⊢ zero = succ n✝
case cons.succ.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? (x :: xs) (succ n✝) = get? (x :: xs) zero
⊢ succ n✝ = zero
[PROOFSTEP]
all_goals (dsimp at h₂ ; cases' h₁ with _ _ h h')
[GOAL]
case cons.zero.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
n✝ : ℕ
h₂ : get? (x :: xs) zero = get? (x :: xs) (succ n✝)
⊢ zero = succ n✝
[PROOFSTEP]
dsimp at h₂ 
[GOAL]
case cons.zero.succ
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
h₀ : zero < length (x :: xs)
n✝ : ℕ
h₂ : some x = get? xs n✝
⊢ zero = succ n✝
[PROOFSTEP]
cases' h₁ with _ _ h h'
[GOAL]
case cons.succ.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? (x :: xs) (succ n✝) = get? (x :: xs) zero
⊢ succ n✝ = zero
[PROOFSTEP]
dsimp at h₂ 
[GOAL]
case cons.succ.zero
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₁ : Nodup (x :: xs)
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? xs n✝ = some x
⊢ succ n✝ = zero
[PROOFSTEP]
cases' h₁ with _ _ h h'
[GOAL]
case cons.zero.succ.cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
h₀ : zero < length (x :: xs)
n✝ : ℕ
h₂ : some x = get? xs n✝
h' : Pairwise (fun x x_1 => x ≠ x_1) xs
h : ∀ (a' : α), a' ∈ xs → x ≠ a'
⊢ zero = succ n✝
[PROOFSTEP]
cases (h x (mem_iff_get?.mpr ⟨_, h₂.symm⟩) rfl)
[GOAL]
case cons.succ.zero.cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u
x : α
xs : List α
tail_ih : ∀ {i j : ℕ}, i < length xs → Nodup xs → get? xs i = get? xs j → i = j
n✝ : ℕ
h₀ : succ n✝ < length (x :: xs)
h₂ : get? xs n✝ = some x
h' : Pairwise (fun x x_1 => x ≠ x_1) xs
h : ∀ (a' : α), a' ∈ xs → x ≠ a'
⊢ succ n✝ = zero
[PROOFSTEP]
cases (h x (mem_iff_get?.mpr ⟨_, h₂⟩) rfl)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L L' : List α
h : L = L'
i : ℕ
hi : i < length L
⊢ nthLe L i hi = nthLe L' i (_ : i < length L')
[PROOFSTEP]
congr
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
L : List α
h : 0 < length L
⊢ nthLe L 0 h = head! L
[PROOFSTEP]
cases L
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
h : 0 < length []
⊢ nthLe [] 0 h = head! []
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
head✝ : α
tail✝ : List α
h : 0 < length (head✝ :: tail✝)
⊢ nthLe (head✝ :: tail✝) 0 h = head! (head✝ :: tail✝)
[PROOFSTEP]
cases h
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
head✝ : α
tail✝ : List α
h : 0 < length (head✝ :: tail✝)
⊢ nthLe (head✝ :: tail✝) 0 h = head! (head✝ :: tail✝)
[PROOFSTEP]
simp [nthLe]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l - 1 < length l
⊢ l ≠ []
[PROOFSTEP]
rintro rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : length [] - 1 < length []
⊢ False
[PROOFSTEP]
exact Nat.lt_irrefl 0 h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l - 1 < length l
⊢ l ≠ []
[PROOFSTEP]
rintro rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
h : length [] - 1 < length []
⊢ False
[PROOFSTEP]
exact Nat.lt_irrefl 0 h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
xs : List α
n : ℕ
h : n = length xs
⊢ n < length (x :: xs)
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
h : n < length l
⊢ take 1 (drop n l) = [get l { val := n, isLt := h }]
[PROOFSTEP]
induction' l with x l ih generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : ℕ
h✝ : n✝ < length l
n : ℕ
h : n < length []
⊢ take 1 (drop n []) = [get [] { val := n, isLt := h }]
[PROOFSTEP]
cases h
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ : ℕ
h✝ : n✝ < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]
[PROOFSTEP]
by_cases h₁ : l = []
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ : ℕ
h✝ : n✝ < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : l = []
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]
[PROOFSTEP]
subst h₁
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : ℕ
h✝ : n✝ < length l
x : α
n : ℕ
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
h : n < length [x]
⊢ take 1 (drop n [x]) = [get [x] { val := n, isLt := h }]
[PROOFSTEP]
rw [get_singleton]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : ℕ
h✝ : n✝ < length l
x : α
n : ℕ
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
h : n < length [x]
⊢ take 1 (drop n [x]) = [x]
[PROOFSTEP]
simp [lt_succ_iff] at h 
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : ℕ
h✝ : n✝ < length l
x : α
n : ℕ
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
h : n = 0
⊢ take 1 (drop n [x]) = [x]
[PROOFSTEP]
subst h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
h : n < length l
x : α
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
⊢ take 1 (drop 0 [x]) = [x]
[PROOFSTEP]
simp
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ : ℕ
h✝ : n✝ < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : ¬l = []
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]
[PROOFSTEP]
have h₂ := h
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ : ℕ
h✝ : n✝ < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : ¬l = []
h₂ : n < length (x :: l)
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]
[PROOFSTEP]
rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂ 
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ : ℕ
h✝ : n✝ < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : ¬l = []
h₂ : n = length l ∨ n < length l
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]
[PROOFSTEP]
cases n
[GOAL]
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n : ℕ
h✝ : n < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
h₁ : ¬l = []
h : zero < length (x :: l)
h₂ : zero = length l ∨ zero < length l
⊢ take 1 (drop zero (x :: l)) = [get (x :: l) { val := zero, isLt := h }]
[PROOFSTEP]
simp [get]
[GOAL]
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n : ℕ
h✝ : n < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
h₁ : ¬l = []
n✝ : ℕ
h : succ n✝ < length (x :: l)
h₂ : succ n✝ = length l ∨ succ n✝ < length l
⊢ take 1 (drop (succ n✝) (x :: l)) = [get (x :: l) { val := succ n✝, isLt := h }]
[PROOFSTEP]
rw [drop, get]
[GOAL]
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n : ℕ
h✝ : n < length l✝
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
h₁ : ¬l = []
n✝ : ℕ
h : succ n✝ < length (x :: l)
h₂ : succ n✝ = length l ∨ succ n✝ < length l
⊢ take 1 (drop n✝ l) = [get l { val := n✝, isLt := (_ : succ n✝ ≤ length l) }]
[PROOFSTEP]
apply ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : indexOf a (b :: l) < length (b :: l)
⊢ get (b :: l) { val := indexOf a (b :: l), isLt := h } = a
[PROOFSTEP]
by_cases h' : a = b
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : indexOf a (b :: l) < length (b :: l)
h' : a = b
⊢ get (b :: l) { val := indexOf a (b :: l), isLt := h } = a
[PROOFSTEP]
simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : indexOf a (b :: l) < length (b :: l)
h' : ¬a = b
⊢ get (b :: l) { val := indexOf a (b :: l), isLt := h } = a
[PROOFSTEP]
simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
h : a ∈ l
⊢ get? l (indexOf a l) = some a
[PROOFSTEP]
rw [nthLe_get?, indexOf_nthLe (indexOf_lt_length.2 h)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
⊢ ∀ (h1 : i + length (a :: l) < length (reverseAux (a :: l) r)) (h2 : i < length r),
    get (reverseAux (a :: l) r) { val := i + length (a :: l), isLt := h1 } = get r { val := i, isLt := h2 }
[PROOFSTEP]
rw [show i + length (a :: l) = i + 1 + length l from add_right_comm i (length l) 1]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
⊢ ∀ (h1 : i + 1 + length l < length (reverseAux (a :: l) r)) (h2 : i < length r),
    get (reverseAux (a :: l) r) { val := i + 1 + length l, isLt := h1 } = get r { val := i, isLt := h2 }
[PROOFSTEP]
exact fun h1 h2 => get_reverse_aux₁ l (a :: r) (i + 1) h1 (succ_lt_succ h2)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
⊢ x = y
[PROOFSTEP]
have x_eq_y : get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ = get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
  simp only [h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
⊢ get l { val := indexOf x l, isLt := (_ : indexOf x l < length l) } =
    get l { val := indexOf y l, isLt := (_ : indexOf y l < length l) }
[PROOFSTEP]
simp only [h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
x_eq_y :
  get l { val := indexOf x l, isLt := (_ : indexOf x l < length l) } =
    get l { val := indexOf y l, isLt := (_ : indexOf y l < length l) }
⊢ x = y
[PROOFSTEP]
simp only [indexOf_get] at x_eq_y 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
x_eq_y : x = y
⊢ x = y
[PROOFSTEP]
exact x_eq_y
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : x = y
⊢ indexOf x l = indexOf y l
[PROOFSTEP]
subst h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x : α
hx hy : x ∈ l
⊢ indexOf x l = indexOf x l
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
h1 : length (a :: l) - 1 - 0 < length (reverseAux (a :: l) r)
x✝ : 0 < length (a :: l)
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - 0, isLt := h1 } = get (a :: l) { val := 0, isLt := x✝ }
[PROOFSTEP]
have aux := get_reverse_aux₁ l (a :: r) 0
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
h1 : length (a :: l) - 1 - 0 < length (reverseAux (a :: l) r)
x✝ : 0 < length (a :: l)
aux :
  ∀ (h1 : 0 + length l < length (reverseAux l (a :: r))) (h2 : 0 < length (a :: r)),
    get (reverseAux l (a :: r)) { val := 0 + length l, isLt := h1 } = get (a :: r) { val := 0, isLt := h2 }
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - 0, isLt := h1 } = get (a :: l) { val := 0, isLt := x✝ }
[PROOFSTEP]
rw [zero_add] at aux 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
h1 : length (a :: l) - 1 - 0 < length (reverseAux (a :: l) r)
x✝ : 0 < length (a :: l)
aux :
  ∀ (h1 : length l < length (reverseAux l (a :: r))) (h2 : 0 < length (a :: r)),
    get (reverseAux l (a :: r)) { val := length l, isLt := h1 } = get (a :: r) { val := 0, isLt := h2 }
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - 0, isLt := h1 } = get (a :: l) { val := 0, isLt := x✝ }
[PROOFSTEP]
exact aux _ (zero_lt_succ _)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }
[PROOFSTEP]
have aux := get_reverse_aux₂ l (a :: r) i
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }
[PROOFSTEP]
have heq :=
  calc
    length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm]; rfl
    _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ length (a :: l) - 1 - (i + 1) = length l - (1 + i)
[PROOFSTEP]
rw [add_comm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ length (a :: l) - 1 - (1 + i) = length l - (1 + i)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ length l - (1 + i) = length l - 1 - i
[PROOFSTEP]
rw [← tsub_add_eq_tsub_tsub]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
heq : length (a :: l) - 1 - (i + 1) = length l - 1 - i
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }
[PROOFSTEP]
rw [← heq] at aux 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } = get l { val := i, isLt := h2 }
heq : length (a :: l) - 1 - (i + 1) = length l - 1 - i
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }
[PROOFSTEP]
apply aux
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ nthLe (reverse l) n hn = nthLe l (length l - 1 - n) hn'
[PROOFSTEP]
rw [eq_comm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ nthLe l (length l - 1 - n) hn' = nthLe (reverse l) n hn
[PROOFSTEP]
convert nthLe_reverse l.reverse n (by simpa) hn using 1
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ length (reverse l) - 1 - n < length (reverse (reverse l))
[PROOFSTEP]
simpa
[GOAL]
case h.e'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ nthLe l (length l - 1 - n) hn' =
    nthLe (reverse (reverse l)) (length (reverse l) - 1 - n)
      (_ : length (reverse l) - 1 - n < length (reverse (reverse l)))
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l = 1
⊢ l = [nthLe l 0 (_ : 0 < length l)]
[PROOFSTEP]
refine' ext_get (by convert h) fun n h₁ h₂ => _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l = 1
⊢ length l = length [nthLe l 0 (_ : 0 < length l)]
[PROOFSTEP]
convert h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l = 1
n : ℕ
h₁ : n < length l
h₂ : n < length [nthLe l 0 (_ : 0 < length l)]
⊢ get l { val := n, isLt := h₁ } = get [nthLe l 0 (_ : 0 < length l)] { val := n, isLt := h₂ }
[PROOFSTEP]
simp only [get_singleton]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l = 1
n : ℕ
h₁ : n < length l
h₂ : n < length [nthLe l 0 (_ : 0 < length l)]
⊢ get l { val := n, isLt := h₁ } = nthLe l 0 (_ : 0 < length l)
[PROOFSTEP]
congr
[GOAL]
case e_a.e_val
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : length l = 1
n : ℕ
h₁ : n < length l
h₂ : n < length [nthLe l 0 (_ : 0 < length l)]
⊢ n = 0
[PROOFSTEP]
exact eq_bot_iff.mpr (Nat.lt_succ_iff.mp h₂)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : Fin (length l)
x : α
⊢ get l n = x ↔ get? l ↑n = some x
[PROOFSTEP]
rw [get?_eq_some]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : Fin (length l)
x : α
⊢ get l n = x ↔ ∃ h, get l { val := ↑n, isLt := h } = x
[PROOFSTEP]
simp [n.2]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : List α → List α
m n : ℕ
l : List α
h : n ≤ m
⊢ modifyNthTail g m (modifyNthTail f n l) = modifyNthTail (fun l => modifyNthTail g (m - n) (f l)) n l
[PROOFSTEP]
rcases exists_add_of_le h with ⟨m, rfl⟩
[GOAL]
case intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : List α → List α
n : ℕ
l : List α
m : ℕ
h : n ≤ n + m
⊢ modifyNthTail g (n + m) (modifyNthTail f n l) = modifyNthTail (fun l => modifyNthTail g (n + m - n) (f l)) n l
[PROOFSTEP]
rw [@add_tsub_cancel_left, add_comm, modifyNthTail_modifyNthTail]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : List α → List α
n : ℕ
l : List α
⊢ modifyNthTail g n (modifyNthTail f n l) = modifyNthTail (g ∘ f) n l
[PROOFSTEP]
rw [modifyNthTail_modifyNthTail_le n n l (le_refl n), tsub_self]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : List α → List α
n : ℕ
l : List α
⊢ modifyNthTail (fun l => modifyNthTail g 0 (f l)) n l = modifyNthTail (g ∘ f) n l
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
⊢ removeNth l 0 = modifyNthTail tail 0 l
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ removeNth [] 0 = modifyNthTail tail 0 []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : α
tail✝ : List α
⊢ removeNth (head✝ :: tail✝) 0 = modifyNthTail tail 0 (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
l : List α
⊢ modifyNth f 0 l = Option.getD ((fun a => set l 0 (f a)) <$> get? l 0) l
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
⊢ modifyNth f 0 [] = Option.getD ((fun a => set [] 0 (f a)) <$> get? [] 0) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
head✝ : α
tail✝ : List α
⊢ modifyNth f 0 (head✝ :: tail✝) =
    Option.getD ((fun a => set (head✝ :: tail✝) 0 (f a)) <$> get? (head✝ :: tail✝) 0) (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
n : ℕ
b : α
l : List α
⊢ b :: Option.getD ((fun a => set l n (f a)) <$> get? l n) l =
    Option.getD ((fun a => set (b :: l) (n + 1) (f a)) <$> get? (b :: l) (n + 1)) (b :: l)
[PROOFSTEP]
cases get? l n
[GOAL]
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
n : ℕ
b : α
l : List α
⊢ b :: Option.getD ((fun a => set l n (f a)) <$> none) l =
    Option.getD ((fun a => set (b :: l) (n + 1) (f a)) <$> none) (b :: l)
[PROOFSTEP]
rfl
[GOAL]
case some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
n : ℕ
b : α
l : List α
val✝ : α
⊢ b :: Option.getD ((fun a => set l n (f a)) <$> some val✝) l =
    Option.getD ((fun a => set (b :: l) (n + 1) (f a)) <$> some val✝) (b :: l)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i j : ℕ
h : i ≠ j
a : α
hj : j < length (set l i a)
⊢ j < length l
[PROOFSTEP]
simpa using hj
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i j : ℕ
h : i ≠ j
a : α
hj : j < length (set l i a)
⊢ get (set l i a) { val := j, isLt := hj } = get l { val := j, isLt := (_ : j < length l) }
[PROOFSTEP]
rw [← Option.some_inj, ← List.get?_eq_get, List.get?_set_ne _ _ h, List.get?_eq_get]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i j : ℕ
h : i ≠ j
a : α
hj : j < length (set l i a)
⊢ j < length l
[PROOFSTEP]
simpa using hj
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
l : List α
⊢ removeNth (insertNth n a l) n = l
[PROOFSTEP]
rw [removeNth_eq_nth_tail, insertNth, modifyNthTail_modifyNthTail_same]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
l : List α
⊢ modifyNthTail (tail ∘ cons a) n l = l
[PROOFSTEP]
exact modifyNthTail_id _ _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
as : List α
x✝¹ : 0 < length (head✝ :: as)
x✝ : 0 ≤ 0
⊢ insertNth 0 a (removeNth (head✝ :: as) 0) = removeNth (insertNth (0 + 1) a (head✝ :: as)) 0
[PROOFSTEP]
simp [removeNth, insertNth]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ a b : α
j : ℕ
l : List α
⊢ 0 ≤ j → j ≤ length l → insertNth (j + 1) b (insertNth 0 a l) = insertNth 0 a (insertNth j b l)
[PROOFSTEP]
simp [insertNth]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ a b : α
i j : ℕ
⊢ i + 1 ≤ j + 1 →
    j + 1 ≤ length [] → insertNth (j + 1 + 1) b (insertNth (i + 1) a []) = insertNth (i + 1) a (insertNth (j + 1) b [])
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ a b : α
i j : ℕ
c : α
l : List α
h₀ : i + 1 ≤ j + 1
h₁ : j + 1 ≤ length (c :: l)
⊢ insertNth (j + 1 + 1) b (insertNth (i + 1) a (c :: l)) = insertNth (i + 1) a (insertNth (j + 1) b (c :: l))
[PROOFSTEP]
simp [insertNth]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ a b : α
i j : ℕ
c : α
l : List α
h₀ : i + 1 ≤ j + 1
h₁ : j + 1 ≤ length (c :: l)
⊢ modifyNthTail (cons b) (j + 1) (modifyNthTail (cons a) i l) = modifyNthTail (cons a) i (modifyNthTail (cons b) j l)
[PROOFSTEP]
exact insertNth_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ a b : α
as : List α
x✝ : 0 ≤ length as
⊢ a ∈ insertNth 0 b as ↔ a = b ∨ a ∈ as
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ a b : α
n : ℕ
a' : α
as : List α
h : n + 1 ≤ length (a' :: as)
⊢ a ∈ insertNth (n + 1) b (a' :: as) ↔ a = b ∨ a ∈ a' :: as
[PROOFSTEP]
rw [List.insertNth_succ_cons, mem_cons, mem_insertNth (Nat.le_of_succ_le_succ h), ← or_assoc, @or_comm (a = a'),
  or_assoc, mem_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h : length l < n
⊢ insertNth n x l = l
[PROOFSTEP]
induction' l with hd tl IH generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ : ℕ
h✝ : length l < n✝
n : ℕ
h : length [] < n
⊢ insertNth n x [] = []
[PROOFSTEP]
cases n
[GOAL]
case nil.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h✝ : length l < n
h : length [] < zero
⊢ insertNth zero x [] = []
[PROOFSTEP]
simp at h 
[GOAL]
case nil.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h✝ : length l < n
n✝ : ℕ
h : length [] < succ n✝
⊢ insertNth (succ n✝) x [] = []
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ : ℕ
h✝ : length l < n✝
hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
n : ℕ
h : length (hd :: tl) < n
⊢ insertNth n x (hd :: tl) = hd :: tl
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h✝ : length l < n
hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
h : length (hd :: tl) < zero
⊢ insertNth zero x (hd :: tl) = hd :: tl
[PROOFSTEP]
simp at h 
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h✝ : length l < n
hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
n✝ : ℕ
h : length (hd :: tl) < succ n✝
⊢ insertNth (succ n✝) x (hd :: tl) = hd :: tl
[PROOFSTEP]
simp only [Nat.succ_lt_succ_iff, length] at h 
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h✝ : length l < n
hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
n✝ : ℕ
h : length tl < n✝
⊢ insertNth (succ n✝) x (hd :: tl) = hd :: tl
[PROOFSTEP]
simpa using IH _ h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
⊢ insertNth (length l) x l = l ++ [x]
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
⊢ insertNth (length []) x [] = [] ++ [x]
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x hd : α
tl : List α
IH : insertNth (length tl) x tl = tl ++ [x]
⊢ insertNth (length (hd :: tl)) x (hd :: tl) = hd :: tl ++ [x]
[PROOFSTEP]
simpa using IH
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
⊢ length l ≤ length (insertNth n x l)
[PROOFSTEP]
cases' le_or_lt n l.length with hn hn
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ length l ≤ length (insertNth n x l)
[PROOFSTEP]
rw [length_insertNth _ _ hn]
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ length l ≤ length l + 1
[PROOFSTEP]
exact (Nat.lt_succ_self _).le
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : length l < n
⊢ length l ≤ length (insertNth n x l)
[PROOFSTEP]
rw [insertNth_of_length_lt _ _ _ hn]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
⊢ length (insertNth n x l) ≤ length l + 1
[PROOFSTEP]
cases' le_or_lt n l.length with hn hn
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ length (insertNth n x l) ≤ length l + 1
[PROOFSTEP]
rw [length_insertNth _ _ hn]
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : length l < n
⊢ length (insertNth n x l) ≤ length l + 1
[PROOFSTEP]
rw [insertNth_of_length_lt _ _ _ hn]
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : length l < n
⊢ length l ≤ length l + 1
[PROOFSTEP]
exact (Nat.lt_succ_self _).le
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k : ℕ
hn : k < n
hk : k < length l
hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))
⊢ get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
[PROOFSTEP]
induction' n with n IH generalizing k l
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l✝ : List α
x : α
n k✝ : ℕ
hn✝ : k✝ < n
hk✝ : k✝ < length l✝
hk'✝ : optParam (k✝ < length (insertNth n x l✝)) (_ : k✝ < length (insertNth n x l✝))
l : List α
k : ℕ
hn : k < zero
hk : k < length l
hk' : optParam (k < length (insertNth zero x l)) (_ : k < length (insertNth zero x l))
⊢ get (insertNth zero x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
[PROOFSTEP]
simp at hn 
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l✝ : List α
x : α
n✝ k✝ : ℕ
hn✝ : k✝ < n✝
hk✝ : k✝ < length l✝
hk'✝ : optParam (k✝ < length (insertNth n✝ x l✝)) (_ : k✝ < length (insertNth n✝ x l✝))
n : ℕ
IH :
  ∀ (l : List α) (k : ℕ),
    k < n →
      ∀ (hk : k < length l) (hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))),
        get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
l : List α
k : ℕ
hn : k < succ n
hk : k < length l
hk' : optParam (k < length (insertNth (succ n) x l)) (_ : k < length (insertNth (succ n) x l))
⊢ get (insertNth (succ n) x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
[PROOFSTEP]
cases' l with hd tl
[GOAL]
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ k✝ : ℕ
hn✝ : k✝ < n✝
hk✝ : k✝ < length l
hk'✝ : optParam (k✝ < length (insertNth n✝ x l)) (_ : k✝ < length (insertNth n✝ x l))
n : ℕ
IH :
  ∀ (l : List α) (k : ℕ),
    k < n →
      ∀ (hk : k < length l) (hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))),
        get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
k : ℕ
hn : k < succ n
hk : k < length []
hk' : optParam (k < length (insertNth (succ n) x [])) (_ : k < length (insertNth (succ n) x []))
⊢ get (insertNth (succ n) x []) { val := k, isLt := hk' } = get [] { val := k, isLt := hk }
[PROOFSTEP]
simp
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ k✝ : ℕ
hn✝ : k✝ < n✝
hk✝ : k✝ < length l
hk'✝ : optParam (k✝ < length (insertNth n✝ x l)) (_ : k✝ < length (insertNth n✝ x l))
n : ℕ
IH :
  ∀ (l : List α) (k : ℕ),
    k < n →
      ∀ (hk : k < length l) (hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))),
        get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
k : ℕ
hn : k < succ n
hd : α
tl : List α
hk : k < length (hd :: tl)
hk' : optParam (k < length (insertNth (succ n) x (hd :: tl))) (_ : k < length (insertNth (succ n) x (hd :: tl)))
⊢ get (insertNth (succ n) x (hd :: tl)) { val := k, isLt := hk' } = get (hd :: tl) { val := k, isLt := hk }
[PROOFSTEP]
cases k
[GOAL]
case succ.cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ k : ℕ
hn✝ : k < n✝
hk✝ : k < length l
hk'✝ : optParam (k < length (insertNth n✝ x l)) (_ : k < length (insertNth n✝ x l))
n : ℕ
IH :
  ∀ (l : List α) (k : ℕ),
    k < n →
      ∀ (hk : k < length l) (hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))),
        get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
hd : α
tl : List α
hn : zero < succ n
hk : zero < length (hd :: tl)
hk' : optParam (zero < length (insertNth (succ n) x (hd :: tl))) (_ : zero < length (insertNth (succ n) x (hd :: tl)))
⊢ get (insertNth (succ n) x (hd :: tl)) { val := zero, isLt := hk' } = get (hd :: tl) { val := zero, isLt := hk }
[PROOFSTEP]
simp [get]
[GOAL]
case succ.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝¹ k : ℕ
hn✝ : k < n✝¹
hk✝ : k < length l
hk'✝ : optParam (k < length (insertNth n✝¹ x l)) (_ : k < length (insertNth n✝¹ x l))
n : ℕ
IH :
  ∀ (l : List α) (k : ℕ),
    k < n →
      ∀ (hk : k < length l) (hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))),
        get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
hd : α
tl : List α
n✝ : ℕ
hn : succ n✝ < succ n
hk : succ n✝ < length (hd :: tl)
hk' :
  optParam (succ n✝ < length (insertNth (succ n) x (hd :: tl))) (_ : succ n✝ < length (insertNth (succ n) x (hd :: tl)))
⊢ get (insertNth (succ n) x (hd :: tl)) { val := succ n✝, isLt := hk' } = get (hd :: tl) { val := succ n✝, isLt := hk }
[PROOFSTEP]
rw [Nat.succ_lt_succ_iff] at hn 
[GOAL]
case succ.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝¹ k : ℕ
hn✝ : k < n✝¹
hk✝ : k < length l
hk'✝ : optParam (k < length (insertNth n✝¹ x l)) (_ : k < length (insertNth n✝¹ x l))
n : ℕ
IH :
  ∀ (l : List α) (k : ℕ),
    k < n →
      ∀ (hk : k < length l) (hk' : optParam (k < length (insertNth n x l)) (_ : k < length (insertNth n x l))),
        get (insertNth n x l) { val := k, isLt := hk' } = get l { val := k, isLt := hk }
hd : α
tl : List α
n✝ : ℕ
hn : n✝ < n
hk : succ n✝ < length (hd :: tl)
hk' :
  optParam (succ n✝ < length (insertNth (succ n) x (hd :: tl))) (_ : succ n✝ < length (insertNth (succ n) x (hd :: tl)))
⊢ get (insertNth (succ n) x (hd :: tl)) { val := succ n✝, isLt := hk' } = get (hd :: tl) { val := succ n✝, isLt := hk }
[PROOFSTEP]
simpa using IH _ _ hn _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ n < length (insertNth n x l)
[PROOFSTEP]
rwa [length_insertNth _ _ hn, Nat.lt_succ_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
hn' : optParam (n < length (insertNth n x l)) (_ : n < length (insertNth n x l))
⊢ get (insertNth n x l) { val := n, isLt := hn' } = x
[PROOFSTEP]
induction' l with hd tl IH generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ : ℕ
hn✝ : n✝ ≤ length l
hn'✝ : optParam (n✝ < length (insertNth n✝ x l)) (_ : n✝ < length (insertNth n✝ x l))
n : ℕ
hn : n ≤ length []
hn' : optParam (n < length (insertNth n x [])) (_ : n < length (insertNth n x []))
⊢ get (insertNth n x []) { val := n, isLt := hn' } = x
[PROOFSTEP]
simp only [length, nonpos_iff_eq_zero] at hn 
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ : ℕ
hn✝¹ : n✝ ≤ length l
hn'✝ : optParam (n✝ < length (insertNth n✝ x l)) (_ : n✝ < length (insertNth n✝ x l))
n : ℕ
hn✝ : n ≤ length []
hn' : optParam (n < length (insertNth n x [])) (_ : n < length (insertNth n x []))
hn : n = 0
⊢ get (insertNth n x []) { val := n, isLt := hn' } = x
[PROOFSTEP]
cases hn
[GOAL]
case nil.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn✝ : n ≤ length l
hn'✝ : optParam (n < length (insertNth n x l)) (_ : n < length (insertNth n x l))
hn : 0 ≤ length []
hn' : optParam (0 < length (insertNth 0 x [])) (_ : 0 < length (insertNth 0 x []))
⊢ get (insertNth 0 x []) { val := 0, isLt := hn' } = x
[PROOFSTEP]
simp only [insertNth_zero, get_singleton]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ : ℕ
hn✝ : n✝ ≤ length l
hn'✝ : optParam (n✝ < length (insertNth n✝ x l)) (_ : n✝ < length (insertNth n✝ x l))
hd : α
tl : List α
IH :
  ∀ (n : ℕ) (hn : n ≤ length tl) (hn' : optParam (n < length (insertNth n x tl)) (_ : n < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n, isLt := hn' } = x
n : ℕ
hn : n ≤ length (hd :: tl)
hn' : optParam (n < length (insertNth n x (hd :: tl))) (_ : n < length (insertNth n x (hd :: tl)))
⊢ get (insertNth n x (hd :: tl)) { val := n, isLt := hn' } = x
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn✝ : n ≤ length l
hn'✝ : optParam (n < length (insertNth n x l)) (_ : n < length (insertNth n x l))
hd : α
tl : List α
IH :
  ∀ (n : ℕ) (hn : n ≤ length tl) (hn' : optParam (n < length (insertNth n x tl)) (_ : n < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n, isLt := hn' } = x
hn : zero ≤ length (hd :: tl)
hn' : optParam (zero < length (insertNth zero x (hd :: tl))) (_ : zero < length (insertNth zero x (hd :: tl)))
⊢ get (insertNth zero x (hd :: tl)) { val := zero, isLt := hn' } = x
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn✝ : n ≤ length l
hn'✝ : optParam (n < length (insertNth n x l)) (_ : n < length (insertNth n x l))
hd : α
tl : List α
IH :
  ∀ (n : ℕ) (hn : n ≤ length tl) (hn' : optParam (n < length (insertNth n x tl)) (_ : n < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n, isLt := hn' } = x
n✝ : ℕ
hn : succ n✝ ≤ length (hd :: tl)
hn' :
  optParam (succ n✝ < length (insertNth (succ n✝) x (hd :: tl)))
    (_ : succ n✝ < length (insertNth (succ n✝) x (hd :: tl)))
⊢ get (insertNth (succ n✝) x (hd :: tl)) { val := succ n✝, isLt := hn' } = x
[PROOFSTEP]
simp only [Nat.succ_le_succ_iff, length] at hn 
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn✝¹ : n ≤ length l
hn'✝ : optParam (n < length (insertNth n x l)) (_ : n < length (insertNth n x l))
hd : α
tl : List α
IH :
  ∀ (n : ℕ) (hn : n ≤ length tl) (hn' : optParam (n < length (insertNth n x tl)) (_ : n < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n, isLt := hn' } = x
n✝ : ℕ
hn✝ : succ n✝ ≤ length (hd :: tl)
hn' :
  optParam (succ n✝ < length (insertNth (succ n✝) x (hd :: tl)))
    (_ : succ n✝ < length (insertNth (succ n✝) x (hd :: tl)))
hn : n✝ ≤ length tl
⊢ get (insertNth (succ n✝) x (hd :: tl)) { val := succ n✝, isLt := hn' } = x
[PROOFSTEP]
simpa using IH _ hn
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ n < length (insertNth n x l)
[PROOFSTEP]
rwa [length_insertNth _ _ hn, Nat.lt_succ_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k : ℕ
hk' : n + k < length l
⊢ n + k + 1 < length (insertNth n x l)
[PROOFSTEP]
rw [length_insertNth _ _ (le_self_add.trans hk'.le)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k : ℕ
hk' : n + k < length l
⊢ n + k + 1 < length l + 1
[PROOFSTEP]
exact Nat.succ_lt_succ_iff.2 hk'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k : ℕ
hk' : n + k < length l
hk : optParam (n + k + 1 < length (insertNth n x l)) (_ : n + k + 1 < length (insertNth n x l))
⊢ get (insertNth n x l) { val := n + k + 1, isLt := hk } = get l { val := n + k, isLt := hk' }
[PROOFSTEP]
induction' l with hd tl IH generalizing n k
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ k✝ : ℕ
hk'✝ : n✝ + k✝ < length l
hk✝ : optParam (n✝ + k✝ + 1 < length (insertNth n✝ x l)) (_ : n✝ + k✝ + 1 < length (insertNth n✝ x l))
n k : ℕ
hk' : n + k < length []
hk : optParam (n + k + 1 < length (insertNth n x [])) (_ : n + k + 1 < length (insertNth n x []))
⊢ get (insertNth n x []) { val := n + k + 1, isLt := hk } = get [] { val := n + k, isLt := hk' }
[PROOFSTEP]
simp at hk' 
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n✝ k✝ : ℕ
hk'✝ : n✝ + k✝ < length l
hk✝ : optParam (n✝ + k✝ + 1 < length (insertNth n✝ x l)) (_ : n✝ + k✝ + 1 < length (insertNth n✝ x l))
hd : α
tl : List α
IH :
  ∀ (n k : ℕ) (hk' : n + k < length tl)
    (hk : optParam (n + k + 1 < length (insertNth n x tl)) (_ : n + k + 1 < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n + k + 1, isLt := hk } = get tl { val := n + k, isLt := hk' }
n k : ℕ
hk' : n + k < length (hd :: tl)
hk : optParam (n + k + 1 < length (insertNth n x (hd :: tl))) (_ : n + k + 1 < length (insertNth n x (hd :: tl)))
⊢ get (insertNth n x (hd :: tl)) { val := n + k + 1, isLt := hk } = get (hd :: tl) { val := n + k, isLt := hk' }
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k✝ : ℕ
hk'✝ : n + k✝ < length l
hk✝ : optParam (n + k✝ + 1 < length (insertNth n x l)) (_ : n + k✝ + 1 < length (insertNth n x l))
hd : α
tl : List α
IH :
  ∀ (n k : ℕ) (hk' : n + k < length tl)
    (hk : optParam (n + k + 1 < length (insertNth n x tl)) (_ : n + k + 1 < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n + k + 1, isLt := hk } = get tl { val := n + k, isLt := hk' }
k : ℕ
hk' : zero + k < length (hd :: tl)
hk :
  optParam (zero + k + 1 < length (insertNth zero x (hd :: tl)))
    (_ : zero + k + 1 < length (insertNth zero x (hd :: tl)))
⊢ get (insertNth zero x (hd :: tl)) { val := zero + k + 1, isLt := hk } =
    get (hd :: tl) { val := zero + k, isLt := hk' }
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k✝ : ℕ
hk'✝ : n + k✝ < length l
hk✝ : optParam (n + k✝ + 1 < length (insertNth n x l)) (_ : n + k✝ + 1 < length (insertNth n x l))
hd : α
tl : List α
IH :
  ∀ (n k : ℕ) (hk' : n + k < length tl)
    (hk : optParam (n + k + 1 < length (insertNth n x tl)) (_ : n + k + 1 < length (insertNth n x tl))),
    get (insertNth n x tl) { val := n + k + 1, isLt := hk } = get tl { val := n + k, isLt := hk' }
k n✝ : ℕ
hk' : succ n✝ + k < length (hd :: tl)
hk :
  optParam (succ n✝ + k + 1 < length (insertNth (succ n✝) x (hd :: tl)))
    (_ : succ n✝ + k + 1 < length (insertNth (succ n✝) x (hd :: tl)))
⊢ get (insertNth (succ n✝) x (hd :: tl)) { val := succ n✝ + k + 1, isLt := hk } =
    get (hd :: tl) { val := succ n✝ + k, isLt := hk' }
[PROOFSTEP]
simpa [succ_add] using IH _ _ _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k : ℕ
hk' : n + k < length l
⊢ n + k + 1 < length (insertNth n x l)
[PROOFSTEP]
rw [length_insertNth _ _ (le_self_add.trans hk'.le)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
l : List α
x : α
n k : ℕ
hk' : n + k < length l
⊢ n + k + 1 < length l + 1
[PROOFSTEP]
exact Nat.succ_lt_succ_iff.2 hk'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
x : α
⊢ Injective (insertNth n x)
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
⊢ Injective (insertNth zero x)
[PROOFSTEP]
have : insertNth 0 x = cons x := funext fun _ => rfl
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
this : insertNth 0 x = cons x
⊢ Injective (insertNth zero x)
[PROOFSTEP]
simp [this]
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
n : ℕ
IH : Injective (insertNth n x)
⊢ Injective (insertNth (succ n) x)
[PROOFSTEP]
rintro (_ | ⟨a, as⟩) (_ | ⟨b, bs⟩) h
[GOAL]
case succ.nil.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
n : ℕ
IH : Injective (insertNth n x)
h : insertNth (succ n) x [] = insertNth (succ n) x []
⊢ [] = []
[PROOFSTEP]
simpa [IH.eq_iff] using h
[GOAL]
case succ.nil.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a x : α
n : ℕ
IH : Injective (insertNth n x)
b : α
bs : List α
h : insertNth (succ n) x [] = insertNth (succ n) x (b :: bs)
⊢ [] = b :: bs
[PROOFSTEP]
simpa [IH.eq_iff] using h
[GOAL]
case succ.cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ x : α
n : ℕ
IH : Injective (insertNth n x)
a : α
as : List α
h : insertNth (succ n) x (a :: as) = insertNth (succ n) x []
⊢ a :: as = []
[PROOFSTEP]
simpa [IH.eq_iff] using h
[GOAL]
case succ.cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a✝ x : α
n : ℕ
IH : Injective (insertNth n x)
a : α
as : List α
b : α
bs : List α
h : insertNth (succ n) x (a :: as) = insertNth (succ n) x (b :: bs)
⊢ a :: as = b :: bs
[PROOFSTEP]
simpa [IH.eq_iff] using h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
⊢ map f l = foldr (fun a bs => f a :: bs) [] l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ map f [] = foldr (fun a bs => f a :: bs) [] []
[PROOFSTEP]
simp [*]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
head✝ : α
tail✝ : List α
tail_ih✝ : map f tail✝ = foldr (fun a bs => f a :: bs) [] tail✝
⊢ map f (head✝ :: tail✝) = foldr (fun a bs => f a :: bs) [] (head✝ :: tail✝)
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
a : α
l : List α
h : ∀ (x : α), x ∈ a :: l → f x = g x
⊢ map f (a :: l) = map g (a :: l)
[PROOFSTEP]
let ⟨h₁, h₂⟩ := forall_mem_cons.1 h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
a : α
l : List α
h : ∀ (x : α), x ∈ a :: l → f x = g x
h₁ : f a = g a
h₂ : ∀ (x : α), x ∈ l → f x = g x
⊢ map f (a :: l) = map g (a :: l)
[PROOFSTEP]
rw [map, map, h₁, map_congr h₂]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
l : List α
⊢ map f l = map g l ↔ ∀ (x : α), x ∈ l → f x = g x
[PROOFSTEP]
refine' ⟨_, map_congr⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
l : List α
⊢ map f l = map g l → ∀ (x : α), x ∈ l → f x = g x
[PROOFSTEP]
intro h x hx
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
l : List α
h : map f l = map g l
x : α
hx : x ∈ l
⊢ f x = g x
[PROOFSTEP]
rw [mem_iff_get] at hx 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
l : List α
h : map f l = map g l
x : α
hx : ∃ n, get l n = x
⊢ f x = g x
[PROOFSTEP]
rcases hx with ⟨n, hn, rfl⟩
[GOAL]
case intro.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
l : List α
h : map f l = map g l
n : Fin (length l)
⊢ f (get l n) = g (get l n)
[PROOFSTEP]
rw [get_map_rev f, get_map_rev g]
[GOAL]
case intro.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β
l : List α
h : map f l = map g l
n : Fin (length l)
⊢ get (map f l) { val := ↑n, isLt := (_ : ↑n < length (map f l)) } =
    get (map g l) { val := ↑n, isLt := (_ : ↑n < length (map g l)) }
[PROOFSTEP]
congr!
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
a : α
l : List α
⊢ map f (concat l a) = concat (map f l) (f a)
[PROOFSTEP]
induction l <;> [rfl; simp only [*, concat_eq_append, cons_append, map, map_append]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
a : α
l : List α
⊢ map f (concat l a) = concat (map f l) (f a)
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
a : α
⊢ map f (concat [] a) = concat (map f []) (f a)
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
a head✝ : α
tail✝ : List α
tail_ih✝ : map f (concat tail✝ a) = concat (map f tail✝) (f a)
⊢ map f (concat (head✝ :: tail✝) a) = concat (map f (head✝ :: tail✝)) (f a)
[PROOFSTEP]
simp only [*, concat_eq_append, cons_append, map, map_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
h : ∀ (x : α), f x = x
l : List α
⊢ map f l = l
[PROOFSTEP]
simp [show f = id from funext h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
h : map f l = []
⊢ length l = 0
[PROOFSTEP]
rw [← length_map l f, h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
h : map f l = []
⊢ length [] = 0
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
L : List (List α)
⊢ map f (join L) = join (map (map f) L)
[PROOFSTEP]
induction L <;> [rfl; simp only [*, join, map, map_append]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
L : List (List α)
⊢ map f (join L) = join (map (map f) L)
[PROOFSTEP]
induction L
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ map f (join []) = join (map (map f) [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
head✝ : List α
tail✝ : List (List α)
tail_ih✝ : map f (join tail✝) = join (map (map f) tail✝)
⊢ map f (join (head✝ :: tail✝)) = join (map (map f) (head✝ :: tail✝))
[PROOFSTEP]
simp only [*, join, map, map_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
⊢ List.bind l (List.ret ∘ f) = map f l
[PROOFSTEP]
unfold List.bind
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
⊢ join (map (List.ret ∘ f) l) = map f l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ join (map (List.ret ∘ f) []) = map f []
[PROOFSTEP]
simp [map, join, List.ret, cons_append, nil_append, *] at *
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
head✝ : α
tail✝ : List α
tail_ih✝ : join (map (List.ret ∘ f) tail✝) = map f tail✝
⊢ join (map (List.ret ∘ f) (head✝ :: tail✝)) = map f (head✝ :: tail✝)
[PROOFSTEP]
simp [map, join, List.ret, cons_append, nil_append, *] at *
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
head✝ : α
tail✝ : List α
tail_ih✝ : join (map ((fun a => [a]) ∘ f) tail✝) = map f tail✝
⊢ join (map ((fun a => [a]) ∘ f) tail✝) = map f tail✝
[PROOFSTEP]
assumption
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
⊢ map f (tail l) = tail (map f l)
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ map f (tail []) = tail (map f [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
head✝ : α
tail✝ : List α
⊢ map f (tail (head✝ :: tail✝)) = tail (map f (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ Injective (map f) ↔ Injective f
[PROOFSTEP]
constructor
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ Injective (map f) → Injective f
[PROOFSTEP]
intro h x y hxy
[GOAL]
case mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ Injective f → Injective (map f)
[PROOFSTEP]
intro h x y hxy
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective (map f)
x y : α
hxy : f x = f y
⊢ x = y
[PROOFSTEP]
suffices [x] = [y] by simpa using this
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective (map f)
x y : α
hxy : f x = f y
this : [x] = [y]
⊢ x = y
[PROOFSTEP]
simpa using this
[GOAL]
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective (map f)
x y : α
hxy : f x = f y
⊢ [x] = [y]
[PROOFSTEP]
apply h
[GOAL]
case mp.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective (map f)
x y : α
hxy : f x = f y
⊢ map f [x] = map f [y]
[PROOFSTEP]
simp [hxy]
[GOAL]
case mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective f
x y : List α
hxy : map f x = map f y
⊢ x = y
[PROOFSTEP]
induction' y with yh yt y_ih generalizing x
[GOAL]
case mpr.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective f
x✝ y : List α
hxy✝ : map f x✝ = map f y
x : List α
hxy : map f x = map f []
⊢ x = []
[PROOFSTEP]
simpa using hxy
[GOAL]
case mpr.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective f
x✝ y : List α
hxy✝ : map f x✝ = map f y
yh : α
yt : List α
y_ih : ∀ ⦃x : List α⦄, map f x = map f yt → x = yt
x : List α
hxy : map f x = map f (yh :: yt)
⊢ x = yh :: yt
[PROOFSTEP]
cases x
[GOAL]
case mpr.cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective f
x y : List α
hxy✝ : map f x = map f y
yh : α
yt : List α
y_ih : ∀ ⦃x : List α⦄, map f x = map f yt → x = yt
hxy : map f [] = map f (yh :: yt)
⊢ [] = yh :: yt
[PROOFSTEP]
simp at hxy 
[GOAL]
case mpr.cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective f
x y : List α
hxy✝ : map f x = map f y
yh : α
yt : List α
y_ih : ∀ ⦃x : List α⦄, map f x = map f yt → x = yt
head✝ : α
tail✝ : List α
hxy : map f (head✝ :: tail✝) = map f (yh :: yt)
⊢ head✝ :: tail✝ = yh :: yt
[PROOFSTEP]
simp only [map, cons.injEq] at hxy 
[GOAL]
case mpr.cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
h : Injective f
x y : List α
hxy✝ : map f x = map f y
yh : α
yt : List α
y_ih : ∀ ⦃x : List α⦄, map f x = map f yt → x = yt
head✝ : α
tail✝ : List α
hxy : f head✝ = f yh ∧ map f tail✝ = map f yt
⊢ head✝ :: tail✝ = yh :: yt
[PROOFSTEP]
simp [y_ih hxy.2, h hxy.1]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
g : β → γ
f : α → β
⊢ map g ∘ map f = map (g ∘ f)
[PROOFSTEP]
ext l
[GOAL]
case h.a.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
g : β → γ
f : α → β
l : List α
n✝ : ℕ
a✝ : γ
⊢ a✝ ∈ get? ((map g ∘ map f) l) n✝ ↔ a✝ ∈ get? (map (g ∘ f) l) n✝
[PROOFSTEP]
rw [comp_map, Function.comp_apply]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
p : α → Bool
as : List α
⊢ map f (filter p as) = foldr (fun a bs => bif p a then f a :: bs else bs) [] as
[PROOFSTEP]
induction' as with head tail
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
p : α → Bool
⊢ map f (filter p []) = foldr (fun a bs => bif p a then f a :: bs else bs) [] []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
p : α → Bool
head : α
tail : List α
tail_ih✝ : map f (filter p tail) = foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
⊢ map f (filter p (head :: tail)) = foldr (fun a bs => bif p a then f a :: bs else bs) [] (head :: tail)
[PROOFSTEP]
simp only [foldr]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
p : α → Bool
head : α
tail : List α
tail_ih✝ : map f (filter p tail) = foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
⊢ map f (filter p (head :: tail)) =
    bif p head then f head :: foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
    else foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
[PROOFSTEP]
cases hp : p head
[GOAL]
case cons.false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
p : α → Bool
head : α
tail : List α
tail_ih✝ : map f (filter p tail) = foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
hp : p head = false
⊢ map f (filter p (head :: tail)) =
    bif false then f head :: foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
    else foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
[PROOFSTEP]
simp [filter, *]
[GOAL]
case cons.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
p : α → Bool
head : α
tail : List α
tail_ih✝ : map f (filter p tail) = foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
hp : p head = true
⊢ map f (filter p (head :: tail)) =
    bif true then f head :: foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
    else foldr (fun a bs => bif p a then f a :: bs else bs) [] tail
[PROOFSTEP]
simp [filter, *]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
hl : l ≠ []
⊢ getLast (map f l) (_ : ¬map f l = []) = f (getLast l hl)
[PROOFSTEP]
induction' l with l_hd l_tl l_ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
hl✝ : l ≠ []
hl : [] ≠ []
⊢ getLast (map f []) (_ : ¬map f [] = []) = f (getLast [] hl)
[PROOFSTEP]
apply (hl rfl).elim
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
hl✝ : l ≠ []
l_hd : α
l_tl : List α
l_ih : ∀ (hl : l_tl ≠ []), getLast (map f l_tl) (_ : ¬map f l_tl = []) = f (getLast l_tl hl)
hl : l_hd :: l_tl ≠ []
⊢ getLast (map f (l_hd :: l_tl)) (_ : ¬map f (l_hd :: l_tl) = []) = f (getLast (l_hd :: l_tl) hl)
[PROOFSTEP]
cases l_tl
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
hl✝ : l ≠ []
l_hd : α
l_ih : ∀ (hl : [] ≠ []), getLast (map f []) (_ : ¬map f [] = []) = f (getLast [] hl)
hl : [l_hd] ≠ []
⊢ getLast (map f [l_hd]) (_ : ¬map f [l_hd] = []) = f (getLast [l_hd] hl)
[PROOFSTEP]
simp
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
l : List α
hl✝ : l ≠ []
l_hd head✝ : α
tail✝ : List α
l_ih :
  ∀ (hl : head✝ :: tail✝ ≠ []),
    getLast (map f (head✝ :: tail✝)) (_ : ¬map f (head✝ :: tail✝) = []) = f (getLast (head✝ :: tail✝) hl)
hl : l_hd :: head✝ :: tail✝ ≠ []
⊢ getLast (map f (l_hd :: head✝ :: tail✝)) (_ : ¬map f (l_hd :: head✝ :: tail✝) = []) =
    f (getLast (l_hd :: head✝ :: tail✝) hl)
[PROOFSTEP]
simpa using l_ih _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
f : α → β
b : β
⊢ map f l = replicate (length l) b ↔ ∀ (x : α), x ∈ l → f x = b
[PROOFSTEP]
simp [eq_replicate]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
b₁ b₂ : β
l : List α
h : b₁ ∈ map (const α b₂) l
⊢ b₁ = b₂
[PROOFSTEP]
rw [map_const] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
b₁ b₂ : β
l : List α
h : b₁ ∈ replicate (length l) b₂
⊢ b₁ = b₂
[PROOFSTEP]
exact eq_of_mem_replicate h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
l : List β
⊢ zipWith f [] l = []
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
⊢ zipWith f [] [] = []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
head✝ : β
tail✝ : List β
⊢ zipWith f [] (head✝ :: tail✝) = []
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
l : List α
⊢ zipWith f l [] = []
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
⊢ zipWith f [] [] = []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
head✝ : α
tail✝ : List α
⊢ zipWith f (head✝ :: tail✝) [] = []
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
a : α
as : List α
b : β
bs : List β
⊢ zipWith (flip f) (b :: bs) (a :: as) = zipWith f (a :: as) (b :: bs)
[PROOFSTEP]
simp! [zipWith_flip]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
a : α
as : List α
b : β
bs : List β
⊢ flip f b a = f a b
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
l : List α
h : length (a :: l) ≤ n + 1
⊢ take (n + 1) (a :: l) = a :: l
[PROOFSTEP]
change a :: take n l = a :: l
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
l : List α
h : length (a :: l) ≤ n + 1
⊢ a :: take n l = a :: l
[PROOFSTEP]
rw [take_all_of_le (le_of_succ_le_succ h)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
h : length l₁ = n
⊢ take n (l₁ ++ l₂) = l₁
[PROOFSTEP]
rw [← h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
h : length l₁ = n
⊢ take (length l₁) (l₁ ++ l₂) = l₁
[PROOFSTEP]
apply take_left
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
l : List α
⊢ take n (take 0 l) = take (min n 0) l
[PROOFSTEP]
rw [min_zero, take_zero, take_nil]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : ℕ
l : List α
⊢ take 0 (take m l) = take (min 0 m) l
[PROOFSTEP]
rw [zero_min, take_zero, take_zero]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n m : ℕ
⊢ take (succ n) (take (succ m) []) = take (min (succ n) (succ m)) []
[PROOFSTEP]
simp only [take_nil]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n m : ℕ
a : α
l : List α
⊢ take (succ n) (take (succ m) (a :: l)) = take (min (succ n) (succ m)) (a :: l)
[PROOFSTEP]
simp only [take, min_succ_succ, take_take n m l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
⊢ take n (replicate 0 a) = replicate (min n 0) a
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
m : ℕ
⊢ take 0 (replicate m a) = replicate (min 0 m) a
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n m : ℕ
⊢ take (succ n) (replicate (succ m) a) = replicate (min (succ n) (succ m)) a
[PROOFSTEP]
simp [min_succ_succ, take_replicate]
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
i : ℕ
⊢ map f (take i []) = take i (map f [])
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
x✝ : List α
⊢ map f (take 0 x✝) = take 0 (map f x✝)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
h : α
t : List α
n : ℕ
⊢ map f (take (n + 1) (h :: t)) = take (n + 1) (map f (h :: t))
[PROOFSTEP]
dsimp
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
h : α
t : List α
n : ℕ
⊢ f h :: map f (take n t) = f h :: take n (map f t)
[PROOFSTEP]
rw [map_take f t n]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
⊢ take n (l₁ ++ l₂) = take n l₁ ++ take (n - length l₁) l₂
[PROOFSTEP]
induction l₁ generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
n : ℕ
⊢ take n ([] ++ l₂) = take n [] ++ take (n - length []) l₂
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, take n (tail✝ ++ l₂) = take n tail✝ ++ take (n - length tail✝) l₂
n : ℕ
⊢ take n (head✝ :: tail✝ ++ l₂) = take n (head✝ :: tail✝) ++ take (n - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
{simp
}
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
n : ℕ
⊢ take n ([] ++ l₂) = take n [] ++ take (n - length []) l₂
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, take n (tail✝ ++ l₂) = take n tail✝ ++ take (n - length tail✝) l₂
n : ℕ
⊢ take n (head✝ :: tail✝ ++ l₂) = take n (head✝ :: tail✝) ++ take (n - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, take n (tail✝ ++ l₂) = take n tail✝ ++ take (n - length tail✝) l₂
⊢ take zero (head✝ :: tail✝ ++ l₂) = take zero (head✝ :: tail✝) ++ take (zero - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
simp [*]
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, take n (tail✝ ++ l₂) = take n tail✝ ++ take (n - length tail✝) l₂
n✝ : ℕ
⊢ take (succ n✝) (head✝ :: tail✝ ++ l₂) = take (succ n✝) (head✝ :: tail✝) ++ take (succ n✝ - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
h : n ≤ length l₁
⊢ take n (l₁ ++ l₂) = take n l₁
[PROOFSTEP]
simp [take_append_eq_append_take, tsub_eq_zero_iff_le.mpr h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ take (length l₁ + i) (l₁ ++ l₂) = l₁ ++ take i l₂
[PROOFSTEP]
simp [take_append_eq_append_take, take_all_of_le le_self_add]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
j : ℕ
i : Fin (length (take j L))
⊢ length (take j L) ≤ length L
[PROOFSTEP]
simp [le_refl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
j : ℕ
i : Fin (length (take j L))
⊢ get (take j L) i = get L { val := ↑i, isLt := (_ : ↑i < length L) }
[PROOFSTEP]
let ⟨i, hi⟩ := i
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
j : ℕ
i✝ : Fin (length (take j L))
i : ℕ
hi : i < length (take j L)
⊢ get (take j L) { val := i, isLt := hi } =
    get L { val := ↑{ val := i, isLt := hi }, isLt := (_ : ↑{ val := i, isLt := hi } < length L) }
[PROOFSTEP]
simp at hi 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
j : ℕ
i✝ : Fin (length (take j L))
i : ℕ
hi✝ : i < length (take j L)
hi : i < j ∧ i < length L
⊢ get (take j L) { val := i, isLt := hi✝ } =
    get L { val := ↑{ val := i, isLt := hi✝ }, isLt := (_ : ↑{ val := i, isLt := hi✝ } < length L) }
[PROOFSTEP]
rw [get_take L _ hi.1]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
hi : i < length (take j L)
⊢ length (take j L) ≤ length L
[PROOFSTEP]
simp [le_refl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n m : ℕ
h : m < n
⊢ get? (take n l) m = get? l m
[PROOFSTEP]
induction' n with n hn generalizing l m
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n m✝ : ℕ
h✝ : m✝ < n
l : List α
m : ℕ
h : m < zero
⊢ get? (take zero l) m = get? l m
[PROOFSTEP]
simp only [Nat.zero_eq] at h 
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n m✝ : ℕ
h✝ : m✝ < n
l : List α
m : ℕ
h : m < 0
⊢ get? (take zero l) m = get? l m
[PROOFSTEP]
exact absurd h (not_lt_of_le m.zero_le)
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ m✝ : ℕ
h✝ : m✝ < n✝
n : ℕ
hn : ∀ {l : List α} {m : ℕ}, m < n → get? (take n l) m = get? l m
l : List α
m : ℕ
h : m < succ n
⊢ get? (take (succ n) l) m = get? l m
[PROOFSTEP]
cases' l with hd tl
[GOAL]
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ m✝ : ℕ
h✝ : m✝ < n✝
n : ℕ
hn : ∀ {l : List α} {m : ℕ}, m < n → get? (take n l) m = get? l m
m : ℕ
h : m < succ n
⊢ get? (take (succ n) []) m = get? [] m
[PROOFSTEP]
simp only [take_nil]
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ m✝ : ℕ
h✝ : m✝ < n✝
n : ℕ
hn : ∀ {l : List α} {m : ℕ}, m < n → get? (take n l) m = get? l m
m : ℕ
h : m < succ n
hd : α
tl : List α
⊢ get? (take (succ n) (hd :: tl)) m = get? (hd :: tl) m
[PROOFSTEP]
cases m
[GOAL]
case succ.cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ m : ℕ
h✝ : m < n✝
n : ℕ
hn : ∀ {l : List α} {m : ℕ}, m < n → get? (take n l) m = get? l m
hd : α
tl : List α
h : zero < succ n
⊢ get? (take (succ n) (hd :: tl)) zero = get? (hd :: tl) zero
[PROOFSTEP]
simp only [get?, take]
[GOAL]
case succ.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝¹ m : ℕ
h✝ : m < n✝¹
n : ℕ
hn : ∀ {l : List α} {m : ℕ}, m < n → get? (take n l) m = get? l m
hd : α
tl : List α
n✝ : ℕ
h : succ n✝ < succ n
⊢ get? (take (succ n) (hd :: tl)) (succ n✝) = get? (hd :: tl) (succ n✝)
[PROOFSTEP]
simpa only using hn (Nat.lt_of_succ_lt_succ h)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
⊢ take (n + 1) l = take n l ++ Option.toList (get? l n)
[PROOFSTEP]
induction' l with hd tl hl generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ n : ℕ
⊢ take (n + 1) [] = take n [] ++ Option.toList (get? [] n)
[PROOFSTEP]
simp only [Option.toList, get?, take_nil, append_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ : ℕ
hd : α
tl : List α
hl : ∀ {n : ℕ}, take (n + 1) tl = take n tl ++ Option.toList (get? tl n)
n : ℕ
⊢ take (n + 1) (hd :: tl) = take n (hd :: tl) ++ Option.toList (get? (hd :: tl) n)
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
hd : α
tl : List α
hl : ∀ {n : ℕ}, take (n + 1) tl = take n tl ++ Option.toList (get? tl n)
⊢ take (zero + 1) (hd :: tl) = take zero (hd :: tl) ++ Option.toList (get? (hd :: tl) zero)
[PROOFSTEP]
simp only [Option.toList, get?, eq_self_iff_true, and_self_iff, take, nil_append]
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
hd : α
tl : List α
hl : ∀ {n : ℕ}, take (n + 1) tl = take n tl ++ Option.toList (get? tl n)
n✝ : ℕ
⊢ take (succ n✝ + 1) (hd :: tl) = take (succ n✝) (hd :: tl) ++ Option.toList (get? (hd :: tl) (succ n✝))
[PROOFSTEP]
simp only [hl, cons_append, get?, eq_self_iff_true, and_self_iff, take]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
k : ℕ
⊢ take k l = [] ↔ l = [] ∨ k = 0
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
k : ℕ
⊢ take k [] = [] ↔ [] = [] ∨ k = 0
[PROOFSTEP]
cases k
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
k : ℕ
head✝ : α
tail✝ : List α
⊢ take k (head✝ :: tail✝) = [] ↔ head✝ :: tail✝ = [] ∨ k = 0
[PROOFSTEP]
cases k
[GOAL]
case nil.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ take zero [] = [] ↔ [] = [] ∨ zero = 0
[PROOFSTEP]
simp [Nat.succ_ne_zero]
[GOAL]
case nil.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ : ℕ
⊢ take (succ n✝) [] = [] ↔ [] = [] ∨ succ n✝ = 0
[PROOFSTEP]
simp [Nat.succ_ne_zero]
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : α
tail✝ : List α
⊢ take zero (head✝ :: tail✝) = [] ↔ head✝ :: tail✝ = [] ∨ zero = 0
[PROOFSTEP]
simp [Nat.succ_ne_zero]
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : α
tail✝ : List α
n✝ : ℕ
⊢ take (succ n✝) (head✝ :: tail✝) = [] ↔ head✝ :: tail✝ = [] ∨ succ n✝ = 0
[PROOFSTEP]
simp [Nat.succ_ne_zero]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n : ℕ
⊢ take m [] = take n [] ↔ min m (length []) = min n (length [])
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : α
xs : List α
⊢ take 0 (head✝ :: xs) = take 0 (head✝ :: xs) ↔ min 0 (length (head✝ :: xs)) = min 0 (length (head✝ :: xs))
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
xs : List α
m : ℕ
⊢ take (m + 1) (x :: xs) = take 0 (x :: xs) ↔ min (m + 1) (length (x :: xs)) = min 0 (length (x :: xs))
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
xs : List α
n : ℕ
⊢ take 0 (x :: xs) = take (n + 1) (x :: xs) ↔ min 0 (length (x :: xs)) = min (n + 1) (length (x :: xs))
[PROOFSTEP]
simp [@eq_comm ℕ 0]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
xs : List α
m n : ℕ
⊢ take (m + 1) (x :: xs) = take (n + 1) (x :: xs) ↔ min (m + 1) (length (x :: xs)) = min (n + 1) (length (x :: xs))
[PROOFSTEP]
simp [Nat.min_succ_succ, take_eq_take]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n) l = take m l ++ take n (drop m l)
[PROOFSTEP]
convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
[GOAL]
case h.e'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n) l = take (m + n) (take m l ++ drop m l)
[PROOFSTEP]
rw [take_append_drop]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
[PROOFSTEP]
rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n - length (take m l)) (drop m l) = take n (drop m l)
[PROOFSTEP]
simp only [take_eq_take, length_take, length_drop]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ min (m + n - min m (length l)) (length l - m) = min n (length l - m)
[PROOFSTEP]
generalize l.length = k
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n k : ℕ
⊢ min (m + n - min m k) (k - m) = min n (k - m)
[PROOFSTEP]
by_cases h : m ≤ k
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n k : ℕ
h : m ≤ k
⊢ min (m + n - min m k) (k - m) = min n (k - m)
[PROOFSTEP]
simp [min_eq_left_iff.mpr h]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n k : ℕ
h : ¬m ≤ k
⊢ min (m + n - min m k) (k - m) = min n (k - m)
[PROOFSTEP]
push_neg at h 
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n k : ℕ
h : k < m
⊢ min (m + n - min m k) (k - m) = min n (k - m)
[PROOFSTEP]
simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ length (take m l) ≤ m + n
[PROOFSTEP]
trans m
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ length (take m l) ≤ m
[PROOFSTEP]
apply length_take_le
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
m n : ℕ
⊢ m ≤ m + n
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
⊢ dropLast l = take (pred (length l)) l
[PROOFSTEP]
cases' l with x l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ dropLast [] = take (pred (length [])) []
[PROOFSTEP]
simp [dropLast]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
l : List α
⊢ dropLast (x :: l) = take (pred (length (x :: l))) (x :: l)
[PROOFSTEP]
induction' l with hd tl hl generalizing x
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ x : α
⊢ dropLast [x] = take (pred (length [x])) [x]
[PROOFSTEP]
simp [dropLast]
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ hd : α
tl : List α
hl : ∀ (x : α), dropLast (x :: tl) = take (pred (length (x :: tl))) (x :: tl)
x : α
⊢ dropLast (x :: hd :: tl) = take (pred (length (x :: hd :: tl))) (x :: hd :: tl)
[PROOFSTEP]
simp [dropLast, hl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
l : List α
h : n < length l
⊢ dropLast (take n l) = take (pred n) l
[PROOFSTEP]
simp [dropLast_eq_take, min_eq_left_of_lt h, take_take, pred_le]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
x : α
l : List α
h : l ≠ []
⊢ dropLast (x :: l) = x :: dropLast l
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List α
x✝ : l ≠ []
⊢ dropLast ([] ++ l) = [] ++ dropLast l
[PROOFSTEP]
simp only [nil_append]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List α
a : α
l' : List α
h : l ≠ []
⊢ dropLast (a :: l' ++ l) = a :: l' ++ dropLast l
[PROOFSTEP]
rw [cons_append, dropLast, dropLast_append_of_ne_nil l' h, cons_append]
[GOAL]
case x_2
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List α
a : α
l' : List α
h : l ≠ []
⊢ l' ++ l = [] → False
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
k : ℕ
⊢ drop k l = [] ↔ length l ≤ k
[PROOFSTEP]
refine' ⟨fun h => _, drop_eq_nil_of_le⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
k : ℕ
h : drop k l = []
⊢ length l ≤ k
[PROOFSTEP]
induction' k with k hk generalizing l
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
k : ℕ
h✝ : drop k l✝ = []
l : List α
h : drop zero l = []
⊢ length l ≤ zero
[PROOFSTEP]
simp only [drop] at h 
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
k : ℕ
h✝ : drop k l✝ = []
l : List α
h : l = []
⊢ length l ≤ zero
[PROOFSTEP]
simp [h]
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
k✝ : ℕ
h✝ : drop k✝ l✝ = []
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
l : List α
h : drop (succ k) l = []
⊢ length l ≤ succ k
[PROOFSTEP]
cases l
[GOAL]
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
k✝ : ℕ
h✝ : drop k✝ l = []
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
h : drop (succ k) [] = []
⊢ length [] ≤ succ k
[PROOFSTEP]
simp
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
k✝ : ℕ
h✝ : drop k✝ l = []
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
head✝ : α
tail✝ : List α
h : drop (succ k) (head✝ :: tail✝) = []
⊢ length (head✝ :: tail✝) ≤ succ k
[PROOFSTEP]
simp only [drop] at h 
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
k✝ : ℕ
h✝ : drop k✝ l = []
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
head✝ : α
tail✝ : List α
h : drop k tail✝ = []
⊢ length (head✝ :: tail✝) ≤ succ k
[PROOFSTEP]
simpa [Nat.succ_le_succ_iff] using hk h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
⊢ tail (drop n l) = drop (n + 1) l
[PROOFSTEP]
induction' l with hd tl hl generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ n : ℕ
⊢ tail (drop n []) = drop (n + 1) []
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ : ℕ
hd : α
tl : List α
hl : ∀ (n : ℕ), tail (drop n tl) = drop (n + 1) tl
n : ℕ
⊢ tail (drop n (hd :: tl)) = drop (n + 1) (hd :: tl)
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
hd : α
tl : List α
hl : ∀ (n : ℕ), tail (drop n tl) = drop (n + 1) tl
⊢ tail (drop zero (hd :: tl)) = drop (zero + 1) (hd :: tl)
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
hd : α
tl : List α
hl : ∀ (n : ℕ), tail (drop n tl) = drop (n + 1) tl
n✝ : ℕ
⊢ tail (drop (succ n✝) (hd :: tl)) = drop (succ n✝ + 1) (hd :: tl)
[PROOFSTEP]
simp [hl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : Fin (length l)
⊢ get l n :: drop (↑n + 1) l = drop (↑n) l
[PROOFSTEP]
induction' l with hd tl hl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : Fin (length l)
n : Fin (length [])
⊢ get [] n :: drop (↑n + 1) [] = drop ↑n []
[PROOFSTEP]
exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : Fin (length l)
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n : Fin (length (hd :: tl))
⊢ get (hd :: tl) n :: drop (↑n + 1) (hd :: tl) = drop (↑n) (hd :: tl)
[PROOFSTEP]
match n with
| ⟨0, _⟩ => simp [get]
| ⟨n + 1, hn⟩ =>
  simp only [Nat.succ_lt_succ_iff, List.length] at hn 
  simpa [List.get, List.drop] using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝ : Fin (length l)
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n : Fin (length (hd :: tl))
isLt✝ : 0 < length (hd :: tl)
⊢ get (hd :: tl) { val := 0, isLt := isLt✝ } :: drop (↑{ val := 0, isLt := isLt✝ } + 1) (hd :: tl) =
    drop (↑{ val := 0, isLt := isLt✝ }) (hd :: tl)
[PROOFSTEP]
simp [get]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝¹ : Fin (length l)
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n✝ : Fin (length (hd :: tl))
n : ℕ
hn : n + 1 < length (hd :: tl)
⊢ get (hd :: tl) { val := n + 1, isLt := hn } :: drop (↑{ val := n + 1, isLt := hn } + 1) (hd :: tl) =
    drop (↑{ val := n + 1, isLt := hn }) (hd :: tl)
[PROOFSTEP]
simp only [Nat.succ_lt_succ_iff, List.length] at hn 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n✝¹ : Fin (length l)
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n✝ : Fin (length (hd :: tl))
n : ℕ
hn✝ : n + 1 < length (hd :: tl)
hn : n < length tl
⊢ get (hd :: tl) { val := n + 1, isLt := hn✝ } :: drop (↑{ val := n + 1, isLt := hn✝ } + 1) (hd :: tl) =
    drop (↑{ val := n + 1, isLt := hn✝ }) (hd :: tl)
[PROOFSTEP]
simpa [List.get, List.drop] using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
h : length l₁ = n
⊢ drop n (l₁ ++ l₂) = l₂
[PROOFSTEP]
rw [← h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
h : length l₁ = n
⊢ drop (length l₁) (l₁ ++ l₂) = l₂
[PROOFSTEP]
apply drop_left
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h : l ≠ []
a : α
⊢ drop (length l) (a :: l) = [getLast l h]
[PROOFSTEP]
induction' l with y l ih generalizing a
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
h✝ : l ≠ []
a✝ : α
h : [] ≠ []
a : α
⊢ drop (length []) [a] = [getLast [] h]
[PROOFSTEP]
cases h rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
h✝ : l✝ ≠ []
a✝ y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
⊢ drop (length (y :: l)) (a :: y :: l) = [getLast (y :: l) h]
[PROOFSTEP]
simp only [drop, length]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
h✝ : l✝ ≠ []
a✝ y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast (y :: l) h]
[PROOFSTEP]
by_cases h₁ : l = []
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
h✝ : l✝ ≠ []
a✝ y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
h₁ : l = []
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast (y :: l) h]
[PROOFSTEP]
simp [h₁]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
h✝ : l✝ ≠ []
a✝ y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
h₁ : ¬l = []
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast (y :: l) h]
[PROOFSTEP]
rw [getLast_cons h₁]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
h✝ : l✝ ≠ []
a✝ y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
h₁ : ¬l = []
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast l h₁]
[PROOFSTEP]
exact ih h₁ y
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
⊢ drop n (l₁ ++ l₂) = drop n l₁ ++ drop (n - length l₁) l₂
[PROOFSTEP]
induction l₁ generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
n : ℕ
⊢ drop n ([] ++ l₂) = drop n [] ++ drop (n - length []) l₂
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, drop n (tail✝ ++ l₂) = drop n tail✝ ++ drop (n - length tail✝) l₂
n : ℕ
⊢ drop n (head✝ :: tail✝ ++ l₂) = drop n (head✝ :: tail✝) ++ drop (n - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, drop n (tail✝ ++ l₂) = drop n tail✝ ++ drop (n - length tail✝) l₂
⊢ drop zero (head✝ :: tail✝ ++ l₂) = drop zero (head✝ :: tail✝) ++ drop (zero - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
simp [*]
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {n : ℕ}, drop n (tail✝ ++ l₂) = drop n tail✝ ++ drop (n - length tail✝) l₂
n✝ : ℕ
⊢ drop (succ n✝) (head✝ :: tail✝ ++ l₂) = drop (succ n✝) (head✝ :: tail✝) ++ drop (succ n✝ - length (head✝ :: tail✝)) l₂
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
h : n ≤ length l₁
⊢ drop n (l₁ ++ l₂) = drop n l₁ ++ l₂
[PROOFSTEP]
simp [drop_append_eq_append_drop, tsub_eq_zero_iff_le.mpr h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ drop (length l₁ + i) (l₁ ++ l₂) = drop i l₂
[PROOFSTEP]
rw [drop_append_eq_append_drop, drop_eq_nil_of_le]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ [] ++ drop (length l₁ + i - length l₁) l₂ = drop i l₂
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ length l₁ ≤ length l₁ + i
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
l : List α
⊢ ∀ (n : ℕ), sizeOf (drop n l) ≤ sizeOf l
[PROOFSTEP]
induction' l with _ _ lih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
⊢ ∀ (n : ℕ), sizeOf (drop n []) ≤ sizeOf []
[PROOFSTEP]
intro n
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
head✝ : α
tail✝ : List α
lih : ∀ (n : ℕ), sizeOf (drop n tail✝) ≤ sizeOf tail✝
⊢ ∀ (n : ℕ), sizeOf (drop n (head✝ :: tail✝)) ≤ sizeOf (head✝ :: tail✝)
[PROOFSTEP]
intro n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
n : ℕ
⊢ sizeOf (drop n []) ≤ sizeOf []
[PROOFSTEP]
rw [drop_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
head✝ : α
tail✝ : List α
lih : ∀ (n : ℕ), sizeOf (drop n tail✝) ≤ sizeOf tail✝
n : ℕ
⊢ sizeOf (drop n (head✝ :: tail✝)) ≤ sizeOf (head✝ :: tail✝)
[PROOFSTEP]
induction' n with n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
head✝ : α
tail✝ : List α
lih : ∀ (n : ℕ), sizeOf (drop n tail✝) ≤ sizeOf tail✝
⊢ sizeOf (drop zero (head✝ :: tail✝)) ≤ sizeOf (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
head✝ : α
tail✝ : List α
lih : ∀ (n : ℕ), sizeOf (drop n tail✝) ≤ sizeOf tail✝
n : ℕ
n_ih✝ : sizeOf (drop n (head✝ :: tail✝)) ≤ sizeOf (head✝ :: tail✝)
⊢ sizeOf (drop (succ n) (head✝ :: tail✝)) ≤ sizeOf (head✝ :: tail✝)
[PROOFSTEP]
exact Trans.trans (lih _) le_add_self
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ j < length (drop i L)
[PROOFSTEP]
have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
A : i < length L
⊢ j < length (drop i L)
[PROOFSTEP]
rw [(take_append_drop i L).symm] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length (take i L ++ drop i L)
A : i < length L
⊢ j < length (drop i L)
[PROOFSTEP]
simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take, length_append] using h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ get L { val := i + j, isLt := h } = get (drop i L) { val := j, isLt := (_ : j < length (drop i L)) }
[PROOFSTEP]
rw [← nthLe_eq, ← nthLe_eq]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ nthLe L (i + j) h = nthLe (drop i L) j (_ : j < length (drop i L))
[PROOFSTEP]
rw [nthLe_of_eq (take_append_drop i L).symm h, nthLe_append_right]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ nthLe (drop i L) (i + j - length (take i L)) (_ : i + j - length (take i L) < length (drop i L)) =
    nthLe (drop i L) j (_ : j < length (drop i L))
[PROOFSTEP]
simp [min_eq_left (show i ≤ length L from le_trans (by simp) (le_of_lt h))]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ i ≤ i + j
[PROOFSTEP]
simp
[GOAL]
case h₁
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ length (take i L) ≤ i + j
[PROOFSTEP]
simp [min_eq_left (show i ≤ length L from le_trans (by simp) (le_of_lt h))]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ i ≤ i + j
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
⊢ j < length (drop i L)
[PROOFSTEP]
have A : i < L.length := lt_of_le_of_lt (Nat.le.intro rfl) h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length L
A : i < length L
⊢ j < length (drop i L)
[PROOFSTEP]
rw [(take_append_drop i L).symm] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
h : i + j < length (take i L ++ drop i L)
A : i < length L
⊢ j < length (drop i L)
[PROOFSTEP]
simpa only [le_of_lt A, min_eq_left, add_lt_add_iff_left, length_take, length_append] using h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : ℕ
j : Fin (length (drop i L))
⊢ get (drop i L) j = get L { val := i + ↑j, isLt := (_ : i + ↑j < length L) }
[PROOFSTEP]
rw [get_drop]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
⊢ get? (drop i L) j = get? L (i + j)
[PROOFSTEP]
ext
[GOAL]
case a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
a✝ : α
⊢ a✝ ∈ get? (drop i L) j ↔ a✝ ∈ get? L (i + j)
[PROOFSTEP]
simp only [get?_eq_some, get_drop', Option.mem_def]
[GOAL]
case a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
a✝ : α
⊢ (∃ h, get L { val := i + j, isLt := (_ : i + ↑{ val := j, isLt := (_ : j < length (drop i L)) } < length L) } = a✝) ↔
    ∃ h, get L { val := i + j, isLt := h } = a✝
[PROOFSTEP]
constructor
[GOAL]
case a.mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
a✝ : α
⊢ (∃ h, get L { val := i + j, isLt := (_ : i + ↑{ val := j, isLt := (_ : j < length (drop i L)) } < length L) } = a✝) →
    ∃ h, get L { val := i + j, isLt := h } = a✝
[PROOFSTEP]
exact fun ⟨h, ha⟩ => ⟨by simpa [lt_tsub_iff_left] using h, ha⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
a✝ : α
x✝ : ∃ h, get L { val := i + j, isLt := (_ : i + ↑{ val := j, isLt := (_ : j < length (drop i L)) } < length L) } = a✝
h : j < length (drop i L)
ha : get L { val := i + j, isLt := (_ : i + ↑{ val := j, isLt := (_ : j < length (drop i L)) } < length L) } = a✝
⊢ i + j < length L
[PROOFSTEP]
simpa [lt_tsub_iff_left] using h
[GOAL]
case a.mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
a✝ : α
⊢ (∃ h, get L { val := i + j, isLt := h } = a✝) →
    ∃ h, get L { val := i + j, isLt := (_ : i + ↑{ val := j, isLt := (_ : j < length (drop i L)) } < length L) } = a✝
[PROOFSTEP]
exact fun ⟨h, ha⟩ => ⟨by simpa [lt_tsub_iff_left] using h, ha⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i j : ℕ
a✝ : α
x✝ : ∃ h, get L { val := i + j, isLt := h } = a✝
h : i + j < length L
ha : get L { val := i + j, isLt := h } = a✝
⊢ j < length (drop i L)
[PROOFSTEP]
simpa [lt_tsub_iff_left] using h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n m : ℕ
⊢ drop n (drop m []) = drop (n + m) []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
l : List α
⊢ drop n (drop 0 l) = drop (n + 0) l
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
x✝ : List α
⊢ drop 0 (take (0 + n) x✝) = take n (drop 0 x✝)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n : ℕ
⊢ drop (m + 1) (take (m + 1 + n) []) = take n (drop (m + 1) [])
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n : ℕ
head✝ : α
l : List α
⊢ drop (m + 1) (take (m + 1 + n) (head✝ :: l)) = take n (drop (m + 1) (head✝ :: l))
[PROOFSTEP]
have h : m + 1 + n = m + n + 1 := by ac_rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n : ℕ
head✝ : α
l : List α
⊢ m + 1 + n = m + n + 1
[PROOFSTEP]
ac_rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n : ℕ
head✝ : α
l : List α
h : m + 1 + n = m + n + 1
⊢ drop (m + 1) (take (m + 1 + n) (head✝ :: l)) = take n (drop (m + 1) (head✝ :: l))
[PROOFSTEP]
simpa [take_cons, h] using drop_take m n l
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
i : ℕ
⊢ map f (drop i []) = drop i (map f [])
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
L : List α
⊢ map f (drop 0 L) = drop 0 (map f L)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
h : α
t : List α
n : ℕ
⊢ map f (drop (n + 1) (h :: t)) = drop (n + 1) (map f (h :: t))
[PROOFSTEP]
dsimp
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
h : α
t : List α
n : ℕ
⊢ map f (drop n t) = drop n (map f t)
[PROOFSTEP]
rw [map_drop f t]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
n : ℕ
l : List α
h : n < length l
⊢ modifyNth f n l = take n l ++ f (get l { val := n, isLt := h }) :: drop (n + 1) l
[PROOFSTEP]
rw [modifyNth_eq_take_drop, drop_eq_get_cons h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
n : ℕ
l : List α
h : n < length l
⊢ take n l ++ modifyHead f (get l { val := n, isLt := h } :: drop (n + 1) l) =
    take n l ++ f (get l { val := n, isLt := h }) :: drop (n + 1) l
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n : ℕ
l : List α
h : n < length l
⊢ set l n a = take n l ++ a :: drop (n + 1) l
[PROOFSTEP]
rw [set_eq_modifyNth, modifyNth_eq_take_cons_drop _ h]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n : ℕ
h : n ≤ length xs
⊢ take n (reverse xs) = reverse (drop (length xs - n) xs)
[PROOFSTEP]
induction' xs with xs_hd xs_tl xs_ih generalizing n
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
n : ℕ
h : n ≤ length []
⊢ take n (reverse []) = reverse (drop (length [] - n) [])
[PROOFSTEP]
simp only [reverse_cons, drop, reverse_nil, zero_tsub, length, take_nil]
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
⊢ take n (reverse (xs_hd :: xs_tl)) = reverse (drop (length (xs_hd :: xs_tl) - n) (xs_hd :: xs_tl))
[PROOFSTEP]
simp only [reverse_cons, drop, reverse_nil, zero_tsub, length, take_nil]
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
⊢ take n (reverse xs_tl ++ [xs_hd]) = reverse (drop (length xs_tl + 1 - n) (xs_hd :: xs_tl))
[PROOFSTEP]
cases' h.lt_or_eq_dec with h' h'
[GOAL]
case cons.inl
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n < length (xs_hd :: xs_tl)
⊢ take n (reverse xs_tl ++ [xs_hd]) = reverse (drop (length xs_tl + 1 - n) (xs_hd :: xs_tl))
[PROOFSTEP]
replace h' := le_of_succ_le_succ h'
[GOAL]
case cons.inl
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n ≤ length xs_tl
⊢ take n (reverse xs_tl ++ [xs_hd]) = reverse (drop (length xs_tl + 1 - n) (xs_hd :: xs_tl))
[PROOFSTEP]
rw [take_append_of_le_length, xs_ih _ h']
[GOAL]
case cons.inl
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n ≤ length xs_tl
⊢ reverse (drop (length xs_tl - n) xs_tl) = reverse (drop (length xs_tl + 1 - n) (xs_hd :: xs_tl))
case cons.inl
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n ≤ length xs_tl
⊢ n ≤ length (reverse xs_tl)
[PROOFSTEP]
rw [show xs_tl.length + 1 - n = succ (xs_tl.length - n) from _, drop]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n ≤ length xs_tl
⊢ length xs_tl + 1 - n = succ (length xs_tl - n)
[PROOFSTEP]
rwa [succ_eq_add_one, ← @tsub_add_eq_add_tsub]
[GOAL]
case cons.inl
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n ≤ length xs_tl
⊢ n ≤ length (reverse xs_tl)
[PROOFSTEP]
rwa [length_reverse]
[GOAL]
case cons.inr
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n✝ : ℕ
h✝ : n✝ ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
n : ℕ
h : n ≤ length (xs_hd :: xs_tl)
h' : n = length (xs_hd :: xs_tl)
⊢ take n (reverse xs_tl ++ [xs_hd]) = reverse (drop (length xs_tl + 1 - n) (xs_hd :: xs_tl))
[PROOFSTEP]
subst h'
[GOAL]
case cons.inr
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n : ℕ
h✝ : n ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
h : length (xs_hd :: xs_tl) ≤ length (xs_hd :: xs_tl)
⊢ take (length (xs_hd :: xs_tl)) (reverse xs_tl ++ [xs_hd]) =
    reverse (drop (length xs_tl + 1 - length (xs_hd :: xs_tl)) (xs_hd :: xs_tl))
[PROOFSTEP]
rw [length, tsub_self, drop]
[GOAL]
case cons.inr
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n : ℕ
h✝ : n ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
h : length (xs_hd :: xs_tl) ≤ length (xs_hd :: xs_tl)
⊢ take (length xs_tl + 1) (reverse xs_tl ++ [xs_hd]) = reverse (xs_hd :: xs_tl)
[PROOFSTEP]
suffices xs_tl.length + 1 = (xs_tl.reverse ++ [xs_hd]).length by rw [this, take_length, reverse_cons]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n : ℕ
h✝ : n ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
h : length (xs_hd :: xs_tl) ≤ length (xs_hd :: xs_tl)
this : length xs_tl + 1 = length (reverse xs_tl ++ [xs_hd])
⊢ take (length xs_tl + 1) (reverse xs_tl ++ [xs_hd]) = reverse (xs_hd :: xs_tl)
[PROOFSTEP]
rw [this, take_length, reverse_cons]
[GOAL]
case cons.inr
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n : ℕ
h✝ : n ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
h : length (xs_hd :: xs_tl) ≤ length (xs_hd :: xs_tl)
⊢ length xs_tl + 1 = length (reverse xs_tl ++ [xs_hd])
[PROOFSTEP]
rw [length_append, length_reverse]
[GOAL]
case cons.inr
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
xs : List α
n : ℕ
h✝ : n ≤ length xs
xs_hd : α
xs_tl : List α
xs_ih : ∀ (n : ℕ), n ≤ length xs_tl → take n (reverse xs_tl) = reverse (drop (length xs_tl - n) xs_tl)
h : length (xs_hd :: xs_tl) ≤ length (xs_hd :: xs_tl)
⊢ length xs_tl + 1 = length xs_tl + length [xs_hd]
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
a : α
⊢ set l n a = [] ↔ l = []
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
⊢ set [] n a = [] ↔ [] = []
[PROOFSTEP]
cases n
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a head✝ : α
tail✝ : List α
⊢ set (head✝ :: tail✝) n a = [] ↔ head✝ :: tail✝ = []
[PROOFSTEP]
cases n
[GOAL]
case nil.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ set [] zero a = [] ↔ [] = []
[PROOFSTEP]
simp only [set]
[GOAL]
case nil.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
n✝ : ℕ
⊢ set [] (succ n✝) a = [] ↔ [] = []
[PROOFSTEP]
simp only [set]
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
⊢ set (head✝ :: tail✝) zero a = [] ↔ head✝ :: tail✝ = []
[PROOFSTEP]
simp only [set]
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a head✝ : α
tail✝ : List α
n✝ : ℕ
⊢ set (head✝ :: tail✝) (succ n✝) a = [] ↔ head✝ :: tail✝ = []
[PROOFSTEP]
simp only [set]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : Inhabited α
l₁ l₂ : List α
⊢ length l₁ ≤ length (l₁ ++ l₂)
[PROOFSTEP]
simp only [length_append, Nat.le_add_right]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : Inhabited α
l₁ l₂ : List α
n : ℕ
h : length l₁ = n
⊢ takeI n (l₁ ++ l₂) = l₁
[PROOFSTEP]
rw [← h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : Inhabited α
l₁ l₂ : List α
n : ℕ
h : length l₁ = n
⊢ takeI (length l₁) (l₁ ++ l₂) = l₁
[PROOFSTEP]
apply takeI_left
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
a : α
⊢ length l₁ ≤ length (l₁ ++ l₂)
[PROOFSTEP]
simp only [length_append, Nat.le_add_right]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
a : α
h : length l₁ = n
⊢ takeD n (l₁ ++ l₂) a = l₁
[PROOFSTEP]
rw [← h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ l₁ l₂ : List α
n : ℕ
a : α
h : length l₁ = n
⊢ takeD (length l₁) (l₁ ++ l₂) a = l₁
[PROOFSTEP]
apply takeD_left
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
a : α
l : List β
H : ∀ (a : α) (b : β), b ∈ l → f a b = g a b
⊢ foldl f a l = foldl g a l
[PROOFSTEP]
induction l generalizing a with
| nil => rfl
| cons hd tl ih =>
  unfold foldl
  rw [ih _ fun a b bin => H a b <| mem_cons_of_mem _ bin, H a hd (mem_cons_self _ _)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
a : α
l : List β
H : ∀ (a : α) (b : β), b ∈ l → f a b = g a b
⊢ foldl f a l = foldl g a l
[PROOFSTEP]
induction l generalizing a with
| nil => rfl
| cons hd tl ih =>
  unfold foldl
  rw [ih _ fun a b bin => H a b <| mem_cons_of_mem _ bin, H a hd (mem_cons_self _ _)]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
a : α
H : ∀ (a : α) (b : β), b ∈ [] → f a b = g a b
⊢ foldl f a [] = foldl g a []
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
a : α
H : ∀ (a : α) (b : β), b ∈ [] → f a b = g a b
⊢ foldl f a [] = foldl g a []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
hd : β
tl : List β
ih : ∀ (a : α), (∀ (a : α) (b : β), b ∈ tl → f a b = g a b) → foldl f a tl = foldl g a tl
a : α
H : ∀ (a : α) (b : β), b ∈ hd :: tl → f a b = g a b
⊢ foldl f a (hd :: tl) = foldl g a (hd :: tl)
[PROOFSTEP]

| cons hd tl ih =>
  unfold foldl
  rw [ih _ fun a b bin => H a b <| mem_cons_of_mem _ bin, H a hd (mem_cons_self _ _)]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
hd : β
tl : List β
ih : ∀ (a : α), (∀ (a : α) (b : β), b ∈ tl → f a b = g a b) → foldl f a tl = foldl g a tl
a : α
H : ∀ (a : α) (b : β), b ∈ hd :: tl → f a b = g a b
⊢ foldl f a (hd :: tl) = foldl g a (hd :: tl)
[PROOFSTEP]
unfold foldl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → α
hd : β
tl : List β
ih : ∀ (a : α), (∀ (a : α) (b : β), b ∈ tl → f a b = g a b) → foldl f a tl = foldl g a tl
a : α
H : ∀ (a : α) (b : β), b ∈ hd :: tl → f a b = g a b
⊢ foldl f (f a hd) tl = foldl g (g a hd) tl
[PROOFSTEP]
rw [ih _ fun a b bin => H a b <| mem_cons_of_mem _ bin, H a hd (mem_cons_self _ _)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → β
b : β
l : List α
H : ∀ (a : α), a ∈ l → ∀ (b : β), f a b = g a b
⊢ foldr f b l = foldr g b l
[PROOFSTEP]
induction' l with hd tl ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → β
b : β
l : List α
H✝ : ∀ (a : α), a ∈ l → ∀ (b : β), f a b = g a b
H : ∀ (a : α), a ∈ [] → ∀ (b : β), f a b = g a b
⊢ foldr f b [] = foldr g b []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → β
b : β
l : List α
H✝ : ∀ (a : α), a ∈ l → ∀ (b : β), f a b = g a b
hd : α
tl : List α
ih : (∀ (a : α), a ∈ tl → ∀ (b : β), f a b = g a b) → foldr f b tl = foldr g b tl
H : ∀ (a : α), a ∈ hd :: tl → ∀ (b : β), f a b = g a b
⊢ foldr f b (hd :: tl) = foldr g b (hd :: tl)
[PROOFSTEP]
simp only [mem_cons, or_imp, forall_and, forall_eq] at H 
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f g : α → β → β
b : β
l : List α
H✝ : ∀ (a : α), a ∈ l → ∀ (b : β), f a b = g a b
hd : α
tl : List α
ih : (∀ (a : α), a ∈ tl → ∀ (b : β), f a b = g a b) → foldr f b tl = foldr g b tl
H : (∀ (b : β), f hd b = g hd b) ∧ ∀ (x : α), x ∈ tl → ∀ (b : β), f x b = g x b
⊢ foldr f b (hd :: tl) = foldr g b (hd :: tl)
[PROOFSTEP]
simp only [foldr, ih H.2, H.1]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
x : α
xs : List α
⊢ foldl f b (xs ++ [x]) = f (foldl f b xs) x
[PROOFSTEP]
simp only [List.foldl_append, List.foldl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
x : α
xs : List α
⊢ foldr f b (xs ++ [x]) = foldr f (f x b) xs
[PROOFSTEP]
simp only [List.foldr_append, List.foldr]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → α
a : α
hf : ∀ (b : β), f a b = a
b : β
l : List β
⊢ foldl f a (b :: l) = a
[PROOFSTEP]
rw [foldl_cons, hf b, foldl_fixed' hf l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
hf : ∀ (a : α), f a b = b
a : α
l : List α
⊢ foldr f b (a :: l) = b
[PROOFSTEP]
rw [foldr_cons, foldr_fixed' hf l, hf a]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → α
a : α
l : List β
L : List (List β)
⊢ foldl f a (join (l :: L)) = foldl (foldl f) a (l :: L)
[PROOFSTEP]
simp only [join, foldl_append, foldl_cons, foldl_join f (foldl f a l) L]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
a : β
l : List α
L : List (List α)
⊢ foldr f a (join (l :: L)) = foldr (fun l b => foldr f b l) a (l :: L)
[PROOFSTEP]
simp only [join, foldr_append, foldr_join f a L, foldr_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ ∀ (l : List α), foldr cons [] l = l
[PROOFSTEP]
simp only [foldr_self_append, append_nil, forall_const]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
⊢ reverse (foldl (fun t h => h :: t) [] l) = l
[PROOFSTEP]
rw [← foldr_reverse]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
⊢ reverse (foldr (fun h t => h :: t) [] (reverse l)) = l
[PROOFSTEP]
simp only [foldr_self_append, append_nil, reverse_reverse]
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α β : Type u
g : α → β
f : α → α → α
f' : β → β → β
a : α
l : List α
h : ∀ (x y : α), f' (g x) (g y) = g (f x y)
⊢ foldl f' (g a) (map g l) = g (foldl f a l)
[PROOFSTEP]
induction l generalizing a
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α β : Type u
g : α → β
f : α → α → α
f' : β → β → β
h : ∀ (x y : α), f' (g x) (g y) = g (f x y)
a : α
⊢ foldl f' (g a) (map g []) = g (foldl f a [])
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α β : Type u
g : α → β
f : α → α → α
f' : β → β → β
h : ∀ (x y : α), f' (g x) (g y) = g (f x y)
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (a : α), foldl f' (g a) (map g tail✝) = g (foldl f a tail✝)
a : α
⊢ foldl f' (g a) (map g (head✝ :: tail✝)) = g (foldl f a (head✝ :: tail✝))
[PROOFSTEP]
simp [*, h]
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α β : Type u
g : α → β
f : α → α → α
f' : β → β → β
a : α
l : List α
h : ∀ (x y : α), f' (g x) (g y) = g (f x y)
⊢ foldr f' (g a) (map g l) = g (foldr f a l)
[PROOFSTEP]
induction l generalizing a
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α β : Type u
g : α → β
f : α → α → α
f' : β → β → β
h : ∀ (x y : α), f' (g x) (g y) = g (f x y)
a : α
⊢ foldr f' (g a) (map g []) = g (foldr f a [])
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α β : Type u
g : α → β
f : α → α → α
f' : β → β → β
h : ∀ (x y : α), f' (g x) (g y) = g (f x y)
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (a : α), foldr f' (g a) (map g tail✝) = g (foldr f a tail✝)
a : α
⊢ foldr f' (g a) (map g (head✝ :: tail✝)) = g (foldr f a (head✝ :: tail✝))
[PROOFSTEP]
simp [*, h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List ι
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
a : α
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
⊢ f (foldl op₁ a l) (foldl op₂ b l) = foldl op₃ (f a b) l
[PROOFSTEP]
revert a b
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List ι
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
⊢ ∀ (a : α) (b : β), f (foldl op₁ a l) (foldl op₂ b l) = foldl op₃ (f a b) l
[PROOFSTEP]
induction l <;> intros <;> [rfl; simp only [*, foldl]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List ι
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
⊢ ∀ (a : α) (b : β), f (foldl op₁ a l) (foldl op₂ b l) = foldl op₃ (f a b) l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
⊢ ∀ (a : α) (b : β), f (foldl op₁ a []) (foldl op₂ b []) = foldl op₃ (f a b) []
[PROOFSTEP]
intros
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
head✝ : ι
tail✝ : List ι
tail_ih✝ : ∀ (a : α) (b : β), f (foldl op₁ a tail✝) (foldl op₂ b tail✝) = foldl op₃ (f a b) tail✝
⊢ ∀ (a : α) (b : β),
    f (foldl op₁ a (head✝ :: tail✝)) (foldl op₂ b (head✝ :: tail✝)) = foldl op₃ (f a b) (head✝ :: tail✝)
[PROOFSTEP]
intros
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
a✝ : α
b✝ : β
⊢ f (foldl op₁ a✝ []) (foldl op₂ b✝ []) = foldl op₃ (f a✝ b✝) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : α → ι → α
op₂ : β → ι → β
op₃ : γ → ι → γ
h : ∀ (a : α) (b : β) (i : ι), f (op₁ a i) (op₂ b i) = op₃ (f a b) i
head✝ : ι
tail✝ : List ι
tail_ih✝ : ∀ (a : α) (b : β), f (foldl op₁ a tail✝) (foldl op₂ b tail✝) = foldl op₃ (f a b) tail✝
a✝ : α
b✝ : β
⊢ f (foldl op₁ a✝ (head✝ :: tail✝)) (foldl op₂ b✝ (head✝ :: tail✝)) = foldl op₃ (f a✝ b✝) (head✝ :: tail✝)
[PROOFSTEP]
simp only [*, foldl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List ι
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
a : α
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
⊢ foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l)
[PROOFSTEP]
revert a
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List ι
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
⊢ ∀ (a : α), foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l)
[PROOFSTEP]
induction l <;> intros <;> [rfl; simp only [*, foldr]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List ι
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
⊢ ∀ (a : α), foldr op₃ (f a b) l = f (foldr op₁ a l) (foldr op₂ b l)
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
⊢ ∀ (a : α), foldr op₃ (f a b) [] = f (foldr op₁ a []) (foldr op₂ b [])
[PROOFSTEP]
intros
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
head✝ : ι
tail✝ : List ι
tail_ih✝ : ∀ (a : α), foldr op₃ (f a b) tail✝ = f (foldr op₁ a tail✝) (foldr op₂ b tail✝)
⊢ ∀ (a : α), foldr op₃ (f a b) (head✝ :: tail✝) = f (foldr op₁ a (head✝ :: tail✝)) (foldr op₂ b (head✝ :: tail✝))
[PROOFSTEP]
intros
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
a✝ : α
⊢ foldr op₃ (f a✝ b) [] = f (foldr op₁ a✝ []) (foldr op₂ b [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → γ
op₁ : ι → α → α
op₂ : ι → β → β
op₃ : ι → γ → γ
b : β
h : ∀ (a : α) (b : β) (i : ι), f (op₁ i a) (op₂ i b) = op₃ i (f a b)
head✝ : ι
tail✝ : List ι
tail_ih✝ : ∀ (a : α), foldr op₃ (f a b) tail✝ = f (foldr op₁ a tail✝) (foldr op₂ b tail✝)
a✝ : α
⊢ foldr op₃ (f a✝ b) (head✝ :: tail✝) = f (foldr op₁ a✝ (head✝ :: tail✝)) (foldr op₂ b (head✝ :: tail✝))
[PROOFSTEP]
simp only [*, foldr]
[GOAL]
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List (α → α)
f : α → α
hl : ∀ (f : α → α), f ∈ l → Injective f
hf : Injective f
⊢ Injective (foldl comp f l)
[PROOFSTEP]
induction' l with lh lt l_ih generalizing f
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List (α → α)
f✝ : α → α
hl✝ : ∀ (f : α → α), f ∈ l → Injective f
hf✝ : Injective f✝
f : α → α
hl : ∀ (f : α → α), f ∈ [] → Injective f
hf : Injective f
⊢ Injective (foldl comp f [])
[PROOFSTEP]
exact hf
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List (α → α)
f✝ : α → α
hl✝ : ∀ (f : α → α), f ∈ l → Injective f
hf✝ : Injective f✝
lh : α → α
lt : List (α → α)
l_ih : ∀ {f : α → α}, (∀ (f : α → α), f ∈ lt → Injective f) → Injective f → Injective (foldl comp f lt)
f : α → α
hl : ∀ (f : α → α), f ∈ lh :: lt → Injective f
hf : Injective f
⊢ Injective (foldl comp f (lh :: lt))
[PROOFSTEP]
apply l_ih fun _ h => hl _ (List.mem_cons_of_mem _ h)
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List (α → α)
f✝ : α → α
hl✝ : ∀ (f : α → α), f ∈ l → Injective f
hf✝ : Injective f✝
lh : α → α
lt : List (α → α)
l_ih : ∀ {f : α → α}, (∀ (f : α → α), f ∈ lt → Injective f) → Injective f → Injective (foldl comp f lt)
f : α → α
hl : ∀ (f : α → α), f ∈ lh :: lt → Injective f
hf : Injective f
⊢ Injective (f ∘ lh)
[PROOFSTEP]
apply Function.Injective.comp hf
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
l : List (α → α)
f✝ : α → α
hl✝ : ∀ (f : α → α), f ∈ l → Injective f
hf✝ : Injective f✝
lh : α → α
lt : List (α → α)
l_ih : ∀ {f : α → α}, (∀ (f : α → α), f ∈ lt → Injective f) → Injective f → Injective (foldl comp f lt)
f : α → α
hl : ∀ (f : α → α), f ∈ lh :: lt → Injective f
hf : Injective f
⊢ Injective lh
[PROOFSTEP]
apply hl _ (List.mem_cons_self _ _)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
l : List α
op : α → β → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ l → C (op a b)
⊢ C (foldr op b l)
[PROOFSTEP]
cases l with
| nil => exact hb
|
  cons hd tl =>
  have IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl) := foldrRecOn _ _ _ hb
  refine' hl _ _ hd (mem_cons_self hd tl)
  refine' IH _
  intro y hy x hx
  exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
l : List α
op : α → β → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ l → C (op a b)
⊢ C (foldr op b l)
[PROOFSTEP]
cases l with
| nil => exact hb
|
  cons hd tl =>
  have IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl) := foldrRecOn _ _ _ hb
  refine' hl _ _ hd (mem_cons_self hd tl)
  refine' IH _
  intro y hy x hx
  exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ [] → C (op a b)
⊢ C (foldr op b [])
[PROOFSTEP]

| nil => exact hb
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ [] → C (op a b)
⊢ C (foldr op b [])
[PROOFSTEP]
exact hb
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op a b)
⊢ C (foldr op b (hd :: tl))
[PROOFSTEP]

|
  cons hd tl =>
  have IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl) := foldrRecOn _ _ _ hb
  refine' hl _ _ hd (mem_cons_self hd tl)
  refine' IH _
  intro y hy x hx
  exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op a b)
⊢ C (foldr op b (hd :: tl))
[PROOFSTEP]
have IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl) := foldrRecOn _ _ _ hb
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op a b)
IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl)
⊢ C (foldr op b (hd :: tl))
[PROOFSTEP]
refine' hl _ _ hd (mem_cons_self hd tl)
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op a b)
IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl)
⊢ C (foldr op b tl)
[PROOFSTEP]
refine' IH _
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op a b)
IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl)
⊢ (b : β) → C b → (a : α) → a ∈ tl → C (op a b)
[PROOFSTEP]
intro y hy x hx
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : α → β → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op a b)
IH : ((b : β) → C b → (a : α) → a ∈ tl → C (op a b)) → C (foldr op b tl)
y : β
hy : C y
x : α
hx : x ∈ tl
⊢ C (op x y)
[PROOFSTEP]
exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
l : List α
op : β → α → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ l → C (op b a)
⊢ C (foldl op b l)
[PROOFSTEP]
cases l with
| nil => exact hb
|
  cons hd tl =>
  have IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl) := foldlRecOn _ _
  refine' IH _ _ _
  · exact hl b hb hd (mem_cons_self hd tl)
  · intro y hy x hx
    exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
l : List α
op : β → α → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ l → C (op b a)
⊢ C (foldl op b l)
[PROOFSTEP]
cases l with
| nil => exact hb
|
  cons hd tl =>
  have IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl) := foldlRecOn _ _
  refine' IH _ _ _
  · exact hl b hb hd (mem_cons_self hd tl)
  · intro y hy x hx
    exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ [] → C (op b a)
⊢ C (foldl op b [])
[PROOFSTEP]

| nil => exact hb
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hl : (b : β) → C b → (a : α) → a ∈ [] → C (op b a)
⊢ C (foldl op b [])
[PROOFSTEP]
exact hb
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op b a)
⊢ C (foldl op b (hd :: tl))
[PROOFSTEP]

|
  cons hd tl =>
  have IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl) := foldlRecOn _ _
  refine' IH _ _ _
  · exact hl b hb hd (mem_cons_self hd tl)
  · intro y hy x hx
    exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op b a)
⊢ C (foldl op b (hd :: tl))
[PROOFSTEP]
have IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl) := foldlRecOn _ _
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op b a)
IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl)
⊢ C (foldl op b (hd :: tl))
[PROOFSTEP]
refine' IH _ _ _
[GOAL]
case cons.refine'_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op b a)
IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl)
⊢ C (op b hd)
[PROOFSTEP]
exact hl b hb hd (mem_cons_self hd tl)
[GOAL]
case cons.refine'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op b a)
IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl)
⊢ (b : β) → C b → (a : α) → a ∈ tl → C (op b a)
[PROOFSTEP]
intro y hy x hx
[GOAL]
case cons.refine'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
C : β → Sort u_2
op : β → α → β
b : β
hb : C b
hd : α
tl : List α
hl : (b : β) → C b → (a : α) → a ∈ hd :: tl → C (op b a)
IH : (b : β) → C b → ((b : β) → C b → (a : α) → a ∈ tl → C (op b a)) → C (foldl op b tl)
y : β
hy : C y
x : α
hx : x ∈ tl
⊢ C (op y x)
[PROOFSTEP]
exact hl y hy x (mem_cons_of_mem hd hx)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a✝ : α
l✝ : List α
a : β
x : α
l : List α
⊢ length (scanl f a (x :: l)) = length (x :: l) + 1
[PROOFSTEP]
rw [scanl, length_cons, length_cons, ← succ_eq_add_one, congr_arg succ]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a✝ : α
l✝ : List α
a : β
x : α
l : List α
⊢ length (scanl f (f a x) l) = length l + 1
[PROOFSTEP]
exact length_scanl _ _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
l : List α
⊢ scanl f b (a :: l) = [b] ++ scanl f (f b a) l
[PROOFSTEP]
simp only [scanl, eq_self_iff_true, singleton_append, and_self_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
l : List α
⊢ get? (scanl f b l) 0 = some b
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
⊢ get? (scanl f b []) 0 = some b
[PROOFSTEP]
simp only [get?, scanl_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a head✝ : α
tail✝ : List α
⊢ get? (scanl f b (head✝ :: tail✝)) 0 = some b
[PROOFSTEP]
simp only [get?, scanl_cons, singleton_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
l : List α
h : 0 < length (scanl f b l)
⊢ get (scanl f b l) { val := 0, isLt := h } = b
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
h : 0 < length (scanl f b [])
⊢ get (scanl f b []) { val := 0, isLt := h } = b
[PROOFSTEP]
simp only [get, scanl_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a head✝ : α
tail✝ : List α
h : 0 < length (scanl f b (head✝ :: tail✝))
⊢ get (scanl f b (head✝ :: tail✝)) { val := 0, isLt := h } = b
[PROOFSTEP]
simp only [get, scanl_cons, singleton_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
l : List α
i : ℕ
⊢ get? (scanl f b l) (i + 1) = Option.bind (get? (scanl f b l) i) fun x => Option.map (fun y => f x y) (get? l i)
[PROOFSTEP]
induction' l with hd tl hl generalizing b i
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b✝ : β
a : α
l : List α
i✝ : ℕ
b : β
i : ℕ
⊢ get? (scanl f b []) (i + 1) = Option.bind (get? (scanl f b []) i) fun x => Option.map (fun y => f x y) (get? [] i)
[PROOFSTEP]
symm
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b✝ : β
a : α
l : List α
i✝ : ℕ
b : β
i : ℕ
⊢ (Option.bind (get? (scanl f b []) i) fun x => Option.map (fun y => f x y) (get? [] i)) = get? (scanl f b []) (i + 1)
[PROOFSTEP]
simp only [Option.bind_eq_none', get?, forall₂_true_iff, not_false_iff, Option.map_none', scanl_nil,
  Option.not_mem_none, forall_true_iff]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b✝ : β
a : α
l : List α
i✝ : ℕ
hd : α
tl : List α
hl :
  ∀ {b : β} {i : ℕ},
    get? (scanl f b tl) (i + 1) = Option.bind (get? (scanl f b tl) i) fun x => Option.map (fun y => f x y) (get? tl i)
b : β
i : ℕ
⊢ get? (scanl f b (hd :: tl)) (i + 1) =
    Option.bind (get? (scanl f b (hd :: tl)) i) fun x => Option.map (fun y => f x y) (get? (hd :: tl) i)
[PROOFSTEP]
simp only [scanl_cons, singleton_append]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b✝ : β
a : α
l : List α
i✝ : ℕ
hd : α
tl : List α
hl :
  ∀ {b : β} {i : ℕ},
    get? (scanl f b tl) (i + 1) = Option.bind (get? (scanl f b tl) i) fun x => Option.map (fun y => f x y) (get? tl i)
b : β
i : ℕ
⊢ get? (b :: scanl f (f b hd) tl) (i + 1) =
    Option.bind (get? (b :: scanl f (f b hd) tl) i) fun x => Option.map (fun y => f x y) (get? (hd :: tl) i)
[PROOFSTEP]
cases i
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b✝ : β
a : α
l : List α
i : ℕ
hd : α
tl : List α
hl :
  ∀ {b : β} {i : ℕ},
    get? (scanl f b tl) (i + 1) = Option.bind (get? (scanl f b tl) i) fun x => Option.map (fun y => f x y) (get? tl i)
b : β
⊢ get? (b :: scanl f (f b hd) tl) (zero + 1) =
    Option.bind (get? (b :: scanl f (f b hd) tl) zero) fun x => Option.map (fun y => f x y) (get? (hd :: tl) zero)
[PROOFSTEP]
simp only [Option.map_some', get?_zero_scanl, get?, Option.some_bind']
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b✝ : β
a : α
l : List α
i : ℕ
hd : α
tl : List α
hl :
  ∀ {b : β} {i : ℕ},
    get? (scanl f b tl) (i + 1) = Option.bind (get? (scanl f b tl) i) fun x => Option.map (fun y => f x y) (get? tl i)
b : β
n✝ : ℕ
⊢ get? (b :: scanl f (f b hd) tl) (succ n✝ + 1) =
    Option.bind (get? (b :: scanl f (f b hd) tl) (succ n✝)) fun x =>
      Option.map (fun y => f x y) (get? (hd :: tl) (succ n✝))
[PROOFSTEP]
simp only [hl, get?]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
l : List α
i : ℕ
h : i + 1 < length (scanl f b l)
⊢ nthLe (scanl f b l) (i + 1) h =
    f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
[PROOFSTEP]
induction i generalizing b l with
| zero =>
  cases l
  · simp only [length, zero_add, scanl_nil] at h 
  · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
| succ i hi =>
  cases l
  · simp only [length, add_lt_iff_neg_right, scanl_nil] at h 
    exact absurd h (not_lt_of_lt Nat.succ_pos')
  · simp_rw [scanl_cons]
    rw [nthLe_append_right]
    · simp only [length, zero_add 1, succ_add_sub_one, hi]; rfl
    · simp only [length, Nat.zero_le, le_add_iff_nonneg_left]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
b : β
a : α
l : List α
i : ℕ
h : i + 1 < length (scanl f b l)
⊢ nthLe (scanl f b l) (i + 1) h =
    f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
[PROOFSTEP]
induction i generalizing b l with
| zero =>
  cases l
  · simp only [length, zero_add, scanl_nil] at h 
  · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
| succ i hi =>
  cases l
  · simp only [length, add_lt_iff_neg_right, scanl_nil] at h 
    exact absurd h (not_lt_of_lt Nat.succ_pos')
  · simp_rw [scanl_cons]
    rw [nthLe_append_right]
    · simp only [length, zero_add 1, succ_add_sub_one, hi]; rfl
    · simp only [length, Nat.zero_le, le_add_iff_nonneg_left]
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
b : β
l : List α
h : zero + 1 < length (scanl f b l)
⊢ nthLe (scanl f b l) (zero + 1) h =
    f (nthLe (scanl f b l) zero (_ : zero < length (scanl f b l))) (nthLe l zero (_ : zero < length l))
[PROOFSTEP]

| zero =>
  cases l
  · simp only [length, zero_add, scanl_nil] at h 
  · simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
b : β
l : List α
h : zero + 1 < length (scanl f b l)
⊢ nthLe (scanl f b l) (zero + 1) h =
    f (nthLe (scanl f b l) zero (_ : zero < length (scanl f b l))) (nthLe l zero (_ : zero < length l))
[PROOFSTEP]
cases l
[GOAL]
case zero.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
b : β
h : zero + 1 < length (scanl f b [])
⊢ nthLe (scanl f b []) (zero + 1) h =
    f (nthLe (scanl f b []) zero (_ : zero < length (scanl f b []))) (nthLe [] zero (_ : zero < length []))
[PROOFSTEP]
simp only [length, zero_add, scanl_nil] at h 
[GOAL]
case zero.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
b : β
head✝ : α
tail✝ : List α
h : zero + 1 < length (scanl f b (head✝ :: tail✝))
⊢ nthLe (scanl f b (head✝ :: tail✝)) (zero + 1) h =
    f (nthLe (scanl f b (head✝ :: tail✝)) zero (_ : zero < length (scanl f b (head✝ :: tail✝))))
      (nthLe (head✝ :: tail✝) zero (_ : zero < length (head✝ :: tail✝)))
[PROOFSTEP]
simp [scanl_cons, singleton_append, nthLe_zero_scanl, nthLe_cons]
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
l : List α
h : succ i + 1 < length (scanl f b l)
⊢ nthLe (scanl f b l) (succ i + 1) h =
    f (nthLe (scanl f b l) (succ i) (_ : succ i < length (scanl f b l))) (nthLe l (succ i) (_ : succ i < length l))
[PROOFSTEP]

| succ i hi =>
  cases l
  · simp only [length, add_lt_iff_neg_right, scanl_nil] at h 
    exact absurd h (not_lt_of_lt Nat.succ_pos')
  · simp_rw [scanl_cons]
    rw [nthLe_append_right]
    · simp only [length, zero_add 1, succ_add_sub_one, hi]; rfl
    · simp only [length, Nat.zero_le, le_add_iff_nonneg_left]
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
l : List α
h : succ i + 1 < length (scanl f b l)
⊢ nthLe (scanl f b l) (succ i + 1) h =
    f (nthLe (scanl f b l) (succ i) (_ : succ i < length (scanl f b l))) (nthLe l (succ i) (_ : succ i < length l))
[PROOFSTEP]
cases l
[GOAL]
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
h : succ i + 1 < length (scanl f b [])
⊢ nthLe (scanl f b []) (succ i + 1) h =
    f (nthLe (scanl f b []) (succ i) (_ : succ i < length (scanl f b []))) (nthLe [] (succ i) (_ : succ i < length []))
[PROOFSTEP]
simp only [length, add_lt_iff_neg_right, scanl_nil] at h 
[GOAL]
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
h✝ : succ i + 1 < length (scanl f b [])
h : succ i < 0
⊢ nthLe (scanl f b []) (succ i + 1) h✝ =
    f (nthLe (scanl f b []) (succ i) (_ : succ i < length (scanl f b []))) (nthLe [] (succ i) (_ : succ i < length []))
[PROOFSTEP]
exact absurd h (not_lt_of_lt Nat.succ_pos')
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
head✝ : α
tail✝ : List α
h : succ i + 1 < length (scanl f b (head✝ :: tail✝))
⊢ nthLe (scanl f b (head✝ :: tail✝)) (succ i + 1) h =
    f (nthLe (scanl f b (head✝ :: tail✝)) (succ i) (_ : succ i < length (scanl f b (head✝ :: tail✝))))
      (nthLe (head✝ :: tail✝) (succ i) (_ : succ i < length (head✝ :: tail✝)))
[PROOFSTEP]
simp_rw [scanl_cons]
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
head✝ : α
tail✝ : List α
h : succ i + 1 < length (scanl f b (head✝ :: tail✝))
⊢ nthLe ([b] ++ scanl f (f b head✝) tail✝) (succ i + 1) (_ : succ i + 1 < length ([b] ++ scanl f (f b head✝) tail✝)) =
    f (nthLe ([b] ++ scanl f (f b head✝) tail✝) (succ i) (_ : succ i < length ([b] ++ scanl f (f b head✝) tail✝)))
      (nthLe (head✝ :: tail✝) (succ i) (_ : succ i < length (head✝ :: tail✝)))
[PROOFSTEP]
rw [nthLe_append_right]
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
head✝ : α
tail✝ : List α
h : succ i + 1 < length (scanl f b (head✝ :: tail✝))
⊢ nthLe (scanl f (f b head✝) tail✝) (succ i + 1 - length [b])
      (_ : succ i + 1 - length [b] < length (scanl f (f b head✝) tail✝)) =
    f (nthLe ([b] ++ scanl f (f b head✝) tail✝) (succ i) (_ : succ i < length ([b] ++ scanl f (f b head✝) tail✝)))
      (nthLe (head✝ :: tail✝) (succ i) (_ : succ i < length (head✝ :: tail✝)))
[PROOFSTEP]
simp only [length, zero_add 1, succ_add_sub_one, hi]
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
head✝ : α
tail✝ : List α
h : succ i + 1 < length (scanl f b (head✝ :: tail✝))
⊢ f (nthLe (scanl f (f b head✝) tail✝) i (_ : i < length (scanl f (f b head✝) tail✝)))
      (nthLe tail✝ i (_ : i < length tail✝)) =
    f (nthLe ([b] ++ scanl f (f b head✝) tail✝) (succ i) (_ : succ i < length ([b] ++ scanl f (f b head✝) tail✝)))
      (nthLe (head✝ :: tail✝) (succ i) (_ : succ i < length (head✝ :: tail✝)))
[PROOFSTEP]
rfl
[GOAL]
case succ.cons.h₁
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : β → α → β
a : α
i : ℕ
hi :
  ∀ {b : β} {l : List α} {h : i + 1 < length (scanl f b l)},
    nthLe (scanl f b l) (i + 1) h =
      f (nthLe (scanl f b l) i (_ : i < length (scanl f b l))) (nthLe l i (_ : i < length l))
b : β
head✝ : α
tail✝ : List α
h : succ i + 1 < length (scanl f b (head✝ :: tail✝))
⊢ length [b] ≤ succ i + 1
[PROOFSTEP]
simp only [length, Nat.zero_le, le_add_iff_nonneg_left]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
a : α
l : List α
⊢ scanr f b (a :: l) = foldr f b (a :: l) :: scanr f b l
[PROOFSTEP]
simp only [scanr, foldr, cons.injEq, and_true]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
a : α
l : List α
⊢ f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) l).fst = f a (foldr f b l)
[PROOFSTEP]
induction l generalizing a with
| nil => rfl
| cons hd tl ih => simp only [foldr, ih]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
a : α
l : List α
⊢ f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) l).fst = f a (foldr f b l)
[PROOFSTEP]
induction l generalizing a with
| nil => rfl
| cons hd tl ih => simp only [foldr, ih]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
a : α
⊢ f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) []).fst = f a (foldr f b [])
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
a : α
⊢ f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) []).fst = f a (foldr f b [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
hd : α
tl : List α
ih : ∀ (a : α), f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) tl).fst = f a (foldr f b tl)
a : α
⊢ f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) (hd :: tl)).fst = f a (foldr f b (hd :: tl))
[PROOFSTEP]

| cons hd tl ih => simp only [foldr, ih]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
b : β
hd : α
tl : List α
ih : ∀ (a : α), f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) tl).fst = f a (foldr f b tl)
a : α
⊢ f a (foldr (fun a x => (f a x.fst, x.fst :: x.snd)) (b, []) (hd :: tl)).fst = f a (foldr f b (hd :: tl))
[PROOFSTEP]
simp only [foldr, ih]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b c : α
l : List α
⊢ foldl f a (c :: l ++ [b]) = foldr f b (a :: c :: l)
[PROOFSTEP]
simp only [cons_append, foldl_cons, foldr_cons, foldl1_eq_foldr1 _ _ l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b c : α
l : List α
⊢ f (f a c) (foldr f b l) = f a (f c (foldr f b l))
[PROOFSTEP]
rw [hassoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b c : α
l : List α
⊢ foldl f a (b :: c :: l) = f b (foldl f a (c :: l))
[PROOFSTEP]
simp only [foldl_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b c : α
l : List α
⊢ foldl f (f (f a b) c) l = f b (foldl f (f a c) l)
[PROOFSTEP]
rw [← foldl_eq_of_comm_of_assoc .., right_comm _ hcomm hassoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b c : α
l : List α
⊢ foldl f (f (f a c) b) l = foldl f (f a c) (b :: l)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b : α
l : List α
⊢ foldl f a (b :: l) = foldr f a (b :: l)
[PROOFSTEP]
simp only [foldr_cons, foldl_eq_of_comm_of_assoc hcomm hassoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α → α
hcomm : Commutative f
hassoc : Associative f
a b : α
l : List α
⊢ f b (foldl f a l) = f b (foldr f a l)
[PROOFSTEP]
rw [foldl_eq_foldr a l]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → α
hf : ∀ (a : α) (b c : β), f (f a b) c = f (f a c) b
a : α
b c : β
l : List β
⊢ foldl f a (b :: c :: l) = f (foldl f a (c :: l)) b
[PROOFSTEP]
rw [foldl, foldl, foldl, ← foldl_eq_of_comm' .., foldl, hf]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → α
hf : ∀ (a : α) (b c : β), f (f a b) c = f (f a c) b
a : α
b : β
l : List β
⊢ foldl f a (b :: l) = foldr (flip f) a (b :: l)
[PROOFSTEP]
rw [foldl_eq_of_comm' hf, foldr, foldl_eq_foldr' ..]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → α
hf : ∀ (a : α) (b c : β), f (f a b) c = f (f a c) b
a : α
b : β
l : List β
⊢ f (foldr (flip f) a l) b = flip f b (foldr (flip f) a l)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
hf : ∀ (a b : α) (c : β), f a (f b c) = f b (f a c)
a : β
b c : α
l : List α
⊢ foldr f a (b :: c :: l) = foldr f (f b a) (c :: l)
[PROOFSTEP]
rw [foldr, foldr, foldr, hf, ← foldr_eq_of_comm' ..]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β → β
hf : ∀ (a b : α) (c : β), f a (f b c) = f b (f a c)
a : β
b c : α
l : List α
⊢ f c (f b (foldr f a l)) = f c (foldr f a (b :: l))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
op : α → α → α
ha : IsAssociative α op
hc : IsCommutative α op
a : α
l : List α
a₁ a₂ : α
⊢ ((a :: l) <*> op a₁ a₂) = l <*> op a₁ (op a₂ a)
[PROOFSTEP]
simp only [foldl_cons, ha.assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
op : α → α → α
ha : IsAssociative α op
hc : IsCommutative α op
a : α
l : List α
a₁ a₂ : α
⊢ (l <*> op a₁ (op a₂ a)) = op a₁ ((a :: l) <*> a₂)
[PROOFSTEP]
rw [foldl_assoc, foldl_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
op : α → α → α
ha : IsAssociative α op
hc : IsCommutative α op
a : α
l : List α
a₁ a₂ : α
⊢ op ((a :: l) <*> a₁) a₂ = op a₁ (foldr (fun x x_1 => op x x_1) a₂ (a :: l))
[PROOFSTEP]
simp only [foldl_cons, foldr_cons, foldl_assoc, ha.assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
op : α → α → α
ha : IsAssociative α op
hc : IsCommutative α op
a : α
l : List α
a₁ a₂ : α
⊢ op a₁ (op (l <*> a) a₂) = op a₁ (op a (foldr (fun x x_1 => op x x_1) a₂ l))
[PROOFSTEP]
rw [foldl_op_eq_op_foldr_assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
op : α → α → α
ha : IsAssociative α op
hc : IsCommutative α op
l : List α
a₁ a₂ : α
⊢ ((a₁ :: l) <*> a₂) = op a₁ (l <*> a₂)
[PROOFSTEP]
rw [foldl_cons, hc.comm, foldl_assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m β
b : β
l : List α
⊢ foldrM f b l = foldr (fun a mb => mb >>= f a) (pure b) l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m β
b : β
⊢ foldrM f b [] = foldr (fun a mb => mb >>= f a) (pure b) []
[PROOFSTEP]
simp [*]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → β → m β
b : β
head✝ : α
tail✝ : List α
tail_ih✝ : foldrM f b tail✝ = foldr (fun a mb => mb >>= f a) (pure b) tail✝
⊢ foldrM f b (head✝ :: tail✝) = foldr (fun a mb => mb >>= f a) (pure b) (head✝ :: tail✝)
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
l : List α
⊢ List.foldlM f b l =
    foldl
      (fun mb a => do
        let b ← mb
        f b a)
      (pure b) l
[PROOFSTEP]
suffices h : ∀ mb : m β, (mb >>= fun b => List.foldlM f b l) = foldl (fun mb a => mb >>= fun b => f b a) mb l
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
l : List α
h :
  ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b l) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb l
⊢ List.foldlM f b l =
    foldl
      (fun mb a => do
        let b ← mb
        f b a)
      (pure b) l
[PROOFSTEP]
simp [← h (pure b)]
[GOAL]
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
l : List α
⊢ ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b l) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb l
[PROOFSTEP]
induction l with
| nil => intro; simp
| cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ← l_ih, functor_norm]
[GOAL]
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
l : List α
⊢ ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b l) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb l
[PROOFSTEP]
induction l with
| nil => intro; simp
| cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ← l_ih, functor_norm]
[GOAL]
case h.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
⊢ ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b []) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb []
[PROOFSTEP]

| nil => intro; simp
[GOAL]
case h.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
⊢ ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b []) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb []
[PROOFSTEP]
intro
[GOAL]
case h.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
mb✝ : m β
⊢ (do
      let b ← mb✝
      List.foldlM f b []) =
    foldl
      (fun mb a => do
        let b ← mb
        f b a)
      mb✝ []
[PROOFSTEP]
simp
[GOAL]
case h.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
head✝ : α
tail✝ : List α
l_ih :
  ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b tail✝) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb tail✝
⊢ ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b (head✝ :: tail✝)) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb (head✝ :: tail✝)
[PROOFSTEP]

| cons _ _ l_ih => intro; simp only [List.foldlM, foldl, ← l_ih, functor_norm]
[GOAL]
case h.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
head✝ : α
tail✝ : List α
l_ih :
  ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b tail✝) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb tail✝
⊢ ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b (head✝ :: tail✝)) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb (head✝ :: tail✝)
[PROOFSTEP]
intro
[GOAL]
case h.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : Type v → Type w
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : β → α → m β
b : β
head✝ : α
tail✝ : List α
l_ih :
  ∀ (mb : m β),
    (do
        let b ← mb
        List.foldlM f b tail✝) =
      foldl
        (fun mb a => do
          let b ← mb
          f b a)
        mb tail✝
mb✝ : m β
⊢ (do
      let b ← mb✝
      List.foldlM f b (head✝ :: tail✝)) =
    foldl
      (fun mb a => do
        let b ← mb
        f b a)
      mb✝ (head✝ :: tail✝)
[PROOFSTEP]
simp only [List.foldlM, foldl, ← l_ih, functor_norm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n✝ : ℕ
l✝ : List α
n : ℕ
l xs : List α
acc : Array α
⊢ splitAt.go l xs n acc = if n < length xs then (Array.toList acc ++ take n xs, drop n xs) else (l, [])
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n✝ : ℕ
l✝ : List α
n : ℕ
l xs : List α
acc : Array α
h : n < length xs
⊢ splitAt.go l xs n acc = (Array.toList acc ++ take n xs, drop n xs)
[PROOFSTEP]
induction n generalizing xs acc with
| zero =>
  rw [splitAt.go, take, drop, append_nil]
  · intros h₁; rw [h₁] at h ; contradiction
  · intros; contradiction
| succ _ ih =>
  cases xs with
  | nil => contradiction
  | cons hd tl =>
    rw [length, succ_eq_add_one] at h 
    rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
    exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n✝ : ℕ
l✝ : List α
n : ℕ
l xs : List α
acc : Array α
h : n < length xs
⊢ splitAt.go l xs n acc = (Array.toList acc ++ take n xs, drop n xs)
[PROOFSTEP]
induction n generalizing xs acc with
| zero =>
  rw [splitAt.go, take, drop, append_nil]
  · intros h₁; rw [h₁] at h ; contradiction
  · intros; contradiction
| succ _ ih =>
  cases xs with
  | nil => contradiction
  | cons hd tl =>
    rw [length, succ_eq_add_one] at h 
    rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
    exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case pos.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
⊢ splitAt.go l xs zero acc = (Array.toList acc ++ take zero xs, drop zero xs)
[PROOFSTEP]

| zero =>
  rw [splitAt.go, take, drop, append_nil]
  · intros h₁; rw [h₁] at h ; contradiction
  · intros; contradiction
[GOAL]
case pos.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
⊢ splitAt.go l xs zero acc = (Array.toList acc ++ take zero xs, drop zero xs)
[PROOFSTEP]
rw [splitAt.go, take, drop, append_nil]
[GOAL]
case pos.zero.x_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
⊢ xs = [] → False
[PROOFSTEP]
intros h₁
[GOAL]
case pos.zero.x_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
h₁ : xs = []
⊢ False
[PROOFSTEP]
rw [h₁] at h 
[GOAL]
case pos.zero.x_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length []
h₁ : xs = []
⊢ False
[PROOFSTEP]
contradiction
[GOAL]
case pos.zero.x_5
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
⊢ ∀ (x : α) (xs_1 : List α) (n : ℕ), xs = x :: xs_1 → zero = succ n → False
[PROOFSTEP]
intros
[GOAL]
case pos.zero.x_5
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
x✝ : α
xs_1✝ : List α
n✝ : ℕ
x_1✝ : xs = x✝ :: xs_1✝
x_2✝ : zero = succ n✝
⊢ False
[PROOFSTEP]
contradiction
[GOAL]
case pos.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
xs : List α
acc : Array α
h : succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (Array.toList acc ++ take (succ n✝) xs, drop (succ n✝) xs)
[PROOFSTEP]

| succ _ ih =>
  cases xs with
  | nil => contradiction
  | cons hd tl =>
    rw [length, succ_eq_add_one] at h 
    rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
    exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case pos.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
xs : List α
acc : Array α
h : succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (Array.toList acc ++ take (succ n✝) xs, drop (succ n✝) xs)
[PROOFSTEP]
cases xs with
| nil => contradiction
| cons hd tl =>
  rw [length, succ_eq_add_one] at h 
  rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
  exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case pos.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
xs : List α
acc : Array α
h : succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (Array.toList acc ++ take (succ n✝) xs, drop (succ n✝) xs)
[PROOFSTEP]
cases xs with
| nil => contradiction
| cons hd tl =>
  rw [length, succ_eq_add_one] at h 
  rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
  exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case pos.succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
h : succ n✝ < length []
⊢ splitAt.go l [] (succ n✝) acc = (Array.toList acc ++ take (succ n✝) [], drop (succ n✝) [])
[PROOFSTEP]

| nil => contradiction
[GOAL]
case pos.succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
h : succ n✝ < length []
⊢ splitAt.go l [] (succ n✝) acc = (Array.toList acc ++ take (succ n✝) [], drop (succ n✝) [])
[PROOFSTEP]
contradiction
[GOAL]
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : succ n✝ < length (hd :: tl)
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (Array.toList acc ++ take (succ n✝) (hd :: tl), drop (succ n✝) (hd :: tl))
[PROOFSTEP]

| cons hd tl =>
  rw [length, succ_eq_add_one] at h 
  rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
  exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : succ n✝ < length (hd :: tl)
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (Array.toList acc ++ take (succ n✝) (hd :: tl), drop (succ n✝) (hd :: tl))
[PROOFSTEP]
rw [length, succ_eq_add_one] at h 
[GOAL]
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : n✝ + 1 < length tl + 1
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (Array.toList acc ++ take (succ n✝) (hd :: tl), drop (succ n✝) (hd :: tl))
[PROOFSTEP]
rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data, ← Array.toList_eq]
[GOAL]
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : n✝ + 1 < length tl + 1
⊢ splitAt.go l tl n✝ (Array.push acc hd) = (Array.toList (Array.push acc hd) ++ take n✝ tl, drop n✝ tl)
[PROOFSTEP]
exact ih _ _ <| lt_of_add_lt_add_right h
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n✝ : ℕ
l✝ : List α
n : ℕ
l xs : List α
acc : Array α
h : ¬n < length xs
⊢ splitAt.go l xs n acc = (l, [])
[PROOFSTEP]
induction n generalizing xs acc with
| zero =>
  rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h 
  rw [eq_nil_of_length_eq_zero h, splitAt.go]
| succ _ ih =>
  cases xs with
  | nil => rw [splitAt.go]
  | cons hd tl =>
    rw [length, succ_eq_add_one] at h 
    rw [splitAt.go]
    exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n✝ : ℕ
l✝ : List α
n : ℕ
l xs : List α
acc : Array α
h : ¬n < length xs
⊢ splitAt.go l xs n acc = (l, [])
[PROOFSTEP]
induction n generalizing xs acc with
| zero =>
  rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h 
  rw [eq_nil_of_length_eq_zero h, splitAt.go]
| succ _ ih =>
  cases xs with
  | nil => rw [splitAt.go]
  | cons hd tl =>
    rw [length, succ_eq_add_one] at h 
    rw [splitAt.go]
    exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : ¬zero < length xs
⊢ splitAt.go l xs zero acc = (l, [])
[PROOFSTEP]

| zero =>
  rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h 
  rw [eq_nil_of_length_eq_zero h, splitAt.go]
[GOAL]
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : ¬zero < length xs
⊢ splitAt.go l xs zero acc = (l, [])
[PROOFSTEP]
rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h 
[GOAL]
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : length xs = 0
⊢ splitAt.go l xs zero acc = (l, [])
[PROOFSTEP]
rw [eq_nil_of_length_eq_zero h, splitAt.go]
[GOAL]
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
xs : List α
acc : Array α
h : ¬succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (l, [])
[PROOFSTEP]

| succ _ ih =>
  cases xs with
  | nil => rw [splitAt.go]
  | cons hd tl =>
    rw [length, succ_eq_add_one] at h 
    rw [splitAt.go]
    exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
xs : List α
acc : Array α
h : ¬succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (l, [])
[PROOFSTEP]
cases xs with
| nil => rw [splitAt.go]
| cons hd tl =>
  rw [length, succ_eq_add_one] at h 
  rw [splitAt.go]
  exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
xs : List α
acc : Array α
h : ¬succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (l, [])
[PROOFSTEP]
cases xs with
| nil => rw [splitAt.go]
| cons hd tl =>
  rw [length, succ_eq_add_one] at h 
  rw [splitAt.go]
  exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
case neg.succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
acc : Array α
h : ¬succ n✝ < length []
⊢ splitAt.go l [] (succ n✝) acc = (l, [])
[PROOFSTEP]

| nil => rw [splitAt.go]
[GOAL]
case neg.succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
acc : Array α
h : ¬succ n✝ < length []
⊢ splitAt.go l [] (succ n✝) acc = (l, [])
[PROOFSTEP]
rw [splitAt.go]
[GOAL]
case neg.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
acc : Array α
hd : α
tl : List α
h : ¬succ n✝ < length (hd :: tl)
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (l, [])
[PROOFSTEP]

| cons hd tl =>
  rw [length, succ_eq_add_one] at h 
  rw [splitAt.go]
  exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
case neg.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
acc : Array α
hd : α
tl : List α
h : ¬succ n✝ < length (hd :: tl)
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (l, [])
[PROOFSTEP]
rw [length, succ_eq_add_one] at h 
[GOAL]
case neg.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
acc : Array α
hd : α
tl : List α
h : ¬n✝ + 1 < length tl + 1
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (l, [])
[PROOFSTEP]
rw [splitAt.go]
[GOAL]
case neg.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
acc : Array α
hd : α
tl : List α
h : ¬n✝ + 1 < length tl + 1
⊢ splitAt.go l tl n✝ (Array.push acc hd) = (l, [])
[PROOFSTEP]
exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l : List α
⊢ splitAt n l = (take n l, drop n l)
[PROOFSTEP]
by_cases h : n < l.length
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l : List α
h : n < length l
⊢ splitAt n l = (take n l, drop n l)
[PROOFSTEP]
rw [splitAt, go_eq_take_drop]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l : List α
h : ¬n < length l
⊢ splitAt n l = (take n l, drop n l)
[PROOFSTEP]
rw [splitAt, go_eq_take_drop]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l : List α
h : n < length l
⊢ (if n < length l then (Array.toList #[] ++ take n l, drop n l) else (l, [])) = (take n l, drop n l)
[PROOFSTEP]
rw [if_pos h]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l : List α
h : n < length l
⊢ (Array.toList #[] ++ take n l, drop n l) = (take n l, drop n l)
[PROOFSTEP]
rfl
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l : List α
h : ¬n < length l
⊢ (if n < length l then (Array.toList #[] ++ take n l, drop n l) else (l, [])) = (take n l, drop n l)
[PROOFSTEP]
rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
xs acc : List α
⊢ go p xs acc ≠ []
[PROOFSTEP]
induction xs generalizing acc
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
acc : List α
⊢ go p [] acc ≠ []
[PROOFSTEP]
simp [go]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (acc : List α), go p tail✝ acc ≠ []
acc : List α
⊢ go p (head✝ :: tail✝) acc ≠ []
[PROOFSTEP]
simp [go]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (acc : List α), go p tail✝ acc ≠ []
acc : List α
⊢ ¬(if p head✝ = true then reverse acc :: go p tail✝ [] else go p tail✝ (head✝ :: acc)) = []
[PROOFSTEP]
split
[GOAL]
case cons.inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (acc : List α), go p tail✝ acc ≠ []
acc : List α
h✝ : p head✝ = true
⊢ ¬False
[PROOFSTEP]
simp [*]
[GOAL]
case cons.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (acc : List α), go p tail✝ acc ≠ []
acc : List α
h✝ : ¬p head✝ = true
⊢ ¬go p tail✝ (head✝ :: acc) = []
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
xs acc : List α
⊢ go p xs acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p xs)
[PROOFSTEP]
induction xs generalizing acc with
| nil => simp only [go, modifyHead, splitOnP_nil, append_nil]
| cons hd tl ih =>
  simp only [splitOnP, go]; split
  · simp only [modifyHead, reverse_nil, append_nil]
  · rw [ih [hd], modifyHead_modifyHead, ih]
    congr; funext x; simp only [reverse_cons, append_assoc]; rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
xs acc : List α
⊢ go p xs acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p xs)
[PROOFSTEP]
induction xs generalizing acc with
| nil => simp only [go, modifyHead, splitOnP_nil, append_nil]
| cons hd tl ih =>
  simp only [splitOnP, go]; split
  · simp only [modifyHead, reverse_nil, append_nil]
  · rw [ih [hd], modifyHead_modifyHead, ih]
    congr; funext x; simp only [reverse_cons, append_assoc]; rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
acc : List α
⊢ go p [] acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p [])
[PROOFSTEP]

| nil => simp only [go, modifyHead, splitOnP_nil, append_nil]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
acc : List α
⊢ go p [] acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p [])
[PROOFSTEP]
simp only [go, modifyHead, splitOnP_nil, append_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
⊢ go p (hd :: tl) acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p (hd :: tl))
[PROOFSTEP]

| cons hd tl ih =>
  simp only [splitOnP, go]; split
  · simp only [modifyHead, reverse_nil, append_nil]
  · rw [ih [hd], modifyHead_modifyHead, ih]
    congr; funext x; simp only [reverse_cons, append_assoc]; rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
⊢ go p (hd :: tl) acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p (hd :: tl))
[PROOFSTEP]
simp only [splitOnP, go]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
⊢ (if p hd = true then reverse acc :: go p tl [] else go p tl (hd :: acc)) =
    modifyHead (fun x => reverse acc ++ x) (if p hd = true then reverse [] :: go p tl [] else go p tl [hd])
[PROOFSTEP]
split
[GOAL]
case cons.inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
h✝ : p hd = true
⊢ reverse acc :: go p tl [] = modifyHead (fun x => reverse acc ++ x) (reverse [] :: go p tl [])
[PROOFSTEP]
simp only [modifyHead, reverse_nil, append_nil]
[GOAL]
case cons.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
h✝ : ¬p hd = true
⊢ go p tl (hd :: acc) = modifyHead (fun x => reverse acc ++ x) (go p tl [hd])
[PROOFSTEP]
rw [ih [hd], modifyHead_modifyHead, ih]
[GOAL]
case cons.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
h✝ : ¬p hd = true
⊢ modifyHead (fun x => reverse (hd :: acc) ++ x) (splitOnP p tl) =
    modifyHead ((fun x => reverse acc ++ x) ∘ fun x => reverse [hd] ++ x) (splitOnP p tl)
[PROOFSTEP]
congr
[GOAL]
case cons.inr.e_f
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
h✝ : ¬p hd = true
⊢ (fun x => reverse (hd :: acc) ++ x) = (fun x => reverse acc ++ x) ∘ fun x => reverse [hd] ++ x
[PROOFSTEP]
funext x
[GOAL]
case cons.inr.e_f.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
h✝ : ¬p hd = true
x : List α
⊢ reverse (hd :: acc) ++ x = ((fun x => reverse acc ++ x) ∘ fun x => reverse [hd] ++ x) x
[PROOFSTEP]
simp only [reverse_cons, append_assoc]
[GOAL]
case cons.inr.e_f.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : ∀ (acc : List α), go p tl acc = modifyHead (fun x => reverse acc ++ x) (splitOnP p tl)
acc : List α
h✝ : ¬p hd = true
x : List α
⊢ reverse acc ++ ([hd] ++ x) = ((fun x => reverse acc ++ x) ∘ fun x => reverse [] ++ ([hd] ++ x)) x
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
x : α
xs : List α
⊢ splitOnP p (x :: xs) = if p x = true then [] :: splitOnP p xs else modifyHead (cons x) (splitOnP p xs)
[PROOFSTEP]
rw [splitOnP, splitOnP.go]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
x : α
xs : List α
⊢ (if p x = true then reverse [] :: splitOnP.go p xs [] else splitOnP.go p xs [x]) =
    if p x = true then [] :: splitOnP p xs else modifyHead (cons x) (splitOnP p xs)
[PROOFSTEP]
split <;> [rfl; simp [splitOnP.go_acc]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
x : α
xs : List α
⊢ (if p x = true then reverse [] :: splitOnP.go p xs [] else splitOnP.go p xs [x]) =
    if p x = true then [] :: splitOnP p xs else modifyHead (cons x) (splitOnP p xs)
[PROOFSTEP]
split
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
x : α
xs : List α
h✝ : p x = true
⊢ reverse [] :: splitOnP.go p xs [] = [] :: splitOnP p xs
[PROOFSTEP]
rfl
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
x : α
xs : List α
h✝ : ¬p x = true
⊢ splitOnP.go p xs [x] = modifyHead (cons x) (splitOnP p xs)
[PROOFSTEP]
simp [splitOnP.go_acc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
xs ys : List (List α)
a : α
hxs : xs ≠ []
hys : ys ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) xs) ys) = a :: join (zipWith (fun x x_1 => x ++ x_1) xs ys)
[PROOFSTEP]
cases xs with
| nil => contradiction
| cons =>
  cases ys with
  | nil => contradiction
  | cons => rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs✝ ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
xs ys : List (List α)
a : α
hxs : xs ≠ []
hys : ys ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) xs) ys) = a :: join (zipWith (fun x x_1 => x ++ x_1) xs ys)
[PROOFSTEP]
cases xs with
| nil => contradiction
| cons =>
  cases ys with
  | nil => contradiction
  | cons => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
ys : List (List α)
a : α
hys : ys ≠ []
hxs : [] ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) []) ys) = a :: join (zipWith (fun x x_1 => x ++ x_1) [] ys)
[PROOFSTEP]

| nil => contradiction
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
ys : List (List α)
a : α
hys : ys ≠ []
hxs : [] ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) []) ys) = a :: join (zipWith (fun x x_1 => x ++ x_1) [] ys)
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
ys : List (List α)
a : α
hys : ys ≠ []
head✝ : List α
tail✝ : List (List α)
hxs : head✝ :: tail✝ ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝ :: tail✝)) ys) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝ :: tail✝) ys)
[PROOFSTEP]

| cons =>
  cases ys with
  | nil => contradiction
  | cons => rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
ys : List (List α)
a : α
hys : ys ≠ []
head✝ : List α
tail✝ : List (List α)
hxs : head✝ :: tail✝ ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝ :: tail✝)) ys) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝ :: tail✝) ys)
[PROOFSTEP]
cases ys with
| nil => contradiction
| cons => rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys✝ : List α
ls : List (List α)
f : List α → List α
as : List α
ys : List (List α)
a : α
hys : ys ≠ []
head✝ : List α
tail✝ : List (List α)
hxs : head✝ :: tail✝ ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝ :: tail✝)) ys) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝ :: tail✝) ys)
[PROOFSTEP]
cases ys with
| nil => contradiction
| cons => rfl
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
as : List α
a : α
head✝ : List α
tail✝ : List (List α)
hxs : head✝ :: tail✝ ≠ []
hys : [] ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝ :: tail✝)) []) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝ :: tail✝) [])
[PROOFSTEP]

| nil => contradiction
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
as : List α
a : α
head✝ : List α
tail✝ : List (List α)
hxs : head✝ :: tail✝ ≠ []
hys : [] ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝ :: tail✝)) []) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝ :: tail✝) [])
[PROOFSTEP]
contradiction
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
as : List α
a : α
head✝¹ : List α
tail✝¹ : List (List α)
hxs : head✝¹ :: tail✝¹ ≠ []
head✝ : List α
tail✝ : List (List α)
hys : head✝ :: tail✝ ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝¹ :: tail✝¹)) (head✝ :: tail✝)) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝¹ :: tail✝¹) (head✝ :: tail✝))
[PROOFSTEP]

| cons => rfl
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
as : List α
a : α
head✝¹ : List α
tail✝¹ : List (List α)
hxs : head✝¹ :: tail✝¹ ≠ []
head✝ : List α
tail✝ : List (List α)
hys : head✝ :: tail✝ ≠ []
⊢ join (zipWith (fun x x_1 => x ++ x_1) (modifyHead (cons a) (head✝¹ :: tail✝¹)) (head✝ :: tail✝)) =
    a :: join (zipWith (fun x x_1 => x ++ x_1) (head✝¹ :: tail✝¹) (head✝ :: tail✝))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
as : List α
⊢ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as) (map (fun x => [x]) (filter p as) ++ [[]])) = as
[PROOFSTEP]
induction as with
| nil => rfl
| cons a as' ih =>
  rw [splitOnP_cons, filter]
  by_cases h : p a
  · rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj]
    exact ih
  · rw [if_neg h, eq_false_of_ne_true h,
      join_zipWith (splitOnP_ne_nil _ _) (append_ne_nil_of_ne_nil_right _ [[]] (cons_ne_nil [] [])), cons_inj]
    exact ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
as : List α
⊢ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as) (map (fun x => [x]) (filter p as) ++ [[]])) = as
[PROOFSTEP]
induction as with
| nil => rfl
| cons a as' ih =>
  rw [splitOnP_cons, filter]
  by_cases h : p a
  · rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj]
    exact ih
  · rw [if_neg h, eq_false_of_ne_true h,
      join_zipWith (splitOnP_ne_nil _ _) (append_ne_nil_of_ne_nil_right _ [[]] (cons_ne_nil [] [])), cons_inj]
    exact ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
⊢ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p []) (map (fun x => [x]) (filter p []) ++ [[]])) = []
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
⊢ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p []) (map (fun x => [x]) (filter p []) ++ [[]])) = []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
⊢ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p (a :: as')) (map (fun x => [x]) (filter p (a :: as')) ++ [[]])) =
    a :: as'
[PROOFSTEP]

| cons a as' ih =>
  rw [splitOnP_cons, filter]
  by_cases h : p a
  · rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj]
    exact ih
  · rw [if_neg h, eq_false_of_ne_true h,
      join_zipWith (splitOnP_ne_nil _ _) (append_ne_nil_of_ne_nil_right _ [[]] (cons_ne_nil [] [])), cons_inj]
    exact ih
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
⊢ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p (a :: as')) (map (fun x => [x]) (filter p (a :: as')) ++ [[]])) =
    a :: as'
[PROOFSTEP]
rw [splitOnP_cons, filter]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
⊢ join
      (zipWith (fun x x_1 => x ++ x_1)
        (if p a = true then [] :: splitOnP p as' else modifyHead (cons a) (splitOnP p as'))
        (map (fun x => [x])
            (match p a with
            | true => a :: filter p as'
            | false => filter p as') ++
          [[]])) =
    a :: as'
[PROOFSTEP]
by_cases h : p a
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
h : p a = true
⊢ join
      (zipWith (fun x x_1 => x ++ x_1)
        (if p a = true then [] :: splitOnP p as' else modifyHead (cons a) (splitOnP p as'))
        (map (fun x => [x])
            (match p a with
            | true => a :: filter p as'
            | false => filter p as') ++
          [[]])) =
    a :: as'
[PROOFSTEP]
rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
h : p a = true
⊢ [] ++ join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
[PROOFSTEP]
exact ih
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
h : ¬p a = true
⊢ join
      (zipWith (fun x x_1 => x ++ x_1)
        (if p a = true then [] :: splitOnP p as' else modifyHead (cons a) (splitOnP p as'))
        (map (fun x => [x])
            (match p a with
            | true => a :: filter p as'
            | false => filter p as') ++
          [[]])) =
    a :: as'
[PROOFSTEP]
rw [if_neg h, eq_false_of_ne_true h,
  join_zipWith (splitOnP_ne_nil _ _) (append_ne_nil_of_ne_nil_right _ [[]] (cons_ne_nil [] [])), cons_inj]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
a : α
as' : List α
ih : join (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as') (map (fun x => [x]) (filter p as') ++ [[]])) = as'
h : ¬p a = true
⊢ join
      (zipWith (fun x x_1 => x ++ x_1) (splitOnP p as')
        (map (fun x => [x])
            (match false with
            | true => a :: filter p as'
            | false => filter p as') ++
          [[]])) =
    as'
[PROOFSTEP]
exact ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ xs → ¬p x = true
⊢ splitOnP p xs = [xs]
[PROOFSTEP]
induction xs with
| nil => rfl
| cons hd tl ih =>
  simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
  rw [ih <| forall_mem_of_forall_mem_cons h]
  rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ xs → ¬p x = true
⊢ splitOnP p xs = [xs]
[PROOFSTEP]
induction xs with
| nil => rfl
| cons hd tl ih =>
  simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
  rw [ih <| forall_mem_of_forall_mem_cons h]
  rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p [] = [[]]
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p [] = [[]]
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl) = [hd :: tl]
[PROOFSTEP]

| cons hd tl ih =>
  simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
  rw [ih <| forall_mem_of_forall_mem_cons h]
  rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl) = [hd :: tl]
[PROOFSTEP]
simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ modifyHead (cons hd) (splitOnP p tl) = [hd :: tl]
[PROOFSTEP]
rw [ih <| forall_mem_of_forall_mem_cons h]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ modifyHead (cons hd) [tl] = [hd :: tl]
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ xs → ¬p x = true
sep : α
hsep : p sep = true
as : List α
⊢ splitOnP p (xs ++ sep :: as) = xs :: splitOnP p as
[PROOFSTEP]
induction xs with
| nil => simp [hsep]
| cons hd tl ih => simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ xs → ¬p x = true
sep : α
hsep : p sep = true
as : List α
⊢ splitOnP p (xs ++ sep :: as) = xs :: splitOnP p as
[PROOFSTEP]
induction xs with
| nil => simp [hsep]
| cons hd tl ih => simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p ([] ++ sep :: as) = [] :: splitOnP p as
[PROOFSTEP]

| nil => simp [hsep]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p ([] ++ sep :: as) = [] :: splitOnP p as
[PROOFSTEP]
simp [hsep]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p (tl ++ sep :: as) = tl :: splitOnP p as
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl ++ sep :: as) = (hd :: tl) :: splitOnP p as
[PROOFSTEP]

| cons hd tl ih => simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p (tl ++ sep :: as) = tl :: splitOnP p as
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl ++ sep :: as) = (hd :: tl) :: splitOnP p as
[PROOFSTEP]
simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
⊢ intercalate [x] (splitOn x xs) = xs
[PROOFSTEP]
simp only [intercalate, splitOn]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) xs)) = xs
[PROOFSTEP]
induction' xs with hd tl ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) [])) = []
[PROOFSTEP]
simp [join]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl : List α
ih : join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) tl)) = tl
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl
[PROOFSTEP]
cases' h' : splitOnP (· == x) tl with hd' tl'
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl : List α
ih : join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) tl)) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = []
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl
[PROOFSTEP]
exact (splitOnP_ne_nil _ tl h').elim
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl : List α
ih : join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) tl)) = tl
hd' : List α
tl' : List (List α)
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl
[PROOFSTEP]
rw [h'] at ih 
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl
[PROOFSTEP]
rw [splitOnP_cons]
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
⊢ join
      (intersperse [x]
        (if (hd == x) = true then [] :: splitOnP (fun x_1 => x_1 == x) tl
        else modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) =
    hd :: tl
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
h : (hd == x) = true
⊢ join (intersperse [x] ([] :: splitOnP (fun x_1 => x_1 == x) tl)) = hd :: tl
[PROOFSTEP]
rw [beq_iff_eq] at h 
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
h : hd = x
⊢ join (intersperse [x] ([] :: splitOnP (fun x_1 => x_1 == x) tl)) = hd :: tl
[PROOFSTEP]
subst h
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [hd] (hd' :: tl')) = tl
h' : splitOnP (fun x => x == hd) tl = hd' :: tl'
⊢ join (intersperse [hd] ([] :: splitOnP (fun x => x == hd) tl)) = hd :: tl
[PROOFSTEP]
simp [ih, join, h']
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
h : ¬(hd == x) = true
⊢ join (intersperse [x] (modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) = hd :: tl
[PROOFSTEP]
cases tl'
[GOAL]
case neg.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
h : ¬(hd == x) = true
ih : join (intersperse [x] [hd']) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = [hd']
⊢ join (intersperse [x] (modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) = hd :: tl
[PROOFSTEP]
simpa [join, h'] using ih
[GOAL]
case neg.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
h : ¬(hd == x) = true
head✝ : List α
tail✝ : List (List α)
ih : join (intersperse [x] (hd' :: head✝ :: tail✝)) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: head✝ :: tail✝
⊢ join (intersperse [x] (modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) = hd :: tl
[PROOFSTEP]
simpa [join, h'] using ih
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls : ls ≠ []
⊢ splitOn x (intercalate [x] ls) = ls
[PROOFSTEP]
simp only [intercalate]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls : ls ≠ []
⊢ splitOn x (join (intersperse [x] ls)) = ls
[PROOFSTEP]
induction' ls with hd tl ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hx : ∀ (l : List α), l ∈ [] → ¬x ∈ l
hls : [] ≠ []
⊢ splitOn x (join (intersperse [x] [])) = []
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
tl : List (List α)
ih : (∀ (l : List α), l ∈ tl → ¬x ∈ l) → tl ≠ [] → splitOn x (join (intersperse [x] tl)) = tl
hx : ∀ (l : List α), l ∈ hd :: tl → ¬x ∈ l
hls : hd :: tl ≠ []
⊢ splitOn x (join (intersperse [x] (hd :: tl))) = hd :: tl
[PROOFSTEP]
cases tl
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
⊢ splitOn x (join (intersperse [x] [hd])) = [hd]
[PROOFSTEP]
suffices hd.splitOn x = [hd] by simpa [join]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
this : splitOn x hd = [hd]
⊢ splitOn x (join (intersperse [x] [hd])) = [hd]
[PROOFSTEP]
simpa [join]
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
⊢ splitOn x hd = [hd]
[PROOFSTEP]
refine' splitOnP_eq_single _ _ _
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(x_1 == x) = true
[PROOFSTEP]
intro y hy H
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
y : α
hy : y ∈ hd
H : (y == x) = true
⊢ False
[PROOFSTEP]
rw [eq_of_beq H] at hy 
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
y : α
hy : x ∈ hd
H : (y == x) = true
⊢ False
[PROOFSTEP]
refine' hx hd _ hy
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
y : α
hy : x ∈ hd
H : (y == x) = true
⊢ hd ∈ [hd]
[PROOFSTEP]
simp
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ splitOn x (join (intersperse [x] (hd :: head✝ :: tail✝))) = hd :: head✝ :: tail✝
[PROOFSTEP]
simp only [intersperse_cons_cons, singleton_append, join]
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝
[PROOFSTEP]
specialize ih _ _
[GOAL]
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ ∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l
[PROOFSTEP]
intro l hl
[GOAL]
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
l : List α
hl : l ∈ head✝ :: tail✝
⊢ ¬x ∈ l
[PROOFSTEP]
apply hx l
[GOAL]
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
l : List α
hl : l ∈ head✝ :: tail✝
⊢ l ∈ hd :: head✝ :: tail✝
[PROOFSTEP]
simp at hl ⊢
[GOAL]
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
l : List α
hl : l = head✝ ∨ l ∈ tail✝
⊢ l = hd ∨ l = head✝ ∨ l ∈ tail✝
[PROOFSTEP]
exact Or.inr hl
[GOAL]
case cons.cons.specialize_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ head✝ :: tail✝ ≠ []
[PROOFSTEP]
exact List.noConfusion
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝
[PROOFSTEP]
have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
this : ∀ (as : List α), splitOnP (fun x_1 => x_1 == x) (hd ++ x :: as) = hd :: splitOnP (fun x_1 => x_1 == x) as
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(fun x_2 => x_2 == x) x_1 = true
[PROOFSTEP]
case h =>
  intro y hy H
  rw [eq_of_beq H] at hy 
  exact hx hd (.head _) hy
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(fun x_2 => x_2 == x) x_1 = true
[PROOFSTEP]
case h =>
  intro y hy H
  rw [eq_of_beq H] at hy 
  exact hx hd (.head _) hy
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(fun x_2 => x_2 == x) x_1 = true
[PROOFSTEP]
intro y hy H
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
y : α
hy : y ∈ hd
H : (fun x_1 => x_1 == x) y = true
⊢ False
[PROOFSTEP]
rw [eq_of_beq H] at hy 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
y : α
hy : x ∈ hd
H : (fun x_1 => x_1 == x) y = true
⊢ False
[PROOFSTEP]
exact hx hd (.head _) hy
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
this : ∀ (as : List α), splitOnP (fun x_1 => x_1 == x) (hd ++ x :: as) = hd :: splitOnP (fun x_1 => x_1 == x) as
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝
[PROOFSTEP]
simp only [splitOn] at ih ⊢
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hx✝ : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls✝ : ls ≠ []
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOnP (fun x_1 => x_1 == x) (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
this : ∀ (as : List α), splitOnP (fun x_1 => x_1 == x) (hd ++ x :: as) = hd :: splitOnP (fun x_1 => x_1 == x) as
⊢ splitOnP (fun x_1 => x_1 == x) (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝
[PROOFSTEP]
rw [this, ih]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
tl : List α
r : Array α
⊢ go f (tl ++ [a]) r = Array.toListAppend r (go f (tl ++ [a]) #[])
[PROOFSTEP]
cases tl with
| nil => simp only [nil_append, modifyLast.go]; rfl
| cons hd tl =>
  simp only [cons_append]
  rw [modifyLast.go, modifyLast.go]
  case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
  rw [modifyLast.go_append_one _ _ tl _, modifyLast.go_append_one _ _ tl (Array.push #[] hd)]
  simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, append_assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
tl : List α
r : Array α
⊢ go f (tl ++ [a]) r = Array.toListAppend r (go f (tl ++ [a]) #[])
[PROOFSTEP]
cases tl with
| nil => simp only [nil_append, modifyLast.go]; rfl
| cons hd tl =>
  simp only [cons_append]
  rw [modifyLast.go, modifyLast.go]
  case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
  rw [modifyLast.go_append_one _ _ tl _, modifyLast.go_append_one _ _ tl (Array.push #[] hd)]
  simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, append_assoc]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
⊢ go f ([] ++ [a]) r = Array.toListAppend r (go f ([] ++ [a]) #[])
[PROOFSTEP]

| nil => simp only [nil_append, modifyLast.go]; rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
⊢ go f ([] ++ [a]) r = Array.toListAppend r (go f ([] ++ [a]) #[])
[PROOFSTEP]
simp only [nil_append, modifyLast.go]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
⊢ Array.toListAppend r [f a] = Array.toListAppend r (Array.toListAppend #[] [f a])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ go f (hd :: tl ++ [a]) r = Array.toListAppend r (go f (hd :: tl ++ [a]) #[])
[PROOFSTEP]

| cons hd tl =>
  simp only [cons_append]
  rw [modifyLast.go, modifyLast.go]
  case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
  rw [modifyLast.go_append_one _ _ tl _, modifyLast.go_append_one _ _ tl (Array.push #[] hd)]
  simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, append_assoc]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ go f (hd :: tl ++ [a]) r = Array.toListAppend r (go f (hd :: tl ++ [a]) #[])
[PROOFSTEP]
simp only [cons_append]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ go f (hd :: (tl ++ [a])) r = Array.toListAppend r (go f (hd :: (tl ++ [a])) #[])
[PROOFSTEP]
rw [modifyLast.go, modifyLast.go]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ go f (tl ++ [a]) (Array.push r hd) = Array.toListAppend r (go f (tl ++ [a]) (Array.push #[] hd))
case cons.x_3
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ tl ++ [a] = [] → False
case cons.x_3
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
case x_3 | x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ go f (tl ++ [a]) (Array.push r hd) = Array.toListAppend r (go f (tl ++ [a]) (Array.push #[] hd))
[PROOFSTEP]
rw [modifyLast.go_append_one _ _ tl _, modifyLast.go_append_one _ _ tl (Array.push #[] hd)]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
r : Array α
hd : α
tl : List α
⊢ Array.toListAppend (Array.push r hd) (go f (tl ++ [a]) #[]) =
    Array.toListAppend r (Array.toListAppend (Array.push #[] hd) (go f (tl ++ [a]) #[]))
[PROOFSTEP]
simp only [Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, append_assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
l : List α
⊢ modifyLast f (l ++ [a]) = l ++ [f a]
[PROOFSTEP]
cases l with
| nil => simp only [nil_append, modifyLast, modifyLast.go, Array.toListAppend_eq, Array.data_toArray]
| cons _ tl =>
  simp only [cons_append, modifyLast]
  rw [modifyLast.go]
  case x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
  rw [modifyLast.go_append_one, Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, cons_append,
    nil_append, cons_inj]
  exact modifyLast_append_one _ _ tl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
l : List α
⊢ modifyLast f (l ++ [a]) = l ++ [f a]
[PROOFSTEP]
cases l with
| nil => simp only [nil_append, modifyLast, modifyLast.go, Array.toListAppend_eq, Array.data_toArray]
| cons _ tl =>
  simp only [cons_append, modifyLast]
  rw [modifyLast.go]
  case x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
  rw [modifyLast.go_append_one, Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, cons_append,
    nil_append, cons_inj]
  exact modifyLast_append_one _ _ tl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
⊢ modifyLast f ([] ++ [a]) = [] ++ [f a]
[PROOFSTEP]

| nil => simp only [nil_append, modifyLast, modifyLast.go, Array.toListAppend_eq, Array.data_toArray]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a : α
⊢ modifyLast f ([] ++ [a]) = [] ++ [f a]
[PROOFSTEP]
simp only [nil_append, modifyLast, modifyLast.go, Array.toListAppend_eq, Array.data_toArray]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ modifyLast f (head✝ :: tl ++ [a]) = head✝ :: tl ++ [f a]
[PROOFSTEP]

| cons _ tl =>
  simp only [cons_append, modifyLast]
  rw [modifyLast.go]
  case x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
  rw [modifyLast.go_append_one, Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, cons_append,
    nil_append, cons_inj]
  exact modifyLast_append_one _ _ tl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ modifyLast f (head✝ :: tl ++ [a]) = head✝ :: tl ++ [f a]
[PROOFSTEP]
simp only [cons_append, modifyLast]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ modifyLast.go f (head✝ :: (tl ++ [a])) #[] = head✝ :: (tl ++ [f a])
[PROOFSTEP]
rw [modifyLast.go]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ modifyLast.go f (tl ++ [a]) (Array.push #[] head✝) = head✝ :: (tl ++ [f a])
case cons.x_3
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
case x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
case x_3 => exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ tl ++ [a] = [] → False
[PROOFSTEP]
exact append_ne_nil_of_ne_nil_right tl [a] (cons_ne_nil a [])
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ modifyLast.go f (tl ++ [a]) (Array.push #[] head✝) = head✝ :: (tl ++ [f a])
[PROOFSTEP]
rw [modifyLast.go_append_one, Array.toListAppend_eq, Array.push_data, Array.data_toArray, nil_append, cons_append,
  nil_append, cons_inj]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → α
a head✝ : α
tl : List α
⊢ modifyLast.go f (tl ++ [a]) #[] = tl ++ [f a]
[PROOFSTEP]
exact modifyLast_append_one _ _ tl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
f : α → α
l₁ l₂ : List α
x✝ : l₂ ≠ []
⊢ modifyLast f (l₁ ++ l₂) = l₁ ++ modifyLast f l₂
[PROOFSTEP]
cases l₂ with
| nil => contradiction
| cons hd tl =>
  cases tl with
  | nil => exact modifyLast_append_one _ hd _
  |
    cons hd' tl' =>
    rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
      modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
    all_goals {exact cons_ne_nil _ _
    }
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
f : α → α
l₁ l₂ : List α
x✝ : l₂ ≠ []
⊢ modifyLast f (l₁ ++ l₂) = l₁ ++ modifyLast f l₂
[PROOFSTEP]
cases l₂ with
| nil => contradiction
| cons hd tl =>
  cases tl with
  | nil => exact modifyLast_append_one _ hd _
  |
    cons hd' tl' =>
    rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
      modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
    all_goals {exact cons_ne_nil _ _
    }
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
x✝ : [] ≠ []
⊢ modifyLast f (l₁ ++ []) = l₁ ++ modifyLast f []
[PROOFSTEP]

| nil => contradiction
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
x✝ : [] ≠ []
⊢ modifyLast f (l₁ ++ []) = l₁ ++ modifyLast f []
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd : α
tl : List α
x✝ : hd :: tl ≠ []
⊢ modifyLast f (l₁ ++ hd :: tl) = l₁ ++ modifyLast f (hd :: tl)
[PROOFSTEP]

| cons hd tl =>
  cases tl with
  | nil => exact modifyLast_append_one _ hd _
  |
    cons hd' tl' =>
    rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
      modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
    all_goals {exact cons_ne_nil _ _
    }
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd : α
tl : List α
x✝ : hd :: tl ≠ []
⊢ modifyLast f (l₁ ++ hd :: tl) = l₁ ++ modifyLast f (hd :: tl)
[PROOFSTEP]
cases tl with
| nil => exact modifyLast_append_one _ hd _
|
  cons hd' tl' =>
  rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
    modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
  all_goals {exact cons_ne_nil _ _
  }
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd : α
tl : List α
x✝ : hd :: tl ≠ []
⊢ modifyLast f (l₁ ++ hd :: tl) = l₁ ++ modifyLast f (hd :: tl)
[PROOFSTEP]
cases tl with
| nil => exact modifyLast_append_one _ hd _
|
  cons hd' tl' =>
  rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
    modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
  all_goals {exact cons_ne_nil _ _
  }
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd : α
x✝ : [hd] ≠ []
⊢ modifyLast f (l₁ ++ [hd]) = l₁ ++ modifyLast f [hd]
[PROOFSTEP]

| nil => exact modifyLast_append_one _ hd _
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd : α
x✝ : [hd] ≠ []
⊢ modifyLast f (l₁ ++ [hd]) = l₁ ++ modifyLast f [hd]
[PROOFSTEP]
exact modifyLast_append_one _ hd _
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ modifyLast f (l₁ ++ hd :: hd' :: tl') = l₁ ++ modifyLast f (hd :: hd' :: tl')
[PROOFSTEP]

|
  cons hd' tl' =>
  rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
    modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
  all_goals {exact cons_ne_nil _ _
  }
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ modifyLast f (l₁ ++ hd :: hd' :: tl') = l₁ ++ modifyLast f (hd :: hd' :: tl')
[PROOFSTEP]
rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append,
  modifyLast_append _ (l₁ ++ [hd]) (hd' :: tl') _, modifyLast_append _ [hd] (hd' :: tl') _, append_assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ hd' :: tl' ≠ []
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ hd' :: tl' ≠ []
[PROOFSTEP]
all_goals {exact cons_ne_nil _ _
}
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ hd' :: tl' ≠ []
[PROOFSTEP]
{exact cons_ne_nil _ _
}
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ hd' :: tl' ≠ []
[PROOFSTEP]
exact cons_ne_nil _ _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ hd' :: tl' ≠ []
[PROOFSTEP]
{exact cons_ne_nil _ _
}
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
f : α → α
l₁ : List α
hd hd' : α
tl' : List α
x✝ : hd :: hd' :: tl' ≠ []
⊢ hd' :: tl' ≠ []
[PROOFSTEP]
exact cons_ne_nil _ _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
⊢ sizeOf x < sizeOf l
[PROOFSTEP]
induction' l with h t ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx✝ : x ∈ l
hx : x ∈ []
⊢ sizeOf x < sizeOf []
[PROOFSTEP]
cases hx
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx✝ : x ∈ l
h : α
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
hx : x ∈ h :: t
⊢ sizeOf x < sizeOf (h :: t)
[PROOFSTEP]
cases hx
[GOAL]
case cons.head
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
⊢ sizeOf x < sizeOf (x :: t)
[PROOFSTEP]
rw [cons.sizeOf_spec]
[GOAL]
case cons.tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
h : α
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
a✝ : Mem x t
⊢ sizeOf x < sizeOf (h :: t)
[PROOFSTEP]
rw [cons.sizeOf_spec]
[GOAL]
case cons.head
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
⊢ sizeOf x < 1 + sizeOf x + sizeOf t
[PROOFSTEP]
exact lt_add_of_lt_of_nonneg (lt_one_add _) (Nat.zero_le _)
[GOAL]
case cons.tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
h : α
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
a✝ : Mem x t
⊢ sizeOf x < 1 + sizeOf h + sizeOf t
[PROOFSTEP]
refine lt_add_of_pos_of_le ?_ (le_of_lt (ih ‹_›))
[GOAL]
case cons.tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
h : α
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
a✝ : Mem x t
⊢ 0 < 1 + sizeOf h
[PROOFSTEP]
rw [add_comm]
[GOAL]
case cons.tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
l : List α
hx : x ∈ l
h : α
t : List α
ih : x ∈ t → sizeOf x < sizeOf t
a✝ : Mem x t
⊢ 0 < sizeOf h + 1
[PROOFSTEP]
exact succ_pos _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : α → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ pmap (fun a x => f a) l H = map f l
[PROOFSTEP]
induction l <;> [rfl; simp only [*, pmap, map]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : α → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ pmap (fun a x => f a) l H = map f l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : α → β
H : ∀ (a : α), a ∈ [] → p a
⊢ pmap (fun a x => f a) [] H = map f []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : α → β
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (H : ∀ (a : α), a ∈ tail✝ → p a), pmap (fun a x => f a) tail✝ H = map f tail✝
H : ∀ (a : α), a ∈ head✝ :: tail✝ → p a
⊢ pmap (fun a x => f a) (head✝ :: tail✝) H = map f (head✝ :: tail✝)
[PROOFSTEP]
simp only [*, pmap, map]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
f : (a : α) → p a → β
g : (a : α) → q a → β
l : List α
H₁ : ∀ (a : α), a ∈ l → p a
H₂ : ∀ (a : α), a ∈ l → q a
h : ∀ (a : α), a ∈ l → ∀ (h₁ : p a) (h₂ : q a), f a h₁ = g a h₂
⊢ pmap f l H₁ = pmap g l H₂
[PROOFSTEP]
induction' l with _ _ ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
f : (a : α) → p a → β
g : (a : α) → q a → β
l : List α
H₁✝ : ∀ (a : α), a ∈ l → p a
H₂✝ : ∀ (a : α), a ∈ l → q a
h✝ : ∀ (a : α), a ∈ l → ∀ (h₁ : p a) (h₂ : q a), f a h₁ = g a h₂
H₁ : ∀ (a : α), a ∈ [] → p a
H₂ : ∀ (a : α), a ∈ [] → q a
h : ∀ (a : α), a ∈ [] → ∀ (h₁ : p a) (h₂ : q a), f a h₁ = g a h₂
⊢ pmap f [] H₁ = pmap g [] H₂
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
f : (a : α) → p a → β
g : (a : α) → q a → β
l : List α
H₁✝ : ∀ (a : α), a ∈ l → p a
H₂✝ : ∀ (a : α), a ∈ l → q a
h✝ : ∀ (a : α), a ∈ l → ∀ (h₁ : p a) (h₂ : q a), f a h₁ = g a h₂
head✝ : α
tail✝ : List α
ih :
  ∀ {H₁ : ∀ (a : α), a ∈ tail✝ → p a} {H₂ : ∀ (a : α), a ∈ tail✝ → q a},
    (∀ (a : α), a ∈ tail✝ → ∀ (h₁ : p a) (h₂ : q a), f a h₁ = g a h₂) → pmap f tail✝ H₁ = pmap g tail✝ H₂
H₁ : ∀ (a : α), a ∈ head✝ :: tail✝ → p a
H₂ : ∀ (a : α), a ∈ head✝ :: tail✝ → q a
h : ∀ (a : α), a ∈ head✝ :: tail✝ → ∀ (h₁ : p a) (h₂ : q a), f a h₁ = g a h₂
⊢ pmap f (head✝ :: tail✝) H₁ = pmap g (head✝ :: tail✝) H₂
[PROOFSTEP]
rw [pmap, pmap, h _ (mem_cons_self _ _), ih fun a ha => h a (mem_cons_of_mem _ ha)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
g : β → γ
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ map g (pmap f l H) = pmap (fun a h => g (f a h)) l H
[PROOFSTEP]
induction l <;> [rfl; simp only [*, pmap, map]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
g : β → γ
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ map g (pmap f l H) = pmap (fun a h => g (f a h)) l H
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
g : β → γ
f : (a : α) → p a → β
H : ∀ (a : α), a ∈ [] → p a
⊢ map g (pmap f [] H) = pmap (fun a h => g (f a h)) [] H
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
g : β → γ
f : (a : α) → p a → β
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (H : ∀ (a : α), a ∈ tail✝ → p a), map g (pmap f tail✝ H) = pmap (fun a h => g (f a h)) tail✝ H
H : ∀ (a : α), a ∈ head✝ :: tail✝ → p a
⊢ map g (pmap f (head✝ :: tail✝) H) = pmap (fun a h => g (f a h)) (head✝ :: tail✝) H
[PROOFSTEP]
simp only [*, pmap, map]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : β → Prop
g : (b : β) → p b → γ
f : α → β
l : List α
H : ∀ (a : β), a ∈ map f l → p a
⊢ pmap g (map f l) H = pmap (fun a h => g (f a) h) l (_ : ∀ (a : α), a ∈ l → p (f a))
[PROOFSTEP]
induction l <;> [rfl; simp only [*, pmap, map]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : β → Prop
g : (b : β) → p b → γ
f : α → β
l : List α
H : ∀ (a : β), a ∈ map f l → p a
⊢ pmap g (map f l) H = pmap (fun a h => g (f a) h) l (_ : ∀ (a : α), a ∈ l → p (f a))
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : β → Prop
g : (b : β) → p b → γ
f : α → β
H : ∀ (a : β), a ∈ map f [] → p a
⊢ pmap g (map f []) H = pmap (fun a h => g (f a) h) [] (_ : ∀ (a : α), a ∈ [] → p (f a))
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : β → Prop
g : (b : β) → p b → γ
f : α → β
head✝ : α
tail✝ : List α
tail_ih✝ :
  ∀ (H : ∀ (a : β), a ∈ map f tail✝ → p a),
    pmap g (map f tail✝) H = pmap (fun a h => g (f a) h) tail✝ (_ : ∀ (a : α), a ∈ tail✝ → p (f a))
H : ∀ (a : β), a ∈ map f (head✝ :: tail✝) → p a
⊢ pmap g (map f (head✝ :: tail✝)) H =
    pmap (fun a h => g (f a) h) (head✝ :: tail✝) (_ : ∀ (a : α), a ∈ head✝ :: tail✝ → p (f a))
[PROOFSTEP]
simp only [*, pmap, map]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ pmap f l H = map (fun x => f ↑x (_ : p ↑x)) (attach l)
[PROOFSTEP]
rw [attach, map_pmap]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ pmap f l H =
    pmap (fun a h => f ↑{ val := a, property := h } (_ : p ↑{ val := a, property := h })) l
      (_ : ∀ (x : α), x ∈ l → x ∈ l)
[PROOFSTEP]
exact pmap_congr l fun _ _ _ _ => rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
f : α → β
⊢ map (fun i => f ↑i) (attach l) = map f l
[PROOFSTEP]
rw [attach, map_pmap]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
f : α → β
⊢ pmap (fun a h => f ↑{ val := a, property := h }) l (_ : ∀ (x : α), x ∈ l → x ∈ l) = map f l
[PROOFSTEP]
exact pmap_eq_map _ _ _ _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
h : a ∈ l
⊢ { val := a, property := h } ∈ attach l
[PROOFSTEP]
have := mem_map.1 (by rw [attach_map_val] <;> exact h)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
h : a ∈ l
⊢ ?m.323925 ∈ map ?m.323926 ?m.323927
[PROOFSTEP]
rw [attach_map_val]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
h : a ∈ l
⊢ ?m.323925 ∈ ?m.323939
[PROOFSTEP]
exact h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
a : α
h : a ∈ l
this : ∃ a_1, a_1 ∈ attach l ∧ ↑a_1 = a
⊢ { val := a, property := h } ∈ attach l
[PROOFSTEP]
rcases this with ⟨⟨_, _⟩, m, rfl⟩
[GOAL]
case intro.mk.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
val✝ : α
property✝ : val✝ ∈ l
m : { val := val✝, property := property✝ } ∈ attach l
h : ↑{ val := val✝, property := property✝ } ∈ l
⊢ { val := ↑{ val := val✝, property := property✝ }, property := h } ∈ attach l
[PROOFSTEP]
exact m
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
b : β
⊢ b ∈ pmap f l H ↔ ∃ a h, f a (_ : p a) = b
[PROOFSTEP]
simp only [pmap_eq_map_attach, mem_map, mem_attach, true_and_iff, Subtype.exists, eq_comm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ length (pmap f l H) = length l
[PROOFSTEP]
induction l <;> [rfl; simp only [*, pmap, length]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ length (pmap f l H) = length l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
H : ∀ (a : α), a ∈ [] → p a
⊢ length (pmap f [] H) = length []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {H : ∀ (a : α), a ∈ tail✝ → p a}, length (pmap f tail✝ H) = length tail✝
H : ∀ (a : α), a ∈ head✝ :: tail✝ → p a
⊢ length (pmap f (head✝ :: tail✝) H) = length (head✝ :: tail✝)
[PROOFSTEP]
simp only [*, pmap, length]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
H : ∀ (a : α), a ∈ l → p a
⊢ pmap f l H = [] ↔ l = []
[PROOFSTEP]
rw [← length_eq_zero, length_pmap, length_eq_zero]
[GOAL]
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁ : ∀ (a : α), a ∈ l → p a
hl₂ : l ≠ []
⊢ getLast (pmap f l hl₁) (_ : ¬pmap f l hl₁ = []) = f (getLast l hl₂) (_ : p (getLast l hl₂))
[PROOFSTEP]
induction' l with l_hd l_tl l_ih
[GOAL]
case nil
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁✝ : ∀ (a : α), a ∈ l → p a
hl₂✝ : l ≠ []
hl₁ : ∀ (a : α), a ∈ [] → p a
hl₂ : [] ≠ []
⊢ getLast (pmap f [] hl₁) (_ : ¬pmap f [] hl₁ = []) = f (getLast [] hl₂) (_ : p (getLast [] hl₂))
[PROOFSTEP]
apply (hl₂ rfl).elim
[GOAL]
case cons
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁✝ : ∀ (a : α), a ∈ l → p a
hl₂✝ : l ≠ []
l_hd : α
l_tl : List α
l_ih :
  ∀ (hl₁ : ∀ (a : α), a ∈ l_tl → p a) (hl₂ : l_tl ≠ []),
    getLast (pmap f l_tl hl₁) (_ : ¬pmap f l_tl hl₁ = []) = f (getLast l_tl hl₂) (_ : p (getLast l_tl hl₂))
hl₁ : ∀ (a : α), a ∈ l_hd :: l_tl → p a
hl₂ : l_hd :: l_tl ≠ []
⊢ getLast (pmap f (l_hd :: l_tl) hl₁) (_ : ¬pmap f (l_hd :: l_tl) hl₁ = []) =
    f (getLast (l_hd :: l_tl) hl₂) (_ : p (getLast (l_hd :: l_tl) hl₂))
[PROOFSTEP]
by_cases hl_tl : l_tl = []
[GOAL]
case pos
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁✝ : ∀ (a : α), a ∈ l → p a
hl₂✝ : l ≠ []
l_hd : α
l_tl : List α
l_ih :
  ∀ (hl₁ : ∀ (a : α), a ∈ l_tl → p a) (hl₂ : l_tl ≠ []),
    getLast (pmap f l_tl hl₁) (_ : ¬pmap f l_tl hl₁ = []) = f (getLast l_tl hl₂) (_ : p (getLast l_tl hl₂))
hl₁ : ∀ (a : α), a ∈ l_hd :: l_tl → p a
hl₂ : l_hd :: l_tl ≠ []
hl_tl : l_tl = []
⊢ getLast (pmap f (l_hd :: l_tl) hl₁) (_ : ¬pmap f (l_hd :: l_tl) hl₁ = []) =
    f (getLast (l_hd :: l_tl) hl₂) (_ : p (getLast (l_hd :: l_tl) hl₂))
[PROOFSTEP]
simp [hl_tl]
[GOAL]
case neg
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁✝ : ∀ (a : α), a ∈ l → p a
hl₂✝ : l ≠ []
l_hd : α
l_tl : List α
l_ih :
  ∀ (hl₁ : ∀ (a : α), a ∈ l_tl → p a) (hl₂ : l_tl ≠ []),
    getLast (pmap f l_tl hl₁) (_ : ¬pmap f l_tl hl₁ = []) = f (getLast l_tl hl₂) (_ : p (getLast l_tl hl₂))
hl₁ : ∀ (a : α), a ∈ l_hd :: l_tl → p a
hl₂ : l_hd :: l_tl ≠ []
hl_tl : ¬l_tl = []
⊢ getLast (pmap f (l_hd :: l_tl) hl₁) (_ : ¬pmap f (l_hd :: l_tl) hl₁ = []) =
    f (getLast (l_hd :: l_tl) hl₂) (_ : p (getLast (l_hd :: l_tl) hl₂))
[PROOFSTEP]
simp only [pmap]
[GOAL]
case neg
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁✝ : ∀ (a : α), a ∈ l → p a
hl₂✝ : l ≠ []
l_hd : α
l_tl : List α
l_ih :
  ∀ (hl₁ : ∀ (a : α), a ∈ l_tl → p a) (hl₂ : l_tl ≠ []),
    getLast (pmap f l_tl hl₁) (_ : ¬pmap f l_tl hl₁ = []) = f (getLast l_tl hl₂) (_ : p (getLast l_tl hl₂))
hl₁ : ∀ (a : α), a ∈ l_hd :: l_tl → p a
hl₂ : l_hd :: l_tl ≠ []
hl_tl : ¬l_tl = []
⊢ getLast (f l_hd (_ : p l_hd) :: pmap f l_tl (_ : ∀ (x : α), x ∈ l_tl → p x))
      (_ : f l_hd (_ : p l_hd) :: pmap f l_tl (_ : ∀ (x : α), x ∈ l_tl → p x) ≠ []) =
    f (getLast (l_hd :: l_tl) hl₂) (_ : p (getLast (l_hd :: l_tl) hl₂))
[PROOFSTEP]
rw [getLast_cons, l_ih _ hl_tl]
[GOAL]
case neg
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
l : List α
hl₁✝ : ∀ (a : α), a ∈ l → p a
hl₂✝ : l ≠ []
l_hd : α
l_tl : List α
l_ih :
  ∀ (hl₁ : ∀ (a : α), a ∈ l_tl → p a) (hl₂ : l_tl ≠ []),
    getLast (pmap f l_tl hl₁) (_ : ¬pmap f l_tl hl₁ = []) = f (getLast l_tl hl₂) (_ : p (getLast l_tl hl₂))
hl₁ : ∀ (a : α), a ∈ l_hd :: l_tl → p a
hl₂ : l_hd :: l_tl ≠ []
hl_tl : ¬l_tl = []
⊢ f (getLast l_tl hl_tl) (_ : p (getLast l_tl hl_tl)) =
    f (getLast (l_hd :: l_tl) hl₂) (_ : p (getLast (l_hd :: l_tl) hl₂))
[PROOFSTEP]
simp only [getLast_cons hl_tl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h : ∀ (a : α), a ∈ l → p a
n : ℕ
⊢ get? (pmap f l h) n = Option.pmap f (get? l n) (_ : ∀ (x : α), x ∈ get? l n → p x)
[PROOFSTEP]
induction' l with hd tl hl generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n✝ : ℕ
h : ∀ (a : α), a ∈ [] → p a
n : ℕ
⊢ get? (pmap f [] h) n = Option.pmap f (get? [] n) (_ : ∀ (x : α), x ∈ get? [] n → p x)
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n✝ : ℕ
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) (n : ℕ),
    get? (pmap f tl h) n = Option.pmap f (get? tl n) (_ : ∀ (x : α), x ∈ get? tl n → p x)
h : ∀ (a : α), a ∈ hd :: tl → p a
n : ℕ
⊢ get? (pmap f (hd :: tl) h) n = Option.pmap f (get? (hd :: tl) n) (_ : ∀ (x : α), x ∈ get? (hd :: tl) n → p x)
[PROOFSTEP]
cases' n with n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n : ℕ
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) (n : ℕ),
    get? (pmap f tl h) n = Option.pmap f (get? tl n) (_ : ∀ (x : α), x ∈ get? tl n → p x)
h : ∀ (a : α), a ∈ hd :: tl → p a
⊢ get? (pmap f (hd :: tl) h) zero = Option.pmap f (get? (hd :: tl) zero) (_ : ∀ (x : α), x ∈ get? (hd :: tl) zero → p x)
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n✝ : ℕ
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) (n : ℕ),
    get? (pmap f tl h) n = Option.pmap f (get? tl n) (_ : ∀ (x : α), x ∈ get? tl n → p x)
h : ∀ (a : α), a ∈ hd :: tl → p a
n : ℕ
⊢ get? (pmap f (hd :: tl) h) (succ n) =
    Option.pmap f (get? (hd :: tl) (succ n)) (_ : ∀ (x : α), x ∈ get? (hd :: tl) (succ n) → p x)
[PROOFSTEP]
simp [hl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h : ∀ (a : α), a ∈ l → p a
n : ℕ
hn : n < length (pmap f l h)
⊢ get (pmap f l h) { val := n, isLt := hn } =
    f (get l { val := n, isLt := (_ : n < length l) }) (_ : p (get l { val := n, isLt := (_ : n < length l) }))
[PROOFSTEP]
induction' l with hd tl hl generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n✝ : ℕ
hn✝ : n✝ < length (pmap f l h✝)
h : ∀ (a : α), a ∈ [] → p a
n : ℕ
hn : n < length (pmap f [] h)
⊢ get (pmap f [] h) { val := n, isLt := hn } =
    f (get [] { val := n, isLt := (_ : n < length []) }) (_ : p (get [] { val := n, isLt := (_ : n < length []) }))
[PROOFSTEP]
simp only [length, pmap] at hn 
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n✝ : ℕ
hn✝ : n✝ < length (pmap f l h✝)
h : ∀ (a : α), a ∈ [] → p a
n : ℕ
hn : n < 0
⊢ get (pmap f [] h) { val := n, isLt := hn } =
    f (get [] { val := n, isLt := (_ : n < length []) }) (_ : p (get [] { val := n, isLt := (_ : n < length []) }))
[PROOFSTEP]
exact absurd hn (not_lt_of_le n.zero_le)
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n✝ : ℕ
hn✝ : n✝ < length (pmap f l h✝)
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) {n : ℕ} (hn : n < length (pmap f tl h)),
    get (pmap f tl h) { val := n, isLt := hn } =
      f (get tl { val := n, isLt := (_ : n < length tl) }) (_ : p (get tl { val := n, isLt := (_ : n < length tl) }))
h : ∀ (a : α), a ∈ hd :: tl → p a
n : ℕ
hn : n < length (pmap f (hd :: tl) h)
⊢ get (pmap f (hd :: tl) h) { val := n, isLt := hn } =
    f (get (hd :: tl) { val := n, isLt := (_ : n < length (hd :: tl)) })
      (_ : p (get (hd :: tl) { val := n, isLt := (_ : n < length (hd :: tl)) }))
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n : ℕ
hn✝ : n < length (pmap f l h✝)
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) {n : ℕ} (hn : n < length (pmap f tl h)),
    get (pmap f tl h) { val := n, isLt := hn } =
      f (get tl { val := n, isLt := (_ : n < length tl) }) (_ : p (get tl { val := n, isLt := (_ : n < length tl) }))
h : ∀ (a : α), a ∈ hd :: tl → p a
hn : zero < length (pmap f (hd :: tl) h)
⊢ get (pmap f (hd :: tl) h) { val := zero, isLt := hn } =
    f (get (hd :: tl) { val := zero, isLt := (_ : zero < length (hd :: tl)) })
      (_ : p (get (hd :: tl) { val := zero, isLt := (_ : zero < length (hd :: tl)) }))
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Prop
f : (a : α) → p a → β
l : List α
h✝ : ∀ (a : α), a ∈ l → p a
n : ℕ
hn✝ : n < length (pmap f l h✝)
hd : α
tl : List α
hl :
  ∀ (h : ∀ (a : α), a ∈ tl → p a) {n : ℕ} (hn : n < length (pmap f tl h)),
    get (pmap f tl h) { val := n, isLt := hn } =
      f (get tl { val := n, isLt := (_ : n < length tl) }) (_ : p (get tl { val := n, isLt := (_ : n < length tl) }))
h : ∀ (a : α), a ∈ hd :: tl → p a
n✝ : ℕ
hn : succ n✝ < length (pmap f (hd :: tl) h)
⊢ get (pmap f (hd :: tl) h) { val := succ n✝, isLt := hn } =
    f (get (hd :: tl) { val := succ n✝, isLt := (_ : succ n✝ < length (hd :: tl)) })
      (_ : p (get (hd :: tl) { val := succ n✝, isLt := (_ : succ n✝ < length (hd :: tl)) }))
[PROOFSTEP]
simp [hl]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₁ l₂ : List ι
h : ∀ (a : ι), a ∈ l₁ ++ l₂ → p a
⊢ pmap f (l₁ ++ l₂) h = pmap f l₁ (_ : ∀ (a : ι), a ∈ l₁ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
[PROOFSTEP]
induction' l₁ with _ _ ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₁ l₂ : List ι
h✝ : ∀ (a : ι), a ∈ l₁ ++ l₂ → p a
h : ∀ (a : ι), a ∈ [] ++ l₂ → p a
⊢ pmap f ([] ++ l₂) h = pmap f [] (_ : ∀ (a : ι), a ∈ [] → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₁ l₂ : List ι
h✝ : ∀ (a : ι), a ∈ l₁ ++ l₂ → p a
head✝ : ι
tail✝ : List ι
ih :
  ∀ (h : ∀ (a : ι), a ∈ tail✝ ++ l₂ → p a),
    pmap f (tail✝ ++ l₂) h = pmap f tail✝ (_ : ∀ (a : ι), a ∈ tail✝ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
h : ∀ (a : ι), a ∈ head✝ :: tail✝ ++ l₂ → p a
⊢ pmap f (head✝ :: tail✝ ++ l₂) h =
    pmap f (head✝ :: tail✝) (_ : ∀ (a : ι), a ∈ head✝ :: tail✝ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
[PROOFSTEP]
dsimp only [pmap, cons_append]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
p : ι → Prop
f : (a : ι) → p a → α
l₁ l₂ : List ι
h✝ : ∀ (a : ι), a ∈ l₁ ++ l₂ → p a
head✝ : ι
tail✝ : List ι
ih :
  ∀ (h : ∀ (a : ι), a ∈ tail✝ ++ l₂ → p a),
    pmap f (tail✝ ++ l₂) h = pmap f tail✝ (_ : ∀ (a : ι), a ∈ tail✝ → p a) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a)
h : ∀ (a : ι), a ∈ head✝ :: tail✝ ++ l₂ → p a
⊢ f head✝ (_ : p head✝) :: pmap f (tail✝ ++ l₂) (_ : ∀ (x : ι), x ∈ tail✝ ++ l₂ → p x) =
    f head✝ (_ : p head✝) :: (pmap f tail✝ (_ : ∀ (x : ι), x ∈ tail✝ → p x) ++ pmap f l₂ (_ : ∀ (a : ι), a ∈ l₂ → p a))
[PROOFSTEP]
rw [ih]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
a : α
H : find? p l = some a
⊢ a ∈ l
[PROOFSTEP]
induction' l with b l IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
a : α
H✝ : find? p l = some a
H : find? p [] = some a
⊢ a ∈ []
[PROOFSTEP]
contradiction
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
H✝ : find? p l✝ = some a
b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p (b :: l) = some a
⊢ a ∈ b :: l
[PROOFSTEP]
by_cases h : p b
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
H✝ : find? p l✝ = some a
b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p (b :: l) = some a
h : p b = true
⊢ a ∈ b :: l
[PROOFSTEP]
rw [find?_cons_of_pos _ h] at H 
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
H✝ : find? p l✝ = some a
b : α
l : List α
IH : find? p l = some a → a ∈ l
H : some b = some a
h : p b = true
⊢ a ∈ b :: l
[PROOFSTEP]
cases H
[GOAL]
case pos.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
H : find? p l✝ = some a
l : List α
IH : find? p l = some a → a ∈ l
h : p a = true
⊢ a ∈ a :: l
[PROOFSTEP]
apply mem_cons_self
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
H✝ : find? p l✝ = some a
b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p (b :: l) = some a
h : ¬p b = true
⊢ a ∈ b :: l
[PROOFSTEP]
rw [find?_cons_of_neg _ h] at H 
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l✝ : List α
a : α
H✝ : find? p l✝ = some a
b : α
l : List α
IH : find? p l = some a → a ∈ l
H : find? p l = some a
h : ¬p b = true
⊢ a ∈ b :: l
[PROOFSTEP]
exact mem_cons_of_mem _ (IH H)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
l : List α
acc : Array α
⊢ go f l acc = Array.toListAppend acc (lookmap f l)
[PROOFSTEP]
cases l with
| nil => rfl
| cons hd tl =>
  rw [lookmap, go, go]
  cases f hd with
  | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
  | some a => rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
l : List α
acc : Array α
⊢ go f l acc = Array.toListAppend acc (lookmap f l)
[PROOFSTEP]
cases l with
| nil => rfl
| cons hd tl =>
  rw [lookmap, go, go]
  cases f hd with
  | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
  | some a => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
⊢ go f [] acc = Array.toListAppend acc (lookmap f [])
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
⊢ go f [] acc = Array.toListAppend acc (lookmap f [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ go f (hd :: tl) acc = Array.toListAppend acc (lookmap f (hd :: tl))
[PROOFSTEP]

| cons hd tl =>
  rw [lookmap, go, go]
  cases f hd with
  | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
  | some a => rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ go f (hd :: tl) acc = Array.toListAppend acc (lookmap f (hd :: tl))
[PROOFSTEP]
rw [lookmap, go, go]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ (match f hd with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match f hd with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))
[PROOFSTEP]
cases f hd with
| none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
| some a => rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
x✝ : Option α
⊢ (match x✝ with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match x✝ with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))
[PROOFSTEP]
cases f hd with
| none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
| some a => rfl
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ (match none with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match none with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))
[PROOFSTEP]

| none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]; rfl
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ (match none with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match none with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))
[PROOFSTEP]
simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.push_data]
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
⊢ acc.data ++ ([hd] ++ lookmap f tl) = acc.data ++ (#[].data ++ ([hd] ++ lookmap f tl))
[PROOFSTEP]
rfl
[GOAL]
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
a : α
⊢ (match some a with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match some a with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))
[PROOFSTEP]

| some a => rfl
[GOAL]
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
acc : Array α
hd : α
tl : List α
a : α
⊢ (match some a with
    | some b => Array.toListAppend acc (b :: tl)
    | none => go f tl (Array.push acc hd)) =
    Array.toListAppend acc
      (match some a with
      | some b => Array.toListAppend #[] (b :: tl)
      | none => go f tl (Array.push #[] hd))
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
a : α
l : List α
h : f a = none
⊢ lookmap f (a :: l) = a :: lookmap f l
[PROOFSTEP]
simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
a : α
l : List α
h : f a = none
⊢ (match f a with
    | some b => b :: l
    | none => lookmap.go f l (Array.push #[] a)) =
    a :: lookmap.go f l #[]
[PROOFSTEP]
rw [lookmap.go_append, h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
a : α
l : List α
h : f a = none
⊢ (match none with
    | some b => b :: l
    | none => Array.toListAppend (Array.push #[] a) (lookmap f l)) =
    a :: lookmap.go f l #[]
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
a b : α
l : List α
h : f a = some b
⊢ lookmap f (a :: l) = b :: l
[PROOFSTEP]
simp only [lookmap, lookmap.go, Array.toListAppend_eq, Array.data_toArray, nil_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
a b : α
l : List α
h : f a = some b
⊢ (match f a with
    | some b => b :: l
    | none => lookmap.go f l (Array.push #[] a)) =
    b :: l
[PROOFSTEP]
rw [h]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
⊢ lookmap f (a :: l) = lookmap g (a :: l)
[PROOFSTEP]
cases' forall_mem_cons.1 H with H₁ H₂
[GOAL]
case intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
H₁ : f a = g a
H₂ : ∀ (x : α), x ∈ l → f x = g x
⊢ lookmap f (a :: l) = lookmap g (a :: l)
[PROOFSTEP]
cases' h : g a with b
[GOAL]
case intro.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
H₁ : f a = g a
H₂ : ∀ (x : α), x ∈ l → f x = g x
h : g a = none
⊢ lookmap f (a :: l) = lookmap g (a :: l)
[PROOFSTEP]
simp [h, H₁.trans h, lookmap_congr H₂]
[GOAL]
case intro.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f✝ f g : α → Option α
a : α
l : List α
H : ∀ (a_1 : α), a_1 ∈ a :: l → f a_1 = g a_1
H₁ : f a = g a
H₂ : ∀ (x : α), x ∈ l → f x = g x
b : α
h : g a = some b
⊢ lookmap f (a :: l) = lookmap g (a :: l)
[PROOFSTEP]
simp [lookmap_cons_some _ _ h, lookmap_cons_some _ _ (H₁.trans h)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
⊢ map g (lookmap f (a :: l)) = map g (a :: l)
[PROOFSTEP]
cases' h' : f a with b
[GOAL]
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
h' : f a = none
⊢ map g (lookmap f (a :: l)) = map g (a :: l)
[PROOFSTEP]
simp [h']
[GOAL]
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
h' : f a = none
⊢ map g (lookmap f l) = map g l
[PROOFSTEP]
exact lookmap_map_eq _ h l
[GOAL]
case some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
g : α → β
h : ∀ (a b : α), b ∈ f a → g a = g b
a : α
l : List α
b : α
h' : f a = some b
⊢ map g (lookmap f (a :: l)) = map g (a :: l)
[PROOFSTEP]
simp [lookmap_cons_some _ _ h', h _ _ h']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
h : ∀ (a b : α), b ∈ f a → a = b
l : List α
⊢ lookmap f l = l
[PROOFSTEP]
rw [← map_id (l.lookmap f), lookmap_map_eq, map_id]
[GOAL]
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
h : ∀ (a b : α), b ∈ f a → a = b
l : List α
⊢ ∀ (a b : α), b ∈ f a → id a = id b
[PROOFSTEP]
exact h
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
l : List α
⊢ length (lookmap f l) = length l
[PROOFSTEP]
rw [← length_map, lookmap_map_eq _ fun _ => (), length_map]
[GOAL]
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option α
l : List α
⊢ ∀ (a b : α), b ∈ f a → () = ()
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
l : List (Option α)
⊢ reduceOption (some x :: l) = x :: reduceOption l
[PROOFSTEP]
simp only [reduceOption, filterMap, id.def, eq_self_iff_true, and_self_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
⊢ reduceOption (none :: l) = reduceOption l
[PROOFSTEP]
simp only [reduceOption, filterMap, id.def]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
f : α → β
⊢ reduceOption (map (Option.map f) l) = map f (reduceOption l)
[PROOFSTEP]
induction' l with hd tl hl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
⊢ reduceOption (map (Option.map f) []) = map f (reduceOption [])
[PROOFSTEP]
simp only [reduceOption_nil, map_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
hd : Option α
tl : List (Option α)
hl : reduceOption (map (Option.map f) tl) = map f (reduceOption tl)
⊢ reduceOption (map (Option.map f) (hd :: tl)) = map f (reduceOption (hd :: tl))
[PROOFSTEP]
cases hd
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
tl : List (Option α)
hl : reduceOption (map (Option.map f) tl) = map f (reduceOption tl)
⊢ reduceOption (map (Option.map f) (none :: tl)) = map f (reduceOption (none :: tl))
[PROOFSTEP]
simpa [true_and_iff, Option.map_some', map, eq_self_iff_true, reduceOption_cons_of_some] using hl
[GOAL]
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → β
tl : List (Option α)
hl : reduceOption (map (Option.map f) tl) = map f (reduceOption tl)
val✝ : α
⊢ reduceOption (map (Option.map f) (some val✝ :: tl)) = map f (reduceOption (some val✝ :: tl))
[PROOFSTEP]
simpa [true_and_iff, Option.map_some', map, eq_self_iff_true, reduceOption_cons_of_some] using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
⊢ length (reduceOption l) ≤ length l
[PROOFSTEP]
induction' l with hd tl hl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ length (reduceOption []) ≤ length []
[PROOFSTEP]
simp only [reduceOption_nil, length]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hd : Option α
tl : List (Option α)
hl : length (reduceOption tl) ≤ length tl
⊢ length (reduceOption (hd :: tl)) ≤ length (hd :: tl)
[PROOFSTEP]
cases hd
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) ≤ length tl
⊢ length (reduceOption (none :: tl)) ≤ length (none :: tl)
[PROOFSTEP]
exact Nat.le_succ_of_le hl
[GOAL]
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) ≤ length tl
val✝ : α
⊢ length (reduceOption (some val✝ :: tl)) ≤ length (some val✝ :: tl)
[PROOFSTEP]
simpa only [length, add_le_add_iff_right, reduceOption_cons_of_some] using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
⊢ length (reduceOption l) = length l ↔ ∀ (x : Option α), x ∈ l → Option.isSome x = true
[PROOFSTEP]
induction' l with hd tl hl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ length (reduceOption []) = length [] ↔ ∀ (x : Option α), x ∈ [] → Option.isSome x = true
[PROOFSTEP]
simp only [forall_const, reduceOption_nil, not_mem_nil, forall_prop_of_false, eq_self_iff_true, length, not_false_iff]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
hd : Option α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
⊢ length (reduceOption (hd :: tl)) = length (hd :: tl) ↔ ∀ (x : Option α), x ∈ hd :: tl → Option.isSome x = true
[PROOFSTEP]
cases hd
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
⊢ length (reduceOption (none :: tl)) = length (none :: tl) ↔ ∀ (x : Option α), x ∈ none :: tl → Option.isSome x = true
[PROOFSTEP]
simp only [mem_cons, forall_eq_or_imp, Bool.coe_sort_false, false_and_iff, reduceOption_cons_of_none, length,
  Option.isSome_none, iff_false_iff]
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
⊢ ¬length (reduceOption tl) = length tl + 1
[PROOFSTEP]
intro H
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
H : length (reduceOption tl) = length tl + 1
⊢ False
[PROOFSTEP]
have := reduceOption_length_le tl
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
H : length (reduceOption tl) = length tl + 1
this : length (reduceOption tl) ≤ length tl
⊢ False
[PROOFSTEP]
rw [H] at this 
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
H : length (reduceOption tl) = length tl + 1
this : length tl + 1 ≤ length tl
⊢ False
[PROOFSTEP]
exact absurd (Nat.lt_succ_self _) (not_lt_of_le this)
[GOAL]
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
tl : List (Option α)
hl : length (reduceOption tl) = length tl ↔ ∀ (x : Option α), x ∈ tl → Option.isSome x = true
val✝ : α
⊢ length (reduceOption (some val✝ :: tl)) = length (some val✝ :: tl) ↔
    ∀ (x : Option α), x ∈ some val✝ :: tl → Option.isSome x = true
[PROOFSTEP]
simp only [length, add_left_inj, find?, mem_cons, forall_eq_or_imp, Option.isSome_some, ← hl, reduceOption, true_and]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
⊢ length (reduceOption l) < length l ↔ none ∈ l
[PROOFSTEP]
rw [(reduceOption_length_le l).lt_iff_ne, Ne, reduceOption_length_eq_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
⊢ (¬∀ (x : Option α), x ∈ l → Option.isSome x = true) ↔ none ∈ l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ (¬∀ (x : Option α), x ∈ [] → Option.isSome x = true) ↔ none ∈ []
[PROOFSTEP]
simp [*]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : Option α
tail✝ : List (Option α)
tail_ih✝ : (¬∀ (x : Option α), x ∈ tail✝ → Option.isSome x = true) ↔ none ∈ tail✝
⊢ (¬∀ (x : Option α), x ∈ head✝ :: tail✝ → Option.isSome x = true) ↔ none ∈ head✝ :: tail✝
[PROOFSTEP]
simp [*]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : Option α
tail✝ : List (Option α)
tail_ih✝ : (¬∀ (x : Option α), x ∈ tail✝ → Option.isSome x = true) ↔ none ∈ tail✝
⊢ (Option.isSome head✝ = true → ∃ x, x ∈ tail✝ ∧ Option.isNone x = true) ↔ none = head✝ ∨ none ∈ tail✝
[PROOFSTEP]
rw [@eq_comm _ none, ← Option.not_isSome_iff_eq_none, Decidable.imp_iff_not_or]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
head✝ : Option α
tail✝ : List (Option α)
tail_ih✝ : (¬∀ (x : Option α), x ∈ tail✝ → Option.isSome x = true) ↔ none ∈ tail✝
⊢ (¬Option.isSome head✝ = true ∨ ∃ x, x ∈ tail✝ ∧ Option.isNone x = true) ↔ ¬Option.isSome head✝ = true ∨ none ∈ tail✝
[PROOFSTEP]
simp [Option.isNone_iff_eq_none]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : Option α
⊢ reduceOption [x] = Option.toList x
[PROOFSTEP]
cases x
[GOAL]
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ reduceOption [none] = Option.toList none
[PROOFSTEP]
rfl
[GOAL]
case some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
val✝ : α
⊢ reduceOption [some val✝] = Option.toList (some val✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
x : Option α
⊢ reduceOption (concat l x) = reduceOption l ++ Option.toList x
[PROOFSTEP]
induction' l with hd tl hl generalizing x
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ x : Option α
⊢ reduceOption (concat [] x) = reduceOption [] ++ Option.toList x
[PROOFSTEP]
cases x
[GOAL]
case nil.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : Option α
⊢ reduceOption (concat [] none) = reduceOption [] ++ Option.toList none
[PROOFSTEP]
simp [Option.toList]
[GOAL]
case nil.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : Option α
val✝ : α
⊢ reduceOption (concat [] (some val✝)) = reduceOption [] ++ Option.toList (some val✝)
[PROOFSTEP]
simp [Option.toList]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ hd : Option α
tl : List (Option α)
hl : ∀ (x : Option α), reduceOption (concat tl x) = reduceOption tl ++ Option.toList x
x : Option α
⊢ reduceOption (concat (hd :: tl) x) = reduceOption (hd :: tl) ++ Option.toList x
[PROOFSTEP]
simp only [concat_eq_append, reduceOption_append] at hl 
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ hd : Option α
tl : List (Option α)
x : Option α
hl : ∀ (x : Option α), reduceOption tl ++ reduceOption [x] = reduceOption tl ++ Option.toList x
⊢ reduceOption (concat (hd :: tl) x) = reduceOption (hd :: tl) ++ Option.toList x
[PROOFSTEP]
cases hd
[GOAL]
case cons.none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ : Option α
tl : List (Option α)
x : Option α
hl : ∀ (x : Option α), reduceOption tl ++ reduceOption [x] = reduceOption tl ++ Option.toList x
⊢ reduceOption (concat (none :: tl) x) = reduceOption (none :: tl) ++ Option.toList x
[PROOFSTEP]
simp [hl, reduceOption_append]
[GOAL]
case cons.some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ : Option α
tl : List (Option α)
x : Option α
hl : ∀ (x : Option α), reduceOption tl ++ reduceOption [x] = reduceOption tl ++ Option.toList x
val✝ : α
⊢ reduceOption (concat (some val✝ :: tl) x) = reduceOption (some val✝ :: tl) ++ Option.toList x
[PROOFSTEP]
simp [hl, reduceOption_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
x : α
⊢ reduceOption (concat l (some x)) = concat (reduceOption l) x
[PROOFSTEP]
simp only [reduceOption_nil, concat_eq_append, reduceOption_append, reduceOption_cons_of_some]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
x : α
⊢ x ∈ reduceOption l ↔ some x ∈ l
[PROOFSTEP]
simp only [reduceOption, id.def, mem_filterMap, exists_eq_right]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
l : List (Option α)
x : α
⊢ (∃ i, get? l i = some (some x)) ↔ ∃ i, get? (reduceOption l) i = some x
[PROOFSTEP]
rw [← mem_iff_get?, ← mem_iff_get?, reduceOption_mem_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
l : List α
⊢ filter p l = foldr (fun a out => bif p a then a :: out else out) [] l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
⊢ filter p [] = foldr (fun a out => bif p a then a :: out else out) [] []
[PROOFSTEP]
simp [*, filter]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
head✝ : α
tail✝ : List α
tail_ih✝ : filter p tail✝ = foldr (fun a out => bif p a then a :: out else out) [] tail✝
⊢ filter p (head✝ :: tail✝) = foldr (fun a out => bif p a then a :: out else out) [] (head✝ :: tail✝)
[PROOFSTEP]
simp [*, filter]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
head✝ : α
tail✝ : List α
tail_ih✝ : filter p tail✝ = foldr (fun a out => bif p a then a :: out else out) [] tail✝
⊢ (match p head✝ with
    | true => head✝ :: foldr (fun a out => bif p a then a :: out else out) [] tail✝
    | false => foldr (fun a out => bif p a then a :: out else out) [] tail✝) =
    bif p head✝ then head✝ :: foldr (fun a out => bif p a then a :: out else out) [] tail✝
    else foldr (fun a out => bif p a then a :: out else out) [] tail✝
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a b : α
l : List α
ain : a ∈ filter p (b :: l)
pb : p b = true
⊢ a ∈ b :: filter p l
[PROOFSTEP]
simpa only [filter_cons_of_pos _ pb] using ain
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a b : α
l : List α
ain : a ∈ filter p (b :: l)
pb : p b = true
this : a ∈ b :: filter p l
h : a = b
⊢ p a = true
[PROOFSTEP]
rw [← h] at pb 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a b : α
l : List α
ain : a ∈ filter p (b :: l)
pb : p a = true
this : a ∈ b :: filter p l
h : a = b
⊢ p a = true
[PROOFSTEP]
exact pb
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a b : α
l : List α
ain : a ∈ filter p (b :: l)
pb : ¬p b = true
⊢ p a = true
[PROOFSTEP]
simp only [filter_cons_of_neg _ pb] at ain 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a b : α
l : List α
pb : ¬p b = true
ain : a ∈ filter p l
⊢ p a = true
[PROOFSTEP]
exact of_mem_filter ain
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a x : α
l : List α
h : a ∈ x :: l
h1 : p a = true
⊢ a ∈ filter p (x :: l)
[PROOFSTEP]
rcases mem_cons.1 h with rfl | h
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a : α
l : List α
h1 : p a = true
h : a ∈ a :: l
⊢ a ∈ filter p (a :: l)
[PROOFSTEP]
simp [filter, h1]
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a x : α
l : List α
h✝ : a ∈ x :: l
h1 : p a = true
h : a ∈ l
⊢ a ∈ filter p (x :: l)
[PROOFSTEP]
rw [filter]
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a x : α
l : List α
h✝ : a ∈ x :: l
h1 : p a = true
h : a ∈ l
⊢ a ∈
    match p x with
    | true => x :: filter p l
    | false => filter p l
[PROOFSTEP]
cases p x
[GOAL]
case inr.false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a x : α
l : List α
h✝ : a ∈ x :: l
h1 : p a = true
h : a ∈ l
⊢ a ∈
    match false with
    | true => x :: filter p l
    | false => filter p l
[PROOFSTEP]
simp [mem_filter_of_mem h h1]
[GOAL]
case inr.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
a x : α
l : List α
h✝ : a ∈ x :: l
h1 : p a = true
h : a ∈ l
⊢ a ∈
    match true with
    | true => x :: filter p l
    | false => filter p l
[PROOFSTEP]
simp [mem_filter_of_mem h h1]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
l l' : List α
h : l ⊆ l'
⊢ filter p l ⊆ filter p l'
[PROOFSTEP]
intro x hx
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
l l' : List α
h : l ⊆ l'
x : α
hx : x ∈ filter p l
⊢ x ∈ filter p l'
[PROOFSTEP]
rw [mem_filter] at hx ⊢
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p : α → Bool
l l' : List α
h : l ⊆ l'
x : α
hx : x ∈ l ∧ p x = true
⊢ x ∈ l' ∧ p x = true
[PROOFSTEP]
exact ⟨h hx.left, hx.right⟩
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
⊢ filter p l <+ filter q l
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
⊢ filter p [] <+ filter q []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
⊢ filter p (hd :: tl) <+ filter q (hd :: tl)
[PROOFSTEP]
by_cases hp : p hd
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : p hd = true
⊢ filter p (hd :: tl) <+ filter q (hd :: tl)
[PROOFSTEP]
rw [filter_cons_of_pos _ hp, filter_cons_of_pos _ (h _ hp)]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : p hd = true
⊢ hd :: filter p tl <+ hd :: filter q tl
[PROOFSTEP]
exact IH.cons_cons hd
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : ¬p hd = true
⊢ filter p (hd :: tl) <+ filter q (hd :: tl)
[PROOFSTEP]
rw [filter_cons_of_neg _ hp]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : ¬p hd = true
⊢ filter p tl <+ filter q (hd :: tl)
[PROOFSTEP]
by_cases hq : q hd
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : ¬p hd = true
hq : q hd = true
⊢ filter p tl <+ filter q (hd :: tl)
[PROOFSTEP]
rw [filter_cons_of_pos _ hq]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : ¬p hd = true
hq : q hd = true
⊢ filter p tl <+ hd :: filter q tl
[PROOFSTEP]
exact sublist_cons_of_sublist hd IH
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : ¬p hd = true
hq : ¬q hd = true
⊢ filter p tl <+ filter q (hd :: tl)
[PROOFSTEP]
rw [filter_cons_of_neg _ hq]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ p q : α → Bool
h : ∀ (a : α), p a = true → q a = true
hd : α
tl : List α
IH : filter p tl <+ filter q tl
hp : ¬p hd = true
hq : ¬q hd = true
⊢ filter p tl <+ filter q tl
[PROOFSTEP]
exact IH
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ filter (fun x => true) l = l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
⊢ filter (fun x => true) [] = []
[PROOFSTEP]
simp [*, filter]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
head✝ : α
tail✝ : List α
tail_ih✝ : filter (fun x => true) tail✝ = tail✝
⊢ filter (fun x => true) (head✝ :: tail✝) = head✝ :: tail✝
[PROOFSTEP]
simp [*, filter]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ filter (fun x => false) l = []
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
⊢ filter (fun x => false) [] = []
[PROOFSTEP]
simp [*, filter]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
head✝ : α
tail✝ : List α
tail_ih✝ : filter (fun x => false) tail✝ = []
⊢ filter (fun x => false) (head✝ :: tail✝) = []
[PROOFSTEP]
simp [*, filter]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ : List α
p : α → Bool
l₂ : List α
⊢ loop p [] l₂ = (reverse l₂ ++ takeWhile p [], dropWhile p [])
[PROOFSTEP]
simp [span.loop, takeWhile, dropWhile]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ : List α
p : α → Bool
a : α
l l₂ : List α
⊢ loop p (a :: l) l₂ = (reverse l₂ ++ takeWhile p (a :: l), dropWhile p (a :: l))
[PROOFSTEP]
cases hp : p a
[GOAL]
case false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ : List α
p : α → Bool
a : α
l l₂ : List α
hp : p a = false
⊢ loop p (a :: l) l₂ = (reverse l₂ ++ takeWhile p (a :: l), dropWhile p (a :: l))
[PROOFSTEP]
simp [hp, span.loop, span.loop_eq_take_drop, takeWhile, dropWhile]
[GOAL]
case true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂✝ : List α
p : α → Bool
a : α
l l₂ : List α
hp : p a = true
⊢ loop p (a :: l) l₂ = (reverse l₂ ++ takeWhile p (a :: l), dropWhile p (a :: l))
[PROOFSTEP]
simp [hp, span.loop, span.loop_eq_take_drop, takeWhile, dropWhile]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ span p l = (takeWhile p l, dropWhile p l)
[PROOFSTEP]
simpa using span.loop_eq_take_drop p l []
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
hl : 0 < length (dropWhile p l)
⊢ ¬p (nthLe (dropWhile p l) 0 hl) = true
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
hl✝ : 0 < length (dropWhile p l)
hl : 0 < length (dropWhile p [])
⊢ ¬p (nthLe (dropWhile p []) 0 hl) = true
[PROOFSTEP]
cases hl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
hl✝ : 0 < length (dropWhile p l)
hd : α
tl : List α
IH : ∀ (hl : 0 < length (dropWhile p tl)), ¬p (nthLe (dropWhile p tl) 0 hl) = true
hl : 0 < length (dropWhile p (hd :: tl))
⊢ ¬p (nthLe (dropWhile p (hd :: tl)) 0 hl) = true
[PROOFSTEP]
simp only [dropWhile]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
hl✝ : 0 < length (dropWhile p l)
hd : α
tl : List α
IH : ∀ (hl : 0 < length (dropWhile p tl)), ¬p (nthLe (dropWhile p tl) 0 hl) = true
hl : 0 < length (dropWhile p (hd :: tl))
⊢ ¬p
        (nthLe
          (match p hd with
          | true => dropWhile p tl
          | false => hd :: tl)
          0
          (_ :
            0 <
              length
                (match p hd with
                | true => dropWhile p tl
                | false => hd :: tl))) =
      true
[PROOFSTEP]
by_cases hp : p hd
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
hl✝ : 0 < length (dropWhile p l)
hd : α
tl : List α
IH : ∀ (hl : 0 < length (dropWhile p tl)), ¬p (nthLe (dropWhile p tl) 0 hl) = true
hl : 0 < length (dropWhile p (hd :: tl))
hp : p hd = true
⊢ ¬p
        (nthLe
          (match p hd with
          | true => dropWhile p tl
          | false => hd :: tl)
          0
          (_ :
            0 <
              length
                (match p hd with
                | true => dropWhile p tl
                | false => hd :: tl))) =
      true
[PROOFSTEP]
simp [hp, IH]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
hl✝ : 0 < length (dropWhile p l)
hd : α
tl : List α
IH : ∀ (hl : 0 < length (dropWhile p tl)), ¬p (nthLe (dropWhile p tl) 0 hl) = true
hl : 0 < length (dropWhile p (hd :: tl))
hp : ¬p hd = true
⊢ ¬p
        (nthLe
          (match p hd with
          | true => dropWhile p tl
          | false => hd :: tl)
          0
          (_ :
            0 <
              length
                (match p hd with
                | true => dropWhile p tl
                | false => hd :: tl))) =
      true
[PROOFSTEP]
simp [hp, nthLe_cons]
  -- porting note: How did the Lean 3 proof work,
  -- without mentioning nthLe_cons?
  -- Same question for takeWhile_eq_nil_iff below
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ dropWhile p l = [] ↔ ∀ (x : α), x ∈ l → p x = true
[PROOFSTEP]
induction' l with x xs IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ dropWhile p [] = [] ↔ ∀ (x : α), x ∈ [] → p x = true
[PROOFSTEP]
simp [dropWhile]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : dropWhile p xs = [] ↔ ∀ (x : α), x ∈ xs → p x = true
⊢ dropWhile p (x :: xs) = [] ↔ ∀ (x_1 : α), x_1 ∈ x :: xs → p x_1 = true
[PROOFSTEP]
by_cases hp : p x
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : dropWhile p xs = [] ↔ ∀ (x : α), x ∈ xs → p x = true
hp : p x = true
⊢ dropWhile p (x :: xs) = [] ↔ ∀ (x_1 : α), x_1 ∈ x :: xs → p x_1 = true
[PROOFSTEP]
simp [hp, dropWhile, IH]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : dropWhile p xs = [] ↔ ∀ (x : α), x ∈ xs → p x = true
hp : ¬p x = true
⊢ dropWhile p (x :: xs) = [] ↔ ∀ (x_1 : α), x_1 ∈ x :: xs → p x_1 = true
[PROOFSTEP]
simp [hp, dropWhile, IH]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p l = l ↔ ∀ (x : α), x ∈ l → p x = true
[PROOFSTEP]
induction' l with x xs IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p [] = [] ↔ ∀ (x : α), x ∈ [] → p x = true
[PROOFSTEP]
simp [takeWhile]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : takeWhile p xs = xs ↔ ∀ (x : α), x ∈ xs → p x = true
⊢ takeWhile p (x :: xs) = x :: xs ↔ ∀ (x_1 : α), x_1 ∈ x :: xs → p x_1 = true
[PROOFSTEP]
by_cases hp : p x
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : takeWhile p xs = xs ↔ ∀ (x : α), x ∈ xs → p x = true
hp : p x = true
⊢ takeWhile p (x :: xs) = x :: xs ↔ ∀ (x_1 : α), x_1 ∈ x :: xs → p x_1 = true
[PROOFSTEP]
simp [hp, takeWhile, IH]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : takeWhile p xs = xs ↔ ∀ (x : α), x ∈ xs → p x = true
hp : ¬p x = true
⊢ takeWhile p (x :: xs) = x :: xs ↔ ∀ (x_1 : α), x_1 ∈ x :: xs → p x_1 = true
[PROOFSTEP]
simp [hp, takeWhile, IH]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p l = [] ↔ ∀ (hl : 0 < length l), ¬p (nthLe l 0 hl) = true
[PROOFSTEP]
induction' l with x xs IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p [] = [] ↔ ∀ (hl : 0 < length []), ¬p (nthLe [] 0 hl) = true
[PROOFSTEP]
simp [takeWhile, true_iff]
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ ∀ (hl : 0 < length []), p (nthLe [] 0 hl) = false
[PROOFSTEP]
intro h
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
h : 0 < length []
⊢ p (nthLe [] 0 h) = false
[PROOFSTEP]
simp at h 
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : takeWhile p xs = [] ↔ ∀ (hl : 0 < length xs), ¬p (nthLe xs 0 hl) = true
⊢ takeWhile p (x :: xs) = [] ↔ ∀ (hl : 0 < length (x :: xs)), ¬p (nthLe (x :: xs) 0 hl) = true
[PROOFSTEP]
by_cases hp : p x
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : takeWhile p xs = [] ↔ ∀ (hl : 0 < length xs), ¬p (nthLe xs 0 hl) = true
hp : p x = true
⊢ takeWhile p (x :: xs) = [] ↔ ∀ (hl : 0 < length (x :: xs)), ¬p (nthLe (x :: xs) 0 hl) = true
[PROOFSTEP]
simp [hp, takeWhile, IH, nthLe_cons]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
xs : List α
IH : takeWhile p xs = [] ↔ ∀ (hl : 0 < length xs), ¬p (nthLe xs 0 hl) = true
hp : ¬p x = true
⊢ takeWhile p (x :: xs) = [] ↔ ∀ (hl : 0 < length (x :: xs)), ¬p (nthLe (x :: xs) 0 hl) = true
[PROOFSTEP]
simp [hp, takeWhile, IH, nthLe_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
hx : x ∈ takeWhile p l
⊢ p x = true
[PROOFSTEP]
induction l with simp [takeWhile] at hx 
| cons hd tl IH =>
  cases hp : p hd
  · simp [hp] at hx 
  · rw [hp, mem_cons] at hx 
    rcases hx with (rfl | hx)
    · exact hp
    · exact IH hx
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
hx : x ∈ takeWhile p l
⊢ p x = true
[PROOFSTEP]
induction l with simp [takeWhile] at hx 
| cons hd tl IH =>
  cases hp : p hd
  · simp [hp] at hx 
  · rw [hp, mem_cons] at hx 
    rcases hx with (rfl | hx)
    · exact hp
    · exact IH hx
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hx : x ∈ takeWhile p (hd :: tl)
⊢ p x = true
[PROOFSTEP]
simp [takeWhile] at hx 
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hx :
  x ∈
    match p hd with
    | true => hd :: takeWhile p tl
    | false => []
⊢ p x = true
[PROOFSTEP]

| cons hd tl IH =>
  cases hp : p hd
  · simp [hp] at hx 
  · rw [hp, mem_cons] at hx 
    rcases hx with (rfl | hx)
    · exact hp
    · exact IH hx
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hx :
  x ∈
    match p hd with
    | true => hd :: takeWhile p tl
    | false => []
⊢ p x = true
[PROOFSTEP]
cases hp : p hd
[GOAL]
case cons.false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hx :
  x ∈
    match p hd with
    | true => hd :: takeWhile p tl
    | false => []
hp : p hd = false
⊢ p x = true
[PROOFSTEP]
simp [hp] at hx 
[GOAL]
case cons.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hx :
  x ∈
    match p hd with
    | true => hd :: takeWhile p tl
    | false => []
hp : p hd = true
⊢ p x = true
[PROOFSTEP]
rw [hp, mem_cons] at hx 
[GOAL]
case cons.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hx : x = hd ∨ x ∈ takeWhile p tl
hp : p hd = true
⊢ p x = true
[PROOFSTEP]
rcases hx with (rfl | hx)
[GOAL]
case cons.true.inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hp : p x = true
⊢ p x = true
[PROOFSTEP]
exact hp
[GOAL]
case cons.true.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x hd : α
tl : List α
IH : x ∈ takeWhile p tl → p x = true
hp : p hd = true
hx : x ∈ takeWhile p tl
⊢ p x = true
[PROOFSTEP]
exact IH hx
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
hx : x ∈ takeWhile p []
⊢ p x = true
[PROOFSTEP]
simp [takeWhile] at hx 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l✝ : List α
p q : α → Bool
l : List α
⊢ takeWhile p (takeWhile q l) = takeWhile (fun a => decide (p a = true ∧ q a = true)) l
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
⊢ takeWhile p (takeWhile q []) = takeWhile (fun a => decide (p a = true ∧ q a = true)) []
[PROOFSTEP]
simp [takeWhile]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
by_cases hp : p hd
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
hp : p hd = true
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
by_cases hq : q hd
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
hp : ¬p hd = true
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
by_cases hq : q hd
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
hp : p hd = true
hq : q hd = true
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
simp [takeWhile, hp, hq, IH]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
hp : p hd = true
hq : ¬q hd = true
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
simp [takeWhile, hp, hq, IH]
[GOAL]
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
hp : ¬p hd = true
hq : q hd = true
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
simp [takeWhile, hp, hq, IH]
[GOAL]
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
hd : α
tl : List α
IH : takeWhile p (takeWhile q tl) = takeWhile (fun a => decide (p a = true ∧ q a = true)) tl
hp : ¬p hd = true
hq : ¬q hd = true
⊢ takeWhile p (takeWhile q (hd :: tl)) = takeWhile (fun a => decide (p a = true ∧ q a = true)) (hd :: tl)
[PROOFSTEP]
simp [takeWhile, hp, hq, IH]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p (takeWhile p l) = takeWhile p l
[PROOFSTEP]
simp_rw [takeWhile_takeWhile, and_self_iff, Bool.decide_coe]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p : α → Bool
l : List α
a : α
al : a ∈ l
pa : p a = true
⊢ length (eraseP p l) + 1 = length l
[PROOFSTEP]
let ⟨_, l₁, l₂, _, _, h₁, h₂⟩ := exists_of_eraseP al pa
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
p : α → Bool
l : List α
a : α
al : a ∈ l
pa : p a = true
w✝ : α
l₁ l₂ : List α
left✝¹ : ∀ (b : α), b ∈ l₁ → ¬p b = true
left✝ : p w✝ = true
h₁ : l = l₁ ++ w✝ :: l₂
h₂ : eraseP p l = l₁ ++ l₂
⊢ length (eraseP p l) + 1 = length l
[PROOFSTEP]
rw [h₂, h₁, length_append, length_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
p : α → Bool
l : List α
a : α
al : a ∈ l
pa : p a = true
w✝ : α
l₁ l₂ : List α
left✝¹ : ∀ (b : α), b ∈ l₁ → ¬p b = true
left✝ : p w✝ = true
h₁ : l = l₁ ++ w✝ :: l₂
h₂ : eraseP p l = l₁ ++ l₂
⊢ length l₁ + length l₂ + 1 = length l₁ + length (w✝ :: l₂)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
h : a ∈ l
⊢ length (List.erase l a) + 1 = length l
[PROOFSTEP]
rw [erase_eq_eraseP, length_eraseP_add_one h (decide_eq_true rfl)]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
⊢ map f (List.erase l a) = List.erase (map f l) (f a)
[PROOFSTEP]
have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
⊢ Eq a = Eq (f a) ∘ f
[PROOFSTEP]
ext b
[GOAL]
case h.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
b : α
⊢ a = b ↔ (Eq (f a) ∘ f) b
[PROOFSTEP]
simp [finj.eq_iff]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
this : Eq a = Eq (f a) ∘ f
⊢ map f (List.erase l a) = List.erase (map f l) (f a)
[PROOFSTEP]
simp [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
this : Eq a = Eq (f a) ∘ f
⊢ map f (eraseP (fun b => decide (f a = f b)) l) = map f (eraseP ((fun b => decide (f a = b)) ∘ f) l)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
l₁ l₂ : List α
⊢ map f (foldl List.erase l₁ l₂) = foldl (fun l a => List.erase l (f a)) (map f l₁) l₂
[PROOFSTEP]
induction l₂ generalizing l₁ <;> [rfl; simp only [foldl_cons, map_erase finj, *]]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
l₁ l₂ : List α
⊢ map f (foldl List.erase l₁ l₂) = foldl (fun l a => List.erase l (f a)) (map f l₁) l₂
[PROOFSTEP]
induction l₂ generalizing l₁
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
l₁ : List α
⊢ map f (foldl List.erase l₁ []) = foldl (fun l a => List.erase l (f a)) (map f l₁) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ {l₁ : List α}, map f (foldl List.erase l₁ tail✝) = foldl (fun l a => List.erase l (f a)) (map f l₁) tail✝
l₁ : List α
⊢ map f (foldl List.erase l₁ (head✝ :: tail✝)) = foldl (fun l a => List.erase l (f a)) (map f l₁) (head✝ :: tail✝)
[PROOFSTEP]
simp only [foldl_cons, map_erase finj, *]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
l₁ l₂ : List α
⊢ map f (List.diff l₁ l₂) = List.diff (map f l₁) (map f l₂)
[PROOFSTEP]
simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b :: l₁ <+ l₂
heq : b = a
⊢ List.diff (List.erase l₂ a) (List.erase (b :: l₁) a) <+ List.diff l₂ (b :: l₁)
[PROOFSTEP]
simp only [heq, erase_cons_head, diff_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b :: l₁ <+ l₂
heq : b = a
⊢ List.diff (List.erase l₂ a) l₁ <+ List.diff (List.erase l₂ a) l₁
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b :: l₁ <+ l₂
heq : ¬b = a
⊢ List.diff (List.erase l₂ a) (List.erase (b :: l₁) a) <+ List.diff l₂ (b :: l₁)
[PROOFSTEP]
simp only [erase_cons_head b l₁, erase_cons_tail l₁ heq, diff_cons ((List.erase l₂ a)) (List.erase l₁ a) b,
  diff_cons l₂ l₁ b, erase_comm a b l₂]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b :: l₁ <+ l₂
heq : ¬b = a
⊢ List.diff (List.erase (List.erase l₂ b) a) (List.erase l₁ a) <+ List.diff (List.erase l₂ b) l₁
[PROOFSTEP]
have h' := h.erase b
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b :: l₁ <+ l₂
heq : ¬b = a
h' : List.erase (b :: l₁) b <+ List.erase l₂ b
⊢ List.diff (List.erase (List.erase l₂ b) a) (List.erase l₁ a) <+ List.diff (List.erase l₂ b) l₁
[PROOFSTEP]
rw [erase_cons_head] at h' 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b :: l₁ <+ l₂
heq : ¬b = a
h' : l₁ <+ List.erase l₂ b
⊢ List.diff (List.erase (List.erase l₂ b) a) (List.erase l₁ a) <+ List.diff (List.erase l₂ b) l₁
[PROOFSTEP]
exact @erase_diff_erase_sublist_of_sublist _ l₁ (l₂.erase b) h'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
l : List α
m : ℕ
⊢ (fun a => (n + 1 + m, a)) <$> get? l m = (fun a => (n + (m + 1), a)) <$> get? (a :: l) (m + 1)
[PROOFSTEP]
rw [add_right_comm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
a : α
l : List α
m : ℕ
⊢ (fun a => (n + m + 1, a)) <$> get? l m = (fun a => (n + (m + 1), a)) <$> get? (a :: l) (m + 1)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ ∀ (l : List α) (n : ℕ), get? (enum l) n = (fun a => (n, a)) <$> get? l n
[PROOFSTEP]
simp only [enum, enumFrom_get?, zero_add]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
⊢ List α → ℕ → True
[PROOFSTEP]
intros
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
n✝ : ℕ
⊢ True
[PROOFSTEP]
trivial
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
⊢ (i, x) ∈ enumFrom j [] → j ≤ i ∧ i < j + length [] ∧ x ∈ []
[PROOFSTEP]
simp [enumFrom]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
⊢ (i, x) ∈ enumFrom j (y :: ys) → j ≤ i ∧ i < j + length (y :: ys) ∧ x ∈ y :: ys
[PROOFSTEP]
suffices i = j ∧ x = y ∨ (i, x) ∈ enumFrom (j + 1) ys → j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys) by
  simpa [enumFrom, mem_enumFrom ys]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
this : i = j ∧ x = y ∨ (i, x) ∈ enumFrom (j + 1) ys → j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
⊢ (i, x) ∈ enumFrom j (y :: ys) → j ≤ i ∧ i < j + length (y :: ys) ∧ x ∈ y :: ys
[PROOFSTEP]
simpa [enumFrom, mem_enumFrom ys]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
⊢ i = j ∧ x = y ∨ (i, x) ∈ enumFrom (j + 1) ys → j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
[PROOFSTEP]
rintro (h | h)
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : i = j ∧ x = y
⊢ j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
[PROOFSTEP]
refine' ⟨le_of_eq h.1.symm, h.1 ▸ _, Or.inl h.2⟩
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : i = j ∧ x = y
⊢ i < i + (length ys + 1)
[PROOFSTEP]
apply Nat.lt_add_of_pos_right
[GOAL]
case inl.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : i = j ∧ x = y
⊢ 0 < length ys + 1
[PROOFSTEP]
simp
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : (i, x) ∈ enumFrom (j + 1) ys
⊢ j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
[PROOFSTEP]
have ⟨hji, hijlen, hmem⟩ := mem_enumFrom _ h
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : (i, x) ∈ enumFrom (j + 1) ys
hji : j + 1 ≤ i
hijlen : i < j + 1 + length ys
hmem : x ∈ ys
⊢ j ≤ i ∧ i < j + (length ys + 1) ∧ (x = y ∨ x ∈ ys)
[PROOFSTEP]
refine' ⟨_, _, _⟩
[GOAL]
case inr.refine'_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : (i, x) ∈ enumFrom (j + 1) ys
hji : j + 1 ≤ i
hijlen : i < j + 1 + length ys
hmem : x ∈ ys
⊢ j ≤ i
[PROOFSTEP]
exact le_trans (Nat.le_succ _) hji
[GOAL]
case inr.refine'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : (i, x) ∈ enumFrom (j + 1) ys
hji : j + 1 ≤ i
hijlen : i < j + 1 + length ys
hmem : x ∈ ys
⊢ i < j + (length ys + 1)
[PROOFSTEP]
convert hijlen using 1
[GOAL]
case h.e'_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : (i, x) ∈ enumFrom (j + 1) ys
hji : j + 1 ≤ i
hijlen : i < j + 1 + length ys
hmem : x ∈ ys
⊢ j + (length ys + 1) = j + 1 + length ys
[PROOFSTEP]
ac_rfl
[GOAL]
case inr.refine'_3
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
i j : ℕ
y : α
ys : List α
h : (i, x) ∈ enumFrom (j + 1) ys
hji : j + 1 ≤ i
hijlen : i < j + 1 + length ys
hmem : x ∈ ys
⊢ x = y ∨ x ∈ ys
[PROOFSTEP]
simp [hmem]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ xs ys : List α
n : ℕ
⊢ enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + length xs) ys
[PROOFSTEP]
induction' xs with x xs IH generalizing ys n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ ys✝ : List α
n✝ : ℕ
ys : List α
n : ℕ
⊢ enumFrom n ([] ++ ys) = enumFrom n [] ++ enumFrom (n + length []) ys
[PROOFSTEP]
simp
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ ys✝ : List α
n✝ : ℕ
x : α
xs : List α
IH : ∀ (ys : List α) (n : ℕ), enumFrom n (xs ++ ys) = enumFrom n xs ++ enumFrom (n + length xs) ys
ys : List α
n : ℕ
⊢ enumFrom n (x :: xs ++ ys) = enumFrom n (x :: xs) ++ enumFrom (n + length (x :: xs)) ys
[PROOFSTEP]
rw [cons_append, enumFrom_cons, IH, ← cons_append, ← enumFrom_cons, length, add_right_comm, add_assoc]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ xs ys : List α
⊢ enum (xs ++ ys) = enum xs ++ enumFrom (length xs) ys
[PROOFSTEP]
simp [enum, enumFrom_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n k : ℕ
⊢ map (Prod.map (fun x => x + n) id) (enumFrom k l) = enumFrom (n + k) l
[PROOFSTEP]
induction' l with hd tl IH generalizing n k
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ k✝ n k : ℕ
⊢ map (Prod.map (fun x => x + n) id) (enumFrom k []) = enumFrom (n + k) []
[PROOFSTEP]
simp [enumFrom]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ k✝ : ℕ
hd : α
tl : List α
IH : ∀ (n k : ℕ), map (Prod.map (fun x => x + n) id) (enumFrom k tl) = enumFrom (n + k) tl
n k : ℕ
⊢ map (Prod.map (fun x => x + n) id) (enumFrom k (hd :: tl)) = enumFrom (n + k) (hd :: tl)
[PROOFSTEP]
simp only [enumFrom, map, zero_add, Prod.map_mk, id.def, eq_self_iff_true, true_and_iff]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n✝ k✝ : ℕ
hd : α
tl : List α
IH : ∀ (n k : ℕ), map (Prod.map (fun x => x + n) id) (enumFrom k tl) = enumFrom (n + k) tl
n k : ℕ
⊢ (k + n, hd) :: map (Prod.map (fun x => x + n) id) (enumFrom (k + 1) tl) = (n + k, hd) :: enumFrom (n + k + 1) tl
[PROOFSTEP]
simp [IH, add_comm n k, add_assoc, add_left_comm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
x : α
xs : List α
⊢ enumFrom n (x :: xs) = (n, x) :: map (Prod.map succ id) (enumFrom n xs)
[PROOFSTEP]
rw [enumFrom_cons, add_comm, ← map_fst_add_enumFrom_eq_enumFrom]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
l : List α
f : α → β
⊢ enumFrom n (map f l) = map (Prod.map id f) (enumFrom n l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
f : α → β
⊢ enumFrom n (map f []) = map (Prod.map id f) (enumFrom n [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
f : α → β
hd : α
tl : List α
IH : enumFrom n (map f tl) = map (Prod.map id f) (enumFrom n tl)
⊢ enumFrom n (map f (hd :: tl)) = map (Prod.map id f) (enumFrom n (hd :: tl))
[PROOFSTEP]
rw [map_cons, enumFrom_cons', enumFrom_cons', map_cons, map_map, IH, map_map]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
n : ℕ
f : α → β
hd : α
tl : List α
IH : enumFrom n (map f tl) = map (Prod.map id f) (enumFrom n tl)
⊢ (n, f hd) :: map (Prod.map succ id ∘ Prod.map id f) (enumFrom n tl) =
    Prod.map id f (n, hd) :: map (Prod.map id f ∘ Prod.map succ id) (enumFrom n tl)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
i : Fin (length (enumFrom n l))
⊢ ↑i < length l
[PROOFSTEP]
simpa [length_enumFrom] using i.2
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
i : Fin (length (enumFrom n l))
hi : optParam (↑i < length l) (_ : ↑i < length l)
⊢ get (enumFrom n l) i = (n + ↑i, get l { val := ↑i, isLt := hi })
[PROOFSTEP]
rw [← Option.some_inj, ← get?_eq_get]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n : ℕ
i : Fin (length (enumFrom n l))
hi : optParam (↑i < length l) (_ : ↑i < length l)
⊢ get? (enumFrom n l) ↑i = some (n + ↑i, get l { val := ↑i, isLt := hi })
[PROOFSTEP]
simp [enumFrom_get?, get?_eq_get hi]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
n i : ℕ
hi' : i < length (enumFrom n l)
⊢ i < length l
[PROOFSTEP]
simpa [length_enumFrom] using hi'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i : Fin (length (enum l))
⊢ ↑i < length l
[PROOFSTEP]
simpa [length_enum] using i.2
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i : Fin (length (enum l))
hi : optParam (↑i < length l) (_ : ↑i < length l)
⊢ get (enum l) i = (↑i, get l { val := ↑i, isLt := hi })
[PROOFSTEP]
convert get_enumFrom _ _ i
[GOAL]
case h.e'_3.h.e'_3
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i : Fin (length (enum l))
hi : optParam (↑i < length l) (_ : ↑i < length l)
⊢ ↑i = 0 + ↑i
[PROOFSTEP]
exact (zero_add _).symm
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
i : ℕ
hi' : i < length (enum l)
⊢ i < length l
[PROOFSTEP]
simpa [length_enum] using hi'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as : List α
⊢ map₂Left' f as [] = (map (fun a => f a none) as, [])
[PROOFSTEP]
cases as
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
⊢ map₂Left' f [] [] = (map (fun a => f a none) [], [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
head✝ : α
tail✝ : List α
⊢ map₂Left' f (head✝ :: tail✝) [] = (map (fun a => f a none) (head✝ :: tail✝), [])
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
bs : List β
⊢ map₂Right' f [] bs = (map (f none) bs, [])
[PROOFSTEP]
cases bs
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
⊢ map₂Right' f [] [] = (map (f none) [], [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b head✝ : β
tail✝ : List β
⊢ map₂Right' f [] (head✝ :: tail✝) = (map (f none) (head✝ :: tail✝), [])
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
⊢ zipLeft' as [] = (map (fun a => (a, none)) as, [])
[PROOFSTEP]
cases as
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
bs : List β
⊢ zipLeft' [] [] = (map (fun a => (a, none)) [], [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
bs : List β
head✝ : α
tail✝ : List α
⊢ zipLeft' (head✝ :: tail✝) [] = (map (fun a => (a, none)) (head✝ :: tail✝), [])
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
⊢ zipRight' [] bs = (map (fun b => (none, b)) bs, [])
[PROOFSTEP]
cases bs
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
⊢ zipRight' [] [] = (map (fun b => (none, b)) [], [])
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b head✝ : β
tail✝ : List β
⊢ zipRight' [] (head✝ :: tail✝) = (map (fun b => (none, b)) (head✝ :: tail✝), [])
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as : List α
⊢ map₂Left f as [] = map (fun a => f a none) as
[PROOFSTEP]
cases as
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
⊢ map₂Left f [] [] = map (fun a => f a none) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
head✝ : α
tail✝ : List α
⊢ map₂Left f (head✝ :: tail✝) [] = map (fun a => f a none) (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as : List α
x✝ : List β
⊢ map₂Left f [] x✝ = (map₂Left' f [] x✝).fst
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as✝ : List α
a : α
as : List α
⊢ map₂Left f (a :: as) [] = (map₂Left' f (a :: as) []).fst
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as✝ : List α
a : α
as : List α
b : β
bs : List β
⊢ map₂Left f (a :: as) (b :: bs) = (map₂Left' f (a :: as) (b :: bs)).fst
[PROOFSTEP]
simp [map₂Left_eq_map₂Left']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as : List α
x✝ : length [] ≤ length []
⊢ map₂Left f [] [] = zipWith (fun a b => f a (some b)) [] []
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as : List α
head✝ : β
tail✝ : List β
x✝ : length [] ≤ length (head✝ :: tail✝)
⊢ map₂Left f [] (head✝ :: tail✝) = zipWith (fun a b => f a (some b)) [] (head✝ :: tail✝)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as✝ : List α
a : α
as : List α
h : length (a :: as) ≤ length []
⊢ map₂Left f (a :: as) [] = zipWith (fun a b => f a (some b)) (a :: as) []
[PROOFSTEP]
simp at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as✝ : List α
a : α
as : List α
b : β
bs : List β
h : length (a :: as) ≤ length (b :: bs)
⊢ map₂Left f (a :: as) (b :: bs) = zipWith (fun a b => f a (some b)) (a :: as) (b :: bs)
[PROOFSTEP]
simp [Nat.succ_le_succ_iff] at h 
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : α → Option β → γ
as✝ : List α
a : α
as : List α
b : β
bs : List β
h : length as ≤ length bs
⊢ map₂Left f (a :: as) (b :: bs) = zipWith (fun a b => f a (some b)) (a :: as) (b :: bs)
[PROOFSTEP]
simp [h, map₂Left_eq_zipWith]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
bs : List β
⊢ map₂Right f [] bs = map (f none) bs
[PROOFSTEP]
cases bs
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
⊢ map₂Right f [] [] = map (f none) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b head✝ : β
tail✝ : List β
⊢ map₂Right f [] (head✝ :: tail✝) = map (f none) (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
bs : List β
⊢ map₂Right f as bs = (map₂Right' f as bs).fst
[PROOFSTEP]
simp only [map₂Right, map₂Right', map₂Left_eq_map₂Left']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
bs : List β
h : length bs ≤ length as
⊢ map₂Right f as bs = zipWith (fun a b => f (some a) b) as bs
[PROOFSTEP]
have : (fun a b => flip f a (some b)) = flip fun a b => f (some a) b := rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
f : Option α → β → γ
a : α
as : List α
b : β
bs : List β
h : length bs ≤ length as
this : (fun a b => flip f a (some b)) = flip fun a b => f (some a) b
⊢ map₂Right f as bs = zipWith (fun a b => f (some a) b) as bs
[PROOFSTEP]
simp only [map₂Right, map₂Left_eq_zipWith, zipWith_flip, *]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
⊢ zipLeft as [] = map (fun a => (a, none)) as
[PROOFSTEP]
cases as
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
bs : List β
⊢ zipLeft [] [] = map (fun a => (a, none)) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
bs : List β
head✝ : α
tail✝ : List α
⊢ zipLeft (head✝ :: tail✝) [] = map (fun a => (a, none)) (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as✝ : List α
b : β
bs✝ : List β
as : List α
bs : List β
⊢ zipLeft as bs = (zipLeft' as bs).fst
[PROOFSTEP]
rw [zipLeft, zipLeft']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as✝ : List α
b : β
bs✝ : List β
as : List α
bs : List β
⊢ zipWithLeft Prod.mk as bs = (zipWithLeft' Prod.mk as bs).fst
[PROOFSTEP]
cases as with
| nil => rfl
| cons _ atl =>
  cases bs with
  | nil => rfl
  | cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as✝ : List α
b : β
bs✝ : List β
as : List α
bs : List β
⊢ zipWithLeft Prod.mk as bs = (zipWithLeft' Prod.mk as bs).fst
[PROOFSTEP]
cases as with
| nil => rfl
| cons _ atl =>
  cases bs with
  | nil => rfl
  | cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs✝ bs : List β
⊢ zipWithLeft Prod.mk [] bs = (zipWithLeft' Prod.mk [] bs).fst
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs✝ bs : List β
⊢ zipWithLeft Prod.mk [] bs = (zipWithLeft' Prod.mk [] bs).fst
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs✝ bs : List β
head✝ : α
atl : List α
⊢ zipWithLeft Prod.mk (head✝ :: atl) bs = (zipWithLeft' Prod.mk (head✝ :: atl) bs).fst
[PROOFSTEP]

| cons _ atl =>
  cases bs with
  | nil => rfl
  | cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs✝ bs : List β
head✝ : α
atl : List α
⊢ zipWithLeft Prod.mk (head✝ :: atl) bs = (zipWithLeft' Prod.mk (head✝ :: atl) bs).fst
[PROOFSTEP]
cases bs with
| nil => rfl
| cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs✝ bs : List β
head✝ : α
atl : List α
⊢ zipWithLeft Prod.mk (head✝ :: atl) bs = (zipWithLeft' Prod.mk (head✝ :: atl) bs).fst
[PROOFSTEP]
cases bs with
| nil => rfl
| cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
head✝ : α
atl : List α
⊢ zipWithLeft Prod.mk (head✝ :: atl) [] = (zipWithLeft' Prod.mk (head✝ :: atl) []).fst
[PROOFSTEP]

| nil => rfl
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
head✝ : α
atl : List α
⊢ zipWithLeft Prod.mk (head✝ :: atl) [] = (zipWithLeft' Prod.mk (head✝ :: atl) []).fst
[PROOFSTEP]
rfl
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
head✝¹ : α
atl : List α
head✝ : β
btl : List β
⊢ zipWithLeft Prod.mk (head✝¹ :: atl) (head✝ :: btl) = (zipWithLeft' Prod.mk (head✝¹ :: atl) (head✝ :: btl)).fst
[PROOFSTEP]

| cons _ btl => rw [zipWithLeft, zipWithLeft', cons_inj]; exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
head✝¹ : α
atl : List α
head✝ : β
btl : List β
⊢ zipWithLeft Prod.mk (head✝¹ :: atl) (head✝ :: btl) = (zipWithLeft' Prod.mk (head✝¹ :: atl) (head✝ :: btl)).fst
[PROOFSTEP]
rw [zipWithLeft, zipWithLeft', cons_inj]
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
head✝¹ : α
atl : List α
head✝ : β
btl : List β
⊢ zipWithLeft Prod.mk atl btl = (zipWithLeft' Prod.mk atl btl).fst
[PROOFSTEP]
exact @zipLeft_eq_zipLeft' atl btl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
⊢ zipRight [] bs = map (fun b => (none, b)) bs
[PROOFSTEP]
cases bs
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
⊢ zipRight [] [] = map (fun b => (none, b)) []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b head✝ : β
tail✝ : List β
⊢ zipRight [] (head✝ :: tail✝) = map (fun b => (none, b)) (head✝ :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
as : List α
b : β
bs : List β
⊢ zipRight as bs = (zipRight' as bs).fst
[PROOFSTEP]
induction as generalizing bs
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
bs : List β
⊢ zipRight [] bs = (zipRight' [] bs).fst
[PROOFSTEP]
cases bs
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (bs : List β), zipRight tail✝ bs = (zipRight' tail✝ bs).fst
bs : List β
⊢ zipRight (head✝ :: tail✝) bs = (zipRight' (head✝ :: tail✝) bs).fst
[PROOFSTEP]
cases bs
[GOAL]
case nil.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
⊢ zipRight [] [] = (zipRight' [] []).fst
[PROOFSTEP]
simp [*]
[GOAL]
case nil.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b head✝ : β
tail✝ : List β
⊢ zipRight [] (head✝ :: tail✝) = (zipRight' [] (head✝ :: tail✝)).fst
[PROOFSTEP]
simp [*]
[GOAL]
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ (bs : List β), zipRight tail✝ bs = (zipRight' tail✝ bs).fst
⊢ zipRight (head✝ :: tail✝) [] = (zipRight' (head✝ :: tail✝) []).fst
[PROOFSTEP]
simp [*]
[GOAL]
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
b : β
head✝¹ : α
tail✝¹ : List α
tail_ih✝ : ∀ (bs : List β), zipRight tail✝¹ bs = (zipRight' tail✝¹ bs).fst
head✝ : β
tail✝ : List β
⊢ zipRight (head✝¹ :: tail✝¹) (head✝ :: tail✝) = (zipRight' (head✝¹ :: tail✝¹) (head✝ :: tail✝)).fst
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
l✝ : List α
x : α
l : List α
⊢ All₂ p (x :: l) ↔ ∀ (x_1 : α), x_1 ∈ x :: l → p x_1
[PROOFSTEP]
rw [forall_mem_cons, all₂_cons, all₂_iff_forall]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
l✝ : List α
h : ∀ (x : α), p x → q x
x : α
l : List α
⊢ All₂ p (x :: l) → All₂ q (x :: l)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
l✝ : List α
h : ∀ (x : α), p x → q x
x : α
l : List α
⊢ p x → All₂ p l → q x ∧ All₂ q l
[PROOFSTEP]
rw [← and_imp]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p q : α → Prop
l✝ : List α
h : ∀ (x : α), p x → q x
x : α
l : List α
⊢ p x ∧ All₂ p l → q x ∧ All₂ q l
[PROOFSTEP]
exact And.imp (h x) (All₂.imp h)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ q : α → Prop
l : List α
p : β → Prop
f : α → β
⊢ All₂ p (map f l) ↔ All₂ (p ∘ f) l
[PROOFSTEP]
induction l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ q : α → Prop
l : List α
p : β → Prop
f : α → β
⊢ All₂ p (map f []) ↔ All₂ (p ∘ f) []
[PROOFSTEP]
simp [*]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
p✝ q : α → Prop
l : List α
p : β → Prop
f : α → β
head✝ : α
tail✝ : List α
tail_ih✝ : All₂ p (map f tail✝) ↔ All₂ (p ∘ f) tail✝
⊢ All₂ p (map f (head✝ :: tail✝)) ↔ All₂ (p ∘ f) (head✝ :: tail✝)
[PROOFSTEP]
simp [*]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
hl : reverse l ≠ []
⊢ 0 < length l
[PROOFSTEP]
contrapose! hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
hl : length l ≤ 0
⊢ reverse l = []
[PROOFSTEP]
simpa [length_eq_zero] using hl
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
hl : reverse l ≠ []
hl' : optParam (0 < length l) (_ : 0 < length l)
⊢ getLast (reverse l) hl = get l { val := 0, isLt := hl' }
[PROOFSTEP]
rw [getLast_eq_get, get_reverse']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
hl : reverse l ≠ []
hl' : optParam (0 < length l) (_ : 0 < length l)
⊢ get l
      {
        val :=
          length l - 1 - ↑{ val := length (reverse l) - 1, isLt := (_ : length (reverse l) - 1 < length (reverse l)) },
        isLt := ?hn' } =
    get l { val := 0, isLt := hl' }
[PROOFSTEP]
simp
[GOAL]
case hn'
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
hl : reverse l ≠ []
hl' : optParam (0 < length l) (_ : 0 < length l)
⊢ length l - 1 - ↑{ val := length (reverse l) - 1, isLt := (_ : length (reverse l) - 1 < length (reverse l)) } <
    length l
[PROOFSTEP]
simpa using hl'
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a : α
⊢ ilast' a [] ∈ [a]
[PROOFSTEP]
simp [ilast']
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ ilast' a (b :: l) ∈ a :: b :: l
[PROOFSTEP]
rw [mem_cons]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
a b : α
l : List α
⊢ ilast' a (b :: l) = a ∨ ilast' a (b :: l) ∈ b :: l
[PROOFSTEP]
exact Or.inr (ilast'_mem b l)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : Fin (length (attach L))
⊢ ↑i < length (map Subtype.val (attach L))
[PROOFSTEP]
simpa using i.2
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : Fin (length (attach L))
⊢ ↑(get (attach L) i) =
    get (map Subtype.val (attach L)) { val := ↑i, isLt := (_ : ↑i < length (map Subtype.val (attach L))) }
[PROOFSTEP]
rw [get_map]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : Fin (length (attach L))
⊢ get (map Subtype.val (attach L)) { val := ↑i, isLt := (_ : ↑i < length (map Subtype.val (attach L))) } =
    get L { val := ↑i, isLt := (_ : ↑i < length L) }
[PROOFSTEP]
congr 2
[GOAL]
case h.e_2.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : Fin (length (attach L))
⊢ map Subtype.val (attach L) = L
[PROOFSTEP]
simp
[GOAL]
case h.e_3.e_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : Fin (length (attach L))
⊢ length (map Subtype.val (attach L)) = length L
[PROOFSTEP]
simp
[GOAL]
case h.e_3.e_3
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ L : List α
i : Fin (length (attach L))
⊢ HEq (_ : ↑i < length (map Subtype.val (attach L))) (_ : ↑i < length L)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
y : β
xs : List (α × β)
⊢ (y, x) ∈ map Prod.swap xs ↔ (x, y) ∈ xs
[PROOFSTEP]
induction' xs with x xs xs_ih
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
y : β
⊢ (y, x) ∈ map Prod.swap [] ↔ (x, y) ∈ []
[PROOFSTEP]
simp only [not_mem_nil, map_nil]
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x✝ : α
y : β
x : α × β
xs : List (α × β)
xs_ih : (y, x✝) ∈ map Prod.swap xs ↔ (x✝, y) ∈ xs
⊢ (y, x✝) ∈ map Prod.swap (x :: xs) ↔ (x✝, y) ∈ x :: xs
[PROOFSTEP]
cases' x with a b
[GOAL]
case cons.mk
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
x : α
y : β
xs : List (α × β)
xs_ih : (y, x) ∈ map Prod.swap xs ↔ (x, y) ∈ xs
a : α
b : β
⊢ (y, x) ∈ map Prod.swap ((a, b) :: xs) ↔ (x, y) ∈ (a, b) :: xs
[PROOFSTEP]
simp only [mem_cons, Prod.mk.inj_iff, map, Prod.swap_prod_mk, Prod.exists, xs_ih, and_comm]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ xs : List α
n m : ℕ
⊢ dropSlice n m xs = take n xs ++ drop (n + m) xs
[PROOFSTEP]
induction n generalizing xs
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : ℕ
xs : List α
⊢ dropSlice zero m xs = take zero xs ++ drop (zero + m) xs
[PROOFSTEP]
cases xs
[GOAL]
case zero.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : ℕ
⊢ dropSlice zero m [] = take zero [] ++ drop (zero + m) []
[PROOFSTEP]
simp [dropSlice]
[GOAL]
case zero.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m : ℕ
head✝ : α
tail✝ : List α
⊢ dropSlice zero m (head✝ :: tail✝) = take zero (head✝ :: tail✝) ++ drop (zero + m) (head✝ :: tail✝)
[PROOFSTEP]
simp [dropSlice]
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n✝ : ℕ
n_ih✝ : ∀ (xs : List α), dropSlice n✝ m xs = take n✝ xs ++ drop (n✝ + m) xs
xs : List α
⊢ dropSlice (succ n✝) m xs = take (succ n✝) xs ++ drop (succ n✝ + m) xs
[PROOFSTEP]
cases xs
[GOAL]
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n✝ : ℕ
n_ih✝ : ∀ (xs : List α), dropSlice n✝ m xs = take n✝ xs ++ drop (n✝ + m) xs
⊢ dropSlice (succ n✝) m [] = take (succ n✝) [] ++ drop (succ n✝ + m) []
[PROOFSTEP]
simp [dropSlice, *, Nat.succ_add]
[GOAL]
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
m n✝ : ℕ
n_ih✝ : ∀ (xs : List α), dropSlice n✝ m xs = take n✝ xs ++ drop (n✝ + m) xs
head✝ : α
tail✝ : List α
⊢ dropSlice (succ n✝) m (head✝ :: tail✝) = take (succ n✝) (head✝ :: tail✝) ++ drop (succ n✝ + m) (head✝ :: tail✝)
[PROOFSTEP]
simp [dropSlice, *, Nat.succ_add]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
i j : ℕ
hj : 0 < j
xs : List α
hi : i < length xs
⊢ sizeOf (dropSlice i j xs) < sizeOf xs
[PROOFSTEP]
induction xs generalizing i j hj with
| nil => cases hi
| cons x xs xs_ih =>
  cases i <;> simp only [List.dropSlice]
  ·
    cases j with
    | zero => contradiction
    | succ n =>
      dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
      induction xs generalizing n with
      | nil => rw [drop_nil]
      | cons _ xs_tl =>
        cases n
        · simp
        · simp [drop]
          rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
          exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
      · simp
  · simp
    apply xs_ih _ j hj
    apply lt_of_succ_lt_succ hi
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
i j : ℕ
hj : 0 < j
xs : List α
hi : i < length xs
⊢ sizeOf (dropSlice i j xs) < sizeOf xs
[PROOFSTEP]
induction xs generalizing i j hj with
| nil => cases hi
| cons x xs xs_ih =>
  cases i <;> simp only [List.dropSlice]
  ·
    cases j with
    | zero => contradiction
    | succ n =>
      dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
      induction xs generalizing n with
      | nil => rw [drop_nil]
      | cons _ xs_tl =>
        cases n
        · simp
        · simp [drop]
          rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
          exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
      · simp
  · simp
    apply xs_ih _ j hj
    apply lt_of_succ_lt_succ hi
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
i j : ℕ
hj : 0 < j
hi : i < length []
⊢ sizeOf (dropSlice i j []) < sizeOf []
[PROOFSTEP]

| nil => cases hi
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
i j : ℕ
hj : 0 < j
hi : i < length []
⊢ sizeOf (dropSlice i j []) < sizeOf []
[PROOFSTEP]
cases hi
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
i j : ℕ
hj : 0 < j
hi : i < length (x :: xs)
⊢ sizeOf (dropSlice i j (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]

| cons x xs xs_ih =>
  cases i <;> simp only [List.dropSlice]
  ·
    cases j with
    | zero => contradiction
    | succ n =>
      dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
      induction xs generalizing n with
      | nil => rw [drop_nil]
      | cons _ xs_tl =>
        cases n
        · simp
        · simp [drop]
          rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
          exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
      · simp
  · simp
    apply xs_ih _ j hj
    apply lt_of_succ_lt_succ hi
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
i j : ℕ
hj : 0 < j
hi : i < length (x :: xs)
⊢ sizeOf (dropSlice i j (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
cases i
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
hi : zero < length (x :: xs)
⊢ sizeOf (dropSlice zero j (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
simp only [List.dropSlice]
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
n✝ : ℕ
hi : succ n✝ < length (x :: xs)
⊢ sizeOf (dropSlice (succ n✝) j (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
simp only [List.dropSlice]
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
hi : zero < length (x :: xs)
⊢ sizeOf (drop j (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
cases j with
| zero => contradiction
| succ n =>
  dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
  induction xs generalizing n with
  | nil => rw [drop_nil]
  | cons _ xs_tl =>
    cases n
    · simp
    · simp [drop]
      rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
      exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
  · simp
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
hi : zero < length (x :: xs)
⊢ sizeOf (drop j (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
cases j with
| zero => contradiction
| succ n =>
  dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
  induction xs generalizing n with
  | nil => rw [drop_nil]
  | cons _ xs_tl =>
    cases n
    · simp
    · simp [drop]
      rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
      exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
  · simp
[GOAL]
case cons.zero.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
hj : 0 < zero
⊢ sizeOf (drop zero (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]

| zero => contradiction
[GOAL]
case cons.zero.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
hj : 0 < zero
⊢ sizeOf (drop zero (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
contradiction
[GOAL]
case cons.zero.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop (succ n) (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]

| succ n =>
  dsimp only [drop]; apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
  induction xs generalizing n with
  | nil => rw [drop_nil]
  | cons _ xs_tl =>
    cases n
    · simp
    · simp [drop]
      rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
      exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
  · simp
[GOAL]
case cons.zero.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop (succ n) (x :: xs)) < sizeOf (x :: xs)
[PROOFSTEP]
dsimp only [drop]
[GOAL]
case cons.zero.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n xs) < sizeOf (x :: xs)
[PROOFSTEP]
apply @lt_of_le_of_lt _ _ _ (sizeOf xs)
[GOAL]
case cons.zero.succ.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n xs) ≤ sizeOf xs
case cons.zero.succ.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf xs < sizeOf (x :: xs)
[PROOFSTEP]
induction xs generalizing n with
| nil => rw [drop_nil]
| cons _ xs_tl =>
  cases n
  · simp
  · simp [drop]
    rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
    exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
[GOAL]
case cons.zero.succ.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n xs) ≤ sizeOf xs
[PROOFSTEP]
induction xs generalizing n with
| nil => rw [drop_nil]
| cons _ xs_tl =>
  cases n
  · simp
  · simp [drop]
    rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
    exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
[GOAL]
case cons.zero.succ.a.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length [] → sizeOf (dropSlice i j []) < sizeOf []
hi : zero < length [x]
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n []) ≤ sizeOf []
[PROOFSTEP]

| nil => rw [drop_nil]
[GOAL]
case cons.zero.succ.a.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length [] → sizeOf (dropSlice i j []) < sizeOf []
hi : zero < length [x]
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n []) ≤ sizeOf []
[PROOFSTEP]
rw [drop_nil]
[GOAL]
case cons.zero.succ.a.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x head✝ : α
xs_tl : List α
tail_ih✝ :
  (∀ (i j : ℕ), 0 < j → i < length xs_tl → sizeOf (dropSlice i j xs_tl) < sizeOf xs_tl) →
    zero < length (x :: xs_tl) → ∀ (n : ℕ), 0 < succ n → sizeOf (drop n xs_tl) ≤ sizeOf xs_tl
xs_ih :
  ∀ (i j : ℕ), 0 < j → i < length (head✝ :: xs_tl) → sizeOf (dropSlice i j (head✝ :: xs_tl)) < sizeOf (head✝ :: xs_tl)
hi : zero < length (x :: head✝ :: xs_tl)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n (head✝ :: xs_tl)) ≤ sizeOf (head✝ :: xs_tl)
[PROOFSTEP]

| cons _ xs_tl =>
  cases n
  · simp
  · simp [drop]
    rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
    exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
[GOAL]
case cons.zero.succ.a.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x head✝ : α
xs_tl : List α
tail_ih✝ :
  (∀ (i j : ℕ), 0 < j → i < length xs_tl → sizeOf (dropSlice i j xs_tl) < sizeOf xs_tl) →
    zero < length (x :: xs_tl) → ∀ (n : ℕ), 0 < succ n → sizeOf (drop n xs_tl) ≤ sizeOf xs_tl
xs_ih :
  ∀ (i j : ℕ), 0 < j → i < length (head✝ :: xs_tl) → sizeOf (dropSlice i j (head✝ :: xs_tl)) < sizeOf (head✝ :: xs_tl)
hi : zero < length (x :: head✝ :: xs_tl)
n : ℕ
hj : 0 < succ n
⊢ sizeOf (drop n (head✝ :: xs_tl)) ≤ sizeOf (head✝ :: xs_tl)
[PROOFSTEP]
cases n
[GOAL]
case cons.zero.succ.a.cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x head✝ : α
xs_tl : List α
tail_ih✝ :
  (∀ (i j : ℕ), 0 < j → i < length xs_tl → sizeOf (dropSlice i j xs_tl) < sizeOf xs_tl) →
    zero < length (x :: xs_tl) → ∀ (n : ℕ), 0 < succ n → sizeOf (drop n xs_tl) ≤ sizeOf xs_tl
xs_ih :
  ∀ (i j : ℕ), 0 < j → i < length (head✝ :: xs_tl) → sizeOf (dropSlice i j (head✝ :: xs_tl)) < sizeOf (head✝ :: xs_tl)
hi : zero < length (x :: head✝ :: xs_tl)
hj : 0 < succ zero
⊢ sizeOf (drop zero (head✝ :: xs_tl)) ≤ sizeOf (head✝ :: xs_tl)
[PROOFSTEP]
simp
[GOAL]
case cons.zero.succ.a.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x head✝ : α
xs_tl : List α
tail_ih✝ :
  (∀ (i j : ℕ), 0 < j → i < length xs_tl → sizeOf (dropSlice i j xs_tl) < sizeOf xs_tl) →
    zero < length (x :: xs_tl) → ∀ (n : ℕ), 0 < succ n → sizeOf (drop n xs_tl) ≤ sizeOf xs_tl
xs_ih :
  ∀ (i j : ℕ), 0 < j → i < length (head✝ :: xs_tl) → sizeOf (dropSlice i j (head✝ :: xs_tl)) < sizeOf (head✝ :: xs_tl)
hi : zero < length (x :: head✝ :: xs_tl)
n✝ : ℕ
hj : 0 < succ (succ n✝)
⊢ sizeOf (drop (succ n✝) (head✝ :: xs_tl)) ≤ sizeOf (head✝ :: xs_tl)
[PROOFSTEP]
simp [drop]
[GOAL]
case cons.zero.succ.a.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x head✝ : α
xs_tl : List α
tail_ih✝ :
  (∀ (i j : ℕ), 0 < j → i < length xs_tl → sizeOf (dropSlice i j xs_tl) < sizeOf xs_tl) →
    zero < length (x :: xs_tl) → ∀ (n : ℕ), 0 < succ n → sizeOf (drop n xs_tl) ≤ sizeOf xs_tl
xs_ih :
  ∀ (i j : ℕ), 0 < j → i < length (head✝ :: xs_tl) → sizeOf (dropSlice i j (head✝ :: xs_tl)) < sizeOf (head✝ :: xs_tl)
hi : zero < length (x :: head✝ :: xs_tl)
n✝ : ℕ
hj : 0 < succ (succ n✝)
⊢ sizeOf (drop n✝ xs_tl) ≤ 1 + sizeOf head✝ + sizeOf xs_tl
[PROOFSTEP]
rw [← Nat.zero_add (sizeOf (drop _ xs_tl))]
[GOAL]
case cons.zero.succ.a.cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x head✝ : α
xs_tl : List α
tail_ih✝ :
  (∀ (i j : ℕ), 0 < j → i < length xs_tl → sizeOf (dropSlice i j xs_tl) < sizeOf xs_tl) →
    zero < length (x :: xs_tl) → ∀ (n : ℕ), 0 < succ n → sizeOf (drop n xs_tl) ≤ sizeOf xs_tl
xs_ih :
  ∀ (i j : ℕ), 0 < j → i < length (head✝ :: xs_tl) → sizeOf (dropSlice i j (head✝ :: xs_tl)) < sizeOf (head✝ :: xs_tl)
hi : zero < length (x :: head✝ :: xs_tl)
n✝ : ℕ
hj : 0 < succ (succ n✝)
⊢ 0 + sizeOf (drop n✝ xs_tl) ≤ 1 + sizeOf head✝ + sizeOf xs_tl
[PROOFSTEP]
exact Nat.add_le_add (Nat.zero_le _) (drop_sizeOf_le xs_tl _)
[GOAL]
case cons.zero.succ.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
hi : zero < length (x :: xs)
n : ℕ
hj : 0 < succ n
⊢ sizeOf xs < sizeOf (x :: xs)
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
n✝ : ℕ
hi : succ n✝ < length (x :: xs)
⊢ sizeOf (x :: dropSlice n✝ j xs) < sizeOf (x :: xs)
[PROOFSTEP]
simp
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
n✝ : ℕ
hi : succ n✝ < length (x :: xs)
⊢ sizeOf (dropSlice n✝ j xs) < sizeOf xs
[PROOFSTEP]
apply xs_ih _ j hj
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : SizeOf α
x : α
xs : List α
xs_ih : ∀ (i j : ℕ), 0 < j → i < length xs → sizeOf (dropSlice i j xs) < sizeOf xs
j : ℕ
hj : 0 < j
n✝ : ℕ
hi : succ n✝ < length (x :: xs)
⊢ n✝ < length xs
[PROOFSTEP]
apply lt_of_succ_lt_succ hi
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
hn : n < length l
⊢ getD l n d = get l { val := n, isLt := hn }
[PROOFSTEP]
induction' l with hd tl IH generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n✝ : ℕ
hn✝ : n✝ < length l
n : ℕ
hn : n < length []
⊢ getD [] n d = get [] { val := n, isLt := hn }
[PROOFSTEP]
exact absurd hn (not_lt_of_ge (Nat.zero_le _))
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n✝ : ℕ
hn✝ : n✝ < length l
hd : α
tl : List α
IH : ∀ {n : ℕ} (hn : n < length tl), getD tl n d = get tl { val := n, isLt := hn }
n : ℕ
hn : n < length (hd :: tl)
⊢ getD (hd :: tl) n d = get (hd :: tl) { val := n, isLt := hn }
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
hn✝ : n < length l
hd : α
tl : List α
IH : ∀ {n : ℕ} (hn : n < length tl), getD tl n d = get tl { val := n, isLt := hn }
hn : zero < length (hd :: tl)
⊢ getD (hd :: tl) zero d = get (hd :: tl) { val := zero, isLt := hn }
[PROOFSTEP]
exact getD_cons_zero _ _ _
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n : ℕ
hn✝ : n < length l
hd : α
tl : List α
IH : ∀ {n : ℕ} (hn : n < length tl), getD tl n d = get tl { val := n, isLt := hn }
n✝ : ℕ
hn : succ n✝ < length (hd :: tl)
⊢ getD (hd :: tl) (succ n✝) d = get (hd :: tl) { val := succ n✝, isLt := hn }
[PROOFSTEP]
exact IH _
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
hn : length l ≤ n
⊢ getD l n d = d
[PROOFSTEP]
induction' l with hd tl IH generalizing n
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n✝ : ℕ
hn✝ : length l ≤ n✝
n : ℕ
hn : length [] ≤ n
⊢ getD [] n d = d
[PROOFSTEP]
exact getD_nil _ _
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n✝ : ℕ
hn✝ : length l ≤ n✝
hd : α
tl : List α
IH : ∀ {n : ℕ}, length tl ≤ n → getD tl n d = d
n : ℕ
hn : length (hd :: tl) ≤ n
⊢ getD (hd :: tl) n d = d
[PROOFSTEP]
cases n
[GOAL]
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
hn✝ : length l ≤ n
hd : α
tl : List α
IH : ∀ {n : ℕ}, length tl ≤ n → getD tl n d = d
hn : length (hd :: tl) ≤ zero
⊢ getD (hd :: tl) zero d = d
[PROOFSTEP]
refine' absurd (Nat.zero_lt_succ _) (not_lt_of_ge hn)
[GOAL]
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n : ℕ
hn✝ : length l ≤ n
hd : α
tl : List α
IH : ∀ {n : ℕ}, length tl ≤ n → getD tl n d = d
n✝ : ℕ
hn : length (hd :: tl) ≤ succ n✝
⊢ getD (hd :: tl) (succ n✝) d = d
[PROOFSTEP]
exact IH (Nat.le_of_succ_le_succ hn)
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
⊢ getD [d] n d = d
[PROOFSTEP]
cases n
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n : ℕ
⊢ getD [d] zero d = d
[PROOFSTEP]
simp
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n n✝ : ℕ
⊢ getD [d] (succ n✝) d = d
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ r n : ℕ
⊢ getD (replicate r d) n d = d
[PROOFSTEP]
induction' r with r IH generalizing n
[GOAL]
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n✝ n : ℕ
⊢ getD (replicate zero d) n d = d
[PROOFSTEP]
simp
[GOAL]
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n✝ r : ℕ
IH : ∀ (n : ℕ), getD (replicate r d) n d = d
n : ℕ
⊢ getD (replicate (succ r) d) n d = d
[PROOFSTEP]
cases n
[GOAL]
case succ.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n r : ℕ
IH : ∀ (n : ℕ), getD (replicate r d) n d = d
⊢ getD (replicate (succ r) d) zero d = d
[PROOFSTEP]
simp [IH]
[GOAL]
case succ.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝¹ n r : ℕ
IH : ∀ (n : ℕ), getD (replicate r d) n d = d
n✝ : ℕ
⊢ getD (replicate (succ r) d) (succ n✝) d = d
[PROOFSTEP]
simp [IH]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : n < length l
h' : optParam (n < length (l ++ l')) (_ : n < length (l ++ l'))
⊢ getD (l ++ l') n d = getD l n d
[PROOFSTEP]
rw [getD_eq_get _ _ h', get_append _ h, getD_eq_get]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
⊢ getD (l ++ l') n d = getD l' (n - length l) d
[PROOFSTEP]
cases' lt_or_le n (l ++ l').length with h' h'
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length (l ++ l')
⊢ getD (l ++ l') n d = getD l' (n - length l) d
[PROOFSTEP]
rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
[GOAL]
case inl.hn
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length (l ++ l')
⊢ n - length l < length l'
[PROOFSTEP]
rw [length_append] at h' 
[GOAL]
case inl.hn
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length l + length l'
⊢ n - length l < length l'
[PROOFSTEP]
exact Nat.sub_lt_left_of_lt_add h h'
[GOAL]
case inl.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length (l ++ l')
⊢ ¬n < length l
[PROOFSTEP]
exact not_lt_of_le h
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : length (l ++ l') ≤ n
⊢ getD (l ++ l') n d = getD l' (n - length l) d
[PROOFSTEP]
rw [getD_eq_default _ _ h', getD_eq_default]
[GOAL]
case inr.hn
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : length (l ++ l') ≤ n
⊢ length l' ≤ n - length l
[PROOFSTEP]
rwa [le_tsub_iff_left h, ← length_append]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
⊢ getD l n d = Option.getD (get? l n) d
[PROOFSTEP]
cases' lt_or_le n l.length with h h
[GOAL]
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
h : n < length l
⊢ getD l n d = Option.getD (get? l n) d
[PROOFSTEP]
rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
[GOAL]
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
h : length l ≤ n
⊢ getD l n d = Option.getD (get? l n) d
[PROOFSTEP]
rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
x : α
xs : List α
n✝ n : ℕ
⊢ getI l n = Option.iget (get? l n)
[PROOFSTEP]
rw [← getD_default_eq_getI, getD_eq_getD_get?, Option.getD_default_eq_iget]
[GOAL]
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
x : α
xs : List α
n : ℕ
⊢ getI l 0 = headI l
[PROOFSTEP]
cases l
[GOAL]
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
x : α
xs : List α
n : ℕ
⊢ getI [] 0 = headI []
[PROOFSTEP]
rfl
[GOAL]
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
δ : Type x
l₁ l₂ : List α
inst✝ : Inhabited α
x : α
xs : List α
n : ℕ
head✝ : α
tail✝ : List α
⊢ getI (head✝ :: tail✝) 0 = headI (head✝ :: tail✝)
[PROOFSTEP]
rfl
