l3lab/ntp-mathlib huggingface dataset:
theorem extend_function_finite {α : Type u} {β : Type v} [Finite α] {s : Set α} (f : s ↪ β)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  apply extend_function.{v, u} f
  cases' id h with g
  rw [← lift_mk_eq.{u, v, max u v}] at h
  rw [← lift_mk_eq.{u, v, max u v}, mk_compl_eq_mk_compl_finite_lift.{u, v, max u v} h]
  

Proof state:
case intro
α : Type u
β : Type v
inst✝ : Finite α
s : Set α
f : ↑s ↪ β
h : lift.{max u v, u} #α = lift.{max u v, v} #β
g : α ≃ β
⊢ lift.{max u v, u} #↑s = lift.{max u v, v} #↑(range ⇑f)

Next tactic:
rw [mk_range_eq_lift.{u, v, max u v}]
theorem extend_function_finite {α : Type u} {β : Type v} [Finite α] {s : Set α} (f : s ↪ β)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  apply extend_function.{v, u} f
  cases' id h with g
  rw [← lift_mk_eq.{u, v, max u v}] at h
  rw [← lift_mk_eq.{u, v, max u v}, mk_compl_eq_mk_compl_finite_lift.{u, v, max u v} h]
  rw [mk_range_eq_lift.{u, v, max u v}]; 

Proof state:
case intro
α : Type u
β : Type v
inst✝ : Finite α
s : Set α
f : ↑s ↪ β
h : lift.{max u v, u} #α = lift.{max u v, v} #β
g : α ≃ β
⊢ Injective ⇑f

Next tactic:
exact f.2
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : Nonempty (α ≃ β)
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Next tactic:
cases fintypeOrInfinite α
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · 

Proof state:
case inl
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : Nonempty (α ≃ β)
val✝ : Fintype α
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Next tactic:
exact extend_function_finite f h
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · exact extend_function_finite f h
  · 

Proof state:
case inr
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : Nonempty (α ≃ β)
val✝ : Infinite α
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Next tactic:
apply extend_function f
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · exact extend_function_finite f h
  · apply extend_function f
    

Proof state:
case inr
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : Nonempty (α ≃ β)
val✝ : Infinite α
⊢ Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)

Next tactic:
cases' id h with g
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · exact extend_function_finite f h
  · apply extend_function f
    cases' id h with g
    

Proof state:
case inr.intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : Nonempty (α ≃ β)
val✝ : Infinite α
g : α ≃ β
⊢ Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)

Next tactic:
haveI := Infinite.of_injective _ g.injective
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · exact extend_function_finite f h
  · apply extend_function f
    cases' id h with g
    haveI := Infinite.of_injective _ g.injective
    

Proof state:
case inr.intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : Nonempty (α ≃ β)
val✝ : Infinite α
g : α ≃ β
this : Infinite β
⊢ Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)

Next tactic:
rw [← lift_mk_eq'] at h ⊢
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · exact extend_function_finite f h
  · apply extend_function f
    cases' id h with g
    haveI := Infinite.of_injective _ g.injective
    rw [← lift_mk_eq'] at h ⊢
    

Proof state:
case inr.intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : lift.{u_2, u_1} #α = lift.{u_1, u_2} #β
val✝ : Infinite α
g : α ≃ β
this : Infinite β
⊢ lift.{u_2, u_1} #↑sᶜ = lift.{u_1, u_2} #↑(range ⇑f)ᶜ

Next tactic:
rwa [mk_compl_of_infinite s hs, mk_compl_of_infinite]
theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : #s < #α)
    (h : Nonempty (α ≃ β)) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by
  cases fintypeOrInfinite α
  · exact extend_function_finite f h
  · apply extend_function f
    cases' id h with g
    haveI := Infinite.of_injective _ g.injective
    rw [← lift_mk_eq'] at h ⊢
    rwa [mk_compl_of_infinite s hs, mk_compl_of_infinite]
    

Proof state:
case inr.intro.h2
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
hs : #↑s < #α
h : lift.{u_2, u_1} #α = lift.{u_1, u_2} #β
val✝ : Infinite α
g : α ≃ β
this : Infinite β
⊢ #↑(range ⇑f) < #β

Next tactic:
rwa [← lift_lt, mk_range_eq_of_injective f.injective, ← h, lift_lt]
/--
Bounding the cardinal of an ordinal-indexed union of sets.
-/
lemma mk_iUnion_Ordinal_le_of_le {β : Type*} {o : Ordinal} {c : Cardinal}
    (ho : o.card ≤ c) (hc : ℵ₀ ≤ c) (A : Ordinal → Set β)
    (hA : ∀ j < o, #(A j) ≤ c) :
    #(⋃ j < o, A j) ≤ c := by
  

Proof state:
β : Type u_1
o : Ordinal.{u_1}
c : Cardinal.{u_1}
ho : card o ≤ c
hc : ℵ₀ ≤ c
A : Ordinal.{u_1} → Set β
hA : ∀ j < o, #↑(A j) ≤ c
⊢ #↑(⋃ j, ⋃ (_ : j < o), A j) ≤ c

Next tactic:
simp_rw [← mem_Iio, biUnion_eq_iUnion, iUnion, iSup, ← o.enumIsoOut.symm.surjective.range_comp]
/--
Bounding the cardinal of an ordinal-indexed union of sets.
-/
lemma mk_iUnion_Ordinal_le_of_le {β : Type*} {o : Ordinal} {c : Cardinal}
    (ho : o.card ≤ c) (hc : ℵ₀ ≤ c) (A : Ordinal → Set β)
    (hA : ∀ j < o, #(A j) ≤ c) :
    #(⋃ j < o, A j) ≤ c := by
  simp_rw [← mem_Iio, biUnion_eq_iUnion, iUnion, iSup, ← o.enumIsoOut.symm.surjective.range_comp]
  

Proof state:
β : Type u_1
o : Ordinal.{u_1}
c : Cardinal.{u_1}
ho : card o ≤ c
hc : ℵ₀ ≤ c
A : Ordinal.{u_1} → Set β
hA : ∀ j < o, #↑(A j) ≤ c
⊢ #↑(sSup (range ((fun x => A ↑x) ∘ ⇑(OrderIso.symm (enumIsoOut o))))) ≤ c

Next tactic:
apply ((mk_iUnion_le _).trans _).trans_eq (mul_eq_self hc)
/--
Bounding the cardinal of an ordinal-indexed union of sets.
-/
lemma mk_iUnion_Ordinal_le_of_le {β : Type*} {o : Ordinal} {c : Cardinal}
    (ho : o.card ≤ c) (hc : ℵ₀ ≤ c) (A : Ordinal → Set β)
    (hA : ∀ j < o, #(A j) ≤ c) :
    #(⋃ j < o, A j) ≤ c := by
  simp_rw [← mem_Iio, biUnion_eq_iUnion, iUnion, iSup, ← o.enumIsoOut.symm.surjective.range_comp]
  apply ((mk_iUnion_le _).trans _).trans_eq (mul_eq_self hc)
  

Proof state:
β : Type u_1
o : Ordinal.{u_1}
c : Cardinal.{u_1}
ho : card o ≤ c
hc : ℵ₀ ≤ c
A : Ordinal.{u_1} → Set β
hA : ∀ j < o, #↑(A j) ≤ c
⊢ #(Quotient.out o).α * ⨆ i, #↑(((fun x => A ↑x) ∘ ⇑(OrderIso.symm (enumIsoOut o))) i) ≤ c * c

Next tactic:
rw [mk_ordinal_out]
/--
Bounding the cardinal of an ordinal-indexed union of sets.
-/
lemma mk_iUnion_Ordinal_le_of_le {β : Type*} {o : Ordinal} {c : Cardinal}
    (ho : o.card ≤ c) (hc : ℵ₀ ≤ c) (A : Ordinal → Set β)
    (hA : ∀ j < o, #(A j) ≤ c) :
    #(⋃ j < o, A j) ≤ c := by
  simp_rw [← mem_Iio, biUnion_eq_iUnion, iUnion, iSup, ← o.enumIsoOut.symm.surjective.range_comp]
  apply ((mk_iUnion_le _).trans _).trans_eq (mul_eq_self hc)
  rw [mk_ordinal_out]
  

Proof state:
β : Type u_1
o : Ordinal.{u_1}
c : Cardinal.{u_1}
ho : card o ≤ c
hc : ℵ₀ ≤ c
A : Ordinal.{u_1} → Set β
hA : ∀ j < o, #↑(A j) ≤ c
⊢ card o * ⨆ i, #↑(((fun x => A ↑x) ∘ ⇑(OrderIso.symm (enumIsoOut o))) i) ≤ c * c

Next tactic:
exact mul_le_mul' ho <| ciSup_le' <| (hA _ <| typein_lt_self ·)
/-- Given a matching on a finset, construct the restriction of that matching to a subset. -/
def hallMatchingsOn.restrict {ι : Type u} {α : Type v} (t : ι → Finset α) {ι' ι'' : Finset ι}
    (h : ι' ⊆ ι'') (f : hallMatchingsOn t ι'') : hallMatchingsOn t ι' := by
  

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' ι'' : Finset ι
h : ι' ⊆ ι''
f : ↑(hallMatchingsOn t ι'')
⊢ ↑(hallMatchingsOn t ι')

Next tactic:
refine' ⟨fun i => f.val ⟨i, h i.property⟩, _⟩
/-- Given a matching on a finset, construct the restriction of that matching to a subset. -/
def hallMatchingsOn.restrict {ι : Type u} {α : Type v} (t : ι → Finset α) {ι' ι'' : Finset ι}
    (h : ι' ⊆ ι'') (f : hallMatchingsOn t ι'') : hallMatchingsOn t ι' := by
  refine' ⟨fun i => f.val ⟨i, h i.property⟩, _⟩
  

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' ι'' : Finset ι
h : ι' ⊆ ι''
f : ↑(hallMatchingsOn t ι'')
⊢ (fun i => ↑f { val := ↑i, property := (_ : ↑i ∈ ι'') }) ∈ hallMatchingsOn t ι'

Next tactic:
cases' f.property with hinj hc
/-- Given a matching on a finset, construct the restriction of that matching to a subset. -/
def hallMatchingsOn.restrict {ι : Type u} {α : Type v} (t : ι → Finset α) {ι' ι'' : Finset ι}
    (h : ι' ⊆ ι'') (f : hallMatchingsOn t ι'') : hallMatchingsOn t ι' := by
  refine' ⟨fun i => f.val ⟨i, h i.property⟩, _⟩
  cases' f.property with hinj hc
  

Proof state:
case intro
ι : Type u
α : Type v
t : ι → Finset α
ι' ι'' : Finset ι
h : ι' ⊆ ι''
f : ↑(hallMatchingsOn t ι'')
hinj : Function.Injective ↑f
hc : ∀ (x : { x // x ∈ ι'' }), ↑f x ∈ t ↑x
⊢ (fun i => ↑f { val := ↑i, property := (_ : ↑i ∈ ι'') }) ∈ hallMatchingsOn t ι'

Next tactic:
refine' ⟨_, fun i => hc ⟨i, h i.property⟩⟩
/-- Given a matching on a finset, construct the restriction of that matching to a subset. -/
def hallMatchingsOn.restrict {ι : Type u} {α : Type v} (t : ι → Finset α) {ι' ι'' : Finset ι}
    (h : ι' ⊆ ι'') (f : hallMatchingsOn t ι'') : hallMatchingsOn t ι' := by
  refine' ⟨fun i => f.val ⟨i, h i.property⟩, _⟩
  cases' f.property with hinj hc
  refine' ⟨_, fun i => hc ⟨i, h i.property⟩⟩
  

Proof state:
case intro
ι : Type u
α : Type v
t : ι → Finset α
ι' ι'' : Finset ι
h : ι' ⊆ ι''
f : ↑(hallMatchingsOn t ι'')
hinj : Function.Injective ↑f
hc : ∀ (x : { x // x ∈ ι'' }), ↑f x ∈ t ↑x
⊢ Function.Injective fun i => ↑f { val := ↑i, property := (_ : ↑i ∈ ι'') }

Next tactic:
rintro ⟨i, hi⟩ ⟨j, hj⟩ hh
/-- Given a matching on a finset, construct the restriction of that matching to a subset. -/
def hallMatchingsOn.restrict {ι : Type u} {α : Type v} (t : ι → Finset α) {ι' ι'' : Finset ι}
    (h : ι' ⊆ ι'') (f : hallMatchingsOn t ι'') : hallMatchingsOn t ι' := by
  refine' ⟨fun i => f.val ⟨i, h i.property⟩, _⟩
  cases' f.property with hinj hc
  refine' ⟨_, fun i => hc ⟨i, h i.property⟩⟩
  rintro ⟨i, hi⟩ ⟨j, hj⟩ hh
  

Proof state:
case intro.mk.mk
ι : Type u
α : Type v
t : ι → Finset α
ι' ι'' : Finset ι
h : ι' ⊆ ι''
f : ↑(hallMatchingsOn t ι'')
hinj : Function.Injective ↑f
hc : ∀ (x : { x // x ∈ ι'' }), ↑f x ∈ t ↑x
i : ι
hi : i ∈ ι'
j : ι
hj : j ∈ ι'
hh :
  (fun i => ↑f { val := ↑i, property := (_ : ↑i ∈ ι'') }) { val := i, property := hi } =
    (fun i => ↑f { val := ↑i, property := (_ : ↑i ∈ ι'') }) { val := j, property := hj }
⊢ { val := i, property := hi } = { val := j, property := hj }

Next tactic:
simpa only [Subtype.mk_eq_mk] using hinj hh
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  

Proof state:
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
⊢ Nonempty ↑(hallMatchingsOn t ι')

Next tactic:
classical
    refine' ⟨Classical.indefiniteDescription _ _⟩
    apply (all_card_le_biUnion_card_iff_existsInjective' fun i : ι' => t i).mp
    intro s'
    convert h (s'.image (↑)) using 1
    simp only [card_image_of_injective s' Subtype.coe_injective]
    rw [image_biUnion]
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  classical
    

Proof state:
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
⊢ Nonempty ↑(hallMatchingsOn t ι')

Next tactic:
refine' ⟨Classical.indefiniteDescription _ _⟩
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  classical
    refine' ⟨Classical.indefiniteDescription _ _⟩
    

Proof state:
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
⊢ ∃ x, x ∈ hallMatchingsOn t ι'

Next tactic:
apply (all_card_le_biUnion_card_iff_existsInjective' fun i : ι' => t i).mp
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  classical
    refine' ⟨Classical.indefiniteDescription _ _⟩
    apply (all_card_le_biUnion_card_iff_existsInjective' fun i : ι' => t i).mp
    

Proof state:
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
⊢ ∀ (s : Finset { x // x ∈ ι' }), card s ≤ card (Finset.biUnion s fun i => t ↑i)

Next tactic:
intro s'
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  classical
    refine' ⟨Classical.indefiniteDescription _ _⟩
    apply (all_card_le_biUnion_card_iff_existsInjective' fun i : ι' => t i).mp
    intro s'
    

Proof state:
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
s' : Finset { x // x ∈ ι' }
⊢ card s' ≤ card (Finset.biUnion s' fun i => t ↑i)

Next tactic:
convert h (s'.image (↑)) using 1
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  classical
    refine' ⟨Classical.indefiniteDescription _ _⟩
    apply (all_card_le_biUnion_card_iff_existsInjective' fun i : ι' => t i).mp
    intro s'
    convert h (s'.image (↑)) using 1
    

Proof state:
case h.e'_3
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
s' : Finset { x // x ∈ ι' }
⊢ card s' = card (image Subtype.val s')
case h.e'_4
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
s' : Finset { x // x ∈ ι' }
⊢ card (Finset.biUnion s' fun i => t ↑i) = card (Finset.biUnion (image Subtype.val s') t)

Next tactic:
simp only [card_image_of_injective s' Subtype.coe_injective]
/-- When the Hall condition is satisfied, the set of matchings on a finite set is nonempty.
This is where `Finset.all_card_le_biUnion_card_iff_existsInjective'` comes into the argument. -/
theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t : ι → Finset α)
    (h : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (ι' : Finset ι) :
    Nonempty (hallMatchingsOn t ι') := by
  classical
    refine' ⟨Classical.indefiniteDescription _ _⟩
    apply (all_card_le_biUnion_card_iff_existsInjective' fun i : ι' => t i).mp
    intro s'
    convert h (s'.image (↑)) using 1
    simp only [card_image_of_injective s' Subtype.coe_injective]
    

Proof state:
case h.e'_4
ι : Type u
α : Type v
inst✝ : DecidableEq α
t : ι → Finset α
h : ∀ (s : Finset ι), card s ≤ card (Finset.biUnion s t)
ι' : Finset ι
s' : Finset { x // x ∈ ι' }
⊢ card (Finset.biUnion s' fun i => t ↑i) = card (Finset.biUnion (image Subtype.val s') t)

Next tactic:
rw [image_biUnion]
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
⊢ Finite ↑(hallMatchingsOn t ι')

Next tactic:
classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
    apply Finite.of_injective g
    intro f f' h
    ext a
    rw [Function.funext_iff] at h
    simpa using h a
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
⊢ Finite ↑(hallMatchingsOn t ι')

Next tactic:
rw [hallMatchingsOn]
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
⊢ Finite ↑{f | Function.Injective f ∧ ∀ (x : { x // x ∈ ι' }), f x ∈ t ↑x}

Next tactic:
let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
⊢ ↑(hallMatchingsOn t ι') → { x // x ∈ ι' } → { x // x ∈ Finset.biUnion ι' t }

Next tactic:
rintro f i
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
f : ↑(hallMatchingsOn t ι')
i : { x // x ∈ ι' }
⊢ { x // x ∈ Finset.biUnion ι' t }

Next tactic:
refine' ⟨f.val i, _⟩
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
f : ↑(hallMatchingsOn t ι')
i : { x // x ∈ ι' }
⊢ ↑f i ∈ Finset.biUnion ι' t

Next tactic:
rw [mem_biUnion]
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
f : ↑(hallMatchingsOn t ι')
i : { x // x ∈ ι' }
⊢ ∃ a ∈ ι', ↑f i ∈ t a

Next tactic:
exact ⟨i, i.property, f.property.2 i⟩
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
    

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
g : ↑(hallMatchingsOn t ι') → { x // x ∈ ι' } → { x // x ∈ Finset.biUnion ι' t } :=
  fun f i => { val := ↑f i, property := (_ : ↑f i ∈ Finset.biUnion ι' t) }
⊢ Finite ↑{f | Function.Injective f ∧ ∀ (x : { x // x ∈ ι' }), f x ∈ t ↑x}

Next tactic:
apply Finite.of_injective g
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
    apply Finite.of_injective g
    

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
g : ↑(hallMatchingsOn t ι') → { x // x ∈ ι' } → { x // x ∈ Finset.biUnion ι' t } :=
  fun f i => { val := ↑f i, property := (_ : ↑f i ∈ Finset.biUnion ι' t) }
⊢ Function.Injective g

Next tactic:
intro f f' h
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
    apply Finite.of_injective g
    intro f f' h
    

Proof state:
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
g : ↑(hallMatchingsOn t ι') → { x // x ∈ ι' } → { x // x ∈ Finset.biUnion ι' t } :=
  fun f i => { val := ↑f i, property := (_ : ↑f i ∈ Finset.biUnion ι' t) }
f f' : ↑(hallMatchingsOn t ι')
h : g f = g f'
⊢ f = f'

Next tactic:
ext a
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
    apply Finite.of_injective g
    intro f f' h
    ext a
    

Proof state:
case a.h
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
g : ↑(hallMatchingsOn t ι') → { x // x ∈ ι' } → { x // x ∈ Finset.biUnion ι' t } :=
  fun f i => { val := ↑f i, property := (_ : ↑f i ∈ Finset.biUnion ι' t) }
f f' : ↑(hallMatchingsOn t ι')
h : g f = g f'
a : { x // x ∈ ι' }
⊢ ↑f a = ↑f' a

Next tactic:
rw [Function.funext_iff] at h
instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) :
    Finite (hallMatchingsOn t ι') := by
  classical
    rw [hallMatchingsOn]
    let g : hallMatchingsOn t ι' → ι' → ι'.biUnion t := by
      rintro f i
      refine' ⟨f.val i, _⟩
      rw [mem_biUnion]
      exact ⟨i, i.property, f.property.2 i⟩
    apply Finite.of_injective g
    intro f f' h
    ext a
    rw [Function.funext_iff] at h
    

Proof state:
case a.h
ι : Type u
α : Type v
t : ι → Finset α
ι' : Finset ι
g : ↑(hallMatchingsOn t ι') → { x // x ∈ ι' } → { x // x ∈ Finset.biUnion ι' t } :=
  fun f i => { val := ↑f i, property := (_ : ↑f i ∈ Finset.biUnion ι' t) }
f f' : ↑(hallMatchingsOn t ι')
h : ∀ (a : { x // x ∈ ι' }), g f a = g f' a
a : { x // x ∈ ι' }
⊢ ↑f a = ↑f' a

Next tactic:
simpa using h a