l3lab/ntp-mathlib huggingface dataset:
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : CompHaus.{u}}
    (X : α → CompHaus.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    obtain ⟨t, rfl⟩ := e b
    let q := i.hom t
    refine ⟨q.1,q.2,?_⟩
    have : t = i.inv (i.hom t) := show t = (i.hom ≫ i.inv) t by simp only [i.hom_inv_id]; rfl
    rw [this]
    show _ = (i.inv ≫ Sigma.desc π) (i.hom t)
    suffices i.inv ≫ Sigma.desc π = finiteCoproduct.desc X π by
      rw [this]; rfl
    rw [Iso.inv_comp_eq]
    apply colimit.hom_ext
    rintro ⟨a⟩
    

Proof state:
case tfae_2_to_3.intro.w.mk
α : Type
inst✝ : Fintype α
B : CompHaus
X : α → CompHaus
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
t : (forget CompHaus).obj (∐ fun b => X b)
q : (forget CompHaus).obj (finiteCoproduct X) := i.hom t
this : t = i.inv (i.hom t)
a : α
⊢ colimit.ι (Discrete.functor X) { as := a } ≫ Sigma.desc π =
    colimit.ι (Discrete.functor X) { as := a } ≫ i.hom ≫ finiteCoproduct.desc X π

Next tactic:
simp only [Discrete.functor_obj, colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app,
      colimit.comp_coconePointUniqueUpToIso_hom_assoc]
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : CompHaus.{u}}
    (X : α → CompHaus.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    obtain ⟨t, rfl⟩ := e b
    let q := i.hom t
    refine ⟨q.1,q.2,?_⟩
    have : t = i.inv (i.hom t) := show t = (i.hom ≫ i.inv) t by simp only [i.hom_inv_id]; rfl
    rw [this]
    show _ = (i.inv ≫ Sigma.desc π) (i.hom t)
    suffices i.inv ≫ Sigma.desc π = finiteCoproduct.desc X π by
      rw [this]; rfl
    rw [Iso.inv_comp_eq]
    apply colimit.hom_ext
    rintro ⟨a⟩
    simp only [Discrete.functor_obj, colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app,
      colimit.comp_coconePointUniqueUpToIso_hom_assoc]
    

Proof state:
case tfae_2_to_3.intro.w.mk
α : Type
inst✝ : Fintype α
B : CompHaus
X : α → CompHaus
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
t : (forget CompHaus).obj (∐ fun b => X b)
q : (forget CompHaus).obj (finiteCoproduct X) := i.hom t
this : t = i.inv (i.hom t)
a : α
⊢ π a = (finiteCoproduct.cocone X).ι.app { as := a } ≫ finiteCoproduct.desc X π

Next tactic:
ext
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : CompHaus.{u}}
    (X : α → CompHaus.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    obtain ⟨t, rfl⟩ := e b
    let q := i.hom t
    refine ⟨q.1,q.2,?_⟩
    have : t = i.inv (i.hom t) := show t = (i.hom ≫ i.inv) t by simp only [i.hom_inv_id]; rfl
    rw [this]
    show _ = (i.inv ≫ Sigma.desc π) (i.hom t)
    suffices i.inv ≫ Sigma.desc π = finiteCoproduct.desc X π by
      rw [this]; rfl
    rw [Iso.inv_comp_eq]
    apply colimit.hom_ext
    rintro ⟨a⟩
    simp only [Discrete.functor_obj, colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app,
      colimit.comp_coconePointUniqueUpToIso_hom_assoc]
    ext; 

Proof state:
case tfae_2_to_3.intro.w.mk.w
α : Type
inst✝ : Fintype α
B : CompHaus
X : α → CompHaus
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
e : Function.Surjective ⇑(Sigma.desc π)
i : ∐ X ≅ finiteCoproduct X :=
  IsColimit.coconePointUniqueUpToIso (colimit.isColimit (Discrete.functor X)) (finiteCoproduct.isColimit X)
t : (forget CompHaus).obj (∐ fun b => X b)
q : (forget CompHaus).obj (finiteCoproduct X) := i.hom t
this : t = i.inv (i.hom t)
a : α
x✝ : (forget CompHaus).obj (X a)
⊢ (π a) x✝ = ((finiteCoproduct.cocone X).ι.app { as := a } ≫ finiteCoproduct.desc X π) x✝

Next tactic:
rfl
open List in
theorem effectiveEpiFamily_tfae
    {α : Type} [Fintype α] {B : CompHaus.{u}}
    (X : α → CompHaus.{u}) (π : (a : α) → (X a ⟶ B)) :
    TFAE
    [ EffectiveEpiFamily X π
    , Epi (Sigma.desc π)
    , ∀ b : B, ∃ (a : α) (x : X a), π a x = b
    ] := by
  tfae_have 2 → 1
  · intro
    simpa [← effectiveEpi_desc_iff_effectiveEpiFamily, (effectiveEpi_tfae (Sigma.desc π)).out 0 1]
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 3 → 2
  · intro e
    rw [epi_iff_surjective]
    intro b
    obtain ⟨t, x, h⟩ := e b
    refine ⟨Sigma.ι X t x, ?_⟩
    change (Sigma.ι X t ≫ Sigma.desc π) x = _
    simpa using h
  tfae_have 2 → 3
  · intro e; rw [epi_iff_surjective] at e
    let i : ∐ X ≅ finiteCoproduct X :=
      (colimit.isColimit _).coconePointUniqueUpToIso (finiteCoproduct.isColimit _)
    intro b
    obtain ⟨t, rfl⟩ := e b
    let q := i.hom t
    refine ⟨q.1,q.2,?_⟩
    have : t = i.inv (i.hom t) := show t = (i.hom ≫ i.inv) t by simp only [i.hom_inv_id]; rfl
    rw [this]
    show _ = (i.inv ≫ Sigma.desc π) (i.hom t)
    suffices i.inv ≫ Sigma.desc π = finiteCoproduct.desc X π by
      rw [this]; rfl
    rw [Iso.inv_comp_eq]
    apply colimit.hom_ext
    rintro ⟨a⟩
    simp only [Discrete.functor_obj, colimit.ι_desc, Cofan.mk_pt, Cofan.mk_ι_app,
      colimit.comp_coconePointUniqueUpToIso_hom_assoc]
    ext; rfl
  

Proof state:
α : Type
inst✝ : Fintype α
B : CompHaus
X : α → CompHaus
π : (a : α) → X a ⟶ B
tfae_2_to_1 : Epi (Sigma.desc π) → EffectiveEpiFamily X π
tfae_1_to_2 : EffectiveEpiFamily X π → Epi (Sigma.desc π)
tfae_3_to_2 : (∀ (b : ↑B.toTop), ∃ a x, (π a) x = b) → Epi (Sigma.desc π)
tfae_2_to_3 : Epi (Sigma.desc π) → ∀ (b : ↑B.toTop), ∃ a x, (π a) x = b
⊢ TFAE [EffectiveEpiFamily X π, Epi (Sigma.desc π), ∀ (b : ↑B.toTop), ∃ a x, (π a) x = b]

Next tactic:
tfae_finish
@[simp]
theorem bernstein_apply (n ν : ℕ) (x : I) :
    bernstein n ν x = (n.choose ν : ℝ) * (x : ℝ) ^ ν * (1 - (x : ℝ)) ^ (n - ν) := by
  

Proof state:
n ν : ℕ
x : ↑I
⊢ (bernstein n ν) x = ↑(Nat.choose n ν) * ↑x ^ ν * (1 - ↑x) ^ (n - ν)

Next tactic:
dsimp [bernstein, Polynomial.toContinuousMapOn, Polynomial.toContinuousMap, bernsteinPolynomial]
@[simp]
theorem bernstein_apply (n ν : ℕ) (x : I) :
    bernstein n ν x = (n.choose ν : ℝ) * (x : ℝ) ^ ν * (1 - (x : ℝ)) ^ (n - ν) := by
  dsimp [bernstein, Polynomial.toContinuousMapOn, Polynomial.toContinuousMap, bernsteinPolynomial]
  

Proof state:
n ν : ℕ
x : ↑I
⊢ Polynomial.eval (↑x) (↑(Nat.choose n ν) * Polynomial.X ^ ν * (1 - Polynomial.X) ^ (n - ν)) =
    ↑(Nat.choose n ν) * ↑x ^ ν * (1 - ↑x) ^ (n - ν)

Next tactic:
simp
theorem bernstein_nonneg {n ν : ℕ} {x : I} : 0 ≤ bernstein n ν x := by
  

Proof state:
n ν : ℕ
x : ↑I
⊢ 0 ≤ (bernstein n ν) x

Next tactic:
simp only [bernstein_apply]
theorem bernstein_nonneg {n ν : ℕ} {x : I} : 0 ≤ bernstein n ν x := by
  simp only [bernstein_apply]
  

Proof state:
n ν : ℕ
x : ↑I
⊢ 0 ≤ ↑(Nat.choose n ν) * ↑x ^ ν * (1 - ↑x) ^ (n - ν)

Next tactic:
have h₁ : (0:ℝ) ≤ x := by unit_interval
theorem bernstein_nonneg {n ν : ℕ} {x : I} : 0 ≤ bernstein n ν x := by
  simp only [bernstein_apply]
  have h₁ : (0:ℝ) ≤ x := by 

Proof state:
n ν : ℕ
x : ↑I
⊢ 0 ≤ ↑x

Next tactic:
unit_interval
theorem bernstein_nonneg {n ν : ℕ} {x : I} : 0 ≤ bernstein n ν x := by
  simp only [bernstein_apply]
  have h₁ : (0:ℝ) ≤ x := by unit_interval
  

Proof state:
n ν : ℕ
x : ↑I
h₁ : 0 ≤ ↑x
⊢ 0 ≤ ↑(Nat.choose n ν) * ↑x ^ ν * (1 - ↑x) ^ (n - ν)

Next tactic:
have h₂ : (0:ℝ) ≤ 1 - x := by unit_interval
theorem bernstein_nonneg {n ν : ℕ} {x : I} : 0 ≤ bernstein n ν x := by
  simp only [bernstein_apply]
  have h₁ : (0:ℝ) ≤ x := by unit_interval
  have h₂ : (0:ℝ) ≤ 1 - x := by 

Proof state:
n ν : ℕ
x : ↑I
h₁ : 0 ≤ ↑x
⊢ 0 ≤ 1 - ↑x

Next tactic:
unit_interval
theorem bernstein_nonneg {n ν : ℕ} {x : I} : 0 ≤ bernstein n ν x := by
  simp only [bernstein_apply]
  have h₁ : (0:ℝ) ≤ x := by unit_interval
  have h₂ : (0:ℝ) ≤ 1 - x := by unit_interval
  

Proof state:
n ν : ℕ
x : ↑I
h₁ : 0 ≤ ↑x
h₂ : 0 ≤ 1 - ↑x
⊢ 0 ≤ ↑(Nat.choose n ν) * ↑x ^ ν * (1 - ↑x) ^ (n - ν)

Next tactic:
positivity
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    

Proof state:
n : ℕ
k : Fin (n + 1)
⊢ ↑↑k / ↑n ∈ I

Next tactic:
cases' n with n
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    cases' n with n
    · 

Proof state:
case zero
k : Fin (Nat.zero + 1)
⊢ ↑↑k / ↑Nat.zero ∈ I

Next tactic:
norm_num
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    cases' n with n
    · norm_num
    · 

Proof state:
case succ
n : ℕ
k : Fin (Nat.succ n + 1)
⊢ ↑↑k / ↑(Nat.succ n) ∈ I

Next tactic:
have h₁ : 0 < (n.succ : ℝ) := mod_cast Nat.succ_pos _
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    cases' n with n
    · norm_num
    · have h₁ : 0 < (n.succ : ℝ) := mod_cast Nat.succ_pos _
      

Proof state:
case succ
n : ℕ
k : Fin (Nat.succ n + 1)
h₁ : 0 < ↑(Nat.succ n)
⊢ ↑↑k / ↑(Nat.succ n) ∈ I

Next tactic:
have h₂ : ↑k ≤ n.succ := mod_cast Fin.le_last k
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    cases' n with n
    · norm_num
    · have h₁ : 0 < (n.succ : ℝ) := mod_cast Nat.succ_pos _
      have h₂ : ↑k ≤ n.succ := mod_cast Fin.le_last k
      

Proof state:
case succ
n : ℕ
k : Fin (Nat.succ n + 1)
h₁ : 0 < ↑(Nat.succ n)
h₂ : ↑k ≤ Nat.succ n
⊢ ↑↑k / ↑(Nat.succ n) ∈ I

Next tactic:
rw [Set.mem_Icc, le_div_iff h₁, div_le_iff h₁]
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    cases' n with n
    · norm_num
    · have h₁ : 0 < (n.succ : ℝ) := mod_cast Nat.succ_pos _
      have h₂ : ↑k ≤ n.succ := mod_cast Fin.le_last k
      rw [Set.mem_Icc, le_div_iff h₁, div_le_iff h₁]
      

Proof state:
case succ
n : ℕ
k : Fin (Nat.succ n + 1)
h₁ : 0 < ↑(Nat.succ n)
h₂ : ↑k ≤ Nat.succ n
⊢ 0 * ↑(Nat.succ n) ≤ ↑↑k ∧ ↑↑k ≤ 1 * ↑(Nat.succ n)

Next tactic:
norm_cast
/-- Send `k : Fin (n+1)` to the equally spaced points `k/n` in the unit interval.
-/
def z {n : ℕ} (k : Fin (n + 1)) : I :=
  ⟨(k : ℝ) / n, by
    cases' n with n
    · norm_num
    · have h₁ : 0 < (n.succ : ℝ) := mod_cast Nat.succ_pos _
      have h₂ : ↑k ≤ n.succ := mod_cast Fin.le_last k
      rw [Set.mem_Icc, le_div_iff h₁, div_le_iff h₁]
      norm_cast
      

Proof state:
case succ
n : ℕ
k : Fin (Nat.succ n + 1)
h₁ : 0 < ↑(Nat.succ n)
h₂ : ↑k ≤ Nat.succ n
⊢ 0 * Nat.succ n ≤ ↑k ∧ ↑k ≤ 1 * Nat.succ n

Next tactic:
simp [h₂]
theorem probability (n : ℕ) (x : I) : (∑ k : Fin (n + 1), bernstein n k x) = 1 := by
  

Proof state:
n : ℕ
x : ↑I
⊢ ∑ k : Fin (n + 1), (bernstein n ↑k) x = 1

Next tactic:
have := bernsteinPolynomial.sum ℝ n
theorem probability (n : ℕ) (x : I) : (∑ k : Fin (n + 1), bernstein n k x) = 1 := by
  have := bernsteinPolynomial.sum ℝ n
  

Proof state:
n : ℕ
x : ↑I
this : ∑ ν in Finset.range (n + 1), bernsteinPolynomial ℝ n ν = 1
⊢ ∑ k : Fin (n + 1), (bernstein n ↑k) x = 1

Next tactic:
apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
theorem probability (n : ℕ) (x : I) : (∑ k : Fin (n + 1), bernstein n k x) = 1 := by
  have := bernsteinPolynomial.sum ℝ n
  apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
  

Proof state:
n : ℕ
x : ↑I
this : (Polynomial.aeval ↑x) (∑ ν in Finset.range (n + 1), bernsteinPolynomial ℝ n ν) = (Polynomial.aeval ↑x) 1
⊢ ∑ k : Fin (n + 1), (bernstein n ↑k) x = 1

Next tactic:
simp? [AlgHom.map_sum, Finset.sum_range] at this says
    simp only [Finset.sum_range, map_sum, Polynomial.coe_aeval_eq_eval, map_one] at this
theorem probability (n : ℕ) (x : I) : (∑ k : Fin (n + 1), bernstein n k x) = 1 := by
  have := bernsteinPolynomial.sum ℝ n
  apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
  simp? [AlgHom.map_sum, Finset.sum_range] at this says
    

Proof state:
n : ℕ
x : ↑I
this : (Polynomial.aeval ↑x) (∑ ν in Finset.range (n + 1), bernsteinPolynomial ℝ n ν) = (Polynomial.aeval ↑x) 1
⊢ ∑ k : Fin (n + 1), (bernstein n ↑k) x = 1

Next tactic:
simp only [Finset.sum_range, map_sum, Polynomial.coe_aeval_eq_eval, map_one] at this
theorem probability (n : ℕ) (x : I) : (∑ k : Fin (n + 1), bernstein n k x) = 1 := by
  have := bernsteinPolynomial.sum ℝ n
  apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
  simp? [AlgHom.map_sum, Finset.sum_range] at this says
    simp only [Finset.sum_range, map_sum, Polynomial.coe_aeval_eq_eval, map_one] at this
  

Proof state:
n : ℕ
x : ↑I
this : ∑ x_1 : Fin (n + 1), Polynomial.eval (↑x) (bernsteinPolynomial ℝ n ↑x_1) = 1
⊢ ∑ k : Fin (n + 1), (bernstein n ↑k) x = 1

Next tactic:
exact this
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
⊢ ∑ k : Fin (n + 1), (↑x - ↑(k/ₙ)) ^ 2 * (bernstein n ↑k) x = ↑x * (1 - ↑x) / ↑n

Next tactic:
have h' : (n : ℝ) ≠ 0 := ne_of_gt h
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
⊢ ∑ k : Fin (n + 1), (↑x - ↑(k/ₙ)) ^ 2 * (bernstein n ↑k) x = ↑x * (1 - ↑x) / ↑n

Next tactic:
apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
⊢ (fun x => x * ↑n) (∑ k : Fin (n + 1), (↑x - ↑(k/ₙ)) ^ 2 * (bernstein n ↑k) x) = (fun x => x * ↑n) (↑x * (1 - ↑x) / ↑n)

Next tactic:
apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
⊢ (fun x => x * ↑n) ((fun x => x * ↑n) (∑ k : Fin (n + 1), (↑x - ↑(k/ₙ)) ^ 2 * (bernstein n ↑k) x)) =
    (fun x => x * ↑n) ((fun x => x * ↑n) (↑x * (1 - ↑x) / ↑n))

Next tactic:
dsimp
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
⊢ (∑ k : Fin (n + 1), (↑x - ↑(k/ₙ)) ^ 2 * (bernstein n ↑k) x) * ↑n * ↑n = ↑x * (1 - ↑x) / ↑n * ↑n * ↑n

Next tactic:
conv_lhs => simp only [Finset.sum_mul, z]
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => 

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
| (∑ k : Fin (n + 1), (↑x - ↑(k/ₙ)) ^ 2 * (bernstein n ↑k) x) * ↑n * ↑n

Next tactic:
simp only [Finset.sum_mul, z]
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
⊢ ∑ x_1 : Fin (n + 1), (↑x - ↑↑x_1 / ↑n) ^ 2 * (bernstein n ↑x_1) x * ↑n * ↑n = ↑x * (1 - ↑x) / ↑n * ↑n * ↑n

Next tactic:
conv_rhs => rw [div_mul_cancel _ h']
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  conv_rhs => 

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
| ↑x * (1 - ↑x) / ↑n * ↑n * ↑n

Next tactic:
rw [div_mul_cancel _ h']
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  conv_rhs => rw [div_mul_cancel _ h']
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
⊢ ∑ x_1 : Fin (n + 1), (↑x - ↑↑x_1 / ↑n) ^ 2 * (bernstein n ↑x_1) x * ↑n * ↑n = ↑x * (1 - ↑x) * ↑n

Next tactic:
have := bernsteinPolynomial.variance ℝ n
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  conv_rhs => rw [div_mul_cancel _ h']
  have := bernsteinPolynomial.variance ℝ n
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
this :
  ∑ ν in Finset.range (n + 1), (n • Polynomial.X - ↑ν) ^ 2 * bernsteinPolynomial ℝ n ν =
    n • Polynomial.X * (1 - Polynomial.X)
⊢ ∑ x_1 : Fin (n + 1), (↑x - ↑↑x_1 / ↑n) ^ 2 * (bernstein n ↑x_1) x * ↑n * ↑n = ↑x * (1 - ↑x) * ↑n

Next tactic:
apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  conv_rhs => rw [div_mul_cancel _ h']
  have := bernsteinPolynomial.variance ℝ n
  apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
this :
  (Polynomial.aeval ↑x) (∑ ν in Finset.range (n + 1), (n • Polynomial.X - ↑ν) ^ 2 * bernsteinPolynomial ℝ n ν) =
    (Polynomial.aeval ↑x) (n • Polynomial.X * (1 - Polynomial.X))
⊢ ∑ x_1 : Fin (n + 1), (↑x - ↑↑x_1 / ↑n) ^ 2 * (bernstein n ↑x_1) x * ↑n * ↑n = ↑x * (1 - ↑x) * ↑n

Next tactic:
simp? [AlgHom.map_sum, Finset.sum_range, ← Polynomial.nat_cast_mul] at this says
    simp only [nsmul_eq_mul, Finset.sum_range, map_sum, map_mul, map_pow, map_sub, map_natCast,
      Polynomial.aeval_X, Polynomial.coe_aeval_eq_eval, map_one] at this
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  conv_rhs => rw [div_mul_cancel _ h']
  have := bernsteinPolynomial.variance ℝ n
  apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
  simp? [AlgHom.map_sum, Finset.sum_range, ← Polynomial.nat_cast_mul] at this says
    

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
this :
  (Polynomial.aeval ↑x) (∑ ν in Finset.range (n + 1), (n • Polynomial.X - ↑ν) ^ 2 * bernsteinPolynomial ℝ n ν) =
    (Polynomial.aeval ↑x) (n • Polynomial.X * (1 - Polynomial.X))
⊢ ∑ x_1 : Fin (n + 1), (↑x - ↑↑x_1 / ↑n) ^ 2 * (bernstein n ↑x_1) x * ↑n * ↑n = ↑x * (1 - ↑x) * ↑n

Next tactic:
simp only [nsmul_eq_mul, Finset.sum_range, map_sum, map_mul, map_pow, map_sub, map_natCast,
      Polynomial.aeval_X, Polynomial.coe_aeval_eq_eval, map_one] at this
theorem variance {n : ℕ} (h : 0 < (n : ℝ)) (x : I) :
    (∑ k : Fin (n + 1), (x - k/ₙ : ℝ) ^ 2 * bernstein n k x) = (x : ℝ) * (1 - x) / n := by
  have h' : (n : ℝ) ≠ 0 := ne_of_gt h
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  apply_fun fun x : ℝ => x * n using GroupWithZero.mul_right_injective h'
  dsimp
  conv_lhs => simp only [Finset.sum_mul, z]
  conv_rhs => rw [div_mul_cancel _ h']
  have := bernsteinPolynomial.variance ℝ n
  apply_fun fun p => Polynomial.aeval (x : ℝ) p at this
  simp? [AlgHom.map_sum, Finset.sum_range, ← Polynomial.nat_cast_mul] at this says
    simp only [nsmul_eq_mul, Finset.sum_range, map_sum, map_mul, map_pow, map_sub, map_natCast,
      Polynomial.aeval_X, Polynomial.coe_aeval_eq_eval, map_one] at this
  

Proof state:
n : ℕ
h : 0 < ↑n
x : ↑I
h' : ↑n ≠ 0
this :
  ∑ x_1 : Fin (n + 1), (↑n * ↑x - ↑↑x_1) ^ 2 * Polynomial.eval (↑x) (bernsteinPolynomial ℝ n ↑x_1) = ↑n * ↑x * (1 - ↑x)
⊢ ∑ x_1 : Fin (n + 1), (↑x - ↑↑x_1 / ↑n) ^ 2 * (bernstein n ↑x_1) x * ↑n * ↑n = ↑x * (1 - ↑x) * ↑n

Next tactic:
convert this using 1