Equivalence of reals

Аналіз I, Розділ 5, Епілог: Ізоморфізм із дійсними числами Mathlib

Я (пр.перекл. Терренс Тао) намагався зробити переклад якомога точнішим перефразуванням оригінального тексту. Коли є вибір між більш ідіоматичним рішенням Lean та більш точним перекладом, я зазвичай обирав останній. Зокрема, будуть місця, де код Lean можна було б "підбуцнути", щоб зробити його більш елегантним та ідіоматичним, але я свідомо уникав цього вибору.

Відтепер Chapter5.Real : TypeChapter5.Real вважатиметься застарілим, і замість нього ми використовуватимемо стандартні дійсні числа : Type. Зокрема, для всіх наступних розділів слід використовувати повний API Mathlib для : Type замість API Chapter5.Real : TypeChapter5.Real.

Заповнення пропусків (sorries) тут потребує як API Chapter5.Real : TypeChapter5.Real, так і API Mathlib для стандартних дійсних чисел : Type. Таким чином, ці вправи є чудовою підготовкою до вищезгаданого переходу.

Підказки від попередніх користувачів

Користувачі супровідного матеріалу, які виконали вправи в цьому розділі, можуть надсилати свої поради майбутнім користувачам цього розділу як PRи.

  • (Додайте підказку тут)

namespace Chapter5@[ext] structure DedekindCut where E : Set nonempty : E.Nonempty bounded : BddAbove E lower: IsLowerSet E nomax : q E, r E, r > qtheorem isLowerSet_iff (E: Set ) : IsLowerSet E q r, r < q q E r E := isLowerSet_iff_forall_ltabbrev Real.toSet_Rat (x:Real) : Set := { q | (q:Real) < x }lemma declaration uses 'sorry'Real.toSet_Rat_nonempty (x:Real) : x.toSet_Rat.Nonempty := x:Realx.toSet_Rat.Nonempty All goals completed! 🐙lemma declaration uses 'sorry'Real.toSet_Rat_bounded (x:Real) : BddAbove x.toSet_Rat := x:RealBddAbove x.toSet_Rat All goals completed! 🐙lemma declaration uses 'sorry'Real.toSet_Rat_lower (x:Real) : IsLowerSet x.toSet_Rat := x:RealIsLowerSet x.toSet_Rat All goals completed! 🐙lemma declaration uses 'sorry'Real.toSet_Rat_nomax {x:Real} : q x.toSet_Rat, r x.toSet_Rat, r > q := x:Real q x.toSet_Rat, r x.toSet_Rat, r > q All goals completed! 🐙abbrev Real.toCut (x:Real) : DedekindCut := { E := x.toSet_Rat nonempty := x.toSet_Rat_nonempty bounded := x.toSet_Rat_bounded lower := x.toSet_Rat_lower nomax := x.toSet_Rat_nomax }abbrev DedekindCut.toSet_Real (c: DedekindCut) : Set Real := (fun (q:) (q:Real)) '' c.Elemma declaration uses 'sorry'DedekindCut.toSet_Real_nonempty (c: DedekindCut) : c.toSet_Real.Nonempty := c:DedekindCutc.toSet_Real.Nonempty All goals completed! 🐙lemma declaration uses 'sorry'DedekindCut.toSet_Real_bounded (c: DedekindCut) : BddAbove c.toSet_Real := c:DedekindCutBddAbove c.toSet_Real All goals completed! 🐙noncomputable abbrev DedekindCut.toReal (c: DedekindCut) : Real := sSup c.toSet_Reallemma DedekindCut.toReal_isLUB (c: DedekindCut) : IsLUB c.toSet_Real c.toReal := ExtendedReal.sSup_of_bounded c.toSet_Real_nonempty c.toSet_Real_boundednoncomputable abbrev declaration uses 'sorry'declaration uses 'sorry'Real.equivCut : Real DedekindCut where toFun := toCut invFun := DedekindCut.toReal left_inv x := x:Realx.toCut.toReal = x All goals completed! 🐙 right_inv c := c:DedekindCutc.toReal.toCut = c All goals completed! 🐙end Chapter5

Тепер необхідно розробити аналогічні результати для дійсних чисел Mathlib.

abbrev Real.toSet_Rat (x:) : Set := { q | (q:) < x }
lemma declaration uses 'sorry'Real.toSet_Rat_nonempty (x:) : x.toSet_Rat.Nonempty := x:x.toSet_Rat.Nonempty All goals completed! 🐙lemma declaration uses 'sorry'Real.toSet_Rat_bounded (x:) : BddAbove x.toSet_Rat := x:BddAbove x.toSet_Rat All goals completed! 🐙lemma declaration uses 'sorry'Real.toSet_Rat_lower (x:) : IsLowerSet x.toSet_Rat := x:IsLowerSet x.toSet_Rat All goals completed! 🐙lemma declaration uses 'sorry'Real.toSet_Rat_nomax (x:) : q x.toSet_Rat, r x.toSet_Rat, r > q := x: q x.toSet_Rat, r x.toSet_Rat, r > q All goals completed! 🐙abbrev Real.toCut (x:) : Chapter5.DedekindCut := { E := x.toSet_Rat nonempty := x.toSet_Rat_nonempty bounded := x.toSet_Rat_bounded lower := x.toSet_Rat_lower nomax := x.toSet_Rat_nomax }namespace Chapter5abbrev DedekindCut.toSet_R (c: DedekindCut) : Set := (fun (q:) (q:)) '' c.Elemma declaration uses 'sorry'DedekindCut.toSet_R_nonempty (c: DedekindCut) : c.toSet_R.Nonempty := c:DedekindCutc.toSet_R.Nonempty All goals completed! 🐙lemma declaration uses 'sorry'DedekindCut.toSet_R_bounded (c: DedekindCut) : BddAbove c.toSet_R := c:DedekindCutBddAbove c.toSet_R All goals completed! 🐙noncomputable abbrev DedekindCut.toR (c: DedekindCut) : := sSup c.toSet_Rlemma DedekindCut.toR_isLUB (c: DedekindCut) : IsLUB c.toSet_R c.toR := isLUB_csSup c.toSet_R_nonempty c.toSet_R_boundedend Chapter5noncomputable abbrev declaration uses 'sorry'declaration uses 'sorry'Real.equivCut : Chapter5.DedekindCut where toFun := _root_.Real.toCut invFun := Chapter5.DedekindCut.toR left_inv x := x:x.toCut.toR = x All goals completed! 🐙 right_inv c := c:Chapter5.DedekindCutc.toR.toCut = c All goals completed! 🐙namespace Chapter5

Ізоморфізм між дійсними числами Розділу 5 та дійсними числами Mathlib.

noncomputable abbrev Real.equivR : Real := Real.equivCut.trans _root_.Real.equivCut.symm
lemma Real.equivR_iff (x : Real) (y : ) : y = Real.equivR x y.toCut = x.toCut := x:Realy:y = equivR x y.toCut = x.toCut x:Realy:_root_.Real.equivCut y = equivCut x y.toCut = x.toCut All goals completed! 🐙-- Щоб скористатися цим визначенням, нам знадобиться певний допоміжний апарат. ----- -- Почнемо з того, що покажемо, як це працює для `ratCasts` theorem declaration uses 'sorry'Real.equivR_ratCast {q: } : equivR q = (q: ) := q:equivR q = q All goals completed! 🐙lemma Real.equivR_nat {n: } : equivR n = (n: ) := equivR_ratCastlemma Real.equivR_int {n: } : equivR n = (n: ) := equivR_ratCast---- -- Далі ми хочемо налаштувати спосіб конвертації з Real `LIM` у ℝ `Real.mk` -- Для цього нам знадобиться дещо: -- Конвертація між поняттями послідовностей Коші theorem declaration uses 'sorry'Sequence.IsCauchy.to_IsCauSeq {a: } (ha: IsCauchy a) : IsCauSeq _root_.abs a := a: ha:(↑a).IsCauchyIsCauSeq _root_.abs a All goals completed! 🐙-- Перетворення `IsCauchy` у `CauSeq` abbrev Sequence.IsCauchy.CauSeq {a: } : (ha: IsCauchy a) CauSeq _root_.abs := (a, ·.to_IsCauSeq)-- Потім ми налаштовуємо перетворення з Sequence.Equiv у CauSeq.LimZero, оскільки -- це є відношенням еквівалентності example {a b: CauSeq abs} : a b CauSeq.LimZero (a - b) := a:CauSeq absb:CauSeq absa b (a - b).LimZero All goals completed! 🐙theorem declaration uses 'sorry'Sequence.Equiv.LimZero {a b: } (ha: IsCauchy a) (hb: IsCauchy b) (h:Equiv a b) : CauSeq.LimZero (ha.CauSeq - hb.CauSeq) := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyh:Equiv a b(ha.CauSeq - hb.CauSeq).LimZero All goals completed! 🐙-- Тепер ми можемо використовувати це для конвертації між різними функціями в Real.mk theorem Real.mk_eq_mk {a b: } (ha : Sequence.IsCauchy a) (hb : Sequence.IsCauchy b) (hab: Sequence.Equiv a b) : Real.mk ha.CauSeq = Real.mk hb.CauSeq := Real.mk_eq.mpr (hab.LimZero ha hb)-- Обидва напрямки еквівалентності theorem declaration uses 'sorry'Sequence.Equiv_iff_LimZero {a b: } (ha: IsCauchy a) (hb: IsCauchy b) : Equiv a b CauSeq.LimZero (ha.CauSeq - hb.CauSeq) := a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchyEquiv a b (ha.CauSeq - hb.CauSeq).LimZero a: b: ha:(↑a).IsCauchyhb:(↑b).IsCauchy(ha.CauSeq - hb.CauSeq).LimZero Equiv a b All goals completed! 🐙---- -- Ми створюємо кілька послідовностей Коші з корисними властивостями -- Ми показуємо, що для будь-якої послідовності вона врешті-решт стане довільно близькою до свого LIM. open Real in theorem declaration uses 'sorry'Sequence.difference_approaches_zero {a: } (ha: Sequence.IsCauchy a) : ε > 0, N, n N, |LIM a - a n| (ε: ) := a: ha:(↑a).IsCauchy ε > 0, N, n N, |LIM a - (a n)| ε All goals completed! 🐙-- Існує послідовність Коші, яка повністю лежить вище свого LIM theorem declaration uses 'sorry'Real.exists_equiv_above {a: } (ha: Sequence.IsCauchy a) : (b: ), Sequence.IsCauchy b Sequence.Equiv a b n, LIM a b n := a: ha:(↑a).IsCauchy b, (↑b).IsCauchy Sequence.Equiv a b (n : ), LIM a (b n) All goals completed! 🐙-- Існує послідовність Коші, яка повністю лежить нижче свого LIM theorem declaration uses 'sorry'Real.exists_equiv_below {a: } (ha: Sequence.IsCauchy a) : (b: ), Sequence.IsCauchy b Sequence.Equiv a b n, b n LIM a := a: ha:(↑a).IsCauchy b, (↑b).IsCauchy Sequence.Equiv a b (n : ), (b n) LIM a All goals completed! 🐙
Real.mk_le {f g : CauSeq  abs} : Real.mk f  Real.mk g  f  g
Real.mk_le_of_forall_le {f : CauSeq  abs} {x : } (h :  i,  j  i, (f j)  x) : Real.mk f  x
Real.mk_const {x : } : Real.mk (CauSeq.const abs x) = x
-- Перетворіть `Real` у `ℝ`, використовуючи послідовності Коші -- ми можемо використовувати перетворення `Real.mk_eq`, щоб застосовувати різні послідовності для доведення різних частин theorem declaration uses 'sorry'Real.equivR_eq' {a: } (ha: Sequence.IsCauchy a) : (LIM a).equivR = Real.mk ha.CauSeq := a: ha:(↑a).IsCauchyequivR (LIM a) = Real.mk ha.CauSeq a: ha:(↑a).IsCauchyhq: q, q = LIM aequivR (LIM a) = Real.mk ha.CauSeqa: ha:(↑a).IsCauchyhq:¬ q, q = LIM aequivR (LIM a) = Real.mk ha.CauSeq a: ha:(↑a).IsCauchyhq: q, q = LIM aequivR (LIM a) = Real.mk ha.CauSeq All goals completed! 🐙 a: ha:(↑a).IsCauchyhq:¬ q, q = LIM asSup (Rat.cast '' (LIM a).toSet_Rat) = Real.mk ha.CauSeq a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aReal.mk ha.CauSeq upperBounds (Rat.cast '' (LIM a).toSet_Rat)a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aReal.mk ha.CauSeq lowerBounds (upperBounds (Rat.cast '' (LIM a).toSet_Rat)) a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aReal.mk ha.CauSeq upperBounds (Rat.cast '' (LIM a).toSet_Rat) -- покажіть, що `Real.mk ha.CauSeq` є верхньою межею a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aa✝:hy:a✝ Rat.cast '' (LIM a).toSet_Rata✝ Real.mk ha.CauSeq a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aa✝:hy✝:a✝ Rat.cast '' (LIM a).toSet_Raty:hy:y (LIM a).toSet_Rath:y = a✝a✝ Real.mk ha.CauSeq a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aa✝:hy✝:a✝ Rat.cast '' (LIM a).toSet_Raty:hy:y (LIM a).toSet_Rath:y = a✝Real.mk (CauSeq.const _root_.abs y) Real.mk ha.CauSeq All goals completed! 🐙 -- покажіть, що для будь-якої іншої верхньої межі `Real.mk ha.CauSeq` є меншим a: ha:(↑a).IsCauchyhq:¬ q, q = LIM aM:hM:M upperBounds (Rat.cast '' (LIM a).toSet_Rat)Real.mk ha.CauSeq M All goals completed! 🐙lemma Real.equivR_eq (x: Real) : (a : ) (ha: Sequence.IsCauchy a), x = LIM a x.equivR = Real.mk ha.CauSeq := x:Real a, (ha : (↑a).IsCauchy), x = LIM a equivR x = Real.mk ha.CauSeq a: ha:(↑a).IsCauchy a_1, (ha : (↑a_1).IsCauchy), LIM a = LIM a_1 equivR (LIM a) = Real.mk ha.CauSeq All goals completed! 🐙

Ізоморфізм зберігає порядок та кільцеві операції

noncomputable abbrev declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'Real.equivR_ordered_ring : Real ≃+*o where toEquiv := equivR map_add' := (x y : Real), equivR.toFun (x + y) = equivR.toFun x + equivR.toFun y All goals completed! 🐙 map_mul' := (x y : Real), equivR.toFun (x * y) = equivR.toFun x * equivR.toFun y All goals completed! 🐙 map_le_map_iff' := {a b : Real}, equivR.toFun a equivR.toFun b a b All goals completed! 🐙
-- допоміжні твердження для конвертації властивостей між Real та ℝ lemma Real.equivR_map_mul {x y : Real} : equivR (x * y) = equivR x * equivR y := equivR_ordered_ring.map_mul _ _lemma Real.equivR_map_inv {x: Real} : equivR (x⁻¹) = (equivR x)⁻¹ := map_inv₀ equivR_ordered_ring _theorem declaration uses 'sorry'Real.equivR_map_pos {x: Real} : 0 < x 0 < equivR x := x:Real0 < x 0 < equivR x All goals completed! 🐙theorem declaration uses 'sorry'Real.equivR_map_nonneg {x: Real} : 0 x 0 equivR x := x:Real0 x 0 equivR x All goals completed! 🐙-- Доведення еквівалентності різних операцій піднесення до степеня theorem declaration uses 'sorry'Real.pow_of_equivR (x:Real) (n:) : equivR (x^n) = (equivR x)^n := x:Realn:equivR (x ^ n) = equivR x ^ n All goals completed! 🐙theorem declaration uses 'sorry'Real.zpow_of_equivR (x:Real) (n:) : equivR (x^n) = (equivR x)^n := x:Realn:equivR (x ^ n) = equivR x ^ n All goals completed! 🐙theorem declaration uses 'sorry'Real.ratPow_of_equivR (x:Real) (q:) : equivR (x^q) = (equivR x)^(q:) := x:Realq:equivR (x ^ q) = equivR x ^ q All goals completed! 🐙end Chapter5