Аналіз I, Глава 2.1
Цей файл є перекладом Глави 2.1 Аналізу I до Lean 4. Вся нумерація посилається на оригінальний текст.
Я (пр.перекл. Терренс Тао) намагався зробити переклад якомога точнішим перефразуванням оригінального тексту. Коли є вибір між більш ідіоматичним рішенням Lean та більш точним перекладом, я зазвичай обирав останній. Зокрема, будуть місця, де код Lean можна було б "підбуцнути", щоб зробити його більш елегантним та ідіоматичним, але я свідомо уникав цього вибору.
Основні конструкції та результати цього розділу:
-
Визанчення натуральних чисел "Розділу 2",
Chapter2.Nat, абревіюється якNatв середині простору іменChapter2. (У книзі натуральні числа трактуються суто аксіоматично, як тип, що підпорядковується аксіомам Пеано; але тут ми використовуємо переваги рідних для Lean індуктивних типів, щоб явно побудувати версію натуральних чисел, які підпорядковуються цим аксіомам. Можна також діяти більш аксіоматично, як це зроблено в розділі 3 для теорії множин, але ми залишаємо це як вправу для читача..) -
Встановлення аксіом Пеано для
Chapter2.Nat -
Рекурсивні визначення для
Chapter2.Nat
Примітка: наприкінці цього розділу клас Chapter2.Nat буде замінено на користь стандартного
класу Mathlib _root_.Nat, або ℕ. Однак, ми пропрацюємо властивості
Chapter2.Nat "вручну" в наступних кількох розділах для педагогічних цілей.
namespace Chapter2Припущення 2.6 (Існування натуральних чисел). Тут ми будемо використовувати явне побудування натуральних чисел (використовуючи індуктивний тип). Для більш аксіоматичного підходу, дивіться епілог до цього розділу
inductive Nat where
| zero : Nat
| succ : Nat → Nat
deriving Repr, DecidableEq -- це дозволяє `decide` працювати із `Nat`#check (0:Nat)0 : Nat
/-- Аксіома 2.2 (Наступник натурального числа також є натуральним числом) -/
postfix:100 "++" => Nat.succ#check (fun n ↦ n++)fun n => n++ : Nat → Nat
Визначення 2.1.3 (Визначення чисел 0, 1, 2, etc.). Примітка: щоб уникнути неоднозначності, вам може знадобитися явна конвертація як наприклад (0:Nat), (1:Nat), і т.д. щоб посилатися на версію натуральних чисел із цього розділу.
instance Nat.instOfNat {n:_root_.Nat} : OfNat Nat n where
ofNat := _root_.Nat.rec 0 (fun _ n ↦ n++) ninstance Nat.instOne : One Nat := ⟨ 1 ⟩lemma Nat.zero_succ : 0++ = 1 := ⊢ 0++ = 1 All goals completed! 🐙#check (1:Nat)1 : Nat
lemma Nat.one_succ : 1++ = 2 := ⊢ 1++ = 2 All goals completed! 🐙#check (2:Nat)2 : Nat
Твердження 2.1.4 (3 є натуральним числом)
lemma Nat.two_succ : 2++ = 3 := ⊢ 2++ = 3 All goals completed! 🐙#check (3:Nat)3 : Nat
Аксіома 2.3 (0 не є наступником ніякого натурального числа).
Порівняйте із Mathlib-овським Nat.succ_ne_zero.
theorem Nat.succ_ne (n:Nat) : n++ ≠ 0 := n:Nat⊢ n++ ≠ 0
n:Nath:n++ = 0⊢ False
All goals completed! 🐙Твердження 2.1.6 (4 не дорівнює нулю)
theorem Nat.four_ne : (4:Nat) ≠ 0 := ⊢ 4 ≠ 0
-- За визначенням, 4 = 3++.
⊢ 3++ ≠ 0
-- За аксіомою 2.3, 3++ не є нулем.
All goals completed! 🐙
Аксіома 2.4 (Різні натуральні числа мають різних наступників).
Порівняйте із Mathlib-овським Nat.succ_inj.
theorem Nat.succ_cancel {n m:Nat} (hnm: n++ = m++) : n = m := n:Natm:Nathnm:n++ = m++⊢ n = m
rwa [succ.injEqn:Natm:Nathnm:n = m⊢ n = m at hnm
Аксіома 2.4 (Різні натуральні числа мають різних наступників).
Порівняйте із Mathlib-овським Nat.succ_ne_succ.
theorem Nat.succ_ne_succ (n m:Nat) : n ≠ m → n++ ≠ m++ := n:Natm:Nat⊢ n ≠ m → n++ ≠ m++
n:Natm:Nath:n ≠ m⊢ n++ ≠ m++
n:Natm:Nath:n++ = m++⊢ n = m
All goals completed! 🐙Твердження 2.1.8 (6 не дорівнює 2)
theorem Nat.six_ne_two : (6:Nat) ≠ 2 := ⊢ 6 ≠ 2
-- цей доказ написан так, щоб співпадати із структурою орігінального тексту.
h:6 = 2⊢ False
h:5++ = 1++⊢ False
h:5 = 1⊢ False
h:4++ = 0++⊢ False
h:4 = 0⊢ False
h:4 = 0this:4 ≠ 0⊢ False
All goals completed! 🐙
Ви також можете довести такого типу результат використовуючи тактику decide
theorem Nat.six_ne_two' : (6:Nat) ≠ 2 := ⊢ 6 ≠ 2
All goals completed! 🐙
Аксіома 2.5 (принцип математичної індукції). Тактика induction (або induction') в
Mathlib служить заміною для цієї аксіоми.
theorem Nat.induction (P : Nat → Prop) (hbase : P 0) (hind : ∀ n, P n → P (n++)) :
∀ n, P n := P:Nat → Prophbase:P 0hind:∀ (n : Nat), P n → P (n++)⊢ ∀ (n : Nat), P n
P:Nat → Prophbase:P 0hind:∀ (n : Nat), P n → P (n++)n:Nat⊢ P n
induction n with
P:Nat → Prophbase:P 0hind:∀ (n : Nat), P n → P (n++)⊢ P zero All goals completed! 🐙
P:Nat → Prophbase:P 0hind:∀ (n : Nat), P n → P (n++)n:Natih:P n⊢ P (n++) All goals completed! 🐙
Рекурсія. Аналогічно до вбудованого методу Mathlib Nat.rec ассоційованого із
натуральними числами Mathlib
abbrev Nat.recurse (f: Nat → Nat → Nat) (c: Nat) : Nat → Nat := fun n ↦ match n with
| 0 => c
| n++ => f n (recurse f c n)
Твердження 2.1.16 (рекурсивне визначення). Порівняйте із Mathlib-овським Nat.rec_zero.
theorem Nat.recurse_zero (f: Nat → Nat → Nat) (c: Nat) : Nat.recurse f c 0 = c := f:Nat → Nat → Natc:Nat⊢ recurse f c 0 = c All goals completed! 🐙
Твердження 2.1.16 (рекурсивне визначення). Порівняйте із Mathlib-овським Nat.rec_add_one.
theorem Nat.recurse_succ (f: Nat → Nat → Nat) (c: Nat) (n: Nat) :
recurse f c (n++) = f n (recurse f c n) := f:Nat → Nat → Natc:Natn:Nat⊢ recurse f c (n++) = f n (recurse f c n) All goals completed! 🐙Твердження 2.1.16 (рекурсивне визначення).
theorem Nat.eq_recurse (f: Nat → Nat → Nat) (c: Nat) (a: Nat → Nat) :
(a 0 = c ∧ ∀ n, a (n++) = f n (a n)) ↔ a = recurse f c := f:Nat → Nat → Natc:Nata:Nat → Nat⊢ (a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)) ↔ a = recurse f c
f:Nat → Nat → Natc:Nata:Nat → Nat⊢ (a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)) → a = recurse f cf:Nat → Nat → Natc:Nata:Nat → Nat⊢ a = recurse f c → a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)
f:Nat → Nat → Natc:Nata:Nat → Nat⊢ (a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)) → a = recurse f c f:Nat → Nat → Natc:Nata:Nat → Nath0:a 0 = chsucc:∀ (n : Nat), a (n++) = f n (a n)⊢ a = recurse f c
-- цей доказ написан так, щоб співпадати із структурою орігінального тексту.
f:Nat → Nat → Natc:Nata:Nat → Nath0:a 0 = chsucc:∀ (n : Nat), a (n++) = f n (a n)⊢ ∀ (x : Nat), a x = recurse f c x; f:Nat → Nat → Natc:Nata:Nat → Nath0:a 0 = chsucc:∀ (n : Nat), a (n++) = f n (a n)⊢ a 0 = recurse f c 0f:Nat → Nat → Natc:Nata:Nat → Nath0:a 0 = chsucc:∀ (n : Nat), a (n++) = f n (a n)⊢ ∀ (n : Nat), a n = recurse f c n → a (n++) = recurse f c (n++)
f:Nat → Nat → Natc:Nata:Nat → Nath0:a 0 = chsucc:∀ (n : Nat), a (n++) = f n (a n)⊢ a 0 = recurse f c 0 All goals completed! 🐙
f:Nat → Nat → Natc:Nata:Nat → Nath0:a 0 = chsucc:∀ (n : Nat), a (n++) = f n (a n)n:Nathn:a n = recurse f c n⊢ a (n++) = recurse f c (n++)
All goals completed! 🐙
f:Nat → Nat → Natc:Nata:Nat → Nath:a = recurse f c⊢ a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)
f:Nat → Nat → Natc:Nata:Nat → Nath:a = recurse f c⊢ recurse f c 0 = c ∧ ∀ (n : Nat), recurse f c (n++) = f n (recurse f c n)
f:Nat → Nat → Natc:Nata:Nat → Nath:a = recurse f c⊢ recurse f c 0 = cf:Nat → Nat → Natc:Nata:Nat → Nath:a = recurse f c⊢ ∀ (n : Nat), recurse f c (n++) = f n (recurse f c n)
f:Nat → Nat → Natc:Nata:Nat → Nath:a = recurse f c⊢ recurse f c 0 = c All goals completed! 🐙
All goals completed! 🐙Твердження 2.1.16 (рекурсивне визначення).
theorem Nat.recurse_uniq (f: Nat → Nat → Nat) (c: Nat) :
∃! (a: Nat → Nat), a 0 = c ∧ ∀ n, a (n++) = f n (a n) := f:Nat → Nat → Natc:Nat⊢ ∃! a, a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)
f:Nat → Nat → Natc:Nat⊢ recurse f c 0 = c ∧ ∀ (n : Nat), recurse f c (n++) = f n (recurse f c n)f:Nat → Nat → Natc:Nat⊢ ∀ (y : Nat → Nat), (y 0 = c ∧ ∀ (n : Nat), y (n++) = f n (y n)) → y = recurse f c
f:Nat → Nat → Natc:Nat⊢ recurse f c 0 = c ∧ ∀ (n : Nat), recurse f c (n++) = f n (recurse f c n) f:Nat → Nat → Natc:Nat⊢ recurse f c 0 = cf:Nat → Nat → Natc:Nat⊢ ∀ (n : Nat), recurse f c (n++) = f n (recurse f c n)
f:Nat → Nat → Natc:Nat⊢ recurse f c 0 = c All goals completed! 🐙
f:Nat → Nat → Natc:Nat⊢ ∀ (n : Nat), recurse f c (n++) = f n (recurse f c n) All goals completed! 🐙
f:Nat → Nat → Natc:Nata:Nat → Nat⊢ (a 0 = c ∧ ∀ (n : Nat), a (n++) = f n (a n)) → a = recurse f c
All goals completed! 🐙end Chapter2