l3lab/ntp-mathlib huggingface dataset:
theorem range_extend_subset (f : α → β) (g : α → γ) (g' : β → γ) :
    range (extend f g g') ⊆ range g ∪ g' '' (range f)ᶜ := by
  classical
  rintro _ ⟨y, rfl⟩
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
g : α → γ
g' : β → γ
y : β
⊢ extend f g g' y ∈ range g ∪ g' '' (range f)ᶜ

Next tactic:
rw [extend_def]
theorem range_extend_subset (f : α → β) (g : α → γ) (g' : β → γ) :
    range (extend f g g') ⊆ range g ∪ g' '' (range f)ᶜ := by
  classical
  rintro _ ⟨y, rfl⟩
  rw [extend_def]
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
g : α → γ
g' : β → γ
y : β
⊢ (if h : ∃ a, f a = y then g (Classical.choose h) else g' y) ∈ range g ∪ g' '' (range f)ᶜ

Next tactic:
split_ifs with h
theorem range_extend_subset (f : α → β) (g : α → γ) (g' : β → γ) :
    range (extend f g g') ⊆ range g ∪ g' '' (range f)ᶜ := by
  classical
  rintro _ ⟨y, rfl⟩
  rw [extend_def]
  split_ifs with h
  

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
g : α → γ
g' : β → γ
y : β
h : ∃ a, f a = y
⊢ g (Classical.choose h) ∈ range g ∪ g' '' (range f)ᶜ
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
g : α → γ
g' : β → γ
y : β
h : ¬∃ a, f a = y
⊢ g' y ∈ range g ∪ g' '' (range f)ᶜ

Next tactic:
exacts [Or.inl (mem_range_self _), Or.inr (mem_image_of_mem _ h)]
theorem range_extend {f : α → β} (hf : Injective f) (g : α → γ) (g' : β → γ) :
    range (extend f g g') = range g ∪ g' '' (range f)ᶜ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
hf : Injective f
g : α → γ
g' : β → γ
⊢ range (extend f g g') = range g ∪ g' '' (range f)ᶜ

Next tactic:
refine' (range_extend_subset _ _ _).antisymm _
theorem range_extend {f : α → β} (hf : Injective f) (g : α → γ) (g' : β → γ) :
    range (extend f g g') = range g ∪ g' '' (range f)ᶜ := by
  refine' (range_extend_subset _ _ _).antisymm _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
hf : Injective f
g : α → γ
g' : β → γ
⊢ range g ∪ g' '' (range f)ᶜ ⊆ range (extend f g g')

Next tactic:
rintro z (⟨x, rfl⟩ | ⟨y, hy, rfl⟩)
theorem range_extend {f : α → β} (hf : Injective f) (g : α → γ) (g' : β → γ) :
    range (extend f g g') = range g ∪ g' '' (range f)ᶜ := by
  refine' (range_extend_subset _ _ _).antisymm _
  rintro z (⟨x, rfl⟩ | ⟨y, hy, rfl⟩)
  

Proof state:
case inl.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
hf : Injective f
g : α → γ
g' : β → γ
x : α
⊢ g x ∈ range (extend f g g')
case inr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : α → β
hf : Injective f
g : α → γ
g' : β → γ
y : β
hy : y ∈ (range f)ᶜ
⊢ g' y ∈ range (extend f g g')

Next tactic:
exacts [⟨f x, hf.extend_apply _ _ _⟩, ⟨y, extend_apply' _ _ _ hy⟩]
@[simp]
theorem injective_codRestrict {f : ι → α} {s : Set α} (h : ∀ x, f x ∈ s) :
    Injective (codRestrict f s h) ↔ Injective f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : α → Type u_5
f : ι → α
s : Set α
h : ∀ (x : ι), f x ∈ s
⊢ Injective (codRestrict f s h) ↔ Injective f

Next tactic:
simp only [Injective, Subtype.ext_iff, val_codRestrict_apply]
@[simp]
theorem eqOn_singleton : Set.EqOn f₁ f₂ {a} ↔ f₁ a = f₂ a := 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 : β
⊢ EqOn f₁ f₂ {a} ↔ f₁ a = f₂ a

Next tactic:
simp [Set.EqOn]
@[simp]
theorem eqOn_univ (f₁ f₂ : α → β) : EqOn f₁ f₂ univ ↔ f₁ = f₂ := 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 : β
f₁ f₂ : α → β
⊢ EqOn f₁ f₂ univ ↔ f₁ = f₂

Next tactic:
simp [EqOn, funext_iff]
/-- Variant of `EqOn.image_eq`, for one function being the identity. -/
theorem EqOn.image_eq_self {f : α → α} (h : Set.EqOn f id 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 t₁ t₂ : Set β
p : Set γ
f✝ f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
f : α → α
h : EqOn f id s
⊢ f '' s = s

Next tactic:
rw [h.image_eq, image_id]
theorem EqOn.inter_preimage_eq (heq : EqOn f₁ f₂ s) (t : Set β) : s ∩ f₁ ⁻¹' t = s ∩ f₂ ⁻¹' t :=
  ext fun x => and_congr_right_iff.2 fun hx => 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 : β
heq : EqOn f₁ f₂ s
t : Set β
x : α
hx : x ∈ s
⊢ x ∈ f₁ ⁻¹' t ↔ x ∈ f₂ ⁻¹' t

Next tactic:
rw [mem_preimage, mem_preimage, heq hx]
theorem _root_.MonotoneOn.congr (h₁ : MonotoneOn f₁ s) (h : s.EqOn f₁ f₂) : MonotoneOn 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 : β
inst✝¹ : Preorder α
inst✝ : Preorder β
h₁ : MonotoneOn f₁ s
h : EqOn f₁ f₂ s
⊢ MonotoneOn f₂ s

Next tactic:
intro a ha b hb hab
theorem _root_.MonotoneOn.congr (h₁ : MonotoneOn f₁ s) (h : s.EqOn f₁ f₂) : MonotoneOn f₂ s := by
  intro a ha b hb hab
  

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✝ : β
inst✝¹ : Preorder α
inst✝ : Preorder β
h₁ : MonotoneOn f₁ s
h : EqOn f₁ f₂ s
a : α
ha : a ∈ s
b : α
hb : b ∈ s
hab : a ≤ b
⊢ f₂ a ≤ f₂ b

Next tactic:
rw [← h ha, ← h hb]
theorem _root_.MonotoneOn.congr (h₁ : MonotoneOn f₁ s) (h : s.EqOn f₁ f₂) : MonotoneOn f₂ s := by
  intro a ha b hb hab
  rw [← h ha, ← h hb]
  

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✝ : β
inst✝¹ : Preorder α
inst✝ : Preorder β
h₁ : MonotoneOn f₁ s
h : EqOn f₁ f₂ s
a : α
ha : a ∈ s
b : α
hb : b ∈ s
hab : a ≤ b
⊢ f₁ a ≤ f₁ b

Next tactic:
exact h₁ ha hb hab
theorem _root_.StrictMonoOn.congr (h₁ : StrictMonoOn f₁ s) (h : s.EqOn f₁ f₂) :
    StrictMonoOn 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 : β
inst✝¹ : Preorder α
inst✝ : Preorder β
h₁ : StrictMonoOn f₁ s
h : EqOn f₁ f₂ s
⊢ StrictMonoOn f₂ s

Next tactic:
intro a ha b hb hab
theorem _root_.StrictMonoOn.congr (h₁ : StrictMonoOn f₁ s) (h : s.EqOn f₁ f₂) :
    StrictMonoOn f₂ s := by
  intro a ha b hb hab
  

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✝ : β
inst✝¹ : Preorder α
inst✝ : Preorder β
h₁ : StrictMonoOn f₁ s
h : EqOn f₁ f₂ s
a : α
ha : a ∈ s
b : α
hb : b ∈ s
hab : a < b
⊢ f₂ a < f₂ b

Next tactic:
rw [← h ha, ← h hb]
theorem _root_.StrictMonoOn.congr (h₁ : StrictMonoOn f₁ s) (h : s.EqOn f₁ f₂) :
    StrictMonoOn f₂ s := by
  intro a ha b hb hab
  rw [← h ha, ← h hb]
  

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✝ : β
inst✝¹ : Preorder α
inst✝ : Preorder β
h₁ : StrictMonoOn f₁ s
h : EqOn f₁ f₂ s
a : α
ha : a ∈ s
b : α
hb : b ∈ s
hab : a < b
⊢ f₁ a < f₁ b

Next tactic:
exact h₁ ha hb hab
theorem MapsTo.coe_iterate_restrict {f : α → α} (h : MapsTo f s s) (x : s) (k : ℕ) :
    h.restrict^[k] x = f^[k] x := 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 : β
f : α → α
h : MapsTo f s s
x : ↑s
k : ℕ
⊢ ↑((restrict f s s h)^[k] x) = f^[k] ↑x

Next tactic:
induction' k with k ih
theorem MapsTo.coe_iterate_restrict {f : α → α} (h : MapsTo f s s) (x : s) (k : ℕ) :
    h.restrict^[k] x = f^[k] x := by
  induction' k with k ih; · 

Proof state:
case zero
α : 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 : β
f : α → α
h : MapsTo f s s
x : ↑s
⊢ ↑((restrict f s s h)^[Nat.zero] x) = f^[Nat.zero] ↑x

Next tactic:
simp
theorem MapsTo.coe_iterate_restrict {f : α → α} (h : MapsTo f s s) (x : s) (k : ℕ) :
    h.restrict^[k] x = f^[k] x := by
  induction' k with k ih; · simp
  

Proof state:
case succ
α : 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 : β
f : α → α
h : MapsTo f s s
x : ↑s
k : ℕ
ih : ↑((restrict f s s h)^[k] x) = f^[k] ↑x
⊢ ↑((restrict f s s h)^[Nat.succ k] x) = f^[Nat.succ k] ↑x

Next tactic:
simp only [iterate_succ', comp_apply, val_restrict_apply, ih]
theorem mapsTo_iff_exists_map_subtype : MapsTo f s t ↔ ∃ g : s → t, ∀ x : s, f x = g x :=
  ⟨fun h => ⟨h.restrict f s t, fun _ => rfl⟩, fun ⟨g, hg⟩ 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 t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g✝ g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
x✝ : ∃ g, ∀ (x : ↑s), f ↑x = ↑(g x)
x : α
hx : x ∈ s
g : ↑s → ↑t
hg : ∀ (x : ↑s), f ↑x = ↑(g x)
⊢ f x ∈ t

Next tactic:
erw [hg ⟨x, hx⟩]
theorem mapsTo_iff_exists_map_subtype : MapsTo f s t ↔ ∃ g : s → t, ∀ x : s, f x = g x :=
  ⟨fun h => ⟨h.restrict f s t, fun _ => rfl⟩, fun ⟨g, hg⟩ x hx => by
    erw [hg ⟨x, hx⟩]
    

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 : β
x✝ : ∃ g, ∀ (x : ↑s), f ↑x = ↑(g x)
x : α
hx : x ∈ s
g : ↑s → ↑t
hg : ∀ (x : ↑s), f ↑x = ↑(g x)
⊢ ↑(g { val := x, property := hx }) ∈ t

Next tactic:
apply Subtype.coe_prop
theorem MapsTo.iterate_restrict {f : α → α} {s : Set α} (h : MapsTo f s s) (n : ℕ) :
    (h.restrict f s s)^[n] = (h.iterate n).restrict _ _ _ := 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 : β
f : α → α
s : Set α
h : MapsTo f s s
n : ℕ
⊢ (restrict f s s h)^[n] = restrict f^[n] s s (_ : MapsTo f^[n] s s)

Next tactic:
funext x
theorem MapsTo.iterate_restrict {f : α → α} {s : Set α} (h : MapsTo f s s) (n : ℕ) :
    (h.restrict f s s)^[n] = (h.iterate n).restrict _ _ _ := by
  funext 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 t₁ t₂ : Set β
p : Set γ
f✝ f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
f : α → α
s : Set α
h : MapsTo f s s
n : ℕ
x : ↑s
⊢ (restrict f s s h)^[n] x = restrict f^[n] s s (_ : MapsTo f^[n] s s) x

Next tactic:
rw [Subtype.ext_iff, MapsTo.val_restrict_apply]
theorem MapsTo.iterate_restrict {f : α → α} {s : Set α} (h : MapsTo f s s) (n : ℕ) :
    (h.restrict f s s)^[n] = (h.iterate n).restrict _ _ _ := by
  funext x
  rw [Subtype.ext_iff, MapsTo.val_restrict_apply]
  

Proof state:
case h
α : 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 : β
f : α → α
s : Set α
h : MapsTo f s s
n : ℕ
x : ↑s
⊢ ↑((restrict f s s h)^[n] x) = f^[n] ↑x

Next tactic:
induction' n with n ihn generalizing x
theorem MapsTo.iterate_restrict {f : α → α} {s : Set α} (h : MapsTo f s s) (n : ℕ) :
    (h.restrict f s s)^[n] = (h.iterate n).restrict _ _ _ := by
  funext x
  rw [Subtype.ext_iff, MapsTo.val_restrict_apply]
  induction' n with n ihn generalizing x
  · 

Proof state:
case h.zero
α : 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 : β
f : α → α
s : Set α
h : MapsTo f s s
x : ↑s
⊢ ↑((restrict f s s h)^[Nat.zero] x) = f^[Nat.zero] ↑x

Next tactic:
rfl
theorem MapsTo.iterate_restrict {f : α → α} {s : Set α} (h : MapsTo f s s) (n : ℕ) :
    (h.restrict f s s)^[n] = (h.iterate n).restrict _ _ _ := by
  funext x
  rw [Subtype.ext_iff, MapsTo.val_restrict_apply]
  induction' n with n ihn generalizing x
  · rfl
  · 

Proof state:
case h.succ
α : 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 : β
f : α → α
s : Set α
h : MapsTo f s s
n : ℕ
ihn : ∀ (x : ↑s), ↑((restrict f s s h)^[n] x) = f^[n] ↑x
x : ↑s
⊢ ↑((restrict f s s h)^[Nat.succ n] x) = f^[Nat.succ n] ↑x

Next tactic:
simp [Nat.iterate, ihn]
theorem mapsTo_image (f : α → β) (s : Set α) : MapsTo 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 t₁ t₂ : Set β
p : Set γ
f✝ f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
f : α → β
s : Set α
⊢ MapsTo f s (f '' s)

Next tactic:
rw [mapsTo']
@[simp]
theorem maps_range_to (f : α → β) (g : γ → α) (s : Set β) :
    MapsTo f (range g) s ↔ MapsTo (f ∘ g) univ 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 : β
f : α → β
g : γ → α
s : Set β
⊢ MapsTo f (range g) s ↔ MapsTo (f ∘ g) univ s

Next tactic:
rw [← image_univ, maps_image_to]
theorem range_restrictPreimage : range (t.restrictPreimage f) = Subtype.val ⁻¹' 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 t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
⊢ range (restrictPreimage t f) = Subtype.val ⁻¹' range f

Next tactic:
delta Set.restrictPreimage
theorem range_restrictPreimage : range (t.restrictPreimage f) = Subtype.val ⁻¹' range f := by
  delta Set.restrictPreimage
  

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 : β
⊢ range (MapsTo.restrict f (f ⁻¹' t) t (_ : MapsTo f (f ⁻¹' t) t)) = Subtype.val ⁻¹' range f

Next tactic:
rw [MapsTo.range_restrict, Set.image_preimage_eq_inter_range, Set.preimage_inter,
    Subtype.coe_preimage_self, Set.univ_inter]
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := 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 : β
h : Disjoint s₁ s₂
⊢ InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y

Next tactic:
refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := by
  refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
  · 

Proof state:
case refine'_1
α : 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 : β
h : Disjoint s₁ s₂
H : InjOn f (s₁ ∪ s₂)
⊢ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y

Next tactic:
intro x hx y hy hxy
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := by
  refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
  · intro x hx y hy hxy
    

Proof state:
case refine'_1
α : 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 : β
h : Disjoint s₁ s₂
H : InjOn f (s₁ ∪ s₂)
x : α
hx : x ∈ s₁
y : α
hy : y ∈ s₂
hxy : f x = f y
⊢ False

Next tactic:
obtain rfl : x = y := H (Or.inl hx) (Or.inr hy) hxy
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := by
  refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
  · intro x hx y hy hxy
    obtain rfl : x = y := H (Or.inl hx) (Or.inr hy) hxy
    

Proof state:
case refine'_1
α : 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 : β
h : Disjoint s₁ s₂
H : InjOn f (s₁ ∪ s₂)
x : α
hx : x ∈ s₁
hy : x ∈ s₂
hxy : f x = f x
⊢ False

Next tactic:
exact h.le_bot ⟨hx, hy⟩
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := by
  refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
  · intro x hx y hy hxy
    obtain rfl : x = y := H (Or.inl hx) (Or.inr hy) hxy
    exact h.le_bot ⟨hx, hy⟩
  · 

Proof state:
case refine'_2
α : 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 : β
h : Disjoint s₁ s₂
⊢ (InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y) → InjOn f (s₁ ∪ s₂)

Next tactic:
rintro ⟨h₁, h₂, h₁₂⟩
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := by
  refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
  · intro x hx y hy hxy
    obtain rfl : x = y := H (Or.inl hx) (Or.inr hy) hxy
    exact h.le_bot ⟨hx, hy⟩
  · rintro ⟨h₁, h₂, h₁₂⟩
    

Proof state:
case refine'_2.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 : β
h : Disjoint s₁ s₂
h₁ : InjOn f s₁
h₂ : InjOn f s₂
h₁₂ : ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y
⊢ InjOn f (s₁ ∪ s₂)

Next tactic:
rintro x (hx | hx) y (hy | hy) hxy
theorem injOn_union (h : Disjoint s₁ s₂) :
    InjOn f (s₁ ∪ s₂) ↔ InjOn f s₁ ∧ InjOn f s₂ ∧ ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y := by
  refine' ⟨fun H => ⟨H.mono <| subset_union_left _ _, H.mono <| subset_union_right _ _, _⟩, _⟩
  · intro x hx y hy hxy
    obtain rfl : x = y := H (Or.inl hx) (Or.inr hy) hxy
    exact h.le_bot ⟨hx, hy⟩
  · rintro ⟨h₁, h₂, h₁₂⟩
    rintro x (hx | hx) y (hy | hy) hxy
    

Proof state:
case refine'_2.intro.intro.inl.inl
α : 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 : β
h : Disjoint s₁ s₂
h₁ : InjOn f s₁
h₂ : InjOn f s₂
h₁₂ : ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y
x : α
hx : x ∈ s₁
y : α
hy : y ∈ s₁
hxy : f x = f y
⊢ x = y
case refine'_2.intro.intro.inl.inr
α : 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 : β
h : Disjoint s₁ s₂
h₁ : InjOn f s₁
h₂ : InjOn f s₂
h₁₂ : ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y
x : α
hx : x ∈ s₁
y : α
hy : y ∈ s₂
hxy : f x = f y
⊢ x = y
case refine'_2.intro.intro.inr.inl
α : 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 : β
h : Disjoint s₁ s₂
h₁ : InjOn f s₁
h₂ : InjOn f s₂
h₁₂ : ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y
x : α
hx : x ∈ s₂
y : α
hy : y ∈ s₁
hxy : f x = f y
⊢ x = y
case refine'_2.intro.intro.inr.inr
α : 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 : β
h : Disjoint s₁ s₂
h₁ : InjOn f s₁
h₂ : InjOn f s₂
h₁₂ : ∀ x ∈ s₁, ∀ y ∈ s₂, f x ≠ f y
x : α
hx : x ∈ s₂
y : α
hy : y ∈ s₂
hxy : f x = f y
⊢ x = y

Next tactic:
exacts [h₁ hx hy hxy, (h₁₂ _ hx _ hy hxy).elim, (h₁₂ _ hy _ hx hxy.symm).elim, h₂ hx hy hxy]
theorem injOn_insert {f : α → β} {s : Set α} {a : α} (has : a ∉ s) :
    Set.InjOn f (insert a s) ↔ Set.InjOn f s ∧ f a ∉ 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 : β
f : α → β
s : Set α
a : α
has : a ∉ s
⊢ InjOn f (insert a s) ↔ InjOn f s ∧ f a ∉ f '' s

Next tactic:
have : Disjoint s {a} := disjoint_iff_inf_le.mpr fun x ⟨hxs, (hxa : x = a)⟩ => has (hxa ▸ hxs)
theorem injOn_insert {f : α → β} {s : Set α} {a : α} (has : a ∉ s) :
    Set.InjOn f (insert a s) ↔ Set.InjOn f s ∧ f a ∉ f '' s := by
  have : Disjoint s {a} := disjoint_iff_inf_le.mpr fun x ⟨hxs, (hxa : x = a)⟩ => has (hxa ▸ hxs)
  

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 : β
f : α → β
s : Set α
a : α
has : a ∉ s
this : Disjoint s {a}
⊢ InjOn f (insert a s) ↔ InjOn f s ∧ f a ∉ f '' s

Next tactic:
rw [← union_singleton, injOn_union this]
theorem injOn_insert {f : α → β} {s : Set α} {a : α} (has : a ∉ s) :
    Set.InjOn f (insert a s) ↔ Set.InjOn f s ∧ f a ∉ f '' s := by
  have : Disjoint s {a} := disjoint_iff_inf_le.mpr fun x ⟨hxs, (hxa : x = a)⟩ => has (hxa ▸ hxs)
  rw [← union_singleton, injOn_union this]
  

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 : β
f : α → β
s : Set α
a : α
has : a ∉ s
this : Disjoint s {a}
⊢ (InjOn f s ∧ InjOn f {a} ∧ ∀ x ∈ s, ∀ y ∈ {a}, f x ≠ f y) ↔ InjOn f s ∧ f a ∉ f '' s

Next tactic:
simp
theorem _root_.Function.Injective.injOn_range (h : Injective (g ∘ f)) : InjOn g (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 t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
h : Injective (g ∘ f)
⊢ InjOn g (range f)

Next tactic:
rintro _ ⟨x, rfl⟩ _ ⟨y, rfl⟩ H
theorem _root_.Function.Injective.injOn_range (h : Injective (g ∘ f)) : InjOn g (range f) := by
  rintro _ ⟨x, rfl⟩ _ ⟨y, rfl⟩ H
  

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 t₁ t₂ : Set β
p : Set γ
f f₁ f₂ f₃ : α → β
g g₁ g₂ : β → γ
f' f₁' f₂' : β → α
g' : γ → β
a : α
b : β
h : Injective (g ∘ f)
x y : α
H : g (f x) = g (f y)
⊢ f x = f y

Next tactic:
exact congr_arg f (h H)
theorem MapsTo.restrict_inj (h : MapsTo f s t) : Injective (h.restrict f s t) ↔ InjOn 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 : β
h : MapsTo f s t
⊢ Injective (restrict f s t h) ↔ InjOn f s

Next tactic:
rw [h.restrict_eq_codRestrict, injective_codRestrict, injOn_iff_injective]