[GOAL]
n : ℕ
x : ℕ × ℕ
⊢ x ∈ antidiagonal n ↔ x.fst + x.snd = n
[PROOFSTEP]
rw [antidiagonal, mem_def, Multiset.Nat.mem_antidiagonal]
[GOAL]
n : ℕ
⊢ card (antidiagonal n) = n + 1
[PROOFSTEP]
simp [antidiagonal]
[GOAL]
n : ℕ
⊢ ¬(0, n + 1) ∈
      map (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (antidiagonal n)
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ antidiagonal (n + 1) =
    cons (0, n + 1)
      (map (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (antidiagonal n))
      (_ :
        ¬(0, n + 1) ∈
            map (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ))
              (antidiagonal n))
[PROOFSTEP]
apply eq_of_veq
[GOAL]
case a
n : ℕ
⊢ (antidiagonal (n + 1)).val =
    (cons (0, n + 1)
        (map (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (antidiagonal n))
        (_ :
          ¬(0, n + 1) ∈
              map (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ))
                (antidiagonal n))).val
[PROOFSTEP]
rw [cons_val, map_val]
[GOAL]
case a
n : ℕ
⊢ (antidiagonal (n + 1)).val =
    (0, n + 1) ::ₘ
      Multiset.map (↑(Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)))
        (antidiagonal n).val
[PROOFSTEP]
apply Multiset.Nat.antidiagonal_succ
[GOAL]
n : ℕ
⊢ ¬(n + 1, 0) ∈
      map (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective }) (antidiagonal n)
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ antidiagonal (n + 1) =
    cons (n + 1, 0)
      (map (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective }) (antidiagonal n))
      (_ :
        ¬(n + 1, 0) ∈
            map (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective })
              (antidiagonal n))
[PROOFSTEP]
apply eq_of_veq
[GOAL]
case a
n : ℕ
⊢ (antidiagonal (n + 1)).val =
    (cons (n + 1, 0)
        (map (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective }) (antidiagonal n))
        (_ :
          ¬(n + 1, 0) ∈
              map (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective })
                (antidiagonal n))).val
[PROOFSTEP]
rw [cons_val, map_val]
[GOAL]
case a
n : ℕ
⊢ (antidiagonal (n + 1)).val =
    (n + 1, 0) ::ₘ
      Multiset.map (↑(Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective }))
        (antidiagonal n).val
[PROOFSTEP]
exact Multiset.Nat.antidiagonal_succ'
[GOAL]
n : ℕ
⊢ ¬(n + 2, 0) ∈
      map
        (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
          { toFun := Nat.succ, inj' := Nat.succ_injective })
        (antidiagonal n)
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ ¬(0, n + 2) ∈
      cons (n + 2, 0)
        (map
          (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
            { toFun := Nat.succ, inj' := Nat.succ_injective })
          (antidiagonal n))
        (_ :
          ¬(n + 2, 0) ∈
              map
                (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                  { toFun := Nat.succ, inj' := Nat.succ_injective })
                (antidiagonal n))
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ antidiagonal (n + 2) =
    cons (0, n + 2)
      (cons (n + 2, 0)
        (map
          (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
            { toFun := Nat.succ, inj' := Nat.succ_injective })
          (antidiagonal n))
        (_ :
          ¬(n + 2, 0) ∈
              map
                (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                  { toFun := Nat.succ, inj' := Nat.succ_injective })
                (antidiagonal n)))
      (_ :
        ¬(0, n + 2) ∈
            cons (n + 2, 0)
              (map
                (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                  { toFun := Nat.succ, inj' := Nat.succ_injective })
                (antidiagonal n))
              (_ :
                ¬(n + 2, 0) ∈
                    map
                      (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                        { toFun := Nat.succ, inj' := Nat.succ_injective })
                      (antidiagonal n)))
[PROOFSTEP]
simp_rw [antidiagonal_succ (n + 1), antidiagonal_succ', Finset.map_cons, map_map]
[GOAL]
n : ℕ
⊢ cons (0, n + 1 + 1)
      (cons (↑(Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (n + 1, 0))
        (map
          (Embedding.trans (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective })
            (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)))
          (antidiagonal n))
        (_ :
          ¬↑(Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (n + 1, 0) ∈
              map
                (Embedding.trans
                  (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective })
                  (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)))
                (antidiagonal n)))
      (_ :
        ¬(0, n + 1 + 1) ∈
            cons (↑(Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (n + 1, 0))
              (map
                (Embedding.trans
                  (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective })
                  (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)))
                (antidiagonal n))
              (_ :
                ¬↑(Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)) (n + 1, 0) ∈
                    map
                      (Embedding.trans
                        (Embedding.prodMap (Embedding.refl ℕ) { toFun := Nat.succ, inj' := Nat.succ_injective })
                        (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective } (Embedding.refl ℕ)))
                      (antidiagonal n))) =
    cons (0, n + 2)
      (cons (n + 2, 0)
        (map
          (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
            { toFun := Nat.succ, inj' := Nat.succ_injective })
          (antidiagonal n))
        (_ :
          ¬(n + 2, 0) ∈
              map
                (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                  { toFun := Nat.succ, inj' := Nat.succ_injective })
                (antidiagonal n)))
      (_ :
        ¬(0, n + 2) ∈
            cons (n + 2, 0)
              (map
                (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                  { toFun := Nat.succ, inj' := Nat.succ_injective })
                (antidiagonal n))
              (_ :
                ¬(n + 2, 0) ∈
                    map
                      (Embedding.prodMap { toFun := Nat.succ, inj' := Nat.succ_injective }
                        { toFun := Nat.succ, inj' := Nat.succ_injective })
                      (antidiagonal n)))
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
⊢ (map { toFun := Prod.swap, inj' := (_ : Injective Prod.swap) } (antidiagonal n)).val = (antidiagonal n).val
[PROOFSTEP]
simp [antidiagonal, Multiset.Nat.map_swap_antidiagonal]
[GOAL]
n : ℕ
p q : ℕ × ℕ
hp : p ∈ antidiagonal n
hq : q ∈ antidiagonal n
⊢ p = q ↔ p.fst = q.fst
[PROOFSTEP]
refine' ⟨congr_arg Prod.fst, fun h ↦ Prod.ext h ((add_right_inj q.fst).mp _)⟩
[GOAL]
n : ℕ
p q : ℕ × ℕ
hp : p ∈ antidiagonal n
hq : q ∈ antidiagonal n
h : p.fst = q.fst
⊢ q.fst + p.snd = q.fst + q.snd
[PROOFSTEP]
rw [mem_antidiagonal] at hp hq
[GOAL]
n : ℕ
p q : ℕ × ℕ
hp : p.fst + p.snd = n
hq : q.fst + q.snd = n
h : p.fst = q.fst
⊢ q.fst + p.snd = q.fst + q.snd
[PROOFSTEP]
rw [hq, ← h, hp]
[GOAL]
n : ℕ
kl : ℕ × ℕ
hlk : kl ∈ antidiagonal n
⊢ kl.fst ≤ n
[PROOFSTEP]
rw [le_iff_exists_add]
[GOAL]
n : ℕ
kl : ℕ × ℕ
hlk : kl ∈ antidiagonal n
⊢ ∃ c, n = kl.fst + c
[PROOFSTEP]
use kl.2
[GOAL]
case h
n : ℕ
kl : ℕ × ℕ
hlk : kl ∈ antidiagonal n
⊢ n = kl.fst + kl.snd
[PROOFSTEP]
rwa [mem_antidiagonal, eq_comm] at hlk
[GOAL]
n : ℕ
kl : ℕ × ℕ
hlk : kl ∈ antidiagonal n
⊢ kl.snd ≤ n
[PROOFSTEP]
rw [le_iff_exists_add]
[GOAL]
n : ℕ
kl : ℕ × ℕ
hlk : kl ∈ antidiagonal n
⊢ ∃ c, n = kl.snd + c
[PROOFSTEP]
use kl.1
[GOAL]
case h
n : ℕ
kl : ℕ × ℕ
hlk : kl ∈ antidiagonal n
⊢ n = kl.snd + kl.fst
[PROOFSTEP]
rwa [mem_antidiagonal, eq_comm, add_comm] at hlk
[GOAL]
n m : ℕ
⊢ filter (fun x => x.fst = m) (antidiagonal n) = if m ≤ n then {(m, n - m)} else ∅
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case a.mk
n m x y : ℕ
⊢ (x, y) ∈ filter (fun x => x.fst = m) (antidiagonal n) ↔ (x, y) ∈ if m ≤ n then {(m, n - m)} else ∅
[PROOFSTEP]
simp only [mem_filter, Nat.mem_antidiagonal]
[GOAL]
case a.mk
n m x y : ℕ
⊢ x + y = n ∧ x = m ↔ (x, y) ∈ if m ≤ n then {(m, n - m)} else ∅
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
n m x y : ℕ
h : m ≤ n
⊢ x + y = n ∧ x = m ↔ (x, y) ∈ {(m, n - m)}
[PROOFSTEP]
simp (config := { contextual := true }) [and_comm, eq_tsub_iff_add_eq_of_le h, add_comm]
[GOAL]
case neg
n m x y : ℕ
h : ¬m ≤ n
⊢ x + y = n ∧ x = m ↔ (x, y) ∈ ∅
[PROOFSTEP]
rw [not_le] at h
[GOAL]
case neg
n m x y : ℕ
h : n < m
⊢ x + y = n ∧ x = m ↔ (x, y) ∈ ∅
[PROOFSTEP]
simp only [not_mem_empty, iff_false_iff, not_and, decide_eq_true_eq]
[GOAL]
case neg
n m x y : ℕ
h : n < m
⊢ x + y = n → ¬x = m
[PROOFSTEP]
exact fun hn => ne_of_lt (lt_of_le_of_lt (le_self_add.trans hn.le) h)
[GOAL]
n m : ℕ
⊢ filter (fun x => x.snd = m) (antidiagonal n) = if m ≤ n then {(n - m, m)} else ∅
[PROOFSTEP]
have : (fun x : ℕ × ℕ ↦ (x.snd = m)) ∘ Prod.swap = fun x : ℕ × ℕ ↦ x.fst = m := by ext; simp
[GOAL]
n m : ℕ
⊢ (fun x => x.snd = m) ∘ Prod.swap = fun x => x.fst = m
[PROOFSTEP]
ext
[GOAL]
case h.a
n m : ℕ
x✝ : ℕ × ℕ
⊢ ((fun x => x.snd = m) ∘ Prod.swap) x✝ ↔ x✝.fst = m
[PROOFSTEP]
simp
[GOAL]
n m : ℕ
this : (fun x => x.snd = m) ∘ Prod.swap = fun x => x.fst = m
⊢ filter (fun x => x.snd = m) (antidiagonal n) = if m ≤ n then {(n - m, m)} else ∅
[PROOFSTEP]
rw [← map_swap_antidiagonal, filter_map]
[GOAL]
n m : ℕ
this : (fun x => x.snd = m) ∘ Prod.swap = fun x => x.fst = m
⊢ map { toFun := Prod.swap, inj' := (_ : Injective Prod.swap) }
      (filter ((fun x => x.snd = m) ∘ ↑{ toFun := Prod.swap, inj' := (_ : Injective Prod.swap) }) (antidiagonal n)) =
    if m ≤ n then {(n - m, m)} else ∅
[PROOFSTEP]
simp [this, filter_fst_eq_antidiagonal, apply_ite (Finset.map _)]
[GOAL]
n k : ℕ
h : k ≤ n
⊢ filter (fun a => a.snd ≤ k) (antidiagonal n) =
    map
      (Embedding.prodMap { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) }
        (Embedding.refl ℕ))
      (antidiagonal k)
[PROOFSTEP]
ext ⟨i, j⟩
[GOAL]
case a.mk
n k : ℕ
h : k ≤ n
i j : ℕ
⊢ (i, j) ∈ filter (fun a => a.snd ≤ k) (antidiagonal n) ↔
    (i, j) ∈
      map
        (Embedding.prodMap { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) }
          (Embedding.refl ℕ))
        (antidiagonal k)
[PROOFSTEP]
suffices : i + j = n ∧ j ≤ k ↔ ∃ a, a + j = k ∧ a + (n - k) = i
[GOAL]
case a.mk
n k : ℕ
h : k ≤ n
i j : ℕ
this : i + j = n ∧ j ≤ k ↔ ∃ a, a + j = k ∧ a + (n - k) = i
⊢ (i, j) ∈ filter (fun a => a.snd ≤ k) (antidiagonal n) ↔
    (i, j) ∈
      map
        (Embedding.prodMap { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) }
          (Embedding.refl ℕ))
        (antidiagonal k)
[PROOFSTEP]
simpa
[GOAL]
case this
n k : ℕ
h : k ≤ n
i j : ℕ
⊢ i + j = n ∧ j ≤ k ↔ ∃ a, a + j = k ∧ a + (n - k) = i
[PROOFSTEP]
refine' ⟨fun hi ↦ ⟨k - j, tsub_add_cancel_of_le hi.2, _⟩, _⟩
[GOAL]
case this.refine'_1
n k : ℕ
h : k ≤ n
i j : ℕ
hi : i + j = n ∧ j ≤ k
⊢ k - j + (n - k) = i
[PROOFSTEP]
rw [add_comm, tsub_add_eq_add_tsub h, ← hi.1, add_assoc, Nat.add_sub_of_le hi.2, add_tsub_cancel_right]
[GOAL]
case this.refine'_2
n k : ℕ
h : k ≤ n
i j : ℕ
⊢ (∃ a, a + j = k ∧ a + (n - k) = i) → i + j = n ∧ j ≤ k
[PROOFSTEP]
rintro ⟨l, hl, rfl⟩
[GOAL]
case this.refine'_2.intro.intro
n k : ℕ
h : k ≤ n
j l : ℕ
hl : l + j = k
⊢ l + (n - k) + j = n ∧ j ≤ k
[PROOFSTEP]
refine' ⟨_, hl ▸ Nat.le_add_left j l⟩
[GOAL]
case this.refine'_2.intro.intro
n k : ℕ
h : k ≤ n
j l : ℕ
hl : l + j = k
⊢ l + (n - k) + j = n
[PROOFSTEP]
rw [add_assoc, add_comm, add_assoc, add_comm j l, hl]
[GOAL]
case this.refine'_2.intro.intro
n k : ℕ
h : k ≤ n
j l : ℕ
hl : l + j = k
⊢ n - k + k = n
[PROOFSTEP]
exact Nat.sub_add_cancel h
[GOAL]
n k : ℕ
h : k ≤ n
⊢ filter (fun a => a.fst ≤ k) (antidiagonal n) =
    map
      (Embedding.prodMap (Embedding.refl ℕ)
        { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) })
      (antidiagonal k)
[PROOFSTEP]
have aux₁ : (fun a ↦ a.fst ≤ k) = (fun a ↦ a.snd ≤ k) ∘ (Equiv.prodComm ℕ ℕ).symm := rfl
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
⊢ filter (fun a => a.fst ≤ k) (antidiagonal n) =
    map
      (Embedding.prodMap (Embedding.refl ℕ)
        { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) })
      (antidiagonal k)
[PROOFSTEP]
have aux₂ : ∀ i j, (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j :=
  fun i j ↦ by rw [exists_comm]; exact exists₂_congr (fun a b ↦ by rw [add_comm])
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
i j : ℕ
⊢ (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j
[PROOFSTEP]
rw [exists_comm]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
i j : ℕ
⊢ (∃ b a, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j
[PROOFSTEP]
exact exists₂_congr (fun a b ↦ by rw [add_comm])
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
i j a b : ℕ
⊢ b + a = k ∧ a = i ∧ b + (n - k) = j ↔ a + b = k ∧ a = i ∧ b + (n - k) = j
[PROOFSTEP]
rw [add_comm]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j
⊢ filter (fun a => a.fst ≤ k) (antidiagonal n) =
    map
      (Embedding.prodMap (Embedding.refl ℕ)
        { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) })
      (antidiagonal k)
[PROOFSTEP]
rw [← map_prodComm_antidiagonal]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j
⊢ filter (fun a => a.fst ≤ k) (map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) (antidiagonal n)) =
    map
      (Embedding.prodMap (Embedding.refl ℕ)
        { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) })
      (antidiagonal k)
[PROOFSTEP]
simp_rw [aux₁, ← map_filter, antidiagonal_filter_snd_le_of_le h, map_map]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j
⊢ map
      (Embedding.trans
        (Embedding.prodMap { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) }
          (Embedding.refl ℕ))
        (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)))
      (antidiagonal k) =
    map
      (Embedding.prodMap (Embedding.refl ℕ)
        { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) })
      (antidiagonal k)
[PROOFSTEP]
ext ⟨i, j⟩
[GOAL]
case a.mk
n k : ℕ
h : k ≤ n
aux₁ : (fun a => a.fst ≤ k) = (fun a => a.snd ≤ k) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j
i j : ℕ
⊢ (i, j) ∈
      map
        (Embedding.trans
          (Embedding.prodMap { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) }
            (Embedding.refl ℕ))
          (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)))
        (antidiagonal k) ↔
    (i, j) ∈
      map
        (Embedding.prodMap (Embedding.refl ℕ)
          { toFun := fun x => x + (n - k), inj' := (_ : Injective fun x => x + (n - k)) })
        (antidiagonal k)
[PROOFSTEP]
simpa using aux₂ i j
[GOAL]
n k : ℕ
h : k ≤ n
⊢ filter (fun a => k ≤ a.fst) (antidiagonal n) =
    map (Embedding.prodMap { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) } (Embedding.refl ℕ))
      (antidiagonal (n - k))
[PROOFSTEP]
ext ⟨i, j⟩
[GOAL]
case a.mk
n k : ℕ
h : k ≤ n
i j : ℕ
⊢ (i, j) ∈ filter (fun a => k ≤ a.fst) (antidiagonal n) ↔
    (i, j) ∈
      map (Embedding.prodMap { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) } (Embedding.refl ℕ))
        (antidiagonal (n - k))
[PROOFSTEP]
suffices : i + j = n ∧ k ≤ i ↔ ∃ a, a + j = n - k ∧ a + k = i
[GOAL]
case a.mk
n k : ℕ
h : k ≤ n
i j : ℕ
this : i + j = n ∧ k ≤ i ↔ ∃ a, a + j = n - k ∧ a + k = i
⊢ (i, j) ∈ filter (fun a => k ≤ a.fst) (antidiagonal n) ↔
    (i, j) ∈
      map (Embedding.prodMap { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) } (Embedding.refl ℕ))
        (antidiagonal (n - k))
[PROOFSTEP]
simpa
[GOAL]
case this
n k : ℕ
h : k ≤ n
i j : ℕ
⊢ i + j = n ∧ k ≤ i ↔ ∃ a, a + j = n - k ∧ a + k = i
[PROOFSTEP]
refine' ⟨fun hi ↦ ⟨i - k, _, tsub_add_cancel_of_le hi.2⟩, _⟩
[GOAL]
case this.refine'_1
n k : ℕ
h : k ≤ n
i j : ℕ
hi : i + j = n ∧ k ≤ i
⊢ i - k + j = n - k
[PROOFSTEP]
rw [← Nat.sub_add_comm hi.2, hi.1]
[GOAL]
case this.refine'_2
n k : ℕ
h : k ≤ n
i j : ℕ
⊢ (∃ a, a + j = n - k ∧ a + k = i) → i + j = n ∧ k ≤ i
[PROOFSTEP]
rintro ⟨l, hl, rfl⟩
[GOAL]
case this.refine'_2.intro.intro
n k : ℕ
h : k ≤ n
j l : ℕ
hl : l + j = n - k
⊢ l + k + j = n ∧ k ≤ l + k
[PROOFSTEP]
refine' ⟨_, Nat.le_add_left k l⟩
[GOAL]
case this.refine'_2.intro.intro
n k : ℕ
h : k ≤ n
j l : ℕ
hl : l + j = n - k
⊢ l + k + j = n
[PROOFSTEP]
rw [add_right_comm, hl]
[GOAL]
case this.refine'_2.intro.intro
n k : ℕ
h : k ≤ n
j l : ℕ
hl : l + j = n - k
⊢ n - k + k = n
[PROOFSTEP]
exact tsub_add_cancel_of_le h
[GOAL]
n k : ℕ
h : k ≤ n
⊢ filter (fun a => k ≤ a.snd) (antidiagonal n) =
    map (Embedding.prodMap (Embedding.refl ℕ) { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) })
      (antidiagonal (n - k))
[PROOFSTEP]
have aux₁ : (fun a ↦ k ≤ a.snd) = (fun a ↦ k ≤ a.fst) ∘ (Equiv.prodComm ℕ ℕ).symm := rfl
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
⊢ filter (fun a => k ≤ a.snd) (antidiagonal n) =
    map (Embedding.prodMap (Embedding.refl ℕ) { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) })
      (antidiagonal (n - k))
[PROOFSTEP]
have aux₂ : ∀ i j, (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j := fun i j ↦ by
  rw [exists_comm]; exact exists₂_congr (fun a b ↦ by rw [add_comm])
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
i j : ℕ
⊢ (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j
[PROOFSTEP]
rw [exists_comm]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
i j : ℕ
⊢ (∃ b a, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j
[PROOFSTEP]
exact exists₂_congr (fun a b ↦ by rw [add_comm])
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
i j a b : ℕ
⊢ b + a = n - k ∧ a = i ∧ b + k = j ↔ a + b = n - k ∧ a = i ∧ b + k = j
[PROOFSTEP]
rw [add_comm]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j
⊢ filter (fun a => k ≤ a.snd) (antidiagonal n) =
    map (Embedding.prodMap (Embedding.refl ℕ) { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) })
      (antidiagonal (n - k))
[PROOFSTEP]
rw [← map_prodComm_antidiagonal]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j
⊢ filter (fun a => k ≤ a.snd) (map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) (antidiagonal n)) =
    map (Embedding.prodMap (Embedding.refl ℕ) { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) })
      (antidiagonal (n - k))
[PROOFSTEP]
simp_rw [aux₁, ← map_filter, antidiagonal_filter_le_fst_of_le h, map_map]
[GOAL]
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j
⊢ map
      (Embedding.trans
        (Embedding.prodMap { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) } (Embedding.refl ℕ))
        (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)))
      (antidiagonal (n - k)) =
    map (Embedding.prodMap (Embedding.refl ℕ) { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) })
      (antidiagonal (n - k))
[PROOFSTEP]
ext ⟨i, j⟩
[GOAL]
case a.mk
n k : ℕ
h : k ≤ n
aux₁ : (fun a => k ≤ a.snd) = (fun a => k ≤ a.fst) ∘ ↑(Equiv.prodComm ℕ ℕ).symm
aux₂ : ∀ (i j : ℕ), (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j
i j : ℕ
⊢ (i, j) ∈
      map
        (Embedding.trans
          (Embedding.prodMap { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) } (Embedding.refl ℕ))
          (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)))
        (antidiagonal (n - k)) ↔
    (i, j) ∈
      map (Embedding.prodMap (Embedding.refl ℕ) { toFun := fun x => x + k, inj' := (_ : Injective fun x => x + k) })
        (antidiagonal (n - k))
[PROOFSTEP]
simpa using aux₂ i j
[GOAL]
⊢ LeftInverse
    (fun x => { fst := x.fst + x.snd, snd := { val := x, property := (_ : x ∈ antidiagonal (x.fst + x.snd)) } })
    fun x => ↑x.snd
[PROOFSTEP]
rintro ⟨n, ⟨k, l⟩, h⟩
[GOAL]
case mk.mk.mk
n k l : ℕ
h : (k, l) ∈ antidiagonal n
⊢ (fun x => { fst := x.fst + x.snd, snd := { val := x, property := (_ : x ∈ antidiagonal (x.fst + x.snd)) } })
      ((fun x => ↑x.snd) { fst := n, snd := { val := (k, l), property := h } }) =
    { fst := n, snd := { val := (k, l), property := h } }
[PROOFSTEP]
rw [mem_antidiagonal] at h
[GOAL]
case mk.mk.mk
n k l : ℕ
h✝ : (k, l) ∈ antidiagonal n
h : (k, l).fst + (k, l).snd = n
⊢ (fun x => { fst := x.fst + x.snd, snd := { val := x, property := (_ : x ∈ antidiagonal (x.fst + x.snd)) } })
      ((fun x => ↑x.snd) { fst := n, snd := { val := (k, l), property := h✝ } }) =
    { fst := n, snd := { val := (k, l), property := h✝ } }
[PROOFSTEP]
exact Sigma.subtype_ext h rfl


[GOAL]
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
A✝ B✝ : C
f : A✝ ⟶ B✝
i : IsIso (F.map f)
⊢ F.map (f ≫ F.preimage (inv (F.map f))) = F.map (𝟙 A✝)
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
A✝ B✝ : C
f : A✝ ⟶ B✝
i : IsIso (F.map f)
⊢ F.map (F.preimage (inv (F.map f)) ≫ f) = F.map (𝟙 B✝)
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
G : D ⥤ E
inst✝¹ : ReflectsIsomorphisms F
inst✝ : ReflectsIsomorphisms G
A✝ B✝ : C
f : A✝ ⟶ B✝
hf : IsIso (G.map (F.map f))
⊢ IsIso f
[PROOFSTEP]
haveI := isIso_of_reflects_iso (F.map f) G
[GOAL]
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
G : D ⥤ E
inst✝¹ : ReflectsIsomorphisms F
inst✝ : ReflectsIsomorphisms G
A✝ B✝ : C
f : A✝ ⟶ B✝
hf : IsIso (G.map (F.map f))
this : IsIso (F.map f)
⊢ IsIso f
[PROOFSTEP]
exact isIso_of_reflects_iso f F
[GOAL]
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
E : Type u₃
inst✝³ : Category.{v₃, u₃} E
inst✝² : Balanced C
F : C ⥤ D
inst✝¹ : ReflectsMonomorphisms F
inst✝ : ReflectsEpimorphisms F
A✝ B✝ : C
f : A✝ ⟶ B✝
hf : IsIso (F.map f)
⊢ IsIso f
[PROOFSTEP]
haveI : Epi f := epi_of_epi_map F inferInstance
[GOAL]
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
E : Type u₃
inst✝³ : Category.{v₃, u₃} E
inst✝² : Balanced C
F : C ⥤ D
inst✝¹ : ReflectsMonomorphisms F
inst✝ : ReflectsEpimorphisms F
A✝ B✝ : C
f : A✝ ⟶ B✝
hf : IsIso (F.map f)
this : Epi f
⊢ IsIso f
[PROOFSTEP]
haveI : Mono f := mono_of_mono_map F inferInstance
[GOAL]
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁴ : Category.{v₂, u₂} D
E : Type u₃
inst✝³ : Category.{v₃, u₃} E
inst✝² : Balanced C
F : C ⥤ D
inst✝¹ : ReflectsMonomorphisms F
inst✝ : ReflectsEpimorphisms F
A✝ B✝ : C
f : A✝ ⟶ B✝
hf : IsIso (F.map f)
this✝ : Epi f
this : Mono f
⊢ IsIso f
[PROOFSTEP]
exact isIso_of_mono_of_epi f


[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ Int.natAbs n
[PROOFSTEP]
let y := rexp (-π * z.im)
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ Int.natAbs n
[PROOFSTEP]
have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ Int.natAbs n
[PROOFSTEP]
refine' (le_of_eq _).trans (_ : y ^ n ^ 2 ≤ _)
[GOAL]
case refine'_1
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ‖cexp (↑π * I * ↑n ^ 2 * z)‖ = y ^ n ^ 2
[PROOFSTEP]
rw [Complex.norm_eq_abs, Complex.abs_exp]
[GOAL]
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
[PROOFSTEP]
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
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ (↑π * I * ↑n ^ 2 * z).re = -π * z.im * ↑n ^ 2
[PROOFSTEP]
rw [(by push_cast ; ring : ↑π * I * (n : ℂ) ^ 2 * z = ↑(π * (n : ℝ) ^ 2) * (z * I)), ofReal_mul_re, mul_I_re]
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ↑π * I * ↑n ^ 2 * z = ↑(π * ↑n ^ 2) * (z * I)
[PROOFSTEP]
push_cast
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ ↑π * I * ↑n ^ 2 * z = ↑π * ↑n ^ 2 * (z * I)
[PROOFSTEP]
ring
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ π * ↑n ^ 2 * -z.im = -π * z.im * ↑n ^ 2
[PROOFSTEP]
ring
[GOAL]
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
[PROOFSTEP]
obtain ⟨m, hm⟩ := Int.eq_ofNat_of_zero_le (sq_nonneg n)
[GOAL]
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
[PROOFSTEP]
rw [this, exp_mul, ← Int.cast_pow, rpow_int_cast, hm, zpow_ofNat]
[GOAL]
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
[PROOFSTEP]
have : n ^ 2 = ↑(n.natAbs ^ 2) := by rw [Nat.cast_pow, Int.natAbs_sq]
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℤ
y : ℝ := rexp (-π * z.im)
h : y < 1
⊢ n ^ 2 = ↑(Int.natAbs n ^ 2)
[PROOFSTEP]
rw [Nat.cast_pow, Int.natAbs_sq]
[GOAL]
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
[PROOFSTEP]
rw [this, zpow_ofNat]
[GOAL]
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
[PROOFSTEP]
exact pow_le_pow_of_le_one (exp_pos _).le h.le ((sq n.natAbs).symm ▸ n.natAbs.le_mul_self)
[GOAL]
R : ℝ
hR : 0 < R
⊢ ∃ bd, Summable bd ∧ ∀ {τ : ℂ}, R ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n
[PROOFSTEP]
let y := rexp (-π * R)
[GOAL]
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
⊢ ∃ bd, Summable bd ∧ ∀ {τ : ℂ}, R ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n
[PROOFSTEP]
have h : y < 1 := exp_lt_one_iff.mpr (mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hR)
[GOAL]
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ ∃ bd, Summable bd ∧ ∀ {τ : ℂ}, R ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n
[PROOFSTEP]
refine' ⟨fun n => y ^ n.natAbs, summable_int_of_summable_nat _ _, fun hτ n => _⟩
[GOAL]
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
[PROOFSTEP]
pick_goal 3
[GOAL]
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
[PROOFSTEP]
refine' (norm_exp_mul_sq_le (hR.trans_le hτ) n).trans _
[GOAL]
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
[PROOFSTEP]
refine' pow_le_pow_of_le_left (exp_pos _).le (Real.exp_le_exp.mpr _) _
[GOAL]
case refine'_3
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
τ✝ : ℂ
hτ : R ≤ τ✝.im
n : ℤ
⊢ -π * τ✝.im ≤ -π * R
[PROOFSTEP]
rwa [mul_le_mul_left_of_neg (neg_lt_zero.mpr pi_pos)]
[GOAL]
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)
[PROOFSTEP]
all_goals simpa only [Int.natAbs_neg, Int.natAbs_ofNat] using summable_geometric_of_lt_1 (Real.exp_pos _).le h
[GOAL]
case refine'_1
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs ↑n
[PROOFSTEP]
simpa only [Int.natAbs_neg, Int.natAbs_ofNat] using summable_geometric_of_lt_1 (Real.exp_pos _).le h
[GOAL]
case refine'_2
R : ℝ
hR : 0 < R
y : ℝ := rexp (-π * R)
h : y < 1
⊢ Summable fun n => y ^ Int.natAbs (-↑n)
[PROOFSTEP]
simpa only [Int.natAbs_neg, Int.natAbs_ofNat] using summable_geometric_of_lt_1 (Real.exp_pos _).le h
[GOAL]
z : ℂ
⊢ jacobiTheta (2 + z) = jacobiTheta z
[PROOFSTEP]
refine' tsum_congr fun n => _
[GOAL]
z : ℂ
n : ℤ
⊢ cexp (↑π * I * ↑n ^ 2 * (2 + z)) = cexp (↑π * I * ↑n ^ 2 * z)
[PROOFSTEP]
suffices cexp (↑π * I * (n : ℂ) ^ 2 * 2) = 1 by rw [mul_add, Complex.exp_add, this, one_mul]
[GOAL]
z : ℂ
n : ℤ
this : cexp (↑π * I * ↑n ^ 2 * 2) = 1
⊢ cexp (↑π * I * ↑n ^ 2 * (2 + z)) = cexp (↑π * I * ↑n ^ 2 * z)
[PROOFSTEP]
rw [mul_add, Complex.exp_add, this, one_mul]
[GOAL]
z : ℂ
n : ℤ
⊢ cexp (↑π * I * ↑n ^ 2 * 2) = 1
[PROOFSTEP]
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]
[GOAL]
z : ℂ
n : ℤ
⊢ ↑π * I * ↑n ^ 2 * 2 = ↑(n ^ 2) * (2 * ↑π * I)
[PROOFSTEP]
push_cast
[GOAL]
z : ℂ
n : ℤ
⊢ ↑π * I * ↑n ^ 2 * 2 = ↑n ^ 2 * (2 * ↑π * I)
[PROOFSTEP]
ring
[GOAL]
τ : ℍ
⊢ jacobiTheta ↑(ModularGroup.T ^ 2 • τ) = jacobiTheta ↑τ
[PROOFSTEP]
suffices ↑(ModularGroup.T ^ 2 • τ) = (2 : ℂ) + ↑τ by simp_rw [this, jacobiTheta_two_add]
[GOAL]
τ : ℍ
this : ↑(ModularGroup.T ^ 2 • τ) = 2 + ↑τ
⊢ jacobiTheta ↑(ModularGroup.T ^ 2 • τ) = jacobiTheta ↑τ
[PROOFSTEP]
simp_rw [this, jacobiTheta_two_add]
[GOAL]
τ : ℍ
⊢ ↑(ModularGroup.T ^ 2 • τ) = 2 + ↑τ
[PROOFSTEP]
have : ModularGroup.T ^ (2 : ℕ) = ModularGroup.T ^ (2 : ℤ) := by rfl
[GOAL]
τ : ℍ
⊢ ModularGroup.T ^ 2 = ModularGroup.T ^ 2
[PROOFSTEP]
rfl
[GOAL]
τ : ℍ
this : ModularGroup.T ^ 2 = ModularGroup.T ^ 2
⊢ ↑(ModularGroup.T ^ 2 • τ) = 2 + ↑τ
[PROOFSTEP]
simp_rw [this, UpperHalfPlane.modular_T_zpow_smul, UpperHalfPlane.coe_vadd]
[GOAL]
τ : ℍ
this : ModularGroup.T ^ 2 = ModularGroup.T ^ 2
⊢ ↑↑2 + ↑τ = 2 + ↑τ
[PROOFSTEP]
norm_cast
[GOAL]
τ : ℍ
⊢ jacobiTheta ↑(ModularGroup.S • τ) = (-I * ↑τ) ^ (1 / 2) * jacobiTheta ↑τ
[PROOFSTEP]
unfold jacobiTheta
[GOAL]
τ : ℍ
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑(ModularGroup.S • τ)) =
    (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
rw [UpperHalfPlane.modular_S_smul, UpperHalfPlane.coe_mk]
[GOAL]
τ : ℍ
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
have ha : 0 < (-I * τ).re :=
  by
  rw [neg_mul, neg_re, mul_re, I_re, I_im, zero_mul, one_mul, zero_sub, neg_neg]
  exact τ.im_pos
[GOAL]
τ : ℍ
⊢ 0 < (-I * ↑τ).re
[PROOFSTEP]
rw [neg_mul, neg_re, mul_re, I_re, I_im, zero_mul, one_mul, zero_sub, neg_neg]
[GOAL]
τ : ℍ
⊢ 0 < (↑τ).im
[PROOFSTEP]
exact τ.im_pos
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
have ha' : (-I * τ) ^ (1 / 2 : ℂ) ≠ 0 := by
  rw [Ne.def, cpow_eq_zero_iff]
  contrapose! ha
  rw [ha.1, zero_re]
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
⊢ (-I * ↑τ) ^ (1 / 2) ≠ 0
[PROOFSTEP]
rw [Ne.def, cpow_eq_zero_iff]
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
⊢ ¬(-I * ↑τ = 0 ∧ 1 / 2 ≠ 0)
[PROOFSTEP]
contrapose! ha
[GOAL]
τ : ℍ
ha : -I * ↑τ = 0 ∧ 1 / 2 ≠ 0
⊢ (-I * ↑τ).re ≤ 0
[PROOFSTEP]
rw [ha.1, zero_re]
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
have hτ : (τ : ℂ) ≠ 0 := τ.ne_zero
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
have := Complex.tsum_exp_neg_mul_int_sq ha
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this :
  ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2) = 1 / (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2)
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
rw [mul_comm ((1 : ℂ) / _) _, mul_one_div, eq_div_iff ha', mul_comm _ (_ ^ _), eq_comm] at this
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this : ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
have expo1 : ∀ n : ℤ, -↑π / (-I * ↑τ) * (n : ℂ) ^ 2 = ↑π * I * (n : ℂ) ^ 2 * (-↑τ)⁻¹ :=
  by
  intro n
  field_simp [hτ, I_ne_zero]
  ring_nf
  rw [I_sq, mul_neg, mul_one, neg_neg]
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this : ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
⊢ ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
[PROOFSTEP]
intro n
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this : ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
n : ℤ
⊢ -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
[PROOFSTEP]
field_simp [hτ, I_ne_zero]
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this : ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
n : ℤ
⊢ ↑π * ↑n ^ 2 * ↑τ = -(↑π * I * ↑n ^ 2 * (I * ↑τ))
[PROOFSTEP]
ring_nf
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this : ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
n : ℤ
⊢ ↑π * ↑n ^ 2 * ↑τ = -(↑π * ↑n ^ 2 * ↑τ * I ^ 2)
[PROOFSTEP]
rw [I_sq, mul_neg, mul_one, neg_neg]
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
this : ∑' (n : ℤ), cexp (-↑π / (-I * ↑τ) * ↑n ^ 2) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
expo1 : ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
simp_rw [expo1] at this
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
expo1 : ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
this : ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
have expo2 : ∀ n : ℤ, -↑π * (-I * ↑τ) * (n : ℂ) ^ 2 = ↑π * I * (n : ℂ) ^ 2 * ↑τ :=
  by
  intro n
  ring_nf
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
expo1 : ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
this : ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
⊢ ∀ (n : ℤ), -↑π * (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * ↑τ
[PROOFSTEP]
intro n
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
expo1 : ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
this : ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
n : ℤ
⊢ -↑π * (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * ↑τ
[PROOFSTEP]
ring_nf
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
expo1 : ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
this : ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (-↑π * (-I * ↑τ) * ↑n ^ 2)
expo2 : ∀ (n : ℤ), -↑π * (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * ↑τ
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
simp_rw [expo2] at this
[GOAL]
τ : ℍ
ha : 0 < (-I * ↑τ).re
ha' : (-I * ↑τ) ^ (1 / 2) ≠ 0
hτ : ↑τ ≠ 0
expo1 : ∀ (n : ℤ), -↑π / (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * (-↑τ)⁻¹
expo2 : ∀ (n : ℤ), -↑π * (-I * ↑τ) * ↑n ^ 2 = ↑π * I * ↑n ^ 2 * ↑τ
this : ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
⊢ ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * (-↑τ)⁻¹) = (-I * ↑τ) ^ (1 / 2) * ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * ↑τ)
[PROOFSTEP]
exact this
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ HasSum (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z)) ((jacobiTheta z - 1) / 2)
[PROOFSTEP]
have := (summable_exp_mul_sq hz).hasSum.sum_nat_of_sum_int
[GOAL]
z : ℂ
hz : 0 < z.im
this :
  HasSum (fun n => cexp (↑π * I * ↑↑n ^ 2 * z) + cexp (↑π * I * ↑(-↑n) ^ 2 * z))
    (∑' (b : ℤ), cexp (↑π * I * ↑b ^ 2 * z) + cexp (↑π * I * ↑0 ^ 2 * z))
⊢ HasSum (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z)) ((jacobiTheta z - 1) / 2)
[PROOFSTEP]
rw [← @hasSum_nat_add_iff' ℂ _ _ _ _ 1] at this
[GOAL]
z : ℂ
hz : 0 < z.im
this :
  HasSum (fun n => cexp (↑π * I * ↑↑(n + 1) ^ 2 * z) + cexp (↑π * I * ↑(-↑(n + 1)) ^ 2 * z))
    (∑' (b : ℤ), cexp (↑π * I * ↑b ^ 2 * z) + cexp (↑π * I * ↑0 ^ 2 * z) -
      ∑ i in Finset.range 1, (cexp (↑π * I * ↑↑i ^ 2 * z) + cexp (↑π * I * ↑(-↑i) ^ 2 * z)))
⊢ HasSum (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z)) ((jacobiTheta z - 1) / 2)
[PROOFSTEP]
simp_rw [Finset.sum_range_one, Int.cast_neg, Int.cast_ofNat, Nat.cast_zero, neg_zero, Int.cast_zero, sq (0 : ℂ),
  mul_zero, zero_mul, neg_sq, ← mul_two, Complex.exp_zero, add_sub_assoc, (by norm_num : (1 : ℂ) - 1 * 2 = -1), ←
  sub_eq_add_neg, Nat.cast_add, Nat.cast_one] at this
[GOAL]
z : ℂ
hz : 0 < z.im
this : HasSum (fun n => cexp (↑π * I * ↑(n + 1) ^ 2 * z) * 2) (∑' (b : ℤ), cexp (↑π * I * ↑b ^ 2 * z) + (1 - 1 * 2))
⊢ 1 - 1 * 2 = -1
[PROOFSTEP]
norm_num
[GOAL]
z : ℂ
hz : 0 < z.im
this : HasSum (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z) * 2) (∑' (b : ℤ), cexp (↑π * I * ↑b ^ 2 * z) - 1)
⊢ HasSum (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z)) ((jacobiTheta z - 1) / 2)
[PROOFSTEP]
convert this.div_const 2 using 1
[GOAL]
case h.e'_5
z : ℂ
hz : 0 < z.im
this : HasSum (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z) * 2) (∑' (b : ℤ), cexp (↑π * I * ↑b ^ 2 * z) - 1)
⊢ (fun n => cexp (↑π * I * (↑n + 1) ^ 2 * z)) = fun i => cexp (↑π * I * (↑i + 1) ^ 2 * z) * 2 / 2
[PROOFSTEP]
simp_rw [mul_div_cancel (G₀ := ℂ) _ two_ne_zero]
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ jacobiTheta z = 1 + 2 * ∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)
[PROOFSTEP]
rw [(hasSum_nat_jacobiTheta hz).tsum_eq, mul_div_cancel' _ (two_ne_zero' ℂ), ← add_sub_assoc, add_sub_cancel']
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ ‖jacobiTheta z - 1‖ ≤ 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im)
[PROOFSTEP]
suffices ‖∑' n : ℕ, cexp (π * I * ((n : ℂ) + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im)) by
  calc
    ‖jacobiTheta z - 1‖ = ↑2 * ‖∑' n : ℕ, cexp (π * I * ((n : ℂ) + 1) ^ 2 * z)‖ := by
      rw [sub_eq_iff_eq_add'.mpr (jacobiTheta_eq_tsum_nat hz), norm_mul, Complex.norm_eq_abs, Complex.abs_two]
    _ ≤ 2 * (rexp (-π * z.im) / (1 - rexp (-π * z.im))) := by rwa [mul_le_mul_left (zero_lt_two' ℝ)]
    _ = 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im) := by rw [div_mul_comm, mul_comm]
[GOAL]
z : ℂ
hz : 0 < z.im
this : ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
⊢ ‖jacobiTheta z - 1‖ ≤ 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im)
[PROOFSTEP]
calc
  ‖jacobiTheta z - 1‖ = ↑2 * ‖∑' n : ℕ, cexp (π * I * ((n : ℂ) + 1) ^ 2 * z)‖ := by
    rw [sub_eq_iff_eq_add'.mpr (jacobiTheta_eq_tsum_nat hz), norm_mul, Complex.norm_eq_abs, Complex.abs_two]
  _ ≤ 2 * (rexp (-π * z.im) / (1 - rexp (-π * z.im))) := by rwa [mul_le_mul_left (zero_lt_two' ℝ)]
  _ = 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im) := by rw [div_mul_comm, mul_comm]
[GOAL]
z : ℂ
hz : 0 < z.im
this : ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
⊢ ‖jacobiTheta z - 1‖ = 2 * ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖
[PROOFSTEP]
rw [sub_eq_iff_eq_add'.mpr (jacobiTheta_eq_tsum_nat hz), norm_mul, Complex.norm_eq_abs, Complex.abs_two]
[GOAL]
z : ℂ
hz : 0 < z.im
this : ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
⊢ 2 * ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ 2 * (rexp (-π * z.im) / (1 - rexp (-π * z.im)))
[PROOFSTEP]
rwa [mul_le_mul_left (zero_lt_two' ℝ)]
[GOAL]
z : ℂ
hz : 0 < z.im
this : ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
⊢ 2 * (rexp (-π * z.im) / (1 - rexp (-π * z.im))) = 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im)
[PROOFSTEP]
rw [div_mul_comm, mul_comm]
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
[PROOFSTEP]
have : ∀ n : ℕ, ‖cexp (π * I * ((n : ℂ) + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1) :=
  by
  intro n
  simpa only [Int.cast_add, Int.cast_one] using norm_exp_mul_sq_le hz (n + 1)
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ ∀ (n : ℕ), ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
[PROOFSTEP]
intro n
[GOAL]
z : ℂ
hz : 0 < z.im
n : ℕ
⊢ ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
[PROOFSTEP]
simpa only [Int.cast_add, Int.cast_one] using norm_exp_mul_sq_le hz (n + 1)
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (n : ℕ), ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
⊢ ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
[PROOFSTEP]
have s : HasSum (fun n : ℕ => rexp (-π * z.im) ^ (n + 1)) (rexp (-π * z.im) / (1 - rexp (-π * z.im))) :=
  by
  simp_rw [pow_succ, div_eq_mul_inv, hasSum_mul_left_iff (Real.exp_ne_zero _)]
  exact
    hasSum_geometric_of_lt_1 (exp_pos (-π * z.im)).le
      (exp_lt_one_iff.mpr <| mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (n : ℕ), ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
⊢ HasSum (fun n => rexp (-π * z.im) ^ (n + 1)) (rexp (-π * z.im) / (1 - rexp (-π * z.im)))
[PROOFSTEP]
simp_rw [pow_succ, div_eq_mul_inv, hasSum_mul_left_iff (Real.exp_ne_zero _)]
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (n : ℕ), ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
⊢ HasSum (fun i => rexp (-π * z.im) ^ i) (1 - rexp (-π * z.im))⁻¹
[PROOFSTEP]
exact
  hasSum_geometric_of_lt_1 (exp_pos (-π * z.im)).le
    (exp_lt_one_iff.mpr <| mul_neg_of_neg_of_pos (neg_lt_zero.mpr pi_pos) hz)
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (n : ℕ), ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
s : HasSum (fun n => rexp (-π * z.im) ^ (n + 1)) (rexp (-π * z.im) / (1 - rexp (-π * z.im)))
⊢ ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
[PROOFSTEP]
have aux : Summable fun n : ℕ => ‖cexp (π * I * ((n : ℂ) + 1) ^ 2 * z)‖ :=
  summable_of_nonneg_of_le (fun n => norm_nonneg _) this s.summable
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (n : ℕ), ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) ^ (n + 1)
s : HasSum (fun n => rexp (-π * z.im) ^ (n + 1)) (rexp (-π * z.im) / (1 - rexp (-π * z.im)))
aux : Summable fun n => ‖cexp (↑π * I * (↑n + 1) ^ 2 * z)‖
⊢ ‖∑' (n : ℕ), cexp (↑π * I * (↑n + 1) ^ 2 * z)‖ ≤ rexp (-π * z.im) / (1 - rexp (-π * z.im))
[PROOFSTEP]
exact (norm_tsum_le_tsum_norm aux).trans ((tsum_mono aux s.summable this).trans (le_of_eq s.tsum_eq))
[GOAL]
⊢ (fun τ => jacobiTheta τ - 1) =O[comap im atTop] fun τ => rexp (-π * τ.im)
[PROOFSTEP]
simp_rw [IsBigO, IsBigOWith, Filter.eventually_comap, Filter.eventually_atTop]
[GOAL]
⊢ ∃ c a, ∀ (b : ℝ), b ≥ a → ∀ (a : ℂ), a.im = b → ‖jacobiTheta a - 1‖ ≤ c * ‖rexp (-π * a.im)‖
[PROOFSTEP]
refine'
  ⟨2 / (1 - rexp (-π)), 1, fun y hy z hz =>
    (norm_jacobiTheta_sub_one_le (hz.symm ▸ zero_lt_one.trans_le hy : 0 < im z)).trans _⟩
[GOAL]
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im) ≤ 2 / (1 - rexp (-π)) * ‖rexp (-π * z.im)‖
[PROOFSTEP]
rw [Real.norm_eq_abs, Real.abs_exp]
[GOAL]
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 2 / (1 - rexp (-π * z.im)) * rexp (-π * z.im) ≤ 2 / (1 - rexp (-π)) * rexp (-π * z.im)
[PROOFSTEP]
refine' mul_le_mul_of_nonneg_right _ (exp_pos _).le
[GOAL]
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 2 / (1 - rexp (-π * z.im)) ≤ 2 / (1 - rexp (-π))
[PROOFSTEP]
rw [div_le_div_left (zero_lt_two' ℝ), sub_le_sub_iff_left, exp_le_exp, neg_mul, neg_le_neg_iff]
[GOAL]
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ π ≤ π * z.im
[PROOFSTEP]
exact le_mul_of_one_le_right pi_pos.le (hz.symm ▸ hy)
[GOAL]
case hb
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 0 < 1 - rexp (-π * z.im)
[PROOFSTEP]
rw [sub_pos, exp_lt_one_iff, neg_mul, neg_lt_zero]
[GOAL]
case hb
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 0 < π * z.im
[PROOFSTEP]
exact mul_pos pi_pos (hz.symm ▸ zero_lt_one.trans_le hy)
[GOAL]
case hc
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 0 < 1 - rexp (-π)
[PROOFSTEP]
rw [sub_pos, exp_lt_one_iff, neg_lt_zero]
[GOAL]
case hc
y : ℝ
hy : y ≥ 1
z : ℂ
hz : z.im = y
⊢ 0 < π
[PROOFSTEP]
exact pi_pos
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ DifferentiableAt ℂ jacobiTheta z
[PROOFSTEP]
suffices
  ∀ (y : ℝ) (_ : 0 < y), DifferentiableOn ℂ (fun z => ∑' n : ℤ, cexp (π * I * (n : ℂ) ^ 2 * z)) {w : ℂ | y < im w}
  by
  let ⟨y, hy, hy'⟩ := exists_between hz
  exact (this y hy).differentiableAt ((Complex.continuous_im.isOpen_preimage _ isOpen_Ioi).mem_nhds hy')
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (y : ℝ), 0 < y → DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
⊢ DifferentiableAt ℂ jacobiTheta z
[PROOFSTEP]
let ⟨y, hy, hy'⟩ := exists_between hz
[GOAL]
z : ℂ
hz : 0 < z.im
this : ∀ (y : ℝ), 0 < y → DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
y : ℝ
hy : 0 < y
hy' : y < z.im
⊢ DifferentiableAt ℂ jacobiTheta z
[PROOFSTEP]
exact (this y hy).differentiableAt ((Complex.continuous_im.isOpen_preimage _ isOpen_Ioi).mem_nhds hy')
[GOAL]
z : ℂ
hz : 0 < z.im
⊢ ∀ (y : ℝ), 0 < y → DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
[PROOFSTEP]
intro y hy
[GOAL]
z : ℂ
hz : 0 < z.im
y : ℝ
hy : 0 < y
⊢ DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
[PROOFSTEP]
have h1 :
  ∀ (n : ℤ) (w : ℂ) (_ : y < im w),
    DifferentiableWithinAt ℂ (fun v : ℂ => cexp (π * I * (n : ℂ) ^ 2 * v)) {z : ℂ | y < im z} w :=
  fun n w _ => (differentiableAt_id.const_mul _).cexp.differentiableWithinAt
[GOAL]
z : ℂ
hz : 0 < z.im
y : ℝ
hy : 0 < y
h1 : ∀ (n : ℤ) (w : ℂ), y < w.im → DifferentiableWithinAt ℂ (fun v => cexp (↑π * I * ↑n ^ 2 * v)) {z | y < z.im} w
⊢ DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
[PROOFSTEP]
have h2 : IsOpen {w : ℂ | y < im w} := continuous_im.isOpen_preimage _ isOpen_Ioi
[GOAL]
z : ℂ
hz : 0 < z.im
y : ℝ
hy : 0 < y
h1 : ∀ (n : ℤ) (w : ℂ), y < w.im → DifferentiableWithinAt ℂ (fun v => cexp (↑π * I * ↑n ^ 2 * v)) {z | y < z.im} w
h2 : IsOpen {w | y < w.im}
⊢ DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
[PROOFSTEP]
obtain ⟨bd, bd_s, le_bd⟩ := exists_summable_bound_exp_mul_sq hy
[GOAL]
case intro.intro
z : ℂ
hz : 0 < z.im
y : ℝ
hy : 0 < y
h1 : ∀ (n : ℤ) (w : ℂ), y < w.im → DifferentiableWithinAt ℂ (fun v => cexp (↑π * I * ↑n ^ 2 * v)) {z | y < z.im} w
h2 : IsOpen {w | y < w.im}
bd : ℤ → ℝ
bd_s : Summable bd
le_bd : ∀ {τ : ℂ}, y ≤ τ.im → ∀ (n : ℤ), ‖cexp (↑π * I * ↑n ^ 2 * τ)‖ ≤ bd n
⊢ DifferentiableOn ℂ (fun z => ∑' (n : ℤ), cexp (↑π * I * ↑n ^ 2 * z)) {w | y < w.im}
[PROOFSTEP]
exact differentiableOn_tsum_of_summable_norm bd_s h1 h2 fun i w hw => le_bd (le_of_lt hw) i


[GOAL]
n : ℕ
⊢ bernoulli n = ∑ i in range (n + 1), ↑(monomial i) (_root_.bernoulli (n - i) * ↑(Nat.choose n i))
[PROOFSTEP]
rw [← sum_range_reflect, add_succ_sub_one, add_zero, bernoulli]
[GOAL]
n : ℕ
⊢ ∑ i in range (n + 1), ↑(monomial (n - i)) (_root_.bernoulli i * ↑(Nat.choose n i)) =
    ∑ j in range (n + 1), ↑(monomial (n - j)) (_root_.bernoulli (n - (n - j)) * ↑(Nat.choose n (n - j)))
[PROOFSTEP]
apply sum_congr rfl
[GOAL]
n : ℕ
⊢ ∀ (x : ℕ),
    x ∈ range (n + 1) →
      ↑(monomial (n - x)) (_root_.bernoulli x * ↑(Nat.choose n x)) =
        ↑(monomial (n - x)) (_root_.bernoulli (n - (n - x)) * ↑(Nat.choose n (n - x)))
[PROOFSTEP]
rintro x hx
[GOAL]
n x : ℕ
hx : x ∈ range (n + 1)
⊢ ↑(monomial (n - x)) (_root_.bernoulli x * ↑(Nat.choose n x)) =
    ↑(monomial (n - x)) (_root_.bernoulli (n - (n - x)) * ↑(Nat.choose n (n - x)))
[PROOFSTEP]
rw [mem_range_succ_iff] at hx
[GOAL]
n x : ℕ
hx : x ≤ n
⊢ ↑(monomial (n - x)) (_root_.bernoulli x * ↑(Nat.choose n x)) =
    ↑(monomial (n - x)) (_root_.bernoulli (n - (n - x)) * ↑(Nat.choose n (n - x)))
[PROOFSTEP]
rw [choose_symm hx, tsub_tsub_cancel_of_le hx]
[GOAL]
⊢ bernoulli 0 = 1
[PROOFSTEP]
simp [bernoulli]
[GOAL]
n : ℕ
⊢ eval 0 (bernoulli n) = _root_.bernoulli n
[PROOFSTEP]
rw [bernoulli, eval_finset_sum, sum_range_succ]
[GOAL]
n : ℕ
⊢ ∑ x in range n, eval 0 (↑(monomial (n - x)) (_root_.bernoulli x * ↑(Nat.choose n x))) +
      eval 0 (↑(monomial (n - n)) (_root_.bernoulli n * ↑(Nat.choose n n))) =
    _root_.bernoulli n
[PROOFSTEP]
have : (∑ x : ℕ in range n, _root_.bernoulli x * n.choose x * 0 ^ (n - x)) = 0 :=
  by
  apply sum_eq_zero <| fun x hx => _
  intros x hx
  have h : x < n := (mem_range.1 hx)
  simp [h]
[GOAL]
n : ℕ
⊢ ∑ x in range n, _root_.bernoulli x * ↑(Nat.choose n x) * 0 ^ (n - x) = 0
[PROOFSTEP]
apply sum_eq_zero <| fun x hx => _
[GOAL]
n : ℕ
⊢ ∀ (x : ℕ), x ∈ range n → _root_.bernoulli x * ↑(Nat.choose n x) * 0 ^ (n - x) = 0
[PROOFSTEP]
intros x hx
[GOAL]
n x : ℕ
hx : x ∈ range n
⊢ _root_.bernoulli x * ↑(Nat.choose n x) * 0 ^ (n - x) = 0
[PROOFSTEP]
have h : x < n := (mem_range.1 hx)
[GOAL]
n x : ℕ
hx : x ∈ range n
h : x < n
⊢ _root_.bernoulli x * ↑(Nat.choose n x) * 0 ^ (n - x) = 0
[PROOFSTEP]
simp [h]
[GOAL]
n : ℕ
this : ∑ x in range n, _root_.bernoulli x * ↑(Nat.choose n x) * 0 ^ (n - x) = 0
⊢ ∑ x in range n, eval 0 (↑(monomial (n - x)) (_root_.bernoulli x * ↑(Nat.choose n x))) +
      eval 0 (↑(monomial (n - n)) (_root_.bernoulli n * ↑(Nat.choose n n))) =
    _root_.bernoulli n
[PROOFSTEP]
simp [this]
[GOAL]
n : ℕ
⊢ eval 1 (bernoulli n) = bernoulli' n
[PROOFSTEP]
simp only [bernoulli, eval_finset_sum]
[GOAL]
n : ℕ
⊢ ∑ i in range (n + 1), eval 1 (↑(monomial (n - i)) (_root_.bernoulli i * ↑(Nat.choose n i))) = bernoulli' n
[PROOFSTEP]
simp only [← succ_eq_add_one, sum_range_succ, mul_one, cast_one, choose_self, (_root_.bernoulli _).mul_comm,
  sum_bernoulli, one_pow, mul_one, eval_C, eval_monomial, one_mul]
[GOAL]
n : ℕ
⊢ (if n = 1 then 1 else 0) + _root_.bernoulli n = bernoulli' n
[PROOFSTEP]
by_cases h : n = 1
[GOAL]
case pos
n : ℕ
h : n = 1
⊢ (if n = 1 then 1 else 0) + _root_.bernoulli n = bernoulli' n
[PROOFSTEP]
simp [h]
[GOAL]
case pos
n : ℕ
h : n = 1
⊢ 1 + -1 / 2 = 2⁻¹
[PROOFSTEP]
norm_num
[GOAL]
case neg
n : ℕ
h : ¬n = 1
⊢ (if n = 1 then 1 else 0) + _root_.bernoulli n = bernoulli' n
[PROOFSTEP]
simp [h]
[GOAL]
case neg
n : ℕ
h : ¬n = 1
⊢ _root_.bernoulli n = bernoulli' n
[PROOFSTEP]
exact bernoulli_eq_bernoulli'_of_ne_one h
[GOAL]
k : ℕ
⊢ ↑derivative (bernoulli (k + 1)) = (↑k + 1) * bernoulli k
[PROOFSTEP]
simp_rw [bernoulli, derivative_sum, derivative_monomial, Nat.sub_sub, Nat.add_sub_add_right]
  -- LHS sum has an extra term, but the coefficient is zero:
[GOAL]
k : ℕ
⊢ ∑ x in range (k + 1 + 1), ↑(monomial (k - x)) (_root_.bernoulli x * ↑(Nat.choose (k + 1) x) * ↑(k + 1 - x)) =
    (↑k + 1) * ∑ x in range (k + 1), ↑(monomial (k - x)) (_root_.bernoulli x * ↑(Nat.choose k x))
[PROOFSTEP]
rw [range_add_one, sum_insert not_mem_range_self, tsub_self, cast_zero, mul_zero, map_zero, zero_add, mul_sum]
  -- the rest of the sum is termwise equal:
[GOAL]
k : ℕ
⊢ ∑ x in range (k + 1), ↑(monomial (k - x)) (_root_.bernoulli x * ↑(Nat.choose (k + 1) x) * ↑(k + 1 - x)) =
    ∑ x in range (k + 1), (↑k + 1) * ↑(monomial (k - x)) (_root_.bernoulli x * ↑(Nat.choose k x))
[PROOFSTEP]
refine' sum_congr (by rfl) fun m _ => _
[GOAL]
k : ℕ
⊢ range (k + 1) = range (k + 1)
[PROOFSTEP]
rfl
[GOAL]
k m : ℕ
x✝ : m ∈ range (k + 1)
⊢ ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose (k + 1) m) * ↑(k + 1 - m)) =
    (↑k + 1) * ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose k m))
[PROOFSTEP]
conv_rhs => rw [← Nat.cast_one, ← Nat.cast_add, ← C_eq_nat_cast, C_mul_monomial, mul_comm]
[GOAL]
k m : ℕ
x✝ : m ∈ range (k + 1)
| (↑k + 1) * ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose k m))
[PROOFSTEP]
rw [← Nat.cast_one, ← Nat.cast_add, ← C_eq_nat_cast, C_mul_monomial, mul_comm]
[GOAL]
k m : ℕ
x✝ : m ∈ range (k + 1)
| (↑k + 1) * ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose k m))
[PROOFSTEP]
rw [← Nat.cast_one, ← Nat.cast_add, ← C_eq_nat_cast, C_mul_monomial, mul_comm]
[GOAL]
k m : ℕ
x✝ : m ∈ range (k + 1)
| (↑k + 1) * ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose k m))
[PROOFSTEP]
rw [← Nat.cast_one, ← Nat.cast_add, ← C_eq_nat_cast, C_mul_monomial, mul_comm]
[GOAL]
k m : ℕ
x✝ : m ∈ range (k + 1)
⊢ ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose (k + 1) m) * ↑(k + 1 - m)) =
    ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose k m) * ↑(k + 1))
[PROOFSTEP]
rw [mul_assoc, mul_assoc, ← Nat.cast_mul, ← Nat.cast_mul]
[GOAL]
k m : ℕ
x✝ : m ∈ range (k + 1)
⊢ ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose (k + 1) m * (k + 1 - m))) =
    ↑(monomial (k - m)) (_root_.bernoulli m * ↑(Nat.choose k m * (k + 1)))
[PROOFSTEP]
congr 3
[GOAL]
case h.e_6.h.e_a.e_a
k m : ℕ
x✝ : m ∈ range (k + 1)
⊢ Nat.choose (k + 1) m * (k + 1 - m) = Nat.choose k m * (k + 1)
[PROOFSTEP]
rw [(choose_mul_succ_eq k m).symm, mul_comm]
[GOAL]
k : ℕ
⊢ ↑derivative (bernoulli k) = ↑k * bernoulli (k - 1)
[PROOFSTEP]
cases k with
| zero => rw [Nat.cast_zero, zero_mul, bernoulli_zero, derivative_one]
| succ k => exact_mod_cast derivative_bernoulli_add_one k
[GOAL]
k : ℕ
⊢ ↑derivative (bernoulli k) = ↑k * bernoulli (k - 1)
[PROOFSTEP]
cases k with
| zero => rw [Nat.cast_zero, zero_mul, bernoulli_zero, derivative_one]
| succ k => exact_mod_cast derivative_bernoulli_add_one k
[GOAL]
case zero
⊢ ↑derivative (bernoulli Nat.zero) = ↑Nat.zero * bernoulli (Nat.zero - 1)
[PROOFSTEP]

| zero => rw [Nat.cast_zero, zero_mul, bernoulli_zero, derivative_one]
[GOAL]
case zero
⊢ ↑derivative (bernoulli Nat.zero) = ↑Nat.zero * bernoulli (Nat.zero - 1)
[PROOFSTEP]
rw [Nat.cast_zero, zero_mul, bernoulli_zero, derivative_one]
[GOAL]
case succ
k : ℕ
⊢ ↑derivative (bernoulli (succ k)) = ↑(succ k) * bernoulli (succ k - 1)
[PROOFSTEP]

| succ k => exact_mod_cast derivative_bernoulli_add_one k
[GOAL]
case succ
k : ℕ
⊢ ↑derivative (bernoulli (succ k)) = ↑(succ k) * bernoulli (succ k - 1)
[PROOFSTEP]
exact_mod_cast derivative_bernoulli_add_one k
[GOAL]
n : ℕ
⊢ ∑ k in range (n + 1), ↑(Nat.choose (n + 1) k) • bernoulli k = ↑(monomial n) (↑n + 1)
[PROOFSTEP]
simp_rw [bernoulli_def, Finset.smul_sum, Finset.range_eq_Ico, ← Finset.sum_Ico_Ico_comm, Finset.sum_Ico_eq_sum_range]
[GOAL]
n : ℕ
⊢ ∑ k in range (n + 1 - 0),
      ∑ k_1 in range (n + 1 - (0 + k)),
        ↑(Nat.choose (n + 1) (0 + k + k_1)) •
          ↑(monomial (0 + k)) (_root_.bernoulli (0 + k + k_1 - (0 + k)) * ↑(Nat.choose (0 + k + k_1) (0 + k))) =
    ↑(monomial n) (↑n + 1)
[PROOFSTEP]
simp only [add_tsub_cancel_left, tsub_zero, zero_add, map_add]
[GOAL]
n : ℕ
⊢ ∑ x in range (n + 1),
      ∑ x_1 in range (n + 1 - x),
        ↑(Nat.choose (n + 1) (x + x_1)) • ↑(monomial x) (_root_.bernoulli x_1 * ↑(Nat.choose (x + x_1) x)) =
    ↑(monomial n) ↑n + ↑(monomial n) 1
[PROOFSTEP]
simp_rw [smul_monomial, mul_comm (_root_.bernoulli _) _, smul_eq_mul, ← mul_assoc]
[GOAL]
n : ℕ
⊢ ∑ x in range (n + 1),
      ∑ x_1 in range (n + 1 - x),
        ↑(monomial x) (↑(Nat.choose (n + 1) (x + x_1)) * ↑(Nat.choose (x + x_1) x) * _root_.bernoulli x_1) =
    ↑(monomial n) ↑n + ↑(monomial n) 1
[PROOFSTEP]
conv_lhs =>
  apply_congr
  ·skip
  ·conv =>
      apply_congr
      ·skip
      ·rw [← Nat.cast_mul,
          choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption))
            (le.intro rfl),
          Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
n : ℕ
| ∑ x in range (n + 1),
    ∑ x_1 in range (n + 1 - x),
      ↑(monomial x) (↑(Nat.choose (n + 1) (x + x_1)) * ↑(Nat.choose (x + x_1) x) * _root_.bernoulli x_1)
[PROOFSTEP]
  apply_congr
  ·skip
  ·conv =>
      apply_congr
      ·skip
      ·rw [← Nat.cast_mul,
          choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption))
            (le.intro rfl),
          Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
n : ℕ
| ∑ x in range (n + 1),
    ∑ x_1 in range (n + 1 - x),
      ↑(monomial x) (↑(Nat.choose (n + 1) (x + x_1)) * ↑(Nat.choose (x + x_1) x) * _root_.bernoulli x_1)
[PROOFSTEP]
  apply_congr
  ·skip
  ·conv =>
      apply_congr
      ·skip
      ·rw [← Nat.cast_mul,
          choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption))
            (le.intro rfl),
          Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
n : ℕ
| ∑ x in range (n + 1),
    ∑ x_1 in range (n + 1 - x),
      ↑(monomial x) (↑(Nat.choose (n + 1) (x + x_1)) * ↑(Nat.choose (x + x_1) x) * _root_.bernoulli x_1)
[PROOFSTEP]
apply_congr
[GOAL]
case h
n : ℕ
⊢ range (n + 1) = ?s₂
case a
n x✝ : ℕ
a✝ : x✝ ∈ ?s₂
⊢ ∑ x in range (n + 1 - x✝),
      ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x) =
    ?g x✝
[PROOFSTEP]
·skip
[GOAL]
case h
n : ℕ
⊢ range (n + 1) = ?s₂
[PROOFSTEP]
skip
[GOAL]
case h
n : ℕ
⊢ range (n + 1) = ?s₂
[PROOFSTEP]
skip
[GOAL]
case h
n : ℕ
⊢ range (n + 1) = ?s₂
[PROOFSTEP]
skip
[GOAL]
case a
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ ∑ x in range (n + 1 - x✝),
      ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x) =
    ?g x✝
[PROOFSTEP]
·conv =>
    apply_congr
    ·skip
    ·rw [← Nat.cast_mul,
        choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption))
          (le.intro rfl),
        Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
case a
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ ∑ x in range (n + 1 - x✝),
      ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x) =
    ?g x✝
[PROOFSTEP]
conv =>
    apply_congr
    ·skip
    ·rw [← Nat.cast_mul,
        choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption))
          (le.intro rfl),
        Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
case a
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ ∑ x in range (n + 1 - x✝),
      ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x) =
    ?g x✝
[PROOFSTEP]
conv =>
    apply_congr
    ·skip
    ·rw [← Nat.cast_mul,
        choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption))
          (le.intro rfl),
        Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
case a
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ ∑ x in range (n + 1 - x✝),
      ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x) =
    ?g x✝
[PROOFSTEP]
conv =>
  apply_congr
  ·skip
  ·rw [← Nat.cast_mul,
      choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption)) (le.intro rfl),
      Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
| ∑ x in range (n + 1 - x✝),
    ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x)
[PROOFSTEP]
  apply_congr
  ·skip
  ·rw [← Nat.cast_mul,
      choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption)) (le.intro rfl),
      Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
| ∑ x in range (n + 1 - x✝),
    ↑(monomial x✝) (↑(Nat.choose (n + 1) (x✝ + x)) * ↑(Nat.choose (x✝ + x) x✝) * _root_.bernoulli x)
[PROOFSTEP]
apply_congr
[GOAL]
case h
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ range (n + 1 - x✝) = ?s₂
case a
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ ?s₂
⊢ ↑(monomial x✝¹) (↑(Nat.choose (n + 1) (x✝¹ + x✝)) * ↑(Nat.choose (x✝¹ + x✝) x✝¹) * _root_.bernoulli x✝) = ?g x✝
[PROOFSTEP]
·skip
[GOAL]
case h
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ range (n + 1 - x✝) = ?s₂
[PROOFSTEP]
skip
[GOAL]
case h
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ range (n + 1 - x✝) = ?s₂
[PROOFSTEP]
skip
[GOAL]
case h
n x✝ : ℕ
a✝ : x✝ ∈ range (n + 1)
⊢ range (n + 1 - x✝) = ?s₂
[PROOFSTEP]
skip
[GOAL]
case a
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ range (n + 1 - x✝¹)
⊢ ↑(monomial x✝¹) (↑(Nat.choose (n + 1) (x✝¹ + x✝)) * ↑(Nat.choose (x✝¹ + x✝) x✝¹) * _root_.bernoulli x✝) = ?g x✝
[PROOFSTEP]
·rw [← Nat.cast_mul,
    choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption)) (le.intro rfl),
    Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
case a
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ range (n + 1 - x✝¹)
⊢ ↑(monomial x✝¹) (↑(Nat.choose (n + 1) (x✝¹ + x✝)) * ↑(Nat.choose (x✝¹ + x✝) x✝¹) * _root_.bernoulli x✝) = ?g x✝
[PROOFSTEP]
rw [← Nat.cast_mul,
    choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption)) (le.intro rfl),
    Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
case a
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ range (n + 1 - x✝¹)
⊢ ↑(monomial x✝¹) (↑(Nat.choose (n + 1) (x✝¹ + x✝)) * ↑(Nat.choose (x✝¹ + x✝) x✝¹) * _root_.bernoulli x✝) = ?g x✝
[PROOFSTEP]
rw [← Nat.cast_mul,
    choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption)) (le.intro rfl),
    Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
case a
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ range (n + 1 - x✝¹)
⊢ ↑(monomial x✝¹) (↑(Nat.choose (n + 1) (x✝¹ + x✝)) * ↑(Nat.choose (x✝¹ + x✝) x✝¹) * _root_.bernoulli x✝) = ?g x✝
[PROOFSTEP]
rw [← Nat.cast_mul,
  choose_mul ((le_tsub_iff_left <| mem_range_le (by assumption)).1 <| mem_range_le (by assumption)) (le.intro rfl),
  Nat.cast_mul, add_tsub_cancel_left, mul_assoc, mul_comm, ← smul_eq_mul, ← smul_monomial]
[GOAL]
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ range (n + 1 - x✝¹)
⊢ x✝¹ ∈ range (n + 1)
[PROOFSTEP]
assumption
[GOAL]
n x✝¹ : ℕ
a✝¹ : x✝¹ ∈ range (n + 1)
x✝ : ℕ
a✝ : x✝ ∈ range (n + 1 - x✝¹)
⊢ x✝ ∈ range (n + 1 - x✝¹)
[PROOFSTEP]
assumption
[GOAL]
n : ℕ
⊢ ∑ x in range (n + 1),
      ∑ x_1 in range (n + 1 - x),
        (↑(Nat.choose (n + 1 - x) x_1) * _root_.bernoulli x_1) • ↑(monomial x) ↑(Nat.choose (n + 1) x) =
    ↑(monomial n) ↑n + ↑(monomial n) 1
[PROOFSTEP]
simp_rw [← sum_smul]
[GOAL]
n : ℕ
⊢ ∑ x in range (n + 1),
      (∑ i in range (n + 1 - x), ↑(Nat.choose (n + 1 - x) i) * _root_.bernoulli i) •
        ↑(monomial x) ↑(Nat.choose (n + 1) x) =
    ↑(monomial n) ↑n + ↑(monomial n) 1
[PROOFSTEP]
rw [sum_range_succ_comm]
[GOAL]
n : ℕ
⊢ (∑ i in range (n + 1 - n), ↑(Nat.choose (n + 1 - n) i) * _root_.bernoulli i) • ↑(monomial n) ↑(Nat.choose (n + 1) n) +
      ∑ x in range n,
        (∑ i in range (n + 1 - x), ↑(Nat.choose (n + 1 - x) i) * _root_.bernoulli i) •
          ↑(monomial x) ↑(Nat.choose (n + 1) x) =
    ↑(monomial n) ↑n + ↑(monomial n) 1
[PROOFSTEP]
simp only [add_right_eq_self, mul_one, cast_one, cast_add, add_tsub_cancel_left, choose_succ_self_right, one_smul,
  _root_.bernoulli_zero, sum_singleton, zero_add, map_add, range_one, bernoulli_zero, mul_one, one_mul, add_zero,
  choose_self]
[GOAL]
n : ℕ
⊢ ∑ x in range n,
      (∑ i in range (n + 1 - x), ↑(Nat.choose (n + 1 - x) i) * _root_.bernoulli i) •
        ↑(monomial x) ↑(Nat.choose (n + 1) x) =
    0
[PROOFSTEP]
apply sum_eq_zero fun x hx => _
[GOAL]
n : ℕ
⊢ ∀ (x : ℕ),
    x ∈ range n →
      (∑ i in range (n + 1 - x), ↑(Nat.choose (n + 1 - x) i) * _root_.bernoulli i) •
          ↑(monomial x) ↑(Nat.choose (n + 1) x) =
        0
[PROOFSTEP]
have f : ∀ x ∈ range n, ¬n + 1 - x = 1 := by
  rintro x H
  rw [mem_range] at H
  rw [eq_comm]
  exact _root_.ne_of_lt (Nat.lt_of_lt_of_le one_lt_two (le_tsub_of_add_le_left (succ_le_succ H)))
[GOAL]
n : ℕ
⊢ ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
[PROOFSTEP]
rintro x H
[GOAL]
n x : ℕ
H : x ∈ range n
⊢ ¬n + 1 - x = 1
[PROOFSTEP]
rw [mem_range] at H
[GOAL]
n x : ℕ
H : x < n
⊢ ¬n + 1 - x = 1
[PROOFSTEP]
rw [eq_comm]
[GOAL]
n x : ℕ
H : x < n
⊢ ¬1 = n + 1 - x
[PROOFSTEP]
exact _root_.ne_of_lt (Nat.lt_of_lt_of_le one_lt_two (le_tsub_of_add_le_left (succ_le_succ H)))
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
⊢ ∀ (x : ℕ),
    x ∈ range n →
      (∑ i in range (n + 1 - x), ↑(Nat.choose (n + 1 - x) i) * _root_.bernoulli i) •
          ↑(monomial x) ↑(Nat.choose (n + 1) x) =
        0
[PROOFSTEP]
intro x hx
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
x : ℕ
hx : x ∈ range n
⊢ (∑ i in range (n + 1 - x), ↑(Nat.choose (n + 1 - x) i) * _root_.bernoulli i) • ↑(monomial x) ↑(Nat.choose (n + 1) x) =
    0
[PROOFSTEP]
rw [sum_bernoulli]
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
x : ℕ
hx : x ∈ range n
⊢ (if n + 1 - x = 1 then 1 else 0) • ↑(monomial x) ↑(Nat.choose (n + 1) x) = 0
[PROOFSTEP]
have g : ite (n + 1 - x = 1) (1 : ℚ) 0 = 0 :=
  by
  simp only [ite_eq_right_iff, one_ne_zero]
  intro h₁
  exact (f x hx) h₁
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
x : ℕ
hx : x ∈ range n
⊢ (if n + 1 - x = 1 then 1 else 0) = 0
[PROOFSTEP]
simp only [ite_eq_right_iff, one_ne_zero]
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
x : ℕ
hx : x ∈ range n
⊢ n + 1 - x = 1 → False
[PROOFSTEP]
intro h₁
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
x : ℕ
hx : x ∈ range n
h₁ : n + 1 - x = 1
⊢ False
[PROOFSTEP]
exact (f x hx) h₁
[GOAL]
n : ℕ
f : ∀ (x : ℕ), x ∈ range n → ¬n + 1 - x = 1
x : ℕ
hx : x ∈ range n
g : (if n + 1 - x = 1 then 1 else 0) = 0
⊢ (if n + 1 - x = 1 then 1 else 0) • ↑(monomial x) ↑(Nat.choose (n + 1) x) = 0
[PROOFSTEP]
rw [g, zero_smul]
[GOAL]
n : ℕ
⊢ ↑(succ n) • bernoulli n = ↑(monomial n) ↑(succ n) - ∑ k in range n, ↑(Nat.choose (n + 1) k) • bernoulli k
[PROOFSTEP]
rw [Nat.cast_succ, ← sum_bernoulli n, sum_range_succ, add_sub_cancel', choose_succ_self_right, Nat.cast_succ]
[GOAL]
n p : ℕ
⊢ (↑p + 1) * ∑ k in range n, ↑k ^ p = eval (↑n) (bernoulli (succ p)) - _root_.bernoulli (succ p)
[PROOFSTEP]
rw [sum_range_pow, bernoulli_def, eval_finset_sum, ← sum_div, mul_div_cancel' _ _]
[GOAL]
n p : ℕ
⊢ ∑ x in range (p + 1), _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x) =
    ∑ i in range (succ p + 1), eval (↑n) (↑(monomial i) (_root_.bernoulli (succ p - i) * ↑(Nat.choose (succ p) i))) -
      _root_.bernoulli (succ p)
[PROOFSTEP]
simp_rw [eval_monomial]
[GOAL]
n p : ℕ
⊢ ∑ x in range (p + 1), _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x) =
    ∑ x in range (succ p + 1), _root_.bernoulli (succ p - x) * ↑(Nat.choose (succ p) x) * ↑n ^ x -
      _root_.bernoulli (succ p)
[PROOFSTEP]
symm
[GOAL]
n p : ℕ
⊢ ∑ x in range (succ p + 1), _root_.bernoulli (succ p - x) * ↑(Nat.choose (succ p) x) * ↑n ^ x -
      _root_.bernoulli (succ p) =
    ∑ x in range (p + 1), _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x)
[PROOFSTEP]
rw [← sum_flip _, sum_range_succ]
[GOAL]
n p : ℕ
⊢ ∑ x in range (p + 1),
          _root_.bernoulli (succ p - (p + 1 - x)) * ↑(Nat.choose (succ p) (p + 1 - x)) * ↑n ^ (p + 1 - x) +
        _root_.bernoulli (succ p - (p + 1 - (p + 1))) * ↑(Nat.choose (succ p) (p + 1 - (p + 1))) *
          ↑n ^ (p + 1 - (p + 1)) -
      _root_.bernoulli (succ p) =
    ∑ x in range (p + 1), _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x)
[PROOFSTEP]
simp only [tsub_self, tsub_zero, choose_zero_right, cast_one, mul_one, _root_.pow_zero, add_tsub_cancel_right]
[GOAL]
n p : ℕ
⊢ ∑ x in range (p + 1),
      _root_.bernoulli (succ p - (p + 1 - x)) * ↑(Nat.choose (succ p) (p + 1 - x)) * ↑n ^ (p + 1 - x) =
    ∑ x in range (p + 1), _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x)
[PROOFSTEP]
apply sum_congr rfl fun x hx => _
[GOAL]
n p : ℕ
⊢ ∀ (x : ℕ),
    x ∈ range (p + 1) →
      _root_.bernoulli (succ p - (p + 1 - x)) * ↑(Nat.choose (succ p) (p + 1 - x)) * ↑n ^ (p + 1 - x) =
        _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x)
[PROOFSTEP]
intro x hx
[GOAL]
n p x : ℕ
hx : x ∈ range (p + 1)
⊢ _root_.bernoulli (succ p - (p + 1 - x)) * ↑(Nat.choose (succ p) (p + 1 - x)) * ↑n ^ (p + 1 - x) =
    _root_.bernoulli x * ↑(Nat.choose (p + 1) x) * ↑n ^ (p + 1 - x)
[PROOFSTEP]
apply congr_arg₂ _ (congr_arg₂ _ _ _) rfl
[GOAL]
n p x : ℕ
hx : x ∈ range (p + 1)
⊢ _root_.bernoulli (succ p - (p + 1 - x)) = _root_.bernoulli x
[PROOFSTEP]
rw [Nat.sub_sub_self (mem_range_le hx)]
[GOAL]
n p x : ℕ
hx : x ∈ range (p + 1)
⊢ ↑(Nat.choose (succ p) (p + 1 - x)) = ↑(Nat.choose (p + 1) x)
[PROOFSTEP]
rw [← choose_symm (mem_range_le hx)]
[GOAL]
n p : ℕ
⊢ ↑p + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n p : ℕ
⊢ ¬p + 1 = 0
[PROOFSTEP]
apply succ_ne_zero _
[GOAL]
n p : ℕ
⊢ eval (↑n) (bernoulli (succ p)) = _root_.bernoulli (succ p) + (↑p + 1) * ∑ k in range n, ↑k ^ p
[PROOFSTEP]
apply eq_add_of_sub_eq'
[GOAL]
case h
n p : ℕ
⊢ eval (↑n) (bernoulli (succ p)) - _root_.bernoulli (succ p) = (↑p + 1) * ∑ k in range n, ↑k ^ p
[PROOFSTEP]
rw [sum_range_pow_eq_bernoulli_sub]
[GOAL]
n : ℕ
x : ℚ
⊢ eval (1 + x) (bernoulli n) = eval x (bernoulli n) + ↑n * x ^ (n - 1)
[PROOFSTEP]
refine' Nat.strong_induction_on n fun d hd => _
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
⊢ eval (1 + x) (bernoulli d) = eval x (bernoulli d) + ↑d * x ^ (d - 1)
[PROOFSTEP]
have nz : ((d.succ : ℕ) : ℚ) ≠ 0 := by norm_cast
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
⊢ ↑(succ d) ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (bernoulli d) = eval x (bernoulli d) + ↑d * x ^ (d - 1)
[PROOFSTEP]
apply (mul_right_inj' nz).1
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ ↑(succ d) * eval (1 + x) (bernoulli d) = ↑(succ d) * (eval x (bernoulli d) + ↑d * x ^ (d - 1))
[PROOFSTEP]
rw [← smul_eq_mul, ← eval_smul, bernoulli_eq_sub_sum, mul_add, ← smul_eq_mul, ← eval_smul, bernoulli_eq_sub_sum,
  eval_sub, eval_finset_sum]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (↑(monomial d) ↑(succ d)) - ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i) =
    eval x (↑(monomial d) ↑(succ d) - ∑ k in range d, ↑(Nat.choose (d + 1) k) • bernoulli k) +
      ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
conv_lhs =>
  congr
  ·skip
  · apply_congr
    ·skip
    ·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d)) - ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
  congr
  ·skip
  · apply_congr
    ·skip
    ·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d)) - ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
  congr
  ·skip
  · apply_congr
    ·skip
    ·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d)) - ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
congr
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d))
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
·skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d))
[PROOFSTEP]
skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d))
[PROOFSTEP]
skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| eval (1 + x) (↑(monomial d) ↑(succ d))
[PROOFSTEP]
skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
· apply_congr
  ·skip
  ·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
  apply_congr
  ·skip
  ·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
  apply_congr
  ·skip
  ·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ i in range d, eval (1 + x) (↑(Nat.choose (d + 1) i) • bernoulli i)
[PROOFSTEP]
apply_congr
[GOAL]
case a.h
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ range d = ?a.s₂
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ ?a.s₂
⊢ eval (1 + x) (↑(Nat.choose (d + 1) x✝) • bernoulli x✝) = ?a.g x✝
[PROOFSTEP]
·skip
[GOAL]
case a.h
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ range d = ?a.s₂
[PROOFSTEP]
skip
[GOAL]
case a.h
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ range d = ?a.s₂
[PROOFSTEP]
skip
[GOAL]
case a.h
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ range d = ?a.s₂
[PROOFSTEP]
skip
[GOAL]
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range d
⊢ eval (1 + x) (↑(Nat.choose (d + 1) x✝) • bernoulli x✝) = ?a.g x✝
[PROOFSTEP]
·rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range d
⊢ eval (1 + x) (↑(Nat.choose (d + 1) x✝) • bernoulli x✝) = ?a.g x✝
[PROOFSTEP]
rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range d
⊢ eval (1 + x) (↑(Nat.choose (d + 1) x✝) • bernoulli x✝) = ?a.g x✝
[PROOFSTEP]
rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range d
⊢ eval (1 + x) (↑(Nat.choose (d + 1) x✝) • bernoulli x✝) = ?a.g x✝
[PROOFSTEP]
rw [eval_smul, hd _ (mem_range.1 (by assumption))]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range d
⊢ x✝ ∈ range d
[PROOFSTEP]
assumption
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (↑(monomial d) ↑(succ d)) -
      ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (eval x (bernoulli x_1) + ↑x_1 * x ^ (x_1 - 1)) =
    eval x (↑(monomial d) ↑(succ d) - ∑ k in range d, ↑(Nat.choose (d + 1) k) • bernoulli k) +
      ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
rw [eval_sub, eval_finset_sum]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (↑(monomial d) ↑(succ d)) -
      ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (eval x (bernoulli x_1) + ↑x_1 * x ^ (x_1 - 1)) =
    eval x (↑(monomial d) ↑(succ d)) - ∑ i in range d, eval x (↑(Nat.choose (d + 1) i) • bernoulli i) +
      ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
simp_rw [eval_smul, smul_add]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (↑(monomial d) ↑(succ d)) -
      ∑ x_1 in range d,
        (↑(Nat.choose (d + 1) x_1) • eval x (bernoulli x_1) + ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1))) =
    eval x (↑(monomial d) ↑(succ d)) - ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • eval x (bernoulli x_1) +
      ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
rw [sum_add_distrib, sub_add, sub_eq_sub_iff_sub_eq_sub, _root_.add_sub_sub_cancel]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (↑(monomial d) ↑(succ d)) - eval x (↑(monomial d) ↑(succ d)) =
    ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1)) + ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
conv_rhs =>
  congr
  ·skip
  · congr
    rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1)) + ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
  congr
  ·skip
  · congr
    rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1)) + ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
  congr
  ·skip
  · congr
    rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1)) + ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
congr
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1))
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
·skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1))
[PROOFSTEP]
skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1))
[PROOFSTEP]
skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1))
[PROOFSTEP]
skip
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
· congr
  rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
  congr
  rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
  congr
  rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
case a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑(succ d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
congr
[GOAL]
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑(succ d)
case a.a
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
| ↑d * x ^ (d - 1)
[PROOFSTEP]
rw [succ_eq_add_one, ← choose_succ_self_right d]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ eval (1 + x) (↑(monomial d) ↑(succ d)) - eval x (↑(monomial d) ↑(succ d)) =
    ∑ x_1 in range d, ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1)) + ↑(Nat.choose (d + 1) d) * (↑d * x ^ (d - 1))
[PROOFSTEP]
rw [Nat.cast_succ, ← smul_eq_mul, ← sum_range_succ _ d, eval_monomial_one_add_sub]
[GOAL]
n : ℕ
x : ℚ
d : ℕ
hd : ∀ (m : ℕ), m < d → eval (1 + x) (bernoulli m) = eval x (bernoulli m) + ↑m * x ^ (m - 1)
nz : ↑(succ d) ≠ 0
⊢ ∑ x_1 in range (d + 1), ↑(Nat.choose (d + 1) x_1) * (↑x_1 * x ^ (x_1 - 1)) =
    ∑ x_1 in range (d + 1), ↑(Nat.choose (d + 1) x_1) • (↑x_1 * x ^ (x_1 - 1))
[PROOFSTEP]
simp_rw [smul_eq_mul]
[GOAL]
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
⊢ (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1) = PowerSeries.X * ↑(rescale t) (exp A)
[PROOFSTEP]
ext n
[GOAL]
case h
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ↑(PowerSeries.coeff A n) ((PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    ↑(PowerSeries.coeff A n) (PowerSeries.X * ↑(rescale t) (exp A))
[PROOFSTEP]
cases' n with n
[GOAL]
case h.zero
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
⊢ ↑(PowerSeries.coeff A Nat.zero) ((PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    ↑(PowerSeries.coeff A Nat.zero) (PowerSeries.X * ↑(rescale t) (exp A))
[PROOFSTEP]
simp
  -- n ≥ 1, the coefficients is a sum to n+2, so use `sum_range_succ` to write as
    -- last term plus sum to n+1
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ↑(PowerSeries.coeff A (succ n)) ((PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    ↑(PowerSeries.coeff A (succ n)) (PowerSeries.X * ↑(rescale t) (exp A))
[PROOFSTEP]
rw [coeff_succ_X_mul, coeff_rescale, coeff_exp, PowerSeries.coeff_mul, Nat.sum_antidiagonal_eq_sum_range_succ_mk,
  sum_range_succ]
  -- last term is zero so kill with `add_zero`
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ∑ x in range (n + 1),
        ↑(PowerSeries.coeff A (x, succ n - x).fst) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
          ↑(PowerSeries.coeff A (x, succ n - x).snd) (exp A - 1) +
      ↑(PowerSeries.coeff A (n + 1, succ n - (n + 1)).fst)
          (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
        ↑(PowerSeries.coeff A (n + 1, succ n - (n + 1)).snd) (exp A - 1) =
    t ^ n * ↑(algebraMap ℚ A) (1 / ↑n !)
[PROOFSTEP]
simp only [RingHom.map_sub, tsub_self, constantCoeff_one, constantCoeff_exp, coeff_zero_eq_constantCoeff, mul_zero,
  sub_self, add_zero]
  -- Let's multiply both sides by (n+1)! (OK because it's a unit)
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ∑ x in range (n + 1),
      ↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
        ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1) =
    t ^ n * ↑(algebraMap ℚ A) (1 / ↑n !)
[PROOFSTEP]
have hnp1 : IsUnit ((n + 1)! : ℚ) := IsUnit.mk0 _ (by exact_mod_cast factorial_ne_zero (n + 1))
[GOAL]
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ↑(n + 1)! ≠ 0
[PROOFSTEP]
exact_mod_cast factorial_ne_zero (n + 1)
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∑ x in range (n + 1),
      ↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
        ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1) =
    t ^ n * ↑(algebraMap ℚ A) (1 / ↑n !)
[PROOFSTEP]
rw [← (hnp1.map (algebraMap ℚ A)).mul_right_inj]
  -- do trivial rearrangements to make RHS (n+1)*t^n
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ↑(algebraMap ℚ A) ↑(n + 1)! *
      ∑ x in range (n + 1),
        ↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
          ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1) =
    ↑(algebraMap ℚ A) ↑(n + 1)! * (t ^ n * ↑(algebraMap ℚ A) (1 / ↑n !))
[PROOFSTEP]
rw [mul_left_comm, ← RingHom.map_mul]
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ↑(algebraMap ℚ A) ↑(n + 1)! *
      ∑ x in range (n + 1),
        ↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
          ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1) =
    t ^ n * ↑(algebraMap ℚ A) (↑(n + 1)! * (1 / ↑n !))
[PROOFSTEP]
change _ = t ^ n * algebraMap ℚ A (((n + 1) * n ! : ℕ) * (1 / n !))
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ↑(algebraMap ℚ A) ↑(n + 1)! *
      ∑ x in range (n + 1),
        ↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
          ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1) =
    t ^ n * ↑(algebraMap ℚ A) (↑((n + 1) * n !) * (1 / ↑n !))
[PROOFSTEP]
rw [cast_mul, mul_assoc, mul_one_div_cancel (show (n ! : ℚ) ≠ 0 from cast_ne_zero.2 (factorial_ne_zero n)), mul_one,
  mul_comm (t ^ n), ← aeval_monomial, cast_add, cast_one]
  -- But this is the RHS of `Polynomial.sum_bernoulli`
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ↑(algebraMap ℚ A) ↑(n + 1)! *
      ∑ x in range (n + 1),
        ↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
          ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1) =
    ↑(aeval t) (↑(monomial n) (↑n + 1))
[PROOFSTEP]
rw [← sum_bernoulli, Finset.mul_sum, AlgHom.map_sum]
  -- and now we have to prove a sum is a sum, but all the terms are equal.
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∑ x in range (n + 1),
      ↑(algebraMap ℚ A) ↑(n + 1)! *
        (↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
          ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1)) =
    ∑ x in range (n + 1), ↑(aeval t) (↑(Nat.choose (n + 1) x) • bernoulli x)
[PROOFSTEP]
apply Finset.sum_congr rfl
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∀ (x : ℕ),
    x ∈ range (n + 1) →
      ↑(algebraMap ℚ A) ↑(n + 1)! *
          (↑(PowerSeries.coeff A x) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
            ↑(PowerSeries.coeff A (succ n - x)) (exp A - 1)) =
        ↑(aeval t) (↑(Nat.choose (n + 1) x) • bernoulli x)
[PROOFSTEP]
intro i hi
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
i : ℕ
hi : i ∈ range (n + 1)
⊢ ↑(algebraMap ℚ A) ↑(n + 1)! *
      (↑(PowerSeries.coeff A i) (PowerSeries.mk fun n => ↑(aeval t) ((1 / ↑n !) • bernoulli n)) *
        ↑(PowerSeries.coeff A (succ n - i)) (exp A - 1)) =
    ↑(aeval t) (↑(Nat.choose (n + 1) i) • bernoulli i)
[PROOFSTEP]
simp only [Nat.cast_choose ℚ (mem_range_le hi), coeff_mk, if_neg (mem_range_sub_ne_zero hi), one_div, AlgHom.map_smul,
  PowerSeries.coeff_one, coeff_exp, sub_zero, LinearMap.map_sub, Algebra.smul_mul_assoc, Algebra.smul_def,
  mul_right_comm _ ((aeval t) _), ← mul_assoc, ← RingHom.map_mul, succ_eq_add_one, ← Polynomial.C_eq_algebraMap,
  Polynomial.aeval_mul, Polynomial.aeval_C]
  -- finally cancel the Bernoulli polynomial and the algebra_map
[GOAL]
case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
i : ℕ
hi : i ∈ range (n + 1)
⊢ ↑(algebraMap ℚ A) (↑(n + 1)! * (↑i !)⁻¹ * (↑(n + 1 - i)!)⁻¹) * ↑(aeval t) (bernoulli i) =
    ↑(algebraMap ℚ A) (↑(n + 1)! / (↑i ! * ↑(n + 1 - i)!)) * ↑(aeval t) (bernoulli i)
[PROOFSTEP]
field_simp


[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
x : Vector α n
y : Vector β n
⊢ List.length (List.zipWith f ↑x ↑y) = n
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
x : Vector α n
y : Vector β n
i : Fin n
⊢ get (zipWith f x y) i = f (get x i) (get y i)
[PROOFSTEP]
dsimp only [Vector.zipWith, Vector.get]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
x : Vector α n
y : Vector β n
i : Fin n
⊢ List.nthLe (List.zipWith f ↑x ↑y) ↑i (_ : ↑i < List.length (List.zipWith f ↑x ↑y)) =
    f
      (match x, i with
      | { val := l, property := h }, i => List.nthLe l ↑i (_ : ↑i < List.length l))
      (match y, i with
      | { val := l, property := h }, i => List.nthLe l ↑i (_ : ↑i < List.length l))
[PROOFSTEP]
cases x
[GOAL]
case mk
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
y : Vector β n
i : Fin n
val✝ : List α
property✝ : List.length val✝ = n
⊢ List.nthLe (List.zipWith f ↑{ val := val✝, property := property✝ } ↑y) ↑i
      (_ : ↑i < List.length (List.zipWith f ↑{ val := val✝, property := property✝ } ↑y)) =
    f
      (match { val := val✝, property := property✝ }, i with
      | { val := l, property := h }, i => List.nthLe l ↑i (_ : ↑i < List.length l))
      (match y, i with
      | { val := l, property := h }, i => List.nthLe l ↑i (_ : ↑i < List.length l))
[PROOFSTEP]
cases y
[GOAL]
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
i : Fin n
val✝¹ : List α
property✝¹ : List.length val✝¹ = n
val✝ : List β
property✝ : List.length val✝ = n
⊢ List.nthLe (List.zipWith f ↑{ val := val✝¹, property := property✝¹ } ↑{ val := val✝, property := property✝ }) ↑i
      (_ :
        ↑i <
          List.length
            (List.zipWith f ↑{ val := val✝¹, property := property✝¹ } ↑{ val := val✝, property := property✝ })) =
    f
      (match { val := val✝¹, property := property✝¹ }, i with
      | { val := l, property := h }, i => List.nthLe l ↑i (_ : ↑i < List.length l))
      (match { val := val✝, property := property✝ }, i with
      | { val := l, property := h }, i => List.nthLe l ↑i (_ : ↑i < List.length l))
[PROOFSTEP]
simp only [List.nthLe_zipWith]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
x : Vector α n
y : Vector β n
⊢ tail (zipWith f x y) = zipWith f (tail x) (tail y)
[PROOFSTEP]
ext
[GOAL]
case x
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
f : α → β → γ
x : Vector α n
y : Vector β n
m✝ : Fin (n - 1)
⊢ get (tail (zipWith f x y)) m✝ = get (zipWith f (tail x) (tail y)) m✝
[PROOFSTEP]
simp [get_tail]