l3lab/ntp-mathlib huggingface dataset:
theorem mk_set_eq_nat_iff_finset {α} {s : Set α} {n : ℕ} :
    #s = n ↔ ∃ t : Finset α, (t : Set α) = s ∧ t.card = n := by
  constructor
  · intro h
    

Proof state:
case mp
α✝ β : Type u
c : Cardinal.{?u.823641}
α : Type u_1
s : Set α
n : ℕ
h : #↑s = ↑n
⊢ ∃ t, ↑t = s ∧ Finset.card t = n

Next tactic:
lift s to Finset α using lt_aleph0_iff_set_finite.1 (h.symm ▸ nat_lt_aleph0 n)
theorem mk_set_eq_nat_iff_finset {α} {s : Set α} {n : ℕ} :
    #s = n ↔ ∃ t : Finset α, (t : Set α) = s ∧ t.card = n := by
  constructor
  · intro h
    lift s to Finset α using lt_aleph0_iff_set_finite.1 (h.symm ▸ nat_lt_aleph0 n)
    

Proof state:
case mp.intro
α✝ β : Type u
c : Cardinal.{?u.823641}
α : Type u_1
n : ℕ
s : Finset α
h : #↑↑s = ↑n
⊢ ∃ t, ↑t = ↑s ∧ Finset.card t = n

Next tactic:
simpa using h
theorem mk_set_eq_nat_iff_finset {α} {s : Set α} {n : ℕ} :
    #s = n ↔ ∃ t : Finset α, (t : Set α) = s ∧ t.card = n := by
  constructor
  · intro h
    lift s to Finset α using lt_aleph0_iff_set_finite.1 (h.symm ▸ nat_lt_aleph0 n)
    simpa using h
  · 

Proof state:
case mpr
α✝ β : Type u
c : Cardinal.{?u.823641}
α : Type u_1
s : Set α
n : ℕ
⊢ (∃ t, ↑t = s ∧ Finset.card t = n) → #↑s = ↑n

Next tactic:
rintro ⟨t, rfl, rfl⟩
theorem mk_set_eq_nat_iff_finset {α} {s : Set α} {n : ℕ} :
    #s = n ↔ ∃ t : Finset α, (t : Set α) = s ∧ t.card = n := by
  constructor
  · intro h
    lift s to Finset α using lt_aleph0_iff_set_finite.1 (h.symm ▸ nat_lt_aleph0 n)
    simpa using h
  · rintro ⟨t, rfl, rfl⟩
    

Proof state:
case mpr.intro.intro
α✝ β : Type u
c : Cardinal.{?u.823641}
α : Type u_1
t : Finset α
⊢ #↑↑t = ↑(Finset.card t)

Next tactic:
exact mk_coe_finset
theorem mk_eq_nat_iff_finset {n : ℕ} :
    #α = n ↔ ∃ t : Finset α, (t : Set α) = univ ∧ t.card = n :=
  by 

Proof state:
α β : Type u
c : Cardinal.{?u.826233}
n : ℕ
⊢ #α = ↑n ↔ ∃ t, ↑t = univ ∧ Finset.card t = n

Next tactic:
rw [← mk_univ, mk_set_eq_nat_iff_finset]
theorem mk_eq_nat_iff_fintype {n : ℕ} : #α = n ↔ ∃ h : Fintype α, @Fintype.card α h = n := by
  

Proof state:
α β : Type u
c : Cardinal.{?u.826507}
n : ℕ
⊢ #α = ↑n ↔ ∃ h, Fintype.card α = n

Next tactic:
rw [mk_eq_nat_iff_finset]
theorem mk_eq_nat_iff_fintype {n : ℕ} : #α = n ↔ ∃ h : Fintype α, @Fintype.card α h = n := by
  rw [mk_eq_nat_iff_finset]
  

Proof state:
α β : Type u
c : Cardinal.{?u.826507}
n : ℕ
⊢ (∃ t, ↑t = univ ∧ Finset.card t = n) ↔ ∃ h, Fintype.card α = n

Next tactic:
constructor
theorem mk_eq_nat_iff_fintype {n : ℕ} : #α = n ↔ ∃ h : Fintype α, @Fintype.card α h = n := by
  rw [mk_eq_nat_iff_finset]
  constructor
  · 

Proof state:
case mp
α β : Type u
c : Cardinal.{?u.826507}
n : ℕ
⊢ (∃ t, ↑t = univ ∧ Finset.card t = n) → ∃ h, Fintype.card α = n

Next tactic:
rintro ⟨t, ht, hn⟩
theorem mk_eq_nat_iff_fintype {n : ℕ} : #α = n ↔ ∃ h : Fintype α, @Fintype.card α h = n := by
  rw [mk_eq_nat_iff_finset]
  constructor
  · rintro ⟨t, ht, hn⟩
    

Proof state:
case mp.intro.intro
α β : Type u
c : Cardinal.{?u.826507}
n : ℕ
t : Finset α
ht : ↑t = univ
hn : Finset.card t = n
⊢ ∃ h, Fintype.card α = n

Next tactic:
exact ⟨⟨t, eq_univ_iff_forall.1 ht⟩, hn⟩
theorem mk_eq_nat_iff_fintype {n : ℕ} : #α = n ↔ ∃ h : Fintype α, @Fintype.card α h = n := by
  rw [mk_eq_nat_iff_finset]
  constructor
  · rintro ⟨t, ht, hn⟩
    exact ⟨⟨t, eq_univ_iff_forall.1 ht⟩, hn⟩
  · 

Proof state:
case mpr
α β : Type u
c : Cardinal.{?u.826507}
n : ℕ
⊢ (∃ h, Fintype.card α = n) → ∃ t, ↑t = univ ∧ Finset.card t = n

Next tactic:
rintro ⟨⟨t, ht⟩, hn⟩
theorem mk_eq_nat_iff_fintype {n : ℕ} : #α = n ↔ ∃ h : Fintype α, @Fintype.card α h = n := by
  rw [mk_eq_nat_iff_finset]
  constructor
  · rintro ⟨t, ht, hn⟩
    exact ⟨⟨t, eq_univ_iff_forall.1 ht⟩, hn⟩
  · rintro ⟨⟨t, ht⟩, hn⟩
    

Proof state:
case mpr.intro.mk
α β : Type u
c : Cardinal.{?u.826507}
n : ℕ
t : Finset α
ht : ∀ (x : α), x ∈ t
hn : Fintype.card α = n
⊢ ∃ t, ↑t = univ ∧ Finset.card t = n

Next tactic:
exact ⟨t, eq_univ_iff_forall.2 ht, hn⟩
theorem mk_insert {α : Type u} {s : Set α} {a : α} (h : a ∉ s) :
    #(insert a s : Set α) = #s + 1 := by
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.829338}
α : Type u
s : Set α
a : α
h : a ∉ s
⊢ #↑(insert a s) = #↑s + 1

Next tactic:
rw [← union_singleton, mk_union_of_disjoint, mk_singleton]
theorem mk_insert {α : Type u} {s : Set α} {a : α} (h : a ∉ s) :
    #(insert a s : Set α) = #s + 1 := by
  rw [← union_singleton, mk_union_of_disjoint, mk_singleton]
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.829338}
α : Type u
s : Set α
a : α
h : a ∉ s
⊢ Disjoint s {a}

Next tactic:
simpa
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
⊢ #↑t ≤ ↑n ↔ ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n

Next tactic:
refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by 

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : #↑t ≤ ↑n
s : Finset α
hs : ↑s ⊆ t
⊢ Finset.card s ≤ n

Next tactic:
simpa using (mk_le_mk_of_subset hs).trans H
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n
⊢ #↑t ≤ ↑n

Next tactic:
apply card_le_of (fun s ↦ ?_)
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
  apply card_le_of (fun s ↦ ?_)
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n
s : Finset ↑t
⊢ Finset.card s ≤ n

Next tactic:
let u : Finset α := s.image Subtype.val
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
  apply card_le_of (fun s ↦ ?_)
  let u : Finset α := s.image Subtype.val
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n
s : Finset ↑t
u : Finset α := Finset.image Subtype.val s
⊢ Finset.card s ≤ n

Next tactic:
have : u.card = s.card :=
    Finset.card_image_of_injOn (injOn_of_injective Subtype.coe_injective _)
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
  apply card_le_of (fun s ↦ ?_)
  let u : Finset α := s.image Subtype.val
  have : u.card = s.card :=
    Finset.card_image_of_injOn (injOn_of_injective Subtype.coe_injective _)
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n
s : Finset ↑t
u : Finset α := Finset.image Subtype.val s
this : Finset.card u = Finset.card s
⊢ Finset.card s ≤ n

Next tactic:
rw [← this]
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
  apply card_le_of (fun s ↦ ?_)
  let u : Finset α := s.image Subtype.val
  have : u.card = s.card :=
    Finset.card_image_of_injOn (injOn_of_injective Subtype.coe_injective _)
  rw [← this]
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n
s : Finset ↑t
u : Finset α := Finset.image Subtype.val s
this : Finset.card u = Finset.card s
⊢ Finset.card u ≤ n

Next tactic:
apply H
theorem mk_le_iff_forall_finset_subset_card_le {α : Type u} {n : ℕ} {t : Set α} :
    #t ≤ n ↔ ∀ s : Finset α, (s : Set α) ⊆ t → s.card ≤ n := by
  refine ⟨fun H s hs ↦ by simpa using (mk_le_mk_of_subset hs).trans H, fun H ↦ ?_⟩
  apply card_le_of (fun s ↦ ?_)
  let u : Finset α := s.image Subtype.val
  have : u.card = s.card :=
    Finset.card_image_of_injOn (injOn_of_injective Subtype.coe_injective _)
  rw [← this]
  apply H
  

Proof state:
case a
α✝ β : Type u
c : Cardinal.{?u.830923}
α : Type u
n : ℕ
t : Set α
H : ∀ (s : Finset α), ↑s ⊆ t → Finset.card s ≤ n
s : Finset ↑t
u : Finset α := Finset.image Subtype.val s
this : Finset.card u = Finset.card s
⊢ ↑u ⊆ t

Next tactic:
simp only [Finset.coe_image, image_subset_iff, Subtype.coe_preimage_self, subset_univ]
theorem mk_diff_add_mk {S T : Set α} (h : T ⊆ S) : #(S \ T : Set α) + #T = #S := by
  

Proof state:
α β : Type u
c : Cardinal.{?u.834771}
S T : Set α
h : T ⊆ S
⊢ #↑(S \ T) + #↑T = #↑S

Next tactic:
refine (mk_union_of_disjoint <| ?_).symm.trans <| by rw [diff_union_of_subset h]
theorem mk_diff_add_mk {S T : Set α} (h : T ⊆ S) : #(S \ T : Set α) + #T = #S := by
  refine (mk_union_of_disjoint <| ?_).symm.trans <| by 

Proof state:
α β : Type u
c : Cardinal.{?u.834771}
S T : Set α
h : T ⊆ S
⊢ #↑(S \ T ∪ T) = #↑S

Next tactic:
rw [diff_union_of_subset h]
theorem mk_diff_add_mk {S T : Set α} (h : T ⊆ S) : #(S \ T : Set α) + #T = #S := by
  refine (mk_union_of_disjoint <| ?_).symm.trans <| by rw [diff_union_of_subset h]
  

Proof state:
α β : Type u
c : Cardinal.{?u.834771}
S T : Set α
h : T ⊆ S
⊢ Disjoint (S \ T) T

Next tactic:
exact disjoint_sdiff_self_left
theorem mk_union_le_aleph0 {α} {P Q : Set α} :
    #(P ∪ Q : Set α) ≤ ℵ₀ ↔ #P ≤ ℵ₀ ∧ #Q ≤ ℵ₀ := by
  

Proof state:
α✝ β : Type u
c : Cardinal.{?u.835381}
α : Type u_1
P Q : Set α
⊢ #↑(P ∪ Q) ≤ ℵ₀ ↔ #↑P ≤ ℵ₀ ∧ #↑Q ≤ ℵ₀

Next tactic:
simp only [le_aleph0_iff_subtype_countable, mem_union, setOf_mem_eq, Set.union_def,
    ← countable_union]
theorem mk_preimage_of_injective_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : Injective f) : lift.{v} #(f ⁻¹' s) ≤ lift.{u} #s := by
  

Proof state:
α✝ β✝ : Type u
c : Cardinal.{?u.837718}
α : Type u
β : Type v
f : α → β
s : Set β
h : Injective f
⊢ lift.{v, u} #↑(f ⁻¹' s) ≤ lift.{u, v} #↑s

Next tactic:
rw [lift_mk_le.{0}]
theorem mk_preimage_of_injective_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : Injective f) : lift.{v} #(f ⁻¹' s) ≤ lift.{u} #s := by
  rw [lift_mk_le.{0}]
  -- Porting note: Needed to insert `mem_preimage.mp` below
  

Proof state:
α✝ β✝ : Type u
c : Cardinal.{?u.837718}
α : Type u
β : Type v
f : α → β
s : Set β
h : Injective f
⊢ Nonempty (↑(f ⁻¹' s) ↪ ↑s)

Next tactic:
use Subtype.coind (fun x => f x.1) fun x => mem_preimage.mp x.2
theorem mk_preimage_of_injective_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : Injective f) : lift.{v} #(f ⁻¹' s) ≤ lift.{u} #s := by
  rw [lift_mk_le.{0}]
  -- Porting note: Needed to insert `mem_preimage.mp` below
  use Subtype.coind (fun x => f x.1) fun x => mem_preimage.mp x.2
  

Proof state:
case inj'
α✝ β✝ : Type u
c : Cardinal.{?u.837718}
α : Type u
β : Type v
f : α → β
s : Set β
h : Injective f
⊢ Injective (Subtype.coind (fun x => f ↑x) (_ : ∀ (x : ↑(f ⁻¹' s)), f ↑x ∈ s))

Next tactic:
apply Subtype.coind_injective
theorem mk_preimage_of_injective_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : Injective f) : lift.{v} #(f ⁻¹' s) ≤ lift.{u} #s := by
  rw [lift_mk_le.{0}]
  -- Porting note: Needed to insert `mem_preimage.mp` below
  use Subtype.coind (fun x => f x.1) fun x => mem_preimage.mp x.2
  apply Subtype.coind_injective; 

Proof state:
case inj'.hf
α✝ β✝ : Type u
c : Cardinal.{?u.837718}
α : Type u
β : Type v
f : α → β
s : Set β
h : Injective f
⊢ Injective fun x => f ↑x

Next tactic:
exact h.comp Subtype.val_injective
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  

Proof state:
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
⊢ lift.{u, v} #↑s ≤ lift.{v, u} #↑(f ⁻¹' s)

Next tactic:
rw [lift_mk_le.{0}]
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  

Proof state:
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
⊢ Nonempty (↑s ↪ ↑(f ⁻¹' s))

Next tactic:
refine' ⟨⟨_, _⟩⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · 

Proof state:
case refine'_1
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
⊢ ↑s → ↑(f ⁻¹' s)

Next tactic:
rintro ⟨y, hy⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    

Proof state:
case refine'_1.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
y : β
hy : y ∈ s
⊢ ↑(f ⁻¹' s)

Next tactic:
rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    

Proof state:
case refine'_1.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
x : α
hy : f x ∈ s
⊢ ↑(f ⁻¹' s)

Next tactic:
exact ⟨x, hy⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  

Proof state:
case refine'_2
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
⊢ Injective fun a =>
    Subtype.casesOn a fun y hy =>
      Subtype.casesOn (subtype_of_exists (_ : y ∈ range f)) fun x property =>
        Eq.ndrec (motive := fun y => y ∈ s → ↑(f ⁻¹' s)) (fun hy => { val := x, property := hy }) property hy

Next tactic:
rintro ⟨y, hy⟩ ⟨y', hy'⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  rintro ⟨y, hy⟩ ⟨y', hy'⟩; 

Proof state:
case refine'_2.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
y : β
hy : y ∈ s
y' : β
hy' : y' ∈ s
⊢ (fun a =>
          Subtype.casesOn a fun y hy =>
            Subtype.casesOn (subtype_of_exists (_ : y ∈ range f)) fun x property =>
              Eq.ndrec (motive := fun y => y ∈ s → ↑(f ⁻¹' s)) (fun hy => { val := x, property := hy }) property hy)
        { val := y, property := hy } =
      (fun a =>
          Subtype.casesOn a fun y hy =>
            Subtype.casesOn (subtype_of_exists (_ : y ∈ range f)) fun x property =>
              Eq.ndrec (motive := fun y => y ∈ s → ↑(f ⁻¹' s)) (fun hy => { val := x, property := hy }) property hy)
        { val := y', property := hy' } →
    { val := y, property := hy } = { val := y', property := hy' }

Next tactic:
dsimp
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  rintro ⟨y, hy⟩ ⟨y', hy'⟩; dsimp
  

Proof state:
case refine'_2.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
y : β
hy : y ∈ s
y' : β
hy' : y' ∈ s
⊢ Eq.rec (motive := fun x x_1 => x ∈ s → ↑(f ⁻¹' s))
        (fun hy_1 => { val := ↑(subtype_of_exists (_ : y ∈ range f)), property := hy_1 })
        (_ : f ↑(subtype_of_exists (_ : y ∈ range f)) = y) hy =
      Eq.rec (motive := fun x x_1 => x ∈ s → ↑(f ⁻¹' s))
        (fun hy => { val := ↑(subtype_of_exists (_ : y' ∈ range f)), property := hy })
        (_ : f ↑(subtype_of_exists (_ : y' ∈ range f)) = y') hy' →
    { val := y, property := hy } = { val := y', property := hy' }

Next tactic:
rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  rintro ⟨y, hy⟩ ⟨y', hy'⟩; dsimp
  rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
  

Proof state:
case refine'_2.mk.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
y' : β
hy' : y' ∈ s
x : α
hy : f x ∈ s
⊢ Eq.rec (motive := fun x_1 x => x_1 ∈ s → ↑(f ⁻¹' s))
        (fun hy => { val := ↑{ val := x, property := (_ : f x = f x) }, property := hy })
        (_ : f ↑{ val := x, property := (_ : f x = f x) } = f x) hy =
      Eq.rec (motive := fun x x_1 => x ∈ s → ↑(f ⁻¹' s))
        (fun hy => { val := ↑(subtype_of_exists (_ : y' ∈ range f)), property := hy })
        (_ : f ↑(subtype_of_exists (_ : y' ∈ range f)) = y') hy' →
    { val := f x, property := hy } = { val := y', property := hy' }

Next tactic:
rcases Classical.subtype_of_exists (h hy') with ⟨x', rfl⟩
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  rintro ⟨y, hy⟩ ⟨y', hy'⟩; dsimp
  rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
  rcases Classical.subtype_of_exists (h hy') with ⟨x', rfl⟩
  

Proof state:
case refine'_2.mk.mk.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
x : α
hy : f x ∈ s
x' : α
hy' : f x' ∈ s
⊢ Eq.rec (motive := fun x_1 x => x_1 ∈ s → ↑(f ⁻¹' s))
        (fun hy => { val := ↑{ val := x, property := (_ : f x = f x) }, property := hy })
        (_ : f ↑{ val := x, property := (_ : f x = f x) } = f x) hy =
      Eq.rec (motive := fun x x_1 => x ∈ s → ↑(f ⁻¹' s))
        (fun hy => { val := ↑{ val := x', property := (_ : f x' = f x') }, property := hy })
        (_ : f ↑{ val := x', property := (_ : f x' = f x') } = f x') hy' →
    { val := f x, property := hy } = { val := f x', property := hy' }

Next tactic:
simp
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  rintro ⟨y, hy⟩ ⟨y', hy'⟩; dsimp
  rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
  rcases Classical.subtype_of_exists (h hy') with ⟨x', rfl⟩
  simp; 

Proof state:
case refine'_2.mk.mk.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
x : α
hy : f x ∈ s
x' : α
hy' : f x' ∈ s
⊢ x = x' → f x = f x'

Next tactic:
intro hxx'
theorem mk_preimage_of_subset_range_lift {α : Type u} {β : Type v} (f : α → β) (s : Set β)
    (h : s ⊆ range f) : lift.{u} #s ≤ lift.{v} #(f ⁻¹' s) := by
  rw [lift_mk_le.{0}]
  refine' ⟨⟨_, _⟩⟩
  · rintro ⟨y, hy⟩
    rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
    exact ⟨x, hy⟩
  rintro ⟨y, hy⟩ ⟨y', hy'⟩; dsimp
  rcases Classical.subtype_of_exists (h hy) with ⟨x, rfl⟩
  rcases Classical.subtype_of_exists (h hy') with ⟨x', rfl⟩
  simp; intro hxx'; 

Proof state:
case refine'_2.mk.mk.mk.mk
α✝ β✝ : Type u
c : Cardinal.{?u.838310}
α : Type u
β : Type v
f : α → β
s : Set β
h : s ⊆ range f
x : α
hy : f x ∈ s
x' : α
hy' : f x' ∈ s
hxx' : x = x'
⊢ f x = f x'

Next tactic:
rw [hxx']
theorem mk_preimage_of_injective (f : α → β) (s : Set β) (h : Injective f) :
    #(f ⁻¹' s) ≤ #s := by
  

Proof state:
α β : Type u
c : Cardinal.{?u.840603}
f : α → β
s : Set β
h : Injective f
⊢ #↑(f ⁻¹' s) ≤ #↑s

Next tactic:
rw [← lift_id #(↑(f ⁻¹' s)), ← lift_id #(↑s)]
theorem mk_preimage_of_injective (f : α → β) (s : Set β) (h : Injective f) :
    #(f ⁻¹' s) ≤ #s := by
  rw [← lift_id #(↑(f ⁻¹' s)), ← lift_id #(↑s)]
  

Proof state:
α β : Type u
c : Cardinal.{?u.840603}
f : α → β
s : Set β
h : Injective f
⊢ lift.{u, u} #↑(f ⁻¹' s) ≤ lift.{u, u} #↑s

Next tactic:
exact mk_preimage_of_injective_lift f s h
theorem mk_preimage_of_subset_range (f : α → β) (s : Set β) (h : s ⊆ range f) :
    #s ≤ #(f ⁻¹' s) := by
  

Proof state:
α β : Type u
c : Cardinal.{?u.841267}
f : α → β
s : Set β
h : s ⊆ range f
⊢ #↑s ≤ #↑(f ⁻¹' s)

Next tactic:
rw [← lift_id #(↑(f ⁻¹' s)), ← lift_id #(↑s)]
theorem mk_preimage_of_subset_range (f : α → β) (s : Set β) (h : s ⊆ range f) :
    #s ≤ #(f ⁻¹' s) := by
  rw [← lift_id #(↑(f ⁻¹' s)), ← lift_id #(↑s)]
  

Proof state:
α β : Type u
c : Cardinal.{?u.841267}
f : α → β
s : Set β
h : s ⊆ range f
⊢ lift.{u, u} #↑s ≤ lift.{u, u} #↑(f ⁻¹' s)

Next tactic:
exact mk_preimage_of_subset_range_lift f s h
theorem mk_preimage_of_injective_of_subset_range (f : α → β) (s : Set β) (h : Injective f)
    (h2 : s ⊆ range f) : #(f ⁻¹' s) = #s := by
  

Proof state:
α β : Type u
c : Cardinal.{?u.841945}
f : α → β
s : Set β
h : Injective f
h2 : s ⊆ range f
⊢ #↑(f ⁻¹' s) = #↑s

Next tactic:
convert mk_preimage_of_injective_of_subset_range_lift.{u, u} f s h h2 using 1
theorem mk_preimage_of_injective_of_subset_range (f : α → β) (s : Set β) (h : Injective f)
    (h2 : s ⊆ range f) : #(f ⁻¹' s) = #s := by
  convert mk_preimage_of_injective_of_subset_range_lift.{u, u} f s h h2 using 1 <;> 

Proof state:
case h.e'_2
α β : Type u
c : Cardinal.{?u.841945}
f : α → β
s : Set β
h : Injective f
h2 : s ⊆ range f
⊢ #↑(f ⁻¹' s) = lift.{u, u} #↑(f ⁻¹' s)

Next tactic:
rw [lift_id]
theorem mk_preimage_of_injective_of_subset_range (f : α → β) (s : Set β) (h : Injective f)
    (h2 : s ⊆ range f) : #(f ⁻¹' s) = #s := by
  convert mk_preimage_of_injective_of_subset_range_lift.{u, u} f s h h2 using 1 <;> 

Proof state:
case h.e'_3
α β : Type u
c : Cardinal.{?u.841945}
f : α → β
s : Set β
h : Injective f
h2 : s ⊆ range f
⊢ #↑s = lift.{u, u} #↑s

Next tactic:
rw [lift_id]
theorem mk_subset_ge_of_subset_image_lift {α : Type u} {β : Type v} (f : α → β) {s : Set α}
    {t : Set β} (h : t ⊆ f '' s) : lift.{u} #t ≤ lift.{v} #({ x ∈ s | f x ∈ t } : Set α) := by
  

Proof state:
α✝ β✝ : Type u
c : Cardinal.{?u.842756}
α : Type u
β : Type v
f : α → β
s : Set α
t : Set β
h : t ⊆ f '' s
⊢ lift.{u, v} #↑t ≤ lift.{v, u} #↑{x | x ∈ s ∧ f x ∈ t}

Next tactic:
rw [image_eq_range] at h
theorem mk_subset_ge_of_subset_image_lift {α : Type u} {β : Type v} (f : α → β) {s : Set α}
    {t : Set β} (h : t ⊆ f '' s) : lift.{u} #t ≤ lift.{v} #({ x ∈ s | f x ∈ t } : Set α) := by
  rw [image_eq_range] at h
  

Proof state:
α✝ β✝ : Type u
c : Cardinal.{?u.842756}
α : Type u
β : Type v
f : α → β
s : Set α
t : Set β
h : t ⊆ range fun x => f ↑x
⊢ lift.{u, v} #↑t ≤ lift.{v, u} #↑{x | x ∈ s ∧ f x ∈ t}

Next tactic:
convert mk_preimage_of_subset_range_lift _ _ h using 1
theorem mk_subset_ge_of_subset_image_lift {α : Type u} {β : Type v} (f : α → β) {s : Set α}
    {t : Set β} (h : t ⊆ f '' s) : lift.{u} #t ≤ lift.{v} #({ x ∈ s | f x ∈ t } : Set α) := by
  rw [image_eq_range] at h
  convert mk_preimage_of_subset_range_lift _ _ h using 1
  

Proof state:
case h.e'_4
α✝ β✝ : Type u
c : Cardinal.{?u.842756}
α : Type u
β : Type v
f : α → β
s : Set α
t : Set β
h : t ⊆ range fun x => f ↑x
⊢ lift.{v, u} #↑{x | x ∈ s ∧ f x ∈ t} = lift.{v, u} #↑((fun x => f ↑x) ⁻¹' t)

Next tactic:
rw [mk_sep]