l3lab/ntp-mathlib huggingface dataset:
/-- the universal property for the image factorisation -/
noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I where
  toFun := (fun x => F'.e (Classical.indefiniteDescription _ x.2).1 : image f → F'.I)
  map_zero' := by
    haveI := F'.m_mono
    apply injective_of_mono F'.m
    change (F'.e ≫ F'.m) _ = _
    rw [F'.fac, AddMonoidHom.map_zero]
    exact (Classical.indefiniteDescription (fun y => f y = 0) _).2
  map_add' := by
    intro x y
    haveI := F'.m_mono
    apply injective_of_mono F'.m
    rw [AddMonoidHom.map_add]
    change (F'.e ≫ F'.m) _ = (F'.e ≫ F'.m) _ + (F'.e ≫ F'.m) _
    rw [F'.fac]
    rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
    

Proof state:
case a
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
x y : ↑(image f)
this : Mono F'.m
⊢ ↑(x + y) =
    f ↑(Classical.indefiniteDescription (fun x_1 => f x_1 = ↑x) (_ : ↑x ∈ AddMonoidHom.range f)) +
      f ↑(Classical.indefiniteDescription (fun x => f x = ↑y) (_ : ↑y ∈ AddMonoidHom.range f))

Next tactic:
rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
/-- the universal property for the image factorisation -/
noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I where
  toFun := (fun x => F'.e (Classical.indefiniteDescription _ x.2).1 : image f → F'.I)
  map_zero' := by
    haveI := F'.m_mono
    apply injective_of_mono F'.m
    change (F'.e ≫ F'.m) _ = _
    rw [F'.fac, AddMonoidHom.map_zero]
    exact (Classical.indefiniteDescription (fun y => f y = 0) _).2
  map_add' := by
    intro x y
    haveI := F'.m_mono
    apply injective_of_mono F'.m
    rw [AddMonoidHom.map_add]
    change (F'.e ≫ F'.m) _ = (F'.e ≫ F'.m) _ + (F'.e ≫ F'.m) _
    rw [F'.fac]
    rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
    rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
    

Proof state:
case a
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
x y : ↑(image f)
this : Mono F'.m
⊢ ↑(x + y) = ↑x + f ↑(Classical.indefiniteDescription (fun x => f x = ↑y) (_ : ↑y ∈ AddMonoidHom.range f))

Next tactic:
rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
/-- the universal property for the image factorisation -/
noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I where
  toFun := (fun x => F'.e (Classical.indefiniteDescription _ x.2).1 : image f → F'.I)
  map_zero' := by
    haveI := F'.m_mono
    apply injective_of_mono F'.m
    change (F'.e ≫ F'.m) _ = _
    rw [F'.fac, AddMonoidHom.map_zero]
    exact (Classical.indefiniteDescription (fun y => f y = 0) _).2
  map_add' := by
    intro x y
    haveI := F'.m_mono
    apply injective_of_mono F'.m
    rw [AddMonoidHom.map_add]
    change (F'.e ≫ F'.m) _ = (F'.e ≫ F'.m) _ + (F'.e ≫ F'.m) _
    rw [F'.fac]
    rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
    rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
    rw [(Classical.indefiniteDescription (fun z => f z = _) _).2]
    

Proof state:
case a
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
x y : ↑(image f)
this : Mono F'.m
⊢ ↑(x + y) = ↑x + ↑y

Next tactic:
rfl
theorem image.lift_fac (F' : MonoFactorisation f) : image.lift F' ≫ F'.m = image.ι f := by
  

Proof state:
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
⊢ lift F' ≫ F'.m = ι f

Next tactic:
ext x
theorem image.lift_fac (F' : MonoFactorisation f) : image.lift F' ≫ F'.m = image.ι f := by
  ext x
  

Proof state:
case w
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
x : ↑(image f)
⊢ (lift F' ≫ F'.m) x = (ι f) x

Next tactic:
change (F'.e ≫ F'.m) _ = _
theorem image.lift_fac (F' : MonoFactorisation f) : image.lift F' ≫ F'.m = image.ι f := by
  ext x
  change (F'.e ≫ F'.m) _ = _
  

Proof state:
case w
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
x : ↑(image f)
⊢ (F'.e ≫ F'.m) ↑(Classical.indefiniteDescription (fun x_1 => f x_1 = ↑x) (_ : ↑x ∈ AddMonoidHom.range f)) = (ι f) x

Next tactic:
rw [F'.fac, (Classical.indefiniteDescription _ x.2).2]
theorem image.lift_fac (F' : MonoFactorisation f) : image.lift F' ≫ F'.m = image.ι f := by
  ext x
  change (F'.e ≫ F'.m) _ = _
  rw [F'.fac, (Classical.indefiniteDescription _ x.2).2]
  

Proof state:
case w
G H : AddCommGroupCat
f : G ⟶ H
F' : MonoFactorisation f
x : ↑(image f)
⊢ ↑x = (ι f) x

Next tactic:
rfl
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  

Proof state:
⊢ Subalgebra.topologicalClosure (polynomialFunctions I) = ⊤

Next tactic:
apply eq_top_iff.mpr
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  

Proof state:
⊢ ⊤ ≤ Subalgebra.topologicalClosure (polynomialFunctions I)

Next tactic:
rintro f -
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  

Proof state:
f : C(↑I, ℝ)
⊢ f ∈ Subalgebra.topologicalClosure (polynomialFunctions I)

Next tactic:
refine' Filter.Frequently.mem_closure _
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  

Proof state:
f : C(↑I, ℝ)
⊢ ∃ᶠ (x : C(↑I, ℝ)) in nhds f, x ∈ ↑(polynomialFunctions I)

Next tactic:
refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  

Proof state:
f : C(↑I, ℝ)
⊢ ∃ᶠ (x : ℕ) in atTop, bernsteinApproximation x f ∈ ↑(polynomialFunctions I)

Next tactic:
apply frequently_of_forall
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  

Proof state:
case h
f : C(↑I, ℝ)
⊢ ∀ (x : ℕ), bernsteinApproximation x f ∈ ↑(polynomialFunctions I)

Next tactic:
intro n
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  intro n
  

Proof state:
case h
f : C(↑I, ℝ)
n : ℕ
⊢ bernsteinApproximation n f ∈ ↑(polynomialFunctions I)

Next tactic:
simp only [SetLike.mem_coe]
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  intro n
  simp only [SetLike.mem_coe]
  

Proof state:
case h
f : C(↑I, ℝ)
n : ℕ
⊢ bernsteinApproximation n f ∈ polynomialFunctions I

Next tactic:
apply Subalgebra.sum_mem
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  intro n
  simp only [SetLike.mem_coe]
  apply Subalgebra.sum_mem
  

Proof state:
case h.h
f : C(↑I, ℝ)
n : ℕ
⊢ ∀ x ∈ Finset.univ, f (bernstein.z x) • bernstein n ↑x ∈ polynomialFunctions I

Next tactic:
rintro n -
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  intro n
  simp only [SetLike.mem_coe]
  apply Subalgebra.sum_mem
  rintro n -
  

Proof state:
case h.h
f : C(↑I, ℝ)
n✝ : ℕ
n : Fin (n✝ + 1)
⊢ f (bernstein.z n) • bernstein n✝ ↑n ∈ polynomialFunctions I

Next tactic:
apply Subalgebra.smul_mem
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  intro n
  simp only [SetLike.mem_coe]
  apply Subalgebra.sum_mem
  rintro n -
  apply Subalgebra.smul_mem
  

Proof state:
case h.h.hx
f : C(↑I, ℝ)
n✝ : ℕ
n : Fin (n✝ + 1)
⊢ bernstein n✝ ↑n ∈ polynomialFunctions I

Next tactic:
dsimp [bernstein, polynomialFunctions]
/-- The special case of the Weierstrass approximation theorem for the interval `[0,1]`.
This is just a matter of unravelling definitions and using the Bernstein approximations.
-/
theorem polynomialFunctions_closure_eq_top' : (polynomialFunctions I).topologicalClosure = ⊤ := by
  apply eq_top_iff.mpr
  rintro f -
  refine' Filter.Frequently.mem_closure _
  refine' Filter.Tendsto.frequently (bernsteinApproximation_uniform f) _
  apply frequently_of_forall
  intro n
  simp only [SetLike.mem_coe]
  apply Subalgebra.sum_mem
  rintro n -
  apply Subalgebra.smul_mem
  dsimp [bernstein, polynomialFunctions]
  

Proof state:
case h.h.hx
f : C(↑I, ℝ)
n✝ : ℕ
n : Fin (n✝ + 1)
⊢ Polynomial.toContinuousMapOn (bernsteinPolynomial ℝ n✝ ↑n) I ∈ Subalgebra.map (Polynomial.toContinuousMapOnAlgHom I) ⊤

Next tactic:
simp
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  

Proof state:
a b : ℝ
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
cases' lt_or_le a b with h h
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    

Proof state:
case inl
a b : ℝ
h : a < b
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
    -- This operation is itself a homeomorphism
    -- (with respect to the norm topologies on continuous functions).
    

Proof state:
case inl
a b : ℝ
h : a < b
W : C(↑(Set.Icc a b), ℝ) →ₐ[ℝ] C(↑I, ℝ) :=
  compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h)))
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
    -- This operation is itself a homeomorphism
    -- (with respect to the norm topologies on continuous functions).
    let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm
    

Proof state:
case inl
a b : ℝ
h : a < b
W : C(↑(Set.Icc a b), ℝ) →ₐ[ℝ] C(↑I, ℝ) :=
  compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h)))
W' : C(↑(Set.Icc a b), ℝ) ≃ₜ C(↑I, ℝ) := compRightHomeomorph ℝ (Homeomorph.symm (iccHomeoI a b h))
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
have w : (W : C(Set.Icc a b, ℝ) → C(I, ℝ)) = W' := rfl
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
    -- This operation is itself a homeomorphism
    -- (with respect to the norm topologies on continuous functions).
    let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm
    have w : (W : C(Set.Icc a b, ℝ) → C(I, ℝ)) = W' := rfl
    -- Thus we take the statement of the Weierstrass approximation theorem for `[0,1]`,
    

Proof state:
case inl
a b : ℝ
h : a < b
W : C(↑(Set.Icc a b), ℝ) →ₐ[ℝ] C(↑I, ℝ) :=
  compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h)))
W' : C(↑(Set.Icc a b), ℝ) ≃ₜ C(↑I, ℝ) := compRightHomeomorph ℝ (Homeomorph.symm (iccHomeoI a b h))
w : ⇑W = ⇑W'
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
have p := polynomialFunctions_closure_eq_top'
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
    -- This operation is itself a homeomorphism
    -- (with respect to the norm topologies on continuous functions).
    let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm
    have w : (W : C(Set.Icc a b, ℝ) → C(I, ℝ)) = W' := rfl
    -- Thus we take the statement of the Weierstrass approximation theorem for `[0,1]`,
    have p := polynomialFunctions_closure_eq_top'
    -- and pullback both sides, obtaining an equation between subalgebras of `C([a,b], ℝ)`.
    

Proof state:
case inl
a b : ℝ
h : a < b
W : C(↑(Set.Icc a b), ℝ) →ₐ[ℝ] C(↑I, ℝ) :=
  compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h)))
W' : C(↑(Set.Icc a b), ℝ) ≃ₜ C(↑I, ℝ) := compRightHomeomorph ℝ (Homeomorph.symm (iccHomeoI a b h))
w : ⇑W = ⇑W'
p : Subalgebra.topologicalClosure (polynomialFunctions I) = ⊤
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
apply_fun fun s => s.comap W at p
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
    -- This operation is itself a homeomorphism
    -- (with respect to the norm topologies on continuous functions).
    let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm
    have w : (W : C(Set.Icc a b, ℝ) → C(I, ℝ)) = W' := rfl
    -- Thus we take the statement of the Weierstrass approximation theorem for `[0,1]`,
    have p := polynomialFunctions_closure_eq_top'
    -- and pullback both sides, obtaining an equation between subalgebras of `C([a,b], ℝ)`.
    apply_fun fun s => s.comap W at p
    

Proof state:
case inl
a b : ℝ
h : a < b
W : C(↑(Set.Icc a b), ℝ) →ₐ[ℝ] C(↑I, ℝ) :=
  compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h)))
W' : C(↑(Set.Icc a b), ℝ) ≃ₜ C(↑I, ℝ) := compRightHomeomorph ℝ (Homeomorph.symm (iccHomeoI a b h))
w : ⇑W = ⇑W'
p : Subalgebra.comap W (Subalgebra.topologicalClosure (polynomialFunctions I)) = Subalgebra.comap W ⊤
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
simp only [Algebra.comap_top] at p
/-- The **Weierstrass Approximation Theorem**:
polynomials functions on `[a, b] ⊆ ℝ` are dense in `C([a,b],ℝ)`

(While we could deduce this as an application of the Stone-Weierstrass theorem,
our proof of that relies on the fact that `abs` is in the closure of polynomials on `[-M, M]`,
so we may as well get this done first.)
-/
theorem polynomialFunctions_closure_eq_top (a b : ℝ) :
    (polynomialFunctions (Set.Icc a b)).topologicalClosure = ⊤ := by
  cases' lt_or_le a b with h h
  -- (Otherwise it's easy; we'll deal with that later.)
  · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`,
    -- by precomposing with an affine map.
    let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) :=
      compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap
    -- This operation is itself a homeomorphism
    -- (with respect to the norm topologies on continuous functions).
    let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm
    have w : (W : C(Set.Icc a b, ℝ) → C(I, ℝ)) = W' := rfl
    -- Thus we take the statement of the Weierstrass approximation theorem for `[0,1]`,
    have p := polynomialFunctions_closure_eq_top'
    -- and pullback both sides, obtaining an equation between subalgebras of `C([a,b], ℝ)`.
    apply_fun fun s => s.comap W at p
    simp only [Algebra.comap_top] at p
    -- Since the pullback operation is continuous, it commutes with taking `topologicalClosure`,
    

Proof state:
case inl
a b : ℝ
h : a < b
W : C(↑(Set.Icc a b), ℝ) →ₐ[ℝ] C(↑I, ℝ) :=
  compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h)))
W' : C(↑(Set.Icc a b), ℝ) ≃ₜ C(↑I, ℝ) := compRightHomeomorph ℝ (Homeomorph.symm (iccHomeoI a b h))
w : ⇑W = ⇑W'
p :
  Subalgebra.comap (compRightAlgHom ℝ ℝ (Homeomorph.toContinuousMap (Homeomorph.symm (iccHomeoI a b h))))
      (Subalgebra.topologicalClosure (polynomialFunctions I)) =
    ⊤
⊢ Subalgebra.topologicalClosure (polynomialFunctions (Set.Icc a b)) = ⊤

Next tactic:
rw [Subalgebra.topologicalClosure_comap_homeomorph _ W W' w] at p