l3lab/ntp-mathlib huggingface dataset:
theorem filter_erase (a : α) (s : Finset α) : filter p (erase s a) = erase (filter p s) a := by
  ext x
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
a : α
s : Finset α
x : α
⊢ x ∈ filter p (erase s a) ↔ x ∈ erase (filter p s) a

Next tactic:
simp only [and_assoc, mem_filter, iff_self_iff, mem_erase]
theorem filter_or (s : Finset α) : (s.filter fun a => p a ∨ q a) = s.filter p ∪ s.filter q :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
x✝ : α
⊢ x✝ ∈ filter (fun a => p a ∨ q a) s ↔ x✝ ∈ filter p s ∪ filter q s

Next tactic:
simp [mem_filter, mem_union, and_or_left]
theorem filter_and (s : Finset α) : (s.filter fun a => p a ∧ q a) = s.filter p ∩ s.filter q :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
x✝ : α
⊢ x✝ ∈ filter (fun a => p a ∧ q a) s ↔ x✝ ∈ filter p s ∩ filter q s

Next tactic:
simp [mem_filter, mem_inter, and_comm, and_left_comm, and_self_iff, and_assoc]
theorem filter_not (s : Finset α) : (s.filter fun a => ¬p a) = s \ s.filter p :=
  ext <| fun a => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
a : α
⊢ a ∈ filter (fun a => ¬p a) s ↔ a ∈ s \ filter p s

Next tactic:
simp only [Bool.decide_coe, Bool.not_eq_true', mem_filter, and_comm, mem_sdiff, not_and_or,
      Bool.not_eq_true, and_or_left, and_not_self, or_false]
theorem sdiff_eq_filter (s₁ s₂ : Finset α) : s₁ \ s₂ = filter (· ∉ s₂) s₁ :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s : Finset α
inst✝ : DecidableEq α
s₁ s₂ : Finset α
x✝ : α
⊢ x✝ ∈ s₁ \ s₂ ↔ x✝ ∈ filter (fun x => x ∉ s₂) s₁

Next tactic:
simp [mem_sdiff, mem_filter]
theorem sdiff_eq_self (s₁ s₂ : Finset α) : s₁ \ s₂ = s₁ ↔ s₁ ∩ s₂ ⊆ ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s : Finset α
inst✝ : DecidableEq α
s₁ s₂ : Finset α
⊢ s₁ \ s₂ = s₁ ↔ s₁ ∩ s₂ ⊆ ∅

Next tactic:
simp [Subset.antisymm_iff, disjoint_iff_inter_eq_empty]
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
⊢ ∃ s₁ s₂, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁

Next tactic:
classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · intro x
      simp
    · intro x
      simp only [not_not, coe_filter, Set.mem_setOf_eq, Set.mem_diff, and_imp]
      intro hx hx₂
      refine' ⟨Or.resolve_left (h hx) hx₂, hx₂⟩
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
⊢ ∃ s₁ s₂, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁

Next tactic:
refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · 

Proof state:
case refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
⊢ filter (fun x => x ∈ t₁) s ∪ filter (fun x => x ∉ t₁) s = s

Next tactic:
simp [filter_union_right, em]
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · 

Proof state:
case refine'_2
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
⊢ ↑(filter (fun x => x ∈ t₁) s) ⊆ t₁

Next tactic:
intro x
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · intro x
      

Proof state:
case refine'_2
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
x : α
⊢ x ∈ ↑(filter (fun x => x ∈ t₁) s) → x ∈ t₁

Next tactic:
simp
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · intro x
      simp
    · 

Proof state:
case refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
⊢ ↑(filter (fun x => x ∉ t₁) s) ⊆ t₂ \ t₁

Next tactic:
intro x
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · intro x
      simp
    · intro x
      

Proof state:
case refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
x : α
⊢ x ∈ ↑(filter (fun x => x ∉ t₁) s) → x ∈ t₂ \ t₁

Next tactic:
simp only [not_not, coe_filter, Set.mem_setOf_eq, Set.mem_diff, and_imp]
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · intro x
      simp
    · intro x
      simp only [not_not, coe_filter, Set.mem_setOf_eq, Set.mem_diff, and_imp]
      

Proof state:
case refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
x : α
⊢ x ∈ s → x ∉ t₁ → x ∈ t₂ ∧ x ∉ t₁

Next tactic:
intro hx hx₂
theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t₁ ∪ t₂) :
    ∃ s₁ s₂ : Finset α, s₁ ∪ s₂ = s ∧ ↑s₁ ⊆ t₁ ∧ ↑s₂ ⊆ t₂ \ t₁ := by
  classical
    refine' ⟨s.filter (· ∈ t₁), s.filter (· ∉ t₁), _, _, _⟩
    · simp [filter_union_right, em]
    · intro x
      simp
    · intro x
      simp only [not_not, coe_filter, Set.mem_setOf_eq, Set.mem_diff, and_imp]
      intro hx hx₂
      

Proof state:
case refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
t₁ t₂ : Set α
h : ↑s ⊆ t₁ ∪ t₂
x : α
hx : x ∈ s
hx₂ : x ∉ t₁
⊢ x ∈ t₂ ∧ x ∉ t₁

Next tactic:
refine' ⟨Or.resolve_left (h hx) hx₂, hx₂⟩
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
⊢ filter (Eq b) s = if b ∈ s then {b} else ∅

Next tactic:
split_ifs with h
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∈ s
⊢ filter (Eq b) s = {b}

Next tactic:
ext
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    

Proof state:
case pos.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∈ s
a✝ : β
⊢ a✝ ∈ filter (Eq b) s ↔ a✝ ∈ {b}

Next tactic:
simp only [mem_filter, mem_singleton, decide_eq_true_eq]
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    

Proof state:
case pos.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∈ s
a✝ : β
⊢ a✝ ∈ s ∧ b = a✝ ↔ a✝ = b

Next tactic:
refine ⟨fun h => h.2.symm, ?_⟩
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    refine ⟨fun h => h.2.symm, ?_⟩
    

Proof state:
case pos.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∈ s
a✝ : β
⊢ a✝ = b → a✝ ∈ s ∧ b = a✝

Next tactic:
rintro rfl
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    refine ⟨fun h => h.2.symm, ?_⟩
    rintro rfl
    

Proof state:
case pos.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
a✝ : β
h : a✝ ∈ s
⊢ a✝ ∈ s ∧ a✝ = a✝

Next tactic:
exact ⟨h, rfl⟩
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    refine ⟨fun h => h.2.symm, ?_⟩
    rintro rfl
    exact ⟨h, rfl⟩
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∉ s
⊢ filter (Eq b) s = ∅

Next tactic:
ext
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    refine ⟨fun h => h.2.symm, ?_⟩
    rintro rfl
    exact ⟨h, rfl⟩
  · ext
    

Proof state:
case neg.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∉ s
a✝ : β
⊢ a✝ ∈ filter (Eq b) s ↔ a✝ ∈ ∅

Next tactic:
simp only [mem_filter, not_and, iff_false_iff, not_mem_empty, decide_eq_true_eq]
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    refine ⟨fun h => h.2.symm, ?_⟩
    rintro rfl
    exact ⟨h, rfl⟩
  · ext
    simp only [mem_filter, not_and, iff_false_iff, not_mem_empty, decide_eq_true_eq]
    

Proof state:
case neg.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∉ s
a✝ : β
⊢ a✝ ∈ s → ¬b = a✝

Next tactic:
rintro m rfl
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq'` with the equality the other way.
-/
theorem filter_eq [DecidableEq β] (s : Finset β) (b : β) :
    s.filter (Eq b) = ite (b ∈ s) {b} ∅ := by
  split_ifs with h
  · ext
    simp only [mem_filter, mem_singleton, decide_eq_true_eq]
    refine ⟨fun h => h.2.symm, ?_⟩
    rintro rfl
    exact ⟨h, rfl⟩
  · ext
    simp only [mem_filter, not_and, iff_false_iff, not_mem_empty, decide_eq_true_eq]
    rintro m rfl
    

Proof state:
case neg.a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
h : b ∉ s
m : b ∈ s
⊢ False

Next tactic:
exact h m
/-- After filtering out everything that does not equal a given value, at most that value remains.

  This is equivalent to `filter_eq` with the equality the other way.
-/
theorem filter_eq' [DecidableEq β] (s : Finset β) (b : β) :
    (s.filter fun a => a = b) = ite (b ∈ s) {b} ∅ :=
  _root_.trans (filter_congr fun _ _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b x✝¹ : β
x✝ : x✝¹ ∈ s
⊢ x✝¹ = b ↔ b = x✝¹

Next tactic:
simp_rw [@eq_comm _ b]
theorem filter_ne [DecidableEq β] (s : Finset β) (b : β) :
    (s.filter fun a => b ≠ a) = s.erase b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b : β
⊢ filter (fun a => b ≠ a) s = erase s b

Next tactic:
ext
theorem filter_ne [DecidableEq β] (s : Finset β) (b : β) :
    (s.filter fun a => b ≠ a) = s.erase b := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b a✝ : β
⊢ a✝ ∈ filter (fun a => b ≠ a) s ↔ a✝ ∈ erase s b

Next tactic:
simp only [mem_filter, mem_erase, Ne.def, decide_not, Bool.not_eq_true', decide_eq_false_iff_not]
theorem filter_ne [DecidableEq β] (s : Finset β) (b : β) :
    (s.filter fun a => b ≠ a) = s.erase b := by
  ext
  simp only [mem_filter, mem_erase, Ne.def, decide_not, Bool.not_eq_true', decide_eq_false_iff_not]
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b a✝ : β
⊢ a✝ ∈ s ∧ ¬b = a✝ ↔ ¬a✝ = b ∧ a✝ ∈ s

Next tactic:
tauto
theorem filter_ne' [DecidableEq β] (s : Finset β) (b : β) : (s.filter fun a => a ≠ b) = s.erase b :=
  _root_.trans (filter_congr fun _ _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝³ : DecidablePred p
inst✝² : DecidablePred q
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset β
b x✝¹ : β
x✝ : x✝¹ ∈ s
⊢ x✝¹ ≠ b ↔ b ≠ x✝¹

Next tactic:
simp_rw [@ne_comm _ b]
theorem filter_inter_filter_neg_eq (s t : Finset α) :
    (s.filter p ∩ t.filter fun a => ¬p a) = ∅ :=
  by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝² : DecidablePred p
inst✝¹ : DecidablePred q
s✝ : Finset α
inst✝ : DecidableEq α
s t : Finset α
⊢ filter p s ∩ filter (fun a => ¬p a) t = ∅

Next tactic:
simpa using (disjoint_filter_filter_neg s t p).eq_bot
@[simp]
theorem range_eq_empty_iff : range n = ∅ ↔ n = 0 := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
n m l : ℕ
⊢ range n = ∅ ↔ n = 0

Next tactic:
rw [← not_nonempty_iff_eq_empty, nonempty_range_iff, not_not]
@[simp]
theorem range_filter_eq {n m : ℕ} : (range n).filter (· = m) = if m < n then {m} else ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
n✝ m✝ l n m : ℕ
⊢ filter (fun x => x = m) (range n) = if m < n then {m} else ∅

Next tactic:
convert filter_eq (range n) m using 2
@[simp]
theorem range_filter_eq {n m : ℕ} : (range n).filter (· = m) = if m < n then {m} else ∅ := by
  convert filter_eq (range n) m using 2
  · 

Proof state:
case h.e'_2.h.e'_2
α : Type u_1
β : Type u_2
γ : Type u_3
n✝ m✝ l n m : ℕ
⊢ (fun x => x = m) = Eq m

Next tactic:
ext
@[simp]
theorem range_filter_eq {n m : ℕ} : (range n).filter (· = m) = if m < n then {m} else ∅ := by
  convert filter_eq (range n) m using 2
  · ext
    

Proof state:
case h.e'_2.h.e'_2.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
n✝ m✝ l n m x✝ : ℕ
⊢ x✝ = m ↔ m = x✝

Next tactic:
rw [eq_comm]
@[simp]
theorem range_filter_eq {n m : ℕ} : (range n).filter (· = m) = if m < n then {m} else ∅ := by
  convert filter_eq (range n) m using 2
  · ext
    rw [eq_comm]
  · 

Proof state:
case h.e'_3.h₁.a
α : Type u_1
β : Type u_2
γ : Type u_3
n✝ m✝ l n m : ℕ
⊢ m < n ↔ m ∈ range n

Next tactic:
simp
lemma range_nontrivial {n : ℕ} (hn : 1 < n) : (Finset.range n).Nontrivial := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
n✝ m l n : ℕ
hn : 1 < n
⊢ Finset.Nontrivial (range n)

Next tactic:
rw [Finset.Nontrivial, Finset.coe_range]
lemma range_nontrivial {n : ℕ} (hn : 1 < n) : (Finset.range n).Nontrivial := by
  rw [Finset.Nontrivial, Finset.coe_range]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
n✝ m l n : ℕ
hn : 1 < n
⊢ Set.Nontrivial (Set.Iio n)

Next tactic:
exact ⟨0, zero_lt_one.trans hn, 1, hn, zero_ne_one⟩
theorem exists_mem_empty_iff (p : α → Prop) : (∃ x, x ∈ (∅ : Finset α) ∧ p x) ↔ False := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
⊢ (∃ x ∈ ∅, p x) ↔ False

Next tactic:
simp only [not_mem_empty, false_and_iff, exists_false]
theorem exists_mem_insert [DecidableEq α] (a : α) (s : Finset α) (p : α → Prop) :
    (∃ x, x ∈ insert a s ∧ p x) ↔ p a ∨ ∃ x, x ∈ s ∧ p x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
a : α
s : Finset α
p : α → Prop
⊢ (∃ x ∈ insert a s, p x) ↔ p a ∨ ∃ x ∈ s, p x

Next tactic:
simp only [mem_insert, or_and_right, exists_or, exists_eq_left]
theorem forall_mem_insert [DecidableEq α] (a : α) (s : Finset α) (p : α → Prop) :
    (∀ x, x ∈ insert a s → p x) ↔ p a ∧ ∀ x, x ∈ s → p x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
a : α
s : Finset α
p : α → Prop
⊢ (∀ x ∈ insert a s, p x) ↔ p a ∧ ∀ x ∈ s, p x

Next tactic:
simp only [mem_insert, or_imp, forall_and, forall_eq]
/-- Equivalence between the set of natural numbers which are `≥ k` and `ℕ`, given by `n → n - k`. -/
def notMemRangeEquiv (k : ℕ) : { n // n ∉ range k } ≃ ℕ where
  toFun i := i.1 - k
  invFun j := ⟨j + k, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
k j : ℕ
⊢ j + k ∉ range k

Next tactic:
simp
/-- Equivalence between the set of natural numbers which are `≥ k` and `ℕ`, given by `n → n - k`. -/
def notMemRangeEquiv (k : ℕ) : { n // n ∉ range k } ≃ ℕ where
  toFun i := i.1 - k
  invFun j := ⟨j + k, by simp⟩
  left_inv j := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
k : ℕ
j : { n // n ∉ range k }
⊢ (fun j => { val := j + k, property := (_ : j + k ∉ range k) }) ((fun i => ↑i - k) j) = j

Next tactic:
rw [Subtype.ext_iff_val]
/-- Equivalence between the set of natural numbers which are `≥ k` and `ℕ`, given by `n → n - k`. -/
def notMemRangeEquiv (k : ℕ) : { n // n ∉ range k } ≃ ℕ where
  toFun i := i.1 - k
  invFun j := ⟨j + k, by simp⟩
  left_inv j := by
    rw [Subtype.ext_iff_val]
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
k : ℕ
j : { n // n ∉ range k }
⊢ ↑((fun j => { val := j + k, property := (_ : j + k ∉ range k) }) ((fun i => ↑i - k) j)) = ↑j

Next tactic:
apply tsub_add_cancel_of_le
/-- Equivalence between the set of natural numbers which are `≥ k` and `ℕ`, given by `n → n - k`. -/
def notMemRangeEquiv (k : ℕ) : { n // n ∉ range k } ≃ ℕ where
  toFun i := i.1 - k
  invFun j := ⟨j + k, by simp⟩
  left_inv j := by
    rw [Subtype.ext_iff_val]
    apply tsub_add_cancel_of_le
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
k : ℕ
j : { n // n ∉ range k }
⊢ k ≤ ↑j

Next tactic:
simpa using j.2
@[simp]
theorem coe_notMemRangeEquiv_symm (k : ℕ) :
    ((notMemRangeEquiv k).symm : ℕ → { n // n ∉ range k }) = fun j => ⟨j + k, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
k j : ℕ
⊢ j + k ∉ range k

Next tactic:
simp
theorem Nodup.toFinset_inj {l l' : Multiset α} (hl : Nodup l) (hl' : Nodup l')
    (h : l.toFinset = l'.toFinset) : l = l' := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t l l' : Multiset α
hl : Nodup l
hl' : Nodup l'
h : toFinset l = toFinset l'
⊢ l = l'

Next tactic:
simpa [← toFinset_eq hl, ← toFinset_eq hl'] using h
@[simp]
theorem toFinset_singleton (a : α) : toFinset ({a} : Multiset α) = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
a : α
⊢ toFinset {a} = {a}

Next tactic:
rw [← cons_zero, toFinset_cons, toFinset_zero, IsLawfulSingleton.insert_emptyc_eq]
@[simp]
theorem toFinset_add (s t : Multiset α) : toFinset (s + t) = toFinset s ∪ toFinset t :=
  Finset.ext <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ t✝ s t : Multiset α
⊢ ∀ (a : α), a ∈ toFinset (s + t) ↔ a ∈ toFinset s ∪ toFinset t

Next tactic:
simp
@[simp]
theorem toFinset_nsmul (s : Multiset α) : ∀ n ≠ 0, (n • s).toFinset = s.toFinset
  | 0, h => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ t s : Multiset α
h : 0 ≠ 0
⊢ toFinset (0 • s) = toFinset s

Next tactic:
contradiction
@[simp]
theorem toFinset_nsmul (s : Multiset α) : ∀ n ≠ 0, (n • s).toFinset = s.toFinset
  | 0, h => by contradiction
  | n + 1, _ => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ t s : Multiset α
n : ℕ
x✝ : n + 1 ≠ 0
⊢ toFinset ((n + 1) • s) = toFinset s

Next tactic:
by_cases h : n = 0
@[simp]
theorem toFinset_nsmul (s : Multiset α) : ∀ n ≠ 0, (n • s).toFinset = s.toFinset
  | 0, h => by contradiction
  | n + 1, _ => by
    by_cases h : n = 0
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ t s : Multiset α
n : ℕ
x✝ : n + 1 ≠ 0
h : n = 0
⊢ toFinset ((n + 1) • s) = toFinset s

Next tactic:
rw [h, zero_add, one_nsmul]