l3lab/ntp-mathlib huggingface dataset:
theorem Filter.HasBasis.uniformEquicontinuous_iff {κ₁ κ₂ : Type*} {p₁ : κ₁ → Prop}
    {s₁ : κ₁ → Set (β × β)} {p₂ : κ₂ → Prop} {s₂ : κ₂ → Set (α × α)} {F : ι → β → α}
    (hβ : (𝓤 β).HasBasis p₁ s₁) (hα : (𝓤 α).HasBasis p₂ s₂) :
    UniformEquicontinuous F ↔
      ∀ k₂, p₂ k₂ → ∃ k₁, p₁ k₁ ∧ ∀ x y, (x, y) ∈ s₁ k₁ → ∀ i, (F i x, F i y) ∈ s₂ k₂ := by
  rw [uniformEquicontinuous_iff_uniformContinuous, UniformContinuous,
    hβ.tendsto_iff (UniformFun.hasBasis_uniformity_of_basis ι α hα)]
  simp only [Prod.forall, Function.comp_apply, mem_setOf_eq, exists_prop]
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
κ₁ : Type u_10
κ₂ : Type u_11
p₁ : κ₁ → Prop
s₁ : κ₁ → Set (β × β)
p₂ : κ₂ → Prop
s₂ : κ₂ → Set (α × α)
F : ι → β → α
hβ : HasBasis (𝓤 β) p₁ s₁
hα : HasBasis (𝓤 α) p₂ s₂
⊢ (∀ (ib : κ₂),
      p₂ ib →
        ∃ ia,
          p₁ ia ∧
            ∀ (a b : β),
              (a, b) ∈ s₁ ia →
                (UniformFun.ofFun (Function.swap F a), UniformFun.ofFun (Function.swap F b)) ∈
                  UniformFun.gen ι α (s₂ ib)) ↔
    ∀ (k₂ : κ₂), p₂ k₂ → ∃ k₁, p₁ k₁ ∧ ∀ (x y : β), (x, y) ∈ s₁ k₁ → ∀ (i : ι), (F i x, F i y) ∈ s₂ k₂

Next tactic:
rfl
/-- Given `u : α → β` a uniform inducing map, a family `𝓕 : ι → X → α` is equicontinuous at a point
`x₀ : X` iff the family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is
equicontinuous at `x₀`. -/
theorem UniformInducing.equicontinuousAt_iff {F : ι → X → α} {x₀ : X} {u : α → β}
    (hu : UniformInducing u) : EquicontinuousAt F x₀ ↔ EquicontinuousAt ((u ∘ ·) ∘ F) x₀ := by
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → X → α
x₀ : X
u : α → β
hu : UniformInducing u
⊢ EquicontinuousAt F x₀ ↔ EquicontinuousAt ((fun x => u ∘ x) ∘ F) x₀

Next tactic:
have := (UniformFun.postcomp_uniformInducing (α := ι) hu).inducing
/-- Given `u : α → β` a uniform inducing map, a family `𝓕 : ι → X → α` is equicontinuous at a point
`x₀ : X` iff the family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is
equicontinuous at `x₀`. -/
theorem UniformInducing.equicontinuousAt_iff {F : ι → X → α} {x₀ : X} {u : α → β}
    (hu : UniformInducing u) : EquicontinuousAt F x₀ ↔ EquicontinuousAt ((u ∘ ·) ∘ F) x₀ := by
  have := (UniformFun.postcomp_uniformInducing (α := ι) hu).inducing
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → X → α
x₀ : X
u : α → β
hu : UniformInducing u
this : Inducing (⇑UniformFun.ofFun ∘ (fun x => u ∘ x) ∘ ⇑toFun)
⊢ EquicontinuousAt F x₀ ↔ EquicontinuousAt ((fun x => u ∘ x) ∘ F) x₀

Next tactic:
rw [equicontinuousAt_iff_continuousAt, equicontinuousAt_iff_continuousAt, this.continuousAt_iff]
/-- Given `u : α → β` a uniform inducing map, a family `𝓕 : ι → X → α` is equicontinuous at a point
`x₀ : X` iff the family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is
equicontinuous at `x₀`. -/
theorem UniformInducing.equicontinuousAt_iff {F : ι → X → α} {x₀ : X} {u : α → β}
    (hu : UniformInducing u) : EquicontinuousAt F x₀ ↔ EquicontinuousAt ((u ∘ ·) ∘ F) x₀ := by
  have := (UniformFun.postcomp_uniformInducing (α := ι) hu).inducing
  rw [equicontinuousAt_iff_continuousAt, equicontinuousAt_iff_continuousAt, this.continuousAt_iff]
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → X → α
x₀ : X
u : α → β
hu : UniformInducing u
this : Inducing (⇑UniformFun.ofFun ∘ (fun x => u ∘ x) ∘ ⇑toFun)
⊢ ContinuousAt ((⇑UniformFun.ofFun ∘ (fun x => u ∘ x) ∘ ⇑toFun) ∘ ⇑UniformFun.ofFun ∘ Function.swap F) x₀ ↔
    ContinuousAt (⇑UniformFun.ofFun ∘ Function.swap ((fun x => u ∘ x) ∘ F)) x₀

Next tactic:
rfl
/-- Given `u : α → β` a uniform inducing map, a family `𝓕 : ι → X → α` is equicontinuous iff the
family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is equicontinuous. -/
theorem UniformInducing.equicontinuous_iff {F : ι → X → α} {u : α → β} (hu : UniformInducing u) :
    Equicontinuous F ↔ Equicontinuous ((u ∘ ·) ∘ F) := by
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → X → α
u : α → β
hu : UniformInducing u
⊢ Equicontinuous F ↔ Equicontinuous ((fun x => u ∘ x) ∘ F)

Next tactic:
congrm ∀ x, ?_
/-- Given `u : α → β` a uniform inducing map, a family `𝓕 : ι → X → α` is equicontinuous iff the
family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is equicontinuous. -/
theorem UniformInducing.equicontinuous_iff {F : ι → X → α} {u : α → β} (hu : UniformInducing u) :
    Equicontinuous F ↔ Equicontinuous ((u ∘ ·) ∘ F) := by
  congrm ∀ x, ?_
  

Proof state:
case a
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → X → α
u : α → β
hu : UniformInducing u
x : X
⊢ EquicontinuousAt F x ↔ EquicontinuousAt ((fun x => u ∘ x) ∘ F) x

Next tactic:
rw [hu.equicontinuousAt_iff]
/-- Given `u : α → γ` a uniform inducing map, a family `𝓕 : ι → β → α` is uniformly equicontinuous
iff the family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is uniformly
equicontinuous. -/
theorem UniformInducing.uniformEquicontinuous_iff {F : ι → β → α} {u : α → γ}
    (hu : UniformInducing u) : UniformEquicontinuous F ↔ UniformEquicontinuous ((u ∘ ·) ∘ F) := by
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → β → α
u : α → γ
hu : UniformInducing u
⊢ UniformEquicontinuous F ↔ UniformEquicontinuous ((fun x => u ∘ x) ∘ F)

Next tactic:
have := UniformFun.postcomp_uniformInducing (α := ι) hu
/-- Given `u : α → γ` a uniform inducing map, a family `𝓕 : ι → β → α` is uniformly equicontinuous
iff the family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is uniformly
equicontinuous. -/
theorem UniformInducing.uniformEquicontinuous_iff {F : ι → β → α} {u : α → γ}
    (hu : UniformInducing u) : UniformEquicontinuous F ↔ UniformEquicontinuous ((u ∘ ·) ∘ F) := by
  have := UniformFun.postcomp_uniformInducing (α := ι) hu
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → β → α
u : α → γ
hu : UniformInducing u
this : UniformInducing (⇑UniformFun.ofFun ∘ (fun x => u ∘ x) ∘ ⇑toFun)
⊢ UniformEquicontinuous F ↔ UniformEquicontinuous ((fun x => u ∘ x) ∘ F)

Next tactic:
rw [uniformEquicontinuous_iff_uniformContinuous, uniformEquicontinuous_iff_uniformContinuous,
    this.uniformContinuous_iff]
/-- Given `u : α → γ` a uniform inducing map, a family `𝓕 : ι → β → α` is uniformly equicontinuous
iff the family `𝓕'`, obtained by precomposing each function of `𝓕` by `u`, is uniformly
equicontinuous. -/
theorem UniformInducing.uniformEquicontinuous_iff {F : ι → β → α} {u : α → γ}
    (hu : UniformInducing u) : UniformEquicontinuous F ↔ UniformEquicontinuous ((u ∘ ·) ∘ F) := by
  have := UniformFun.postcomp_uniformInducing (α := ι) hu
  rw [uniformEquicontinuous_iff_uniformContinuous, uniformEquicontinuous_iff_uniformContinuous,
    this.uniformContinuous_iff]
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
F : ι → β → α
u : α → γ
hu : UniformInducing u
this : UniformInducing (⇑UniformFun.ofFun ∘ (fun x => u ∘ x) ∘ ⇑toFun)
⊢ UniformContinuous ((⇑UniformFun.ofFun ∘ (fun x => u ∘ x) ∘ ⇑toFun) ∘ ⇑UniformFun.ofFun ∘ Function.swap F) ↔
    UniformContinuous (⇑UniformFun.ofFun ∘ Function.swap ((fun x => u ∘ x) ∘ F))

Next tactic:
rfl
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
⊢ EquicontinuousAt (u ∘ Subtype.val) x₀

Next tactic:
intro U hU
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  intro U hU
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
⊢ ∀ᶠ (x : X) in 𝓝 x₀, ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i x₀, (u ∘ Subtype.val) i x) ∈ U

Next tactic:
rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  

Proof state:
case intro.intro.intro
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
⊢ ∀ᶠ (x : X) in 𝓝 x₀, ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i x₀, (u ∘ Subtype.val) i x) ∈ U

Next tactic:
filter_upwards [hA V hV] with x hx
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  filter_upwards [hA V hV] with x hx
  

Proof state:
case h
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
x : X
hx : ∀ (i : ↑A), ((u ∘ Subtype.val) i x₀, (u ∘ Subtype.val) i x) ∈ V
⊢ ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i x₀, (u ∘ Subtype.val) i x) ∈ U

Next tactic:
rw [SetCoe.forall] at *
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  filter_upwards [hA V hV] with x hx
  rw [SetCoe.forall] at *
  

Proof state:
case h
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
x : X
hx :
  ∀ (x_1 : Y) (h : x_1 ∈ A),
    ((u ∘ Subtype.val) { val := x_1, property := h } x₀, (u ∘ Subtype.val) { val := x_1, property := h } x) ∈ V
⊢ ∀ (x_1 : Y) (h : x_1 ∈ closure A),
    ((u ∘ Subtype.val) { val := x_1, property := h } x₀, (u ∘ Subtype.val) { val := x_1, property := h } x) ∈ U

Next tactic:
change A ⊆ (fun f => (u f x₀, u f x)) ⁻¹' V at hx
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  filter_upwards [hA V hV] with x hx
  rw [SetCoe.forall] at *
  change A ⊆ (fun f => (u f x₀, u f x)) ⁻¹' V at hx
  

Proof state:
case h
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
x : X
hx : A ⊆ (fun f => (u f x₀, u f x)) ⁻¹' V
⊢ ∀ (x_1 : Y) (h : x_1 ∈ closure A),
    ((u ∘ Subtype.val) { val := x_1, property := h } x₀, (u ∘ Subtype.val) { val := x_1, property := h } x) ∈ U

Next tactic:
refine' (closure_minimal hx <| hVclosed.preimage <| _).trans (preimage_mono hVU)
/-- A version of `EquicontinuousAt.closure` applicable to subsets of types which embed continuously
into `X → α` with the product topology. It turns out we don't need any other condition on the
embedding than continuity, but in practice this will mostly be applied to `FunLike` types where
the coercion is injective. -/
theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X}
    (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) :
    EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  filter_upwards [hA V hV] with x hx
  rw [SetCoe.forall] at *
  change A ⊆ (fun f => (u f x₀, u f x)) ⁻¹' V at hx
  refine' (closure_minimal hx <| hVclosed.preimage <| _).trans (preimage_mono hVU)
  

Proof state:
case h
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → X → α
x₀ : X
hA : EquicontinuousAt (u ∘ Subtype.val) x₀
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
x : X
hx : A ⊆ (fun f => (u f x₀, u f x)) ⁻¹' V
⊢ Continuous fun f => (u f x₀, u f x)

Next tactic:
exact Continuous.prod_mk ((continuous_apply x₀).comp hu) ((continuous_apply x).comp hu)
/-- A version of `UniformEquicontinuous.closure` applicable to subsets of types which embed
continuously into `β → α` with the product topology. It turns out we don't need any other condition
on the embedding than continuity, but in practice this will mostly be applied to `FunLike` types
where the coercion is injective. -/
theorem UniformEquicontinuous.closure' {A : Set Y} {u : Y → β → α}
    (hA : UniformEquicontinuous (u ∘ (↑) : A → β → α)) (hu : Continuous u) :
    UniformEquicontinuous (u ∘ (↑) : closure A → β → α) := by
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → β → α
hA : UniformEquicontinuous (u ∘ Subtype.val)
hu : Continuous u
⊢ UniformEquicontinuous (u ∘ Subtype.val)

Next tactic:
intro U hU
/-- A version of `UniformEquicontinuous.closure` applicable to subsets of types which embed
continuously into `β → α` with the product topology. It turns out we don't need any other condition
on the embedding than continuity, but in practice this will mostly be applied to `FunLike` types
where the coercion is injective. -/
theorem UniformEquicontinuous.closure' {A : Set Y} {u : Y → β → α}
    (hA : UniformEquicontinuous (u ∘ (↑) : A → β → α)) (hu : Continuous u) :
    UniformEquicontinuous (u ∘ (↑) : closure A → β → α) := by
  intro U hU
  

Proof state:
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → β → α
hA : UniformEquicontinuous (u ∘ Subtype.val)
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
⊢ ∀ᶠ (xy : β × β) in 𝓤 β, ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i xy.1, (u ∘ Subtype.val) i xy.2) ∈ U

Next tactic:
rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
/-- A version of `UniformEquicontinuous.closure` applicable to subsets of types which embed
continuously into `β → α` with the product topology. It turns out we don't need any other condition
on the embedding than continuity, but in practice this will mostly be applied to `FunLike` types
where the coercion is injective. -/
theorem UniformEquicontinuous.closure' {A : Set Y} {u : Y → β → α}
    (hA : UniformEquicontinuous (u ∘ (↑) : A → β → α)) (hu : Continuous u) :
    UniformEquicontinuous (u ∘ (↑) : closure A → β → α) := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  

Proof state:
case intro.intro.intro
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → β → α
hA : UniformEquicontinuous (u ∘ Subtype.val)
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
⊢ ∀ᶠ (xy : β × β) in 𝓤 β, ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i xy.1, (u ∘ Subtype.val) i xy.2) ∈ U

Next tactic:
filter_upwards [hA V hV]
/-- A version of `UniformEquicontinuous.closure` applicable to subsets of types which embed
continuously into `β → α` with the product topology. It turns out we don't need any other condition
on the embedding than continuity, but in practice this will mostly be applied to `FunLike` types
where the coercion is injective. -/
theorem UniformEquicontinuous.closure' {A : Set Y} {u : Y → β → α}
    (hA : UniformEquicontinuous (u ∘ (↑) : A → β → α)) (hu : Continuous u) :
    UniformEquicontinuous (u ∘ (↑) : closure A → β → α) := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  filter_upwards [hA V hV]
  

Proof state:
case h
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → β → α
hA : UniformEquicontinuous (u ∘ Subtype.val)
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
⊢ ∀ (a : β × β),
    (∀ (i : ↑A), ((u ∘ Subtype.val) i a.1, (u ∘ Subtype.val) i a.2) ∈ V) →
      ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i a.1, (u ∘ Subtype.val) i a.2) ∈ U

Next tactic:
rintro ⟨x, y⟩ hxy
/-- A version of `UniformEquicontinuous.closure` applicable to subsets of types which embed
continuously into `β → α` with the product topology. It turns out we don't need any other condition
on the embedding than continuity, but in practice this will mostly be applied to `FunLike` types
where the coercion is injective. -/
theorem UniformEquicontinuous.closure' {A : Set Y} {u : Y → β → α}
    (hA : UniformEquicontinuous (u ∘ (↑) : A → β → α)) (hu : Continuous u) :
    UniformEquicontinuous (u ∘ (↑) : closure A → β → α) := by
  intro U hU
  rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩
  filter_upwards [hA V hV]
  rintro ⟨x, y⟩ hxy
  

Proof state:
case h.mk
ι : Type u_1
κ : Type u_2
X : Type u_3
Y : Type u_4
Z : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
𝓕 : Type u_9
inst✝⁵ : TopologicalSpace X
inst✝⁴ : TopologicalSpace Y
inst✝³ : TopologicalSpace Z
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : UniformSpace γ
A : Set Y
u : Y → β → α
hA : UniformEquicontinuous (u ∘ Subtype.val)
hu : Continuous u
U : Set (α × α)
hU : U ∈ 𝓤 α
V : Set (α × α)
hV : V ∈ 𝓤 α
hVclosed : IsClosed V
hVU : V ⊆ U
x y : β
hxy : ∀ (i : ↑A), ((u ∘ Subtype.val) i (x, y).1, (u ∘ Subtype.val) i (x, y).2) ∈ V
⊢ ∀ (i : ↑(closure A)), ((u ∘ Subtype.val) i (x, y).1, (u ∘ Subtype.val) i (x, y).2) ∈ U

Next tactic:
rw [SetCoe.forall] at *