l3lab/ntp-mathlib huggingface dataset:
theorem filter_card_eq {p : α → Prop} [DecidablePred p] (h : (s.filter p).card = s.card) (x : α)
    (hx : x ∈ s) : p x := by
  rw [← eq_of_subset_of_card_le (s.filter_subset p) h.ge, mem_filter] at hx
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
p : α → Prop
inst✝ : DecidablePred p
h : card (filter p s) = card s
x : α
hx : x ∈ s ∧ p x
⊢ p x

Next tactic:
exact hx.2
theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a)
    (hf' : ∀ (i) (h : i < n), f i h ∈ s)
    (f_inj : ∀ (i j) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
⊢ card s = n

Next tactic:
classical
    have : ∀ a : α, a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a := fun a =>
      ⟨fun ha =>
        let ⟨i, hi, eq⟩ := hf a ha
        ⟨i, mem_range.2 hi, eq⟩,
        fun ⟨i, hi, eq⟩ => eq ▸ hf' i (mem_range.1 hi)⟩
    have : s = (range n).attach.image fun i => f i.1 (mem_range.1 i.2) := by
      simpa only [ext_iff, mem_image, exists_prop, Subtype.exists, mem_attach, true_and_iff]
    calc
      s.card = card ((range n).attach.image fun i => f i.1 (mem_range.1 i.2)) := by rw [this]
      _ = card (range n).attach :=
        (card_image_of_injective _) fun ⟨i, hi⟩ ⟨j, hj⟩ eq =>
          Subtype.eq <| f_inj i j (mem_range.1 hi) (mem_range.1 hj) eq
      _ = card (range n) := card_attach
      _ = n := card_range n
theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a)
    (hf' : ∀ (i) (h : i < n), f i h ∈ s)
    (f_inj : ∀ (i j) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
⊢ card s = n

Next tactic:
have : ∀ a : α, a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a := fun a =>
      ⟨fun ha =>
        let ⟨i, hi, eq⟩ := hf a ha
        ⟨i, mem_range.2 hi, eq⟩,
        fun ⟨i, hi, eq⟩ => eq ▸ hf' i (mem_range.1 hi)⟩
theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a)
    (hf' : ∀ (i) (h : i < n), f i h ∈ s)
    (f_inj : ∀ (i j) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by
  classical
    have : ∀ a : α, a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a := fun a =>
      ⟨fun ha =>
        let ⟨i, hi, eq⟩ := hf a ha
        ⟨i, mem_range.2 hi, eq⟩,
        fun ⟨i, hi, eq⟩ => eq ▸ hf' i (mem_range.1 hi)⟩
    

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : ∀ (a : α), a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i (_ : i < n) = a
⊢ card s = n

Next tactic:
have : s = (range n).attach.image fun i => f i.1 (mem_range.1 i.2) := by
      simpa only [ext_iff, mem_image, exists_prop, Subtype.exists, mem_attach, true_and_iff]
theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a)
    (hf' : ∀ (i) (h : i < n), f i h ∈ s)
    (f_inj : ∀ (i j) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by
  classical
    have : ∀ a : α, a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a := fun a =>
      ⟨fun ha =>
        let ⟨i, hi, eq⟩ := hf a ha
        ⟨i, mem_range.2 hi, eq⟩,
        fun ⟨i, hi, eq⟩ => eq ▸ hf' i (mem_range.1 hi)⟩
    have : s = (range n).attach.image fun i => f i.1 (mem_range.1 i.2) := by
      

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : ∀ (a : α), a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i (_ : i < n) = a
⊢ s = image (fun i => f ↑i (_ : ↑i < n)) (attach (range n))

Next tactic:
simpa only [ext_iff, mem_image, exists_prop, Subtype.exists, mem_attach, true_and_iff]
theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a)
    (hf' : ∀ (i) (h : i < n), f i h ∈ s)
    (f_inj : ∀ (i j) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by
  classical
    have : ∀ a : α, a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a := fun a =>
      ⟨fun ha =>
        let ⟨i, hi, eq⟩ := hf a ha
        ⟨i, mem_range.2 hi, eq⟩,
        fun ⟨i, hi, eq⟩ => eq ▸ hf' i (mem_range.1 hi)⟩
    have : s = (range n).attach.image fun i => f i.1 (mem_range.1 i.2) := by
      simpa only [ext_iff, mem_image, exists_prop, Subtype.exists, mem_attach, true_and_iff]
    

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this✝ : ∀ (a : α), a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i (_ : i < n) = a
this : s = image (fun i => f ↑i (_ : ↑i < n)) (attach (range n))
⊢ card s = n

Next tactic:
calc
      s.card = card ((range n).attach.image fun i => f i.1 (mem_range.1 i.2)) := by rw [this]
      _ = card (range n).attach :=
        (card_image_of_injective _) fun ⟨i, hi⟩ ⟨j, hj⟩ eq =>
          Subtype.eq <| f_inj i j (mem_range.1 hi) (mem_range.1 hj) eq
      _ = card (range n) := card_attach
      _ = n := card_range n
theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a)
    (hf' : ∀ (i) (h : i < n), f i h ∈ s)
    (f_inj : ∀ (i j) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by
  classical
    have : ∀ a : α, a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a := fun a =>
      ⟨fun ha =>
        let ⟨i, hi, eq⟩ := hf a ha
        ⟨i, mem_range.2 hi, eq⟩,
        fun ⟨i, hi, eq⟩ => eq ▸ hf' i (mem_range.1 hi)⟩
    have : s = (range n).attach.image fun i => f i.1 (mem_range.1 i.2) := by
      simpa only [ext_iff, mem_image, exists_prop, Subtype.exists, mem_attach, true_and_iff]
    calc
      s.card = card ((range n).attach.image fun i => f i.1 (mem_range.1 i.2)) := by 

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this✝ : ∀ (a : α), a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i (_ : i < n) = a
this : s = image (fun i => f ↑i (_ : ↑i < n)) (attach (range n))
⊢ card s = card (image (fun i => f ↑i (_ : ↑i < n)) (attach (range n)))

Next tactic:
rw [this]
theorem card_congr {t : Finset β} (f : ∀ a ∈ s, β) (h₁ : ∀ a ha, f a ha ∈ t)
    (h₂ : ∀ a b ha hb, f a ha = f b hb → a = b) (h₃ : ∀ b ∈ t, ∃ a ha, f a ha = b) :
    s.card = t.card := by
  

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
h₁ : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
h₂ : ∀ (a b : α) (ha : a ∈ s) (hb : b ∈ s), f a ha = f b hb → a = b
h₃ : ∀ b ∈ t, ∃ a, ∃ (ha : a ∈ s), f a ha = b
⊢ card s = card t

Next tactic:
classical calc
      s.card = s.attach.card := card_attach.symm
      _ = (s.attach.image fun a : { a // a ∈ s } => f a.1 a.2).card :=
        Eq.symm ((card_image_of_injective _) fun a b h => Subtype.eq <| h₂ _ _ _ _ h)
      _ = t.card :=
        congr_arg card
          (Finset.ext fun b =>
            ⟨fun h =>
              let ⟨a, _, ha₂⟩ := mem_image.1 h
              ha₂ ▸ h₁ _ _,
              fun h =>
              let ⟨a, ha₁, ha₂⟩ := h₃ b h
              mem_image.2 ⟨⟨a, ha₁⟩, by simp [ha₂]⟩⟩)
theorem card_congr {t : Finset β} (f : ∀ a ∈ s, β) (h₁ : ∀ a ha, f a ha ∈ t)
    (h₂ : ∀ a b ha hb, f a ha = f b hb → a = b) (h₃ : ∀ b ∈ t, ∃ a ha, f a ha = b) :
    s.card = t.card := by
  classical 

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
h₁ : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
h₂ : ∀ (a b : α) (ha : a ∈ s) (hb : b ∈ s), f a ha = f b hb → a = b
h₃ : ∀ b ∈ t, ∃ a, ∃ (ha : a ∈ s), f a ha = b
⊢ card s = card t

Next tactic:
calc
      s.card = s.attach.card := card_attach.symm
      _ = (s.attach.image fun a : { a // a ∈ s } => f a.1 a.2).card :=
        Eq.symm ((card_image_of_injective _) fun a b h => Subtype.eq <| h₂ _ _ _ _ h)
      _ = t.card :=
        congr_arg card
          (Finset.ext fun b =>
            ⟨fun h =>
              let ⟨a, _, ha₂⟩ := mem_image.1 h
              ha₂ ▸ h₁ _ _,
              fun h =>
              let ⟨a, ha₁, ha₂⟩ := h₃ b h
              mem_image.2 ⟨⟨a, ha₁⟩, by simp [ha₂]⟩⟩)
theorem card_congr {t : Finset β} (f : ∀ a ∈ s, β) (h₁ : ∀ a ha, f a ha ∈ t)
    (h₂ : ∀ a b ha hb, f a ha = f b hb → a = b) (h₃ : ∀ b ∈ t, ∃ a ha, f a ha = b) :
    s.card = t.card := by
  classical calc
      s.card = s.attach.card := card_attach.symm
      _ = (s.attach.image fun a : { a // a ∈ s } => f a.1 a.2).card :=
        Eq.symm ((card_image_of_injective _) fun a b h => Subtype.eq <| h₂ _ _ _ _ h)
      _ = t.card :=
        congr_arg card
          (Finset.ext fun b =>
            ⟨fun h =>
              let ⟨a, _, ha₂⟩ := mem_image.1 h
              ha₂ ▸ h₁ _ _,
              fun h =>
              let ⟨a, ha₁, ha₂⟩ := h₃ b h
              mem_image.2 ⟨⟨a, ha₁⟩, by 

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
h₁ : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
h₂ : ∀ (a b : α) (ha : a ∈ s) (hb : b ∈ s), f a ha = f b hb → a = b
h₃ : ∀ b ∈ t, ∃ a, ∃ (ha : a ∈ s), f a ha = b
b : β
h : b ∈ t
a : α
ha₁ : a ∈ s
ha₂ : f a ha₁ = b
⊢ { val := a, property := ha₁ } ∈ attach s ∧
    f ↑{ val := a, property := ha₁ } (_ : ↑{ val := a, property := ha₁ } ∈ s) = b

Next tactic:
simp [ha₂]
theorem card_le_card_of_inj_on {t : Finset β} (f : α → β) (hf : ∀ a ∈ s, f a ∈ t)
    (f_inj : ∀ a₁ ∈ s, ∀ a₂ ∈ s, f a₁ = f a₂ → a₁ = a₂) : s.card ≤ t.card := by
  

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : α → β
hf : ∀ a ∈ s, f a ∈ t
f_inj : ∀ a₁ ∈ s, ∀ a₂ ∈ s, f a₁ = f a₂ → a₁ = a₂
⊢ card s ≤ card t

Next tactic:
classical calc
      s.card = (s.image f).card := (card_image_of_injOn f_inj).symm
      _ ≤ t.card := card_le_of_subset <| image_subset_iff.2 hf
theorem card_le_card_of_inj_on {t : Finset β} (f : α → β) (hf : ∀ a ∈ s, f a ∈ t)
    (f_inj : ∀ a₁ ∈ s, ∀ a₂ ∈ s, f a₁ = f a₂ → a₁ = a₂) : s.card ≤ t.card := by
  classical 

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : α → β
hf : ∀ a ∈ s, f a ∈ t
f_inj : ∀ a₁ ∈ s, ∀ a₂ ∈ s, f a₁ = f a₂ → a₁ = a₂
⊢ card s ≤ card t

Next tactic:
calc
      s.card = (s.image f).card := (card_image_of_injOn f_inj).symm
      _ ≤ t.card := card_le_of_subset <| image_subset_iff.2 hf
/-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole.
-/
theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β}
    (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
hc : card t < card s
f : α → β
hf : ∀ a ∈ s, f a ∈ t
⊢ ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y

Next tactic:
classical
    by_contra! hz
    refine' hc.not_le (card_le_card_of_inj_on f hf _)
    intro x hx y hy
    contrapose
    exact hz x hx y hy
/-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole.
-/
theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β}
    (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
hc : card t < card s
f : α → β
hf : ∀ a ∈ s, f a ∈ t
⊢ ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y

Next tactic:
by_contra! hz
/-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole.
-/
theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β}
    (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  classical
    by_contra! hz
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
hc : card t < card s
f : α → β
hf : ∀ a ∈ s, f a ∈ t
hz : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → f x ≠ f y
⊢ False

Next tactic:
refine' hc.not_le (card_le_card_of_inj_on f hf _)
/-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole.
-/
theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β}
    (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  classical
    by_contra! hz
    refine' hc.not_le (card_le_card_of_inj_on f hf _)
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
hc : card t < card s
f : α → β
hf : ∀ a ∈ s, f a ∈ t
hz : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → f x ≠ f y
⊢ ∀ a₁ ∈ s, ∀ a₂ ∈ s, f a₁ = f a₂ → a₁ = a₂

Next tactic:
intro x hx y hy
/-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole.
-/
theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β}
    (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  classical
    by_contra! hz
    refine' hc.not_le (card_le_card_of_inj_on f hf _)
    intro x hx y hy
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
hc : card t < card s
f : α → β
hf : ∀ a ∈ s, f a ∈ t
hz : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → f x ≠ f y
x : α
hx : x ∈ s
y : α
hy : y ∈ s
⊢ f x = f y → x = y

Next tactic:
contrapose
/-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole.
-/
theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β}
    (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by
  classical
    by_contra! hz
    refine' hc.not_le (card_le_card_of_inj_on f hf _)
    intro x hx y hy
    contrapose
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
hc : card t < card s
f : α → β
hf : ∀ a ∈ s, f a ∈ t
hz : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → f x ≠ f y
x : α
hx : x ∈ s
y : α
hy : y ∈ s
⊢ ¬x = y → ¬f x = f y

Next tactic:
exact hz x hx y hy
theorem le_card_of_inj_on_range (f : ℕ → α) (hf : ∀ i < n, f i ∈ s)
    (f_inj : ∀ i < n, ∀ j < n, f i = f j → i = j) : n ≤ s.card :=
  calc
    n = card (range n) := (card_range n).symm
    _ ≤ s.card := card_le_card_of_inj_on f (by 

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : ℕ → α
hf : ∀ i < n, f i ∈ s
f_inj : ∀ i < n, ∀ j < n, f i = f j → i = j
⊢ ∀ a ∈ range n, f a ∈ s

Next tactic:
simpa only [mem_range]
theorem le_card_of_inj_on_range (f : ℕ → α) (hf : ∀ i < n, f i ∈ s)
    (f_inj : ∀ i < n, ∀ j < n, f i = f j → i = j) : n ≤ s.card :=
  calc
    n = card (range n) := (card_range n).symm
    _ ≤ s.card := card_le_card_of_inj_on f (by simpa only [mem_range] ) (by 

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f✝ : α → β
n : ℕ
f : ℕ → α
hf : ∀ i < n, f i ∈ s
f_inj : ∀ i < n, ∀ j < n, f i = f j → i = j
⊢ ∀ a₁ ∈ range n, ∀ a₂ ∈ range n, f a₁ = f a₂ → a₁ = a₂

Next tactic:
simpa only [mem_range]
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
⊢ ∀ b ∈ t, ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
classical
    intro b hb
    have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
    have h' : image (fun a : { a // a ∈ s } => f a a.prop) s.attach = t :=
      eq_of_subset_of_card_le
        (fun b h =>
          let ⟨a, _, ha₂⟩ := mem_image.1 h
          ha₂ ▸ hf _ _)
        (by simp [hst, h])
    rw [← h'] at hb
    obtain ⟨a, _, ha₂⟩ := mem_image.1 hb
    exact ⟨a, a.2, ha₂.symm⟩
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
⊢ ∀ b ∈ t, ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
intro b hb
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    intro b hb
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
b : β
hb : b ∈ t
⊢ ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    intro b hb
    have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
b : β
hb : b ∈ t
h : card (image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)) = card s
⊢ ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
have h' : image (fun a : { a // a ∈ s } => f a a.prop) s.attach = t :=
      eq_of_subset_of_card_le
        (fun b h =>
          let ⟨a, _, ha₂⟩ := mem_image.1 h
          ha₂ ▸ hf _ _)
        (by simp [hst, h])
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    intro b hb
    have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
    have h' : image (fun a : { a // a ∈ s } => f a a.prop) s.attach = t :=
      eq_of_subset_of_card_le
        (fun b h =>
          let ⟨a, _, ha₂⟩ := mem_image.1 h
          ha₂ ▸ hf _ _)
        (by 

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
b : β
hb : b ∈ t
h : card (image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)) = card s
⊢ card t ≤ card (image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s))

Next tactic:
simp [hst, h]
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    intro b hb
    have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
    have h' : image (fun a : { a // a ∈ s } => f a a.prop) s.attach = t :=
      eq_of_subset_of_card_le
        (fun b h =>
          let ⟨a, _, ha₂⟩ := mem_image.1 h
          ha₂ ▸ hf _ _)
        (by simp [hst, h])
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
b : β
hb : b ∈ t
h : card (image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)) = card s
h' : image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s) = t
⊢ ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
rw [← h'] at hb
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    intro b hb
    have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
    have h' : image (fun a : { a // a ∈ s } => f a a.prop) s.attach = t :=
      eq_of_subset_of_card_le
        (fun b h =>
          let ⟨a, _, ha₂⟩ := mem_image.1 h
          ha₂ ▸ hf _ _)
        (by simp [hst, h])
    rw [← h'] at hb
    

Proof state:
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
b : β
hb : b ∈ image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)
h : card (image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)) = card s
h' : image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s) = t
⊢ ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
obtain ⟨a, _, ha₂⟩ := mem_image.1 hb
theorem surj_on_of_inj_on_of_card_le {t : Finset β} (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t)
    (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) :
    ∀ b ∈ t, ∃ a ha, b = f a ha := by
  classical
    intro b hb
    have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card :=
      @card_attach _ s ▸
        card_image_of_injective _ fun ⟨a₁, ha₁⟩ ⟨a₂, ha₂⟩ h => Subtype.eq <| hinj _ _ _ _ h
    have h' : image (fun a : { a // a ∈ s } => f a a.prop) s.attach = t :=
      eq_of_subset_of_card_le
        (fun b h =>
          let ⟨a, _, ha₂⟩ := mem_image.1 h
          ha₂ ▸ hf _ _)
        (by simp [hst, h])
    rw [← h'] at hb
    obtain ⟨a, _, ha₂⟩ := mem_image.1 hb
    

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
s t✝ : Finset α
f✝ : α → β
n : ℕ
t : Finset β
f : (a : α) → a ∈ s → β
hf : ∀ (a : α) (ha : a ∈ s), f a ha ∈ t
hinj : ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂
hst : card t ≤ card s
b : β
hb : b ∈ image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)
h : card (image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s)) = card s
h' : image (fun a => f ↑a (_ : ↑a ∈ s)) (attach s) = t
a : { a // a ∈ s }
left✝ : a ∈ attach s
ha₂ : f ↑a (_ : ↑a ∈ s) = b
⊢ ∃ a, ∃ (ha : a ∈ s), b = f a ha

Next tactic:
exact ⟨a, a.2, ha₂.symm⟩