l3lab/ntp-mathlib huggingface dataset:
/-- The preimage of a nontrivial set under a surjective map is nontrivial. -/
theorem Nontrivial.preimage {s : Set β} (hs : s.Nontrivial) {f : α → β}
    (hf : Function.Surjective f) : (f ⁻¹' s).Nontrivial := by
  rcases hs with ⟨fx, hx, fy, hy, hxy⟩
  rcases hf fx, hf fy with ⟨⟨x, rfl⟩, ⟨y, rfl⟩⟩
  

Proof state:
case intro.intro.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
s✝ : Set α
s : Set β
f : α → β
hf : Surjective f
x : α
hx : f x ∈ s
y : α
hy : f y ∈ s
hxy : f x ≠ f y
⊢ Set.Nontrivial (f ⁻¹' s)

Next tactic:
exact ⟨x, hx, y, hy, mt (congr_arg f) hxy⟩
theorem Injective.preimage_surjective (hf : Injective f) : Surjective (preimage f) := by
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
⊢ Surjective (preimage f)

Next tactic:
intro s
theorem Injective.preimage_surjective (hf : Injective f) : Surjective (preimage f) := by
  intro s
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
⊢ ∃ a, f ⁻¹' a = s

Next tactic:
use f '' s
theorem Injective.preimage_surjective (hf : Injective f) : Surjective (preimage f) := by
  intro s
  use f '' s
  

Proof state:
case h
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
⊢ f ⁻¹' (f '' s) = s

Next tactic:
rw [hf.preimage_image]
theorem Surjective.image_surjective (hf : Surjective f) : Surjective (image f) := by
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Surjective f
⊢ Surjective (image f)

Next tactic:
intro s
theorem Surjective.image_surjective (hf : Surjective f) : Surjective (image f) := by
  intro s
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Surjective f
s : Set β
⊢ ∃ a, f '' a = s

Next tactic:
use f ⁻¹' s
theorem Surjective.image_surjective (hf : Surjective f) : Surjective (image f) := by
  intro s
  use f ⁻¹' s
  

Proof state:
case h
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Surjective f
s : Set β
⊢ f '' (f ⁻¹' s) = s

Next tactic:
rw [hf.image_preimage]
@[simp]
theorem Surjective.nonempty_preimage (hf : Surjective f) {s : Set β} :
    (f ⁻¹' s).Nonempty ↔ s.Nonempty := by 

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Surjective f
s : Set β
⊢ Set.Nonempty (f ⁻¹' s) ↔ Set.Nonempty s

Next tactic:
rw [← nonempty_image_iff, hf.image_preimage]
theorem Injective.image_injective (hf : Injective f) : Injective (image f) := by
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
⊢ Injective (image f)

Next tactic:
intro s t h
theorem Injective.image_injective (hf : Injective f) : Injective (image f) := by
  intro s t h
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s t : Set α
h : f '' s = f '' t
⊢ s = t

Next tactic:
rw [← preimage_image_eq s hf, ← preimage_image_eq t hf, h]
theorem Surjective.preimage_subset_preimage_iff {s t : Set β} (hf : Surjective f) :
    f ⁻¹' s ⊆ f ⁻¹' t ↔ s ⊆ t := by
  

Proof state:
α : Type u_3
β : Type u_2
ι : Sort u_1
f : α → β
s t : Set β
hf : Surjective f
⊢ f ⁻¹' s ⊆ f ⁻¹' t ↔ s ⊆ t

Next tactic:
apply Set.preimage_subset_preimage_iff
theorem Surjective.preimage_subset_preimage_iff {s t : Set β} (hf : Surjective f) :
    f ⁻¹' s ⊆ f ⁻¹' t ↔ s ⊆ t := by
  apply Set.preimage_subset_preimage_iff
  

Proof state:
case hs
α : Type u_3
β : Type u_2
ι : Sort u_1
f : α → β
s t : Set β
hf : Surjective f
⊢ s ⊆ range f

Next tactic:
rw [hf.range_eq]
theorem Surjective.preimage_subset_preimage_iff {s t : Set β} (hf : Surjective f) :
    f ⁻¹' s ⊆ f ⁻¹' t ↔ s ⊆ t := by
  apply Set.preimage_subset_preimage_iff
  rw [hf.range_eq]
  

Proof state:
case hs
α : Type u_3
β : Type u_2
ι : Sort u_1
f : α → β
s t : Set β
hf : Surjective f
⊢ s ⊆ univ

Next tactic:
apply subset_univ
theorem Injective.compl_image_eq (hf : Injective f) (s : Set α) :
    (f '' s)ᶜ = f '' sᶜ ∪ (range f)ᶜ := by
  

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
⊢ (f '' s)ᶜ = f '' sᶜ ∪ (range f)ᶜ

Next tactic:
ext y
theorem Injective.compl_image_eq (hf : Injective f) (s : Set α) :
    (f '' s)ᶜ = f '' sᶜ ∪ (range f)ᶜ := by
  ext y
  

Proof state:
case h
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
y : β
⊢ y ∈ (f '' s)ᶜ ↔ y ∈ f '' sᶜ ∪ (range f)ᶜ

Next tactic:
rcases em (y ∈ range f) with (⟨x, rfl⟩ | hx)
theorem Injective.compl_image_eq (hf : Injective f) (s : Set α) :
    (f '' s)ᶜ = f '' sᶜ ∪ (range f)ᶜ := by
  ext y
  rcases em (y ∈ range f) with (⟨x, rfl⟩ | hx)
  · 

Proof state:
case h.inl.intro
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
x : α
⊢ f x ∈ (f '' s)ᶜ ↔ f x ∈ f '' sᶜ ∪ (range f)ᶜ

Next tactic:
simp [hf.eq_iff]
theorem Injective.compl_image_eq (hf : Injective f) (s : Set α) :
    (f '' s)ᶜ = f '' sᶜ ∪ (range f)ᶜ := by
  ext y
  rcases em (y ∈ range f) with (⟨x, rfl⟩ | hx)
  · simp [hf.eq_iff]
  · 

Proof state:
case h.inr
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
y : β
hx : y ∉ range f
⊢ y ∈ (f '' s)ᶜ ↔ y ∈ f '' sᶜ ∪ (range f)ᶜ

Next tactic:
rw [mem_range, not_exists] at hx
theorem Injective.compl_image_eq (hf : Injective f) (s : Set α) :
    (f '' s)ᶜ = f '' sᶜ ∪ (range f)ᶜ := by
  ext y
  rcases em (y ∈ range f) with (⟨x, rfl⟩ | hx)
  · simp [hf.eq_iff]
  · rw [mem_range, not_exists] at hx
    

Proof state:
case h.inr
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
hf : Injective f
s : Set α
y : β
hx : ∀ (x : α), ¬f x = y
⊢ y ∈ (f '' s)ᶜ ↔ y ∈ f '' sᶜ ∪ (range f)ᶜ

Next tactic:
simp [hx]
theorem LeftInverse.image_image {g : β → α} (h : LeftInverse g f) (s : Set α) : g '' (f '' s) = s :=
  by 

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
g : β → α
h : LeftInverse g f
s : Set α
⊢ g '' (f '' s) = s

Next tactic:
rw [← image_comp, h.comp_eq_id, image_id]
theorem LeftInverse.preimage_preimage {g : β → α} (h : LeftInverse g f) (s : Set α) :
    f ⁻¹' (g ⁻¹' s) = s := by 

Proof state:
α : Type u_2
β : Type u_3
ι : Sort u_1
f : α → β
g : β → α
h : LeftInverse g f
s : Set α
⊢ f ⁻¹' (g ⁻¹' s) = s

Next tactic:
rw [← preimage_comp, h.comp_eq_id, preimage_id]
@[simp]
theorem coe_image_of_subset {s t : Set α} (h : t ⊆ s) : (↑) '' { x : ↥s | ↑x ∈ t } = t := by
  

Proof state:
α : Type u_1
s t : Set α
h : t ⊆ s
⊢ val '' {x | ↑x ∈ t} = t

Next tactic:
ext x
@[simp]
theorem coe_image_of_subset {s t : Set α} (h : t ⊆ s) : (↑) '' { x : ↥s | ↑x ∈ t } = t := by
  ext x
  

Proof state:
case h
α : Type u_1
s t : Set α
h : t ⊆ s
x : α
⊢ x ∈ val '' {x | ↑x ∈ t} ↔ x ∈ t

Next tactic:
rw [mem_image]
@[simp]
theorem coe_image_of_subset {s t : Set α} (h : t ⊆ s) : (↑) '' { x : ↥s | ↑x ∈ t } = t := by
  ext x
  rw [mem_image]
  

Proof state:
case h
α : Type u_1
s t : Set α
h : t ⊆ s
x : α
⊢ (∃ x_1 ∈ {x | ↑x ∈ t}, ↑x_1 = x) ↔ x ∈ t

Next tactic:
exact ⟨fun ⟨_, hx', hx⟩ => hx ▸ hx', fun hx => ⟨⟨x, h hx⟩, hx, rfl⟩⟩
theorem range_coe {s : Set α} : range ((↑) : s → α) = s := by
  

Proof state:
α : Type u_1
s : Set α
⊢ range val = s

Next tactic:
rw [← image_univ]
theorem range_coe {s : Set α} : range ((↑) : s → α) = s := by
  rw [← image_univ]
  

Proof state:
α : Type u_1
s : Set α
⊢ val '' univ = s

Next tactic:
simp [-image_univ, coe_image]
@[simp]
theorem coe_preimage_self (s : Set α) : ((↑) : s → α) ⁻¹' s = univ := by
  

Proof state:
α : Type u_1
s : Set α
⊢ val ⁻¹' s = univ

Next tactic:
rw [← preimage_range, range_coe]
theorem coe_image_subset (s : Set α) (t : Set s) : ((↑) : s → α) '' t ⊆ s :=
  fun x ⟨y, _, yvaleq⟩ => by
  

Proof state:
α : Type u_1
s : Set α
t : Set ↑s
x : α
x✝ : x ∈ val '' t
y : { x // x ∈ s }
left✝ : y ∈ t
yvaleq : ↑y = x
⊢ x ∈ s

Next tactic:
rw [← yvaleq]
theorem coe_image_subset (s : Set α) (t : Set s) : ((↑) : s → α) '' t ⊆ s :=
  fun x ⟨y, _, yvaleq⟩ => by
  rw [← yvaleq]; 

Proof state:
α : Type u_1
s : Set α
t : Set ↑s
x : α
x✝ : x ∈ val '' t
y : { x // x ∈ s }
left✝ : y ∈ t
yvaleq : ↑y = x
⊢ ↑y ∈ s

Next tactic:
exact y.property
theorem preimage_coe_eq_preimage_coe_iff {s t u : Set α} :
    ((↑) : s → α) ⁻¹' t = ((↑) : s → α) ⁻¹' u ↔ t ∩ s = u ∩ s := by
  

Proof state:
α : Type u_1
s t u : Set α
⊢ val ⁻¹' t = val ⁻¹' u ↔ t ∩ s = u ∩ s

Next tactic:
rw [← image_preimage_coe, ← image_preimage_coe, coe_injective.image_injective.eq_iff]
theorem preimage_coe_inter_self (s t : Set α) :
    ((↑) : s → α) ⁻¹' (t ∩ s) = ((↑) : s → α) ⁻¹' t := by
  

Proof state:
α : Type u_1
s t : Set α
⊢ val ⁻¹' (t ∩ s) = val ⁻¹' t

Next tactic:
rw [preimage_coe_eq_preimage_coe_iff, inter_assoc, inter_self]
theorem exists_set_subtype {t : Set α} (p : Set α → Prop) :
    (∃ s : Set t, p (((↑) : t → α) '' s)) ↔ ∃ s : Set α, s ⊆ t ∧ p s := by
  

Proof state:
α : Type u_1
t : Set α
p : Set α → Prop
⊢ (∃ s, p (val '' s)) ↔ ∃ s ⊆ t, p s

Next tactic:
rw [← exists_subset_range_and_iff, range_coe]
theorem forall_set_subtype {t : Set α} (p : Set α → Prop) :
    (∀ s : Set t, p (((↑) : t → α) '' s)) ↔ ∀ s : Set α, s ⊆ t → p s := by
  

Proof state:
α : Type u_1
t : Set α
p : Set α → Prop
⊢ (∀ (s : Set ↑t), p (val '' s)) ↔ ∀ s ⊆ t, p s

Next tactic:
rw [← forall_subset_range_iff, range_coe]
theorem preimage_coe_nonempty {s t : Set α} :
    (((↑) : s → α) ⁻¹' t).Nonempty ↔ (s ∩ t).Nonempty := by
  

Proof state:
α : Type u_1
s t : Set α
⊢ Set.Nonempty (val ⁻¹' t) ↔ Set.Nonempty (s ∩ t)

Next tactic:
rw [inter_comm, ← image_preimage_coe, nonempty_image_iff]
theorem preimage_coe_eq_empty {s t : Set α} : ((↑) : s → α) ⁻¹' t = ∅ ↔ s ∩ t = ∅ := by
  

Proof state:
α : Type u_1
s t : Set α
⊢ val ⁻¹' t = ∅ ↔ s ∩ t = ∅

Next tactic:
simp [← not_nonempty_iff_eq_empty, preimage_coe_nonempty]
theorem injective_iff {α β} {f : Option α → β} :
    Injective f ↔ Injective (f ∘ some) ∧ f none ∉ range (f ∘ some) := by
  

Proof state:
α : Type u_1
β : Type u_2
f : Option α → β
⊢ Injective f ↔ Injective (f ∘ some) ∧ f none ∉ range (f ∘ some)

Next tactic:
simp only [mem_range, not_exists, (· ∘ ·)]
theorem injective_iff {α β} {f : Option α → β} :
    Injective f ↔ Injective (f ∘ some) ∧ f none ∉ range (f ∘ some) := by
  simp only [mem_range, not_exists, (· ∘ ·)]
  

Proof state:
α : Type u_1
β : Type u_2
f : Option α → β
⊢ Injective f ↔ (Injective fun x => f (some x)) ∧ ∀ (x : α), ¬f (some x) = f none

Next tactic:
refine'
    ⟨fun hf => ⟨hf.comp (Option.some_injective _), fun x => hf.ne <| Option.some_ne_none _⟩, _⟩
theorem injective_iff {α β} {f : Option α → β} :
    Injective f ↔ Injective (f ∘ some) ∧ f none ∉ range (f ∘ some) := by
  simp only [mem_range, not_exists, (· ∘ ·)]
  refine'
    ⟨fun hf => ⟨hf.comp (Option.some_injective _), fun x => hf.ne <| Option.some_ne_none _⟩, _⟩
  

Proof state:
α : Type u_1
β : Type u_2
f : Option α → β
⊢ ((Injective fun x => f (some x)) ∧ ∀ (x : α), ¬f (some x) = f none) → Injective f

Next tactic:
rintro ⟨h_some, h_none⟩ (_ | a) (_ | b) hab
theorem injective_iff {α β} {f : Option α → β} :
    Injective f ↔ Injective (f ∘ some) ∧ f none ∉ range (f ∘ some) := by
  simp only [mem_range, not_exists, (· ∘ ·)]
  refine'
    ⟨fun hf => ⟨hf.comp (Option.some_injective _), fun x => hf.ne <| Option.some_ne_none _⟩, _⟩
  rintro ⟨h_some, h_none⟩ (_ | a) (_ | b) hab
  

Proof state:
case intro.none.none
α : Type u_1
β : Type u_2
f : Option α → β
h_some : Injective fun x => f (some x)
h_none : ∀ (x : α), ¬f (some x) = f none
hab : f none = f none
⊢ none = none
case intro.none.some
α : Type u_1
β : Type u_2
f : Option α → β
h_some : Injective fun x => f (some x)
h_none : ∀ (x : α), ¬f (some x) = f none
b : α
hab : f none = f (some b)
⊢ none = some b
case intro.some.none
α : Type u_1
β : Type u_2
f : Option α → β
h_some : Injective fun x => f (some x)
h_none : ∀ (x : α), ¬f (some x) = f none
a : α
hab : f (some a) = f none
⊢ some a = none
case intro.some.some
α : Type u_1
β : Type u_2
f : Option α → β
h_some : Injective fun x => f (some x)
h_none : ∀ (x : α), ¬f (some x) = f none
a b : α
hab : f (some a) = f (some b)
⊢ some a = some b

Next tactic:
exacts [rfl, (h_none _ hab.symm).elim, (h_none _ hab).elim, congr_arg some (h_some hab)]
@[simp]
theorem preimage_injective : Injective (preimage f) ↔ Surjective f := by
  

Proof state:
α : Type u
β : Type v
f : α → β
⊢ Injective (preimage f) ↔ Surjective f

Next tactic:
refine' ⟨fun h y => _, Surjective.preimage_injective⟩
@[simp]
theorem preimage_injective : Injective (preimage f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.preimage_injective⟩
  

Proof state:
α : Type u
β : Type v
f : α → β
h : Injective (preimage f)
y : β
⊢ ∃ a, f a = y

Next tactic:
obtain ⟨x, hx⟩ : (f ⁻¹' {y}).Nonempty := by
    rw [h.nonempty_apply_iff preimage_empty]
    apply singleton_nonempty
@[simp]
theorem preimage_injective : Injective (preimage f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.preimage_injective⟩
  obtain ⟨x, hx⟩ : (f ⁻¹' {y}).Nonempty := by
    

Proof state:
α : Type u
β : Type v
f : α → β
h : Injective (preimage f)
y : β
⊢ Set.Nonempty (f ⁻¹' {y})

Next tactic:
rw [h.nonempty_apply_iff preimage_empty]
@[simp]
theorem preimage_injective : Injective (preimage f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.preimage_injective⟩
  obtain ⟨x, hx⟩ : (f ⁻¹' {y}).Nonempty := by
    rw [h.nonempty_apply_iff preimage_empty]
    

Proof state:
α : Type u
β : Type v
f : α → β
h : Injective (preimage f)
y : β
⊢ Set.Nonempty {y}

Next tactic:
apply singleton_nonempty
@[simp]
theorem preimage_injective : Injective (preimage f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.preimage_injective⟩
  obtain ⟨x, hx⟩ : (f ⁻¹' {y}).Nonempty := by
    rw [h.nonempty_apply_iff preimage_empty]
    apply singleton_nonempty
  

Proof state:
case intro
α : Type u
β : Type v
f : α → β
h : Injective (preimage f)
y : β
x : α
hx : x ∈ f ⁻¹' {y}
⊢ ∃ a, f a = y

Next tactic:
exact ⟨x, hx⟩
@[simp]
theorem preimage_surjective : Surjective (preimage f) ↔ Injective f := by
  

Proof state:
α : Type u
β : Type v
f : α → β
⊢ Surjective (preimage f) ↔ Injective f

Next tactic:
refine' ⟨fun h x x' hx => _, Injective.preimage_surjective⟩
@[simp]
theorem preimage_surjective : Surjective (preimage f) ↔ Injective f := by
  refine' ⟨fun h x x' hx => _, Injective.preimage_surjective⟩
  

Proof state:
α : Type u
β : Type v
f : α → β
h : Surjective (preimage f)
x x' : α
hx : f x = f x'
⊢ x = x'

Next tactic:
cases' h {x} with s hs
@[simp]
theorem preimage_surjective : Surjective (preimage f) ↔ Injective f := by
  refine' ⟨fun h x x' hx => _, Injective.preimage_surjective⟩
  cases' h {x} with s hs; 

Proof state:
case intro
α : Type u
β : Type v
f : α → β
h : Surjective (preimage f)
x x' : α
hx : f x = f x'
s : Set β
hs : f ⁻¹' s = {x}
⊢ x = x'

Next tactic:
have := mem_singleton x
@[simp]
theorem preimage_surjective : Surjective (preimage f) ↔ Injective f := by
  refine' ⟨fun h x x' hx => _, Injective.preimage_surjective⟩
  cases' h {x} with s hs; have := mem_singleton x
  

Proof state:
case intro
α : Type u
β : Type v
f : α → β
h : Surjective (preimage f)
x x' : α
hx : f x = f x'
s : Set β
hs : f ⁻¹' s = {x}
this : x ∈ {x}
⊢ x = x'

Next tactic:
rwa [← hs, mem_preimage, hx, ← mem_preimage, hs, mem_singleton_iff, eq_comm] at this
@[simp]
theorem image_surjective : Surjective (image f) ↔ Surjective f := by
  

Proof state:
α : Type u
β : Type v
f : α → β
⊢ Surjective (image f) ↔ Surjective f

Next tactic:
refine' ⟨fun h y => _, Surjective.image_surjective⟩
@[simp]
theorem image_surjective : Surjective (image f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.image_surjective⟩
  

Proof state:
α : Type u
β : Type v
f : α → β
h : Surjective (image f)
y : β
⊢ ∃ a, f a = y

Next tactic:
cases' h {y} with s hs
@[simp]
theorem image_surjective : Surjective (image f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.image_surjective⟩
  cases' h {y} with s hs
  

Proof state:
case intro
α : Type u
β : Type v
f : α → β
h : Surjective (image f)
y : β
s : Set α
hs : f '' s = {y}
⊢ ∃ a, f a = y

Next tactic:
have := mem_singleton y
@[simp]
theorem image_surjective : Surjective (image f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.image_surjective⟩
  cases' h {y} with s hs
  have := mem_singleton y; 

Proof state:
case intro
α : Type u
β : Type v
f : α → β
h : Surjective (image f)
y : β
s : Set α
hs : f '' s = {y}
this : y ∈ {y}
⊢ ∃ a, f a = y

Next tactic:
rw [← hs] at this
@[simp]
theorem image_surjective : Surjective (image f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.image_surjective⟩
  cases' h {y} with s hs
  have := mem_singleton y; rw [← hs] at this; 

Proof state:
case intro
α : Type u
β : Type v
f : α → β
h : Surjective (image f)
y : β
s : Set α
hs : f '' s = {y}
this : y ∈ f '' s
⊢ ∃ a, f a = y

Next tactic:
rcases this with ⟨x, _, hx⟩
@[simp]
theorem image_surjective : Surjective (image f) ↔ Surjective f := by
  refine' ⟨fun h y => _, Surjective.image_surjective⟩
  cases' h {y} with s hs
  have := mem_singleton y; rw [← hs] at this; rcases this with ⟨x, _, hx⟩
  

Proof state:
case intro.intro.intro
α : Type u
β : Type v
f : α → β
h : Surjective (image f)
y : β
s : Set α
hs : f '' s = {y}
x : α
left✝ : x ∈ s
hx : f x = y
⊢ ∃ a, f a = y

Next tactic:
exact ⟨x, hx⟩
@[simp]
theorem image_injective : Injective (image f) ↔ Injective f := by
  

Proof state:
α : Type u
β : Type v
f : α → β
⊢ Injective (image f) ↔ Injective f

Next tactic:
refine' ⟨fun h x x' hx => _, Injective.image_injective⟩
@[simp]
theorem image_injective : Injective (image f) ↔ Injective f := by
  refine' ⟨fun h x x' hx => _, Injective.image_injective⟩
  

Proof state:
α : Type u
β : Type v
f : α → β
h : Injective (image f)
x x' : α
hx : f x = f x'
⊢ x = x'

Next tactic:
rw [← singleton_eq_singleton_iff]
@[simp]
theorem image_injective : Injective (image f) ↔ Injective f := by
  refine' ⟨fun h x x' hx => _, Injective.image_injective⟩
  rw [← singleton_eq_singleton_iff]; 

Proof state:
α : Type u
β : Type v
f : α → β
h : Injective (image f)
x x' : α
hx : f x = f x'
⊢ {x} = {x'}

Next tactic:
apply h
@[simp]
theorem image_injective : Injective (image f) ↔ Injective f := by
  refine' ⟨fun h x x' hx => _, Injective.image_injective⟩
  rw [← singleton_eq_singleton_iff]; apply h
  

Proof state:
case a
α : Type u
β : Type v
f : α → β
h : Injective (image f)
x x' : α
hx : f x = f x'
⊢ f '' {x} = f '' {x'}

Next tactic:
rw [image_singleton, image_singleton, hx]
theorem preimage_eq_iff_eq_image {f : α → β} (hf : Bijective f) {s t} : f ⁻¹' s = t ↔ s = f '' t :=
  by 

Proof state:
α : Type u
β : Type v
f✝ f : α → β
hf : Bijective f
s : Set β
t : Set α
⊢ f ⁻¹' s = t ↔ s = f '' t

Next tactic:
rw [← image_eq_image hf.1, hf.2.image_preimage]
theorem eq_preimage_iff_image_eq {f : α → β} (hf : Bijective f) {s t} : s = f ⁻¹' t ↔ f '' s = t :=
  by 

Proof state:
α : Type u
β : Type v
f✝ f : α → β
hf : Bijective f
s : Set α
t : Set β
⊢ s = f ⁻¹' t ↔ f '' s = t

Next tactic:
rw [← image_eq_image hf.1, hf.2.image_preimage]
theorem disjoint_image_image {f : β → α} {g : γ → α} {s : Set β} {t : Set γ}
    (h : ∀ b ∈ s, ∀ c ∈ t, f b ≠ g c) : Disjoint (f '' s) (g '' t) :=
  disjoint_iff_inf_le.mpr <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β
s✝ t✝ : Set α
f : β → α
g : γ → α
s : Set β
t : Set γ
h : ∀ b ∈ s, ∀ c ∈ t, f b ≠ g c
⊢ f '' s ⊓ g '' t ≤ ⊥

Next tactic:
rintro a ⟨⟨b, hb, eq⟩, c, hc, rfl⟩
theorem disjoint_image_image {f : β → α} {g : γ → α} {s : Set β} {t : Set γ}
    (h : ∀ b ∈ s, ∀ c ∈ t, f b ≠ g c) : Disjoint (f '' s) (g '' t) :=
  disjoint_iff_inf_le.mpr <| by rintro a ⟨⟨b, hb, eq⟩, c, hc, rfl⟩; 

Proof state:
case intro.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α → β
s✝ t✝ : Set α
f : β → α
g : γ → α
s : Set β
t : Set γ
h : ∀ b ∈ s, ∀ c ∈ t, f b ≠ g c
b : β
hb : b ∈ s
c : γ
hc : c ∈ t
eq : f b = g c
⊢ g c ∈ ⊥

Next tactic:
exact h b hb c hc eq
theorem _root_.Disjoint.of_preimage (hf : Surjective f) {s t : Set β}
    (h : Disjoint (f ⁻¹' s) (f ⁻¹' t)) : Disjoint s t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
s✝ t✝ : Set α
hf : Surjective f
s t : Set β
h : Disjoint (f ⁻¹' s) (f ⁻¹' t)
⊢ Disjoint s t

Next tactic:
rw [disjoint_iff_inter_eq_empty, ← image_preimage_eq (_ ∩ _) hf, preimage_inter, h.inter_eq,
    image_empty]
theorem preimage_eq_empty {s : Set β} (h : Disjoint s (range f)) :
    f ⁻¹' s = ∅ :=
  by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
s✝ t : Set α
s : Set β
h : Disjoint s (range f)
⊢ f ⁻¹' s = ∅

Next tactic:
simpa using h.preimage f
theorem preimage_eq_empty_iff {s : Set β} : f ⁻¹' s = ∅ ↔ Disjoint s (range f) :=
  ⟨fun h => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
s✝ t : Set α
s : Set β
h : f ⁻¹' s = ∅
⊢ Disjoint s (range f)

Next tactic:
simp only [eq_empty_iff_forall_not_mem, disjoint_iff_inter_eq_empty, not_exists, mem_inter_iff,
      not_and, mem_range, mem_preimage] at h ⊢
theorem preimage_eq_empty_iff {s : Set β} : f ⁻¹' s = ∅ ↔ Disjoint s (range f) :=
  ⟨fun h => by
    simp only [eq_empty_iff_forall_not_mem, disjoint_iff_inter_eq_empty, not_exists, mem_inter_iff,
      not_and, mem_range, mem_preimage] at h ⊢
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
s✝ t : Set α
s : Set β
h : ∀ (x : α), f x ∉ s
⊢ ∀ x ∈ s, ∀ (x_1 : α), ¬f x_1 = x

Next tactic:
intro y hy x hx
theorem preimage_eq_empty_iff {s : Set β} : f ⁻¹' s = ∅ ↔ Disjoint s (range f) :=
  ⟨fun h => by
    simp only [eq_empty_iff_forall_not_mem, disjoint_iff_inter_eq_empty, not_exists, mem_inter_iff,
      not_and, mem_range, mem_preimage] at h ⊢
    intro y hy x hx
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
s✝ t : Set α
s : Set β
h : ∀ (x : α), f x ∉ s
y : β
hy : y ∈ s
x : α
hx : f x = y
⊢ False

Next tactic:
rw [← hx] at hy
theorem preimage_eq_empty_iff {s : Set β} : f ⁻¹' s = ∅ ↔ Disjoint s (range f) :=
  ⟨fun h => by
    simp only [eq_empty_iff_forall_not_mem, disjoint_iff_inter_eq_empty, not_exists, mem_inter_iff,
      not_and, mem_range, mem_preimage] at h ⊢
    intro y hy x hx
    rw [← hx] at hy
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
s✝ t : Set α
s : Set β
h : ∀ (x : α), f x ∉ s
y : β
x : α
hy : f x ∈ s
hx : f x = y
⊢ False

Next tactic:
exact h x hy
lemma sigma_mk_preimage_image' (h : i ≠ j) : Sigma.mk j ⁻¹' (Sigma.mk i '' s) = ∅ := by
  

Proof state:
α : Type u_1
β : α → Type u_2
i j : α
s : Set (β i)
h : i ≠ j
⊢ Sigma.mk j ⁻¹' (Sigma.mk i '' s) = ∅

Next tactic:
simp [image, h]
lemma sigma_mk_preimage_image_eq_self : Sigma.mk i ⁻¹' (Sigma.mk i '' s) = s := by
  

Proof state:
α : Type u_1
β : α → Type u_2
i j : α
s : Set (β i)
⊢ Sigma.mk i ⁻¹' (Sigma.mk i '' s) = s

Next tactic:
simp [image]
theorem nim_def (o : Ordinal) :
    have : IsWellOrder (Quotient.out o).α (· < ·) := inferInstance
    nim o =
      PGame.mk o.out.α o.out.α (fun o₂ => nim (Ordinal.typein (· < ·) o₂)) fun o₂ =>
        nim (Ordinal.typein (· < ·) o₂) := by
  

Proof state:
o : Ordinal.{u_1}
⊢ let_fun this := (_ : IsWellOrder (Quotient.out o).α fun x x_1 => x < x_1);
  nim o =
    mk (Quotient.out o).α (Quotient.out o).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
      nim (typein (fun x x_1 => x < x_1) o₂)

Next tactic:
rw [nim]
theorem nim_def (o : Ordinal) :
    have : IsWellOrder (Quotient.out o).α (· < ·) := inferInstance
    nim o =
      PGame.mk o.out.α o.out.α (fun o₂ => nim (Ordinal.typein (· < ·) o₂)) fun o₂ =>
        nim (Ordinal.typein (· < ·) o₂) := by
  rw [nim]; 

Proof state:
o : Ordinal.{u_1}
⊢ let_fun this := (_ : IsWellOrder (Quotient.out o).α fun x x_1 => x < x_1);
  (mk (Quotient.out o).α (Quotient.out o).α
      (fun o₂ =>
        let_fun x := (_ : typein (fun x x_1 => x < x_1) o₂ < o);
        nim (typein (Quotient.out o).r o₂))
      fun o₂ =>
      let_fun x := (_ : typein (fun x x_1 => x < x_1) o₂ < o);
      nim (typein (Quotient.out o).r o₂)) =
    mk (Quotient.out o).α (Quotient.out o).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
      nim (typein (fun x x_1 => x < x_1) o₂)

Next tactic:
rfl
theorem leftMoves_nim (o : Ordinal) : (nim o).LeftMoves = o.out.α := by 

Proof state:
o : Ordinal.{u_1}
⊢ LeftMoves (nim o) = (Quotient.out o).α

Next tactic:
rw [nim_def]