Imports
import Mathlib.Tactic import Analysis.Section_4_3
set_option doc.verso.suggestions false

Analysis I, Section 5.1: Cauchy sequences

I have attempted to make the translation as faithful a paraphrasing as possible of the original text. When there is a choice between a more idiomatic Lean solution and a more faithful translation, I have generally chosen the latter. In particular, there will be places where the Lean code could be "golfed" to be more elegant and idiomatic, but I have consciously avoided doing so.

Main constructions and results of this section:

  • Notion of a sequence of rationals

  • Notions of ε-steadiness, eventual ε-steadiness, and Cauchy sequences

Tips from past users

Users of the companion who have completed the exercises in this section are welcome to send their tips for future users in this section as PRs.

  • (Add tip here)

namespace Chapter5

Definition 5.1.1 (Sequence). To avoid some technicalities involving dependent types, we extend sequences by zero to the left of the starting point n₀.

@[ext] structure Sequence where n₀ : seq : vanish : n < n₀, seq n = 0

Sequences can be thought of as functions from to .

instance Sequence.instCoeFun : CoeFun Sequence (fun _ ) where coe := fun a a.seq

Functions from to can be thought of as sequences starting from 0; Sequence.­ofNatFun performs this conversion.

The coe attribute allows the delaborator to print Sequence.­ofNatFun f as ↑f, which is more concise; you may safely remove this if you prefer the more explicit notation.

@[coe] def Sequence.ofNatFun (f : ) : Sequence where n₀ := 0 seq n := if n 0 then f n.toNat else 0 vanish := f: n < 0, (if n 0 then f n.toNat else 0) = 0 All goals completed! 🐙
-- Notice how the delaborator prints this as `↑fun x ↦ ↑x ^ 2 : Sequence`. fun x x ^ 2 : Sequence#check Sequence.ofNatFun (· ^ 2)

If a : ℕ → ℚ is used in a context where a Sequence is expected, automatically coerce a to Sequence.­ofNatFun a (which will be pretty-printed as a).

instance : Coe ( ) Sequence where coe := Sequence.ofNatFun
abbrev Sequence.mk' (n₀:) (a: { n // n n₀ } ) : Sequence where n₀ := n₀ seq n := if h : n n₀ then a n, h else 0 vanish := n₀:a:{ n // n n₀ } n < n₀, (if h : n n₀ then a n, h else 0) = 0 All goals completed! 🐙lemma Sequence.eval_mk {n n₀:} (a: { n // n n₀ } ) (h: n n₀) : (Sequence.mk' n₀ a) n = a n, h := n:n₀:a:{ n // n n₀ } h:n n₀(mk' n₀ a).seq n = a n, h All goals completed! 🐙@[simp] lemma Sequence.eval_coe (n:) (a: ) : (a:Sequence) n = a n := n:a: (↑a).seq n = a n All goals completed! 🐙@[simp] lemma Sequence.eval_coe_at_int (n:) (a: ) : (a:Sequence) n = if n 0 then a n.toNat else 0 := n:a: (↑a).seq n = if n 0 then a n.toNat else 0 All goals completed! 🐙@[simp] lemma Sequence.n0_coe (a: ) : (a:Sequence).n₀ = 0 := a: (↑a).n₀ = 0 All goals completed! 🐙

Example 5.1.2

abbrev Sequence.squares : Sequence := ((fun n: (n^2:)):Sequence)
/-- Example 5.1.2 -/ example (n:) : Sequence.squares n = n^2 := Sequence.eval_coe _ _

Example 5.1.2

abbrev Sequence.three : Sequence := ((fun (_:) (3:)):Sequence)
/-- Example 5.1.2 -/ example (n:) : Sequence.three n = 3 := Sequence.eval_coe _ (fun (_:) (3:))

Example 5.1.2

abbrev Sequence.squares_from_three : Sequence := mk' 3 (·^2)
/-- Example 5.1.2 -/ example (n:) (hn: n 3) : Sequence.squares_from_three n = n^2 := Sequence.eval_mk _ hn-- need to temporarily leave the `Chapter5` namespace to introduce the following notation end Chapter5

A slight generalization of Definition 5.1.3 - definition of ε-steadiness for a sequence with an arbitrary starting point a.n₀

abbrev Rat.Steady (ε: ) (a: Chapter5.Sequence) : Prop := n a.n₀, m a.n₀, ε.Close (a n) (a m)
lemma Rat.steady_def (ε: ) (a: Chapter5.Sequence) : ε.Steady a n a.n₀, m a.n₀, ε.Close (a n) (a m) := ε:a:Chapter5.Sequenceε.Steady a n a.n₀, m a.n₀, ε.Close (a.seq n) (a.seq m) All goals completed! 🐙namespace Chapter5

Definition 5.1.3 - definition of ε-steadiness for a sequence starting at 0

lemma Rat.Steady.coe (ε : ) (a: ) : ε.Steady a n m : , ε.Close (a n) (a m) := ε:a: ε.Steady a (n m : ), ε.Close (a n) (a m) ε:a: ε.Steady a (n m : ), ε.Close (a n) (a m)ε:a: (∀ (n m : ), ε.Close (a n) (a m)) ε.Steady a ε:a: ε.Steady a (n m : ), ε.Close (a n) (a m) intro h ε:a: h:ε.Steady an: (m : ), ε.Close (a n) (a m) ε:a: h:ε.Steady an:m:ε.Close (a n) (a m); ε:a: h:ε.Steady an:m:n (↑a).n₀ε:a: h:ε.Steady an:m:m (↑a).n₀ε:a: n:m:h:ε.Close ((↑a).seq n) ((↑a).seq m)ε.Close (a n) (a m) ε:a: h:ε.Steady an:m:n (↑a).n₀ε:a: h:ε.Steady an:m:m (↑a).n₀ε:a: n:m:h:ε.Close ((↑a).seq n) ((↑a).seq m)ε.Close (a n) (a m) All goals completed! 🐙 intro h ε:a: h: (n m : ), ε.Close (a n) (a m)n:n (↑a).n₀ m (↑a).n₀, ε.Close ((↑a).seq n) ((↑a).seq m) ε:a: h: (n m : ), ε.Close (a n) (a m)n:hn:n (↑a).n₀ m (↑a).n₀, ε.Close ((↑a).seq n) ((↑a).seq m) ε:a: h: (n m : ), ε.Close (a n) (a m)n:hn:n (↑a).n₀m:m (↑a).n₀ ε.Close ((↑a).seq n) ((↑a).seq m) ε:a: h: (n m : ), ε.Close (a n) (a m)n:hn:n (↑a).n₀m:hm:m (↑a).n₀ε.Close ((↑a).seq n) ((↑a).seq m) ε:a: h: (n m : ), ε.Close (a n) (a m)m:hm:m (↑a).n₀n:ε.Close ((↑a).seq n) ((↑a).seq m) ε:a: h: (n m : ), ε.Close (a n) (a m)n:m:ε.Close ((↑a).seq n) ((↑a).seq m) All goals completed! 🐙
/-- Not in textbook: the sequence 3, 3 ... is 1-steady. Intended as a demonstration of {name}`Rat.Steady.coe`. -/ example : (1:).Steady ((fun _: (3:)):Sequence) := Rat.Steady 1 fun x 3 All goals completed! 🐙/-- {given -show}`hn : n ≥ 0, hm : m ≥ 0` Compare: if you need to work with {name}`Rat.Steady` on the coercion directly, there will be side conditions {lean}`hn : n ≥ 0` and {lean}`hm : m ≥ 0` that you will need to deal with. -/ example : (1:).Steady ((fun _: (3:)):Sequence) := Rat.Steady 1 fun x 3 intro n n:a✝:n (↑fun x 3).n₀ m (↑fun x 3).n₀, Rat.Close 1 ((↑fun x 3).seq n) ((↑fun x 3).seq m) n:a✝:n (↑fun x 3).n₀m:m (↑fun x 3).n₀ Rat.Close 1 ((↑fun x 3).seq n) ((↑fun x 3).seq m) n:a✝¹:n (↑fun x 3).n₀m:a✝:m (↑fun x 3).n₀Rat.Close 1 ((↑fun x 3).seq n) ((↑fun x 3).seq m); All goals completed! 🐙/-- Example 5.1.5: The sequence `1, 0, 1, 0, ...` is 1-steady. -/ example : (1:).Steady ((fun n: if Even n then (1:) else (0:)):Sequence) := Rat.Steady 1 fun n if Even n then 1 else 0 (n m : ), Rat.Close 1 (if Even n then 1 else 0) (if Even m then 1 else 0) intro n n:m:Rat.Close 1 (if Even n then 1 else 0) (if Even m then 1 else 0) -- Split into four cases based on whether n and m are even or odd -- In each case, we know the exact value of a n and a m n:m:h✝¹:Even nh✝:Even mRat.Close 1 1 1n:m:h✝¹:Even nh✝:¬Even mRat.Close 1 1 0n:m:h✝¹:¬Even nh✝:Even mRat.Close 1 0 1n:m:h✝¹:¬Even nh✝:¬Even mRat.Close 1 0 0 n:m:h✝¹:Even nh✝:Even mRat.Close 1 1 1n:m:h✝¹:Even nh✝:¬Even mRat.Close 1 1 0n:m:h✝¹:¬Even nh✝:Even mRat.Close 1 0 1n:m:h✝¹:¬Even nh✝:¬Even mRat.Close 1 0 0 All goals completed! 🐙/-- Example 5.1.5: The sequence `1, 0, 1, 0, ...` is not ½-steady. -/ example : ¬ (0.5:).Steady ((fun n: if Even n then (1:) else (0:)):Sequence) := ¬Rat.Steady 0.5 fun n if Even n then 1 else 0 ¬ (n m : ), Rat.Close 0.5 (if Even n then 1 else 0) (if Even m then 1 else 0) h: (n m : ), Rat.Close 0.5 (if Even n then 1 else 0) (if Even m then 1 else 0)False; h:Rat.Close 0.5 (if Even 0 then 1 else 0) (if Even 1 then 1 else 0)False; h:1 0.5False All goals completed! 🐙/-- Example 5.1.5: The sequence 0.1, 0.01, 0.001, ... is 0.1-steady. -/ example : (0.1:).Steady ((fun n: (10:) ^ (-(n:)-1) ):Sequence) := Rat.Steady 0.1 fun n 10 ^ (-n - 1) (n m : ), Rat.Close 0.1 (10 ^ (-n - 1)) (10 ^ (-m - 1)) intro n n:m:Rat.Close 0.1 (10 ^ (-n - 1)) (10 ^ (-m - 1)); n:m:|10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1 n:m:this: (n m : ), m n |10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1h:¬m n|10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1n:m:h:m n|10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1 n:m:this: (n m : ), m n |10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1h:¬m n|10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1 specialize this m n (n:m:this: (n m : ), m n |10 ^ (-n - 1) - 10 ^ (-m - 1)| 0.1h:¬m nn m All goals completed! 🐙); rwa [abs_sub_commn:m:h:¬m nthis:|10 ^ (-m - 1) - 10 ^ (-n - 1)| 0.1|10 ^ (-m - 1) - 10 ^ (-n - 1)| 0.1 n:m:h:m n10 ^ (-m - 1) - 10 ^ (-n - 1) 0.1n:m:h:m n0 10 ^ (-m - 1) - 10 ^ (-n - 1) n:m:h:m n10 ^ (-m - 1) - 10 ^ (-n - 1) 0.1 n:m:h:m n10 ^ (-m - 1) - 10 ^ (-n - 1) 10 ^ (-1) - 0 n:m:h:m n1 10n:m:h:m n-m - 1 -1n:m:h:m n0 10 ^ (-n - 1) n:m:h:m n1 10n:m:h:m n-m - 1 -1n:m:h:m n0 10 ^ (-n - 1) try All goals completed! 🐙 All goals completed! 🐙 linarith [show (10:) ^ (-(n:)-1) (10:) ^ (-(m:)-1) Rat.Steady 0.1 fun n 10 ^ (-n - 1) n:m:h:m n1 10; All goals completed! 🐙]/-- Example 5.1.5: The sequence 0.1, 0.01, 0.001, ... is not 0.01-steady. Left as an exercise. -/ declaration uses `sorry`example : ¬(0.01:).Steady ((fun n: (10:) ^ (-(n:)-1) ):Sequence) := ¬Rat.Steady 1e-2 fun n 10 ^ (-n - 1) All goals completed! 🐙/-- Example 5.1.5: The sequence 1, 2, 4, 8, ... is not ε-steady for any ε. Left as an exercise. -/ declaration uses `sorry`example (ε:) : ¬ ε.Steady ((fun n: (2 ^ (n+1):) ):Sequence) := ε:¬ε.Steady fun n 2 ^ (n + 1) All goals completed! 🐙/-- Example 5.1.5:The sequence 2, 2, 2, ... is ε-steady for any ε > 0. -/ example (ε:) (: ε>0) : ε.Steady ((fun _: (2:) ):Sequence) := ε::ε > 0ε.Steady fun x 2 ε::ε > 0 (n m : ), ε.Close 2 2; ε::ε > 00 ε; All goals completed! 🐙/-- The sequence 10, 0, 0, ... is 10-steady. -/ example : (10:).Steady ((fun n: if n = 0 then (10:) else (0:)):Sequence) := Rat.Steady 10 fun n if n = 0 then 10 else 0 (n m : ), Rat.Close 10 (if n = 0 then 10 else 0) (if m = 0 then 10 else 0); intro n n:m:Rat.Close 10 (if n = 0 then 10 else 0) (if m = 0 then 10 else 0) -- Split into 4 cases based on whether n and m are 0 or not n:m:h✝¹:n = 0h✝:m = 0Rat.Close 10 10 10n:m:h✝¹:n = 0h✝:¬m = 0Rat.Close 10 10 0n:m:h✝¹:¬n = 0h✝:m = 0Rat.Close 10 0 10n:m:h✝¹:¬n = 0h✝:¬m = 0Rat.Close 10 0 0 n:m:h✝¹:n = 0h✝:m = 0Rat.Close 10 10 10n:m:h✝¹:n = 0h✝:¬m = 0Rat.Close 10 10 0n:m:h✝¹:¬n = 0h✝:m = 0Rat.Close 10 0 10n:m:h✝¹:¬n = 0h✝:¬m = 0Rat.Close 10 0 0 All goals completed! 🐙/-- The sequence 10, 0, 0, ... is not ε-steady for any smaller value of ε. -/ example (ε:) (:ε<10): ¬ ε.Steady ((fun n: if n = 0 then (10:) else (0:)):Sequence) := ε::ε < 10¬ε.Steady fun n if n = 0 then 10 else 0 ε::ε.Steady fun n if n = 0 then 10 else 010 ε; ε:: (n m : ), ε.Close (if n = 0 then 10 else 0) (if m = 0 then 10 else 0)10 ε; ε::ε.Close (if 0 = 0 then 10 else 0) (if 1 = 0 then 10 else 0)10 ε; All goals completed! 🐙

Sequence.­from starts a : Sequence from n₁. It is intended for use when n₁ n₀, but returns the "junk" value of the original sequence a otherwise.

abbrev Sequence.from (a:Sequence) (n₁:) : Sequence := mk' (max a.n₀ n₁) (fun n a (n:))
lemma Sequence.from_eval (a:Sequence) {n₁ n:} (hn: n n₁) : (a.from n₁) n = a n := a:Sequencen₁:n:hn:n n₁(a.from n₁).seq n = a.seq n a:Sequencen₁:n:hn:n n₁n < a.n₀ 0 = a.seq n; a:Sequencen₁:n:hn:n n₁h:n < a.n₀0 = a.seq n; All goals completed! 🐙end Chapter5

Definition 5.1.6 (Eventually ε-steady)

abbrev Rat.EventuallySteady (ε: ) (a: Chapter5.Sequence) : Prop := N a.n₀, ε.Steady (a.from N)
lemma Rat.eventuallySteady_def (ε: ) (a: Chapter5.Sequence) : ε.EventuallySteady a N a.n₀, ε.Steady (a.from N) := ε:a:Chapter5.Sequenceε.EventuallySteady a N a.n₀, ε.Steady (a.from N) All goals completed! 🐙namespace Chapter5

Example 5.1.7: The sequence 1, 1/2, 1/3, ... is not 0.1-steady

lemma Sequence.ex_5_1_7_a : ¬ (0.1:).Steady ((fun n: (n+1:)⁻¹ ):Sequence) := ¬Rat.Steady 0.1 fun n (n + 1)⁻¹ h:Rat.Steady 0.1 fun n (n + 1)⁻¹False; h: (n m : ), Rat.Close 0.1 (n + 1)⁻¹ (m + 1)⁻¹False; h:Rat.Close 0.1 (0 + 1)⁻¹ (2 + 1)⁻¹False; h:|1 - (2 + 1)⁻¹| 0.1False; All goals completed! 🐙

Example 5.1.7: The sequence a_10, a_11, a_12, ... is 0.1-steady

lemma Sequence.ex_5_1_7_b : (0.1:).Steady (((fun n: (n+1:)⁻¹ ):Sequence).from 10) := Rat.Steady 0.1 ((↑fun n (n + 1)⁻¹).from 10) n ((↑fun n (n + 1)⁻¹).from 10).n₀, m ((↑fun n (n + 1)⁻¹).from 10).n₀, Rat.Close 0.1 (((↑fun n (n + 1)⁻¹).from 10).seq n) (((↑fun n (n + 1)⁻¹).from 10).seq m) intro n n:hn:n ((↑fun n (n + 1)⁻¹).from 10).n₀ m ((↑fun n (n + 1)⁻¹).from 10).n₀, Rat.Close 0.1 (((↑fun n (n + 1)⁻¹).from 10).seq n) (((↑fun n (n + 1)⁻¹).from 10).seq m) n:hn:n ((↑fun n (n + 1)⁻¹).from 10).n₀m:m ((↑fun n (n + 1)⁻¹).from 10).n₀ Rat.Close 0.1 (((↑fun n (n + 1)⁻¹).from 10).seq n) (((↑fun n (n + 1)⁻¹).from 10).seq m) n:hn:n ((↑fun n (n + 1)⁻¹).from 10).n₀m:hm:m ((↑fun n (n + 1)⁻¹).from 10).n₀Rat.Close 0.1 (((↑fun n (n + 1)⁻¹).from 10).seq n) (((↑fun n (n + 1)⁻¹).from 10).seq m); n:m:hn:10 nhm:10 mRat.Close 0.1 (((↑fun n (n + 1)⁻¹).from 10).seq n) (((↑fun n (n + 1)⁻¹).from 10).seq m) lift n to using (n:m:hn:10 nhm:10 m0 n All goals completed! 🐙) lift m to using (m:hm:10 mn:hn:10 n0 m All goals completed! 🐙) n:m:hn:10 nhm:10 m|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1 n:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m n|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1n:m:hn:10 nhm:10 mh:m n|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1 n:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m n|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1 n:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m n10 mn:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m n10 nn:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m nn mn:m:hn:10 nhm:10 mh:¬m nthis:|(m + 1)⁻¹ - (n + 1)⁻¹| 0.1|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1 n:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m n10 mn:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m n10 nn:m:hn:10 nhm:10 mthis: (n m : ), 10 n 10 m m n |(n + 1)⁻¹ - (m + 1)⁻¹| 0.1h:¬m nn mn:m:hn:10 nhm:10 mh:¬m nthis:|(m + 1)⁻¹ - (n + 1)⁻¹| 0.1|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1 try All goals completed! 🐙 rwa [abs_sub_commn:m:hn:10 nhm:10 mh:¬m nthis:|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1|(n + 1)⁻¹ - (m + 1)⁻¹| 0.1 at this n:m:hn:10 nhm:10 mh:m n|(m + 1)⁻¹ - (n + 1)⁻¹| 0.1 have : ((n:) + 1)⁻¹ ((m:) + 1)⁻¹ := Rat.Steady 0.1 ((↑fun n (n + 1)⁻¹).from 10) All goals completed! 🐙 n:m:hn:10 nhm:10 mh:m nthis:(n + 1)⁻¹ (m + 1)⁻¹(m + 1)⁻¹ - (n + 1)⁻¹ 10⁻¹ - 0 n:m:hn:10 nhm:10 mh:m nthis:(n + 1)⁻¹ (m + 1)⁻¹10 m + 1n:m:hn:10 nhm:10 mh:m nthis:(n + 1)⁻¹ (m + 1)⁻¹0 (n + 1)⁻¹ n:m:hn:10 nhm:10 mh:m nthis:(n + 1)⁻¹ (m + 1)⁻¹10 m + 1 n:m:hn:10 nhm:10 mh:m nthis:(n + 1)⁻¹ (m + 1)⁻¹10 m + 1; All goals completed! 🐙 All goals completed! 🐙

Example 5.1.7: The sequence 1, 1/2, 1/3, ... is eventually 0.1-steady

lemma Sequence.ex_5_1_7_c : (0.1:).EventuallySteady ((fun n: (n+1:)⁻¹ ):Sequence) := 10, 10 (↑fun n (n + 1)⁻¹).n₀ All goals completed! 🐙, ex_5_1_7_b

Example 5.1.7

The sequence 10, 0, 0, ... is eventually ε-steady for every ε > 0. Left as an exercise.

lemma declaration uses `sorry`Sequence.ex_5_1_7_d {ε:} (:ε>0) : ε.EventuallySteady ((fun n: if n=0 then (10:) else (0:) ):Sequence) := ε::ε > 0ε.EventuallySteady fun n if n = 0 then 10 else 0 All goals completed! 🐙
abbrev Sequence.IsCauchy (a:Sequence) : Prop := ε > (0:), ε.EventuallySteady alemma Sequence.isCauchy_def (a:Sequence) : a.IsCauchy ε > (0:), ε.EventuallySteady a := a:Sequencea.IsCauchy ε > 0, ε.EventuallySteady a All goals completed! 🐙

Definition of Cauchy sequences, for a sequence starting at 0

lemma Sequence.IsCauchy.coe (a: ) : (a:Sequence).IsCauchy ε > (0:), N, j N, k N, Section_4_3.dist (a j) (a k) ε := a: (↑a).IsCauchy ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) ε a: (↑a).IsCauchy ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εa: (∀ ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) ε) (↑a).IsCauchy a: (↑a).IsCauchy ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εa: (∀ ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) ε) (↑a).IsCauchy intro h a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε:ε > 0 ε.EventuallySteady a a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0ε.EventuallySteady a a: h:(↑a).IsCauchyε::ε > 0 N, j N, k N, Section_4_3.dist (a j) (a k) ε a: h:(↑a).IsCauchyε::ε > 0N:hN:N (↑a).n₀h':ε.Steady ((↑a).from N) N, j N, k N, Section_4_3.dist (a j) (a k) ε a: h:(↑a).IsCauchyε::ε > 0N:h':ε.Steady ((↑a).from N) N, j N, k N, Section_4_3.dist (a j) (a k) ε; a: h:(↑a).IsCauchyε::ε > 0N:h':ε.Steady ((↑a).from N) j N, k N, Section_4_3.dist (a j) (a k) ε intro j a: h:(↑a).IsCauchyε::ε > 0N:h':ε.Steady ((↑a).from N)j:a✝:j N k N, Section_4_3.dist (a j) (a k) ε a: h:(↑a).IsCauchyε::ε > 0N:h':ε.Steady ((↑a).from N)j:a✝:j Nk:k N Section_4_3.dist (a j) (a k) ε a: h:(↑a).IsCauchyε::ε > 0N:h':ε.Steady ((↑a).from N)j:a✝¹:j Nk:a✝:k NSection_4_3.dist (a j) (a k) ε; a: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh': (n : ), N n (m : ), N m ε.Close (if N n then if 0 n then a n.toNat else 0 else 0) (if N m then if 0 m then a m.toNat else 0 else 0)Section_4_3.dist (a j) (a k) ε; a: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh': (n : ), N n (m : ), N m ε.Close (if N n then if 0 n then a n.toNat else 0 else 0) (if N m then if 0 m then a m.toNat else 0 else 0)N ja: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh': (n : ), N n (m : ), N m ε.Close (if N n then if 0 n then a n.toNat else 0 else 0) (if N m then if 0 m then a m.toNat else 0 else 0)N ka: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh':ε.Close (if N j then if 0 j then a (↑j).toNat else 0 else 0) (if N k then if 0 k then a (↑k).toNat else 0 else 0)Section_4_3.dist (a j) (a k) ε a: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh': (n : ), N n (m : ), N m ε.Close (if N n then if 0 n then a n.toNat else 0 else 0) (if N m then if 0 m then a m.toNat else 0 else 0)N ja: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh': (n : ), N n (m : ), N m ε.Close (if N n then if 0 n then a n.toNat else 0 else 0) (if N m then if 0 m then a m.toNat else 0 else 0)N ka: h:(↑a).IsCauchyε::ε > 0N:j:a✝¹:j Nk:a✝:k Nh':ε.Close (if N j then if 0 j then a (↑j).toNat else 0 else 0) (if N k then if 0 k then a (↑k).toNat else 0 else 0)Section_4_3.dist (a j) (a k) ε try All goals completed! 🐙 a: h:(↑a).IsCauchyε:N:j:k::0 < εa✝¹:N ja✝:N kh':ε.Close (a j) (a k)Section_4_3.dist (a j) (a k) ε; All goals completed! 🐙 a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εε.EventuallySteady a refine max N 0, a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εmax (↑N) 0 (↑a).n₀ All goals completed! 🐙, ?_ intro n a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:n ((↑a).from (max (↑N) 0)).n₀ m ((↑a).from (max (↑N) 0)).n₀, ε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m) a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:n ((↑a).from (max (↑N) 0)).n₀m:m ((↑a).from (max (↑N) 0)).n₀ ε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m) a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:n ((↑a).from (max (↑N) 0)).n₀m:hm:m ((↑a).from (max (↑N) 0)).n₀ε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m); a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m) a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 nε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m)a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N m0 n a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 nmpos:0 mε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m)a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 n0 ma: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N m0 n a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εm:hm:N mmpos:0 mn:hn:N nε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m)a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 n0 ma: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N m0 n a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:N nm:hm:N mε.Close (((↑a).from (max (↑N) 0)).seq n) (((↑a).from (max (↑N) 0)).seq m)a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 n0 ma: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N m0 n a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:N nm:hm:N mε.Close (a n) (a m)a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 n0 ma: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N m0 n; a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:N nm:hm:N mn Na: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:hn:N nm:hm:N mm Na: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:n:hn:N nm:hm:N mh':Section_4_3.dist (a n) (a m) εε.Close (a n) (a m)a: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N mnpos:0 n0 ma: h: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εε::ε > 0N:h': j N, k N, Section_4_3.dist (a j) (a k) εn:m:hn:N nhm:N m0 n all_goals try All goals completed! 🐙 All goals completed! 🐙
lemma Sequence.IsCauchy.mk {n₀:} (a: {n // n n₀} ) : (mk' n₀ a).IsCauchy ε > (0:), N n₀, j N, k N, Section_4_3.dist (mk' n₀ a j) (mk' n₀ a k) ε := n₀:a:{ n // n n₀ } (mk' n₀ a).IsCauchy ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } (mk' n₀ a).IsCauchy ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εn₀:a:{ n // n n₀ } (∀ ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε) (mk' n₀ a).IsCauchy n₀:a:{ n // n n₀ } (mk' n₀ a).IsCauchy ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εn₀:a:{ n // n n₀ } (∀ ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε) (mk' n₀ a).IsCauchy intro h n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε:ε > 0 ε.EventuallySteady (mk' n₀ a) n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0ε.EventuallySteady (mk' n₀ a) n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0 N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εn₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0ε.EventuallySteady (mk' n₀ a) n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0N:hN:N n₀h': j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε.EventuallySteady (mk' n₀ a) n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N (mk' n₀ a).n₀h':ε.Steady ((mk' n₀ a).from N) N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N (mk' n₀ a).n₀h':ε.Steady ((mk' n₀ a).from N) j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε; n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀h':ε.Steady ((mk' n₀ a).from N) j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε; intro j n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀h':ε.Steady ((mk' n₀ a).from N)j:a✝:j N k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀h':ε.Steady ((mk' n₀ a).from N)j:a✝:j Nk:k N Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀h':ε.Steady ((mk' n₀ a).from N)j:a✝¹:j Nk:a✝:k NSection_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh': n N, m N, ε.Close (if h : n N then if h_1 : n n₀ then a n, else 0 else 0) (if h : m N then if h_1 : m n₀ then a m, else 0 else 0)Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh': n N, m N, ε.Close (if h : n N then if h_1 : n n₀ then a n, else 0 else 0) (if h : m N then if h_1 : m n₀ then a m, else 0 else 0)j Nn₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh': n N, m N, ε.Close (if h : n N then if h_1 : n n₀ then a n, else 0 else 0) (if h : m N then if h_1 : m n₀ then a m, else 0 else 0)k Nn₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh':ε.Close (if h : j N then if h_1 : j n₀ then a j, else 0 else 0) (if h : k N then if h_1 : k n₀ then a k, else 0 else 0)Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε n₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh': n N, m N, ε.Close (if h : n N then if h_1 : n n₀ then a n, else 0 else 0) (if h : m N then if h_1 : m n₀ then a m, else 0 else 0)j Nn₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh': n N, m N, ε.Close (if h : n N then if h_1 : n n₀ then a n, else 0 else 0) (if h : m N then if h_1 : m n₀ then a m, else 0 else 0)k Nn₀:a:{ n // n n₀ } h:(mk' n₀ a).IsCauchyε::ε > 0N:hN:N n₀j:a✝¹:j Nk:a✝:k Nh':ε.Close (if h : j N then if h_1 : j n₀ then a j, else 0 else 0) (if h : k N then if h_1 : k n₀ then a k, else 0 else 0)Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε try All goals completed! 🐙 simp_all [show n₀ j n₀:a:{ n // n n₀ } (mk' n₀ a).IsCauchy ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε All goals completed! 🐙, show n₀ k n₀:a:{ n // n n₀ } (mk' n₀ a).IsCauchy ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) ε All goals completed! 🐙] All goals completed! 🐙 refine max n₀ N, n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0N:hN:N n₀h': j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εmax n₀ N (mk' n₀ a).n₀ All goals completed! 🐙, ?_ intro n n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0N:hN:N n₀h': j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εn:a✝:n ((mk' n₀ a).from (max n₀ N)).n₀ m ((mk' n₀ a).from (max n₀ N)).n₀, ε.Close (((mk' n₀ a).from (max n₀ N)).seq n) (((mk' n₀ a).from (max n₀ N)).seq m) n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0N:hN:N n₀h': j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εn:a✝:n ((mk' n₀ a).from (max n₀ N)).n₀m:m ((mk' n₀ a).from (max n₀ N)).n₀ ε.Close (((mk' n₀ a).from (max n₀ N)).seq n) (((mk' n₀ a).from (max n₀ N)).seq m) n₀:a:{ n // n n₀ } h: ε > 0, N n₀, j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εε::ε > 0N:hN:N n₀h': j N, k N, Section_4_3.dist ((mk' n₀ a).seq j) ((mk' n₀ a).seq k) εn:a✝¹:n ((mk' n₀ a).from (max n₀ N)).n₀m:a✝:m ((mk' n₀ a).from (max n₀ N)).n₀ε.Close (((mk' n₀ a).from (max n₀ N)).seq n) (((mk' n₀ a).from (max n₀ N)).seq m); n₀:a:{ n // n n₀ } ε:N:hN✝:N n₀n:a✝³:n ((mk' n₀ a).from (max n₀ N)).n₀m:a✝²:m ((mk' n₀ a).from (max n₀ N)).n₀h: (ε : ), 0 < ε N, n₀ N (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) ε:0 < εhN:n₀ Nh': (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) εa✝¹:N na✝:N mε.Close (if h : n₀ n then a n, else 0) (if h : n₀ m then a m, else 0) n₀:a:{ n // n n₀ } ε:N:hN✝:N n₀n:a✝³:n ((mk' n₀ a).from (max n₀ N)).n₀m:a✝²:m ((mk' n₀ a).from (max n₀ N)).n₀h: (ε : ), 0 < ε N, n₀ N (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) ε:0 < εhN:n₀ Nh': (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) εa✝¹:N na✝:N mN mn₀:a:{ n // n n₀ } ε:N:hN✝:N n₀n:a✝³:n ((mk' n₀ a).from (max n₀ N)).n₀m:a✝²:m ((mk' n₀ a).from (max n₀ N)).n₀h: (ε : ), 0 < ε N, n₀ N (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) ε:0 < εhN:n₀ Nh': (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) εa✝¹:N na✝:N mN n n₀:a:{ n // n n₀ } ε:N:hN✝:N n₀n:a✝³:n ((mk' n₀ a).from (max n₀ N)).n₀m:a✝²:m ((mk' n₀ a).from (max n₀ N)).n₀h: (ε : ), 0 < ε N, n₀ N (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) ε:0 < εhN:n₀ Nh': (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) εa✝¹:N na✝:N mN mn₀:a:{ n // n n₀ } ε:N:hN✝:N n₀n:a✝³:n ((mk' n₀ a).from (max n₀ N)).n₀m:a✝²:m ((mk' n₀ a).from (max n₀ N)).n₀h: (ε : ), 0 < ε N, n₀ N (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) ε:0 < εhN:n₀ Nh': (j : ), N j (k : ), N k Section_4_3.dist (if h : n₀ j then a j, else 0) (if h : n₀ k then a k, else 0) εa✝¹:N na✝:N mN n All goals completed! 🐙noncomputable def Sequence.sqrt_two : Sequence := (fun n: (( (Real.sqrt 2)*10^n / 10^n):))

Example 5.1.10. (This requires extensive familiarity with Mathlib's API for the real numbers.)

theorem declaration uses `sorry`Sequence.ex_5_1_10_a : (1:).Steady sqrt_two := Rat.Steady 1 sqrt_two All goals completed! 🐙

Example 5.1.10. (This requires extensive familiarity with Mathlib's API for the real numbers.)

theorem declaration uses `sorry`Sequence.ex_5_1_10_b : (0.1:).Steady (sqrt_two.from 1) := Rat.Steady 0.1 (sqrt_two.from 1) All goals completed! 🐙
theorem declaration uses `sorry`Sequence.ex_5_1_10_c : (0.1:).EventuallySteady sqrt_two := Rat.EventuallySteady 0.1 sqrt_two All goals completed! 🐙

Proposition 5.1.11. The harmonic sequence, defined as a₁ = 1, a₂ = 1/2, ... is a Cauchy sequence.

theorem Sequence.IsCauchy.harmonic : (mk' 1 (fun n (1:)/n)).IsCauchy := (mk' 1 fun n 1 / n).IsCauchy ε > 0, N 1, j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε intro ε ε::ε > 0 N 1, j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε -- We go by reverse from the book - first choose N such that N > 1/ε ε::ε > 0N:hN:N > 1 / ε N 1, j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε have hN' : N > 0 := (mk' 1 fun n 1 / n).IsCauchy ε::ε > 0N:hN:N > 1 / εthis:0 < 1 / εN > 0 ε::ε > 0N:hN:N > 1 / εthis✝:0 < 1 / εthis:0 < NN > 0 All goals completed! 🐙 refine N, ε::ε > 0N:hN:N > 1 / εhN':N > 0N 1 All goals completed! 🐙, ?_ intro j ε::ε > 0N:hN:N > 1 / εhN':N > 0j:hj:j N k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε ε::ε > 0N:hN:N > 1 / εhN':N > 0j:hj:j Nk:k N Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε ε::ε > 0N:hN:N > 1 / εhN':N > 0j:hj:j Nk:hk:k NSection_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε lift j to using (ε::ε > 0N:hN:N > 1 / εhN':N > 0j:hj:j Nk:hk:k N0 j All goals completed! 🐙) lift k to using (ε::ε > 0N:hN:N > 1 / εhN':N > 0k:hk:k Nj:hj:j N0 k All goals completed! 🐙) ε::ε > 0N:hN:N > 1 / εhN':N > 0j:k:hj:N jhk:N kSection_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε ε::ε > 0N:hN:N > 1 / εhN':N > 0j:k:hj:N jhk:N kSection_4_3.dist (↑j)⁻¹ (↑k)⁻¹ ε have hdist : Section_4_3.dist ((1:)/j) ((1:)/k) (1:)/N := (mk' 1 fun n 1 / n).IsCauchy ε::ε > 0N:hN:N > 1 / εhN':N > 0j:k:hj:N jhk:N k1 / j - 1 / k 1 / N -(1 / j - 1 / k) 1 / N /- We establish the following bounds: - 1/j ∈ [0, 1/N] - 1/k ∈ [0, 1/N] These imply that the distance between 1/j and 1/k is at most 1/N - when they are as "far apart" as possible. -/ have : 1/j (1:)/N := (mk' 1 fun n 1 / n).IsCauchy All goals completed! 🐙 ε::ε > 0N:hN:N > 1 / εhN':N > 0j:k:hj:N jhk:N kthis✝:1 / j 1 / Nthis:0 1 / j1 / j - 1 / k 1 / N -(1 / j - 1 / k) 1 / N have : 1/k (1:)/N := (mk' 1 fun n 1 / n).IsCauchy All goals completed! 🐙 ε::ε > 0N:hN:N > 1 / εhN':N > 0j:k:hj:N jhk:N kthis✝²:1 / j 1 / Nthis✝¹:0 1 / jthis✝:1 / k 1 / Nthis:0 1 / k1 / j - 1 / k 1 / N -(1 / j - 1 / k) 1 / N All goals completed! 🐙 ε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ ε; ε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹(↑N)⁻¹ ε ε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹ε⁻¹ Nε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹0 < Nε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹0 < ε ε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹ε⁻¹ Nε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹0 < Nε:N:j:k:hj:N jhk:N k:0 < εhN:ε⁻¹ < NhN':0 < Nhdist:Section_4_3.dist (↑j)⁻¹ (↑k)⁻¹ (↑N)⁻¹0 < ε try All goals completed! 🐙 All goals completed! 🐙
abbrev BoundedBy {n:} (a: Fin n ) (M:) : Prop := i, |a i| M

Definition 5.1.12 (bounded sequences). Here we start sequences from 0 rather than 1 to align better with Mathlib conventions.

lemma boundedBy_def {n:} (a: Fin n ) (M:) : BoundedBy a M i, |a i| M := n:a:Fin n M:BoundedBy a M (i : Fin n), |a i| M All goals completed! 🐙
abbrev Sequence.BoundedBy (a:Sequence) (M:) : Prop := n, |a n| M

Definition 5.1.12 (bounded sequences)

lemma Sequence.boundedBy_def (a:Sequence) (M:) : a.BoundedBy M n, |a n| M := a:SequenceM:a.BoundedBy M (n : ), |a.seq n| M All goals completed! 🐙
abbrev Sequence.IsBounded (a:Sequence) : Prop := M 0, a.BoundedBy M

Definition 5.1.12 (bounded sequences)

lemma Sequence.isBounded_def (a:Sequence) : a.IsBounded M 0, a.BoundedBy M := a:Sequencea.IsBounded M 0, a.BoundedBy M All goals completed! 🐙
/-- Example 5.1.13 -/ example : BoundedBy ![1,-2,3,-4] 4 := BoundedBy ![1, -2, 3, -4] 4 i:Fin (Nat.succ 0).succ.succ.succ|![1, -2, 3, -4] i| 4; |![1, -2, 3, -4] ((fun i i) 0, )| 4|![1, -2, 3, -4] ((fun i i) 1, )| 4|![1, -2, 3, -4] ((fun i i) 2, )| 4|![1, -2, 3, -4] ((fun i i) 3, )| 4 |![1, -2, 3, -4] ((fun i i) 0, )| 4|![1, -2, 3, -4] ((fun i i) 1, )| 4|![1, -2, 3, -4] ((fun i i) 2, )| 4|![1, -2, 3, -4] ((fun i i) 3, )| 4 All goals completed! 🐙/-- Example 5.1.13 -/ declaration uses `sorry`example : ¬((fun n: (-1)^n * (n+1:)):Sequence).IsBounded := ¬(↑fun n (-1) ^ n * (n + 1)).IsBounded All goals completed! 🐙/-- Example 5.1.13 -/ example : ((fun n: (-1:)^n):Sequence).IsBounded := (↑fun n (-1) ^ n).IsBounded refine 1, 1 0 All goals completed! 🐙, ?_ ; i:|(↑fun n (-1) ^ n).seq i| 1; i:h:0 i|(↑fun n (-1) ^ n).seq i| 1i:h:¬0 i|(↑fun n (-1) ^ n).seq i| 1 i:h:0 i|(↑fun n (-1) ^ n).seq i| 1i:h:¬0 i|(↑fun n (-1) ^ n).seq i| 1 All goals completed! 🐙/-- Example 5.1.13 -/ example : ¬((fun n: (-1:)^n):Sequence).IsCauchy := ¬(↑fun n (-1) ^ n).IsCauchy ¬ ε > 0, N, j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) ε h: ε > 0, N, j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) εFalse; specialize h (1/2 : ) (h: ε > 0, N, j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) ε1 / 2 > 0 All goals completed! 🐙) N:h: j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) 1 / 2False; N:h: j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) 1 / 2N NN:h: j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) 1 / 2N + 1 NN:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2False N:h: j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) 1 / 2N NN:h: j N, k N, Section_4_3.dist ((-1) ^ j) ((-1) ^ k) 1 / 2N + 1 NN:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2False try N:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2False N:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2h':Even NFalseN:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2h':¬Even NFalse N:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2h':Even NFalse N:h':Even Nh:|1 + 1| 2⁻¹False All goals completed! 🐙 N:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2h':¬Even Nh₁:Odd NFalse N:h:Section_4_3.dist ((-1) ^ N) ((-1) ^ (N + 1)) 1 / 2h':¬Even Nh₁:Odd Nh₂:Even (N + 1)False N:h':¬Even Nh₁:Odd Nh₂:Even (N + 1)h:|-1 - 1| 2⁻¹False All goals completed! 🐙

Lemma 5.1.14

lemma IsBounded.finite {n:} (a: Fin n ) : M 0, BoundedBy a M := n:a:Fin n M 0, BoundedBy a M -- this proof is written to follow the structure of the original text. a:Fin 0 M 0, BoundedBy a Mn:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) M 0, BoundedBy a M a:Fin 0 M 0, BoundedBy a M a:Fin 0 0 0 BoundedBy a 0; All goals completed! 🐙 n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSucc M 0, BoundedBy a M n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' M M 0, BoundedBy a M have h1 : BoundedBy a' (M + |a (Fin.ofNat _ n)|) := fun m (hM m).trans (n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mm:Fin nM M + |a (Fin.ofNat (n + 1) n)| All goals completed! 🐙) have h2 : |a (Fin.ofNat _ n)| M + |a (Fin.ofNat _ n)| := n:a:Fin n M 0, BoundedBy a M All goals completed! 🐙 refine M + |a (Fin.ofNat _ n)|, n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:BoundedBy a' (M + |a (Fin.ofNat (n + 1) n)|)h2:|a (Fin.ofNat (n + 1) n)| M + |a (Fin.ofNat (n + 1) n)|M + |a (Fin.ofNat (n + 1) n)| 0 All goals completed! 🐙, ?_ n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:BoundedBy a' (M + |a (Fin.ofNat (n + 1) n)|)h2:|a (Fin.ofNat (n + 1) n)| M + |a (Fin.ofNat (n + 1) n)|m:Fin (n + 1)|a m| M + |a (Fin.ofNat (n + 1) n)|; n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:BoundedBy a' (M + |a (Fin.ofNat (n + 1) n)|)h2:|a (Fin.ofNat (n + 1) n)| M + |a (Fin.ofNat (n + 1) n)|j:Fin n|a j.castSucc| M + |a (Fin.ofNat (n + 1) n)|n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:BoundedBy a' (M + |a (Fin.ofNat (n + 1) n)|)h2:|a (Fin.ofNat (n + 1) n)| M + |a (Fin.ofNat (n + 1) n)||a (Fin.last n)| M + |a (Fin.ofNat (n + 1) n)| n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:BoundedBy a' (M + |a (Fin.ofNat (n + 1) n)|)h2:|a (Fin.ofNat (n + 1) n)| M + |a (Fin.ofNat (n + 1) n)|j:Fin n|a j.castSucc| M + |a (Fin.ofNat (n + 1) n)| All goals completed! 🐙 n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin n := fun m a m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:BoundedBy a' (M + |a (Fin.ofNat (n + 1) n)|)h2:|a (Fin.ofNat (n + 1) n)| M + |a (Fin.ofNat (n + 1) n)|Fin.last n = Fin.ofNat (n + 1) n; All goals completed! 🐙

Lemma 5.1.15 (Cauchy sequences are bounded) / Exercise 5.1.1

lemma declaration uses `sorry`Sequence.isBounded_of_isCauchy {a:Sequence} (h: a.IsCauchy) : a.IsBounded := a:Sequenceh:a.IsCauchya.IsBounded All goals completed! 🐙

Exercise 5.1.2

theorem declaration uses `sorry`Sequence.isBounded_add {a b: } (ha: (a:Sequence).IsBounded) (hb: (b:Sequence).IsBounded): (a + b:Sequence).IsBounded := a: b: ha:(↑a).IsBoundedhb:(↑b).IsBounded(↑(a + b)).IsBounded All goals completed! 🐙
theorem declaration uses `sorry`Sequence.isBounded_sub {a b: } (ha: (a:Sequence).IsBounded) (hb: (b:Sequence).IsBounded): (a - b:Sequence).IsBounded := a: b: ha:(↑a).IsBoundedhb:(↑b).IsBounded(↑(a - b)).IsBounded All goals completed! 🐙theorem declaration uses `sorry`Sequence.isBounded_mul {a b: } (ha: (a:Sequence).IsBounded) (hb: (b:Sequence).IsBounded): (a * b:Sequence).IsBounded := a: b: ha:(↑a).IsBoundedhb:(↑b).IsBounded(↑(a * b)).IsBounded All goals completed! 🐙end Chapter5