Cauchy sequences

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 Unknown identifier `ε`ε-steadiness, eventual Unknown identifier `ε`ε-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 Unknown identifier `n₀`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; Unknown identifier `ofNatFun`ofNatFun performs this conversion.

The Unknown identifier `coe`coe attribute allows the delaborator to print sorry : SequenceSequence.ofNatFun Unknown identifier `f`f as Unknown identifier `f`f, which is more concise; you may safely remove this if you prefer the more explicit notation.

@[coe] def Sequence.ofNatFun (a : ) : Sequence where n₀ := 0 seq n := if n 0 then a n.toNat else 0 vanish := a: n < 0, (if n 0 then a n.toNat else 0) = 0 All goals completed! 🐙
fun x => x ^ 2 : Sequence

If is used in a context where a Chapter5.Sequence : TypeSequence is expected, automatically coerce Unknown identifier `a`a to sorry : SequenceSequence.ofNatFun Unknown identifier `a`a (which will be pretty-printed as Unknown identifier `a`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 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) ε: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! 🐙 ε: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 Chapter5.Rat.Steady.coe (ε : ) (a : ) : ε.Steady a (n m : ), ε.Close (a n) (a m)Rat.Steady.coe

example : (1:).Steady ((fun _: (3:)):Sequence) := Rat.Steady 1 fun x => 3 All goals completed! 🐙

Compare: if you need to work with Rat.Steady (ε : ) (a : Sequence) : PropRat.Steady on the coercion directly, there will be side conditions and that you will need to deal with.

example : (1:).Steady ((fun _: (3:)):Sequence) := Rat.Steady 1 fun x => 3 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 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) 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 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)) 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 n:m:h:m n0 10 ^ (-n - 1) 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); 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! 🐙

a.from n₁ starts from Unknown identifier `n₁`n₁. It is intended for use when Unknown identifier `n₁`sorry sorry : Propn₁ Unknown identifier `n₀`n₀, but returns the "junk" value of the original sequence Unknown identifier `a`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; h:|2 / 3| 1 / 10False h:2 / 3 1 / 10Falseh:|2 / 3| 1 / 100 2 / 3 h:2 / 3 1 / 10Falseh:|2 / 3| 1 / 100 2 / 3 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) 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:(_fvar.85687 + 1)⁻¹ (_fvar.85688 + 1)⁻¹ := ?_mvar.86752(m + 1)⁻¹ - (n + 1)⁻¹ 10⁻¹ - 0 n:m:hn:10 nhm:10 mh:m nthis:(_fvar.85687 + 1)⁻¹ (_fvar.85688 + 1)⁻¹ := ?_mvar.8675210 m + 1n:m:hn:10 nhm:10 mh:m nthis:(_fvar.85687 + 1)⁻¹ (_fvar.85688 + 1)⁻¹ := ?_mvar.867520 (n + 1)⁻¹ n:m:hn:10 nhm:10 mh:m nthis:(_fvar.85687 + 1)⁻¹ (_fvar.85688 + 1)⁻¹ := ?_mvar.8675210 m + 1 n:m:hn:10 nhm:10 mh:m nthis:(_fvar.85687 + 1)⁻¹ (_fvar.85688 + 1)⁻¹ := ?_mvar.8675210 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 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) ε 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! 🐙, ?_ 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 _fvar.131394 := ?_mvar.137582ε.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 _fvar.131394 := ?_mvar.137582mpos:0 _fvar.131400 := ?_mvar.137624ε.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 _fvar.131394 := ?_mvar.1375820 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 _fvar.131400 := ?_mvar.137624n: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 _fvar.131394 := ?_mvar.1375820 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 _fvar.131394 := ?_mvar.1375820 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 _fvar.131394 := ?_mvar.1375820 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 _fvar.131394 := ?_mvar.1375820 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 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) ε; 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! 🐙, ?_ 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) ε ε::ε > 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':_fvar.250039 > 0 := Eq.mp (Eq.trans (congrArg (fun x => x < _fvar.250039) (Eq.symm Nat.cast_zero)) Nat.cast_lt._simp_1) (gt_trans _fvar.250040 (one_div_pos.mpr _fvar.249878))N 1 All goals completed! 🐙, ?_ ε::ε > 0N:hN:N > 1 / εhN':_fvar.250039 > 0 := ?_mvar.251160j: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':_fvar.250039 > 0 := Eq.mp (Eq.trans (congrArg (fun x => x < _fvar.250039) (Eq.symm Nat.cast_zero)) Nat.cast_lt._simp_1) (gt_trans _fvar.250040 (one_div_pos.mpr _fvar.249878))j:hj:j Nk:hk:k N0 j All goals completed! 🐙) lift k to using (ε::ε > 0N:hN:N > 1 / εhN':_fvar.250039 > 0 := Eq.mp (Eq.trans (congrArg (fun x => x < _fvar.250039) (Eq.symm Nat.cast_zero)) Nat.cast_lt._simp_1) (gt_trans _fvar.250040 (one_div_pos.mpr _fvar.249878))k:hk:k Nj:hj:j N0 k All goals completed! 🐙) ε::ε > 0N:hN:N > 1 / εhN':_fvar.250039 > 0 := ?_mvar.251160j: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':_fvar.250039 > 0 := ?_mvar.251160j: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':_fvar.250039 > 0 := ?_mvar.251160j: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':_fvar.250039 > 0 := ?_mvar.251160j:k:hj:N jhk:N kthis✝:1 / _fvar.497087 1 / _fvar.250039 := ?_mvar.514962this: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':_fvar.250039 > 0 := ?_mvar.251160j:k:hj:N jhk:N kthis✝²:1 / _fvar.497087 1 / _fvar.250039 := ?_mvar.514962this✝¹:0 1 / jthis✝:1 / _fvar.499385 1 / _fvar.250039 := ?_mvar.529008this: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 _fvar.572699 := fun m => @_fvar.572704 m.castSucc M 0, BoundedBy a M n:hn: (a : Fin n ), M 0, BoundedBy a Ma:Fin (n + 1) a':Fin _fvar.572699 := fun m => @_fvar.572704 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 _fvar.572699 := fun m => @_fvar.572704 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 _fvar.572699 := fun m => @_fvar.572704 m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:Chapter5.BoundedBy _fvar.572972 (_fvar.573031 + |@_fvar.572704 (Fin.ofNat (_fvar.572699 + 1) _fvar.572699)|) := fun m => LE.le.trans (@_fvar.573043 m) (of_eq_true (Eq.trans (Eq.trans (congrArg (fun x => _fvar.573031 _fvar.573031 + |@_fvar.572704 x|) (Fin.natCast_eq_last _fvar.572699)) (le_mul_iff_one_le_right'._simp_4 _fvar.573031)) (one_le_mabs._simp_4 (@_fvar.572704 (Fin.last _fvar.572699)))))h2:|@_fvar.572704 (Fin.ofNat (_fvar.572699 + 1) _fvar.572699)| _fvar.573031 + |@_fvar.572704 (Fin.ofNat (_fvar.572699 + 1) _fvar.572699)| := of_eq_true (Eq.trans (Eq.trans (congr (congrArg (fun x => LE.le |@_fvar.572704 x|) (Fin.natCast_eq_last _fvar.572699)) (congrArg (fun x => _fvar.573031 + |@_fvar.572704 x|) (Fin.natCast_eq_last _fvar.572699))) (le_mul_iff_one_le_left'._simp_4 |@_fvar.572704 (Fin.last _fvar.572699)|)) (eq_true _fvar.573039))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 _fvar.572699 := fun m => @_fvar.572704 m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:Chapter5.BoundedBy _fvar.572972 (_fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.573059 _fvar.572699)|) := fun m => LE.le.trans (@_fvar.573043 m) (@?_mvar.573201 m)h2:|@_fvar.572704 (Fin.ofNat ?_mvar.575355 _fvar.572699)| _fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.575438 _fvar.572699)| := ?_mvar.575521m: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 _fvar.572699 := fun m => @_fvar.572704 m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:Chapter5.BoundedBy _fvar.572972 (_fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.573059 _fvar.572699)|) := fun m => LE.le.trans (@_fvar.573043 m) (@?_mvar.573201 m)h2:|@_fvar.572704 (Fin.ofNat ?_mvar.575355 _fvar.572699)| _fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.575438 _fvar.572699)| := ?_mvar.575521j: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 _fvar.572699 := fun m => @_fvar.572704 m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:Chapter5.BoundedBy _fvar.572972 (_fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.573059 _fvar.572699)|) := fun m => LE.le.trans (@_fvar.573043 m) (@?_mvar.573201 m)h2:|@_fvar.572704 (Fin.ofNat ?_mvar.575355 _fvar.572699)| _fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.575438 _fvar.572699)| := ?_mvar.575521|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 _fvar.572699 := fun m => @_fvar.572704 m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:Chapter5.BoundedBy _fvar.572972 (_fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.573059 _fvar.572699)|) := fun m => LE.le.trans (@_fvar.573043 m) (@?_mvar.573201 m)h2:|@_fvar.572704 (Fin.ofNat ?_mvar.575355 _fvar.572699)| _fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.575438 _fvar.572699)| := ?_mvar.575521j: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 _fvar.572699 := fun m => @_fvar.572704 m.castSuccM:hpos:M 0hM:BoundedBy a' Mh1:Chapter5.BoundedBy _fvar.572972 (_fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.573059 _fvar.572699)|) := fun m => LE.le.trans (@_fvar.573043 m) (@?_mvar.573201 m)h2:|@_fvar.572704 (Fin.ofNat ?_mvar.575355 _fvar.572699)| _fvar.573031 + |@_fvar.572704 (Fin.ofNat ?_mvar.575438 _fvar.572699)| := ?_mvar.575521Fin.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