l3lab/ntp-mathlib huggingface dataset:
theorem Filter.Tendsto.prod_mk_nhds {γ} {a : α} {b : β} {f : Filter γ} {ma : γ → α} {mb : γ → β}
    (ha : Tendsto ma f (𝓝 a)) (hb : Tendsto mb f (𝓝 b)) :
    Tendsto (fun c => (ma c, mb c)) f (𝓝 (a, b)) := by
  rw [nhds_prod_eq]; 

Proof state:
α : Type u
β : Type v
γ✝ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ✝
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
γ : Type u_5
a : α
b : β
f : Filter γ
ma : γ → α
mb : γ → β
ha : Tendsto ma f (𝓝 a)
hb : Tendsto mb f (𝓝 b)
⊢ Tendsto (fun c => (ma c, mb c)) f (𝓝 a ×ˢ 𝓝 b)

Next tactic:
exact Filter.Tendsto.prod_mk ha hb
theorem Filter.Eventually.curry_nhds {p : α × β → Prop} {x : α} {y : β}
    (h : ∀ᶠ x in 𝓝 (x, y), p x) : ∀ᶠ x' in 𝓝 x, ∀ᶠ y' in 𝓝 y, p (x', y') := by
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
p : α × β → Prop
x : α
y : β
h : ∀ᶠ (x : α × β) in 𝓝 (x, y), p x
⊢ ∀ᶠ (x' : α) in 𝓝 x, ∀ᶠ (y' : β) in 𝓝 y, p (x', y')

Next tactic:
rw [nhds_prod_eq] at h
theorem Filter.Eventually.curry_nhds {p : α × β → Prop} {x : α} {y : β}
    (h : ∀ᶠ x in 𝓝 (x, y), p x) : ∀ᶠ x' in 𝓝 x, ∀ᶠ y' in 𝓝 y, p (x', y') := by
  rw [nhds_prod_eq] at h
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
p : α × β → Prop
x : α
y : β
h : ∀ᶠ (x : α × β) in 𝓝 x ×ˢ 𝓝 y, p x
⊢ ∀ᶠ (x' : α) in 𝓝 x, ∀ᶠ (y' : β) in 𝓝 y, p (x', y')

Next tactic:
exact h.curry
theorem prod_generateFrom_generateFrom_eq {α β : Type*} {s : Set (Set α)} {t : Set (Set β)}
    (hs : ⋃₀ s = univ) (ht : ⋃₀ t = univ) :
    @instTopologicalSpaceProd α β (generateFrom s) (generateFrom t) =
      generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v } :=
  let G := generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v }
  le_antisymm
    (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ =>
      g_eq.symm ▸
        @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu)
          (GenerateOpen.basic _ hv))
    (le_inf
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun u hu =>
          have : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u := by
            

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α✝
inst✝⁴ : TopologicalSpace β✝
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
α : Type u_5
β : Type u_6
s : Set (Set α)
t : Set (Set β)
hs : ⋃₀ s = univ
ht : ⋃₀ t = univ
G : TopologicalSpace (α × β) := generateFrom {g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v}
u : Set α
hu : u ∈ s
⊢ ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u

Next tactic:
simp_rw [← prod_iUnion, ← sUnion_eq_biUnion, ht, prod_univ]
theorem prod_generateFrom_generateFrom_eq {α β : Type*} {s : Set (Set α)} {t : Set (Set β)}
    (hs : ⋃₀ s = univ) (ht : ⋃₀ t = univ) :
    @instTopologicalSpaceProd α β (generateFrom s) (generateFrom t) =
      generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v } :=
  let G := generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v }
  le_antisymm
    (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ =>
      g_eq.symm ▸
        @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu)
          (GenerateOpen.basic _ hv))
    (le_inf
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun u hu =>
          have : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u := by
            simp_rw [← prod_iUnion, ← sUnion_eq_biUnion, ht, prod_univ]
          show G.IsOpen (Prod.fst ⁻¹' u) by
            

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α✝
inst✝⁴ : TopologicalSpace β✝
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
α : Type u_5
β : Type u_6
s : Set (Set α)
t : Set (Set β)
hs : ⋃₀ s = univ
ht : ⋃₀ t = univ
G : TopologicalSpace (α × β) := generateFrom {g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v}
u : Set α
hu : u ∈ s
this : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u
⊢ TopologicalSpace.IsOpen (Prod.fst ⁻¹' u)

Next tactic:
rw [← this]
theorem prod_generateFrom_generateFrom_eq {α β : Type*} {s : Set (Set α)} {t : Set (Set β)}
    (hs : ⋃₀ s = univ) (ht : ⋃₀ t = univ) :
    @instTopologicalSpaceProd α β (generateFrom s) (generateFrom t) =
      generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v } :=
  let G := generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v }
  le_antisymm
    (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ =>
      g_eq.symm ▸
        @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu)
          (GenerateOpen.basic _ hv))
    (le_inf
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun u hu =>
          have : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u := by
            simp_rw [← prod_iUnion, ← sUnion_eq_biUnion, ht, prod_univ]
          show G.IsOpen (Prod.fst ⁻¹' u) by
            rw [← this]
            

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α✝
inst✝⁴ : TopologicalSpace β✝
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
α : Type u_5
β : Type u_6
s : Set (Set α)
t : Set (Set β)
hs : ⋃₀ s = univ
ht : ⋃₀ t = univ
G : TopologicalSpace (α × β) := generateFrom {g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v}
u : Set α
hu : u ∈ s
this : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u
⊢ TopologicalSpace.IsOpen (⋃ v ∈ t, u ×ˢ v)

Next tactic:
exact
              isOpen_iUnion fun v =>
                isOpen_iUnion fun hv => GenerateOpen.basic _ ⟨_, hu, _, hv, rfl⟩
theorem prod_generateFrom_generateFrom_eq {α β : Type*} {s : Set (Set α)} {t : Set (Set β)}
    (hs : ⋃₀ s = univ) (ht : ⋃₀ t = univ) :
    @instTopologicalSpaceProd α β (generateFrom s) (generateFrom t) =
      generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v } :=
  let G := generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v }
  le_antisymm
    (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ =>
      g_eq.symm ▸
        @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu)
          (GenerateOpen.basic _ hv))
    (le_inf
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun u hu =>
          have : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u := by
            simp_rw [← prod_iUnion, ← sUnion_eq_biUnion, ht, prod_univ]
          show G.IsOpen (Prod.fst ⁻¹' u) by
            rw [← this]
            exact
              isOpen_iUnion fun v =>
                isOpen_iUnion fun hv => GenerateOpen.basic _ ⟨_, hu, _, hv, rfl⟩)
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun v hv =>
          have : ⋃ u ∈ s, u ×ˢ v = Prod.snd ⁻¹' v := by
            

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α✝
inst✝⁴ : TopologicalSpace β✝
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
α : Type u_5
β : Type u_6
s : Set (Set α)
t : Set (Set β)
hs : ⋃₀ s = univ
ht : ⋃₀ t = univ
G : TopologicalSpace (α × β) := generateFrom {g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v}
v : Set β
hv : v ∈ t
⊢ ⋃ u ∈ s, u ×ˢ v = Prod.snd ⁻¹' v

Next tactic:
simp_rw [← iUnion_prod_const, ← sUnion_eq_biUnion, hs, univ_prod]
theorem prod_generateFrom_generateFrom_eq {α β : Type*} {s : Set (Set α)} {t : Set (Set β)}
    (hs : ⋃₀ s = univ) (ht : ⋃₀ t = univ) :
    @instTopologicalSpaceProd α β (generateFrom s) (generateFrom t) =
      generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v } :=
  let G := generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v }
  le_antisymm
    (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ =>
      g_eq.symm ▸
        @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu)
          (GenerateOpen.basic _ hv))
    (le_inf
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun u hu =>
          have : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u := by
            simp_rw [← prod_iUnion, ← sUnion_eq_biUnion, ht, prod_univ]
          show G.IsOpen (Prod.fst ⁻¹' u) by
            rw [← this]
            exact
              isOpen_iUnion fun v =>
                isOpen_iUnion fun hv => GenerateOpen.basic _ ⟨_, hu, _, hv, rfl⟩)
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun v hv =>
          have : ⋃ u ∈ s, u ×ˢ v = Prod.snd ⁻¹' v := by
            simp_rw [← iUnion_prod_const, ← sUnion_eq_biUnion, hs, univ_prod]
          show G.IsOpen (Prod.snd ⁻¹' v) by
            

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α✝
inst✝⁴ : TopologicalSpace β✝
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
α : Type u_5
β : Type u_6
s : Set (Set α)
t : Set (Set β)
hs : ⋃₀ s = univ
ht : ⋃₀ t = univ
G : TopologicalSpace (α × β) := generateFrom {g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v}
v : Set β
hv : v ∈ t
this : ⋃ u ∈ s, u ×ˢ v = Prod.snd ⁻¹' v
⊢ TopologicalSpace.IsOpen (Prod.snd ⁻¹' v)

Next tactic:
rw [← this]
theorem prod_generateFrom_generateFrom_eq {α β : Type*} {s : Set (Set α)} {t : Set (Set β)}
    (hs : ⋃₀ s = univ) (ht : ⋃₀ t = univ) :
    @instTopologicalSpaceProd α β (generateFrom s) (generateFrom t) =
      generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v } :=
  let G := generateFrom { g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v }
  le_antisymm
    (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ =>
      g_eq.symm ▸
        @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu)
          (GenerateOpen.basic _ hv))
    (le_inf
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun u hu =>
          have : ⋃ v ∈ t, u ×ˢ v = Prod.fst ⁻¹' u := by
            simp_rw [← prod_iUnion, ← sUnion_eq_biUnion, ht, prod_univ]
          show G.IsOpen (Prod.fst ⁻¹' u) by
            rw [← this]
            exact
              isOpen_iUnion fun v =>
                isOpen_iUnion fun hv => GenerateOpen.basic _ ⟨_, hu, _, hv, rfl⟩)
      (coinduced_le_iff_le_induced.mp <|
        le_generateFrom fun v hv =>
          have : ⋃ u ∈ s, u ×ˢ v = Prod.snd ⁻¹' v := by
            simp_rw [← iUnion_prod_const, ← sUnion_eq_biUnion, hs, univ_prod]
          show G.IsOpen (Prod.snd ⁻¹' v) by
            rw [← this]
            

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α✝
inst✝⁴ : TopologicalSpace β✝
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
α : Type u_5
β : Type u_6
s : Set (Set α)
t : Set (Set β)
hs : ⋃₀ s = univ
ht : ⋃₀ t = univ
G : TopologicalSpace (α × β) := generateFrom {g | ∃ u ∈ s, ∃ v ∈ t, g = u ×ˢ v}
v : Set β
hv : v ∈ t
this : ⋃ u ∈ s, u ×ˢ v = Prod.snd ⁻¹' v
⊢ TopologicalSpace.IsOpen (⋃ u ∈ s, u ×ˢ v)

Next tactic:
exact
              isOpen_iUnion fun u =>
                isOpen_iUnion fun hu => GenerateOpen.basic _ ⟨_, hu, _, hv, rfl⟩
theorem prod_eq_generateFrom :
    instTopologicalSpaceProd =
      generateFrom { g | ∃ (s : Set α) (t : Set β), IsOpen s ∧ IsOpen t ∧ g = s ×ˢ t } :=
  le_antisymm (le_generateFrom fun g ⟨s, t, hs, ht, g_eq⟩ => g_eq.symm ▸ hs.prod ht)
    (le_inf
      (ball_image_of_ball fun t ht =>
        GenerateOpen.basic _ ⟨t, univ, by 

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
t : Set α
ht : t ∈ fun s' => inst✝⁵.1 s'
⊢ IsOpen t ∧ IsOpen univ ∧ Prod.fst ⁻¹' t = t ×ˢ univ

Next tactic:
simpa [Set.prod_eq] using ht
theorem prod_eq_generateFrom :
    instTopologicalSpaceProd =
      generateFrom { g | ∃ (s : Set α) (t : Set β), IsOpen s ∧ IsOpen t ∧ g = s ×ˢ t } :=
  le_antisymm (le_generateFrom fun g ⟨s, t, hs, ht, g_eq⟩ => g_eq.symm ▸ hs.prod ht)
    (le_inf
      (ball_image_of_ball fun t ht =>
        GenerateOpen.basic _ ⟨t, univ, by simpa [Set.prod_eq] using ht⟩)
      (ball_image_of_ball fun t ht =>
        GenerateOpen.basic _ ⟨univ, t, by 

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
t : Set β
ht : t ∈ fun s' => inst✝⁴.1 s'
⊢ IsOpen univ ∧ IsOpen t ∧ Prod.snd ⁻¹' t = univ ×ˢ t

Next tactic:
simpa [Set.prod_eq] using ht
theorem isOpen_prod_iff {s : Set (α × β)} :
    IsOpen s ↔ ∀ a b, (a, b) ∈ s →
      ∃ u v, IsOpen u ∧ IsOpen v ∧ a ∈ u ∧ b ∈ v ∧ u ×ˢ v ⊆ s :=
  isOpen_iff_mem_nhds.trans <| by 

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set (α × β)
⊢ (∀ a ∈ s, s ∈ 𝓝 a) ↔ ∀ (a : α) (b : β), (a, b) ∈ s → ∃ u v, IsOpen u ∧ IsOpen v ∧ a ∈ u ∧ b ∈ v ∧ u ×ˢ v ⊆ s

Next tactic:
simp_rw [Prod.forall, mem_nhds_prod_iff', and_left_comm]
/-- A product of induced topologies is induced by the product map -/
theorem prod_induced_induced (f : α → β) (g : γ → δ) :
    @instTopologicalSpaceProd α γ (induced f ‹_›) (induced g ‹_›) =
      induced (fun p => (f p.1, g p.2)) instTopologicalSpaceProd := by
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
f : α → β
g : γ → δ
⊢ instTopologicalSpaceProd = induced (fun p => (f p.1, g p.2)) instTopologicalSpaceProd

Next tactic:
delta instTopologicalSpaceProd
/-- A product of induced topologies is induced by the product map -/
theorem prod_induced_induced (f : α → β) (g : γ → δ) :
    @instTopologicalSpaceProd α γ (induced f ‹_›) (induced g ‹_›) =
      induced (fun p => (f p.1, g p.2)) instTopologicalSpaceProd := by
  delta instTopologicalSpaceProd
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
f : α → β
g : γ → δ
⊢ induced Prod.fst (induced f inst✝⁴) ⊓ induced Prod.snd (induced g inst✝²) =
    induced (fun p => (f p.1, g p.2)) (induced Prod.fst inst✝⁴ ⊓ induced Prod.snd inst✝²)

Next tactic:
simp_rw [induced_inf, induced_compose]
/-- A product of induced topologies is induced by the product map -/
theorem prod_induced_induced (f : α → β) (g : γ → δ) :
    @instTopologicalSpaceProd α γ (induced f ‹_›) (induced g ‹_›) =
      induced (fun p => (f p.1, g p.2)) instTopologicalSpaceProd := by
  delta instTopologicalSpaceProd
  simp_rw [induced_inf, induced_compose]
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
f : α → β
g : γ → δ
⊢ induced (f ∘ Prod.fst) inst✝⁴ ⊓ induced (g ∘ Prod.snd) inst✝² =
    induced (Prod.fst ∘ fun p => (f p.1, g p.2)) inst✝⁴ ⊓ induced (Prod.snd ∘ fun p => (f p.1, g p.2)) inst✝²

Next tactic:
rfl
/-- Given a neighborhood `s` of `(x, x)`, then `(x, x)` has a square open neighborhood
  that is a subset of `s`. -/
theorem exists_nhds_square {s : Set (α × α)} {x : α} (hx : s ∈ 𝓝 (x, x)) :
    ∃ U : Set α, IsOpen U ∧ x ∈ U ∧ U ×ˢ U ⊆ s := by
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set (α × α)
x : α
hx : s ∈ 𝓝 (x, x)
⊢ ∃ U, IsOpen U ∧ x ∈ U ∧ U ×ˢ U ⊆ s

Next tactic:
simpa [nhds_prod_eq, (nhds_basis_opens x).prod_self.mem_iff, and_assoc, and_left_comm] using hx
/-- `Prod.fst` maps neighborhood of `x : α × β` within the section `Prod.snd ⁻¹' {x.2}`
to `𝓝 x.1`. -/
theorem map_fst_nhdsWithin (x : α × β) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1 := by
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
x : α × β
⊢ map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1

Next tactic:
refine' le_antisymm (continuousAt_fst.mono_left inf_le_left) fun s hs => _
/-- `Prod.fst` maps neighborhood of `x : α × β` within the section `Prod.snd ⁻¹' {x.2}`
to `𝓝 x.1`. -/
theorem map_fst_nhdsWithin (x : α × β) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1 := by
  refine' le_antisymm (continuousAt_fst.mono_left inf_le_left) fun s hs => _
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
x : α × β
s : Set α
hs : s ∈ map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x)
⊢ s ∈ 𝓝 x.1

Next tactic:
rcases x with ⟨x, y⟩
/-- `Prod.fst` maps neighborhood of `x : α × β` within the section `Prod.snd ⁻¹' {x.2}`
to `𝓝 x.1`. -/
theorem map_fst_nhdsWithin (x : α × β) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1 := by
  refine' le_antisymm (continuousAt_fst.mono_left inf_le_left) fun s hs => _
  rcases x with ⟨x, y⟩
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set α
x : α
y : β
hs : s ∈ map Prod.fst (𝓝[Prod.snd ⁻¹' {(x, y).2}] (x, y))
⊢ s ∈ 𝓝 (x, y).1

Next tactic:
rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs
/-- `Prod.fst` maps neighborhood of `x : α × β` within the section `Prod.snd ⁻¹' {x.2}`
to `𝓝 x.1`. -/
theorem map_fst_nhdsWithin (x : α × β) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1 := by
  refine' le_antisymm (continuousAt_fst.mono_left inf_le_left) fun s hs => _
  rcases x with ⟨x, y⟩
  rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set α
x : α
y : β
hs : ∃ u ∈ 𝓝 x, ∃ v ∈ 𝓝 y, u ×ˢ v ⊆ {x_1 | x_1 ∈ Prod.snd ⁻¹' {(x, y).2} → x_1 ∈ Prod.fst ⁻¹' s}
⊢ s ∈ 𝓝 (x, y).1

Next tactic:
rcases hs with ⟨u, hu, v, hv, H⟩
/-- `Prod.fst` maps neighborhood of `x : α × β` within the section `Prod.snd ⁻¹' {x.2}`
to `𝓝 x.1`. -/
theorem map_fst_nhdsWithin (x : α × β) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1 := by
  refine' le_antisymm (continuousAt_fst.mono_left inf_le_left) fun s hs => _
  rcases x with ⟨x, y⟩
  rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs
  rcases hs with ⟨u, hu, v, hv, H⟩
  

Proof state:
case mk.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set α
x : α
y : β
u : Set α
hu : u ∈ 𝓝 x
v : Set β
hv : v ∈ 𝓝 y
H : u ×ˢ v ⊆ {x_1 | x_1 ∈ Prod.snd ⁻¹' {(x, y).2} → x_1 ∈ Prod.fst ⁻¹' s}
⊢ s ∈ 𝓝 (x, y).1

Next tactic:
simp only [prod_subset_iff, mem_singleton_iff, mem_setOf_eq, mem_preimage] at H
/-- `Prod.fst` maps neighborhood of `x : α × β` within the section `Prod.snd ⁻¹' {x.2}`
to `𝓝 x.1`. -/
theorem map_fst_nhdsWithin (x : α × β) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x.2}] x) = 𝓝 x.1 := by
  refine' le_antisymm (continuousAt_fst.mono_left inf_le_left) fun s hs => _
  rcases x with ⟨x, y⟩
  rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs
  rcases hs with ⟨u, hu, v, hv, H⟩
  simp only [prod_subset_iff, mem_singleton_iff, mem_setOf_eq, mem_preimage] at H
  

Proof state:
case mk.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set α
x : α
y : β
u : Set α
hu : u ∈ 𝓝 x
v : Set β
hv : v ∈ 𝓝 y
H : ∀ x ∈ u, ∀ y_1 ∈ v, y_1 = y → x ∈ s
⊢ s ∈ 𝓝 (x, y).1

Next tactic:
exact mem_of_superset hu fun z hz => H _ hz _ (mem_of_mem_nhds hv) rfl
/-- `Prod.snd` maps neighborhood of `x : α × β` within the section `Prod.fst ⁻¹' {x.1}`
to `𝓝 x.2`. -/
theorem map_snd_nhdsWithin (x : α × β) : map Prod.snd (𝓝[Prod.fst ⁻¹' {x.1}] x) = 𝓝 x.2 := by
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
x : α × β
⊢ map Prod.snd (𝓝[Prod.fst ⁻¹' {x.1}] x) = 𝓝 x.2

Next tactic:
refine' le_antisymm (continuousAt_snd.mono_left inf_le_left) fun s hs => _
/-- `Prod.snd` maps neighborhood of `x : α × β` within the section `Prod.fst ⁻¹' {x.1}`
to `𝓝 x.2`. -/
theorem map_snd_nhdsWithin (x : α × β) : map Prod.snd (𝓝[Prod.fst ⁻¹' {x.1}] x) = 𝓝 x.2 := by
  refine' le_antisymm (continuousAt_snd.mono_left inf_le_left) fun s hs => _
  

Proof state:
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
x : α × β
s : Set β
hs : s ∈ map Prod.snd (𝓝[Prod.fst ⁻¹' {x.1}] x)
⊢ s ∈ 𝓝 x.2

Next tactic:
rcases x with ⟨x, y⟩
/-- `Prod.snd` maps neighborhood of `x : α × β` within the section `Prod.fst ⁻¹' {x.1}`
to `𝓝 x.2`. -/
theorem map_snd_nhdsWithin (x : α × β) : map Prod.snd (𝓝[Prod.fst ⁻¹' {x.1}] x) = 𝓝 x.2 := by
  refine' le_antisymm (continuousAt_snd.mono_left inf_le_left) fun s hs => _
  rcases x with ⟨x, y⟩
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set β
x : α
y : β
hs : s ∈ map Prod.snd (𝓝[Prod.fst ⁻¹' {(x, y).1}] (x, y))
⊢ s ∈ 𝓝 (x, y).2

Next tactic:
rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs
/-- `Prod.snd` maps neighborhood of `x : α × β` within the section `Prod.fst ⁻¹' {x.1}`
to `𝓝 x.2`. -/
theorem map_snd_nhdsWithin (x : α × β) : map Prod.snd (𝓝[Prod.fst ⁻¹' {x.1}] x) = 𝓝 x.2 := by
  refine' le_antisymm (continuousAt_snd.mono_left inf_le_left) fun s hs => _
  rcases x with ⟨x, y⟩
  rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type u_1
δ : Type u_2
ε : Type u_3
ζ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
inst✝¹ : TopologicalSpace ε
inst✝ : TopologicalSpace ζ
s : Set β
x : α
y : β
hs : ∃ u ∈ 𝓝 x, ∃ v ∈ 𝓝 y, u ×ˢ v ⊆ {x_1 | x_1 ∈ Prod.fst ⁻¹' {(x, y).1} → x_1 ∈ Prod.snd ⁻¹' s}
⊢ s ∈ 𝓝 (x, y).2

Next tactic:
rcases hs with ⟨u, hu, v, hv, H⟩