l3lab/ntp-mathlib huggingface dataset:
@[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
    · rw [h, zero_add, one_nsmul]
    · 

Proof state:
case neg
α : 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 [add_nsmul, toFinset_add, one_nsmul, toFinset_nsmul s n h, Finset.union_idempotent]
@[simp]
theorem toFinset_inter (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_union (s t : Multiset α) : (s ∪ t).toFinset = s.toFinset ∪ t.toFinset := by
  

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

Next tactic:
ext
@[simp]
theorem toFinset_union (s t : Multiset α) : (s ∪ t).toFinset = s.toFinset ∪ t.toFinset := by
  ext; 

Proof state:
case a
α : 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_nonempty : s.toFinset.Nonempty ↔ s ≠ 0 := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
⊢ Finset.Nonempty (toFinset s) ↔ s ≠ 0

Next tactic:
simp only [toFinset_eq_empty, Ne.def, Finset.nonempty_iff_ne_empty]
@[simp]
theorem toFinset_subset : s.toFinset ⊆ t.toFinset ↔ s ⊆ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
⊢ toFinset s ⊆ toFinset t ↔ s ⊆ t

Next tactic:
simp only [Finset.subset_iff, Multiset.subset_iff, Multiset.mem_toFinset]
@[simp]
theorem toFinset_ssubset : s.toFinset ⊂ t.toFinset ↔ s ⊂ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
⊢ toFinset s ⊂ toFinset t ↔ s ⊂ t

Next tactic:
simp_rw [Finset.ssubset_def, toFinset_subset]
@[simp]
theorem toFinset_ssubset : s.toFinset ⊂ t.toFinset ↔ s ⊂ t := by
  simp_rw [Finset.ssubset_def, toFinset_subset]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
⊢ s ⊆ t ∧ ¬t ⊆ s ↔ s ⊂ t

Next tactic:
rfl
@[simp]
theorem toFinset_dedup (m : Multiset α) : m.dedup.toFinset = m.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t m : Multiset α
⊢ toFinset (dedup m) = toFinset m

Next tactic:
simp_rw [toFinset, dedup_idem]
@[simp]
theorem toFinset_bind_dedup [DecidableEq β] (m : Multiset α) (f : α → Multiset β) :
    (m.dedup.bind f).toFinset = (m.bind f).toFinset := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
s t : Multiset α
inst✝ : DecidableEq β
m : Multiset α
f : α → Multiset β
⊢ toFinset (bind (dedup m) f) = toFinset (bind m f)

Next tactic:
simp_rw [toFinset, dedup_bind_dedup]
instance isWellFounded_ssubset : IsWellFounded (Multiset β) (· ⊂ ·) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
⊢ IsWellFounded (Multiset β) fun x x_1 => x ⊂ x_1

Next tactic:
classical
  exact Subrelation.isWellFounded (InvImage _ toFinset) toFinset_ssubset.2
instance isWellFounded_ssubset : IsWellFounded (Multiset β) (· ⊂ ·) := by
  classical
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t : Multiset α
⊢ IsWellFounded (Multiset β) fun x x_1 => x ⊂ x_1

Next tactic:
exact Subrelation.isWellFounded (InvImage _ toFinset) toFinset_ssubset.2
@[simp]
theorem val_toFinset [DecidableEq α] (s : Finset α) : s.val.toFinset = s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s : Finset α
⊢ toFinset s.val = s

Next tactic:
ext
@[simp]
theorem val_toFinset [DecidableEq α] (s : Finset α) : s.val.toFinset = s := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s : Finset α
a✝ : α
⊢ a✝ ∈ toFinset s.val ↔ a✝ ∈ s

Next tactic:
rw [Multiset.mem_toFinset, ← mem_def]
theorem toFinset_eq (n : Nodup l) : @Finset.mk α l n = l.toFinset :=
  Multiset.toFinset_eq <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
n : Nodup l
⊢ Multiset.Nodup ↑l

Next tactic:
rwa [Multiset.coe_nodup]
@[simp]
theorem toFinset_cons : toFinset (a :: l) = insert a (toFinset l) :=
  Finset.eq_of_veq <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
⊢ (toFinset (a :: l)).val = (insert a (toFinset l)).val

Next tactic:
by_cases h : a ∈ l
@[simp]
theorem toFinset_cons : toFinset (a :: l) = insert a (toFinset l) :=
  Finset.eq_of_veq <| by by_cases h : a ∈ l <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
h : a ∈ l
⊢ (toFinset (a :: l)).val = (insert a (toFinset l)).val

Next tactic:
simp [Finset.insert_val', Multiset.dedup_cons, h]
@[simp]
theorem toFinset_cons : toFinset (a :: l) = insert a (toFinset l) :=
  Finset.eq_of_veq <| by by_cases h : a ∈ l <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
h : a ∉ l
⊢ (toFinset (a :: l)).val = (insert a (toFinset l)).val

Next tactic:
simp [Finset.insert_val', Multiset.dedup_cons, h]
theorem toFinset_surj_on : Set.SurjOn toFinset { l : List α | l.Nodup } Set.univ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
⊢ Set.SurjOn toFinset {l | Nodup l} Set.univ

Next tactic:
rintro ⟨⟨l⟩, hl⟩ _
theorem toFinset_surj_on : Set.SurjOn toFinset { l : List α | l.Nodup } Set.univ := by
  rintro ⟨⟨l⟩, hl⟩ _
  

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l' : List α
a : α
val✝ : Multiset α
l : List α
hl : Multiset.Nodup (Quot.mk Setoid.r l)
a✝ : { val := Quot.mk Setoid.r l, nodup := hl } ∈ Set.univ
⊢ { val := Quot.mk Setoid.r l, nodup := hl } ∈ toFinset '' {l | Nodup l}

Next tactic:
exact ⟨l, hl, (toFinset_eq hl).symm⟩
theorem toFinset_eq_iff_perm_dedup : l.toFinset = l'.toFinset ↔ l.dedup ~ l'.dedup := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
⊢ toFinset l = toFinset l' ↔ dedup l ~ dedup l'

Next tactic:
simp [Finset.ext_iff, perm_ext_iff_of_nodup (nodup_dedup _) (nodup_dedup _)]
theorem toFinset.ext_iff {a b : List α} : a.toFinset = b.toFinset ↔ ∀ x, x ∈ a ↔ x ∈ b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a✝ : α
a b : List α
⊢ toFinset a = toFinset b ↔ ∀ (x : α), x ∈ a ↔ x ∈ b

Next tactic:
simp only [Finset.ext_iff, mem_toFinset]
theorem perm_of_nodup_nodup_toFinset_eq (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 α
l l' : List α
a : α
hl : Nodup l
hl' : Nodup l'
h : toFinset l = toFinset l'
⊢ l ~ l'

Next tactic:
rw [← Multiset.coe_eq_coe]
theorem perm_of_nodup_nodup_toFinset_eq (hl : Nodup l) (hl' : Nodup l')
    (h : l.toFinset = l'.toFinset) : l ~ l' := by
  rw [← Multiset.coe_eq_coe]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
hl : Nodup l
hl' : Nodup l'
h : toFinset l = toFinset l'
⊢ ↑l = ↑l'

Next tactic:
exact Multiset.Nodup.toFinset_inj hl hl' h
@[simp]
theorem toFinset_append : toFinset (l ++ l') = l.toFinset ∪ l'.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
⊢ toFinset (l ++ l') = toFinset l ∪ toFinset l'

Next tactic:
induction' l with hd tl hl
@[simp]
theorem toFinset_append : toFinset (l ++ l') = l.toFinset ∪ l'.toFinset := by
  induction' l with hd tl hl
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
⊢ toFinset ([] ++ l') = toFinset [] ∪ toFinset l'

Next tactic:
simp
@[simp]
theorem toFinset_append : toFinset (l ++ l') = l.toFinset ∪ l'.toFinset := by
  induction' l with hd tl hl
  · simp
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a hd : α
tl : List α
hl : toFinset (tl ++ l') = toFinset tl ∪ toFinset l'
⊢ toFinset (hd :: tl ++ l') = toFinset (hd :: tl) ∪ toFinset l'

Next tactic:
simp [hl]
theorem toFinset_replicate_of_ne_zero {n : ℕ} (hn : n ≠ 0) :
    (List.replicate n a).toFinset = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
n : ℕ
hn : n ≠ 0
⊢ toFinset (replicate n a) = {a}

Next tactic:
ext x
theorem toFinset_replicate_of_ne_zero {n : ℕ} (hn : n ≠ 0) :
    (List.replicate n a).toFinset = {a} := by
  ext x
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
n : ℕ
hn : n ≠ 0
x : α
⊢ x ∈ toFinset (replicate n a) ↔ x ∈ {a}

Next tactic:
simp [hn, List.mem_replicate]
@[simp]
theorem toFinset_union (l l' : List α) : (l ∪ l').toFinset = l.toFinset ∪ l'.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l'✝ : List α
a : α
l l' : List α
⊢ toFinset (l ∪ l') = toFinset l ∪ toFinset l'

Next tactic:
ext
@[simp]
theorem toFinset_union (l l' : List α) : (l ∪ l').toFinset = l.toFinset ∪ l'.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l'✝ : List α
a : α
l l' : List α
a✝ : α
⊢ a✝ ∈ toFinset (l ∪ l') ↔ a✝ ∈ toFinset l ∪ toFinset l'

Next tactic:
simp
@[simp]
theorem toFinset_inter (l l' : List α) : (l ∩ l').toFinset = l.toFinset ∩ l'.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l'✝ : List α
a : α
l l' : List α
⊢ toFinset (l ∩ l') = toFinset l ∩ toFinset l'

Next tactic:
ext
@[simp]
theorem toFinset_inter (l l' : List α) : (l ∩ l').toFinset = l.toFinset ∩ l'.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l'✝ : List α
a : α
l l' : List α
a✝ : α
⊢ a✝ ∈ toFinset (l ∩ l') ↔ a✝ ∈ toFinset l ∩ toFinset l'

Next tactic:
simp
@[simp]
theorem toFinset_eq_empty_iff (l : List α) : l.toFinset = ∅ ↔ l = nil := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l' : List α
a : α
l : List α
⊢ toFinset l = ∅ ↔ l = []

Next tactic:
cases l
@[simp]
theorem toFinset_eq_empty_iff (l : List α) : l.toFinset = ∅ ↔ l = nil := by
  cases l <;> 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a : α
⊢ toFinset [] = ∅ ↔ [] = []

Next tactic:
simp
@[simp]
theorem toFinset_eq_empty_iff (l : List α) : l.toFinset = ∅ ↔ l = nil := by
  cases l <;> 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l l' : List α
a head✝ : α
tail✝ : List α
⊢ toFinset (head✝ :: tail✝) = ∅ ↔ head✝ :: tail✝ = []

Next tactic:
simp
@[simp]
theorem toFinset_nonempty_iff (l : List α) : l.toFinset.Nonempty ↔ l ≠ [] := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l✝ l' : List α
a : α
l : List α
⊢ Finset.Nonempty (toFinset l) ↔ l ≠ []

Next tactic:
simp [Finset.nonempty_iff_ne_empty]
theorem nodup_toList (s : Finset α) : s.toList.Nodup := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
⊢ List.Nodup (toList s)

Next tactic:
rw [toList, ← Multiset.coe_nodup, Multiset.coe_toList]
theorem nodup_toList (s : Finset α) : s.toList.Nodup := by
  rw [toList, ← Multiset.coe_nodup, Multiset.coe_toList]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
⊢ Nodup s.val

Next tactic:
exact s.nodup
@[simp]
theorem toList_toFinset [DecidableEq α] (s : Finset α) : s.toList.toFinset = s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s : Finset α
⊢ List.toFinset (toList s) = s

Next tactic:
ext
@[simp]
theorem toList_toFinset [DecidableEq α] (s : Finset α) : s.toList.toFinset = s := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s : Finset α
a✝ : α
⊢ a✝ ∈ List.toFinset (toList s) ↔ a✝ ∈ s

Next tactic:
simp
@[simp]
theorem toList_eq_singleton_iff {a : α} {s : Finset α} : s.toList = [a] ↔ s = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
s : Finset α
⊢ toList s = [a] ↔ s = {a}

Next tactic:
rw [toList, Multiset.toList_eq_singleton_iff, val_eq_singleton_iff]
open scoped List in
theorem toList_cons {a : α} {s : Finset α} (h : a ∉ s) : (cons a s h).toList ~ a :: s.toList :=
  (List.perm_ext_iff_of_nodup (nodup_toList _) (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
s : Finset α
h : a ∉ s
⊢ List.Nodup (a :: toList s)

Next tactic:
simp [h, nodup_toList s]
open scoped List in
theorem toList_cons {a : α} {s : Finset α} (h : a ∉ s) : (cons a s h).toList ~ a :: s.toList :=
  (List.perm_ext_iff_of_nodup (nodup_toList _) (by simp [h, nodup_toList s])).2 fun x => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a : α
s : Finset α
h : a ∉ s
x : α
⊢ x ∈ toList (cons a s h) ↔ x ∈ a :: toList s

Next tactic:
simp only [List.mem_cons, Finset.mem_toList, Finset.mem_cons]
@[simp]
theorem disjiUnion_empty (t : α → Finset β) : disjiUnion ∅ t (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s s₁ s₂ : Finset α
t✝ t₁ t₂ t : α → Finset β
⊢ Set.PairwiseDisjoint (↑∅) t

Next tactic:
simp
@[simp]
theorem mem_disjiUnion {b : β} {h} : b ∈ s.disjiUnion t h ↔ ∃ a ∈ s, b ∈ t a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
b : β
h : Set.PairwiseDisjoint (↑s) t
⊢ b ∈ disjiUnion s t h ↔ ∃ a ∈ s, b ∈ t a

Next tactic:
simp only [mem_def, disjiUnion_val, mem_bind, exists_prop]
@[simp, norm_cast]
theorem coe_disjiUnion {h} : (s.disjiUnion t h : Set β) = ⋃ x ∈ (s : Set α), t x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
h : Set.PairwiseDisjoint (↑s) t
⊢ ↑(disjiUnion s t h) = ⋃ x ∈ ↑s, ↑(t x)

Next tactic:
simp [Set.ext_iff, mem_disjiUnion, Set.mem_iUnion, iff_self_iff, mem_coe, imp_true_iff]
theorem disjiUnion_disjiUnion (s : Finset α) (f : α → Finset β) (g : β → Finset γ) (h1 h2) :
    (s.disjiUnion f h1).disjiUnion g h2 =
      s.attach.disjiUnion
        (fun a =>
          ((f a).disjiUnion g) fun b hb c hc =>
            h2 (mem_disjiUnion.mpr ⟨_, a.prop, hb⟩) (mem_disjiUnion.mpr ⟨_, a.prop, hc⟩))
        fun a _ b _ hab =>
        disjoint_left.mpr fun x hxa hxb => by
          

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
s : Finset α
f : α → Finset β
g : β → Finset γ
h1 : Set.PairwiseDisjoint (↑s) f
h2 : Set.PairwiseDisjoint (↑(disjiUnion s f h1)) g
a : { x // x ∈ s }
x✝¹ : a ∈ ↑(attach s)
b : { x // x ∈ s }
x✝ : b ∈ ↑(attach s)
hab : a ≠ b
x : γ
hxa : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) a
hxb : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) b
⊢ False

Next tactic:
obtain ⟨xa, hfa, hga⟩ := mem_disjiUnion.mp hxa
theorem disjiUnion_disjiUnion (s : Finset α) (f : α → Finset β) (g : β → Finset γ) (h1 h2) :
    (s.disjiUnion f h1).disjiUnion g h2 =
      s.attach.disjiUnion
        (fun a =>
          ((f a).disjiUnion g) fun b hb c hc =>
            h2 (mem_disjiUnion.mpr ⟨_, a.prop, hb⟩) (mem_disjiUnion.mpr ⟨_, a.prop, hc⟩))
        fun a _ b _ hab =>
        disjoint_left.mpr fun x hxa hxb => by
          obtain ⟨xa, hfa, hga⟩ := mem_disjiUnion.mp hxa
          

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
s : Finset α
f : α → Finset β
g : β → Finset γ
h1 : Set.PairwiseDisjoint (↑s) f
h2 : Set.PairwiseDisjoint (↑(disjiUnion s f h1)) g
a : { x // x ∈ s }
x✝¹ : a ∈ ↑(attach s)
b : { x // x ∈ s }
x✝ : b ∈ ↑(attach s)
hab : a ≠ b
x : γ
hxa : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) a
hxb : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) b
xa : β
hfa : xa ∈ f ↑a
hga : x ∈ g xa
⊢ False

Next tactic:
obtain ⟨xb, hfb, hgb⟩ := mem_disjiUnion.mp hxb
theorem disjiUnion_disjiUnion (s : Finset α) (f : α → Finset β) (g : β → Finset γ) (h1 h2) :
    (s.disjiUnion f h1).disjiUnion g h2 =
      s.attach.disjiUnion
        (fun a =>
          ((f a).disjiUnion g) fun b hb c hc =>
            h2 (mem_disjiUnion.mpr ⟨_, a.prop, hb⟩) (mem_disjiUnion.mpr ⟨_, a.prop, hc⟩))
        fun a _ b _ hab =>
        disjoint_left.mpr fun x hxa hxb => by
          obtain ⟨xa, hfa, hga⟩ := mem_disjiUnion.mp hxa
          obtain ⟨xb, hfb, hgb⟩ := mem_disjiUnion.mp hxb
          

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
s : Finset α
f : α → Finset β
g : β → Finset γ
h1 : Set.PairwiseDisjoint (↑s) f
h2 : Set.PairwiseDisjoint (↑(disjiUnion s f h1)) g
a : { x // x ∈ s }
x✝¹ : a ∈ ↑(attach s)
b : { x // x ∈ s }
x✝ : b ∈ ↑(attach s)
hab : a ≠ b
x : γ
hxa : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) a
hxb : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) b
xa : β
hfa : xa ∈ f ↑a
hga : x ∈ g xa
xb : β
hfb : xb ∈ f ↑b
hgb : x ∈ g xb
⊢ False

Next tactic:
refine'
            disjoint_left.mp
              (h2 (mem_disjiUnion.mpr ⟨_, a.prop, hfa⟩) (mem_disjiUnion.mpr ⟨_, b.prop, hfb⟩) _) hga
              hgb
theorem disjiUnion_disjiUnion (s : Finset α) (f : α → Finset β) (g : β → Finset γ) (h1 h2) :
    (s.disjiUnion f h1).disjiUnion g h2 =
      s.attach.disjiUnion
        (fun a =>
          ((f a).disjiUnion g) fun b hb c hc =>
            h2 (mem_disjiUnion.mpr ⟨_, a.prop, hb⟩) (mem_disjiUnion.mpr ⟨_, a.prop, hc⟩))
        fun a _ b _ hab =>
        disjoint_left.mpr fun x hxa hxb => by
          obtain ⟨xa, hfa, hga⟩ := mem_disjiUnion.mp hxa
          obtain ⟨xb, hfb, hgb⟩ := mem_disjiUnion.mp hxb
          refine'
            disjoint_left.mp
              (h2 (mem_disjiUnion.mpr ⟨_, a.prop, hfa⟩) (mem_disjiUnion.mpr ⟨_, b.prop, hfb⟩) _) hga
              hgb
          

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
s : Finset α
f : α → Finset β
g : β → Finset γ
h1 : Set.PairwiseDisjoint (↑s) f
h2 : Set.PairwiseDisjoint (↑(disjiUnion s f h1)) g
a : { x // x ∈ s }
x✝¹ : a ∈ ↑(attach s)
b : { x // x ∈ s }
x✝ : b ∈ ↑(attach s)
hab : a ≠ b
x : γ
hxa : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) a
hxb : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) b
xa : β
hfa : xa ∈ f ↑a
hga : x ∈ g xa
xb : β
hfb : xb ∈ f ↑b
hgb : x ∈ g xb
⊢ xa ≠ xb

Next tactic:
rintro rfl
theorem disjiUnion_disjiUnion (s : Finset α) (f : α → Finset β) (g : β → Finset γ) (h1 h2) :
    (s.disjiUnion f h1).disjiUnion g h2 =
      s.attach.disjiUnion
        (fun a =>
          ((f a).disjiUnion g) fun b hb c hc =>
            h2 (mem_disjiUnion.mpr ⟨_, a.prop, hb⟩) (mem_disjiUnion.mpr ⟨_, a.prop, hc⟩))
        fun a _ b _ hab =>
        disjoint_left.mpr fun x hxa hxb => by
          obtain ⟨xa, hfa, hga⟩ := mem_disjiUnion.mp hxa
          obtain ⟨xb, hfb, hgb⟩ := mem_disjiUnion.mp hxb
          refine'
            disjoint_left.mp
              (h2 (mem_disjiUnion.mpr ⟨_, a.prop, hfa⟩) (mem_disjiUnion.mpr ⟨_, b.prop, hfb⟩) _) hga
              hgb
          rintro rfl
          

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
s : Finset α
f : α → Finset β
g : β → Finset γ
h1 : Set.PairwiseDisjoint (↑s) f
h2 : Set.PairwiseDisjoint (↑(disjiUnion s f h1)) g
a : { x // x ∈ s }
x✝¹ : a ∈ ↑(attach s)
b : { x // x ∈ s }
x✝ : b ∈ ↑(attach s)
hab : a ≠ b
x : γ
hxa : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) a
hxb : x ∈ (fun a => disjiUnion (f ↑a) g (_ : ∀ b ∈ ↑(f ↑a), ∀ c ∈ ↑(f ↑a), b ≠ c → (_root_.Disjoint on g) b c)) b
xa : β
hfa : xa ∈ f ↑a
hga : x ∈ g xa
hfb : xa ∈ f ↑b
hgb : x ∈ g xa
⊢ False

Next tactic:
exact disjoint_left.mp (h1 a.prop b.prop <| Subtype.coe_injective.ne hab) hfa hfb
theorem disjiUnion_filter_eq_of_maps_to [DecidableEq β] {s : Finset α} {t : Finset β} {f : α → β}
    (h : ∀ x ∈ s, f x ∈ t) :
    t.disjiUnion (fun a => s.filter (fun c => f c = a))
      (fun x' hx y' hy hne => by
        

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t✝ t₁ t₂ : α → Finset β
inst✝ : DecidableEq β
s : Finset α
t : Finset β
f : α → β
h : ∀ x ∈ s, f x ∈ t
x' : β
hx : x' ∈ ↑t
y' : β
hy : y' ∈ ↑t
hne : x' ≠ y'
⊢ (_root_.Disjoint on fun a => filter (fun c => f c = a) s) x' y'

Next tactic:
simp_rw [disjoint_left, mem_filter]
theorem disjiUnion_filter_eq_of_maps_to [DecidableEq β] {s : Finset α} {t : Finset β} {f : α → β}
    (h : ∀ x ∈ s, f x ∈ t) :
    t.disjiUnion (fun a => s.filter (fun c => f c = a))
      (fun x' hx y' hy hne => by
        simp_rw [disjoint_left, mem_filter]
        

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t✝ t₁ t₂ : α → Finset β
inst✝ : DecidableEq β
s : Finset α
t : Finset β
f : α → β
h : ∀ x ∈ s, f x ∈ t
x' : β
hx : x' ∈ ↑t
y' : β
hy : y' ∈ ↑t
hne : x' ≠ y'
⊢ ∀ ⦃a : α⦄, a ∈ s ∧ f a = x' → ¬(a ∈ s ∧ f a = y')

Next tactic:
rintro i ⟨_, rfl⟩ ⟨_, rfl⟩
theorem disjiUnion_filter_eq_of_maps_to [DecidableEq β] {s : Finset α} {t : Finset β} {f : α → β}
    (h : ∀ x ∈ s, f x ∈ t) :
    t.disjiUnion (fun a => s.filter (fun c => f c = a))
      (fun x' hx y' hy hne => by
        simp_rw [disjoint_left, mem_filter]
        rintro i ⟨_, rfl⟩ ⟨_, rfl⟩
        

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t✝ t₁ t₂ : α → Finset β
inst✝ : DecidableEq β
s : Finset α
t : Finset β
f : α → β
h : ∀ x ∈ s, f x ∈ t
i : α
left✝¹ : i ∈ s
hx : f i ∈ ↑t
left✝ : i ∈ s
hy : f i ∈ ↑t
hne : f i ≠ f i
⊢ False

Next tactic:
exact hne rfl
theorem disjiUnion_filter_eq_of_maps_to [DecidableEq β] {s : Finset α} {t : Finset β} {f : α → β}
    (h : ∀ x ∈ s, f x ∈ t) :
    t.disjiUnion (fun a => s.filter (fun c => f c = a))
      (fun x' hx y' hy hne => by
        simp_rw [disjoint_left, mem_filter]
        rintro i ⟨_, rfl⟩ ⟨_, rfl⟩
        exact hne rfl) = s :=
  ext fun b => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s₁ s₂ : Finset α
t✝ t₁ t₂ : α → Finset β
inst✝ : DecidableEq β
s : Finset α
t : Finset β
f : α → β
h : ∀ x ∈ s, f x ∈ t
b : α
⊢ b ∈
      disjiUnion t (fun a => filter (fun c => f c = a) s)
        (_ : ∀ x' ∈ ↑t, ∀ y' ∈ ↑t, x' ≠ y' → (_root_.Disjoint on fun a => filter (fun c => f c = a) s) x' y') ↔
    b ∈ s

Next tactic:
simpa using h b
@[simp]
theorem mem_biUnion {b : β} : b ∈ s.biUnion t ↔ ∃ a ∈ s, b ∈ t a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq β
s s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
b : β
⊢ b ∈ Finset.biUnion s t ↔ ∃ a ∈ s, b ∈ t a

Next tactic:
simp only [mem_def, biUnion_val, mem_dedup, mem_bind, exists_prop]
@[simp, norm_cast]
theorem coe_biUnion : (s.biUnion t : Set β) = ⋃ x ∈ (s : Set α), t x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq β
s s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
⊢ ↑(Finset.biUnion s t) = ⋃ x ∈ ↑s, ↑(t x)

Next tactic:
simp [Set.ext_iff, mem_biUnion, Set.mem_iUnion, iff_self_iff, mem_coe, imp_true_iff]
@[simp]
theorem biUnion_insert [DecidableEq α] {a : α} : (insert a s).biUnion t = t a ∪ s.biUnion t :=
  ext fun x => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq β
s s₁ s₂ : Finset α
t t₁ t₂ : α → Finset β
inst✝ : DecidableEq α
a : α
x : β
⊢ x ∈ Finset.biUnion (insert a s) t ↔ x ∈ t a ∪ Finset.biUnion s t

Next tactic:
simp only [mem_biUnion, exists_prop, mem_union, mem_insert, or_and_right, exists_or,
      exists_eq_left]