l3lab/ntp-mathlib huggingface dataset:
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t : Multiset α
a b : α
⊢ ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u

Next tactic:
refine @(Multiset.induction_on t ?_ fun a t IH => ?_)
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> 

Proof state:
case refine_1
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t : Multiset α
a b : α
⊢ ∀ {s u : Multiset α}, s ≤ 0 → s ≤ u → s ≤ 0 ∩ u

Next tactic:
intros s u h₁ h₂
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> 

Proof state:
case refine_2
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t✝ : Multiset α
a✝ b a : α
t : Multiset α
IH : ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u
⊢ ∀ {s u : Multiset α}, s ≤ a ::ₘ t → s ≤ u → s ≤ (a ::ₘ t) ∩ u

Next tactic:
intros s u h₁ h₂
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> intros s u h₁ h₂
  · 

Proof state:
case refine_1
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t : Multiset α
a b : α
s u : Multiset α
h₁ : s ≤ 0
h₂ : s ≤ u
⊢ s ≤ 0 ∩ u

Next tactic:
simpa only [zero_inter, nonpos_iff_eq_zero] using h₁
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> intros s u h₁ h₂
  · simpa only [zero_inter, nonpos_iff_eq_zero] using h₁
  

Proof state:
case refine_2
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t✝ : Multiset α
a✝ b a : α
t : Multiset α
IH : ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u
s u : Multiset α
h₁ : s ≤ a ::ₘ t
h₂ : s ≤ u
⊢ s ≤ (a ::ₘ t) ∩ u

Next tactic:
by_cases h : a ∈ u
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> intros s u h₁ h₂
  · simpa only [zero_inter, nonpos_iff_eq_zero] using h₁
  by_cases h : a ∈ u
  · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t✝ : Multiset α
a✝ b a : α
t : Multiset α
IH : ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u
s u : Multiset α
h₁ : s ≤ a ::ₘ t
h₂ : s ≤ u
h : a ∈ u
⊢ s ≤ (a ::ₘ t) ∩ u

Next tactic:
rw [cons_inter_of_pos _ h, ← erase_le_iff_le_cons]
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> intros s u h₁ h₂
  · simpa only [zero_inter, nonpos_iff_eq_zero] using h₁
  by_cases h : a ∈ u
  · rw [cons_inter_of_pos _ h, ← erase_le_iff_le_cons]
    

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t✝ : Multiset α
a✝ b a : α
t : Multiset α
IH : ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u
s u : Multiset α
h₁ : s ≤ a ::ₘ t
h₂ : s ≤ u
h : a ∈ u
⊢ erase s a ≤ t ∩ erase u a

Next tactic:
exact IH (erase_le_iff_le_cons.2 h₁) (erase_le_erase _ h₂)
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> intros s u h₁ h₂
  · simpa only [zero_inter, nonpos_iff_eq_zero] using h₁
  by_cases h : a ∈ u
  · rw [cons_inter_of_pos _ h, ← erase_le_iff_le_cons]
    exact IH (erase_le_iff_le_cons.2 h₁) (erase_le_erase _ h₂)
  · 

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t✝ : Multiset α
a✝ b a : α
t : Multiset α
IH : ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u
s u : Multiset α
h₁ : s ≤ a ::ₘ t
h₂ : s ≤ u
h : a ∉ u
⊢ s ≤ (a ::ₘ t) ∩ u

Next tactic:
rw [cons_inter_of_neg _ h]
theorem le_inter (h₁ : s ≤ t) (h₂ : s ≤ u) : s ≤ t ∩ u := by
  revert s u; refine @(Multiset.induction_on t ?_ fun a t IH => ?_) <;> intros s u h₁ h₂
  · simpa only [zero_inter, nonpos_iff_eq_zero] using h₁
  by_cases h : a ∈ u
  · rw [cons_inter_of_pos _ h, ← erase_le_iff_le_cons]
    exact IH (erase_le_iff_le_cons.2 h₁) (erase_le_erase _ h₂)
  · rw [cons_inter_of_neg _ h]
    

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
t✝ : Multiset α
a✝ b a : α
t : Multiset α
IH : ∀ {s u : Multiset α}, s ≤ t → s ≤ u → s ≤ t ∩ u
s u : Multiset α
h₁ : s ≤ a ::ₘ t
h₂ : s ≤ u
h : a ∉ u
⊢ s ≤ t ∩ u

Next tactic:
exact IH ((le_cons_of_not_mem <| mt (mem_of_le h₂) h).1 h₁) h₂
@[simp]
theorem mem_inter : a ∈ s ∩ t ↔ a ∈ s ∧ a ∈ t :=
  ⟨fun h => ⟨mem_of_le (inter_le_left _ _) h, mem_of_le (inter_le_right _ _) h⟩, fun ⟨h₁, h₂⟩ => by
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s t u : Multiset α
a b : α
x✝ : a ∈ s ∧ a ∈ t
h₁ : a ∈ s
h₂ : a ∈ t
⊢ a ∈ s ∩ t

Next tactic:
rw [← cons_erase h₁, cons_inter_of_pos _ h₂]
@[simp]
theorem mem_inter : a ∈ s ∩ t ↔ a ∈ s ∧ a ∈ t :=
  ⟨fun h => ⟨mem_of_le (inter_le_left _ _) h, mem_of_le (inter_le_right _ _) h⟩, fun ⟨h₁, h₂⟩ => by
    rw [← cons_erase h₁, cons_inter_of_pos _ h₂]; 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s t u : Multiset α
a b : α
x✝ : a ∈ s ∧ a ∈ t
h₁ : a ∈ s
h₂ : a ∈ t
⊢ a ∈ a ::ₘ erase s a ∩ erase t a

Next tactic:
apply mem_cons_self
theorem eq_union_right (h : s ≤ t) : s ∪ t = t := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s t u : Multiset α
a b : α
h : s ≤ t
⊢ s ∪ t = t

Next tactic:
rw [union_comm, eq_union_left h]
theorem union_add_distrib (s t u : Multiset α) : s ∪ t + u = s + u ∪ (t + u) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a b : α
s t u : Multiset α
⊢ s ∪ t + u = s + u ∪ (t + u)

Next tactic:
simpa [(· ∪ ·), union, eq_comm, add_assoc] using
    show s + u - (t + u) = s - t by rw [add_comm t, tsub_add_eq_tsub_tsub, add_tsub_cancel_right]
theorem union_add_distrib (s t u : Multiset α) : s ∪ t + u = s + u ∪ (t + u) := by
  simpa [(· ∪ ·), union, eq_comm, add_assoc] using
    show s + u - (t + u) = s - t by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a b : α
s t u : Multiset α
⊢ s + u - (t + u) = s - t

Next tactic:
rw [add_comm t, tsub_add_eq_tsub_tsub, add_tsub_cancel_right]
theorem add_union_distrib (s t u : Multiset α) : s + (t ∪ u) = s + t ∪ (s + u) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a b : α
s t u : Multiset α
⊢ s + (t ∪ u) = s + t ∪ (s + u)

Next tactic:
rw [add_comm, union_add_distrib, add_comm s, add_comm s]
theorem cons_union_distrib (a : α) (s t : Multiset α) : a ::ₘ (s ∪ t) = a ::ₘ s ∪ a ::ₘ t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a✝ b a : α
s t : Multiset α
⊢ a ::ₘ (s ∪ t) = a ::ₘ s ∪ a ::ₘ t

Next tactic:
simpa using add_union_distrib (a ::ₘ 0) s t
theorem inter_add_distrib (s t u : Multiset α) : s ∩ t + u = (s + u) ∩ (t + u) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a b : α
s t u : Multiset α
⊢ s ∩ t + u = (s + u) ∩ (t + u)

Next tactic:
by_contra h
theorem inter_add_distrib (s t u : Multiset α) : s ∩ t + u = (s + u) ∩ (t + u) := by
  by_contra h
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a b : α
s t u : Multiset α
h : ¬s ∩ t + u = (s + u) ∩ (t + u)
⊢ False

Next tactic:
cases'
    lt_iff_cons_le.1
      (lt_of_le_of_ne
        (le_inter (add_le_add_right (inter_le_left s t) u)
          (add_le_add_right (inter_le_right s t) u))
        h) with
    a hl
theorem inter_add_distrib (s t u : Multiset α) : s ∩ t + u = (s + u) ∩ (t + u) := by
  by_contra h
  cases'
    lt_iff_cons_le.1
      (lt_of_le_of_ne
        (le_inter (add_le_add_right (inter_le_left s t) u)
          (add_le_add_right (inter_le_right s t) u))
        h) with
    a hl
  

Proof state:
case intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a✝ b : α
s t u : Multiset α
h : ¬s ∩ t + u = (s + u) ∩ (t + u)
a : α
hl : a ::ₘ (s ∩ t + u) ≤ (s + u) ∩ (t + u)
⊢ False

Next tactic:
rw [← cons_add] at hl
theorem inter_add_distrib (s t u : Multiset α) : s ∩ t + u = (s + u) ∩ (t + u) := by
  by_contra h
  cases'
    lt_iff_cons_le.1
      (lt_of_le_of_ne
        (le_inter (add_le_add_right (inter_le_left s t) u)
          (add_le_add_right (inter_le_right s t) u))
        h) with
    a hl
  rw [← cons_add] at hl
  

Proof state:
case intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a✝ b : α
s t u : Multiset α
h : ¬s ∩ t + u = (s + u) ∩ (t + u)
a : α
hl : a ::ₘ s ∩ t + u ≤ (s + u) ∩ (t + u)
⊢ False

Next tactic:
exact
    not_le_of_lt (lt_cons_self (s ∩ t) a)
      (le_inter (le_of_add_le_add_right (le_trans hl (inter_le_left _ _)))
        (le_of_add_le_add_right (le_trans hl (inter_le_right _ _))))
theorem add_inter_distrib (s t u : Multiset α) : s + t ∩ u = (s + t) ∩ (s + u) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u✝ : Multiset α
a b : α
s t u : Multiset α
⊢ s + t ∩ u = (s + t) ∩ (s + u)

Next tactic:
rw [add_comm, inter_add_distrib, add_comm s, add_comm s]
theorem cons_inter_distrib (a : α) (s t : Multiset α) : a ::ₘ s ∩ t = (a ::ₘ s) ∩ (a ::ₘ t) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a✝ b a : α
s t : Multiset α
⊢ a ::ₘ s ∩ t = (a ::ₘ s) ∩ (a ::ₘ t)

Next tactic:
simp
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s ∪ t + s ∩ t = s + t

Next tactic:
apply _root_.le_antisymm
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · 

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s ∪ t + s ∩ t ≤ s + t

Next tactic:
rw [union_add_distrib]
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s + s ∩ t ∪ (t + s ∩ t) ≤ s + t

Next tactic:
refine' union_le (add_le_add_left (inter_le_right _ _) _) _
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    refine' union_le (add_le_add_left (inter_le_right _ _) _) _
    

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ t + s ∩ t ≤ s + t

Next tactic:
rw [add_comm]
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    refine' union_le (add_le_add_left (inter_le_right _ _) _) _
    rw [add_comm]
    

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s ∩ t + t ≤ s + t

Next tactic:
exact add_le_add_right (inter_le_left _ _) _
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    refine' union_le (add_le_add_left (inter_le_right _ _) _) _
    rw [add_comm]
    exact add_le_add_right (inter_le_left _ _) _
  · 

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s + t ≤ s ∪ t + s ∩ t

Next tactic:
rw [add_comm, add_inter_distrib]
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    refine' union_le (add_le_add_left (inter_le_right _ _) _) _
    rw [add_comm]
    exact add_le_add_right (inter_le_left _ _) _
  · rw [add_comm, add_inter_distrib]
    

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ t + s ≤ (s ∪ t + s) ∩ (s ∪ t + t)

Next tactic:
refine' le_inter (add_le_add_right (le_union_right _ _) _) _
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    refine' union_le (add_le_add_left (inter_le_right _ _) _) _
    rw [add_comm]
    exact add_le_add_right (inter_le_left _ _) _
  · rw [add_comm, add_inter_distrib]
    refine' le_inter (add_le_add_right (le_union_right _ _) _) _
    

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ t + s ≤ s ∪ t + t

Next tactic:
rw [add_comm]
theorem union_add_inter (s t : Multiset α) : s ∪ t + s ∩ t = s + t := by
  apply _root_.le_antisymm
  · rw [union_add_distrib]
    refine' union_le (add_le_add_left (inter_le_right _ _) _) _
    rw [add_comm]
    exact add_le_add_right (inter_le_left _ _) _
  · rw [add_comm, add_inter_distrib]
    refine' le_inter (add_le_add_right (le_union_right _ _) _) _
    rw [add_comm]
    

Proof state:
case a
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s + t ≤ s ∪ t + t

Next tactic:
exact add_le_add_right (le_union_left _ _) _
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s - t + s ∩ t = s

Next tactic:
rw [inter_comm]
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  rw [inter_comm]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s - t + t ∩ s = s

Next tactic:
revert s
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  rw [inter_comm]
  revert s; 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s t✝ u : Multiset α
a b : α
t : Multiset α
⊢ ∀ (s : Multiset α), s - t + t ∩ s = s

Next tactic:
refine' Multiset.induction_on t (by simp) fun a t IH s => _
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  rw [inter_comm]
  revert s; refine' Multiset.induction_on t (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s t✝ u : Multiset α
a b : α
t : Multiset α
⊢ ∀ (s : Multiset α), s - 0 + 0 ∩ s = s

Next tactic:
simp
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  rw [inter_comm]
  revert s; refine' Multiset.induction_on t (by simp) fun a t IH s => _
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝¹ u : Multiset α
a✝ b : α
t✝ : Multiset α
a : α
t : Multiset α
IH : ∀ (s : Multiset α), s - t + t ∩ s = s
s : Multiset α
⊢ s - a ::ₘ t + (a ::ₘ t) ∩ s = s

Next tactic:
by_cases h : a ∈ s
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  rw [inter_comm]
  revert s; refine' Multiset.induction_on t (by simp) fun a t IH s => _
  by_cases h : a ∈ s
  · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝¹ u : Multiset α
a✝ b : α
t✝ : Multiset α
a : α
t : Multiset α
IH : ∀ (s : Multiset α), s - t + t ∩ s = s
s : Multiset α
h : a ∈ s
⊢ s - a ::ₘ t + (a ::ₘ t) ∩ s = s

Next tactic:
rw [cons_inter_of_pos _ h, sub_cons, add_cons, IH, cons_erase h]
theorem sub_add_inter (s t : Multiset α) : s - t + s ∩ t = s := by
  rw [inter_comm]
  revert s; refine' Multiset.induction_on t (by simp) fun a t IH s => _
  by_cases h : a ∈ s
  · rw [cons_inter_of_pos _ h, sub_cons, add_cons, IH, cons_erase h]
  · 

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝¹ u : Multiset α
a✝ b : α
t✝ : Multiset α
a : α
t : Multiset α
IH : ∀ (s : Multiset α), s - t + t ∩ s = s
s : Multiset α
h : a ∉ s
⊢ s - a ::ₘ t + (a ::ₘ t) ∩ s = s

Next tactic:
rw [cons_inter_of_neg _ h, sub_cons, erase_of_not_mem h, IH]
theorem sub_inter (s t : Multiset α) : s - s ∩ t = s - t :=
  add_right_cancel <| by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ u : Multiset α
a b : α
s t : Multiset α
⊢ s - s ∩ t + ?m.196429 s t = s - t + ?m.196429 s t

Next tactic:
rw [sub_add_inter s t, tsub_add_cancel_of_le (inter_le_left s t)]
theorem filter_congr {p q : α → Prop} [DecidablePred p] [DecidablePred q] {s : Multiset α} :
    (∀ x ∈ s, p x ↔ q x) → filter p s = filter q s :=
  Quot.inductionOn s fun _l h => congr_arg ofList <| filter_congr' $ by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p✝ : α → Prop
inst✝² : DecidablePred p✝
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Multiset α
_l : List α
h : ∀ x ∈ Quot.mk Setoid.r _l, p x ↔ q x
⊢ ∀ x ∈ _l, decide (p x) = true ↔ decide (q x) = true

Next tactic:
simpa using h
theorem monotone_filter_right (s : Multiset α) ⦃p q : α → Prop⦄ [DecidablePred p] [DecidablePred q]
    (h : ∀ b, p b → q b) :
    s.filter p ≤ s.filter q :=
  Quotient.inductionOn s fun l => (l.monotone_filter_right $ by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p✝ : α → Prop
inst✝² : DecidablePred p✝
s : Multiset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
h : ∀ (b : α), p b → q b
l : List α
⊢ ∀ (a : α), decide (p a) = true → decide (q a) = true

Next tactic:
simpa using h
@[simp]
theorem filter_cons_of_pos {a : α} (s) : p a → filter p (a ::ₘ s) = a ::ₘ filter p s :=
  Quot.inductionOn s fun l h => congr_arg ofList <| List.filter_cons_of_pos l $ by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
a : α
s : Multiset α
l : List α
h : p a
⊢ decide (p a) = true

Next tactic:
simpa using h
@[simp]
theorem filter_cons_of_neg {a : α} (s) : ¬p a → filter p (a ::ₘ s) = filter p s :=
  Quot.inductionOn s fun l h => congr_arg ofList <| List.filter_cons_of_neg l $ by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
a : α
s : Multiset α
l : List α
h : ¬p a
⊢ ¬decide (p a) = true

Next tactic:
simpa using h
@[simp]
theorem mem_filter {a : α} {s} : a ∈ filter p s ↔ a ∈ s ∧ p a :=
  Quot.inductionOn s fun _l => by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
a : α
s : Multiset α
_l : List α
⊢ a ∈ filter p (Quot.mk Setoid.r _l) ↔ a ∈ Quot.mk Setoid.r _l ∧ p a

Next tactic:
simpa using List.mem_filter (p := (p ·))
theorem filter_eq_self {s} : filter p s = s ↔ ∀ a ∈ s, p a :=
  Quot.inductionOn s fun _l =>
    Iff.trans ⟨fun h => (filter_sublist _).eq_of_length (@congr_arg _ _ _ _ card h),
      congr_arg ofList⟩ $
      by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
_l : List α
⊢ List.filter (fun b => decide (p b)) _l = _l ↔ ∀ a ∈ Quot.mk Setoid.r _l, p a

Next tactic:
simpa using List.filter_eq_self (p := (p ·))
theorem filter_eq_nil {s} : filter p s = 0 ↔ ∀ a ∈ s, ¬p a :=
  Quot.inductionOn s fun _l =>
    Iff.trans ⟨fun h => eq_nil_of_length_eq_zero (@congr_arg _ _ _ _ card h), congr_arg ofList⟩ $
      by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
_l : List α
⊢ List.filter (fun b => decide (p b)) _l = [] ↔ ∀ a ∈ Quot.mk Setoid.r _l, ¬p a

Next tactic:
simpa using List.filter_eq_nil (p := (p ·))
theorem filter_cons {a : α} (s : Multiset α) :
    filter p (a ::ₘ s) = (if p a then {a} else 0) + filter p s := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
a : α
s : Multiset α
⊢ filter p (a ::ₘ s) = (if p a then {a} else 0) + filter p s

Next tactic:
split_ifs with h
theorem filter_cons {a : α} (s : Multiset α) :
    filter p (a ::ₘ s) = (if p a then {a} else 0) + filter p s := by
  split_ifs with h
  · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
a : α
s : Multiset α
h : p a
⊢ filter p (a ::ₘ s) = {a} + filter p s

Next tactic:
rw [filter_cons_of_pos _ h, singleton_add]
theorem filter_cons {a : α} (s : Multiset α) :
    filter p (a ::ₘ s) = (if p a then {a} else 0) + filter p s := by
  split_ifs with h
  · rw [filter_cons_of_pos _ h, singleton_add]
  · 

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
a : α
s : Multiset α
h : ¬p a
⊢ filter p (a ::ₘ s) = 0 + filter p s

Next tactic:
rw [filter_cons_of_neg _ h, zero_add]
theorem filter_singleton {a : α} (p : α → Prop) [DecidablePred p] :
    filter p {a} = if p a then {a} else ∅ := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p✝ : α → Prop
inst✝¹ : DecidablePred p✝
a : α
p : α → Prop
inst✝ : DecidablePred p
⊢ filter p {a} = if p a then {a} else ∅

Next tactic:
simp only [singleton, filter_cons, filter_zero, add_zero, empty_eq_zero]
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
⊢ filter p (n • s) = n • filter p s

Next tactic:
refine' s.induction_on _ _
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  refine' s.induction_on _ _
  · 

Proof state:
case refine'_1
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
⊢ filter p (n • 0) = n • filter p 0

Next tactic:
simp only [filter_zero, nsmul_zero]
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  refine' s.induction_on _ _
  · simp only [filter_zero, nsmul_zero]
  · 

Proof state:
case refine'_2
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
⊢ ∀ ⦃a : α⦄ {s : Multiset α}, filter p (n • s) = n • filter p s → filter p (n • (a ::ₘ s)) = n • filter p (a ::ₘ s)

Next tactic:
intro a ha ih
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  refine' s.induction_on _ _
  · simp only [filter_zero, nsmul_zero]
  · intro a ha ih
    

Proof state:
case refine'_2
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
a : α
ha : Multiset α
ih : filter p (n • ha) = n • filter p ha
⊢ filter p (n • (a ::ₘ ha)) = n • filter p (a ::ₘ ha)

Next tactic:
rw [nsmul_cons, filter_add, ih, filter_cons, nsmul_add]
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  refine' s.induction_on _ _
  · simp only [filter_zero, nsmul_zero]
  · intro a ha ih
    rw [nsmul_cons, filter_add, ih, filter_cons, nsmul_add]
    

Proof state:
case refine'_2
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
a : α
ha : Multiset α
ih : filter p (n • ha) = n • filter p ha
⊢ filter p (n • {a}) + n • filter p ha = (n • if p a then {a} else 0) + n • filter p ha

Next tactic:
congr
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  refine' s.induction_on _ _
  · simp only [filter_zero, nsmul_zero]
  · intro a ha ih
    rw [nsmul_cons, filter_add, ih, filter_cons, nsmul_add]
    congr
    

Proof state:
case refine'_2.e_a
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
a : α
ha : Multiset α
ih : filter p (n • ha) = n • filter p ha
⊢ filter p (n • {a}) = n • if p a then {a} else 0

Next tactic:
split_ifs with hp
theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by
  refine' s.induction_on _ _
  · simp only [filter_zero, nsmul_zero]
  · intro a ha ih
    rw [nsmul_cons, filter_add, ih, filter_cons, nsmul_add]
    congr
    split_ifs with hp <;>
      · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
p : α → Prop
inst✝ : DecidablePred p
s : Multiset α
n : ℕ
a : α
ha : Multiset α
ih : filter p (n • ha) = n • filter p ha
hp : p a
⊢ filter p (n • {a}) = n • {a}

Next tactic:
simp only [filter_eq_self, nsmul_zero, filter_eq_nil]