-- Mathlib/SetTheory/Cardinal/Arithmetic.lean
theorem extend_function {α β : Type*} {s : Set α} (f : s ↪ β)
    (h : Nonempty ((sᶜ : Set α) ≃ ((range f)ᶜ : Set β))) : ∃ g : α ≃ β, ∀ x : s, g x = f x

Proof state:
case intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h✝ : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
h : α ≃ β := (Set.sumCompl s).symm.trans (((ofInjective ⇑f ⋯).sumCongr g).trans (Set.sumCompl (range ⇑f)))
⊢ ∀ (x : ↑s), h ↑x = f x

Tactic:
rintro ⟨x, hx⟩

Result:
case intro.mk
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h✝ : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
h : α ≃ β := (Set.sumCompl s).symm.trans (((ofInjective ⇑f ⋯).sumCongr g).trans (Set.sumCompl (range ⇑f)))
x : α
hx : x ∈ s
⊢ h ↑⟨x, hx⟩ = f ⟨x, hx⟩

Proof state:
case intro.mk
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h✝ : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
h : α ≃ β := (Set.sumCompl s).symm.trans (((ofInjective ⇑f ⋯).sumCongr g).trans (Set.sumCompl (range ⇑f)))
x : α
hx : x ∈ s
⊢ h ↑⟨x, hx⟩ = f ⟨x, hx⟩

Tactic:
simp [h, Set.sumCompl_symm_apply_of_mem, hx]

Result:
no goals

Proof state:
case intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Tactic:
let h : α ≃ β :=
  (Set.sumCompl (s : Set α)).symm.trans
    ((sumCongr (Equiv.ofInjective f f.2) g).trans (Set.sumCompl (range f)))

Result:
case intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h✝ : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
h : α ≃ β := (Set.sumCompl s).symm.trans (((ofInjective ⇑f ⋯).sumCongr g).trans (Set.sumCompl (range ⇑f)))
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Proof state:
case intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h✝ : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
h : α ≃ β := (Set.sumCompl s).symm.trans (((ofInjective ⇑f ⋯).sumCongr g).trans (Set.sumCompl (range ⇑f)))
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Tactic:
refine ⟨h, ?_⟩

Result:
case intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h✝ : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
h : α ≃ β := (Set.sumCompl s).symm.trans (((ofInjective ⇑f ⋯).sumCongr g).trans (Set.sumCompl (range ⇑f)))
⊢ ∀ (x : ↑s), h ↑x = f x

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

Tactic:
classical
have := h; obtain ⟨g⟩ := this
let h : α ≃ β :=
  (Set.sumCompl (s : Set α)).symm.trans
    ((sumCongr (Equiv.ofInjective f f.2) g).trans (Set.sumCompl (range f)))
refine ⟨h, ?_⟩; rintro ⟨x, hx⟩; simp [h, Set.sumCompl_symm_apply_of_mem, hx]

Result:
no goals

Proof state:
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h this : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

Tactic:
obtain ⟨g⟩ := this

Result:
case intro
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
g : ↑sᶜ ≃ ↑(range ⇑f)ᶜ
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x

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

Tactic:
have := h

Result:
α : Type u_1
β : Type u_2
s : Set α
f : ↑s ↪ β
h this : Nonempty (↑sᶜ ≃ ↑(range ⇑f)ᶜ)
⊢ ∃ g, ∀ (x : ↑s), g ↑x = f x