l3lab/ntp-mathlib huggingface dataset:
/-- Note this is a special case of `(Finset.image_preimage f univ _).symm`. -/
theorem univ_filter_mem_range (f : α → β) [Fintype β] [DecidablePred fun y => y ∈ Set.range f]
    [DecidableEq β] : (Finset.univ.filter fun y => y ∈ Set.range f) = Finset.univ.image f := by
  letI : DecidablePred (fun y => ∃ x, f x = y) := by simpa using ‹_›
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : Fintype α
s t : Finset α
f : α → β
inst✝² : Fintype β
inst✝¹ : DecidablePred fun y => y ∈ Set.range f
inst✝ : DecidableEq β
this : DecidablePred fun y => ∃ x, f x = y := inst✝¹
⊢ filter (fun y => y ∈ Set.range f) univ = image f univ

Next tactic:
exact univ_filter_exists f
theorem coe_filter_univ (p : α → Prop) [DecidablePred p] : (univ.filter p : Set α) = { x | p x } :=
  by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Fintype α
s t : Finset α
p : α → Prop
inst✝ : DecidablePred p
⊢ ↑(filter p univ) = {x | p x}

Next tactic:
simp
@[simp] lemma subtype_eq_univ {p : α → Prop} [DecidablePred p] [Fintype {a // p a}] :
    s.subtype p = univ ↔ ∀ ⦃a⦄, p a → a ∈ s := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
s t : Finset α
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : Fintype { a // p a }
⊢ Finset.subtype p s = univ ↔ ∀ ⦃a : α⦄, p a → a ∈ s

Next tactic:
simp [ext_iff]
@[simp] lemma subtype_univ [Fintype α] (p : α → Prop) [DecidablePred p] [Fintype {a // p a}] :
    univ.subtype p = univ := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : Fintype α
s t : Finset α
inst✝² : Fintype α
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : Fintype { a // p a }
⊢ Finset.subtype p univ = univ

Next tactic:
simp
instance decidablePiFintype {α} {β : α → Type*} [∀ a, DecidableEq (β a)] [Fintype α] :
    DecidableEq (∀ a, β a) := fun f g =>
  decidable_of_iff (∀ a ∈ @Fintype.elems α _, f a = g a)
    (by 

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type ?u.40282
β : α → Type u_4
inst✝¹ : (a : α) → DecidableEq (β a)
inst✝ : Fintype α
f g : (a : α) → β a
⊢ (∀ a ∈ elems, f a = g a) ↔ f = g

Next tactic:
simp [Function.funext_iff, Fintype.complete]
instance decidableForallFintype {p : α → Prop} [DecidablePred p] [Fintype α] :
    Decidable (∀ a, p a) :=
  decidable_of_iff (∀ a ∈ @univ α _, p a) (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : Fintype α
⊢ (∀ a ∈ univ, p a) ↔ ∀ (a : α), p a

Next tactic:
simp
instance decidableExistsFintype {p : α → Prop} [DecidablePred p] [Fintype α] :
    Decidable (∃ a, p a) :=
  decidable_of_iff (∃ a ∈ @univ α _, p a) (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : Fintype α
⊢ (∃ a ∈ univ, p a) ↔ ∃ a, p a

Next tactic:
simp
instance decidableInjectiveFintype [DecidableEq α] [DecidableEq β] [Fintype α] :
    DecidablePred (Injective : (α → β) → Prop) := fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : Fintype α
x : α → β
⊢ Decidable (Injective x)

Next tactic:
unfold Injective
instance decidableInjectiveFintype [DecidableEq α] [DecidableEq β] [Fintype α] :
    DecidablePred (Injective : (α → β) → Prop) := fun x => by unfold Injective; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : DecidableEq α
inst✝¹ : DecidableEq β
inst✝ : Fintype α
x : α → β
⊢ Decidable (∀ ⦃a₁ a₂ : α⦄, x a₁ = x a₂ → a₁ = a₂)

Next tactic:
infer_instance
instance decidableSurjectiveFintype [DecidableEq β] [Fintype α] [Fintype β] :
    DecidablePred (Surjective : (α → β) → Prop) := fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : DecidableEq β
inst✝¹ : Fintype α
inst✝ : Fintype β
x : α → β
⊢ Decidable (Surjective x)

Next tactic:
unfold Surjective
instance decidableSurjectiveFintype [DecidableEq β] [Fintype α] [Fintype β] :
    DecidablePred (Surjective : (α → β) → Prop) := fun x => by unfold Surjective; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : DecidableEq β
inst✝¹ : Fintype α
inst✝ : Fintype β
x : α → β
⊢ Decidable (∀ (b : β), ∃ a, x a = b)

Next tactic:
infer_instance
instance decidableBijectiveFintype [DecidableEq α] [DecidableEq β] [Fintype α] [Fintype β] :
    DecidablePred (Bijective : (α → β) → Prop) := fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : DecidableEq α
inst✝² : DecidableEq β
inst✝¹ : Fintype α
inst✝ : Fintype β
x : α → β
⊢ Decidable (Bijective x)

Next tactic:
unfold Bijective
instance decidableBijectiveFintype [DecidableEq α] [DecidableEq β] [Fintype α] [Fintype β] :
    DecidablePred (Bijective : (α → β) → Prop) := fun x => by unfold Bijective; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝³ : DecidableEq α
inst✝² : DecidableEq β
inst✝¹ : Fintype α
inst✝ : Fintype β
x : α → β
⊢ Decidable (Injective x ∧ Surjective x)

Next tactic:
infer_instance
instance decidableRightInverseFintype [DecidableEq α] [Fintype α] (f : α → β) (g : β → α) :
    Decidable (Function.RightInverse f g) :=
  show Decidable (∀ x, g (f x) = x) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : Fintype α
f : α → β
g : β → α
⊢ Decidable (∀ (x : α), g (f x) = x)

Next tactic:
infer_instance
instance decidableLeftInverseFintype [DecidableEq β] [Fintype β] (f : α → β) (g : β → α) :
    Decidable (Function.LeftInverse f g) :=
  show Decidable (∀ x, f (g x) = x) by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq β
inst✝ : Fintype β
f : α → β
g : β → α
⊢ Decidable (∀ (x : β), f (g x) = x)

Next tactic:
infer_instance
/-- Construct a proof of `Fintype α` from a universal multiset -/
def ofMultiset [DecidableEq α] (s : Multiset α) (H : ∀ x : α, x ∈ s) : Fintype α :=
  ⟨s.toFinset, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s : Multiset α
H : ∀ (x : α), x ∈ s
⊢ ∀ (x : α), x ∈ Multiset.toFinset s

Next tactic:
simpa using H
/-- Construct a proof of `Fintype α` from a universal list -/
def ofList [DecidableEq α] (l : List α) (H : ∀ x : α, x ∈ l) : Fintype α :=
  ⟨l.toFinset, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
l : List α
H : ∀ (x : α), x ∈ l
⊢ ∀ (x : α), x ∈ List.toFinset l

Next tactic:
simpa using H
instance subsingleton (α : Type*) : Subsingleton (Fintype α) :=
  ⟨fun ⟨s₁, h₁⟩ ⟨s₂, h₂⟩ => by 

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
α : Type u_4
x✝¹ x✝ : Fintype α
s₁ : Finset α
h₁ : ∀ (x : α), x ∈ s₁
s₂ : Finset α
h₂ : ∀ (x : α), x ∈ s₂
⊢ { elems := s₁, complete := h₁ } = { elems := s₂, complete := h₂ }

Next tactic:
congr
instance subsingleton (α : Type*) : Subsingleton (Fintype α) :=
  ⟨fun ⟨s₁, h₁⟩ ⟨s₂, h₂⟩ => by congr; 

Proof state:
case e_elems
α✝ : Type u_1
β : Type u_2
γ : Type u_3
α : Type u_4
x✝¹ x✝ : Fintype α
s₁ : Finset α
h₁ : ∀ (x : α), x ∈ s₁
s₂ : Finset α
h₂ : ∀ (x : α), x ∈ s₂
⊢ s₁ = s₂

Next tactic:
simp [Finset.ext_iff, h₁, h₂]
/-- The inverse of an `hf : injective` function `f : α → β`, of the type `↥(Set.range f) → α`.
This is the computable version of `Function.invFun` that requires `Fintype α` and `DecidableEq β`,
or the function version of applying `(Equiv.ofInjective f hf).symm`.
This function should not usually be used for actual computation because for most cases,
an explicit inverse can be stated that has better computational properties.
This function computes by checking all terms `a : α` to find the `f a = b`, so it is O(N) where
`N = Fintype.card α`.
-/
def invOfMemRange : Set.range f → α := fun b =>
  Finset.choose (fun a => f a = b) Finset.univ
    ((exists_unique_congr (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Fintype α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
b : ↑(Set.range f)
⊢ ∀ (a : α), f a = ↑b ↔ a ∈ univ ∧ (fun a => f a = ↑b) a

Next tactic:
simp
theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = hf.invOfMemRange := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
inst✝¹ : DecidableEq β
f : α → β
hf : Injective f
inst✝ : Nonempty α
⊢ Set.restrict (Set.range f) (invFun f) = invOfMemRange hf

Next tactic:
ext ⟨b, h⟩
theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = hf.invOfMemRange := by
  ext ⟨b, h⟩
  

Proof state:
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
inst✝¹ : DecidableEq β
f : α → β
hf : Injective f
inst✝ : Nonempty α
b : β
h : b ∈ Set.range f
⊢ Set.restrict (Set.range f) (invFun f) { val := b, property := h } = invOfMemRange hf { val := b, property := h }

Next tactic:
apply hf
theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = hf.invOfMemRange := by
  ext ⟨b, h⟩
  apply hf
  

Proof state:
case h.mk.a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
inst✝¹ : DecidableEq β
f : α → β
hf : Injective f
inst✝ : Nonempty α
b : β
h : b ∈ Set.range f
⊢ f (Set.restrict (Set.range f) (invFun f) { val := b, property := h }) =
    f (invOfMemRange hf { val := b, property := h })

Next tactic:
simp [hf.left_inv_of_invOfMemRange, @invFun_eq _ _ _ f b (Set.mem_range.mp h)]
theorem invOfMemRange_surjective : Function.Surjective hf.invOfMemRange := fun a =>
  ⟨⟨f a, Set.mem_range_self a⟩, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Fintype α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
a : α
⊢ invOfMemRange hf { val := f a, property := (_ : f a ∈ Set.range f) } = a

Next tactic:
simp
theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = f.invOfMemRange := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
inst✝¹ : DecidableEq β
f : α ↪ β
b : ↑(Set.range ⇑f)
inst✝ : Nonempty α
⊢ Set.restrict (Set.range ⇑f) (invFun ⇑f) = invOfMemRange f

Next tactic:
ext ⟨b, h⟩
theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = f.invOfMemRange := by
  ext ⟨b, h⟩
  

Proof state:
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
inst✝¹ : DecidableEq β
f : α ↪ β
b✝ : ↑(Set.range ⇑f)
inst✝ : Nonempty α
b : β
h : b ∈ Set.range ⇑f
⊢ Set.restrict (Set.range ⇑f) (invFun ⇑f) { val := b, property := h } = invOfMemRange f { val := b, property := h }

Next tactic:
apply f.injective
theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = f.invOfMemRange := by
  ext ⟨b, h⟩
  apply f.injective
  

Proof state:
case h.mk.a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : Fintype α
inst✝¹ : DecidableEq β
f : α ↪ β
b✝ : ↑(Set.range ⇑f)
inst✝ : Nonempty α
b : β
h : b ∈ Set.range ⇑f
⊢ f (Set.restrict (Set.range ⇑f) (invFun ⇑f) { val := b, property := h }) =
    f (invOfMemRange f { val := b, property := h })

Next tactic:
simp [f.left_inv_of_invOfMemRange, @invFun_eq _ _ _ f b (Set.mem_range.mp h)]
theorem invOfMemRange_surjective : Function.Surjective f.invOfMemRange := fun a =>
  ⟨⟨f a, Set.mem_range_self a⟩, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Fintype α
inst✝ : DecidableEq β
f : α ↪ β
b : ↑(Set.range ⇑f)
a : α
⊢ invOfMemRange f { val := f a, property := (_ : f a ∈ Set.range ⇑f) } = a

Next tactic:
simp
@[congr]
theorem toFinset_congr {s t : Set α} [Fintype s] [Fintype t] (h : s = t) :
    toFinset s = toFinset t := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t✝ s t : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑t
h : s = t
⊢ toFinset s = toFinset t

Next tactic:
subst h
@[congr]
theorem toFinset_congr {s t : Set α} [Fintype s] [Fintype t] (h : s = t) :
    toFinset s = toFinset t := by subst h; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t s : Set α
inst✝¹ inst✝ : Fintype ↑s
⊢ toFinset s = toFinset s

Next tactic:
congr
@[congr]
theorem toFinset_congr {s t : Set α} [Fintype s] [Fintype t] (h : s = t) :
    toFinset s = toFinset t := by subst h; congr; 

Proof state:
case h.e_3.h
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t s : Set α
inst✝¹ inst✝ : Fintype ↑s
⊢ inst✝¹ = inst✝

Next tactic:
exact Subsingleton.elim _ _
@[simp]
theorem mem_toFinset {s : Set α} [Fintype s] {a : α} : a ∈ s.toFinset ↔ a ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t s : Set α
inst✝ : Fintype ↑s
a : α
⊢ a ∈ toFinset s ↔ a ∈ s

Next tactic:
simp [toFinset]
/-- Many `Fintype` instances for sets are defined using an extensionally equal `Finset`.
Rewriting `s.toFinset` with `Set.toFinset_ofFinset` replaces the term with such a `Finset`. -/
theorem toFinset_ofFinset {p : Set α} (s : Finset α) (H : ∀ x, x ∈ s ↔ x ∈ p) :
    @Set.toFinset _ p (Fintype.ofFinset s H) = s :=
  Finset.ext fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t p : Set α
s : Finset α
H : ∀ (x : α), x ∈ s ↔ x ∈ p
x : α
⊢ x ∈ toFinset p ↔ x ∈ s

Next tactic:
rw [@mem_toFinset _ _ (id _), H]
@[simp]
theorem toFinset_nonempty {s : Set α} [Fintype s] : s.toFinset.Nonempty ↔ s.Nonempty := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t s : Set α
inst✝ : Fintype ↑s
⊢ Finset.Nonempty (toFinset s) ↔ Set.Nonempty s

Next tactic:
rw [← Finset.coe_nonempty, coe_toFinset]
@[simp]
theorem toFinset_inj {s t : Set α} [Fintype s] [Fintype t] : s.toFinset = t.toFinset ↔ s = t :=
  ⟨fun h => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t✝ s t : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑t
h : toFinset s = toFinset t
⊢ s = t

Next tactic:
rw [← s.coe_toFinset, h, t.coe_toFinset]
@[simp]
theorem toFinset_inj {s t : Set α} [Fintype s] [Fintype t] : s.toFinset = t.toFinset ↔ s = t :=
  ⟨fun h => by rw [← s.coe_toFinset, h, t.coe_toFinset], fun h => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t✝ s t : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑t
h : s = t
⊢ toFinset s = toFinset t

Next tactic:
simp [h]
@[mono]
theorem toFinset_subset_toFinset [Fintype s] [Fintype t] : s.toFinset ⊆ t.toFinset ↔ s ⊆ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑t
⊢ toFinset s ⊆ toFinset t ↔ s ⊆ t

Next tactic:
simp [Finset.subset_iff, Set.subset_def]
@[simp]
theorem toFinset_ssubset [Fintype s] {t : Finset α} : s.toFinset ⊂ t ↔ s ⊂ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t✝ : Set α
inst✝ : Fintype ↑s
t : Finset α
⊢ toFinset s ⊂ t ↔ s ⊂ ↑t

Next tactic:
rw [← Finset.coe_ssubset, coe_toFinset]
@[simp]
theorem subset_toFinset {s : Finset α} [Fintype t] : s ⊆ t.toFinset ↔ ↑s ⊆ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t : Set α
s : Finset α
inst✝ : Fintype ↑t
⊢ s ⊆ toFinset t ↔ ↑s ⊆ t

Next tactic:
rw [← Finset.coe_subset, coe_toFinset]
@[simp]
theorem ssubset_toFinset {s : Finset α} [Fintype t] : s ⊂ t.toFinset ↔ ↑s ⊂ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t : Set α
s : Finset α
inst✝ : Fintype ↑t
⊢ s ⊂ toFinset t ↔ ↑s ⊂ t

Next tactic:
rw [← Finset.coe_ssubset, coe_toFinset]
@[mono]
theorem toFinset_ssubset_toFinset [Fintype s] [Fintype t] : s.toFinset ⊂ t.toFinset ↔ s ⊂ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑t
⊢ toFinset s ⊂ toFinset t ↔ s ⊂ t

Next tactic:
simp only [Finset.ssubset_def, toFinset_subset_toFinset, ssubset_def]
@[simp]
theorem toFinset_subset [Fintype s] {t : Finset α} : s.toFinset ⊆ t ↔ s ⊆ t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t✝ : Set α
inst✝ : Fintype ↑s
t : Finset α
⊢ toFinset s ⊆ t ↔ s ⊆ ↑t

Next tactic:
rw [← Finset.coe_subset, coe_toFinset]
@[simp]
theorem disjoint_toFinset [Fintype s] [Fintype t] :
    Disjoint s.toFinset t.toFinset ↔ Disjoint s t := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑t
⊢ Disjoint (toFinset s) (toFinset t) ↔ Disjoint s t

Next tactic:
simp only [← disjoint_coe, coe_toFinset]
@[simp]
theorem toFinset_inter [Fintype (s ∩ t : Set _)] : (s ∩ t).toFinset = s.toFinset ∩ t.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s ∩ t)
⊢ toFinset (s ∩ t) = toFinset s ∩ toFinset t

Next tactic:
ext
@[simp]
theorem toFinset_inter [Fintype (s ∩ t : Set _)] : (s ∩ t).toFinset = s.toFinset ∩ t.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s ∩ t)
a✝ : α
⊢ a✝ ∈ toFinset (s ∩ t) ↔ a✝ ∈ toFinset s ∩ toFinset t

Next tactic:
simp
@[simp]
theorem toFinset_union [Fintype (s ∪ t : Set _)] : (s ∪ t).toFinset = s.toFinset ∪ t.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s ∪ t)
⊢ toFinset (s ∪ t) = toFinset s ∪ toFinset t

Next tactic:
ext
@[simp]
theorem toFinset_union [Fintype (s ∪ t : Set _)] : (s ∪ t).toFinset = s.toFinset ∪ t.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s ∪ t)
a✝ : α
⊢ a✝ ∈ toFinset (s ∪ t) ↔ a✝ ∈ toFinset s ∪ toFinset t

Next tactic:
simp
@[simp]
theorem toFinset_diff [Fintype (s \ t : Set _)] : (s \ t).toFinset = s.toFinset \ t.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s \ t)
⊢ toFinset (s \ t) = toFinset s \ toFinset t

Next tactic:
ext
@[simp]
theorem toFinset_diff [Fintype (s \ t : Set _)] : (s \ t).toFinset = s.toFinset \ t.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s \ t)
a✝ : α
⊢ a✝ ∈ toFinset (s \ t) ↔ a✝ ∈ toFinset s \ toFinset t

Next tactic:
simp
@[simp]
theorem toFinset_symmDiff [Fintype (s ∆ t : Set _)] :
    (s ∆ t).toFinset = s.toFinset ∆ t.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s ∆ t)
⊢ toFinset (s ∆ t) = toFinset s ∆ toFinset t

Next tactic:
ext
@[simp]
theorem toFinset_symmDiff [Fintype (s ∆ t : Set _)] :
    (s ∆ t).toFinset = s.toFinset ∆ t.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝³ : DecidableEq α
inst✝² : Fintype ↑s
inst✝¹ : Fintype ↑t
inst✝ : Fintype ↑(s ∆ t)
a✝ : α
⊢ a✝ ∈ toFinset (s ∆ t) ↔ a✝ ∈ toFinset s ∆ toFinset t

Next tactic:
simp [mem_symmDiff, Finset.mem_symmDiff]
@[simp]
theorem toFinset_compl [Fintype α] [Fintype (sᶜ : Set _)] : sᶜ.toFinset = s.toFinsetᶜ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝⁴ : DecidableEq α
inst✝³ : Fintype ↑s
inst✝² : Fintype ↑t
inst✝¹ : Fintype α
inst✝ : Fintype ↑sᶜ
⊢ toFinset sᶜ = (toFinset s)ᶜ

Next tactic:
ext
@[simp]
theorem toFinset_compl [Fintype α] [Fintype (sᶜ : Set _)] : sᶜ.toFinset = s.toFinsetᶜ := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝⁴ : DecidableEq α
inst✝³ : Fintype ↑s
inst✝² : Fintype ↑t
inst✝¹ : Fintype α
inst✝ : Fintype ↑sᶜ
a✝ : α
⊢ a✝ ∈ toFinset sᶜ ↔ a✝ ∈ (toFinset s)ᶜ

Next tactic:
simp
@[simp]
theorem toFinset_empty [Fintype (∅ : Set α)] : (∅ : Set α).toFinset = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝ : Fintype ↑∅
⊢ toFinset ∅ = ∅

Next tactic:
ext
@[simp]
theorem toFinset_empty [Fintype (∅ : Set α)] : (∅ : Set α).toFinset = ∅ := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝ : Fintype ↑∅
a✝ : α
⊢ a✝ ∈ toFinset ∅ ↔ a✝ ∈ ∅

Next tactic:
simp
@[simp]
theorem toFinset_univ [Fintype α] [Fintype (Set.univ : Set α)] :
    (Set.univ : Set α).toFinset = Finset.univ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝¹ : Fintype α
inst✝ : Fintype ↑univ
⊢ toFinset univ = Finset.univ

Next tactic:
ext
@[simp]
theorem toFinset_univ [Fintype α] [Fintype (Set.univ : Set α)] :
    (Set.univ : Set α).toFinset = Finset.univ := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝¹ : Fintype α
inst✝ : Fintype ↑univ
a✝ : α
⊢ a✝ ∈ toFinset univ ↔ a✝ ∈ Finset.univ

Next tactic:
simp
@[simp]
theorem toFinset_eq_empty [Fintype s] : s.toFinset = ∅ ↔ s = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝ : Fintype ↑s
⊢ toFinset s = ∅ ↔ s = ∅

Next tactic:
let A : Fintype (∅ : Set α) := Fintype.ofIsEmpty
@[simp]
theorem toFinset_eq_empty [Fintype s] : s.toFinset = ∅ ↔ s = ∅ := by
  let A : Fintype (∅ : Set α) := Fintype.ofIsEmpty
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝ : Fintype ↑s
A : Fintype ↑∅ := Fintype.ofIsEmpty
⊢ toFinset s = ∅ ↔ s = ∅

Next tactic:
rw [← toFinset_empty, toFinset_inj]
@[simp]
theorem toFinset_eq_univ [Fintype α] [Fintype s] : s.toFinset = Finset.univ ↔ s = univ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝¹ : Fintype α
inst✝ : Fintype ↑s
⊢ toFinset s = Finset.univ ↔ s = univ

Next tactic:
rw [← coe_inj, coe_toFinset, coe_univ]
@[simp]
theorem toFinset_setOf [Fintype α] (p : α → Prop) [DecidablePred p] [Fintype { x | p x }] :
    { x | p x }.toFinset = Finset.univ.filter p := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝² : Fintype α
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : Fintype ↑{x | p x}
⊢ toFinset {x | p x} = filter p Finset.univ

Next tactic:
ext
@[simp]
theorem toFinset_setOf [Fintype α] (p : α → Prop) [DecidablePred p] [Fintype { x | p x }] :
    { x | p x }.toFinset = Finset.univ.filter p := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝² : Fintype α
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : Fintype ↑{x | p x}
a✝ : α
⊢ a✝ ∈ toFinset {x | p x} ↔ a✝ ∈ filter p Finset.univ

Next tactic:
simp
theorem toFinset_ssubset_univ [Fintype α] {s : Set α} [Fintype s] :
    s.toFinset ⊂ Finset.univ ↔ s ⊂ univ := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t : Set α
inst✝¹ : Fintype α
s : Set α
inst✝ : Fintype ↑s
⊢ toFinset s ⊂ Finset.univ ↔ s ⊂ univ

Next tactic:
rw [← coe_ssubset, coe_toFinset, coe_univ]
@[simp]
theorem toFinset_image [DecidableEq β] (f : α → β) (s : Set α) [Fintype s] [Fintype (f '' s)] :
    (f '' s).toFinset = s.toFinset.image f :=
  Finset.coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t : Set α
inst✝² : DecidableEq β
f : α → β
s : Set α
inst✝¹ : Fintype ↑s
inst✝ : Fintype ↑(f '' s)
⊢ ↑(toFinset (f '' s)) = ↑(Finset.image f (toFinset s))

Next tactic:
simp
@[simp]
theorem toFinset_range [DecidableEq α] [Fintype β] (f : β → α) [Fintype (Set.range f)] :
    (Set.range f).toFinset = Finset.univ.image f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝² : DecidableEq α
inst✝¹ : Fintype β
f : β → α
inst✝ : Fintype ↑(range f)
⊢ toFinset (range f) = Finset.image f Finset.univ

Next tactic:
ext
@[simp]
theorem toFinset_range [DecidableEq α] [Fintype β] (f : β → α) [Fintype (Set.range f)] :
    (Set.range f).toFinset = Finset.univ.image f := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
inst✝² : DecidableEq α
inst✝¹ : Fintype β
f : β → α
inst✝ : Fintype ↑(range f)
a✝ : α
⊢ a✝ ∈ toFinset (range f) ↔ a✝ ∈ Finset.image f Finset.univ

Next tactic:
simp
@[simp] -- porting note: new attribute
theorem toFinset_singleton (a : α) [Fintype ({a} : Set α)] : ({a} : Set α).toFinset = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
a : α
inst✝ : Fintype ↑{a}
⊢ toFinset {a} = {a}

Next tactic:
ext
@[simp] -- porting note: new attribute
theorem toFinset_singleton (a : α) [Fintype ({a} : Set α)] : ({a} : Set α).toFinset = {a} := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
γ : Type u_3
s t : Set α
a : α
inst✝ : Fintype ↑{a}
a✝ : α
⊢ a✝ ∈ toFinset {a} ↔ a✝ ∈ {a}

Next tactic:
simp
@[simp]
theorem toFinset_insert [DecidableEq α] {a : α} {s : Set α} [Fintype (insert a s : Set α)]
    [Fintype s] : (insert a s).toFinset = insert a s.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ t : Set α
inst✝² : DecidableEq α
a : α
s : Set α
inst✝¹ : Fintype ↑(insert a s)
inst✝ : Fintype ↑s
⊢ toFinset (insert a s) = insert a (toFinset s)

Next tactic:
ext