l3lab/ntp-mathlib huggingface dataset:
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    

Proof state:
case mpr.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
r : Set ((α × β) × α × β)
r_in : r ∈ (𝓤 (α × β)).sets
⊢ ((a₁, b₁), a₂, b₂) ∈ r

Next tactic:
rw [uniformity_prod] at r_in
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    

Proof state:
case mpr.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
r : Set ((α × β) × α × β)
r_in : r ∈ (Filter.comap (fun p => (p.1.1, p.2.1)) (𝓤 α) ⊓ Filter.comap (fun p => (p.1.2, p.2.2)) (𝓤 β)).sets
⊢ ((a₁, b₁), a₂, b₂) ∈ r

Next tactic:
rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    

Proof state:
case mpr.intro.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
⊢ ((a₁, b₁), a₂, b₂) ∈ t_α ∩ t_β

Next tactic:
let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
    

Proof state:
case mpr.intro.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
p_α : (α × β) × α × β → α × α := fun p => (p.1.1, p.2.1)
⊢ ((a₁, b₁), a₂, b₂) ∈ t_α ∩ t_β

Next tactic:
let p_β := fun p : (α × β) × α × β => (p.1.2, p.2.2)
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
    let p_β := fun p : (α × β) × α × β => (p.1.2, p.2.2)
    

Proof state:
case mpr.intro.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
p_α : (α × β) × α × β → α × α := fun p => (p.1.1, p.2.1)
p_β : (α × β) × α × β → β × β := fun p => (p.1.2, p.2.2)
⊢ ((a₁, b₁), a₂, b₂) ∈ t_α ∩ t_β

Next tactic:
have key_α : p_α ((a₁, b₁), (a₂, b₂)) ∈ r_α := by simp [eqv_α r_α r_α_in]
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
    let p_β := fun p : (α × β) × α × β => (p.1.2, p.2.2)
    have key_α : p_α ((a₁, b₁), (a₂, b₂)) ∈ r_α := by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
p_α : (α × β) × α × β → α × α := fun p => (p.1.1, p.2.1)
p_β : (α × β) × α × β → β × β := fun p => (p.1.2, p.2.2)
⊢ p_α ((a₁, b₁), a₂, b₂) ∈ r_α

Next tactic:
simp [eqv_α r_α r_α_in]
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
    let p_β := fun p : (α × β) × α × β => (p.1.2, p.2.2)
    have key_α : p_α ((a₁, b₁), (a₂, b₂)) ∈ r_α := by simp [eqv_α r_α r_α_in]
    

Proof state:
case mpr.intro.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
p_α : (α × β) × α × β → α × α := fun p => (p.1.1, p.2.1)
p_β : (α × β) × α × β → β × β := fun p => (p.1.2, p.2.2)
key_α : p_α ((a₁, b₁), a₂, b₂) ∈ r_α
⊢ ((a₁, b₁), a₂, b₂) ∈ t_α ∩ t_β

Next tactic:
have key_β : p_β ((a₁, b₁), (a₂, b₂)) ∈ r_β := by simp [eqv_β r_β r_β_in]
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
    let p_β := fun p : (α × β) × α × β => (p.1.2, p.2.2)
    have key_α : p_α ((a₁, b₁), (a₂, b₂)) ∈ r_α := by simp [eqv_α r_α r_α_in]
    have key_β : p_β ((a₁, b₁), (a₂, b₂)) ∈ r_β := by 

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
p_α : (α × β) × α × β → α × α := fun p => (p.1.1, p.2.1)
p_β : (α × β) × α × β → β × β := fun p => (p.1.2, p.2.2)
key_α : p_α ((a₁, b₁), a₂, b₂) ∈ r_α
⊢ p_β ((a₁, b₁), a₂, b₂) ∈ r_β

Next tactic:
simp [eqv_β r_β r_β_in]
theorem separation_prod {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) ≈ (a₂, b₂) ↔ a₁ ≈ a₂ ∧ b₁ ≈ b₂ := by
  constructor
  · intro h
    exact
      ⟨separated_of_uniformContinuous uniformContinuous_fst h,
        separated_of_uniformContinuous uniformContinuous_snd h⟩
  · rintro ⟨eqv_α, eqv_β⟩ r r_in
    rw [uniformity_prod] at r_in
    rcases r_in with ⟨t_α, ⟨r_α, r_α_in, h_α⟩, t_β, ⟨r_β, r_β_in, h_β⟩, rfl⟩
    let p_α := fun p : (α × β) × α × β => (p.1.1, p.2.1)
    let p_β := fun p : (α × β) × α × β => (p.1.2, p.2.2)
    have key_α : p_α ((a₁, b₁), (a₂, b₂)) ∈ r_α := by simp [eqv_α r_α r_α_in]
    have key_β : p_β ((a₁, b₁), (a₂, b₂)) ∈ r_β := by simp [eqv_β r_β r_β_in]
    

Proof state:
case mpr.intro.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
a₁ a₂ : α
b₁ b₂ : β
eqv_α : a₁ ≈ a₂
eqv_β : b₁ ≈ b₂
t_α : Set ((α × β) × α × β)
r_α : Set (α × α)
r_α_in : r_α ∈ 𝓤 α
h_α : (fun p => (p.1.1, p.2.1)) ⁻¹' r_α ⊆ t_α
t_β : Set ((α × β) × α × β)
r_β : Set (β × β)
r_β_in : r_β ∈ 𝓤 β
h_β : (fun p => (p.1.2, p.2.2)) ⁻¹' r_β ⊆ t_β
p_α : (α × β) × α × β → α × α := fun p => (p.1.1, p.2.1)
p_β : (α × β) × α × β → β × β := fun p => (p.1.2, p.2.2)
key_α : p_α ((a₁, b₁), a₂, b₂) ∈ r_α
key_β : p_β ((a₁, b₁), a₂, b₂) ∈ r_β
⊢ ((a₁, b₁), a₂, b₂) ∈ t_α ∩ t_β

Next tactic:
exact ⟨h_α key_α, h_β key_β⟩
theorem eq_of_veq : ∀ {s t : Finset α}, s.1 = t.1 → s = t
  | ⟨s, _⟩, ⟨t, _⟩, h => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Multiset α
nodup✝¹ : Nodup s
t : Multiset α
nodup✝ : Nodup t
h : { val := s, nodup := nodup✝¹ }.val = { val := t, nodup := nodup✝ }.val
⊢ { val := s, nodup := nodup✝¹ } = { val := t, nodup := nodup✝ }

Next tactic:
cases h
theorem eq_of_veq : ∀ {s t : Finset α}, s.1 = t.1 → s = t
  | ⟨s, _⟩, ⟨t, _⟩, h => by cases h; 

Proof state:
case refl
α : Type u_1
β : Type u_2
γ : Type u_3
s : Multiset α
nodup✝¹ nodup✝ : Nodup s
⊢ { val := s, nodup := nodup✝¹ } = { val := s, nodup := nodup✝ }

Next tactic:
rfl
@[simp] lemma forall_mem_not_eq {s : Finset α} {a : α} : (∀ b ∈ s, ¬ a = b) ↔ a ∉ s := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a : α
⊢ (∀ b ∈ s, ¬a = b) ↔ a ∉ s

Next tactic:
aesop
@[simp] lemma forall_mem_not_eq' {s : Finset α} {a : α} : (∀ b ∈ s, ¬ b = a) ↔ a ∉ s := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a : α
⊢ (∀ b ∈ s, ¬b = a) ↔ a ∉ s

Next tactic:
aesop
instance : IsRefl (Finset α) (· ⊆ ·) :=
  show IsRefl (Finset α) (· ≤ ·) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ IsRefl (Finset α) fun x x_1 => x ≤ x_1

Next tactic:
infer_instance
instance : IsTrans (Finset α) (· ⊆ ·) :=
  show IsTrans (Finset α) (· ≤ ·) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ IsTrans (Finset α) fun x x_1 => x ≤ x_1

Next tactic:
infer_instance
instance : IsAntisymm (Finset α) (· ⊆ ·) :=
  show IsAntisymm (Finset α) (· ≤ ·) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ IsAntisymm (Finset α) fun x x_1 => x ≤ x_1

Next tactic:
infer_instance
instance : IsIrrefl (Finset α) (· ⊂ ·) :=
  show IsIrrefl (Finset α) (· < ·) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ IsIrrefl (Finset α) fun x x_1 => x < x_1

Next tactic:
infer_instance
instance : IsTrans (Finset α) (· ⊂ ·) :=
  show IsTrans (Finset α) (· < ·) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ IsTrans (Finset α) fun x x_1 => x < x_1

Next tactic:
infer_instance
instance : IsAsymm (Finset α) (· ⊂ ·) :=
  show IsAsymm (Finset α) (· < ·) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ IsAsymm (Finset α) fun x x_1 => x < x_1

Next tactic:
infer_instance
theorem not_subset : ¬s ⊆ t ↔ ∃ x ∈ s, x ∉ t := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Finset α
⊢ ¬s ⊆ t ↔ ∃ x ∈ s, x ∉ t

Next tactic:
simp only [← coe_subset, Set.not_subset, mem_coe]
@[simp, norm_cast]
theorem coe_ssubset {s₁ s₂ : Finset α} : (s₁ : Set α) ⊂ s₂ ↔ s₁ ⊂ s₂ :=
  show (s₁ : Set α) ⊂ s₂ ↔ s₁ ⊆ s₂ ∧ ¬s₂ ⊆ s₁ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t s₁ s₂ : Finset α
⊢ ↑s₁ ⊂ ↑s₂ ↔ s₁ ⊆ s₂ ∧ ¬s₂ ⊆ s₁

Next tactic:
simp only [Set.ssubset_def, Finset.coe_subset]
instance decidableNonempty {s : Finset α} : Decidable s.Nonempty :=
  Quotient.recOnSubsingleton (motive := fun s : Multiset α => Decidable (∃ a, a ∈ s)) s.1
    (fun l : List α =>
      match l with
      | [] => isFalse <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
l : List α
⊢ ¬∃ a, a ∈ ⟦[]⟧

Next tactic:
simp
instance decidableNonempty {s : Finset α} : Decidable s.Nonempty :=
  Quotient.recOnSubsingleton (motive := fun s : Multiset α => Decidable (∃ a, a ∈ s)) s.1
    (fun l : List α =>
      match l with
      | [] => isFalse <| by simp
      | a::l => isTrue ⟨a, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
l✝ : List α
a : α
l : List α
⊢ a ∈ ⟦a :: l⟧

Next tactic:
simp
@[simp]
theorem not_mem_empty (a : α) : a ∉ (∅ : Finset α) := by
  -- Porting note: was `id`. `a ∈ List.nil` is no longer definitionally equal to `False`
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a : α
⊢ a ∉ ∅

Next tactic:
simp only [mem_def, empty_val, not_mem_zero, not_false_iff]
theorem eq_empty_iff_forall_not_mem {s : Finset α} : s = ∅ ↔ ∀ x, x ∉ s :=
  -- Porting note: used `id`
  ⟨by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s : Finset α
⊢ s = ∅ → ∀ (x : α), x ∉ s

Next tactic:
rintro rfl x
theorem eq_empty_iff_forall_not_mem {s : Finset α} : s = ∅ ↔ ∀ x, x ∉ s :=
  -- Porting note: used `id`
  ⟨by rintro rfl x; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
x : α
⊢ x ∉ ∅

Next tactic:
apply not_mem_empty
@[simp, norm_cast]
theorem coe_empty : ((∅ : Finset α) : Set α) = ∅ :=
  Set.ext <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
⊢ ∀ (x : α), x ∈ ↑∅ ↔ x ∈ ∅

Next tactic:
simp
@[simp, norm_cast]
theorem coe_eq_empty {s : Finset α} : (s : Set α) = ∅ ↔ s = ∅ := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s : Finset α
⊢ ↑s = ∅ ↔ s = ∅

Next tactic:
rw [← coe_empty, coe_inj]
theorem isEmpty_coe_sort {s : Finset α} : IsEmpty (s : Type _) ↔ s = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s : Finset α
⊢ IsEmpty { x // x ∈ s } ↔ s = ∅

Next tactic:
simpa using @Set.isEmpty_coe_sort α s
@[simp]
theorem val_eq_singleton_iff {a : α} {s : Finset α} : s.val = {a} ↔ s = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b a : α
s : Finset α
⊢ s.val = {a} ↔ s = {a}

Next tactic:
rw [← val_inj]
@[simp]
theorem val_eq_singleton_iff {a : α} {s : Finset α} : s.val = {a} ↔ s = {a} := by
  rw [← val_inj]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b a : α
s : Finset α
⊢ s.val = {a} ↔ s.val = {a}.val

Next tactic:
rfl
@[simp, norm_cast]
theorem coe_singleton (a : α) : (({a} : Finset α) : Set α) = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a✝ b a : α
⊢ ↑{a} = {a}

Next tactic:
ext
@[simp, norm_cast]
theorem coe_singleton (a : α) : (({a} : Finset α) : Set α) = {a} := by
  ext
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a✝ b a x✝ : α
⊢ x✝ ∈ ↑{a} ↔ x✝ ∈ {a}

Next tactic:
simp
@[simp, norm_cast]
theorem coe_eq_singleton {s : Finset α} {a : α} : (s : Set α) = {a} ↔ s = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ ↑s = {a} ↔ s = {a}

Next tactic:
rw [← coe_singleton, coe_inj]
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a

Next tactic:
constructor
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ s = {a} → a ∈ s ∧ ∀ x ∈ s, x = a

Next tactic:
intro t
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> 

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ (a ∈ s ∧ ∀ x ∈ s, x = a) → s = {a}

Next tactic:
intro t
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> intro t
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
t : s = {a}
⊢ a ∈ s ∧ ∀ x ∈ s, x = a

Next tactic:
rw [t]
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> intro t
  · rw [t]
    

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
t : s = {a}
⊢ a ∈ {a} ∧ ∀ x ∈ {a}, x = a

Next tactic:
exact ⟨Finset.mem_singleton_self _, fun _ => Finset.mem_singleton.1⟩
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> intro t
  · rw [t]
    exact ⟨Finset.mem_singleton_self _, fun _ => Finset.mem_singleton.1⟩
  · 

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
t : a ∈ s ∧ ∀ x ∈ s, x = a
⊢ s = {a}

Next tactic:
ext
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> intro t
  · rw [t]
    exact ⟨Finset.mem_singleton_self _, fun _ => Finset.mem_singleton.1⟩
  · ext
    

Proof state:
case mpr.a
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝¹ b : α
s : Finset α
a : α
t : a ∈ s ∧ ∀ x ∈ s, x = a
a✝ : α
⊢ a✝ ∈ s ↔ a✝ ∈ {a}

Next tactic:
rw [Finset.mem_singleton]
theorem eq_singleton_iff_unique_mem {s : Finset α} {a : α} : s = {a} ↔ a ∈ s ∧ ∀ x ∈ s, x = a := by
  constructor <;> intro t
  · rw [t]
    exact ⟨Finset.mem_singleton_self _, fun _ => Finset.mem_singleton.1⟩
  · ext
    rw [Finset.mem_singleton]
    

Proof state:
case mpr.a
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝¹ b : α
s : Finset α
a : α
t : a ∈ s ∧ ∀ x ∈ s, x = a
a✝ : α
⊢ a✝ ∈ s ↔ a✝ = a

Next tactic:
exact ⟨t.right _, fun r => r.symm ▸ t.left⟩
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ s = {a} ↔ Finset.Nonempty s ∧ ∀ x ∈ s, x = a

Next tactic:
constructor
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ s = {a} → Finset.Nonempty s ∧ ∀ x ∈ s, x = a

Next tactic:
rintro rfl
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · rintro rfl
    

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a✝ b a : α
⊢ Finset.Nonempty {a} ∧ ∀ x ∈ {a}, x = a

Next tactic:
simp
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · rintro rfl
    simp
  · 

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ (Finset.Nonempty s ∧ ∀ x ∈ s, x = a) → s = {a}

Next tactic:
rintro ⟨hne, h_uniq⟩
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · rintro rfl
    simp
  · rintro ⟨hne, h_uniq⟩
    

Proof state:
case mpr.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
hne : Finset.Nonempty s
h_uniq : ∀ x ∈ s, x = a
⊢ s = {a}

Next tactic:
rw [eq_singleton_iff_unique_mem]
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · rintro rfl
    simp
  · rintro ⟨hne, h_uniq⟩
    rw [eq_singleton_iff_unique_mem]
    

Proof state:
case mpr.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
hne : Finset.Nonempty s
h_uniq : ∀ x ∈ s, x = a
⊢ a ∈ s ∧ ∀ x ∈ s, x = a

Next tactic:
refine' ⟨_, h_uniq⟩
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · rintro rfl
    simp
  · rintro ⟨hne, h_uniq⟩
    rw [eq_singleton_iff_unique_mem]
    refine' ⟨_, h_uniq⟩
    

Proof state:
case mpr.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
hne : Finset.Nonempty s
h_uniq : ∀ x ∈ s, x = a
⊢ a ∈ s

Next tactic:
rw [← h_uniq hne.choose hne.choose_spec]
theorem eq_singleton_iff_nonempty_unique_mem {s : Finset α} {a : α} :
    s = {a} ↔ s.Nonempty ∧ ∀ x ∈ s, x = a := by
  constructor
  · rintro rfl
    simp
  · rintro ⟨hne, h_uniq⟩
    rw [eq_singleton_iff_unique_mem]
    refine' ⟨_, h_uniq⟩
    rw [← h_uniq hne.choose hne.choose_spec]
    

Proof state:
case mpr.intro
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
hne : Finset.Nonempty s
h_uniq : ∀ x ∈ s, x = a
⊢ Exists.choose hne ∈ s

Next tactic:
exact hne.choose_spec
theorem nonempty_iff_eq_singleton_default [Unique α] {s : Finset α} : s.Nonempty ↔ s = {default} :=
  by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a b : α
inst✝ : Unique α
s : Finset α
⊢ Finset.Nonempty s ↔ s = {default}

Next tactic:
simp [eq_singleton_iff_nonempty_unique_mem, eq_iff_true_of_subsingleton]
theorem singleton_iff_unique_mem (s : Finset α) : (∃ a, s = {a}) ↔ ∃! a, a ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a b : α
s : Finset α
⊢ (∃ a, s = {a}) ↔ ∃! a, a ∈ s

Next tactic:
simp only [eq_singleton_iff_unique_mem, ExistsUnique]
theorem singleton_subset_set_iff {s : Set α} {a : α} : ↑({a} : Finset α) ⊆ s ↔ a ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Set α
a : α
⊢ ↑{a} ⊆ s ↔ a ∈ s

Next tactic:
rw [coe_singleton, Set.singleton_subset_iff]
@[simp]
theorem subset_singleton_iff {s : Finset α} {a : α} : s ⊆ {a} ↔ s = ∅ ∨ s = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ s ⊆ {a} ↔ s = ∅ ∨ s = {a}

Next tactic:
rw [← coe_subset, coe_singleton, Set.subset_singleton_iff_eq, coe_eq_empty, coe_eq_singleton]
theorem singleton_subset_singleton : ({a} : Finset α) ⊆ {b} ↔ a = b := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a b : α
⊢ {a} ⊆ {b} ↔ a = b

Next tactic:
simp
@[simp]
theorem ssubset_singleton_iff {s : Finset α} {a : α} : s ⊂ {a} ↔ s = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ : Finset α
a✝ b : α
s : Finset α
a : α
⊢ s ⊂ {a} ↔ s = ∅

Next tactic:
rw [← coe_ssubset, coe_singleton, Set.ssubset_singleton_iff, coe_eq_empty]
@[simp]
theorem not_nontrivial_empty : ¬ (∅ : Finset α).Nontrivial := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a b : α
⊢ ¬Finset.Nontrivial ∅

Next tactic:
simp [Finset.Nontrivial]
@[simp]
theorem not_nontrivial_singleton : ¬ ({a} : Finset α).Nontrivial := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a b : α
⊢ ¬Finset.Nontrivial {a}

Next tactic:
simp [Finset.Nontrivial]
theorem Nontrivial.ne_singleton (hs : s.Nontrivial) : s ≠ {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s : Finset α
a b : α
hs : Finset.Nontrivial s
⊢ s ≠ {a}

Next tactic:
rintro rfl
theorem Nontrivial.ne_singleton (hs : s.Nontrivial) : s ≠ {a} := by
  rintro rfl; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
a b : α
hs : Finset.Nontrivial {a}
⊢ False

Next tactic:
exact not_nontrivial_singleton hs