l3lab/ntp-mathlib huggingface dataset:
/-- **Strong law of large numbers**, Lᵖ version: if `X n` is a sequence of independent
identically distributed random variables in Lᵖ, then `n⁻¹ • ∑ i in range n, X i`
converges in `Lᵖ` to `𝔼[X 0]`. -/
theorem strong_law_Lp {p : ℝ≥0∞} (hp : 1 ≤ p) (hp' : p ≠ ∞) (X : ℕ → Ω → E) (hℒp : Memℒp (X 0) p)
    (hindep : Pairwise fun i j => IndepFun (X i) (X j)) (hident : ∀ i, IdentDistrib (X i) (X 0)) :
    Tendsto (fun (n : ℕ) => snorm (fun ω => (n : ℝ) ⁻¹ • (∑ i in range n, X i ω) - 𝔼[X 0]) p ℙ)
      atTop (𝓝 0) := by
  have hmeas : ∀ i, AEStronglyMeasurable (X i) ℙ := fun i =>
    (hident i).aestronglyMeasurable_iff.2 hℒp.1
  have hint : Integrable (X 0) ℙ := hℒp.integrable hp
  have havg : ∀ (n : ℕ),
      AEStronglyMeasurable (fun ω => (n : ℝ) ⁻¹ • (∑ i in range n, X i ω)) ℙ := by
    intro n
    exact AEStronglyMeasurable.const_smul (aestronglyMeasurable_sum _ fun i _ => hmeas i) _
  refine' tendsto_Lp_of_tendstoInMeasure _ hp hp' havg (memℒp_const _) _
    (tendstoInMeasure_of_tendsto_ae havg (strong_law_ae _ hint hindep hident))
  rw [(_ : (fun (n : ℕ) ω => (n : ℝ)⁻¹ • (∑ i in range n, X i ω))
            = fun (n : ℕ) => (n : ℝ)⁻¹ • (∑ i in range n, X i))]
  · apply UniformIntegrable.unifIntegrable
    apply uniformIntegrable_average hp
    exact Memℒp.uniformIntegrable_of_identDistrib hp hp' hℒp hident
  · 

Proof state:
Ω : Type u_1
inst✝⁶ : MeasureSpace Ω
inst✝⁵ : IsProbabilityMeasure ℙ
E : Type u_2
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : CompleteSpace E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
p : ℝ≥0∞
hp : 1 ≤ p
hp' : p ≠ ⊤
X : ℕ → Ω → E
hℒp : Memℒp (X 0) p
hindep : Pairwise fun i j => IndepFun (X i) (X j)
hident : ∀ (i : ℕ), IdentDistrib (X i) (X 0)
hmeas : ∀ (i : ℕ), AEStronglyMeasurable (X i) ℙ
hint : Integrable (X 0)
havg : ∀ (n : ℕ), AEStronglyMeasurable (fun ω => (↑n)⁻¹ • ∑ i in range n, X i ω) ℙ
⊢ (fun n ω => (↑n)⁻¹ • ∑ i in range n, X i ω) = fun n => (↑n)⁻¹ • ∑ i in range n, X i

Next tactic:
ext n ω
/-- **Strong law of large numbers**, Lᵖ version: if `X n` is a sequence of independent
identically distributed random variables in Lᵖ, then `n⁻¹ • ∑ i in range n, X i`
converges in `Lᵖ` to `𝔼[X 0]`. -/
theorem strong_law_Lp {p : ℝ≥0∞} (hp : 1 ≤ p) (hp' : p ≠ ∞) (X : ℕ → Ω → E) (hℒp : Memℒp (X 0) p)
    (hindep : Pairwise fun i j => IndepFun (X i) (X j)) (hident : ∀ i, IdentDistrib (X i) (X 0)) :
    Tendsto (fun (n : ℕ) => snorm (fun ω => (n : ℝ) ⁻¹ • (∑ i in range n, X i ω) - 𝔼[X 0]) p ℙ)
      atTop (𝓝 0) := by
  have hmeas : ∀ i, AEStronglyMeasurable (X i) ℙ := fun i =>
    (hident i).aestronglyMeasurable_iff.2 hℒp.1
  have hint : Integrable (X 0) ℙ := hℒp.integrable hp
  have havg : ∀ (n : ℕ),
      AEStronglyMeasurable (fun ω => (n : ℝ) ⁻¹ • (∑ i in range n, X i ω)) ℙ := by
    intro n
    exact AEStronglyMeasurable.const_smul (aestronglyMeasurable_sum _ fun i _ => hmeas i) _
  refine' tendsto_Lp_of_tendstoInMeasure _ hp hp' havg (memℒp_const _) _
    (tendstoInMeasure_of_tendsto_ae havg (strong_law_ae _ hint hindep hident))
  rw [(_ : (fun (n : ℕ) ω => (n : ℝ)⁻¹ • (∑ i in range n, X i ω))
            = fun (n : ℕ) => (n : ℝ)⁻¹ • (∑ i in range n, X i))]
  · apply UniformIntegrable.unifIntegrable
    apply uniformIntegrable_average hp
    exact Memℒp.uniformIntegrable_of_identDistrib hp hp' hℒp hident
  · ext n ω
    

Proof state:
case h.h
Ω : Type u_1
inst✝⁶ : MeasureSpace Ω
inst✝⁵ : IsProbabilityMeasure ℙ
E : Type u_2
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : CompleteSpace E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
p : ℝ≥0∞
hp : 1 ≤ p
hp' : p ≠ ⊤
X : ℕ → Ω → E
hℒp : Memℒp (X 0) p
hindep : Pairwise fun i j => IndepFun (X i) (X j)
hident : ∀ (i : ℕ), IdentDistrib (X i) (X 0)
hmeas : ∀ (i : ℕ), AEStronglyMeasurable (X i) ℙ
hint : Integrable (X 0)
havg : ∀ (n : ℕ), AEStronglyMeasurable (fun ω => (↑n)⁻¹ • ∑ i in range n, X i ω) ℙ
n : ℕ
ω : Ω
⊢ (↑n)⁻¹ • ∑ i in range n, X i ω = ((↑n)⁻¹ • ∑ i in range n, X i) ω

Next tactic:
simp only [Pi.smul_apply, sum_apply]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ Int.natAbs n

Next tactic:
let y := rexp (-π * z.im)
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ Int.natAbs n

Next tactic:
have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ Int.natAbs n

Next tactic:
refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · 

Proof state:
case refine'_1
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ = y ^ n ^ 2

Next tactic:
rw [Complex.norm_eq_abs, Complex.abs_exp]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    

Proof state:
case refine'_1
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ rexp (↑π * I * ↑n ^ 2 * z).re = y ^ n ^ 2

Next tactic:
have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ (↑π * I * ↑n ^ 2 * z).re = -π * z.im * ↑n ^ 2

Next tactic:
rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by 

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ↑π * I * ↑n ^ 2 * z = ↑(π * ↑n ^ 2) * (z * I)

Next tactic:
push_cast
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; 

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ↑π * I * ↑n ^ 2 * z = ↑π * ↑n ^ 2 * (z * I)

Next tactic:
ring
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ π * ↑n ^ 2 * -z.im = -π * z.im * ↑n ^ 2

Next tactic:
ring
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
    

Proof state:
case refine'_1
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
this : (↑π * I * ↑n ^ 2 * z).re = -π * z.im * ↑n ^ 2
⊢ rexp (↑π * I * ↑n ^ 2 * z).re = y ^ n ^ 2

Next tactic:
obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
    obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
    

Proof state:
case refine'_1.intro
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
this : (↑π * I * ↑n ^ 2 * z).re = -π * z.im * ↑n ^ 2
m : ℕ
hm : n ^ 2 = ↑m
⊢ rexp (↑π * I * ↑n ^ 2 * z).re = y ^ n ^ 2

Next tactic:
rw [this, exp_mul, ← Int.cast_pow, rpow_int_cast, hm, zpow_ofNat]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
    obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
    rw [this, exp_mul, ← Int.cast_pow, rpow_int_cast, hm, zpow_ofNat]
  · 

Proof state:
case refine'_2
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ y ^ n ^ 2 ≤ rexp (-π * z.im) ^ Int.natAbs n

Next tactic:
have : n ^ 2 = (n.natAbs ^ 2 :) := by rw [Nat.cast_pow, Int.natAbs_sq]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
    obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
    rw [this, exp_mul, ← Int.cast_pow, rpow_int_cast, hm, zpow_ofNat]
  · have : n ^ 2 = (n.natAbs ^ 2 :) := by 

Proof state:
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ n ^ 2 = ↑(Int.natAbs n ^ 2)

Next tactic:
rw [Nat.cast_pow, Int.natAbs_sq]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
    obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
    rw [this, exp_mul, ← Int.cast_pow, rpow_int_cast, hm, zpow_ofNat]
  · have : n ^ 2 = (n.natAbs ^ 2 :) := by rw [Nat.cast_pow, Int.natAbs_sq]
    

Proof state:
case refine'_2
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
this : n ^ 2 = ↑(Int.natAbs n ^ 2)
⊢ y ^ n ^ 2 ≤ rexp (-π * z.im) ^ Int.natAbs n

Next tactic:
rw [this, zpow_ofNat]
theorem norm_exp_mul_sq_le {z : ℂ} (hz : 0 < z.im) (n : ℤ) :
    ‖cexp (π * I * (n : ℂ) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ n.natAbs := by
  let y := rexp (-π * z.im)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
  refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
  · rw [Complex.norm_eq_abs, Complex.abs_exp]
    have : (π * I * n ^ 2 * z : ℂ).re = -π * z.im * (n : ℝ) ^ 2 := by
      rw [(by push_cast; ring : (π * I * n ^ 2 * z : ℂ) = (π * n ^ 2 : ℝ) * (z * I)),
        ofReal_mul_re, mul_I_re]
      ring
    obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
    rw [this, exp_mul, ← Int.cast_pow, rpow_int_cast, hm, zpow_ofNat]
  · have : n ^ 2 = (n.natAbs ^ 2 :) := by rw [Nat.cast_pow, Int.natAbs_sq]
    rw [this, zpow_ofNat]
    

Proof state:
case refine'_2
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
this : n ^ 2 = ↑(Int.natAbs n ^ 2)
⊢ y ^ Int.natAbs n ^ 2 ≤ rexp (-π * z.im) ^ Int.natAbs n

Next tactic:
exact pow_le_pow_of_le_one (exp_pos _).le h.le ((sq n.natAbs).symm ▸ n.natAbs.le_mul_self)
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  

Proof state:
R : ℝ
hR : 0 < R
⊢ ∃ bd, Summable bd ∧ ∀ {τ : ℂ}, R ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n

Next tactic:
let y := rexp (-π * R)
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  

Proof state:
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
⊢ ∃ bd, Summable bd ∧ ∀ {τ : ℂ}, R ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n

Next tactic:
have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  

Proof state:
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ ∃ bd, Summable bd ∧ ∀ {τ : ℂ}, R ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n

Next tactic:
refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; 

Proof state:
case refine'_1
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs ↑n
case refine'_2
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs (-↑n)
case refine'_3
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
τ✝ : ℂ
hτ : R ≤ τ✝.im
n : ℤ
⊢ ‖cexp (↑π * I * ↑n ^ 2 * τ✝)‖ ≤ (fun n => y ^ Int.natAbs n) n

Next tactic:
pick_goal 3
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · 

Proof state:
case refine'_3
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
τ✝ : ℂ
hτ : R ≤ τ✝.im
n : ℤ
⊢ ‖cexp (↑π * I * ↑n ^ 2 * τ✝)‖ ≤ (fun n => y ^ Int.natAbs n) n

Next tactic:
refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
    

Proof state:
case refine'_3
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
τ✝ : ℂ
hτ : R ≤ τ✝.im
n : ℤ
⊢ rexp (-π * τ✝.im) ^ Int.natAbs n ≤ (fun n => y ^ Int.natAbs n) n

Next tactic:
dsimp
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
    dsimp
    

Proof state:
case refine'_3
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
τ✝ : ℂ
hτ : R ≤ τ✝.im
n : ℤ
⊢ rexp (-π * τ✝.im) ^ Int.natAbs n ≤ rexp (-π * R) ^ Int.natAbs n

Next tactic:
gcongr rexp ?_ ^ _
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
    dsimp
    gcongr rexp ?_ ^ _
    

Proof state:
case refine'_3.hab.h
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
τ✝ : ℂ
hτ : R ≤ τ✝.im
n : ℤ
⊢ -π * τ✝.im ≤ -π * R

Next tactic:
rwa [mul_le_mul_left_of_neg (neg_lt_zero.mpr pi_pos)]
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
    dsimp
    gcongr rexp ?_ ^ _
    rwa [mul_le_mul_left_of_neg (neg_lt_zero.mpr pi_pos)]
  

Proof state:
case refine'_1
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs ↑n
case refine'_2 R : ℝ hR : 0 < R y : ℝ := rexp (-π * R) h : y < 1 ⊢ Summable fun n => y ^ Int.natAbs (-↑n)

Next tactic:
all_goals
    simpa only [Int.natAbs_neg, Int.natAbs_ofNat] using
      summable_geometric_of_lt_1 (Real.exp_pos _).le h
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
    dsimp
    gcongr rexp ?_ ^ _
    rwa [mul_le_mul_left_of_neg (neg_lt_zero.mpr pi_pos)]
  all_goals
    

Proof state:
case refine'_1
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs ↑n

Next tactic:
simpa only [Int.natAbs_neg, Int.natAbs_ofNat] using
      summable_geometric_of_lt_1 (Real.exp_pos _).le h
theorem exists_summable_bound_exp_mul_sq {R : ℝ} (hR : 0 < R) :
    ∃ bd : ℤ → ℝ, Summable bd ∧ ∀ {τ : ℂ} (_ : R ≤ τ.im) (n : ℤ),
      ‖cexp (π * I * (n : ℂ) ^ 2 * τ)‖ ≤ bd n := by
  let y := rexp (-π * R)
  have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
  refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩; pick_goal 3
  · refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
    dsimp
    gcongr rexp ?_ ^ _
    rwa [mul_le_mul_left_of_neg (neg_lt_zero.mpr pi_pos)]
  all_goals
    

Proof state:
case refine'_2
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs (-↑n)

Next tactic:
simpa only [Int.natAbs_neg, Int.natAbs_ofNat] using
      summable_geometric_of_lt_1 (Real.exp_pos _).le h
theorem jacobiTheta_two_add (z : ℂ) : jacobiTheta (2 + z) = jacobiTheta z := by
  

Proof state:
z : ℂ
⊢ jacobiTheta (2 + z) = jacobiTheta z

Next tactic:
refine' tsum_congr fun n => _
theorem jacobiTheta_two_add (z : ℂ) : jacobiTheta (2 + z) = jacobiTheta z := by
  refine' tsum_congr fun n => _
  

Proof state:
z : ℂ
n : ℤ
⊢ cexp (↑π * I * ↑n ^ 2 * (2 + z)) = cexp (↑π * I * ↑n ^ 2 * z)

Next tactic:
suffices cexp (π * I * n ^ 2 * 2 : ℂ) = 1 by rw [mul_add, Complex.exp_add, this, one_mul]
theorem jacobiTheta_two_add (z : ℂ) : jacobiTheta (2 + z) = jacobiTheta z := by
  refine' tsum_congr fun n => _
  suffices cexp (π * I * n ^ 2 * 2 : ℂ) = 1 by 

Proof state:
z : ℂ
n : ℤ
this : cexp (↑π * I * ↑n ^ 2 * 2) = 1
⊢ cexp (↑π * I * ↑n ^ 2 * (2 + z)) = cexp (↑π * I * ↑n ^ 2 * z)

Next tactic:
rw [mul_add, Complex.exp_add, this, one_mul]
theorem jacobiTheta_two_add (z : ℂ) : jacobiTheta (2 + z) = jacobiTheta z := by
  refine' tsum_congr fun n => _
  suffices cexp (π * I * n ^ 2 * 2 : ℂ) = 1 by rw [mul_add, Complex.exp_add, this, one_mul]
  

Proof state:
z : ℂ
n : ℤ
⊢ cexp (↑π * I * ↑n ^ 2 * 2) = 1

Next tactic:
rw [(by push_cast; ring : (π * I * n ^ 2 * 2 : ℂ) = (n ^ 2 :) * (2 * π * I)), Complex.exp_int_mul,
    Complex.exp_two_pi_mul_I, one_zpow]
theorem jacobiTheta_two_add (z : ℂ) : jacobiTheta (2 + z) = jacobiTheta z := by
  refine' tsum_congr fun n => _
  suffices cexp (π * I * n ^ 2 * 2 : ℂ) = 1 by rw [mul_add, Complex.exp_add, this, one_mul]
  rw [(by 

Proof state:
z : ℂ
n : ℤ
⊢ ↑π * I * ↑n ^ 2 * 2 = ↑(n ^ 2) * (2 * ↑π * I)

Next tactic:
push_cast
theorem jacobiTheta_two_add (z : ℂ) : jacobiTheta (2 + z) = jacobiTheta z := by
  refine' tsum_congr fun n => _
  suffices cexp (π * I * n ^ 2 * 2 : ℂ) = 1 by rw [mul_add, Complex.exp_add, this, one_mul]
  rw [(by push_cast; 

Proof state:
z : ℂ
n : ℤ
⊢ ↑π * I * ↑n ^ 2 * 2 = ↑n ^ 2 * (2 * ↑π * I)

Next tactic:
ring
theorem jacobiTheta_T_sq_smul (τ : ℍ) : jacobiTheta (ModularGroup.T ^ 2 • τ :) = jacobiTheta τ := by
  

Proof state:
τ : ℍ
⊢ jacobiTheta ↑(ModularGroup.T ^ 2 • τ) = jacobiTheta ↑τ

Next tactic:
suffices (ModularGroup.T ^ 2 • τ :) = (2 : ℂ) + ↑τ by simp_rw [this, jacobiTheta_two_add]
theorem jacobiTheta_T_sq_smul (τ : ℍ) : jacobiTheta (ModularGroup.T ^ 2 • τ :) = jacobiTheta τ := by
  suffices (ModularGroup.T ^ 2 • τ :) = (2 : ℂ) + ↑τ by 

Proof state:
τ : ℍ
this : ↑(ModularGroup.T ^ 2 • τ) = 2 + ↑τ
⊢ jacobiTheta ↑(ModularGroup.T ^ 2 • τ) = jacobiTheta ↑τ

Next tactic:
simp_rw [this, jacobiTheta_two_add]