l3lab/ntp-mathlib huggingface dataset:
lemma sUnion_diffFinset₀_subset (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    ⋃₀ (hC.diffFinset₀ hs hI : Set (Set α)) ⊆ s := by
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
⊢ ⋃₀ ↑(diffFinset₀ hC hs hI) ⊆ s

Next tactic:
rw [← hC.diff_sUnion_eq_sUnion_diffFinset₀]
lemma sUnion_diffFinset₀_subset (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    ⋃₀ (hC.diffFinset₀ hs hI : Set (Set α)) ⊆ s := by
  rw [← hC.diff_sUnion_eq_sUnion_diffFinset₀]
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
⊢ s \ ⋃₀ ↑I ⊆ s

Next tactic:
exact diff_subset _ _
lemma disjoint_sUnion_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint (⋃₀ (I : Set (Set α))) (⋃₀ hC.diffFinset₀ hs hI) := by
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
⊢ Disjoint (⋃₀ ↑I) (⋃₀ ↑(diffFinset₀ hC hs hI))

Next tactic:
rw [← hC.diff_sUnion_eq_sUnion_diffFinset₀]
lemma disjoint_sUnion_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint (⋃₀ (I : Set (Set α))) (⋃₀ hC.diffFinset₀ hs hI) := by
  rw [← hC.diff_sUnion_eq_sUnion_diffFinset₀]; 

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
⊢ Disjoint (⋃₀ ↑I) (s \ ⋃₀ ↑I)

Next tactic:
exact Set.disjoint_sdiff_right
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
⊢ Disjoint I (diffFinset₀ hC hs hI)

Next tactic:
by_contra h
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  by_contra h
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
h : ¬Disjoint I (diffFinset₀ hC hs hI)
⊢ False

Next tactic:
rw [Finset.not_disjoint_iff] at h
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  by_contra h
  rw [Finset.not_disjoint_iff] at h
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
h : ∃ a ∈ I, a ∈ diffFinset₀ hC hs hI
⊢ False

Next tactic:
obtain ⟨u, huI, hu_diffFinset₀⟩ := h
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  by_contra h
  rw [Finset.not_disjoint_iff] at h
  obtain ⟨u, huI, hu_diffFinset₀⟩ := h
  

Proof state:
case intro.intro
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
u : Set α
huI : u ∈ I
hu_diffFinset₀ : u ∈ diffFinset₀ hC hs hI
⊢ False

Next tactic:
have h_disj : u ≤ ⊥ := hC.disjoint_sUnion_diffFinset₀ hs hI (subset_sUnion_of_mem huI)
    (subset_sUnion_of_mem hu_diffFinset₀)
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  by_contra h
  rw [Finset.not_disjoint_iff] at h
  obtain ⟨u, huI, hu_diffFinset₀⟩ := h
  have h_disj : u ≤ ⊥ := hC.disjoint_sUnion_diffFinset₀ hs hI (subset_sUnion_of_mem huI)
    (subset_sUnion_of_mem hu_diffFinset₀)
  

Proof state:
case intro.intro
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
u : Set α
huI : u ∈ I
hu_diffFinset₀ : u ∈ diffFinset₀ hC hs hI
h_disj : u ≤ ⊥
⊢ False

Next tactic:
simp only [Set.bot_eq_empty, Set.le_eq_subset, subset_empty_iff] at h_disj
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  by_contra h
  rw [Finset.not_disjoint_iff] at h
  obtain ⟨u, huI, hu_diffFinset₀⟩ := h
  have h_disj : u ≤ ⊥ := hC.disjoint_sUnion_diffFinset₀ hs hI (subset_sUnion_of_mem huI)
    (subset_sUnion_of_mem hu_diffFinset₀)
  simp only [Set.bot_eq_empty, Set.le_eq_subset, subset_empty_iff] at h_disj
  

Proof state:
case intro.intro
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
u : Set α
huI : u ∈ I
hu_diffFinset₀ : u ∈ diffFinset₀ hC hs hI
h_disj : u = ∅
⊢ False

Next tactic:
refine hC.empty_not_mem_diffFinset₀ hs hI ?_
lemma disjoint_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) :
    Disjoint I (hC.diffFinset₀ hs hI) := by
  by_contra h
  rw [Finset.not_disjoint_iff] at h
  obtain ⟨u, huI, hu_diffFinset₀⟩ := h
  have h_disj : u ≤ ⊥ := hC.disjoint_sUnion_diffFinset₀ hs hI (subset_sUnion_of_mem huI)
    (subset_sUnion_of_mem hu_diffFinset₀)
  simp only [Set.bot_eq_empty, Set.le_eq_subset, subset_empty_iff] at h_disj
  refine hC.empty_not_mem_diffFinset₀ hs hI ?_
  

Proof state:
case intro.intro
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
u : Set α
huI : u ∈ I
hu_diffFinset₀ : u ∈ diffFinset₀ hC hs hI
h_disj : u = ∅
⊢ ∅ ∈ diffFinset₀ hC hs hI

Next tactic:
rwa [h_disj] at hu_diffFinset₀
lemma pairwiseDisjoint_union_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (h_dis : PairwiseDisjoint (I : Set (Set α)) id) :
    PairwiseDisjoint (I ∪ hC.diffFinset₀ hs hI : Set (Set α)) id := by
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
h_dis : PairwiseDisjoint (↑I) id
⊢ PairwiseDisjoint (↑I ∪ ↑(diffFinset₀ hC hs hI)) id

Next tactic:
rw [pairwiseDisjoint_union]
lemma pairwiseDisjoint_union_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (h_dis : PairwiseDisjoint (I : Set (Set α)) id) :
    PairwiseDisjoint (I ∪ hC.diffFinset₀ hs hI : Set (Set α)) id := by
  rw [pairwiseDisjoint_union]
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
h_dis : PairwiseDisjoint (↑I) id
⊢ PairwiseDisjoint (↑I) id ∧
    PairwiseDisjoint (↑(diffFinset₀ hC hs hI)) id ∧
      ∀ ⦃i : Set α⦄, i ∈ ↑I → ∀ ⦃j : Set α⦄, j ∈ ↑(diffFinset₀ hC hs hI) → i ≠ j → Disjoint (id i) (id j)

Next tactic:
refine ⟨h_dis, hC.pairwiseDisjoint_diffFinset₀ hs hI, fun u hu v hv _ ↦ ?_⟩
lemma pairwiseDisjoint_union_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (h_dis : PairwiseDisjoint (I : Set (Set α)) id) :
    PairwiseDisjoint (I ∪ hC.diffFinset₀ hs hI : Set (Set α)) id := by
  rw [pairwiseDisjoint_union]
  refine ⟨h_dis, hC.pairwiseDisjoint_diffFinset₀ hs hI, fun u hu v hv _ ↦ ?_⟩
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
h_dis : PairwiseDisjoint (↑I) id
u : Set α
hu : u ∈ ↑I
v : Set α
hv : v ∈ ↑(diffFinset₀ hC hs hI)
x✝ : u ≠ v
⊢ Disjoint (id u) (id v)

Next tactic:
simp_rw [id.def]
lemma pairwiseDisjoint_union_diffFinset₀ (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (h_dis : PairwiseDisjoint (I : Set (Set α)) id) :
    PairwiseDisjoint (I ∪ hC.diffFinset₀ hs hI : Set (Set α)) id := by
  rw [pairwiseDisjoint_union]
  refine ⟨h_dis, hC.pairwiseDisjoint_diffFinset₀ hs hI, fun u hu v hv _ ↦ ?_⟩
  simp_rw [id.def]
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
h_dis : PairwiseDisjoint (↑I) id
u : Set α
hu : u ∈ ↑I
v : Set α
hv : v ∈ ↑(diffFinset₀ hC hs hI)
x✝ : u ≠ v
⊢ Disjoint u v

Next tactic:
exact disjoint_of_subset (subset_sUnion_of_mem hu) (subset_sUnion_of_mem hv)
    (hC.disjoint_sUnion_diffFinset₀ hs hI)
lemma sUnion_union_sUnion_diffFinset₀_of_subset (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (hI_ss : ⋃₀ ↑I ⊆ s) :
    ⋃₀ I ∪ ⋃₀ hC.diffFinset₀ hs hI = s := by
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
hI_ss : ⋃₀ ↑I ⊆ s
⊢ ⋃₀ ↑I ∪ ⋃₀ ↑(diffFinset₀ hC hs hI) = s

Next tactic:
conv_rhs => rw [← union_diff_cancel hI_ss, hC.diff_sUnion_eq_sUnion_diffFinset₀ hs hI]
lemma sUnion_union_sUnion_diffFinset₀_of_subset (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (hI_ss : ⋃₀ ↑I ⊆ s) :
    ⋃₀ I ∪ ⋃₀ hC.diffFinset₀ hs hI = s := by
  conv_rhs => 

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
hI_ss : ⋃₀ ↑I ⊆ s
| s

Next tactic:
rw [← union_diff_cancel hI_ss, hC.diff_sUnion_eq_sUnion_diffFinset₀ hs hI]
lemma sUnion_union_diffFinset₀_of_subset (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (hI_ss : ⋃₀ ↑I ⊆ s) [DecidableEq (Set α)] :
    ⋃₀ ↑(I ∪ hC.diffFinset₀ hs hI) = s := by
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
hI_ss : ⋃₀ ↑I ⊆ s
inst✝ : DecidableEq (Set α)
⊢ ⋃₀ ↑(I ∪ diffFinset₀ hC hs hI) = s

Next tactic:
conv_rhs => rw [← sUnion_union_sUnion_diffFinset₀_of_subset hC hs hI hI_ss]
lemma sUnion_union_diffFinset₀_of_subset (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (hI_ss : ⋃₀ ↑I ⊆ s) [DecidableEq (Set α)] :
    ⋃₀ ↑(I ∪ hC.diffFinset₀ hs hI) = s := by
  conv_rhs => 

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
hI_ss : ⋃₀ ↑I ⊆ s
inst✝ : DecidableEq (Set α)
| s

Next tactic:
rw [← sUnion_union_sUnion_diffFinset₀_of_subset hC hs hI hI_ss]
lemma sUnion_union_diffFinset₀_of_subset (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (hI_ss : ⋃₀ ↑I ⊆ s) [DecidableEq (Set α)] :
    ⋃₀ ↑(I ∪ hC.diffFinset₀ hs hI) = s := by
  conv_rhs => rw [← sUnion_union_sUnion_diffFinset₀_of_subset hC hs hI hI_ss]
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
hI_ss : ⋃₀ ↑I ⊆ s
inst✝ : DecidableEq (Set α)
⊢ ⋃₀ ↑(I ∪ diffFinset₀ hC hs hI) = ⋃₀ ↑I ∪ ⋃₀ ↑(diffFinset₀ hC hs hI)

Next tactic:
simp_rw [coe_union]
lemma sUnion_union_diffFinset₀_of_subset (hC : IsSetSemiring C) (hs : s ∈ C)
    (hI : ↑I ⊆ C) (hI_ss : ⋃₀ ↑I ⊆ s) [DecidableEq (Set α)] :
    ⋃₀ ↑(I ∪ hC.diffFinset₀ hs hI) = s := by
  conv_rhs => rw [← sUnion_union_sUnion_diffFinset₀_of_subset hC hs hI hI_ss]
  simp_rw [coe_union]
  

Proof state:
α : Type u_1
C : Set (Set α)
s t : Set α
I : Finset (Set α)
hC : IsSetSemiring C
hs : s ∈ C
hI : ↑I ⊆ C
hI_ss : ⋃₀ ↑I ⊆ s
inst✝ : DecidableEq (Set α)
⊢ ⋃₀ (↑I ∪ ↑(diffFinset₀ hC hs hI)) = ⋃₀ ↑I ∪ ⋃₀ ↑(diffFinset₀ hC hs hI)

Next tactic:
rw [sUnion_union]
theorem classes_ker_subset_fiber_set {β : Type*} (f : α → β) :
    (Setoid.ker f).classes ⊆ Set.range fun y => { x | f x = y } := by
  

Proof state:
α : Type u_1
β : Type u_2
f : α → β
⊢ classes (ker f) ⊆ Set.range fun y => {x | f x = y}

Next tactic:
rintro s ⟨x, rfl⟩
theorem classes_ker_subset_fiber_set {β : Type*} (f : α → β) :
    (Setoid.ker f).classes ⊆ Set.range fun y => { x | f x = y } := by
  rintro s ⟨x, rfl⟩
  

Proof state:
case intro
α : Type u_1
β : Type u_2
f : α → β
x : α
⊢ {x_1 | Rel (ker f) x_1 x} ∈ Set.range fun y => {x | f x = y}

Next tactic:
rw [Set.mem_range]
theorem classes_ker_subset_fiber_set {β : Type*} (f : α → β) :
    (Setoid.ker f).classes ⊆ Set.range fun y => { x | f x = y } := by
  rintro s ⟨x, rfl⟩
  rw [Set.mem_range]
  

Proof state:
case intro
α : Type u_1
β : Type u_2
f : α → β
x : α
⊢ ∃ y, {x | f x = y} = {x_1 | Rel (ker f) x_1 x}

Next tactic:
exact ⟨f x, rfl⟩
theorem card_classes_ker_le {α β : Type*} [Fintype β] (f : α → β)
    [Fintype (Setoid.ker f).classes] : Fintype.card (Setoid.ker f).classes ≤ Fintype.card β := by
  

Proof state:
α✝ : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : Fintype β
f : α → β
inst✝ : Fintype ↑(classes (ker f))
⊢ Fintype.card ↑(classes (ker f)) ≤ Fintype.card β

Next tactic:
classical exact
      le_trans (Set.card_le_of_subset (classes_ker_subset_fiber_set f)) (Fintype.card_range_le _)
theorem card_classes_ker_le {α β : Type*} [Fintype β] (f : α → β)
    [Fintype (Setoid.ker f).classes] : Fintype.card (Setoid.ker f).classes ≤ Fintype.card β := by
  classical 

Proof state:
α✝ : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : Fintype β
f : α → β
inst✝ : Fintype ↑(classes (ker f))
⊢ Fintype.card ↑(classes (ker f)) ≤ Fintype.card β

Next tactic:
exact
      le_trans (Set.card_le_of_subset (classes_ker_subset_fiber_set f)) (Fintype.card_range_le _)
theorem rel_iff_exists_classes (r : Setoid α) {x y} : r.Rel x y ↔ ∃ c ∈ r.classes, x ∈ c ∧ y ∈ c :=
  ⟨fun h => ⟨_, r.mem_classes y, h, r.refl' y⟩, fun ⟨c, ⟨z, hz⟩, hx, hy⟩ => by
    

Proof state:
α : Type u_1
r : Setoid α
x y : α
x✝ : ∃ c ∈ classes r, x ∈ c ∧ y ∈ c
c : Set α
z : α
hz : c = {x | Rel r x z}
hx : x ∈ c
hy : y ∈ c
⊢ Rel r x y

Next tactic:
subst c
theorem rel_iff_exists_classes (r : Setoid α) {x y} : r.Rel x y ↔ ∃ c ∈ r.classes, x ∈ c ∧ y ∈ c :=
  ⟨fun h => ⟨_, r.mem_classes y, h, r.refl' y⟩, fun ⟨c, ⟨z, hz⟩, hx, hy⟩ => by
    subst c
    

Proof state:
α : Type u_1
r : Setoid α
x y : α
x✝ : ∃ c ∈ classes r, x ∈ c ∧ y ∈ c
z : α
hx : x ∈ {x | Rel r x z}
hy : y ∈ {x | Rel r x z}
⊢ Rel r x y

Next tactic:
exact r.trans' hx (r.symm' hy)
/-- Two equivalence relations are equal iff their equivalence classes are equal. -/
theorem classes_inj {r₁ r₂ : Setoid α} : r₁ = r₂ ↔ r₁.classes = r₂.classes :=
  ⟨fun h => h ▸ rfl, fun h => ext' fun a b => by 

Proof state:
α : Type u_1
r₁ r₂ : Setoid α
h : classes r₁ = classes r₂
a b : α
⊢ Rel r₁ a b ↔ Rel r₂ a b

Next tactic:
simp only [rel_iff_exists_classes, exists_prop, h]
/-- Equivalence classes partition the type. -/
theorem classes_eqv_classes {r : Setoid α} (a) : ∃! (b : _) (_ : b ∈ r.classes), a ∈ b :=
  ExistsUnique.intro₂ { x | r.Rel x a } (r.mem_classes a) (r.refl' _) <| by
    

Proof state:
α : Type u_1
r : Setoid α
a : α
⊢ ∀ y ∈ classes r, a ∈ y → y = {x | Rel r x a}

Next tactic:
rintro _ ⟨y, rfl⟩ ha
/-- Equivalence classes partition the type. -/
theorem classes_eqv_classes {r : Setoid α} (a) : ∃! (b : _) (_ : b ∈ r.classes), a ∈ b :=
  ExistsUnique.intro₂ { x | r.Rel x a } (r.mem_classes a) (r.refl' _) <| by
    rintro _ ⟨y, rfl⟩ ha
    

Proof state:
case intro
α : Type u_1
r : Setoid α
a y : α
ha : a ∈ {x | Rel r x y}
⊢ {x | Rel r x y} = {x | Rel r x a}

Next tactic:
ext x
/-- Equivalence classes partition the type. -/
theorem classes_eqv_classes {r : Setoid α} (a) : ∃! (b : _) (_ : b ∈ r.classes), a ∈ b :=
  ExistsUnique.intro₂ { x | r.Rel x a } (r.mem_classes a) (r.refl' _) <| by
    rintro _ ⟨y, rfl⟩ ha
    ext x
    

Proof state:
case intro.h
α : Type u_1
r : Setoid α
a y : α
ha : a ∈ {x | Rel r x y}
x : α
⊢ x ∈ {x | Rel r x y} ↔ x ∈ {x | Rel r x a}

Next tactic:
exact ⟨fun hx => r.trans' hx (r.symm' ha), fun hx => r.trans' hx ha⟩
theorem eqv_class_mem' {c : Set (Set α)} (H : ∀ a, ∃! (b : _) (_ : b ∈ c), a ∈ b) {x} :
    { y : α | (mkClasses c H).Rel x y } ∈ c := by
  

Proof state:
α : Type u_1
c : Set (Set α)
H : ∀ (a : α), ∃! b x, a ∈ b
x : α
⊢ {y | Rel (mkClasses c H) x y} ∈ c

Next tactic:
convert @Setoid.eqv_class_mem _ _ H x using 3
theorem eqv_class_mem' {c : Set (Set α)} (H : ∀ a, ∃! (b : _) (_ : b ∈ c), a ∈ b) {x} :
    { y : α | (mkClasses c H).Rel x y } ∈ c := by
  convert @Setoid.eqv_class_mem _ _ H x using 3
  

Proof state:
case h.e'_4.h.e'_2.h.a
α : Type u_1
c : Set (Set α)
H : ∀ (a : α), ∃! b x, a ∈ b
x x✝ : α
⊢ Rel (mkClasses c H) x x✝ ↔ Rel (mkClasses c H) x✝ x

Next tactic:
rw [Setoid.comm']
/-- A set of disjoint sets covering α partition α (classical). -/
theorem eqv_classes_of_disjoint_union {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α)
    (H : c.PairwiseDisjoint id) (a) : ∃! (b : _) (_ : b ∈ c), a ∈ b :=
  let ⟨b, hc, ha⟩ := Set.mem_sUnion.1 <| show a ∈ _ by 

Proof state:
α : Type u_1
c : Set (Set α)
hu : ⋃₀ c = Set.univ
H : Set.PairwiseDisjoint c id
a : α
⊢ a ∈ ⋃₀ c

Next tactic:
rw [hu]
/-- A set of disjoint sets covering α partition α (classical). -/
theorem eqv_classes_of_disjoint_union {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α)
    (H : c.PairwiseDisjoint id) (a) : ∃! (b : _) (_ : b ∈ c), a ∈ b :=
  let ⟨b, hc, ha⟩ := Set.mem_sUnion.1 <| show a ∈ _ by rw [hu]; 

Proof state:
α : Type u_1
c : Set (Set α)
hu : ⋃₀ c = Set.univ
H : Set.PairwiseDisjoint c id
a : α
⊢ a ∈ Set.univ

Next tactic:
exact Set.mem_univ a
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  

Proof state:
α : Type u_1
r : Setoid α
⊢ Quotient r ≃ ↑(classes r)

Next tactic:
let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  

Proof state:
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
⊢ Quotient r ≃ ↑(classes r)

Next tactic:
have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    

Proof state:
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
a b : α
a_rel_b : Setoid.r a b
⊢ f a = f b

Next tactic:
rw [Subtype.mk.injEq]
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    

Proof state:
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
a b : α
a_rel_b : Setoid.r a b
⊢ {x | Setoid.r x a} = {x | Setoid.r x b}

Next tactic:
exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
  

Proof state:
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
f_respects_relation : ∀ (a b : α), Setoid.r a b → f a = f b
⊢ Quotient r ≃ ↑(classes r)

Next tactic:
apply Equiv.ofBijective (Quot.lift f f_respects_relation)
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
  apply Equiv.ofBijective (Quot.lift f f_respects_relation)
  

Proof state:
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
f_respects_relation : ∀ (a b : α), Setoid.r a b → f a = f b
⊢ Function.Bijective (Quot.lift f f_respects_relation)

Next tactic:
constructor
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
  apply Equiv.ofBijective (Quot.lift f f_respects_relation)
  constructor
  · 

Proof state:
case left
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
f_respects_relation : ∀ (a b : α), Setoid.r a b → f a = f b
⊢ Function.Injective (Quot.lift f f_respects_relation)

Next tactic:
intro (q_a : Quotient r) (q_b : Quotient r) h_eq
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
  apply Equiv.ofBijective (Quot.lift f f_respects_relation)
  constructor
  · intro (q_a : Quotient r) (q_b : Quotient r) h_eq
    

Proof state:
case left
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
f_respects_relation : ∀ (a b : α), Setoid.r a b → f a = f b
q_a q_b : Quotient r
h_eq : Quot.lift f f_respects_relation q_a = Quot.lift f f_respects_relation q_b
⊢ q_a = q_b

Next tactic:
induction' q_a using Quotient.ind with a
/-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r := by
  let f (a : α) : Setoid.classes r := ⟨{ x | Setoid.r x a }, Setoid.mem_classes r a⟩
  have f_respects_relation (a b : α) (a_rel_b : Setoid.r a b) : f a = f b := by
    rw [Subtype.mk.injEq]
    exact Setoid.eq_of_mem_classes (Setoid.mem_classes r a) (Setoid.symm a_rel_b)
        (Setoid.mem_classes r b) (Setoid.refl b)
  apply Equiv.ofBijective (Quot.lift f f_respects_relation)
  constructor
  · intro (q_a : Quotient r) (q_b : Quotient r) h_eq
    induction' q_a using Quotient.ind with a
    

Proof state:
case left.a
α : Type u_1
r : Setoid α
f : α → ↑(classes r) := fun a => { val := {x | Setoid.r x a}, property := (_ : {x | Rel r x a} ∈ classes r) }
f_respects_relation : ∀ (a b : α), Setoid.r a b → f a = f b
q_b : Quotient r
a : α
h_eq : Quot.lift f f_respects_relation ⟦a⟧ = Quot.lift f f_respects_relation q_b
⊢ ⟦a⟧ = q_b

Next tactic:
induction' q_b using Quotient.ind with b