l3lab/ntp-mathlib huggingface dataset:
theorem takeWhile_cons_of_pos {x : α} (h : p x) :
    List.takeWhile p (x :: l) = x :: takeWhile p l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
h : p x = true
⊢ takeWhile p (x :: l) = x :: takeWhile p l

Next tactic:
simp [takeWhile_cons, h]
theorem takeWhile_cons_of_neg {x : α} (h : ¬ p x) :
    List.takeWhile p (x :: l) = [] := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
h : ¬p x = true
⊢ takeWhile p (x :: l) = []

Next tactic:
simp [takeWhile_cons, h]
@[simp]
theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p l = l ↔ ∀ (x : α), x ∈ l → p x = true

Next tactic:
induction' l with x xs IH
@[simp]
theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
  induction' l with x xs IH
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p [] = [] ↔ ∀ (x : α), x ∈ [] → p x = true

Next tactic:
simp
@[simp]
theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
  induction' l with x xs IH
  · simp
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
by_cases hp : p x
@[simp]
theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
  induction' l with x xs IH
  · simp
  · by_cases hp : p x <;> 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
simp [hp, takeWhile_cons, IH]
@[simp]
theorem takeWhile_eq_self_iff : takeWhile p l = l ↔ ∀ x ∈ l, p x := by
  induction' l with x xs IH
  · simp
  · by_cases hp : p x <;> 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
simp [hp, takeWhile_cons, IH]
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p l = [] ↔ ∀ (hl : 0 < length l), ¬p (nthLe l 0 hl) = true

Next tactic:
induction' l with x xs IH
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  induction' l with x xs IH
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p [] = [] ↔ ∀ (hl : 0 < length []), ¬p (nthLe [] 0 hl) = true

Next tactic:
simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  induction' l with x xs IH
  · simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
    

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ ∀ (hl : 0 < length []), p (nthLe [] 0 hl) = false

Next tactic:
intro h
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  induction' l with x xs IH
  · simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
    intro h
    

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
h : 0 < length []
⊢ p (nthLe [] 0 h) = false

Next tactic:
simp at h
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  induction' l with x xs IH
  · simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
    intro h
    simp at h
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
by_cases hp : p x
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  induction' l with x xs IH
  · simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
    intro h
    simp at h
  · by_cases hp : p x <;> 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
simp [hp, takeWhile_cons, IH, nthLe_cons]
@[simp]
theorem takeWhile_eq_nil_iff : takeWhile p l = [] ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  induction' l with x xs IH
  · simp only [takeWhile_nil, Bool.not_eq_true, true_iff]
    intro h
    simp at h
  · by_cases hp : p x <;> 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
simp [hp, takeWhile_cons, IH, nthLe_cons]
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
hx : x ∈ takeWhile p l
⊢ p x = true

Next tactic:
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
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
simp [takeWhile] at hx
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with simp [takeWhile] at hx
  

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
| 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
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with simp [takeWhile] at hx
  | cons hd tl IH =>
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
cases hp : p hd
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with simp [takeWhile] at hx
  | cons hd tl IH =>
    cases hp : p hd
    · 

Proof state:
case cons.false
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
simp [hp] at hx
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with simp [takeWhile] at hx
  | cons hd tl IH =>
    cases hp : p hd
    · simp [hp] at hx
    · 

Proof state:
case cons.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
rw [hp, mem_cons] at hx
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  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
      

Proof state:
case cons.true
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
rcases hx with (rfl | hx)
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  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)
      · 

Proof state:
case cons.true.inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
exact hp
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  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
      · 

Proof state:
case cons.true.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
exact IH hx
theorem mem_takeWhile_imp {x : α} (hx : x ∈ takeWhile p l) : p x := by
  induction l with 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
x : α
hx : x ∈ takeWhile p []
⊢ p x = true

Next tactic:
simp [takeWhile] at hx
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
induction' l with hd tl IH
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p✝ : α → Bool
l : List α
p q : α → Bool
⊢ takeWhile p (takeWhile q []) = takeWhile (fun a => decide (p a = true ∧ q a = true)) []

Next tactic:
simp
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
by_cases hp : p hd
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · by_cases hp : p hd <;> 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
by_cases hq : q hd
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · by_cases hp : p hd <;> 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
by_cases hq : q hd
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · by_cases hp : p hd <;> by_cases hq : q hd <;> 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
simp [takeWhile, hp, hq, IH]
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · by_cases hp : p hd <;> by_cases hq : q hd <;> 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
simp [takeWhile, hp, hq, IH]
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · by_cases hp : p hd <;> by_cases hq : q hd <;> 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
simp [takeWhile, hp, hq, IH]
theorem takeWhile_takeWhile (p q : α → Bool) (l : List α) :
    takeWhile p (takeWhile q l) = takeWhile (fun a => p a ∧ q a) l := by
  induction' l with hd tl IH
  · simp
  · by_cases hp : p hd <;> by_cases hq : q hd <;> 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
simp [takeWhile, hp, hq, IH]
theorem takeWhile_idem : takeWhile p (takeWhile p l) = takeWhile p l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
⊢ takeWhile p (takeWhile p l) = takeWhile p l

Next tactic:
simp_rw [takeWhile_takeWhile, and_self_iff, Bool.decide_coe]
@[simp]
theorem length_eraseP_add_one {l : List α} {a} (al : a ∈ l) (pa : p a) :
    (l.eraseP p).length + 1 = l.length := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
l : List α
a : α
al : a ∈ l
pa : p a = true
⊢ length (eraseP p l) + 1 = length l

Next tactic:
let ⟨_, l₁, l₂, _, _, h₁, h₂⟩ := exists_of_eraseP al pa
@[simp]
theorem length_eraseP_add_one {l : List α} {a} (al : a ∈ l) (pa : p a) :
    (l.eraseP p).length + 1 = l.length := by
  let ⟨_, l₁, l₂, _, _, h₁, h₂⟩ := exists_of_eraseP al pa
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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

Next tactic:
rw [h₂, h₁, length_append, length_append]
@[simp]
theorem length_eraseP_add_one {l : List α} {a} (al : a ∈ l) (pa : p a) :
    (l.eraseP p).length + 1 = l.length := by
  let ⟨_, l₁, l₂, _, _, h₁, h₂⟩ := exists_of_eraseP al pa
  rw [h₂, h₁, length_append, length_append]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₂)

Next tactic:
rfl
@[simp] theorem length_erase_add_one {a : α} {l : List α} (h : a ∈ l) :
    (l.erase a).length + 1 = l.length := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
h : a ∈ l
⊢ length (List.erase l a) + 1 = length l

Next tactic:
rw [erase_eq_eraseP, length_eraseP_add_one h (decide_eq_true rfl)]
theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
    map f (l.erase a) = (map f l).erase (f a) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
    map f (l.erase a) = (map f l).erase (f a) := by
  have this : Eq a = Eq (f a) ∘ f := by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
⊢ Eq a = Eq (f a) ∘ f

Next tactic:
ext b
theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
    map f (l.erase a) = (map f l).erase (f a) := by
  have this : Eq a = Eq (f a) ∘ f := by ext b; 

Proof state:
case h.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
finj : Injective f
a : α
l : List α
b : α
⊢ a = b ↔ (Eq (f a) ∘ f) b

Next tactic:
simp [finj.eq_iff]
theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
    map f (l.erase a) = (map f l).erase (f a) := by
  have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
simp [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]
theorem map_erase [DecidableEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) :
    map f (l.erase a) = (map f l).erase (f a) := by
  have this : Eq a = Eq (f a) ∘ f := by ext b; simp [finj.eq_iff]
  simp [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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)

Next tactic:
rfl
theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
    map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.erase (f a)) (map f l₁) l₂ := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₂

Next tactic:
induction l₂ generalizing l₁ <;> [rfl; simp only [foldl_cons, map_erase finj, *]]
theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
    map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.erase (f a)) (map f l₁) l₂ := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₂

Next tactic:
induction l₂ generalizing l₁
theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
    map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.erase (f a)) (map f l₁) l₂ := by
  induction l₂ generalizing l₁ <;> [

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₁) []

Next tactic:
rfl
theorem map_foldl_erase [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
    map f (foldl List.erase l₁ l₂) = foldl (fun l a => l.erase (f a)) (map f l₁) l₂ := by
  induction l₂ generalizing l₁ <;> [rfl; 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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✝)

Next tactic:
simp only [foldl_cons, map_erase finj, *]
@[simp]
theorem map_diff [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} :
    map f (l₁.diff l₂) = (map f l₁).diff (map f l₂) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₂)

Next tactic:
simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
theorem erase_diff_erase_sublist_of_sublist {a : α} :
    ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.erase a).diff (l₁.erase a) <+ l₂.diff l₁
  | [], l₂, _ => erase_sublist _ _
  | b :: l₁, l₂, h =>
    if heq : b = a then by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₁)

Next tactic:
simp only [heq, erase_cons_head, diff_cons]
theorem erase_diff_erase_sublist_of_sublist {a : α} :
    ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.erase a).diff (l₁.erase a) <+ l₂.diff l₁
  | [], l₂, _ => erase_sublist _ _
  | b :: l₁, l₂, h =>
    if heq : b = a then by simp only [heq, erase_cons_head, diff_cons]; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₁

Next tactic:
rfl
theorem erase_diff_erase_sublist_of_sublist {a : α} :
    ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.erase a).diff (l₁.erase a) <+ l₂.diff l₁
  | [], l₂, _ => erase_sublist _ _
  | b :: l₁, l₂, h =>
    if heq : b = a then by simp only [heq, erase_cons_head, diff_cons]; rfl
    else by
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
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₁)

Next tactic:
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₂]