l3lab/ntp-mathlib huggingface dataset:
lemma toClass_eq_zero (P : W.Point) : toClass P = 0 ↔ P = 0 := by
  constructor
  · intro hP
    rcases P with (_ | @⟨_, _, ⟨h, _⟩⟩)
    · rfl
    · rcases (ClassGroup.mk_eq_one_of_coe_ideal <| by rfl).mp hP with ⟨p, h0, hp⟩
      apply (p.natDegree_norm_ne_one _).elim
      

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x✝ y✝ : F
h : W.equation x✝ y✝
right✝ : eval x✝ (eval (C y✝) W.polynomialX) ≠ 0 ∨ eval x✝ (eval (C y✝) W.polynomialY) ≠ 0
hP :
  toClass
      (some
        (_ : W.equation x✝ y✝ ∧ (eval x✝ (eval (C y✝) W.polynomialX) ≠ 0 ∨ eval x✝ (eval (C y✝) W.polynomialY) ≠ 0))) =
    0
p : W.CoordinateRing
h0 : p ≠ 0
hp : CoordinateRing.XYIdeal W x✝ (C y✝) = span {p}
⊢ natDegree ((Algebra.norm F[X]) p) = 1

Next tactic:
rw [← finrank_quotient_span_eq_natDegree_norm (CoordinateRing.basis W) h0,
        ← (quotientEquivAlgOfEq F hp).toLinearEquiv.finrank_eq,
        (CoordinateRing.quotientXYIdealEquiv W h).toLinearEquiv.finrank_eq,
        FiniteDimensional.finrank_self]
lemma toClass_eq_zero (P : W.Point) : toClass P = 0 ↔ P = 0 := by
  constructor
  · intro hP
    rcases P with (_ | @⟨_, _, ⟨h, _⟩⟩)
    · rfl
    · rcases (ClassGroup.mk_eq_one_of_coe_ideal <| by rfl).mp hP with ⟨p, h0, hp⟩
      apply (p.natDegree_norm_ne_one _).elim
      rw [← finrank_quotient_span_eq_natDegree_norm (CoordinateRing.basis W) h0,
        ← (quotientEquivAlgOfEq F hp).toLinearEquiv.finrank_eq,
        (CoordinateRing.quotientXYIdealEquiv W h).toLinearEquiv.finrank_eq,
        FiniteDimensional.finrank_self]
  · 

Proof state:
case mpr
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
P : Point W
⊢ P = 0 → toClass P = 0

Next tactic:
exact congr_arg toClass
lemma toClass_injective : Function.Injective <| @toClass _ _ W := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
⊢ Function.Injective ⇑toClass

Next tactic:
rintro (_ | h) _ hP
lemma toClass_injective : Function.Injective <| @toClass _ _ W := by
  rintro (_ | h) _ hP
  

Proof state:
case zero
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
a₂✝ : Point W
hP : toClass zero = toClass a₂✝
⊢ zero = a₂✝
case some
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x✝ y✝ : F
h : W.nonsingular x✝ y✝
a₂✝ : Point W
hP : toClass (some h) = toClass a₂✝
⊢ some h = a₂✝

Next tactic:
all_goals rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
lemma toClass_injective : Function.Injective <| @toClass _ _ W := by
  rintro (_ | h) _ hP
  all_goals 

Proof state:
case zero
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
a₂✝ : Point W
hP : toClass zero = toClass a₂✝
⊢ zero = a₂✝

Next tactic:
rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
lemma toClass_injective : Function.Injective <| @toClass _ _ W := by
  rintro (_ | h) _ hP
  all_goals 

Proof state:
case some
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x✝ y✝ : F
h : W.nonsingular x✝ y✝
a₂✝ : Point W
hP : toClass (some h) = toClass a₂✝
⊢ some h = a₂✝

Next tactic:
rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
lemma toClass_injective : Function.Injective <| @toClass _ _ W := by
  rintro (_ | h) _ hP
  all_goals rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
  · 

Proof state:
case zero
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
a₂✝ : Point W
hP : toClass zero = toClass a₂✝
⊢ toClass (-zero) + toClass zero = 0

Next tactic:
exact zero_add 0
lemma toClass_injective : Function.Injective <| @toClass _ _ W := by
  rintro (_ | h) _ hP
  all_goals rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
  · exact zero_add 0
  · 

Proof state:
case some
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x✝ y✝ : F
h : W.nonsingular x✝ y✝
a₂✝ : Point W
hP : toClass (some h) = toClass a₂✝
⊢ toClass (-some h) + toClass (some h) = 0

Next tactic:
exact CoordinateRing.mk_XYIdeal'_mul_mk_XYIdeal'_of_Yeq h
lemma add_comm (P Q : W.Point) : P + Q = Q + P :=
  toClass_injective <| by 

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
P Q : Point W
⊢ toClass (P + Q) = toClass (Q + P)

Next tactic:
simp only [map_add, _root_.add_comm]
lemma add_assoc (P Q R : W.Point) : P + Q + R = P + (Q + R) :=
  toClass_injective <| by 

Proof state:
R✝ : Type u
inst✝¹ : CommRing R✝
W✝ : Affine R✝
F : Type u
inst✝ : Field F
W : Affine F
P Q R : Point W
⊢ toClass (P + Q + R) = toClass (P + (Q + R))

Next tactic:
simp only [map_add, _root_.add_assoc]
/-- A faithful linear monoidal functor to a linear monoidal category
ensures that the domain is linear monoidal. -/
theorem monoidalLinearOfFaithful {D : Type*} [Category D] [Preadditive D] [Linear R D]
    [MonoidalCategory D] [MonoidalPreadditive D] (F : MonoidalFunctor D C) [Faithful F.toFunctor]
    [F.toFunctor.Additive] [F.toFunctor.Linear R] : MonoidalLinear R D :=
  { tensor_smul := by
      

Proof state:
R : Type u_1
inst✝¹⁴ : Semiring R
C : Type u_2
inst✝¹³ : Category.{u_5, u_2} C
inst✝¹² : Preadditive C
inst✝¹¹ : Linear R C
inst✝¹⁰ : MonoidalCategory C
inst✝⁹ : MonoidalPreadditive C
inst✝⁸ : MonoidalLinear R C
D : Type u_3
inst✝⁷ : Category.{u_4, u_3} D
inst✝⁶ : Preadditive D
inst✝⁵ : Linear R D
inst✝⁴ : MonoidalCategory D
inst✝³ : MonoidalPreadditive D
F : MonoidalFunctor D C
inst✝² : Faithful F.toFunctor
inst✝¹ : Functor.Additive F.toFunctor
inst✝ : Functor.Linear R F.toFunctor
⊢ ∀ {W X Y Z : D} (f : W ⟶ X) (r : R) (g : Y ⟶ Z), f ⊗ r • g = r • (f ⊗ g)

Next tactic:
intros W X Y Z f r g
/-- A faithful linear monoidal functor to a linear monoidal category
ensures that the domain is linear monoidal. -/
theorem monoidalLinearOfFaithful {D : Type*} [Category D] [Preadditive D] [Linear R D]
    [MonoidalCategory D] [MonoidalPreadditive D] (F : MonoidalFunctor D C) [Faithful F.toFunctor]
    [F.toFunctor.Additive] [F.toFunctor.Linear R] : MonoidalLinear R D :=
  { tensor_smul := by
      intros W X Y Z f r g
      

Proof state:
R : Type u_1
inst✝¹⁴ : Semiring R
C : Type u_2
inst✝¹³ : Category.{u_5, u_2} C
inst✝¹² : Preadditive C
inst✝¹¹ : Linear R C
inst✝¹⁰ : MonoidalCategory C
inst✝⁹ : MonoidalPreadditive C
inst✝⁸ : MonoidalLinear R C
D : Type u_3
inst✝⁷ : Category.{u_4, u_3} D
inst✝⁶ : Preadditive D
inst✝⁵ : Linear R D
inst✝⁴ : MonoidalCategory D
inst✝³ : MonoidalPreadditive D
F : MonoidalFunctor D C
inst✝² : Faithful F.toFunctor
inst✝¹ : Functor.Additive F.toFunctor
inst✝ : Functor.Linear R F.toFunctor
W X Y Z : D
f : W ⟶ X
r : R
g : Y ⟶ Z
⊢ f ⊗ r • g = r • (f ⊗ g)

Next tactic:
apply F.toFunctor.map_injective
/-- A faithful linear monoidal functor to a linear monoidal category
ensures that the domain is linear monoidal. -/
theorem monoidalLinearOfFaithful {D : Type*} [Category D] [Preadditive D] [Linear R D]
    [MonoidalCategory D] [MonoidalPreadditive D] (F : MonoidalFunctor D C) [Faithful F.toFunctor]
    [F.toFunctor.Additive] [F.toFunctor.Linear R] : MonoidalLinear R D :=
  { tensor_smul := by
      intros W X Y Z f r g
      apply F.toFunctor.map_injective
      

Proof state:
case a
R : Type u_1
inst✝¹⁴ : Semiring R
C : Type u_2
inst✝¹³ : Category.{u_5, u_2} C
inst✝¹² : Preadditive C
inst✝¹¹ : Linear R C
inst✝¹⁰ : MonoidalCategory C
inst✝⁹ : MonoidalPreadditive C
inst✝⁸ : MonoidalLinear R C
D : Type u_3
inst✝⁷ : Category.{u_4, u_3} D
inst✝⁶ : Preadditive D
inst✝⁵ : Linear R D
inst✝⁴ : MonoidalCategory D
inst✝³ : MonoidalPreadditive D
F : MonoidalFunctor D C
inst✝² : Faithful F.toFunctor
inst✝¹ : Functor.Additive F.toFunctor
inst✝ : Functor.Linear R F.toFunctor
W X Y Z : D
f : W ⟶ X
r : R
g : Y ⟶ Z
⊢ F.map (f ⊗ r • g) = F.map (r • (f ⊗ g))

Next tactic:
simp only [F.toFunctor.map_smul r (f ⊗ g), F.toFunctor.map_smul r g, F.map_tensor,
        MonoidalLinear.tensor_smul, Linear.smul_comp, Linear.comp_smul]
/-- A faithful linear monoidal functor to a linear monoidal category
ensures that the domain is linear monoidal. -/
theorem monoidalLinearOfFaithful {D : Type*} [Category D] [Preadditive D] [Linear R D]
    [MonoidalCategory D] [MonoidalPreadditive D] (F : MonoidalFunctor D C) [Faithful F.toFunctor]
    [F.toFunctor.Additive] [F.toFunctor.Linear R] : MonoidalLinear R D :=
  { tensor_smul := by
      intros W X Y Z f r g
      apply F.toFunctor.map_injective
      simp only [F.toFunctor.map_smul r (f ⊗ g), F.toFunctor.map_smul r g, F.map_tensor,
        MonoidalLinear.tensor_smul, Linear.smul_comp, Linear.comp_smul]
    smul_tensor := by
      

Proof state:
R : Type u_1
inst✝¹⁴ : Semiring R
C : Type u_2
inst✝¹³ : Category.{u_5, u_2} C
inst✝¹² : Preadditive C
inst✝¹¹ : Linear R C
inst✝¹⁰ : MonoidalCategory C
inst✝⁹ : MonoidalPreadditive C
inst✝⁸ : MonoidalLinear R C
D : Type u_3
inst✝⁷ : Category.{u_4, u_3} D
inst✝⁶ : Preadditive D
inst✝⁵ : Linear R D
inst✝⁴ : MonoidalCategory D
inst✝³ : MonoidalPreadditive D
F : MonoidalFunctor D C
inst✝² : Faithful F.toFunctor
inst✝¹ : Functor.Additive F.toFunctor
inst✝ : Functor.Linear R F.toFunctor
⊢ ∀ {W X Y Z : D} (r : R) (f : W ⟶ X) (g : Y ⟶ Z), r • f ⊗ g = r • (f ⊗ g)

Next tactic:
intros W X Y Z r f g
/-- A faithful linear monoidal functor to a linear monoidal category
ensures that the domain is linear monoidal. -/
theorem monoidalLinearOfFaithful {D : Type*} [Category D] [Preadditive D] [Linear R D]
    [MonoidalCategory D] [MonoidalPreadditive D] (F : MonoidalFunctor D C) [Faithful F.toFunctor]
    [F.toFunctor.Additive] [F.toFunctor.Linear R] : MonoidalLinear R D :=
  { tensor_smul := by
      intros W X Y Z f r g
      apply F.toFunctor.map_injective
      simp only [F.toFunctor.map_smul r (f ⊗ g), F.toFunctor.map_smul r g, F.map_tensor,
        MonoidalLinear.tensor_smul, Linear.smul_comp, Linear.comp_smul]
    smul_tensor := by
      intros W X Y Z r f g
      

Proof state:
R : Type u_1
inst✝¹⁴ : Semiring R
C : Type u_2
inst✝¹³ : Category.{u_5, u_2} C
inst✝¹² : Preadditive C
inst✝¹¹ : Linear R C
inst✝¹⁰ : MonoidalCategory C
inst✝⁹ : MonoidalPreadditive C
inst✝⁸ : MonoidalLinear R C
D : Type u_3
inst✝⁷ : Category.{u_4, u_3} D
inst✝⁶ : Preadditive D
inst✝⁵ : Linear R D
inst✝⁴ : MonoidalCategory D
inst✝³ : MonoidalPreadditive D
F : MonoidalFunctor D C
inst✝² : Faithful F.toFunctor
inst✝¹ : Functor.Additive F.toFunctor
inst✝ : Functor.Linear R F.toFunctor
W X Y Z : D
r : R
f : W ⟶ X
g : Y ⟶ Z
⊢ r • f ⊗ g = r • (f ⊗ g)

Next tactic:
apply F.toFunctor.map_injective
/-- A faithful linear monoidal functor to a linear monoidal category
ensures that the domain is linear monoidal. -/
theorem monoidalLinearOfFaithful {D : Type*} [Category D] [Preadditive D] [Linear R D]
    [MonoidalCategory D] [MonoidalPreadditive D] (F : MonoidalFunctor D C) [Faithful F.toFunctor]
    [F.toFunctor.Additive] [F.toFunctor.Linear R] : MonoidalLinear R D :=
  { tensor_smul := by
      intros W X Y Z f r g
      apply F.toFunctor.map_injective
      simp only [F.toFunctor.map_smul r (f ⊗ g), F.toFunctor.map_smul r g, F.map_tensor,
        MonoidalLinear.tensor_smul, Linear.smul_comp, Linear.comp_smul]
    smul_tensor := by
      intros W X Y Z r f g
      apply F.toFunctor.map_injective
      

Proof state:
case a
R : Type u_1
inst✝¹⁴ : Semiring R
C : Type u_2
inst✝¹³ : Category.{u_5, u_2} C
inst✝¹² : Preadditive C
inst✝¹¹ : Linear R C
inst✝¹⁰ : MonoidalCategory C
inst✝⁹ : MonoidalPreadditive C
inst✝⁸ : MonoidalLinear R C
D : Type u_3
inst✝⁷ : Category.{u_4, u_3} D
inst✝⁶ : Preadditive D
inst✝⁵ : Linear R D
inst✝⁴ : MonoidalCategory D
inst✝³ : MonoidalPreadditive D
F : MonoidalFunctor D C
inst✝² : Faithful F.toFunctor
inst✝¹ : Functor.Additive F.toFunctor
inst✝ : Functor.Linear R F.toFunctor
W X Y Z : D
r : R
f : W ⟶ X
g : Y ⟶ Z
⊢ F.map (r • f ⊗ g) = F.map (r • (f ⊗ g))

Next tactic:
simp only [F.toFunctor.map_smul r (f ⊗ g), F.toFunctor.map_smul r f, F.map_tensor,
        MonoidalLinear.smul_tensor, Linear.smul_comp, Linear.comp_smul]
/-- We have `ζ(0) = -1 / 2`. -/
theorem riemannZeta_zero : riemannZeta 0 = -1 / 2 := by
  

Proof state:
⊢ riemannZeta 0 = -1 / 2

Next tactic:
rw [riemannZeta_def]
/-- We have `ζ(0) = -1 / 2`. -/
theorem riemannZeta_zero : riemannZeta 0 = -1 / 2 := by
  rw [riemannZeta_def]
  

Proof state:
⊢ Function.update (fun s => ↑π ^ (s / 2) * riemannCompletedZeta s / Complex.Gamma (s / 2)) 0 (-1 / 2) 0 = -1 / 2

Next tactic:
exact Function.update_same _ _ _
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  

Proof state:
t : ℝ
ht : 0 < t
⊢ Summable fun n => rexp (-π * t * (↑n + 1) ^ 2)

Next tactic:
have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by 

Proof state:
t : ℝ
ht : 0 < t
⊢ 0 < (↑t * I).im

Next tactic:
rwa [ofReal_mul_im, I_im, mul_one]
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  

Proof state:
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
⊢ Summable fun n => rexp (-π * t * (↑n + 1) ^ 2)

Next tactic:
convert (hasSum_nat_jacobiTheta this).summable.norm using 1
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  convert (hasSum_nat_jacobiTheta this).summable.norm using 1
  

Proof state:
case h.e'_5
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
⊢ (fun n => rexp (-π * t * (↑n + 1) ^ 2)) = fun x => ‖cexp (↑π * I * (↑x + 1) ^ 2 * (↑t * I))‖

Next tactic:
ext1 n
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  convert (hasSum_nat_jacobiTheta this).summable.norm using 1
  ext1 n
  

Proof state:
case h.e'_5.h
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
n : ℕ
⊢ rexp (-π * t * (↑n + 1) ^ 2) = ‖cexp (↑π * I * (↑n + 1) ^ 2 * (↑t * I))‖

Next tactic:
rw [Complex.norm_eq_abs, Complex.abs_exp]
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  convert (hasSum_nat_jacobiTheta this).summable.norm using 1
  ext1 n
  rw [Complex.norm_eq_abs, Complex.abs_exp]
  

Proof state:
case h.e'_5.h
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
n : ℕ
⊢ rexp (-π * t * (↑n + 1) ^ 2) = rexp (↑π * I * (↑n + 1) ^ 2 * (↑t * I)).re

Next tactic:
rw [show ↑π * I * ((n : ℂ) + 1) ^ 2 * (↑t * I) = ((π * t * ((n : ℝ) + 1) ^ 2) : ℝ) * I ^ 2 by
    push_cast; ring]
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  convert (hasSum_nat_jacobiTheta this).summable.norm using 1
  ext1 n
  rw [Complex.norm_eq_abs, Complex.abs_exp]
  rw [show ↑π * I * ((n : ℂ) + 1) ^ 2 * (↑t * I) = ((π * t * ((n : ℝ) + 1) ^ 2) : ℝ) * I ^ 2 by
    

Proof state:
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
n : ℕ
⊢ ↑π * I * (↑n + 1) ^ 2 * (↑t * I) = ↑(π * t * (↑n + 1) ^ 2) * I ^ 2

Next tactic:
push_cast
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  convert (hasSum_nat_jacobiTheta this).summable.norm using 1
  ext1 n
  rw [Complex.norm_eq_abs, Complex.abs_exp]
  rw [show ↑π * I * ((n : ℂ) + 1) ^ 2 * (↑t * I) = ((π * t * ((n : ℝ) + 1) ^ 2) : ℝ) * I ^ 2 by
    push_cast; 

Proof state:
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
n : ℕ
⊢ ↑π * I * (↑n + 1) ^ 2 * (↑t * I) = ↑π * ↑t * (↑n + 1) ^ 2 * I ^ 2

Next tactic:
ring
/-- The sum defining `zetaKernel₁` is convergent. -/
theorem summable_exp_neg_pi_mul_nat_sq {t : ℝ} (ht : 0 < t) :
    Summable fun n : ℕ => rexp (-π * t * ((n : ℝ) + 1) ^ 2) := by
  have : 0 < (↑t * I).im := by rwa [ofReal_mul_im, I_im, mul_one]
  convert (hasSum_nat_jacobiTheta this).summable.norm using 1
  ext1 n
  rw [Complex.norm_eq_abs, Complex.abs_exp]
  rw [show ↑π * I * ((n : ℂ) + 1) ^ 2 * (↑t * I) = ((π * t * ((n : ℝ) + 1) ^ 2) : ℝ) * I ^ 2 by
    push_cast; ring]
  

Proof state:
case h.e'_5.h
t : ℝ
ht : 0 < t
this : 0 < (↑t * I).im
n : ℕ
⊢ rexp (-π * t * (↑n + 1) ^ 2) = rexp (↑(π * t * (↑n + 1) ^ 2) * I ^ 2).re

Next tactic:
rw [I_sq, mul_neg_one, ← ofReal_neg, ofReal_re, neg_mul, neg_mul]
/-- Relate `zetaKernel₁` to the Jacobi theta function on `ℍ`. (We don't use this as the definition
of `zetaKernel₁`, since the sum over `ℕ` rather than `ℤ` is more convenient for relating zeta to
the Dirichlet series for `re s > 1`.) -/
theorem zetaKernel₁_eq_jacobiTheta {t : ℝ} (ht : 0 < t) :
    zetaKernel₁ t = (jacobiTheta (t * I) - 1) / 2 := by
  

Proof state:
t : ℝ
ht : 0 < t
⊢ zetaKernel₁ t = (jacobiTheta (↑t * I) - 1) / 2

Next tactic:
rw [jacobiTheta_eq_tsum_nat ((mul_I_im t).symm ▸ ht : 0 < (↑t * I).im), add_comm, add_sub_cancel,
    mul_div_cancel_left _ (two_ne_zero' ℂ), zetaKernel₁]
/-- Relate `zetaKernel₁` to the Jacobi theta function on `ℍ`. (We don't use this as the definition
of `zetaKernel₁`, since the sum over `ℕ` rather than `ℤ` is more convenient for relating zeta to
the Dirichlet series for `re s > 1`.) -/
theorem zetaKernel₁_eq_jacobiTheta {t : ℝ} (ht : 0 < t) :
    zetaKernel₁ t = (jacobiTheta (t * I) - 1) / 2 := by
  rw [jacobiTheta_eq_tsum_nat ((mul_I_im t).symm ▸ ht : 0 < (↑t * I).im), add_comm, add_sub_cancel,
    mul_div_cancel_left _ (two_ne_zero' ℂ), zetaKernel₁]
  

Proof state:
t : ℝ
ht : 0 < t
⊢ ∑' (n : ℕ), ↑(rexp (-π * t * (↑n + 1) ^ 2)) = ∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * (↑t * I))

Next tactic:
congr 1 with n : 1
/-- Relate `zetaKernel₁` to the Jacobi theta function on `ℍ`. (We don't use this as the definition
of `zetaKernel₁`, since the sum over `ℕ` rather than `ℤ` is more convenient for relating zeta to
the Dirichlet series for `re s > 1`.) -/
theorem zetaKernel₁_eq_jacobiTheta {t : ℝ} (ht : 0 < t) :
    zetaKernel₁ t = (jacobiTheta (t * I) - 1) / 2 := by
  rw [jacobiTheta_eq_tsum_nat ((mul_I_im t).symm ▸ ht : 0 < (↑t * I).im), add_comm, add_sub_cancel,
    mul_div_cancel_left _ (two_ne_zero' ℂ), zetaKernel₁]
  congr 1 with n : 1
  

Proof state:
case e_f.h
t : ℝ
ht : 0 < t
n : ℕ
⊢ ↑(rexp (-π * t * (↑n + 1) ^ 2)) = cexp (↑π * I * (↑n + 1) ^ 2 * (↑t * I))

Next tactic:
push_cast
/-- Relate `zetaKernel₁` to the Jacobi theta function on `ℍ`. (We don't use this as the definition
of `zetaKernel₁`, since the sum over `ℕ` rather than `ℤ` is more convenient for relating zeta to
the Dirichlet series for `re s > 1`.) -/
theorem zetaKernel₁_eq_jacobiTheta {t : ℝ} (ht : 0 < t) :
    zetaKernel₁ t = (jacobiTheta (t * I) - 1) / 2 := by
  rw [jacobiTheta_eq_tsum_nat ((mul_I_im t).symm ▸ ht : 0 < (↑t * I).im), add_comm, add_sub_cancel,
    mul_div_cancel_left _ (two_ne_zero' ℂ), zetaKernel₁]
  congr 1 with n : 1
  push_cast
  

Proof state:
case e_f.h
t : ℝ
ht : 0 < t
n : ℕ
⊢ cexp (-↑π * ↑t * (↑n + 1) ^ 2) = cexp (↑π * I * (↑n + 1) ^ 2 * (↑t * I))

Next tactic:
rw [(by ring : ↑π * I * ((n : ℂ) + 1) ^ 2 * (t * I) = I ^ 2 * π * t * ((n : ℂ) + 1) ^ 2),
    I_sq, neg_one_mul]
/-- Relate `zetaKernel₁` to the Jacobi theta function on `ℍ`. (We don't use this as the definition
of `zetaKernel₁`, since the sum over `ℕ` rather than `ℤ` is more convenient for relating zeta to
the Dirichlet series for `re s > 1`.) -/
theorem zetaKernel₁_eq_jacobiTheta {t : ℝ} (ht : 0 < t) :
    zetaKernel₁ t = (jacobiTheta (t * I) - 1) / 2 := by
  rw [jacobiTheta_eq_tsum_nat ((mul_I_im t).symm ▸ ht : 0 < (↑t * I).im), add_comm, add_sub_cancel,
    mul_div_cancel_left _ (two_ne_zero' ℂ), zetaKernel₁]
  congr 1 with n : 1
  push_cast
  rw [(by 

Proof state:
t : ℝ
ht : 0 < t
n : ℕ
⊢ ↑π * I * (↑n + 1) ^ 2 * (↑t * I) = I ^ 2 * ↑π * ↑t * (↑n + 1) ^ 2

Next tactic:
ring
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  

Proof state:
t : ℝ
ht : 0 < t
⊢ ContinuousAt zetaKernel₁ t

Next tactic:
have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    refine' (ContinuousAt.sub _ continuousAt_const).div_const _
    refine' (continuousAt_jacobiTheta _).comp (ContinuousAt.mul _ continuousAt_const)
    · rwa [mul_I_im, ofReal_re]
    · exact continuous_ofReal.continuousAt
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    

Proof state:
t : ℝ
ht : 0 < t
⊢ ContinuousAt (fun u => (jacobiTheta (↑u * I) - 1) / 2) t

Next tactic:
refine' (ContinuousAt.sub _ continuousAt_const).div_const _
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    refine' (ContinuousAt.sub _ continuousAt_const).div_const _
    

Proof state:
t : ℝ
ht : 0 < t
⊢ ContinuousAt (fun u => jacobiTheta (↑u * I)) t

Next tactic:
refine' (continuousAt_jacobiTheta _).comp (ContinuousAt.mul _ continuousAt_const)
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    refine' (ContinuousAt.sub _ continuousAt_const).div_const _
    refine' (continuousAt_jacobiTheta _).comp (ContinuousAt.mul _ continuousAt_const)
    · 

Proof state:
case refine'_1
t : ℝ
ht : 0 < t
⊢ 0 < (↑t * I).im

Next tactic:
rwa [mul_I_im, ofReal_re]
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    refine' (ContinuousAt.sub _ continuousAt_const).div_const _
    refine' (continuousAt_jacobiTheta _).comp (ContinuousAt.mul _ continuousAt_const)
    · rwa [mul_I_im, ofReal_re]
    · 

Proof state:
case refine'_2
t : ℝ
ht : 0 < t
⊢ ContinuousAt (fun u => ↑u) t

Next tactic:
exact continuous_ofReal.continuousAt
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    refine' (ContinuousAt.sub _ continuousAt_const).div_const _
    refine' (continuousAt_jacobiTheta _).comp (ContinuousAt.mul _ continuousAt_const)
    · rwa [mul_I_im, ofReal_re]
    · exact continuous_ofReal.continuousAt
  

Proof state:
t : ℝ
ht : 0 < t
this : ContinuousAt (fun u => (jacobiTheta (↑u * I) - 1) / 2) t
⊢ ContinuousAt zetaKernel₁ t

Next tactic:
refine' this.congr (eventually_of_mem (Ioi_mem_nhds ht) fun u hu => _)
/-- Continuity of `zetaKernel₁`. -/
theorem continuousAt_zetaKernel₁ {t : ℝ} (ht : 0 < t) : ContinuousAt zetaKernel₁ t := by
  have : ContinuousAt (fun u : ℝ => (jacobiTheta (u * I) - 1) / 2) t := by
    refine' (ContinuousAt.sub _ continuousAt_const).div_const _
    refine' (continuousAt_jacobiTheta _).comp (ContinuousAt.mul _ continuousAt_const)
    · rwa [mul_I_im, ofReal_re]
    · exact continuous_ofReal.continuousAt
  refine' this.congr (eventually_of_mem (Ioi_mem_nhds ht) fun u hu => _)
  

Proof state:
t : ℝ
ht : 0 < t
this : ContinuousAt (fun u => (jacobiTheta (↑u * I) - 1) / 2) t
u : ℝ
hu : u ∈ Ioi 0
⊢ (fun u => (jacobiTheta (↑u * I) - 1) / 2) u = zetaKernel₁ u

Next tactic:
rw [zetaKernel₁_eq_jacobiTheta hu]