l3lab/ntp-mathlib huggingface dataset:
theorem hasSum_nat_add_iff' {f : ℕ → α} (k : ℕ) {a : α} :
    HasSum (fun n => f (n + k)) (a - ∑ i in range k, f i) ↔ HasSum f a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g : β → α
a✝ a₁ a₂ : α
f : ℕ → α
k : ℕ
a : α
⊢ HasSum (fun n => f (n + k)) (a - ∑ i in range k, f i) ↔ HasSum f a

Next tactic:
simp [hasSum_nat_add_iff]
theorem HasSum.sum_range_add [AddCommMonoid M] [TopologicalSpace M] [ContinuousAdd M] {f : ℕ → M}
    {k : ℕ} {a : M} (h : HasSum (fun n ↦ f (n + k)) a) : HasSum f ((∑ i in range k, f i) + a) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : AddCommGroup α
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalAddGroup α
f✝ g : β → α
a✝ a₁ a₂ : α
M : Type u_5
inst✝² : AddCommMonoid M
inst✝¹ : TopologicalSpace M
inst✝ : ContinuousAdd M
f : ℕ → M
k : ℕ
a : M
h : HasSum (fun n => f (n + k)) a
⊢ HasSum f (∑ i in range k, f i + a)

Next tactic:
refine ((range k).hasSum f).add_compl ?_
theorem HasSum.sum_range_add [AddCommMonoid M] [TopologicalSpace M] [ContinuousAdd M] {f : ℕ → M}
    {k : ℕ} {a : M} (h : HasSum (fun n ↦ f (n + k)) a) : HasSum f ((∑ i in range k, f i) + a) := by
  refine ((range k).hasSum f).add_compl ?_
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : AddCommGroup α
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalAddGroup α
f✝ g : β → α
a✝ a₁ a₂ : α
M : Type u_5
inst✝² : AddCommMonoid M
inst✝¹ : TopologicalSpace M
inst✝ : ContinuousAdd M
f : ℕ → M
k : ℕ
a : M
h : HasSum (fun n => f (n + k)) a
⊢ HasSum (f ∘ Subtype.val) a

Next tactic:
rwa [← (notMemRangeEquiv k).symm.hasSum_iff]
theorem tsum_eq_zero_add' [AddCommMonoid M] [TopologicalSpace M] [ContinuousAdd M] [T2Space M]
    {f : ℕ → M} (hf : Summable (fun n => f (n + 1))) :
    ∑' b, f b = f 0 + ∑' b, f (b + 1) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁶ : AddCommGroup α
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
M : Type u_5
inst✝³ : AddCommMonoid M
inst✝² : TopologicalSpace M
inst✝¹ : ContinuousAdd M
inst✝ : T2Space M
f : ℕ → M
hf : Summable fun n => f (n + 1)
⊢ ∑' (b : ℕ), f b = f 0 + ∑' (b : ℕ), f (b + 1)

Next tactic:
simpa only [sum_range_one] using (sum_add_tsum_nat_add' hf).symm
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
⊢ Tendsto (fun i => ∑' (k : ℕ), f (k + i)) atTop (𝓝 0)

Next tactic:
by_cases hf : Summable f
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : Summable f
⊢ Tendsto (fun i => ∑' (k : ℕ), f (k + i)) atTop (𝓝 0)

Next tactic:
have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : Summable f
⊢ (fun i => ∑' (i : ℕ), f i - ∑ j in range i, f j) = fun i => ∑' (k : ℕ), f (k + i)

Next tactic:
ext1 i
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : Summable f
i : ℕ
⊢ ∑' (i : ℕ), f i - ∑ j in range i, f j = ∑' (k : ℕ), f (k + i)

Next tactic:
rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
    

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : Summable f
h₀ : (fun i => ∑' (i : ℕ), f i - ∑ j in range i, f j) = fun i => ∑' (k : ℕ), f (k + i)
⊢ Tendsto (fun i => ∑' (k : ℕ), f (k + i)) atTop (𝓝 0)

Next tactic:
have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
    have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
    

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : Summable f
h₀ : (fun i => ∑' (i : ℕ), f i - ∑ j in range i, f j) = fun i => ∑' (k : ℕ), f (k + i)
h₁ : Tendsto (fun x => ∑' (i : ℕ), f i) atTop (𝓝 (∑' (i : ℕ), f i))
⊢ Tendsto (fun i => ∑' (k : ℕ), f (k + i)) atTop (𝓝 0)

Next tactic:
simpa only [h₀, sub_self] using Tendsto.sub h₁ hf.hasSum.tendsto_sum_nat
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
    have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
    simpa only [h₀, sub_self] using Tendsto.sub h₁ hf.hasSum.tendsto_sum_nat
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : ¬Summable f
⊢ Tendsto (fun i => ∑' (k : ℕ), f (k + i)) atTop (𝓝 0)

Next tactic:
convert tendsto_const_nhds (α := α) (β := ℕ) (a := 0) (f := atTop)
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
    have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
    simpa only [h₀, sub_self] using Tendsto.sub h₁ hf.hasSum.tendsto_sum_nat
  · convert tendsto_const_nhds (α := α) (β := ℕ) (a := 0) (f := atTop)
    

Proof state:
case h.e'_3.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : ¬Summable f
x✝ : ℕ
⊢ ∑' (k : ℕ), f (k + x✝) = 0

Next tactic:
rename_i i
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
    have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
    simpa only [h₀, sub_self] using Tendsto.sub h₁ hf.hasSum.tendsto_sum_nat
  · convert tendsto_const_nhds (α := α) (β := ℕ) (a := 0) (f := atTop)
    rename_i i
    

Proof state:
case h.e'_3.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
hf : ¬Summable f
i : ℕ
⊢ ∑' (k : ℕ), f (k + i) = 0

Next tactic:
rw [← summable_nat_add_iff i] at hf
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
    Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
  by_cases hf : Summable f
  · have h₀ : (fun i => ∑' i, f i - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) := by
      ext1 i
      rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
    have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
    simpa only [h₀, sub_self] using Tendsto.sub h₁ hf.hasSum.tendsto_sum_nat
  · convert tendsto_const_nhds (α := α) (β := ℕ) (a := 0) (f := atTop)
    rename_i i
    rw [← summable_nat_add_iff i] at hf
    

Proof state:
case h.e'_3.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : AddCommGroup α
inst✝² : TopologicalSpace α
inst✝¹ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ : α
inst✝ : T2Space α
f : ℕ → α
i : ℕ
hf : ¬Summable fun n => f (n + i)
⊢ ∑' (k : ℕ), f (k + i) = 0

Next tactic:
exact tsum_eq_zero_of_not_summable hf
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
⊢ HasSum (Int.rec f g) (a + b)

Next tactic:
have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
⊢ HasSum (Int.rec f g) (a + b)

Next tactic:
have h₂ : Injective Int.negSucc := @Int.negSucc.inj
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
⊢ HasSum (Int.rec f g) (a + b)

Next tactic:
have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · rw [disjoint_iff_inf_le]
      rintro _ ⟨⟨i, rfl⟩, ⟨j, ⟨⟩⟩⟩
    · rw [codisjoint_iff_le_sup]
      rintro (i | j) _
      exacts [Or.inl ⟨_, rfl⟩, Or.inr ⟨_, rfl⟩]
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
⊢ IsCompl (Set.range Nat.cast) (Set.range Int.negSucc)

Next tactic:
constructor
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · 

Proof state:
case disjoint
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
⊢ Disjoint (Set.range Nat.cast) (Set.range Int.negSucc)

Next tactic:
rw [disjoint_iff_inf_le]
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · rw [disjoint_iff_inf_le]
      

Proof state:
case disjoint
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
⊢ Set.range Nat.cast ⊓ Set.range Int.negSucc ≤ ⊥

Next tactic:
rintro _ ⟨⟨i, rfl⟩, ⟨j, ⟨⟩⟩⟩
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · rw [disjoint_iff_inf_le]
      rintro _ ⟨⟨i, rfl⟩, ⟨j, ⟨⟩⟩⟩
    · 

Proof state:
case codisjoint
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
⊢ Codisjoint (Set.range Nat.cast) (Set.range Int.negSucc)

Next tactic:
rw [codisjoint_iff_le_sup]
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · rw [disjoint_iff_inf_le]
      rintro _ ⟨⟨i, rfl⟩, ⟨j, ⟨⟩⟩⟩
    · rw [codisjoint_iff_le_sup]
      

Proof state:
case codisjoint
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
⊢ ⊤ ≤ Set.range Nat.cast ⊔ Set.range Int.negSucc

Next tactic:
rintro (i | j) _
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · rw [disjoint_iff_inf_le]
      rintro _ ⟨⟨i, rfl⟩, ⟨j, ⟨⟩⟩⟩
    · rw [codisjoint_iff_le_sup]
      rintro (i | j) _
      

Proof state:
case codisjoint.ofNat
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
i : ℕ
a✝ : Int.ofNat i ∈ ⊤
⊢ Int.ofNat i ∈ Set.range Nat.cast ⊔ Set.range Int.negSucc
case codisjoint.negSucc
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
j : ℕ
a✝ : Int.negSucc j ∈ ⊤
⊢ Int.negSucc j ∈ Set.range Nat.cast ⊔ Set.range Int.negSucc

Next tactic:
exacts [Or.inl ⟨_, rfl⟩, Or.inr ⟨_, rfl⟩]
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
    @HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by
  -- note this proof works for any two-case inductive
  have h₁ : Injective ((↑) : ℕ → ℤ) := @Int.ofNat.inj
  have h₂ : Injective Int.negSucc := @Int.negSucc.inj
  have : IsCompl (Set.range ((↑) : ℕ → ℤ)) (Set.range Int.negSucc) := by
    constructor
    · rw [disjoint_iff_inf_le]
      rintro _ ⟨⟨i, rfl⟩, ⟨j, ⟨⟩⟩⟩
    · rw [codisjoint_iff_le_sup]
      rintro (i | j) _
      exacts [Or.inl ⟨_, rfl⟩, Or.inr ⟨_, rfl⟩]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g✝ : β → α
a a₁ a₂ b : α
f g : ℕ → α
hf : HasSum f a
hg : HasSum g b
h₁ : Injective Nat.cast
h₂ : Injective Int.negSucc
this : IsCompl (Set.range Nat.cast) (Set.range Int.negSucc)
⊢ HasSum (Int.rec f g) (a + b)

Next tactic:
exact HasSum.add_isCompl this (h₁.hasSum_range_iff.mpr hf) (h₂.hasSum_range_iff.mpr hg)
theorem HasSum.nonneg_add_neg {b : α} {f : ℤ → α} (hnonneg : HasSum (fun n : ℕ => f n) a)
    (hneg : HasSum (fun n : ℕ => f (-n.succ)) b) : HasSum f (a + b) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ b : α
f : ℤ → α
hnonneg : HasSum (fun n => f ↑n) a
hneg : HasSum (fun n => f (-↑(Nat.succ n))) b
⊢ HasSum f (a + b)

Next tactic:
simp_rw [← Int.negSucc_coe] at hneg
theorem HasSum.nonneg_add_neg {b : α} {f : ℤ → α} (hnonneg : HasSum (fun n : ℕ => f n) a)
    (hneg : HasSum (fun n : ℕ => f (-n.succ)) b) : HasSum f (a + b) := by
  simp_rw [← Int.negSucc_coe] at hneg
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ b : α
f : ℤ → α
hnonneg : HasSum (fun n => f ↑n) a
hneg : HasSum (fun n => f (Int.negSucc n)) b
⊢ HasSum f (a + b)

Next tactic:
convert hnonneg.int_rec hneg using 1
theorem HasSum.nonneg_add_neg {b : α} {f : ℤ → α} (hnonneg : HasSum (fun n : ℕ => f n) a)
    (hneg : HasSum (fun n : ℕ => f (-n.succ)) b) : HasSum f (a + b) := by
  simp_rw [← Int.negSucc_coe] at hneg
  convert hnonneg.int_rec hneg using 1
  

Proof state:
case h.e'_5
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ b : α
f : ℤ → α
hnonneg : HasSum (fun n => f ↑n) a
hneg : HasSum (fun n => f (Int.negSucc n)) b
⊢ f = Int.rec (fun n => f ↑n) fun n => f (Int.negSucc n)

Next tactic:
ext (i | j)
theorem HasSum.nonneg_add_neg {b : α} {f : ℤ → α} (hnonneg : HasSum (fun n : ℕ => f n) a)
    (hneg : HasSum (fun n : ℕ => f (-n.succ)) b) : HasSum f (a + b) := by
  simp_rw [← Int.negSucc_coe] at hneg
  convert hnonneg.int_rec hneg using 1
  ext (i | j) <;> 

Proof state:
case h.e'_5.h.ofNat
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ b : α
f : ℤ → α
hnonneg : HasSum (fun n => f ↑n) a
hneg : HasSum (fun n => f (Int.negSucc n)) b
i : ℕ
⊢ f (Int.ofNat i) = Int.rec (fun n => f ↑n) (fun n => f (Int.negSucc n)) (Int.ofNat i)

Next tactic:
rfl
theorem HasSum.nonneg_add_neg {b : α} {f : ℤ → α} (hnonneg : HasSum (fun n : ℕ => f n) a)
    (hneg : HasSum (fun n : ℕ => f (-n.succ)) b) : HasSum f (a + b) := by
  simp_rw [← Int.negSucc_coe] at hneg
  convert hnonneg.int_rec hneg using 1
  ext (i | j) <;> 

Proof state:
case h.e'_5.h.negSucc
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : AddCommGroup α
inst✝¹ : TopologicalSpace α
inst✝ : TopologicalAddGroup α
f✝ g : β → α
a a₁ a₂ b : α
f : ℤ → α
hnonneg : HasSum (fun n => f ↑n) a
hneg : HasSum (fun n => f (Int.negSucc n)) b
j : ℕ
⊢ f (Int.negSucc j) = Int.rec (fun n => f ↑n) (fun n => f (Int.negSucc n)) (Int.negSucc j)

Next tactic:
rfl