l3lab/ntp-mathlib huggingface dataset:
theorem LeftInvOn.image_inter' (hf : LeftInvOn f' f s) : f '' (s₁ ∩ s) = f' ⁻¹' s₁ ∩ f '' s := by
  apply Subset.antisymm
  · rintro _ ⟨x, ⟨h₁, h⟩, rfl⟩
    exact ⟨by rwa [mem_preimage, hf h], mem_image_of_mem _ h⟩
  · rintro _ ⟨h₁, ⟨x, h, rfl⟩⟩
    

Proof state:
case h₂.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
x : α
h : x ∈ s
h₁ : f x ∈ f' ⁻¹' s₁
⊢ f x ∈ f '' (s₁ ∩ s)

Next tactic:
exact mem_image_of_mem _ ⟨by rwa [← hf h], h⟩
theorem LeftInvOn.image_inter' (hf : LeftInvOn f' f s) : f '' (s₁ ∩ s) = f' ⁻¹' s₁ ∩ f '' s := by
  apply Subset.antisymm
  · rintro _ ⟨x, ⟨h₁, h⟩, rfl⟩
    exact ⟨by rwa [mem_preimage, hf h], mem_image_of_mem _ h⟩
  · rintro _ ⟨h₁, ⟨x, h, rfl⟩⟩
    exact mem_image_of_mem _ ⟨by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
x : α
h : x ∈ s
h₁ : f x ∈ f' ⁻¹' s₁
⊢ x ∈ s₁

Next tactic:
rwa [← hf h]
theorem LeftInvOn.image_inter (hf : LeftInvOn f' f s) :
    f '' (s₁ ∩ s) = f' ⁻¹' (s₁ ∩ s) ∩ f '' s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
⊢ f '' (s₁ ∩ s) = f' ⁻¹' (s₁ ∩ s) ∩ f '' s

Next tactic:
rw [hf.image_inter']
theorem LeftInvOn.image_inter (hf : LeftInvOn f' f s) :
    f '' (s₁ ∩ s) = f' ⁻¹' (s₁ ∩ s) ∩ f '' s := by
  rw [hf.image_inter']
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
⊢ f' ⁻¹' s₁ ∩ f '' s = f' ⁻¹' (s₁ ∩ s) ∩ f '' s

Next tactic:
refine' Subset.antisymm _ (inter_subset_inter_left _ (preimage_mono <| inter_subset_left _ _))
theorem LeftInvOn.image_inter (hf : LeftInvOn f' f s) :
    f '' (s₁ ∩ s) = f' ⁻¹' (s₁ ∩ s) ∩ f '' s := by
  rw [hf.image_inter']
  refine' Subset.antisymm _ (inter_subset_inter_left _ (preimage_mono <| inter_subset_left _ _))
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
⊢ f' ⁻¹' s₁ ∩ f '' s ⊆ f' ⁻¹' (s₁ ∩ s) ∩ f '' s

Next tactic:
rintro _ ⟨h₁, x, hx, rfl⟩
theorem LeftInvOn.image_inter (hf : LeftInvOn f' f s) :
    f '' (s₁ ∩ s) = f' ⁻¹' (s₁ ∩ s) ∩ f '' s := by
  rw [hf.image_inter']
  refine' Subset.antisymm _ (inter_subset_inter_left _ (preimage_mono <| inter_subset_left _ _))
  rintro _ ⟨h₁, x, hx, rfl⟩; 

Proof state:
case intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
x : α
hx : x ∈ s
h₁ : f x ∈ f' ⁻¹' s₁
⊢ f x ∈ f' ⁻¹' (s₁ ∩ s) ∩ f '' s

Next tactic:
exact ⟨⟨h₁, by rwa [hf hx]⟩, mem_image_of_mem _ hx⟩
theorem LeftInvOn.image_inter (hf : LeftInvOn f' f s) :
    f '' (s₁ ∩ s) = f' ⁻¹' (s₁ ∩ s) ∩ f '' s := by
  rw [hf.image_inter']
  refine' Subset.antisymm _ (inter_subset_inter_left _ (preimage_mono <| inter_subset_left _ _))
  rintro _ ⟨h₁, x, hx, rfl⟩; exact ⟨⟨h₁, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
x : α
hx : x ∈ s
h₁ : f x ∈ f' ⁻¹' s₁
⊢ f' (f x) ∈ s

Next tactic:
rwa [hf hx]
theorem LeftInvOn.image_image (hf : LeftInvOn f' f s) : f' '' (f '' s) = s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : LeftInvOn f' f s
⊢ f' '' (f '' s) = s

Next tactic:
rw [Set.image_image, image_congr hf, image_id']
theorem SurjOn.leftInvOn_of_rightInvOn (hf : SurjOn f s t) (hf' : RightInvOn f f' s) :
    LeftInvOn f f' t := fun y hy => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : SurjOn f s t
hf' : RightInvOn f f' s
y : β
hy : y ∈ t
⊢ f (f' y) = y

Next tactic:
let ⟨x, hx, heq⟩ := hf hy
theorem SurjOn.leftInvOn_of_rightInvOn (hf : SurjOn f s t) (hf' : RightInvOn f f' s) :
    LeftInvOn f f' t := fun y hy => by
  let ⟨x, hx, heq⟩ := hf hy
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
hf : SurjOn f s t
hf' : RightInvOn f f' s
y : β
hy : y ∈ t
x : α
hx : x ∈ s
heq : f x = y
⊢ f (f' y) = y

Next tactic:
rw [← heq, hf' hx]
theorem invFunOn_pos (h : ∃ a ∈ s, f a = b) : invFunOn f s b ∈ s ∧ f (invFunOn f s b) = b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
inst✝ : Nonempty α
s : Set α
f : α → β
a : α
b : β
h : ∃ a ∈ s, f a = b
⊢ invFunOn f s b ∈ s ∧ f (invFunOn f s b) = b

Next tactic:
rw [invFunOn, dif_pos h]
theorem invFunOn_pos (h : ∃ a ∈ s, f a = b) : invFunOn f s b ∈ s ∧ f (invFunOn f s b) = b := by
  rw [invFunOn, dif_pos h]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
inst✝ : Nonempty α
s : Set α
f : α → β
a : α
b : β
h : ∃ a ∈ s, f a = b
⊢ Classical.choose h ∈ s ∧ f (Classical.choose h) = b

Next tactic:
exact Classical.choose_spec h
theorem invFunOn_neg (h : ¬∃ a ∈ s, f a = b) : invFunOn f s b = Classical.choice ‹Nonempty α› :=
  by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
inst✝ : Nonempty α
s : Set α
f : α → β
a : α
b : β
h : ¬∃ a ∈ s, f a = b
⊢ invFunOn f s b = Classical.choice inst✝

Next tactic:
rw [invFunOn, dif_neg h]
theorem _root_.Function.leftInvOn_invFunOn_of_subset_image_image [Nonempty α]
    (h : s ⊆ (invFunOn f s) '' (f '' s)) : LeftInvOn (invFunOn f s) f s :=
  fun x hx ↦ by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : s ⊆ invFunOn f s '' (f '' s)
x : α
hx : x ∈ s
⊢ invFunOn f s (f x) = x

Next tactic:
obtain ⟨-, ⟨x, hx', rfl⟩, rfl⟩ := h hx
theorem _root_.Function.leftInvOn_invFunOn_of_subset_image_image [Nonempty α]
    (h : s ⊆ (invFunOn f s) '' (f '' s)) : LeftInvOn (invFunOn f s) f s :=
  fun x hx ↦ by
    obtain ⟨-, ⟨x, hx', rfl⟩, rfl⟩ := h hx
    

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : s ⊆ invFunOn f s '' (f '' s)
x : α
hx' : x ∈ s
hx : invFunOn f s (f x) ∈ s
⊢ invFunOn f s (f (invFunOn f s (f x))) = invFunOn f s (f x)

Next tactic:
rw [invFunOn_apply_eq (f := f) hx']
theorem _root_.Function.invFunOn_injOn_image [Nonempty α] (f : α → β) (s : Set α) :
    Set.InjOn (invFunOn f s) (f '' s) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
inst✝ : Nonempty α
f : α → β
s : Set α
⊢ InjOn (invFunOn f s) (f '' s)

Next tactic:
rintro _ ⟨x, hx, rfl⟩ _ ⟨x', hx', rfl⟩ he
theorem _root_.Function.invFunOn_injOn_image [Nonempty α] (f : α → β) (s : Set α) :
    Set.InjOn (invFunOn f s) (f '' s) := by
  rintro _ ⟨x, hx, rfl⟩ _ ⟨x', hx', rfl⟩ he
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
inst✝ : Nonempty α
f : α → β
s : Set α
x : α
hx : x ∈ s
x' : α
hx' : x' ∈ s
he : invFunOn f s (f x) = invFunOn f s (f x')
⊢ f x = f x'

Next tactic:
rw [← invFunOn_apply_eq (f := f) hx, he, invFunOn_apply_eq (f := f) hx']
theorem _root_.Function.invFunOn_image_image_subset [Nonempty α] (f : α → β) (s : Set α) :
    (invFunOn f s) '' (f '' s) ⊆ s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
inst✝ : Nonempty α
f : α → β
s : Set α
⊢ invFunOn f s '' (f '' s) ⊆ s

Next tactic:
rintro _ ⟨_, ⟨x,hx,rfl⟩, rfl⟩
theorem _root_.Function.invFunOn_image_image_subset [Nonempty α] (f : α → β) (s : Set α) :
    (invFunOn f s) '' (f '' s) ⊆ s := by
  rintro _ ⟨_, ⟨x,hx,rfl⟩, rfl⟩; 

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
inst✝ : Nonempty α
f : α → β
s : Set α
x : α
hx : x ∈ s
⊢ invFunOn f s (f x) ∈ s

Next tactic:
exact invFunOn_apply_mem hx
theorem SurjOn.invOn_invFunOn [Nonempty α] (h : SurjOn f s t) :
    InvOn (invFunOn f s) f (invFunOn f s '' t) t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : SurjOn f s t
⊢ InvOn (invFunOn f s) f (invFunOn f s '' t) t

Next tactic:
refine' ⟨_, h.rightInvOn_invFunOn⟩
theorem SurjOn.invOn_invFunOn [Nonempty α] (h : SurjOn f s t) :
    InvOn (invFunOn f s) f (invFunOn f s '' t) t := by
  refine' ⟨_, h.rightInvOn_invFunOn⟩
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : SurjOn f s t
⊢ LeftInvOn (invFunOn f s) f (invFunOn f s '' t)

Next tactic:
rintro _ ⟨y, hy, rfl⟩
theorem SurjOn.invOn_invFunOn [Nonempty α] (h : SurjOn f s t) :
    InvOn (invFunOn f s) f (invFunOn f s '' t) t := by
  refine' ⟨_, h.rightInvOn_invFunOn⟩
  rintro _ ⟨y, hy, rfl⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : SurjOn f s t
y : β
hy : y ∈ t
⊢ invFunOn f s (f (invFunOn f s y)) = invFunOn f s y

Next tactic:
rw [h.rightInvOn_invFunOn hy]
theorem SurjOn.bijOn_subset [Nonempty α] (h : SurjOn f s t) : BijOn f (invFunOn f s '' t) t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : SurjOn f s t
⊢ BijOn f (invFunOn f s '' t) t

Next tactic:
refine' h.invOn_invFunOn.bijOn _ (mapsTo_image _ _)
theorem SurjOn.bijOn_subset [Nonempty α] (h : SurjOn f s t) : BijOn f (invFunOn f s '' t) t := by
  refine' h.invOn_invFunOn.bijOn _ (mapsTo_image _ _)
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : SurjOn f s t
⊢ MapsTo f (invFunOn f s '' t) t

Next tactic:
rintro _ ⟨y, hy, rfl⟩
theorem SurjOn.bijOn_subset [Nonempty α] (h : SurjOn f s t) : BijOn f (invFunOn f s '' t) t := by
  refine' h.invOn_invFunOn.bijOn _ (mapsTo_image _ _)
  rintro _ ⟨y, hy, rfl⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
inst✝ : Nonempty α
h : SurjOn f s t
y : β
hy : y ∈ t
⊢ f (invFunOn f s y) ∈ t

Next tactic:
rwa [h.rightInvOn_invFunOn hy]
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
⊢ SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t

Next tactic:
constructor
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
⊢ SurjOn f s t → ∃ s' ⊆ s, BijOn f s' t

Next tactic:
rcases eq_empty_or_nonempty t with (rfl | ht)
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · rcases eq_empty_or_nonempty t with (rfl | ht)
    · 

Proof state:
case mp.inl
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
f : α → β
⊢ SurjOn f s ∅ → ∃ s' ⊆ s, BijOn f s' ∅

Next tactic:
exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · rcases eq_empty_or_nonempty t with (rfl | ht)
    · exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩
    · 

Proof state:
case mp.inr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
ht : Set.Nonempty t
⊢ SurjOn f s t → ∃ s' ⊆ s, BijOn f s' t

Next tactic:
intro h
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · rcases eq_empty_or_nonempty t with (rfl | ht)
    · exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩
    · intro h
      

Proof state:
case mp.inr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
ht : Set.Nonempty t
h : SurjOn f s t
⊢ ∃ s' ⊆ s, BijOn f s' t

Next tactic:
haveI : Nonempty α := ⟨Classical.choose (h.comap_nonempty ht)⟩
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · rcases eq_empty_or_nonempty t with (rfl | ht)
    · exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩
    · intro h
      haveI : Nonempty α := ⟨Classical.choose (h.comap_nonempty ht)⟩
      

Proof state:
case mp.inr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
ht : Set.Nonempty t
h : SurjOn f s t
this : Nonempty α
⊢ ∃ s' ⊆ s, BijOn f s' t

Next tactic:
exact ⟨_, h.mapsTo_invFunOn.image_subset, h.bijOn_subset⟩
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · rcases eq_empty_or_nonempty t with (rfl | ht)
    · exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩
    · intro h
      haveI : Nonempty α := ⟨Classical.choose (h.comap_nonempty ht)⟩
      exact ⟨_, h.mapsTo_invFunOn.image_subset, h.bijOn_subset⟩
  · 

Proof state:
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
⊢ (∃ s' ⊆ s, BijOn f s' t) → SurjOn f s t

Next tactic:
rintro ⟨s', hs', hfs'⟩
theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f s' t := by
  constructor
  · rcases eq_empty_or_nonempty t with (rfl | ht)
    · exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩
    · intro h
      haveI : Nonempty α := ⟨Classical.choose (h.comap_nonempty ht)⟩
      exact ⟨_, h.mapsTo_invFunOn.image_subset, h.bijOn_subset⟩
  · rintro ⟨s', hs', hfs'⟩
    

Proof state:
case mpr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s s₁ s₂ : Set α
t : Set β
f : α → β
s' : Set α
hs' : s' ⊆ s
hfs' : BijOn f s' t
⊢ SurjOn f s t

Next tactic:
exact hfs'.surjOn.mono hs' (Subset.refl _)
theorem preimage_invFun_of_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∈ s) : invFun f ⁻¹' s = f '' s ∪ (range f)ᶜ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∈ s
⊢ invFun f ⁻¹' s = f '' s ∪ (range f)ᶜ

Next tactic:
ext x
theorem preimage_invFun_of_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∈ s) : invFun f ⁻¹' s = f '' s ∪ (range f)ᶜ := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∈ s
x : β
⊢ x ∈ invFun f ⁻¹' s ↔ x ∈ f '' s ∪ (range f)ᶜ

Next tactic:
rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
theorem preimage_invFun_of_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∈ s) : invFun f ⁻¹' s = f '' s ∪ (range f)ᶜ := by
  ext x
  rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
  · 

Proof state:
case h.inl.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∈ s
a : α
⊢ f a ∈ invFun f ⁻¹' s ↔ f a ∈ f '' s ∪ (range f)ᶜ

Next tactic:
simp only [mem_preimage, mem_union, mem_compl_iff, mem_range_self, not_true, or_false,
      leftInverse_invFun hf _, hf.mem_set_image]
theorem preimage_invFun_of_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∈ s) : invFun f ⁻¹' s = f '' s ∪ (range f)ᶜ := by
  ext x
  rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
  · simp only [mem_preimage, mem_union, mem_compl_iff, mem_range_self, not_true, or_false,
      leftInverse_invFun hf _, hf.mem_set_image]
  · 

Proof state:
case h.inr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∈ s
x : β
hx : x ∉ range f
⊢ x ∈ invFun f ⁻¹' s ↔ x ∈ f '' s ∪ (range f)ᶜ

Next tactic:
simp only [mem_preimage, invFun_neg hx, h, hx, mem_union, mem_compl_iff, not_false_iff, or_true]
theorem preimage_invFun_of_not_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∉ s) : invFun f ⁻¹' s = f '' s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∉ s
⊢ invFun f ⁻¹' s = f '' s

Next tactic:
ext x
theorem preimage_invFun_of_not_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∉ s) : invFun f ⁻¹' s = f '' s := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∉ s
x : β
⊢ x ∈ invFun f ⁻¹' s ↔ x ∈ f '' s

Next tactic:
rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
theorem preimage_invFun_of_not_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∉ s) : invFun f ⁻¹' s = f '' s := by
  ext x
  rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
  · 

Proof state:
case h.inl.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∉ s
a : α
⊢ f a ∈ invFun f ⁻¹' s ↔ f a ∈ f '' s

Next tactic:
rw [mem_preimage, leftInverse_invFun hf, hf.mem_set_image]
theorem preimage_invFun_of_not_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∉ s) : invFun f ⁻¹' s = f '' s := by
  ext x
  rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
  · rw [mem_preimage, leftInverse_invFun hf, hf.mem_set_image]
  · 

Proof state:
case h.inr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∉ s
x : β
hx : x ∉ range f
⊢ x ∈ invFun f ⁻¹' s ↔ x ∈ f '' s

Next tactic:
have : x ∉ f '' s := fun h' => hx (image_subset_range _ _ h')
theorem preimage_invFun_of_not_mem [n : Nonempty α] {f : α → β} (hf : Injective f) {s : Set α}
    (h : Classical.choice n ∉ s) : invFun f ⁻¹' s = f '' s := by
  ext x
  rcases em (x ∈ range f) with (⟨a, rfl⟩ | hx)
  · rw [mem_preimage, leftInverse_invFun hf, hf.mem_set_image]
  · have : x ∉ f '' s := fun h' => hx (image_subset_range _ _ h')
    

Proof state:
case h.inr
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
s✝ s₁ s₂ : Set α
t : Set β
f✝ : α → β
n : Nonempty α
f : α → β
hf : Injective f
s : Set α
h : Classical.choice n ∉ s
x : β
hx : x ∉ range f
this : x ∉ f '' s
⊢ x ∈ invFun f ⁻¹' s ↔ x ∈ f '' s

Next tactic:
simp only [mem_preimage, invFun_neg hx, h, this]
@[simp]
theorem piecewise_empty [∀ i : α, Decidable (i ∈ (∅ : Set α))] : piecewise ∅ f g = g := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝ : (i : α) → Decidable (i ∈ ∅)
⊢ piecewise ∅ f g = g

Next tactic:
ext i
@[simp]
theorem piecewise_empty [∀ i : α, Decidable (i ∈ (∅ : Set α))] : piecewise ∅ f g = g := by
  ext i
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝ : (i : α) → Decidable (i ∈ ∅)
i : α
⊢ piecewise ∅ f g i = g i

Next tactic:
simp [piecewise]
@[simp]
theorem piecewise_univ [∀ i : α, Decidable (i ∈ (Set.univ : Set α))] :
    piecewise Set.univ f g = f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝ : (i : α) → Decidable (i ∈ univ)
⊢ piecewise univ f g = f

Next tactic:
ext i
@[simp]
theorem piecewise_univ [∀ i : α, Decidable (i ∈ (Set.univ : Set α))] :
    piecewise Set.univ f g = f := by
  ext i
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝ : (i : α) → Decidable (i ∈ univ)
i : α
⊢ piecewise univ f g i = f i

Next tactic:
simp [piecewise]
theorem piecewise_insert_self {j : α} [∀ i, Decidable (i ∈ insert j s)] :
    (insert j s).piecewise f g j = f j := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
j : α
inst✝ : (i : α) → Decidable (i ∈ insert j s)
⊢ piecewise (insert j s) f g j = f j

Next tactic:
simp [piecewise]
theorem piecewise_insert [DecidableEq α] (j : α) [∀ i, Decidable (i ∈ insert j s)] :
    (insert j s).piecewise f g = Function.update (s.piecewise f g) j (f j) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝² : (j : α) → Decidable (j ∈ s)
inst✝¹ : DecidableEq α
j : α
inst✝ : (i : α) → Decidable (i ∈ insert j s)
⊢ piecewise (insert j s) f g = update (piecewise s f g) j (f j)

Next tactic:
simp (config := { unfoldPartialApp := true }) only [piecewise, mem_insert_iff]
theorem piecewise_insert [DecidableEq α] (j : α) [∀ i, Decidable (i ∈ insert j s)] :
    (insert j s).piecewise f g = Function.update (s.piecewise f g) j (f j) := by
  simp (config := { unfoldPartialApp := true }) only [piecewise, mem_insert_iff]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝² : (j : α) → Decidable (j ∈ s)
inst✝¹ : DecidableEq α
j : α
inst✝ : (i : α) → Decidable (i ∈ insert j s)
⊢ (fun i => if i = j ∨ i ∈ s then f i else g i) = update (fun i => if i ∈ s then f i else g i) j (f j)

Next tactic:
ext i
theorem piecewise_insert [DecidableEq α] (j : α) [∀ i, Decidable (i ∈ insert j s)] :
    (insert j s).piecewise f g = Function.update (s.piecewise f g) j (f j) := by
  simp (config := { unfoldPartialApp := true }) only [piecewise, mem_insert_iff]
  ext i
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝² : (j : α) → Decidable (j ∈ s)
inst✝¹ : DecidableEq α
j : α
inst✝ : (i : α) → Decidable (i ∈ insert j s)
i : α
⊢ (if i = j ∨ i ∈ s then f i else g i) = update (fun i => if i ∈ s then f i else g i) j (f j) i

Next tactic:
by_cases h : i = j
theorem piecewise_insert [DecidableEq α] (j : α) [∀ i, Decidable (i ∈ insert j s)] :
    (insert j s).piecewise f g = Function.update (s.piecewise f g) j (f j) := by
  simp (config := { unfoldPartialApp := true }) only [piecewise, mem_insert_iff]
  ext i
  by_cases h : i = j
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
δ : α → Sort u_6
s : Set α
f g : (i : α) → δ i
inst✝² : (j : α) → Decidable (j ∈ s)
inst✝¹ : DecidableEq α
j : α
inst✝ : (i : α) → Decidable (i ∈ insert j s)
i : α
h : i = j
⊢ (if i = j ∨ i ∈ s then f i else g i) = update (fun i => if i ∈ s then f i else g i) j (f j) i

Next tactic:
rw [h]