Imports
import Mathlib.Tactic import Analysis.Section_5_2 import Mathlib.Algebra.Group.MinimalAxioms

Analysis I, Section 5.3: The construction of the real numbers

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 formal limit of a Cauchy sequence.

  • Construction of a real number type Chapter5.Real.

  • Basic arithmetic operations and properties.

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

A class of Cauchy sequences that start at zero.

@[ext] class CauchySequence extends Sequence where zero : n₀ = 0 cauchy : toSequence.IsCauchy
theorem CauchySequence.ext' {a b: CauchySequence} (h: a.seq = b.seq) : a = b := a:CauchySequenceb:CauchySequenceh:a.seq = b.seqa = b a:CauchySequenceb:CauchySequenceh:a.seq = b.seqa.n₀ = b.n₀ All goals completed! 🐙

A sequence starting at zero that is Cauchy, can be viewed as a CauchySequence.

abbrev CauchySequence.mk' {a: } (ha: (a:Sequence).IsCauchy) : CauchySequence where n₀ := 0 seq := (a:Sequence).seq vanish := a: ha:(↑a).IsCauchy n < 0, (↑a).seq n = 0 All goals completed! 🐙 zero := rfl cauchy := ha
@[simp] theorem CauchySequence.coe_eq {a: } (ha: (a:Sequence).IsCauchy) : (mk' ha).toSequence = (a:Sequence) := rflinstance CauchySequence.instCoeFun : CoeFun CauchySequence (fun _ ) where coe a n := a.toSequence (n:)@[simp] theorem CauchySequence.coe_to_sequence (a: CauchySequence) : ((a: ):Sequence) = a.toSequence := a:CauchySequence(↑fun n a.seq n) = a.toSequence apply Sequence.ext (a:CauchySequence(↑fun n a.seq n).n₀ = a.n₀ All goals completed! 🐙) a:CauchySequencen:(↑fun n a.seq n).seq n = a.seq n; a:CauchySequencen:h:n 0(↑fun n a.seq n).seq n = a.seq na:CauchySequencen:h:¬n 0(↑fun n a.seq n).seq n = a.seq n a:CauchySequencen:h:n 0(↑fun n a.seq n).seq n = a.seq na:CauchySequencen:h:¬n 0(↑fun n a.seq n).seq n = a.seq n a:CauchySequencen:h:n < 00 = a.seq n a:CauchySequencen:h:n < 0n < a.n₀; rwa [a.zeroa:CauchySequencen:h:n < 0n < 0@[simp] theorem CauchySequence.coe_coe {a: } (ha: (a:Sequence).IsCauchy) : mk' ha = a := a: ha:(↑a).IsCauchy(fun n (mk' ha).seq n) = a All goals completed! 🐙

Proposition 5.3.3 / Exercise 5.3.1

theorem declaration uses `sorry`Sequence.equiv_trans {a b c: } (hab: Equiv a b) (hbc: Equiv b c) : Equiv a c := a: b: c: hab:Equiv a bhbc:Equiv b cEquiv a c All goals completed! 🐙

Proposition 5.3.3 / Exercise 5.3.1

instance declaration uses `sorry`CauchySequence.instSetoid : Setoid CauchySequence where r := fun a b Sequence.Equiv a b iseqv := { refl := sorry symm := sorry trans := sorry }
theorem CauchySequence.equiv_iff (a b: CauchySequence) : a b Sequence.Equiv a b := a:CauchySequenceb:CauchySequencea b Sequence.Equiv (fun n a.seq n) fun n b.seq n All goals completed! 🐙

Every constant sequence is Cauchy.

theorem declaration uses `sorry`Sequence.IsCauchy.const (a:) : ((fun _: a):Sequence).IsCauchy := a:(↑fun x a).IsCauchy All goals completed! 🐙
instance CauchySequence.instZero : Zero CauchySequence where zero := CauchySequence.mk' (a := fun _: 0) (Sequence.IsCauchy.const (0:))abbrev Real := Quotient CauchySequence.instSetoid

It is convenient in Lean to assign the "dummy" value of 0 to LIM a when a is not Cauchy. This requires classical logic, because the property of being Cauchy is not computable or decidable.

open Classical innoncomputable abbrev LIM (a: ) : Real := Quotient.mk _ (if h : (a:Sequence).IsCauchy then CauchySequence.mk' h else (0:CauchySequence))
theorem LIM_def {a: } (ha: (a:Sequence).IsCauchy) : LIM a = Quotient.mk _ (CauchySequence.mk' ha) := a: ha:(↑a).IsCauchyLIM a = CauchySequence.mk' ha All goals completed! 🐙

Definition 5.3.1 (Real numbers)

theorem Real.eq_lim (x:Real) : (a: ), (a:Sequence).IsCauchy x = LIM a := x:Real a, (↑a).IsCauchy x = LIM a x:Real (a : CauchySequence), a_1, (↑a_1).IsCauchy a = LIM a_1; x:Reala:CauchySequence a_1, (↑a_1).IsCauchy a = LIM a_1; x:Reala:CauchySequence(↑fun n a.seq n).IsCauchy a = LIM fun n a.seq n x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequence(↑fun n a.seq n).IsCauchy a = LIM fun n a.seq n x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequencea.IsCauchy a = CauchySequence.mk' x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequencea = CauchySequence.mk' x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequencea = CauchySequence.mk' ; x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequencea.n₀ = (CauchySequence.mk' ).n₀x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequencen:a.seq n = (CauchySequence.mk' ).seq n; x:Reala:CauchySequencethis:(↑fun n a.seq n) = a.toSequencen:a.seq n = (CauchySequence.mk' ).seq n; x:Reala:CauchySequencethis✝:(↑fun n a.seq n) = a.toSequencen:this:(↑fun n a.seq n).seq n = a.seq na.seq n = (CauchySequence.mk' ).seq n; All goals completed! 🐙

Definition 5.3.1 (Real numbers)

theorem Real.LIM_eq_LIM {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : LIM a = LIM b Sequence.Equiv a b := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a = LIM b Sequence.Equiv a b a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a = LIM b Sequence.Equiv a ba: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchySequence.Equiv a b LIM a = LIM b a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a = LIM b Sequence.Equiv a b a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:LIM a = LIM bSequence.Equiv a b; a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:(if h : (↑a).IsCauchy then CauchySequence.mk' h else 0) if h : (↑b).IsCauchy then CauchySequence.mk' h else 0Sequence.Equiv a b rwa [dif_pos ha, dif_pos hb, CauchySequence.equiv_iffa: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:Sequence.Equiv (fun n (CauchySequence.mk' ha).seq n) fun n (CauchySequence.mk' hb).seq nSequence.Equiv a b at h a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:Sequence.Equiv a bLIM a = LIM b; a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:Sequence.Equiv a b(if h : (↑a).IsCauchy then CauchySequence.mk' h else 0) if h : (↑b).IsCauchy then CauchySequence.mk' h else 0 rwa [dif_pos ha, dif_pos hb, CauchySequence.equiv_iffa: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:Sequence.Equiv a bSequence.Equiv (fun n (CauchySequence.mk' ha).seq n) fun n (CauchySequence.mk' hb).seq n

Lemma 5.3.6 (Sum of Cauchy sequences is Cauchy)

theorem Sequence.IsCauchy.add {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : (a + b:Sequence).IsCauchy := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchy(↑(a + b)).IsCauchy -- This proof is written to follow the structure of the original text. a: b: ha: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) ε ε > 0, N, j N, k N, Section_4_3.dist ((a + b) j) ((a + b) k) ε intro ε a: b: ha: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0 N, j N, k N, Section_4_3.dist ((a + b) j) ((a + b) k) ε a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2 N, j N, k N, Section_4_3.dist ((a + b) j) ((a + b) k) ε a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2 N, j N, k N, Section_4_3.dist ((a + b) j) ((a + b) k) ε a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2 j max N1 N2, k max N1 N2, Section_4_3.dist ((a + b) j) ((a + b) k) ε intro j a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2 k max N1 N2, Section_4_3.dist ((a + b) j) ((a + b) k) ε a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:k max N1 N2 Section_4_3.dist ((a + b) j) ((a + b) k) ε a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2Section_4_3.dist ((a + b) j) ((a + b) k) ε a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2Section_4_3.dist ((a + b) j) ((a + b) k) εa: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2j N1a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2k N1 a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2Section_4_3.dist ((a + b) j) ((a + b) k) εa: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2j N1a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2k N1 try All goals completed! 🐙 a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2h2:Section_4_3.dist (b j) (b k) ε / 2Section_4_3.dist ((a + b) j) ((a + b) k) εa: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2j N2a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2k N2 a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2h2:Section_4_3.dist (b j) (b k) ε / 2Section_4_3.dist ((a + b) j) ((a + b) k) εa: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2j N2a: b: ha✝: ε > 0, N, j N, k N, Section_4_3.dist (a j) (a k) εhb✝: ε > 0, N, j N, k N, Section_4_3.dist (b j) (b k) εε::ε > 0N1:ha: j N1, k N1, Section_4_3.dist (a j) (a k) ε / 2N2:hb: j N2, k N2, Section_4_3.dist (b j) (b k) ε / 2j:hj:j max N1 N2k:hk:k max N1 N2h1:Section_4_3.dist (a j) (a k) ε / 2k N2 try All goals completed! 🐙 a: b: ε:N1:N2:j:k:h1:|a j - a k| ε / 2h2:|b j - b k| ε / 2ha✝: (ε : ), 0 < ε N, (j : ), N j (k : ), N k |a j - a k| εhb✝: (ε : ), 0 < ε N, (j : ), N j (k : ), N k |b j - b k| ε:0 < εha: (j : ), N1 j (k : ), N1 k |a j - a k| ε / 2hb: (j : ), N2 j (k : ), N2 k |b j - b k| ε / 2hj:N1 j N2 jhk:N1 k N2 k|a j + b j - (a k + b k)| ε; a: b: ε:N1:N2:j:k:h1:(ε / 2).Close (a j) (a k)h2:(ε / 2).Close (b j) (b k)ha✝: (ε : ), 0 < ε N, (j : ), N j (k : ), N k |a j - a k| εhb✝: (ε : ), 0 < ε N, (j : ), N j (k : ), N k |b j - b k| ε:0 < εha: (j : ), N1 j (k : ), N1 k |a j - a k| ε / 2hb: (j : ), N2 j (k : ), N2 k |b j - b k| ε / 2hj:N1 j N2 jhk:N1 k N2 kε.Close (a j + b j) (a k + b k) a: b: ε:N1:N2:j:k:h1:(ε / 2).Close (a j) (a k)h2:(ε / 2).Close (b j) (b k)ha✝: (ε : ), 0 < ε N, (j : ), N j (k : ), N k |a j - a k| εhb✝: (ε : ), 0 < ε N, (j : ), N j (k : ), N k |b j - b k| ε:0 < εha: (j : ), N1 j (k : ), N1 k |a j - a k| ε / 2hb: (j : ), N2 j (k : ), N2 k |b j - b k| ε / 2hj:N1 j N2 jhk:N1 k N2 kε = ε / 2 + ε / 2 All goals completed! 🐙

Lemma 5.3.7 (Sum of equivalent sequences is equivalent)

theorem Sequence.add_equiv_left {a a': } (b: ) (haa': Equiv a a') : Equiv (a + b) (a' + b) := a: a': b: haa':Equiv a a'Equiv (a + b) (a' + b) -- This proof is written to follow the structure of the original text. a: a': b: haa': ε > 0, ε.EventuallyClose a a' ε > 0, ε.EventuallyClose (a + b) (a' + b) a: a': b: haa'✝: ε > 0, ε.EventuallyClose a a'ε::ε > 0haa':ε.EventuallyClose a a'ε.EventuallyClose (a + b) (a' + b) a: a': b: haa'✝: ε > 0, ε.EventuallyClose a a'ε::ε > 0haa': N, ε.CloseSeq ((↑a).from N) ((↑a').from N) N, ε.CloseSeq ((↑(a + b)).from N) ((↑(a' + b)).from N) a: a': b: haa'✝: ε > 0, ε.EventuallyClose a a'ε::ε > 0N:haa':ε.CloseSeq ((↑a).from N) ((↑a').from N) N, ε.CloseSeq ((↑(a + b)).from N) ((↑(a' + b)).from N); a: a': b: haa'✝: ε > 0, ε.EventuallyClose a a'ε::ε > 0N:haa':ε.CloseSeq ((↑a).from N) ((↑a').from N)ε.CloseSeq ((↑(a + b)).from N) ((↑(a' + b)).from N) a: a': b: ε:N:haa'✝: (ε : ), 0 < ε ε.EventuallyClose a a':0 < εhaa': (n : ), 0 n N n 0 n N n ε.Close (if 0 n N n then if 0 n then a n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat else 0 else 0) (n : ), 0 n N n 0 n N n ε.Close (if 0 n N n then if 0 n then a n.toNat + b n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat + b n.toNat else 0 else 0) a: a': b: ε:N:haa'✝¹: (ε : ), 0 < ε ε.EventuallyClose a a':0 < εhaa'✝: (n : ), 0 n N n 0 n N n ε.Close (if 0 n N n then if 0 n then a n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat else 0 else 0)n:hn:0 nhN:N na✝¹:0 na✝:N nhaa':ε.Close (if 0 n N n then if 0 n then a n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat else 0 else 0)ε.Close (if 0 n N n then if 0 n then a n.toNat + b n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat + b n.toNat else 0 else 0) a: a': b: ε:N:haa'✝¹: (ε : ), 0 < ε ε.EventuallyClose a a':0 < εhaa'✝: (n : ), 0 n N n 0 n N n ε.Close (if 0 n N n then if 0 n then a n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat else 0 else 0)n:hn:TruehN:Truea✝¹:Truea✝:Truehaa':ε.Close (a n.toNat) (a' n.toNat)ε.Close (a n.toNat + b n.toNat) (a' n.toNat + b n.toNat) a: a': b: ε:N:haa'✝¹: (ε : ), 0 < ε ε.EventuallyClose a a':0 < εhaa'✝: (n : ), 0 n N n 0 n N n ε.Close (if 0 n N n then if 0 n then a n.toNat else 0 else 0) (if 0 n N n then if 0 n then a' n.toNat else 0 else 0)n:hn:TruehN:Truea✝¹:Truea✝:Truehaa':ε.Close (a n.toNat) (a' n.toNat)ε = ε + 0 All goals completed! 🐙

Lemma 5.3.7 (Sum of equivalent sequences is equivalent)

theorem Sequence.add_equiv_right {b b': } (a: ) (hbb': Equiv b b') : Equiv (a + b) (a + b') := b: b': a: hbb':Equiv b b'Equiv (a + b) (a + b') simp_rw b: b': a: hbb':Equiv b b'Equiv (a + b) (a + b')add_comm]; All goals completed! 🐙

Lemma 5.3.7 (Sum of equivalent sequences is equivalent)

theorem Sequence.add_equiv {a b a' b': } (haa': Equiv a a') (hbb': Equiv b b') : Equiv (a + b) (a' + b') := equiv_trans (add_equiv_left _ haa') (add_equiv_right _ hbb')

Definition 5.3.4 (Addition of reals)

noncomputable instance Real.add_inst : Add Real where add := fun x y Quotient.liftOn₂ x y (fun a b LIM (a + b)) (x:Realy:Real (a₁ b₁ a₂ b₂ : CauchySequence), a₁ a₂ b₁ b₂ (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a₁ b₁ = (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a₂ b₂ intro a x:Realy:Reala:CauchySequenceb:CauchySequence (a₂ b₂ : CauchySequence), a a₂ b b₂ (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a₂ b₂ x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequence (b₂ : CauchySequence), a a' b b₂ (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a' b₂ x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea a' b b' (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a' b' x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝:a a'b b' (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a' b' x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) + fun n b.seq n)) a' b' x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'LIM ((fun n a.seq n) + fun n b.seq n) = LIM ((fun n a'.seq n) + fun n b'.seq n) x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'Sequence.Equiv ((fun n a.seq n) + fun n b.seq n) ((fun n a'.seq n) + fun n b'.seq n)x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(↑((fun n a.seq n) + fun n b.seq n)).IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(↑((fun n a'.seq n) + fun n b'.seq n)).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'Sequence.Equiv ((fun n a.seq n) + fun n b.seq n) ((fun n a'.seq n) + fun n b'.seq n) All goals completed! 🐙 all_goals x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(↑fun n a'.seq n).IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(↑fun n b'.seq n).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(↑fun n a'.seq n).IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'(↑fun n b'.seq n).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'b'.IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'a'.IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea✝¹:a a'a✝:b b'b'.IsCauchy All goals completed! 🐙 )

Definition 5.3.4 (Addition of reals)

theorem Real.LIM_add {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : LIM a + LIM b = LIM (a + b) := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a + LIM b = LIM (a + b) simp_rw a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a + LIM b = LIM (a + b)LIM_def ha, LIM_def hb, LIM_def (Sequence.IsCauchy.add ha hb)] a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyCauchySequence.mk' = LIM ((fun n (CauchySequence.mk' ha).seq n) + fun n (CauchySequence.mk' hb).seq n) a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyCauchySequence.mk' = if h : (↑((fun n (↑a).seq n) + fun n (↑b).seq n)).IsCauchy then CauchySequence.mk' else 0; All goals completed! 🐙

Proposition 5.3.10 (Product of Cauchy sequences is Cauchy)

theorem declaration uses `sorry`Sequence.IsCauchy.mul {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : (a * b:Sequence).IsCauchy := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchy(↑(a * b)).IsCauchy All goals completed! 🐙

Proposition 5.3.10 (Product of equivalent sequences is equivalent) / Exercise 5.3.2

theorem declaration uses `sorry`Sequence.mul_equiv_left {a a': } (b: ) (hb : (b:Sequence).IsCauchy) (haa': Equiv a a') : Equiv (a * b) (a' * b) := a: a': b: hb:(↑b).IsCauchyhaa':Equiv a a'Equiv (a * b) (a' * b) All goals completed! 🐙

Proposition 5.3.10 (Product of equivalent sequences is equivalent) / Exercise 5.3.2

theorem Sequence.mul_equiv_right {b b': } (a: ) (ha : (a:Sequence).IsCauchy) (hbb': Equiv b b') : Equiv (a * b) (a * b') := b: b': a: ha:(↑a).IsCauchyhbb':Equiv b b'Equiv (a * b) (a * b') simp_rw b: b': a: ha:(↑a).IsCauchyhbb':Equiv b b'Equiv (a * b) (a * b')mul_comm]; All goals completed! 🐙

Proposition 5.3.10 (Product of equivalent sequences is equivalent) / Exercise 5.3.2

theorem Sequence.mul_equiv {a b a' b': } (ha : (a:Sequence).IsCauchy) (hb' : (b':Sequence).IsCauchy) (haa': Equiv a a') (hbb': Equiv b b') : Equiv (a * b) (a' * b') := equiv_trans (mul_equiv_right _ ha hbb') (mul_equiv_left _ hb' haa')

Definition 5.3.9 (Product of reals)

noncomputable instance Real.mul_inst : Mul Real where mul := fun x y Quotient.liftOn₂ x y (fun a b LIM (a * b)) (x:Realy:Real (a₁ b₁ a₂ b₂ : CauchySequence), a₁ a₂ b₁ b₂ (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a₁ b₁ = (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a₂ b₂ intro a x:Realy:Reala:CauchySequenceb:CauchySequence (a₂ b₂ : CauchySequence), a a₂ b b₂ (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a₂ b₂ x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequence (b₂ : CauchySequence), a a' b b₂ (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a' b₂ x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencea a' b b' (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a' b' x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'b b' (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a' b' x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a b = (fun a b LIM ((fun n a.seq n) * fun n b.seq n)) a' b' x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'LIM ((fun n a.seq n) * fun n b.seq n) = LIM ((fun n a'.seq n) * fun n b'.seq n) x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'Sequence.Equiv ((fun n a.seq n) * fun n b.seq n) ((fun n a'.seq n) * fun n b'.seq n)x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑((fun n a.seq n) * fun n b.seq n)).IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑((fun n a'.seq n) * fun n b'.seq n)).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'Sequence.Equiv ((fun n a.seq n) * fun n b.seq n) ((fun n a'.seq n) * fun n b'.seq n) exact Sequence.mul_equiv (x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑fun n a.seq n).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'a.IsCauchy; All goals completed! 🐙) (x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑fun n b'.seq n).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'b'.IsCauchy; All goals completed! 🐙) haa' hbb' all_goals x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑fun n a'.seq n).IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑fun n b'.seq n).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑fun n a'.seq n).IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'(↑fun n b'.seq n).IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'b'.IsCauchy x:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'a'.IsCauchyx:Realy:Reala:CauchySequenceb:CauchySequencea':CauchySequenceb':CauchySequencehaa':a a'hbb':b b'b'.IsCauchy All goals completed! 🐙 )
theorem Real.LIM_mul {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : LIM a * LIM b = LIM (a * b) := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a * LIM b = LIM (a * b) simp_rw a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a * LIM b = LIM (a * b)LIM_def ha, LIM_def hb, LIM_def (Sequence.IsCauchy.mul ha hb)] a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyCauchySequence.mk' = LIM ((fun n (CauchySequence.mk' ha).seq n) * fun n (CauchySequence.mk' hb).seq n) a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyCauchySequence.mk' = if h : (↑((fun n (↑a).seq n) * fun n (↑b).seq n)).IsCauchy then CauchySequence.mk' else 0; All goals completed! 🐙instance Real.instRatCast : RatCast Real where ratCast := fun q Quotient.mk _ (CauchySequence.mk' (a := fun _ q) (Sequence.IsCauchy.const q))theorem Real.ratCast_def (q:) : (q:Real) = LIM (fun _ q) := q:q = LIM fun x q q:q = CauchySequence.mk' ?m.5q:(↑fun x q).IsCauchy; All goals completed! 🐙

Exercise 5.3.3

@[simp] theorem declaration uses `sorry`Real.ratCast_inj (q r:) : (q:Real) = (r:Real) q = r := q:r:q = r q = r All goals completed! 🐙
instance Real.instOfNat {n:} : OfNat Real n where ofNat := ((n:):Real)instance Real.instNatCast : NatCast Real where natCast n := ((n:):Real)@[simp] theorem Real.LIM.zero : LIM (fun _ (0:)) = 0 := (LIM fun x 0) = 0 0 = 0; All goals completed! 🐙instance Real.instIntCast : IntCast Real where intCast n := ((n:):Real)

ratCast distributes over addition

theorem declaration uses `sorry`Real.ratCast_add (a b:) : (a:Real) + (b:Real) = (a+b:) := a:b:a + b = (a + b) All goals completed! 🐙

ratCast distributes over multiplication

theorem declaration uses `sorry`Real.ratCast_mul (a b:) : (a:Real) * (b:Real) = (a*b:) := a:b:a * b = (a * b) All goals completed! 🐙
noncomputable instance Real.instNeg : Neg Real where neg x := ((-1:):Real) * x

ratCast commutes with negation

theorem declaration uses `sorry`Real.neg_ratCast (a:) : -(a:Real) = (-a:) := a:-a = (-a) All goals completed! 🐙

It may be possible to omit the IsCauchy hypothesis here.

theorem declaration uses `sorry`Real.neg_LIM (a: ) (ha: (a:Sequence).IsCauchy) : -LIM a = LIM (-a) := a: ha:(↑a).IsCauchy-LIM a = LIM (-a) All goals completed! 🐙
theorem declaration uses `sorry`Sequence.IsCauchy.neg (a: ) (ha: (a:Sequence).IsCauchy) : ((-a: ):Sequence).IsCauchy := a: ha:(↑a).IsCauchy(↑(-a)).IsCauchy All goals completed! 🐙

Proposition 5.3.11 (laws of algebra)

noncomputable instance declaration uses `sorry`Real.addGroup_inst : AddGroup Real := AddGroup.ofLeftAxioms ( (a b c : Real), a + b + c = a + (b + c) All goals completed! 🐙) ( (a : Real), 0 + a = a All goals completed! 🐙) ( (a : Real), -a + a = 0 All goals completed! 🐙)
theorem Real.sub_eq_add_neg (x y:Real) : x - y = x + (-y) := rfltheorem declaration uses `sorry`Sequence.IsCauchy.sub {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : ((a-b: ):Sequence).IsCauchy := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchy(↑(a - b)).IsCauchy All goals completed! 🐙

LIM distributes over subtraction

theorem declaration uses `sorry`Real.LIM_sub {a b: } (ha: (a:Sequence).IsCauchy) (hb: (b:Sequence).IsCauchy) : LIM a - LIM b = LIM (a - b) := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyLIM a - LIM b = LIM (a - b) All goals completed! 🐙

ratCast distributes over subtraction

theorem declaration uses `sorry`Real.ratCast_sub (a b:) : (a:Real) - (b:Real) = (a-b:) := a:b:a - b = (a - b) All goals completed! 🐙

Proposition 5.3.11 (laws of algebra)

noncomputable instance declaration uses `sorry`Real.instAddCommGroup : AddCommGroup Real where add_comm := (a b : Real), a + b = b + a All goals completed! 🐙

Proposition 5.3.11 (laws of algebra)

noncomputable instance declaration uses `sorry`Real.instCommMonoid : CommMonoid Real where mul_comm := (a b : Real), a * b = b * a All goals completed! 🐙 mul_assoc := (a b c : Real), a * b * c = a * (b * c) All goals completed! 🐙 one_mul := (a : Real), 1 * a = a All goals completed! 🐙 mul_one := (a : Real), a * 1 = a All goals completed! 🐙

Proposition 5.3.11 (laws of algebra)

noncomputable instance declaration uses `sorry`Real.instCommRing : CommRing Real where left_distrib := (a b c : Real), a * (b + c) = a * b + a * c All goals completed! 🐙 right_distrib := (a b c : Real), (a + b) * c = a * c + b * c All goals completed! 🐙 zero_mul := (a : Real), 0 * a = 0 All goals completed! 🐙 mul_zero := (a : Real), a * 0 = 0 All goals completed! 🐙 mul_assoc := (a b c : Real), a * b * c = a * (b * c) All goals completed! 🐙 natCast_succ := (n : ), (n + 1) = n + 1 All goals completed! 🐙 intCast_negSucc := (n : ), IntCast.intCast (Int.negSucc n) = -(n + 1) All goals completed! 🐙
abbrev declaration uses `sorry`Real.ratCast_hom : →+* Real where toFun := RatCast.ratCast map_zero' := RatCast.ratCast 0 = 0 All goals completed! 🐙 map_one' := RatCast.ratCast 1 = 1 All goals completed! 🐙 map_add' := (x y : ), RatCast.ratCast (x + y) = RatCast.ratCast x + RatCast.ratCast y All goals completed! 🐙 map_mul' := (x y : ), RatCast.ratCast (x * y) = RatCast.ratCast x * RatCast.ratCast y All goals completed! 🐙

Definition 5.3.12 (sequences bounded away from zero). Sequences are indexed to start from zero as this is more convenient for Mathlib purposes.

abbrev BoundedAwayZero (a: ) : Prop := (c:), c > 0 n, |a n| c
theorem bounded_away_zero_def (a: ) : BoundedAwayZero a (c:), c > 0 n, |a n| c := a: BoundedAwayZero a c > 0, (n : ), |a n| c All goals completed! 🐙/-- Examples 5.3.13 -/ example : BoundedAwayZero (fun n (-1)^n) := BoundedAwayZero fun n (-1) ^ n 1 > 0 (n : ), |(fun n (-1) ^ n) n| 1; All goals completed! 🐙/-- Examples 5.3.13 -/ declaration uses `sorry`example : ¬ BoundedAwayZero (fun n 10^(-(n:)-1)) := ¬BoundedAwayZero fun n 10 ^ (-n - 1) All goals completed! 🐙/-- Examples 5.3.13 -/ declaration uses `sorry`example : ¬ BoundedAwayZero (fun n 1 - 10^(-(n:))) := ¬BoundedAwayZero fun n 1 - 10 ^ (-n) All goals completed! 🐙/-- Examples 5.3.13 -/ example : BoundedAwayZero (fun n 10^(n+1)) := BoundedAwayZero fun n 10 ^ (n + 1) use 1, 1 > 0 All goals completed! 🐙 n:|(fun n 10 ^ (n + 1)) n| 1; n:|10 ^ (n + 1)| 1 n:10 ^ (n + 1) 10 ^ 0 n:1 10n:0 n + 1 n:1 10n:0 n + 1 All goals completed! 🐙/-- Examples 5.3.13 -/ declaration uses `sorry`example : ¬ ((fun (n:) (10:)^(n+1)):Sequence).IsBounded := ¬(↑fun n 10 ^ (n + 1)).IsBounded All goals completed! 🐙

Lemma 5.3.14

theorem declaration uses `sorry`Real.boundedAwayZero_of_nonzero {x:Real} (hx: x 0) : a: , (a:Sequence).IsCauchy BoundedAwayZero a x = LIM a := x:Realhx:x 0 a, (↑a).IsCauchy BoundedAwayZero a x = LIM a -- This proof is written to follow the structure of the original text. b: hb:(↑b).IsCauchyhx:LIM b 0 a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a b: hb:(↑b).IsCauchyhx:¬LIM b = LIM fun x 0 a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a b: hb:(↑b).IsCauchyhx:¬ ε > 0, N, n N, |b n - 0| ε a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a b: hb:(↑b).IsCauchyhx: x, 0 < x (x_1 : ), x_2, x_1 x_2 x < |b x_2| a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a b: hb:(↑b).IsCauchyε::0 < εhx: (x : ), x_1, x x_1 ε < |b x_1| a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a b: hb:(↑b).IsCauchyε::0 < εhx: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2 a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀| a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a have how : j N, |b j| ε/2 := x:Realhx:x 0 a, (↑a).IsCauchy BoundedAwayZero a x = LIM a All goals completed! 🐙 b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b n a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a have not_hard : Sequence.Equiv a b := x:Realhx:x 0 a, (↑a).IsCauchy BoundedAwayZero a x = LIM a All goals completed! 🐙 b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchy a, (↑a).IsCauchy BoundedAwayZero a LIM b = LIM a refine a, ha, ?_, b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyLIM b = LIM a All goals completed! 🐙 b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchy c > 0, (n : ), |a n| c b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchy (n : ), |a n| ε / 2 b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyn:|a n| ε / 2; b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyn:hn:n < n₀|a n| ε / 2b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyn:hn:¬n < n₀|a n| ε / 2 b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyn:hn:n < n₀|a n| ε / 2b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyn:hn:¬n < n₀|a n| ε / 2 b: hb:(↑b).IsCauchyε::0 < εhx✝: (x : ), x_1, x x_1 ε < |b x_1|N:hb': j N, k N, Section_4_3.dist (b j) (b k) ε / 2n₀:hn₀:N n₀hx:ε < |b n₀|how: j N, |b j| ε / 2a: := fun n if n < n₀ then ε / 2 else b nnot_hard:Sequence.Equiv a bha:(↑a).IsCauchyn:hn:¬n < n₀ε / 2 |b n| All goals completed! 🐙

This result was not explicitly stated in the text, but is needed in the theory. It's a good exercise, so I'm setting it as such.

theorem declaration uses `sorry`Real.lim_of_boundedAwayZero {a: } (ha: BoundedAwayZero a) (ha_cauchy: (a:Sequence).IsCauchy) : LIM a 0 := a: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyLIM a 0 All goals completed! 🐙
theorem Real.nonzero_of_boundedAwayZero {a: } (ha: BoundedAwayZero a) (n: ) : a n 0 := a: ha:BoundedAwayZero an:a n 0 a: n:c:hc:c > 0ha: (n : ), |a n| ca n 0; a: n:c:hc:c > 0ha:|a n| ca n 0; a: n:c:hc:c > 0ha:a n = 0|a n| < c; All goals completed! 🐙

Lemma 5.3.15

theorem Real.inv_isCauchy_of_boundedAwayZero {a: } (ha: BoundedAwayZero a) (ha_cauchy: (a:Sequence).IsCauchy) : ((a⁻¹: ):Sequence).IsCauchy := a: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchy(↑a⁻¹).IsCauchy -- This proof is written to follow the structure of the original text. a: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyha': (n : ), a n 0(↑a⁻¹).IsCauchy a: ha: c > 0, (n : ), |a n| cha_cauchy:(↑a).IsCauchyha': (n : ), a n 0(↑a⁻¹).IsCauchy; a: ha_cauchy:(↑a).IsCauchyha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| c(↑a⁻¹).IsCauchy simp_rw a: ha_cauchy:(↑a).IsCauchyha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| c(↑a⁻¹).IsCauchySequence.IsCauchy.coe, Section_4_3.dist_eq] at ha_cauchy intro ε a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cha_cauchy: ε > 0, N, j N, k N, |a j - a k| εε::ε > 0 N, j N, k N, |a⁻¹ j - a⁻¹ k| ε; specialize ha_cauchy (c^2 * ε) (a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cha_cauchy: ε > 0, N, j N, k N, |a j - a k| εε::ε > 0c ^ 2 * ε > 0 All goals completed! 🐙) a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy: j N, k N, |a j - a k| c ^ 2 * ε N, j N, k N, |a⁻¹ j - a⁻¹ k| ε; a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy: j N, k N, |a j - a k| c ^ 2 * ε j N, k N, |a⁻¹ j - a⁻¹ k| ε; a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε|a⁻¹ n - a⁻¹ m| ε calc _ = |(a m - a n) / (a m * a n)| := a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε|a⁻¹ n - a⁻¹ m| = |(a m - a n) / (a m * a n)| a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * εa⁻¹ n - a⁻¹ m = (a m - a n) / (a m * a n); a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε(a n)⁻¹ - (a m)⁻¹ = (a m - a n) / (a m * a n); All goals completed! 🐙 _ |a m - a n| / c^2 := a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε|(a m - a n) / (a m * a n)| |a m - a n| / c ^ 2 a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε|a m - a n| / (|a m| * |a n|) |a m - a n| / (c * c); a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * εc |a m|a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * εc |a n| a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * εc |a m|a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * εc |a n| All goals completed! 🐙 _ = |a n - a m| / c^2 := a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε|a m - a n| / c ^ 2 = |a n - a m| / c ^ 2 All goals completed! 🐙 _ (c^2 * ε) / c^2 := a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * ε|a n - a m| / c ^ 2 c ^ 2 * ε / c ^ 2 All goals completed! 🐙 _ = ε := a: ha': (n : ), a n 0c:hc:c > 0ha: (n : ), |a n| cε::ε > 0N:ha_cauchy✝: j N, k N, |a j - a k| c ^ 2 * εn:hn:n Nm:hm:m Nha_cauchy:|a n - a m| c ^ 2 * εc ^ 2 * ε / c ^ 2 = ε All goals completed! 🐙

Lemma 5.3.17 (Reciprocation is well-defined)

theorem Real.inv_of_equiv {a b: } (ha: BoundedAwayZero a) (ha_cauchy: (a:Sequence).IsCauchy) (hb: BoundedAwayZero b) (hb_cauchy: (b:Sequence).IsCauchy) (hlim: LIM a = LIM b) : LIM a⁻¹ = LIM b⁻¹ := a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bLIM a⁻¹ = LIM b⁻¹ -- This proof is written to follow the structure of the original text. a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹LIM a⁻¹ = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyLIM a⁻¹ = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyLIM a⁻¹ = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyhaainv_cauchy:(↑(a⁻¹ * a)).IsCauchyLIM a⁻¹ = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyhaainv_cauchy:(↑(a⁻¹ * a)).IsCauchyhabinv_cauchy:(↑(a⁻¹ * b)).IsCauchyLIM a⁻¹ = LIM b⁻¹ have claim1 : P = LIM b⁻¹ := a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bLIM a⁻¹ = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyhaainv_cauchy:(↑(a⁻¹ * a)).IsCauchyhabinv_cauchy:(↑(a⁻¹ * b)).IsCauchyLIM (a⁻¹ * a * b⁻¹) = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyhaainv_cauchy:(↑(a⁻¹ * a)).IsCauchyhabinv_cauchy:(↑(a⁻¹ * b)).IsCauchyn:(a⁻¹ * a * b⁻¹) n = b⁻¹ n; All goals completed! 🐙 have claim2 : P = LIM a⁻¹ := a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bLIM a⁻¹ = LIM b⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyhaainv_cauchy:(↑(a⁻¹ * a)).IsCauchyhabinv_cauchy:(↑(a⁻¹ * b)).IsCauchyclaim1:P = LIM b⁻¹LIM (a⁻¹ * b * b⁻¹) = LIM a⁻¹ a: b: ha:BoundedAwayZero aha_cauchy:(↑a).IsCauchyhb:BoundedAwayZero bhb_cauchy:(↑b).IsCauchyhlim:LIM a = LIM bP:Real := LIM a⁻¹ * LIM a * LIM b⁻¹hainv_cauchy:(↑a⁻¹).IsCauchyhbinv_cauchy:(↑b⁻¹).IsCauchyhaainv_cauchy:(↑(a⁻¹ * a)).IsCauchyhabinv_cauchy:(↑(a⁻¹ * b)).IsCauchyclaim1:P = LIM b⁻¹n:(a⁻¹ * b * b⁻¹) n = a⁻¹ n; All goals completed! 🐙 All goals completed! 🐙

Definition 5.3.16 (Reciprocation of real numbers). Requires classical logic because we need to assign a "junk" value to the inverse of 0.

open Classical innoncomputable instance Real.instInv : Inv Real where inv x := if h: x 0 then LIM (boundedAwayZero_of_nonzero h).choose⁻¹ else 0
theorem Real.inv_def {a: } (h: BoundedAwayZero a) (hc: (a:Sequence).IsCauchy) : (LIM a)⁻¹ = LIM a⁻¹ := a: h:BoundedAwayZero ahc:(↑a).IsCauchy(LIM a)⁻¹ = LIM a⁻¹ a: h:BoundedAwayZero ahc:(↑a).IsCauchyhx:LIM a 0(LIM a)⁻¹ = LIM a⁻¹ a: h:BoundedAwayZero ahc:(↑a).IsCauchyx:Real := LIM ahx:x 0x⁻¹ = LIM a⁻¹ a: h:BoundedAwayZero ahc:(↑a).IsCauchyx:Real := LIM ahx:x 0h1:(↑.choose).IsCauchyh2:BoundedAwayZero .chooseh3:x = LIM .choosex⁻¹ = LIM a⁻¹ a: h:BoundedAwayZero ahc:(↑a).IsCauchyx:Real := LIM ahx:x 0h1:(↑.choose).IsCauchyh2:BoundedAwayZero .chooseh3:x = LIM .choose(LIM fun i (.choose i).inv) = LIM fun i (a i).inv All goals completed! 🐙@[simp] theorem Real.inv_zero : (0:Real)⁻¹ = 0 := 0⁻¹ = 0 All goals completed! 🐙theorem declaration uses `sorry`Real.self_mul_inv {x:Real} (hx: x 0) : x * x⁻¹ = 1 := x:Realhx:x 0x * x⁻¹ = 1 All goals completed! 🐙theorem declaration uses `sorry`Real.inv_mul_self {x:Real} (hx: x 0) : x⁻¹ * x = 1 := x:Realhx:x 0x⁻¹ * x = 1 All goals completed! 🐙lemma BoundedAwayZero.const {q : } (hq : q 0) : BoundedAwayZero fun _ q := q:hq:q 0BoundedAwayZero fun x q q:hq:q 0|q| > 0 (n : ), |(fun x q) n| |q|; All goals completed! 🐙theorem Real.inv_ratCast (q:) : (q:Real)⁻¹ = (q⁻¹:) := q:(↑q)⁻¹ = q⁻¹ q:h:q = 0(↑q)⁻¹ = q⁻¹q:h:¬q = 0(↑q)⁻¹ = q⁻¹ q:h:q = 0(↑q)⁻¹ = q⁻¹ q:h:q = 00⁻¹ = 0⁻¹; q:h:q = 00 = 0; All goals completed! 🐙 simp_rw q:h:¬q = 0(↑q)⁻¹ = q⁻¹ratCast_def, inv_def (BoundedAwayZero.const h) (q:h:¬q = 0(↑fun x q).IsCauchy All goals completed! 🐙)]; All goals completed! 🐙

Default definition of division.

noncomputable instance Real.instDivInvMonoid : DivInvMonoid Real where
theorem Real.div_eq (x y:Real) : x/y = x * y⁻¹ := rflnoncomputable instance declaration uses `sorry`Real.instField : Field Real where exists_pair_ne := x y, x y All goals completed! 🐙 mul_inv_cancel := (a : Real), a 0 a * a⁻¹ = 1 All goals completed! 🐙 inv_zero := 0⁻¹ = 0 All goals completed! 🐙 ratCast_def := (q : ), q = q.num / q.den All goals completed! 🐙 qsmul := _ nnqsmul := _theorem declaration uses `sorry`Real.mul_right_cancel₀ {x y z:Real} (hz: z 0) (h: x * z = y * z) : x = y := x:Realy:Realz:Realhz:z 0h:x * z = y * zx = y All goals completed! 🐙theorem declaration uses `sorry`Real.mul_right_nocancel : ¬ (x y z:Real), (hz: z = 0) (x * z = y * z) x = y := ¬ (x y z : Real), z = 0 x * z = y * z x = y All goals completed! 🐙

Exercise 5.3.4

theorem declaration uses `sorry`Real.IsBounded.equiv {a b: } (ha: (a:Sequence).IsBounded) (hab: Sequence.Equiv a b) : (b:Sequence).IsBounded := a: b: ha:(↑a).IsBoundedhab:Sequence.Equiv a b(↑b).IsBounded All goals completed! 🐙

Same as Sequence.­IsCauchy.­harmonic but reindexing the sequence as a₀ = 1, a₁ = 1/2, ... This form is more convenient for the upcoming proof of Theorem 5.5.9.

theorem Sequence.IsCauchy.harmonic' : ((fun n 1/((n:)+1): ):Sequence).IsCauchy := (↑fun n 1 / (n + 1)).IsCauchy ε > 0, N, j N, k N, Section_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε; intro ε ε::ε > 0 N, j N, k N, Section_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε; ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε N, j N, k N, Section_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) ε j N.toNat, k N.toNat, Section_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε; intro j ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝:j N.toNat k N.toNat, Section_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝:j N.toNatk:k N.toNat Section_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝¹:j N.toNatk:a✝:k N.toNatSection_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε; ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝¹:j N.toNatk:a✝:k N.toNatj + 1 Nε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝¹:j N.toNatk:a✝:k N.toNatk + 1 Nε::ε > 0N:h1:N 1j:a✝¹:j N.toNatk:a✝:k N.toNath2:Section_4_3.dist ((mk' 1 fun n 1 / n).seq (j + 1)) ((mk' 1 fun n 1 / n).seq (k + 1)) εSection_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε ε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝¹:j N.toNatk:a✝:k N.toNatj + 1 Nε::ε > 0N:h1:N 1h2: j N, k N, Section_4_3.dist ((mk' 1 fun n 1 / n).seq j) ((mk' 1 fun n 1 / n).seq k) εj:a✝¹:j N.toNatk:a✝:k N.toNatk + 1 Nε::ε > 0N:h1:N 1j:a✝¹:j N.toNatk:a✝:k N.toNath2:Section_4_3.dist ((mk' 1 fun n 1 / n).seq (j + 1)) ((mk' 1 fun n 1 / n).seq (k + 1)) εSection_4_3.dist (1 / (j + 1)) (1 / (k + 1)) ε try All goals completed! 🐙 All goals completed! 🐙

Exercise 5.3.5

theorem declaration uses `sorry`Real.LIM.harmonic : LIM (fun n 1/((n:)+1)) = 0 := (LIM fun n 1 / (n + 1)) = 0 All goals completed! 🐙
end Chapter5