l3lab/ntp-mathlib huggingface dataset:
theorem piecewise_le_piecewise' {δ : α → Type*} [∀ i, Preorder (δ i)] {f g f' g' : ∀ i, δ i}
    (Hf : ∀ x ∈ s, f x ≤ f' x) (Hg : ∀ x ∉ s, g x ≤ g' x) :
    s.piecewise f g ≤ s.piecewise f' g' := fun x => by by_cases hx : x ∈ s <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ✝ : α → Sort u_4
s : Finset α
f✝ g✝ : (i : α) → δ✝ i
inst✝¹ : (j : α) → Decidable (j ∈ s)
δ : α → Type u_5
inst✝ : (i : α) → Preorder (δ i)
f g f' g' : (i : α) → δ i
Hf : ∀ x ∈ s, f x ≤ f' x
Hg : ∀ x ∉ s, g x ≤ g' x
x : α
hx : x ∉ s
⊢ piecewise s f g x ≤ piecewise s f' g' x

Next tactic:
simp [hx, *]
instance decidableExistsAndFinset {p : α → Prop} [_hp : ∀ (a), Decidable (p a)] :
    Decidable (∃ a ∈ s, p a) :=
  decidable_of_iff (∃ (a : _) (_ : a ∈ s), p a) (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
p : α → Prop
_hp : (a : α) → Decidable (p a)
⊢ (∃ a, ∃ (_ : a ∈ s), p a) ↔ ∃ a ∈ s, p a

Next tactic:
simp
theorem filter_filter (s : Finset α) : (s.filter p).filter q = s.filter fun a => p a ∧ q a :=
  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✝ s : Finset α
a : α
⊢ a ∈ filter q (filter p s) ↔ a ∈ filter (fun a => p a ∧ q a) s

Next tactic:
simp only [mem_filter, and_assoc, Bool.decide_and, Bool.decide_coe, Bool.and_eq_true]
theorem filter_comm (s : Finset α) : (s.filter p).filter q = (s.filter q).filter p := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ s : Finset α
⊢ filter q (filter p s) = filter p (filter q s)

Next tactic:
simp_rw [filter_filter, and_comm]
@[simp]
theorem filter_congr_decidable (s : Finset α) (p : α → Prop) (h : DecidablePred p)
    [DecidablePred p] : @filter α p h s = s.filter p := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q : α → Prop
inst✝² : DecidablePred p✝
inst✝¹ : DecidablePred q
s✝ s : Finset α
p : α → Prop
h inst✝ : DecidablePred p
⊢ filter p s = filter p s

Next tactic:
congr
theorem filter_True {h} (s : Finset α) : @filter _ (fun _ => True) h 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 α
h : DecidablePred fun x => True
s : Finset α
⊢ filter (fun x => True) s = s

Next tactic:
ext
theorem filter_True {h} (s : Finset α) : @filter _ (fun _ => True) h s = s := 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 α
h : DecidablePred fun x => True
s : Finset α
a✝ : α
⊢ a✝ ∈ filter (fun x => True) s ↔ a✝ ∈ s

Next tactic:
simp
theorem filter_False {h} (s : Finset α) : @filter _ (fun _ => False) h s = ∅ := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
h : DecidablePred fun x => False
s : Finset α
⊢ filter (fun x => False) s = ∅

Next tactic:
ext
theorem filter_False {h} (s : Finset α) : @filter _ (fun _ => False) h s = ∅ := 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 α
h : DecidablePred fun x => False
s : Finset α
a✝ : α
⊢ a✝ ∈ filter (fun x => False) s ↔ a✝ ∈ ∅

Next tactic:
simp
theorem filter_eq_self : s.filter p = s ↔ ∀ x ∈ s, p x := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
⊢ filter p s = s ↔ ∀ x ∈ s, p x

Next tactic:
simp [Finset.ext_iff]
theorem filter_eq_empty_iff : s.filter p = ∅ ↔ ∀ ⦃x⦄, x ∈ s → ¬p x := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
⊢ filter p s = ∅ ↔ ∀ ⦃x : α⦄, x ∈ s → ¬p x

Next tactic:
simp [Finset.ext_iff]
theorem filter_nonempty_iff : (s.filter p).Nonempty ↔ ∃ a ∈ s, 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 α
⊢ Finset.Nonempty (filter p s) ↔ ∃ a ∈ s, p a

Next tactic:
simp only [nonempty_iff_ne_empty, Ne.def, filter_eq_empty_iff, Classical.not_not, not_forall,
    exists_prop]
@[simp]
theorem filter_const (p : Prop) [Decidable p] (s : Finset α) :
    (s.filter fun _a => p) = if p then s else ∅ := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q : α → Prop
inst✝² : DecidablePred p✝
inst✝¹ : DecidablePred q
s✝ : Finset α
p : Prop
inst✝ : Decidable p
s : Finset α
⊢ filter (fun _a => p) s = if p then s else ∅

Next tactic:
split_ifs
@[simp]
theorem filter_const (p : Prop) [Decidable p] (s : Finset α) :
    (s.filter fun _a => p) = if p then s else ∅ := by split_ifs <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q : α → Prop
inst✝² : DecidablePred p✝
inst✝¹ : DecidablePred q
s✝ : Finset α
p : Prop
inst✝ : Decidable p
s : Finset α
h✝ : p
⊢ filter (fun _a => p) s = s

Next tactic:
simp [*]
@[simp]
theorem filter_const (p : Prop) [Decidable p] (s : Finset α) :
    (s.filter fun _a => p) = if p then s else ∅ := by split_ifs <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q : α → Prop
inst✝² : DecidablePred p✝
inst✝¹ : DecidablePred q
s✝ : Finset α
p : Prop
inst✝ : Decidable p
s : Finset α
h✝ : ¬p
⊢ filter (fun _a => p) s = ∅

Next tactic:
simp [*]
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  

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

Next tactic:
classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    split_ifs with h <;> by_cases h' : x = a <;> simp [h, h']
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    

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

Next tactic:
ext x
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    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 α
a x : α
⊢ x ∈ filter p {a} ↔ x ∈ if p a then {a} else ∅

Next tactic:
simp only [mem_singleton, forall_eq, mem_filter]
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
a x : α
⊢ x = a ∧ p x ↔ x ∈ if p a then {a} else ∅

Next tactic:
split_ifs with h
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    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 α
a x : α
h : p a
⊢ x = a ∧ p x ↔ x ∈ {a}

Next tactic:
by_cases h' : x = a
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    split_ifs with h <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
a x : α
h : ¬p a
⊢ x = a ∧ p x ↔ x ∈ ∅

Next tactic:
by_cases h' : x = a
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    split_ifs with h <;> by_cases h' : x = a <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
a x : α
h : p a
h' : x = a
⊢ x = a ∧ p x ↔ x ∈ {a}

Next tactic:
simp [h, h']
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    split_ifs with h <;> by_cases h' : x = a <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
a x : α
h : p a
h' : ¬x = a
⊢ x = a ∧ p x ↔ x ∈ {a}

Next tactic:
simp [h, h']
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    split_ifs with h <;> by_cases h' : x = a <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
a x : α
h : ¬p a
h' : x = a
⊢ x = a ∧ p x ↔ x ∈ ∅

Next tactic:
simp [h, h']
theorem filter_singleton (a : α) : filter p (singleton a) = if p a then singleton a else ∅ := by
  classical
    ext x
    simp only [mem_singleton, forall_eq, mem_filter]
    split_ifs with h <;> by_cases h' : x = a <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s : Finset α
a x : α
h : ¬p a
h' : ¬x = a
⊢ x = a ∧ p x ↔ x ∈ ∅

Next tactic:
simp [h, h']
theorem disjoint_filter {s : Finset α} {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
    Disjoint (s.filter p) (s.filter q) ↔ ∀ x ∈ s, p x → ¬q x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ _root_.Disjoint (filter p s) (filter q s) ↔ ∀ x ∈ s, p x → ¬q x

Next tactic:
constructor
theorem disjoint_filter {s : Finset α} {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
    Disjoint (s.filter p) (s.filter q) ↔ ∀ x ∈ s, p x → ¬q x := by
  constructor <;> 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ _root_.Disjoint (filter p s) (filter q s) → ∀ x ∈ s, p x → ¬q x

Next tactic:
simp (config := { contextual := true }) [disjoint_left]
theorem disjoint_filter {s : Finset α} {p q : α → Prop} [DecidablePred p] [DecidablePred q] :
    Disjoint (s.filter p) (s.filter q) ↔ ∀ x ∈ s, p x → ¬q x := by
  constructor <;> 

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ (∀ x ∈ s, p x → ¬q x) → _root_.Disjoint (filter p s) (filter q s)

Next tactic:
simp (config := { contextual := true }) [disjoint_left]
theorem disjoint_filter_filter' (s t : Finset α)
    {p q : α → Prop} [DecidablePred p] [DecidablePred q] (h : Disjoint p q) :
    Disjoint (s.filter p) (t.filter q) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s t : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
h : _root_.Disjoint p q
⊢ _root_.Disjoint (filter p s) (filter q t)

Next tactic:
simp_rw [disjoint_left, mem_filter]
theorem disjoint_filter_filter' (s t : Finset α)
    {p q : α → Prop} [DecidablePred p] [DecidablePred q] (h : Disjoint p q) :
    Disjoint (s.filter p) (t.filter q) := by
  simp_rw [disjoint_left, mem_filter]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s t : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
h : _root_.Disjoint p q
⊢ ∀ ⦃a : α⦄, a ∈ s ∧ p a → ¬(a ∈ t ∧ q a)

Next tactic:
rintro a ⟨_, hp⟩ ⟨_, hq⟩
theorem disjoint_filter_filter' (s t : Finset α)
    {p q : α → Prop} [DecidablePred p] [DecidablePred q] (h : Disjoint p q) :
    Disjoint (s.filter p) (t.filter q) := by
  simp_rw [disjoint_left, mem_filter]
  rintro a ⟨_, hp⟩ ⟨_, hq⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s t : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
h : _root_.Disjoint p q
a : α
left✝¹ : a ∈ s
hp : p a
left✝ : a ∈ t
hq : q a
⊢ False

Next tactic:
rw [Pi.disjoint_iff] at h
theorem disjoint_filter_filter' (s t : Finset α)
    {p q : α → Prop} [DecidablePred p] [DecidablePred q] (h : Disjoint p q) :
    Disjoint (s.filter p) (t.filter q) := by
  simp_rw [disjoint_left, mem_filter]
  rintro a ⟨_, hp⟩ ⟨_, hq⟩
  rw [Pi.disjoint_iff] at h
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
p✝ q✝ : α → Prop
inst✝³ : DecidablePred p✝
inst✝² : DecidablePred q✝
s✝ s t : Finset α
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
h : ∀ (i : α), _root_.Disjoint (p i) (q i)
a : α
left✝¹ : a ∈ s
hp : p a
left✝ : a ∈ t
hq : q a
⊢ False

Next tactic:
simpa [hp, hq] using h a
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
a : α
s : Finset α
ha : a ∉ s
⊢ _root_.Disjoint (if p a then {a} else ∅) (filter p s)

Next tactic:
split_ifs
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          split_ifs
          · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
a : α
s : Finset α
ha : a ∉ s
h✝ : p a
⊢ _root_.Disjoint {a} (filter p s)

Next tactic:
rw [disjoint_singleton_left]
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          split_ifs
          · rw [disjoint_singleton_left]
            

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
a : α
s : Finset α
ha : a ∉ s
h✝ : p a
⊢ a ∉ filter p s

Next tactic:
exact mem_filter.not.mpr <| mt And.left ha
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          split_ifs
          · rw [disjoint_singleton_left]
            exact mem_filter.not.mpr <| mt And.left ha
          · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
a : α
s : Finset α
ha : a ∉ s
h✝ : ¬p a
⊢ _root_.Disjoint ∅ (filter p s)

Next tactic:
exact disjoint_empty_left _
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          split_ifs
          · rw [disjoint_singleton_left]
            exact mem_filter.not.mpr <| mt And.left ha
          · exact disjoint_empty_left _) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
a : α
s : Finset α
ha : a ∉ s
⊢ filter p (cons a s ha) =
    disjUnion (if p a then {a} else ∅) (filter p s) (_ : _root_.Disjoint (if p a then {a} else ∅) (filter p s))

Next tactic:
split_ifs with h
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          split_ifs
          · rw [disjoint_singleton_left]
            exact mem_filter.not.mpr <| mt And.left ha
          · exact disjoint_empty_left _) := 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 α
a : α
s : Finset α
ha : a ∉ s
h : p a
⊢ filter p (cons a s ha) = disjUnion {a} (filter p s) (_ : _root_.Disjoint {a} (filter p s))

Next tactic:
rw [filter_cons_of_pos _ _ _ ha h, singleton_disjUnion]
theorem filter_cons {a : α} (s : Finset α) (ha : a ∉ s) :
    filter p (cons a s ha) =
      (if p a then {a} else ∅ : Finset α).disjUnion (filter p s)
        (by
          split_ifs
          · rw [disjoint_singleton_left]
            exact mem_filter.not.mpr <| mt And.left ha
          · exact disjoint_empty_left _) := by
  split_ifs with h
  · rw [filter_cons_of_pos _ _ _ ha h, singleton_disjUnion]
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
p q : α → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
s✝ : Finset α
a : α
s : Finset α
ha : a ∉ s
h : ¬p a
⊢ filter p (cons a s ha) = disjUnion ∅ (filter p s) (_ : _root_.Disjoint ∅ (filter p s))

Next tactic:
rw [filter_cons_of_neg _ _ _ ha h, empty_disjUnion]
theorem filter_union (s₁ s₂ : Finset α) : (s₁ ∪ s₂).filter p = s₁.filter p ∪ s₂.filter p :=
  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✝ ∈ filter p (s₁ ∪ s₂) ↔ x✝ ∈ filter p s₁ ∪ filter p s₂

Next tactic:
simp only [mem_filter, mem_union, or_and_right]
theorem filter_union_right (s : Finset α) : s.filter p ∪ s.filter q = s.filter fun x => p x ∨ q x :=
  ext fun x => 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 p s ∪ filter q s ↔ x ∈ filter (fun x => p x ∨ q x) s

Next tactic:
simp [mem_filter, mem_union, ← and_or_left]
theorem filter_mem_eq_inter {s t : Finset α} [∀ i, Decidable (i ∈ t)] :
    (s.filter fun i => i ∈ t) = s ∩ t :=
  ext fun i => 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 α
inst✝ : (i : α) → Decidable (i ∈ t)
i : α
⊢ i ∈ filter (fun i => i ∈ t) s ↔ i ∈ s ∩ t

Next tactic:
simp [mem_filter, mem_inter]
theorem filter_inter_distrib (s t : Finset α) : (s ∩ t).filter p = s.filter p ∩ t.filter p := 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 ∩ t) = filter p s ∩ filter p t

Next tactic:
ext
theorem filter_inter_distrib (s t : Finset α) : (s ∩ t).filter p = s.filter p ∩ t.filter p := 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 α
s t : Finset α
a✝ : α
⊢ a✝ ∈ filter p (s ∩ t) ↔ a✝ ∈ filter p s ∩ filter p t

Next tactic:
simp [mem_filter, mem_inter, and_assoc]
theorem filter_inter (s t : Finset α) : filter p s ∩ t = filter p (s ∩ 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 t : Finset α
⊢ filter p s ∩ t = filter p (s ∩ t)

Next tactic:
ext
theorem filter_inter (s t : Finset α) : filter p s ∩ t = filter p (s ∩ t) := 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 α
s t : Finset α
a✝ : α
⊢ a✝ ∈ filter p s ∩ t ↔ a✝ ∈ filter p (s ∩ t)

Next tactic:
simp only [mem_inter, mem_filter, and_right_comm]
theorem inter_filter (s t : Finset α) : s ∩ filter p t = filter p (s ∩ 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 t : Finset α
⊢ s ∩ filter p t = filter p (s ∩ t)

Next tactic:
rw [inter_comm, filter_inter, inter_comm]
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p 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 α
a : α
s : Finset α
⊢ filter p (insert a s) = if p a then insert a (filter p s) else filter p s

Next tactic:
ext x
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := 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 (insert a s) ↔ x ∈ if p a then insert a (filter p s) else filter p s

Next tactic:
split_ifs with h
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := by
  ext x
  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 α
a : α
s : Finset α
x : α
h : p a
⊢ x ∈ filter p (insert a s) ↔ x ∈ insert a (filter p s)

Next tactic:
by_cases h' : x = a
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := by
  ext x
  split_ifs with h <;> 

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 α
a : α
s : Finset α
x : α
h : ¬p a
⊢ x ∈ filter p (insert a s) ↔ x ∈ filter p s

Next tactic:
by_cases h' : x = a
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := by
  ext x
  split_ifs with h <;> by_cases h' : x = a <;> 

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 α
a : α
s : Finset α
x : α
h : p a
h' : x = a
⊢ x ∈ filter p (insert a s) ↔ x ∈ insert a (filter p s)

Next tactic:
simp [h, h']
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := by
  ext x
  split_ifs with h <;> by_cases h' : x = a <;> 

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 α
a : α
s : Finset α
x : α
h : p a
h' : ¬x = a
⊢ x ∈ filter p (insert a s) ↔ x ∈ insert a (filter p s)

Next tactic:
simp [h, h']
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := by
  ext x
  split_ifs with h <;> by_cases h' : x = a <;> 

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 α
a : α
s : Finset α
x : α
h : ¬p a
h' : x = a
⊢ x ∈ filter p (insert a s) ↔ x ∈ filter p s

Next tactic:
simp [h, h']
theorem filter_insert (a : α) (s : Finset α) :
    filter p (insert a s) = if p a then insert a (filter p s) else filter p s := by
  ext x
  split_ifs with h <;> by_cases h' : x = a <;> 

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 α
a : α
s : Finset α
x : α
h : ¬p a
h' : ¬x = a
⊢ x ∈ filter p (insert a s) ↔ x ∈ filter p s

Next tactic:
simp [h, h']
theorem filter_erase (a : α) (s : Finset α) : filter p (erase s a) = erase (filter p s) 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 α
a : α
s : Finset α
⊢ filter p (erase s a) = erase (filter p s) a

Next tactic:
ext x