Theorem: isLocallyInjective_iff_isOpen_diagonal
File: Mathlib/Topology/SeparatedMap.lean

tactic: simp_rw [isLocallyInjective_iff_nhds, isOpen_iff_mem_nhds,
  Subtype.forall, Prod.forall, nhds_induced, nhds_prod_eq, Filter.mem_comap]
state_before: X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
⊢ IsLocallyInjective f ↔ IsOpen (Function.pullbackDiagonal f)
state_after: X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
⊢ (∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U) ↔
    ∀ (a b : X) (b_1 : f a = f b),
      ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f

tactic: refine ⟨?_, fun h x ↦ ?_⟩
state_before: X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
⊢ (∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U) ↔
    ∀ (a b : X) (b_1 : f a = f b),
      ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
state_after: case refine_1
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
⊢ (∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U) →
    ∀ (a b : X) (b_1 : f a = f b),
      ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f

case refine_2
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h :
  ∀ (a b : X) (b_1 : f a = f b),
    ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
x : X
⊢ ∃ U ∈ 𝓝 x, Set.InjOn f U

tactic: rintro h x x' hx (rfl : x = x')
state_before: case refine_1
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
⊢ (∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U) →
    ∀ (a b : X) (b_1 : f a = f b),
      ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
state_after: case refine_1
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h : ∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U
x : X
hx : f x = f x
⊢ ∃ t ∈ 𝓝 x ×ˢ 𝓝 x, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f

tactic: obtain ⟨U, hn, hi⟩ := h x
state_before: case refine_1
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h : ∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U
x : X
hx : f x = f x
⊢ ∃ t ∈ 𝓝 x ×ˢ 𝓝 x, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
state_after: case refine_1.intro.intro
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h : ∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U
x : X
hx : f x = f x
U : Set X
hn : U ∈ 𝓝 x
hi : Set.InjOn f U
⊢ ∃ t ∈ 𝓝 x ×ˢ 𝓝 x, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f

tactic: exact ⟨_, Filter.prod_mem_prod hn hn, fun {p} hp ↦ hi hp.1 hp.2 p.2⟩
state_before: case refine_1.intro.intro
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h : ∀ (x : X), ∃ U ∈ 𝓝 x, Set.InjOn f U
x : X
hx : f x = f x
U : Set X
hn : U ∈ 𝓝 x
hi : Set.InjOn f U
⊢ ∃ t ∈ 𝓝 x ×ˢ 𝓝 x, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
state_after: no goals

tactic: obtain ⟨t, ht, t_sub⟩ := h x x rfl rfl
state_before: case refine_2
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h :
  ∀ (a b : X) (b_1 : f a = f b),
    ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
x : X
⊢ ∃ U ∈ 𝓝 x, Set.InjOn f U
state_after: case refine_2.intro.intro
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h :
  ∀ (a b : X) (b_1 : f a = f b),
    ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
x : X
t : Set (X × X)
ht : t ∈ 𝓝 x ×ˢ 𝓝 x
t_sub : Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
⊢ ∃ U ∈ 𝓝 x, Set.InjOn f U

tactic: obtain ⟨t₁, h₁, t₂, h₂, prod_sub⟩ := Filter.mem_prod_iff.mp ht
state_before: case refine_2.intro.intro
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h :
  ∀ (a b : X) (b_1 : f a = f b),
    ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
x : X
t : Set (X × X)
ht : t ∈ 𝓝 x ×ˢ 𝓝 x
t_sub : Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
⊢ ∃ U ∈ 𝓝 x, Set.InjOn f U
state_after: case refine_2.intro.intro.intro.intro.intro.intro
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h :
  ∀ (a b : X) (b_1 : f a = f b),
    ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
x : X
t : Set (X × X)
ht : t ∈ 𝓝 x ×ˢ 𝓝 x
t_sub : Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
t₁ : Set X
h₁ : t₁ ∈ 𝓝 x
t₂ : Set X
h₂ : t₂ ∈ 𝓝 x
prod_sub : t₁ ×ˢ t₂ ⊆ t
⊢ ∃ U ∈ 𝓝 x, Set.InjOn f U

tactic: exact ⟨t₁ ∩ t₂, Filter.inter_mem h₁ h₂,
  fun x₁ h₁ x₂ h₂ he ↦ @t_sub ⟨(x₁, x₂), he⟩ (prod_sub ⟨h₁.1, h₂.2⟩)⟩
state_before: case refine_2.intro.intro.intro.intro.intro.intro
X : Type u_1
Y : Type u_2
A : Type ?u.14918
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace A
f : X → Y
h :
  ∀ (a b : X) (b_1 : f a = f b),
    ⟨(a, b), b_1⟩ ∈ Function.pullbackDiagonal f → ∃ t ∈ 𝓝 a ×ˢ 𝓝 b, Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
x : X
t : Set (X × X)
ht : t ∈ 𝓝 x ×ˢ 𝓝 x
t_sub : Subtype.val ⁻¹' t ⊆ Function.pullbackDiagonal f
t₁ : Set X
h₁ : t₁ ∈ 𝓝 x
t₂ : Set X
h₂ : t₂ ∈ 𝓝 x
prod_sub : t₁ ×ˢ t₂ ⊆ t
⊢ ∃ U ∈ 𝓝 x, Set.InjOn f U
state_after: no goals