-- Mathlib/Analysis/Normed/Group/Uniform.lean
theorem cauchySeq_prod_of_eventually_eq {u v : ℕ → E} {N : ℕ} (huv : ∀ n ≥ N, u n = v n)
    (hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k) :
    CauchySeq fun n => ∏ k ∈ range (n + 1), u k

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
m : ℕ
hm : m ≥ N + 1
⊢ u m / v m = 1

Tactic:
simp [huv m (le_of_lt hm)]

Result:
no goals

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
⊢ d n = d N

Tactic:
dsimp [d]

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
⊢ ∏ k ∈ range (n + 1), u k / v k = ∏ k ∈ range (N + 1), u k / v k

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ CauchySeq (d * fun n => ∏ k ∈ range (n + 1), v k)

Tactic:
suffices ∀ n ≥ N, d n = d N from (tendsto_atTop_of_eventually_const this).cauchySeq.mul hv

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ ∀ n ≥ N, d n = d N

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
⊢ ∏ k ∈ range (n + 1), u k / v k = ∏ k ∈ range (N + 1), u k / v k

Tactic:
rw [eventually_constant_prod _ (add_le_add_right hn 1)]

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
⊢ ∀ n ≥ N + 1, u n / v n = 1

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ ∀ n ≥ N, d n = d N

Tactic:
intro n hn

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
⊢ d n = d N

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
⊢ ∀ n ≥ N + 1, u n / v n = 1

Tactic:
intro m hm

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
hn : n ≥ N
m : ℕ
hm : m ≥ N + 1
⊢ u m / v m = 1

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ (fun n => ∏ k ∈ range (n + 1), u k) = d * fun n => ∏ k ∈ range (n + 1), v k

Tactic:
ext n

Result:
case h
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
⊢ ∏ k ∈ range (n + 1), u k = (d * fun n => ∏ k ∈ range (n + 1), v k) n

Proof state:
case h
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
n : ℕ
⊢ ∏ k ∈ range (n + 1), u k = (d * fun n => ∏ k ∈ range (n + 1), v k) n

Tactic:
simp [d]

Result:
no goals

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
⊢ CauchySeq fun n => ∏ k ∈ range (n + 1), u k

Tactic:
let d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ CauchySeq fun n => ∏ k ∈ range (n + 1), u k

Proof state:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ CauchySeq fun n => ∏ k ∈ range (n + 1), u k

Tactic:
rw [show (fun n => ∏ k ∈ range (n + 1), u k) = d * fun n => ∏ k ∈ range (n + 1), v k
    by ext n; simp [d]]

Result:
E : Type u_2
inst✝ : SeminormedCommGroup E
u v : ℕ → E
N : ℕ
huv : ∀ n ≥ N, u n = v n
hv : CauchySeq fun n => ∏ k ∈ range (n + 1), v k
d : ℕ → E := fun n => ∏ k ∈ range (n + 1), u k / v k
⊢ CauchySeq (d * fun n => ∏ k ∈ range (n + 1), v k)