l3lab/ntp-mathlib huggingface dataset:
/-- A nonzero Hermitian matrix has an eigenvector with nonzero eigenvalue. -/
lemma exists_eigenvector_of_ne_zero (h_ne : A ≠ 0) :
    ∃ (v : n → 𝕜) (t : ℝ), t ≠ 0 ∧ v ≠ 0 ∧ mulVec A v = t • v := by
  have : hA.eigenvalues ≠ 0
  · contrapose! h_ne
    have := hA.spectral_theorem'
    

Proof state:
case this
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
n : Type u_2
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h_ne : eigenvalues hA = 0
this : A = eigenvectorMatrix hA * diagonal (IsROrC.ofReal ∘ eigenvalues hA) * eigenvectorMatrixInv hA
⊢ A = 0

Next tactic:
rwa [h_ne, Pi.comp_zero, IsROrC.ofReal_zero, (by rfl : Function.const n (0 : 𝕜) = fun _ ↦ 0),
      diagonal_zero, mul_zero, zero_mul] at this
/-- A nonzero Hermitian matrix has an eigenvector with nonzero eigenvalue. -/
lemma exists_eigenvector_of_ne_zero (h_ne : A ≠ 0) :
    ∃ (v : n → 𝕜) (t : ℝ), t ≠ 0 ∧ v ≠ 0 ∧ mulVec A v = t • v := by
  have : hA.eigenvalues ≠ 0
  · contrapose! h_ne
    have := hA.spectral_theorem'
    rwa [h_ne, Pi.comp_zero, IsROrC.ofReal_zero, (by 

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
n : Type u_2
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h_ne : eigenvalues hA = 0
this : A = eigenvectorMatrix hA * diagonal (Function.const n 0) * eigenvectorMatrixInv hA
⊢ Function.const n 0 = fun x => 0

Next tactic:
rfl
/-- A nonzero Hermitian matrix has an eigenvector with nonzero eigenvalue. -/
lemma exists_eigenvector_of_ne_zero (h_ne : A ≠ 0) :
    ∃ (v : n → 𝕜) (t : ℝ), t ≠ 0 ∧ v ≠ 0 ∧ mulVec A v = t • v := by
  have : hA.eigenvalues ≠ 0
  · contrapose! h_ne
    have := hA.spectral_theorem'
    rwa [h_ne, Pi.comp_zero, IsROrC.ofReal_zero, (by rfl : Function.const n (0 : 𝕜) = fun _ ↦ 0),
      diagonal_zero, mul_zero, zero_mul] at this
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
n : Type u_2
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h_ne : A ≠ 0
this : eigenvalues hA ≠ 0
⊢ ∃ v t, t ≠ 0 ∧ v ≠ 0 ∧ mulVec A v = t • v

Next tactic:
obtain ⟨i, hi⟩ := Function.ne_iff.mp this
/-- A nonzero Hermitian matrix has an eigenvector with nonzero eigenvalue. -/
lemma exists_eigenvector_of_ne_zero (h_ne : A ≠ 0) :
    ∃ (v : n → 𝕜) (t : ℝ), t ≠ 0 ∧ v ≠ 0 ∧ mulVec A v = t • v := by
  have : hA.eigenvalues ≠ 0
  · contrapose! h_ne
    have := hA.spectral_theorem'
    rwa [h_ne, Pi.comp_zero, IsROrC.ofReal_zero, (by rfl : Function.const n (0 : 𝕜) = fun _ ↦ 0),
      diagonal_zero, mul_zero, zero_mul] at this
  obtain ⟨i, hi⟩ := Function.ne_iff.mp this
  

Proof state:
case intro
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
n : Type u_2
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h_ne : A ≠ 0
this : eigenvalues hA ≠ 0
i : n
hi : eigenvalues hA i ≠ OfNat.ofNat 0 i
⊢ ∃ v t, t ≠ 0 ∧ v ≠ 0 ∧ mulVec A v = t • v

Next tactic:
exact ⟨_, _, hi, hA.eigenvectorBasis.orthonormal.ne_zero i, hA.mulVec_eigenvectorBasis i⟩
theorem sublist_suffix_of_union : ∀ l₁ l₂ : List α, ∃ t, t <+ l₁ ∧ t ++ l₂ = l₁ ∪ l₂
  | [], l₂ => ⟨[], by 

Proof state:
α : Type u_1
l l₁ l₂✝ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₂ : List α
⊢ [] <+ []

Next tactic:
rfl
theorem sublist_suffix_of_union : ∀ l₁ l₂ : List α, ∃ t, t <+ l₁ ∧ t ++ l₂ = l₁ ∪ l₂
  | [], l₂ => ⟨[], by rfl, rfl⟩
  | a :: l₁, l₂ =>
    let ⟨t, s, e⟩ := sublist_suffix_of_union l₁ l₂
    if h : a ∈ l₁ ∪ l₂ then
      ⟨t, sublist_cons_of_sublist _ s, by
        

Proof state:
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a : α
l₁ l₂ t : List α
s : t <+ l₁
e : t ++ l₂ = l₁ ∪ l₂
h : a ∈ l₁ ∪ l₂
⊢ t ++ l₂ = a :: l₁ ∪ l₂

Next tactic:
simp only [e, cons_union, insert_of_mem h]
theorem sublist_suffix_of_union : ∀ l₁ l₂ : List α, ∃ t, t <+ l₁ ∧ t ++ l₂ = l₁ ∪ l₂
  | [], l₂ => ⟨[], by rfl, rfl⟩
  | a :: l₁, l₂ =>
    let ⟨t, s, e⟩ := sublist_suffix_of_union l₁ l₂
    if h : a ∈ l₁ ∪ l₂ then
      ⟨t, sublist_cons_of_sublist _ s, by
        simp only [e, cons_union, insert_of_mem h]⟩
    else
      ⟨a :: t, s.cons_cons _, by
        

Proof state:
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a : α
l₁ l₂ t : List α
s : t <+ l₁
e : t ++ l₂ = l₁ ∪ l₂
h : ¬a ∈ l₁ ∪ l₂
⊢ a :: t ++ l₂ = a :: l₁ ∪ l₂

Next tactic:
simp only [cons_append, cons_union, e, insert_of_not_mem h]
theorem forall_mem_union : (∀ x ∈ l₁ ∪ l₂, p x) ↔ (∀ x ∈ l₁, p x) ∧ ∀ x ∈ l₂, p x := by
  

Proof state:
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
⊢ (∀ (x : α), x ∈ l₁ ∪ l₂ → p x) ↔ (∀ (x : α), x ∈ l₁ → p x) ∧ ∀ (x : α), x ∈ l₂ → p x

Next tactic:
simp only [mem_union_iff, or_imp, forall_and]
@[simp]
theorem inter_cons_of_mem (l₁ : List α) (h : a ∈ l₂) : (a :: l₁) ∩ l₂ = a :: l₁ ∩ l₂ := by
  

Proof state:
α : Type u_1
l l₁✝ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
h : a ∈ l₂
⊢ (a :: l₁) ∩ l₂ = a :: l₁ ∩ l₂

Next tactic:
simp [Inter.inter, List.inter, h]
@[simp]
theorem inter_cons_of_not_mem (l₁ : List α) (h : a ∉ l₂) : (a :: l₁) ∩ l₂ = l₁ ∩ l₂ := by
  

Proof state:
α : Type u_1
l l₁✝ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
h : ¬a ∈ l₂
⊢ (a :: l₁) ∩ l₂ = l₁ ∩ l₂

Next tactic:
simp [Inter.inter, List.inter, h]
theorem mem_of_mem_inter_right (h : a ∈ l₁ ∩ l₂) : a ∈ l₂ := by 

Proof state:
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
h : a ∈ l₁ ∩ l₂
⊢ a ∈ l₂

Next tactic:
simpa using of_mem_filter h
theorem mem_inter_of_mem_of_mem (h₁ : a ∈ l₁) (h₂ : a ∈ l₂) : a ∈ l₁ ∩ l₂ :=
  mem_filter_of_mem h₁ $ by 

Proof state:
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
h₁ : a ∈ l₁
h₂ : a ∈ l₂
⊢ decide (a ∈ l₂) = true

Next tactic:
simpa using h₂
theorem inter_eq_nil_iff_disjoint : l₁ ∩ l₂ = [] ↔ Disjoint l₁ l₂ := by
  

Proof state:
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
⊢ l₁ ∩ l₂ = [] ↔ Disjoint l₁ l₂

Next tactic:
simp only [eq_nil_iff_forall_not_mem, mem_inter_iff, not_and]
theorem inter_eq_nil_iff_disjoint : l₁ ∩ l₂ = [] ↔ Disjoint l₁ l₂ := by
  simp only [eq_nil_iff_forall_not_mem, mem_inter_iff, not_and]
  

Proof state:
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
⊢ (∀ (a : α), a ∈ l₁ → ¬a ∈ l₂) ↔ Disjoint l₁ l₂

Next tactic:
rfl
@[simp]
theorem inter_reverse {xs ys : List α} : xs.inter ys.reverse = xs.inter ys := by
  

Proof state:
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
xs ys : List α
⊢ List.inter xs (reverse ys) = List.inter xs ys

Next tactic:
simp only [List.inter, mem_reverse]
@[simp]
theorem nil_bagInter (l : List α) : [].bagInter l = [] := by 

Proof state:
α : Type u_1
l✝ l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l : List α
⊢ List.bagInter [] l = []

Next tactic:
cases l
@[simp]
theorem nil_bagInter (l : List α) : [].bagInter l = [] := by cases l <;> 

Proof state:
case nil
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
⊢ List.bagInter [] [] = []

Next tactic:
rfl
@[simp]
theorem nil_bagInter (l : List α) : [].bagInter l = [] := by cases l <;> 

Proof state:
case cons
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
head✝ : α
tail✝ : List α
⊢ List.bagInter [] (head✝ :: tail✝) = []

Next tactic:
rfl
@[simp]
theorem bagInter_nil (l : List α) : l.bagInter [] = [] := by 

Proof state:
α : Type u_1
l✝ l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l : List α
⊢ List.bagInter l [] = []

Next tactic:
cases l
@[simp]
theorem bagInter_nil (l : List α) : l.bagInter [] = [] := by cases l <;> 

Proof state:
case nil
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
⊢ List.bagInter [] [] = []

Next tactic:
rfl
@[simp]
theorem bagInter_nil (l : List α) : l.bagInter [] = [] := by cases l <;> 

Proof state:
case cons
α : Type u_1
l l₁ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
head✝ : α
tail✝ : List α
⊢ List.bagInter (head✝ :: tail✝) [] = []

Next tactic:
rfl
@[simp]
theorem cons_bagInter_of_pos (l₁ : List α) (h : a ∈ l₂) :
    (a :: l₁).bagInter l₂ = a :: l₁.bagInter (l₂.erase a) := by
  

Proof state:
α : Type u_1
l l₁✝ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
h : a ∈ l₂
⊢ List.bagInter (a :: l₁) l₂ = a :: List.bagInter l₁ (List.erase l₂ a)

Next tactic:
cases l₂
@[simp]
theorem cons_bagInter_of_pos (l₁ : List α) (h : a ∈ l₂) :
    (a :: l₁).bagInter l₂ = a :: l₁.bagInter (l₂.erase a) := by
  cases l₂
  · 

Proof state:
case nil
α : Type u_1
l l₁✝ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
h : a ∈ []
⊢ List.bagInter (a :: l₁) [] = a :: List.bagInter l₁ (List.erase [] a)

Next tactic:
exact if_pos h
@[simp]
theorem cons_bagInter_of_pos (l₁ : List α) (h : a ∈ l₂) :
    (a :: l₁).bagInter l₂ = a :: l₁.bagInter (l₂.erase a) := by
  cases l₂
  · exact if_pos h
  · 

Proof state:
case cons
α : Type u_1
l l₁✝ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
head✝ : α
tail✝ : List α
h : a ∈ head✝ :: tail✝
⊢ List.bagInter (a :: l₁) (head✝ :: tail✝) = a :: List.bagInter l₁ (List.erase (head✝ :: tail✝) a)

Next tactic:
simp only [List.bagInter, if_pos (elem_eq_true_of_mem h)]
@[simp]
theorem cons_bagInter_of_neg (l₁ : List α) (h : a ∉ l₂) :
    (a :: l₁).bagInter l₂ = l₁.bagInter l₂ := by
  

Proof state:
α : Type u_1
l l₁✝ l₂ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
h : ¬a ∈ l₂
⊢ List.bagInter (a :: l₁) l₂ = List.bagInter l₁ l₂

Next tactic:
cases l₂
@[simp]
theorem cons_bagInter_of_neg (l₁ : List α) (h : a ∉ l₂) :
    (a :: l₁).bagInter l₂ = l₁.bagInter l₂ := by
  cases l₂; · 

Proof state:
case nil
α : Type u_1
l l₁✝ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
h : ¬a ∈ []
⊢ List.bagInter (a :: l₁) [] = List.bagInter l₁ []

Next tactic:
simp only [bagInter_nil]
@[simp]
theorem cons_bagInter_of_neg (l₁ : List α) (h : a ∉ l₂) :
    (a :: l₁).bagInter l₂ = l₁.bagInter l₂ := by
  cases l₂; · simp only [bagInter_nil]
  

Proof state:
case cons
α : Type u_1
l l₁✝ : List α
p : α → Prop
a : α
inst✝ : DecidableEq α
l₁ : List α
head✝ : α
tail✝ : List α
h : ¬a ∈ head✝ :: tail✝
⊢ List.bagInter (a :: l₁) (head✝ :: tail✝) = List.bagInter l₁ (head✝ :: tail✝)

Next tactic:
simp only [erase_of_not_mem h, List.bagInter, if_neg (mt mem_of_elem_eq_true h)]
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by 

Proof state:
α : Type u_1
l l₁ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a : α
l₂ : List α
⊢ a ∈ List.bagInter [] l₂ ↔ a ∈ [] ∧ a ∈ l₂

Next tactic:
simp only [nil_bagInter, not_mem_nil, false_and_iff]
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    

Proof state:
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
⊢ a ∈ List.bagInter (b :: l₁) l₂ ↔ a ∈ b :: l₁ ∧ a ∈ l₂

Next tactic:
by_cases h : b ∈ l₂
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · 

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b ∈ l₂
⊢ a ∈ List.bagInter (b :: l₁) l₂ ↔ a ∈ b :: l₁ ∧ a ∈ l₂

Next tactic:
rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b ∈ l₂
⊢ a = b ∨ a ∈ l₁ ∧ a ∈ List.erase l₂ b ↔ (a = b ∨ a ∈ l₁) ∧ a ∈ l₂

Next tactic:
by_cases ba : a = b
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · 

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b ∈ l₂
ba : a = b
⊢ a = b ∨ a ∈ l₁ ∧ a ∈ List.erase l₂ b ↔ (a = b ∨ a ∈ l₁) ∧ a ∈ l₂

Next tactic:
simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
      · 

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : b ∈ l₂
ba : ¬a = b
⊢ a = b ∨ a ∈ l₁ ∧ a ∈ List.erase l₂ b ↔ (a = b ∨ a ∈ l₁) ∧ a ∈ l₂

Next tactic:
simp only [mem_erase_of_ne ba, ba, false_or_iff]
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
      · simp only [mem_erase_of_ne ba, ba, false_or_iff]
    · 

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : ¬b ∈ l₂
⊢ a ∈ List.bagInter (b :: l₁) l₂ ↔ a ∈ b :: l₁ ∧ a ∈ l₂

Next tactic:
rw [cons_bagInter_of_neg _ h, mem_bagInter, mem_cons, or_and_right]
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
      · simp only [mem_erase_of_ne ba, ba, false_or_iff]
    · rw [cons_bagInter_of_neg _ h, mem_bagInter, mem_cons, or_and_right]
      

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : ¬b ∈ l₂
⊢ a ∈ l₁ ∧ a ∈ l₂ ↔ a = b ∧ a ∈ l₂ ∨ a ∈ l₁ ∧ a ∈ l₂

Next tactic:
symm
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
      · simp only [mem_erase_of_ne ba, ba, false_or_iff]
    · rw [cons_bagInter_of_neg _ h, mem_bagInter, mem_cons, or_and_right]
      symm
      

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : ¬b ∈ l₂
⊢ a = b ∧ a ∈ l₂ ∨ a ∈ l₁ ∧ a ∈ l₂ ↔ a ∈ l₁ ∧ a ∈ l₂

Next tactic:
apply or_iff_right_of_imp
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
      · simp only [mem_erase_of_ne ba, ba, false_or_iff]
    · rw [cons_bagInter_of_neg _ h, mem_bagInter, mem_cons, or_and_right]
      symm
      apply or_iff_right_of_imp
      

Proof state:
case neg.ha
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
h : ¬b ∈ l₂
⊢ a = b ∧ a ∈ l₂ → a ∈ l₁ ∧ a ∈ l₂

Next tactic:
rintro ⟨rfl, h'⟩
@[simp]
theorem mem_bagInter {a : α} : ∀ {l₁ l₂ : List α}, a ∈ l₁.bagInter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
  | [], l₂ => by simp only [nil_bagInter, not_mem_nil, false_and_iff]
  | b :: l₁, l₂ => by
    by_cases h : b ∈ l₂
    · rw [cons_bagInter_of_pos _ h, mem_cons, mem_cons, mem_bagInter]
      by_cases ba : a = b
      · simp only [ba, h, eq_self_iff_true, true_or_iff, true_and_iff]
      · simp only [mem_erase_of_ne ba, ba, false_or_iff]
    · rw [cons_bagInter_of_neg _ h, mem_bagInter, mem_cons, or_and_right]
      symm
      apply or_iff_right_of_imp
      rintro ⟨rfl, h'⟩
      

Proof state:
case neg.ha.intro
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a : α
l₁ l₂ : List α
h' : a ∈ l₂
h : ¬a ∈ l₂
⊢ a ∈ l₁ ∧ a ∈ l₂

Next tactic:
exact h.elim h'
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by 

Proof state:
α : Type u_1
l l₁ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a : α
l₂ : List α
⊢ count a (List.bagInter [] l₂) = min (count a []) (count a l₂)

Next tactic:
simp
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by 

Proof state:
α : Type u_1
l l₁✝ l₂ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a : α
l₁ : List α
⊢ count a (List.bagInter l₁ []) = min (count a l₁) (count a [])

Next tactic:
simp
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    

Proof state:
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
⊢ count a (List.bagInter (b :: l₁) l₂) = min (count a (b :: l₁)) (count a l₂)

Next tactic:
by_cases hb : b ∈ l₂
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · 

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : b ∈ l₂
⊢ count a (List.bagInter (b :: l₁) l₂) = min (count a (b :: l₁)) (count a l₂)

Next tactic:
rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : b ∈ l₂
⊢ min (count a l₁ + if a = b then 1 else 0) ((count a l₂ - if a = b then 1 else 0) + if a = b then 1 else 0) =
    min (count a l₁ + if a = b then 1 else 0) (count a l₂)

Next tactic:
by_cases ab : a = b
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      by_cases ab : a = b
      · 

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : b ∈ l₂
ab : a = b
⊢ min (count a l₁ + if a = b then 1 else 0) ((count a l₂ - if a = b then 1 else 0) + if a = b then 1 else 0) =
    min (count a l₁ + if a = b then 1 else 0) (count a l₂)

Next tactic:
rw [if_pos ab, @tsub_add_cancel_of_le]
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      by_cases ab : a = b
      · rw [if_pos ab, @tsub_add_cancel_of_le]
        

Proof state:
case pos.h
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : b ∈ l₂
ab : a = b
⊢ 1 ≤ count a l₂

Next tactic:
rwa [succ_le_iff, count_pos_iff_mem, ab]
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      by_cases ab : a = b
      · rw [if_pos ab, @tsub_add_cancel_of_le]
        rwa [succ_le_iff, count_pos_iff_mem, ab]
      · 

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : b ∈ l₂
ab : ¬a = b
⊢ min (count a l₁ + if a = b then 1 else 0) ((count a l₂ - if a = b then 1 else 0) + if a = b then 1 else 0) =
    min (count a l₁ + if a = b then 1 else 0) (count a l₂)

Next tactic:
rw [if_neg ab, tsub_zero, add_zero, add_zero]
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      by_cases ab : a = b
      · rw [if_pos ab, @tsub_add_cancel_of_le]
        rwa [succ_le_iff, count_pos_iff_mem, ab]
      · rw [if_neg ab, tsub_zero, add_zero, add_zero]
    · 

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : ¬b ∈ l₂
⊢ count a (List.bagInter (b :: l₁) l₂) = min (count a (b :: l₁)) (count a l₂)

Next tactic:
rw [cons_bagInter_of_neg _ hb, count_bagInter]
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      by_cases ab : a = b
      · rw [if_pos ab, @tsub_add_cancel_of_le]
        rwa [succ_le_iff, count_pos_iff_mem, ab]
      · rw [if_neg ab, tsub_zero, add_zero, add_zero]
    · rw [cons_bagInter_of_neg _ hb, count_bagInter]
      

Proof state:
case neg
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : ¬b ∈ l₂
⊢ min (count a l₁) (count a l₂) = min (count a (b :: l₁)) (count a l₂)

Next tactic:
by_cases ab : a = b
@[simp]
theorem count_bagInter {a : α} :
    ∀ {l₁ l₂ : List α}, count a (l₁.bagInter l₂) = min (count a l₁) (count a l₂)
  | [], l₂ => by simp
  | l₁, [] => by simp
  | b :: l₁, l₂ => by
    by_cases hb : b ∈ l₂
    · rw [cons_bagInter_of_pos _ hb, count_cons, count_cons, count_bagInter, count_erase, ←
        min_add_add_right]
      by_cases ab : a = b
      · rw [if_pos ab, @tsub_add_cancel_of_le]
        rwa [succ_le_iff, count_pos_iff_mem, ab]
      · rw [if_neg ab, tsub_zero, add_zero, add_zero]
    · rw [cons_bagInter_of_neg _ hb, count_bagInter]
      by_cases ab : a = b
      · 

Proof state:
case pos
α : Type u_1
l l₁✝ l₂✝ : List α
p : α → Prop
a✝ : α
inst✝ : DecidableEq α
a b : α
l₁ l₂ : List α
hb : ¬b ∈ l₂
ab : a = b
⊢ min (count a l₁) (count a l₂) = min (count a (b :: l₁)) (count a l₂)

Next tactic:
rw [← ab] at hb