Аналіз I, Глава 2.2

Цей файл є перекладом Глави 2.2 Аналізу I до Lean 4. Вся нумерація посилається на оригінальний текст.

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

Основні конструкції та результати цього розділу:

Примітка: наприкінці цього розділу клас Chapter2.Nat : TypeChapter2.Nat буде замінено на користь стандартного класу Mathlib Nat : Type_root_.Nat, або ℕ : Type. Однак, ми пропрацюємо властивості Chapter2.Nat : TypeChapter2.Nat "вручну" в наступних кількох розділах для педагогічних цілей.

namespace Chapter2

Визначення 2.2.1. (Додавання натуральних чисел. Порівняйте із Mathlib-овським Nat.add : ℕ → ℕ → ℕNat.add

abbrev Nat.add (n m : Nat) : Nat := Nat.recurse (fun _ sum sum++) m n

Цей екземпляр дозволить нотації використовуватися для додавання натуральних чисел.

instance Nat.instAdd : Add Nat where add := add

Порівняйте із Mathlib-овським Nat.zero_add (n : ℕ) : 0 + n = nNat.zero_add

@[simp] theorem Nat.zero_add (m: Nat) : 0 + m = m := recurse_zero (fun _ sum sum++) _

Порівняйте із Mathlib-овським Nat.succ_add (n m : ℕ) : n.succ + m = (n + m).succNat.succ_add

theorem Nat.succ_add (n m: Nat) : n++ + m = (n+m)++ := n:Natm:Natn++ + m = (n + m)++ All goals completed! 🐙

Порівняйте із Mathlib-овським Nat.one_add (n : ℕ) : 1 + n = n.succNat.one_add

theorem Nat.one_add (m:Nat) : 1 + m = m++ := m:Nat1 + m = m++ All goals completed! 🐙
theorem Nat.two_add (m:Nat) : 2 + m = (m++)++ := m:Nat2 + m = m++++ All goals completed! 🐙example : (2:Nat) + 3 = 5 := 2 + 3 = 5 All goals completed! 🐙-- сума двух натуральних чисел це також натуральне число fun n m => n + m : Nat → Nat → Nat#check (fun (n m:Nat) n + m)
fun n m => n + m : Nat → Nat → Nat

Лема 2.2.2 (n + 0 = n). Порівняйте із Mathlib-овським Nat.add_zero (n : ℕ) : n + 0 = nNat.add_zero

@[simp] lemma Nat.add_zero (n:Nat) : n + 0 = n := n:Natn + 0 = n -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. (n : Nat), n + 0 = n; 0 + 0 = 0 (n : Nat), n + 0 = n n++ + 0 = n++ 0 + 0 = 0 All goals completed! 🐙 n:Natih:n + 0 = nn++ + 0 = n++ calc (n++) + 0 = (n + 0)++ := n:Natih:n + 0 = nn++ + 0 = (n + 0)++ All goals completed! 🐙 _ = n++ := n:Natih:n + 0 = n(n + 0)++ = n++ All goals completed! 🐙

Лема 2.2.3 (n+(m++) = (n+m)++). Порівняйте із Mathlib-овським Nat.add_succ (n m : ℕ) : n + m.succ = (n + m).succNat.add_succ

lemma Nat.add_succ (n m:Nat) : n + (m++) = (n + m)++ := n:Natm:Natn + m++ = (n + m)++ -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. m:Nat (n : Nat), n + m++ = (n + m)++; m:Nat0 + m++ = (0 + m)++m:Nat (n : Nat), n + m++ = (n + m)++ n++ + m++ = (n++ + m)++ m:Nat0 + m++ = (0 + m)++ All goals completed! 🐙 m:Natn:Natih:n + m++ = (n + m)++n++ + m++ = (n++ + m)++ m:Natn:Natih:n + m++ = (n + m)++(n + m)++++ = (n++ + m)++ All goals completed! 🐙

n++ = n + 1 (Чому?). Порівняйте із Mathlib-овським Nat.succ_eq_add_one (n : ℕ) : n.succ = n + 1Nat.succ_eq_add_one

theorem declaration uses 'sorry'Nat.succ_eq_add_one (n:Nat) : n++ = n + 1 := n:Natn++ = n + 1 All goals completed! 🐙

Твердження 2.2.4 (Додавання комутативне). Порівняйте із Mathlib-овським Nat.add_comm (n m : ℕ) : n + m = m + nNat.add_comm

theorem Nat.add_comm (n m:Nat) : n + m = m + n := n:Natm:Natn + m = m + n -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. m:Nat (n : Nat), n + m = m + n; m:Nat0 + m = m + 0m:Nat (n : Nat), n + m = m + n n++ + m = m + n++ m:Nat0 + m = m + 0 All goals completed! 🐙 m:Natn:Natih:n + m = m + nn++ + m = m + n++ m:Natn:Natih:n + m = m + n(n + m)++ = m + n++ All goals completed! 🐙

Твердження 2.2.5 (Додавання асоціативне) / Вправа 2.2.1 Порівняйте із Mathlib-овським Nat.add_assoc (n m k : ℕ) : n + m + k = n + (m + k)Nat.add_assoc

theorem declaration uses 'sorry'Nat.add_assoc (a b c:Nat) : (a + b) + c = a + (b + c) := a:Natb:Natc:Nata + b + c = a + (b + c) All goals completed! 🐙

Твердження 2.2.6 (Властивість скорочення) Порівняйте із Mathlib-овським Nat.add_left_cancel {n m k : ℕ} : n + m = n + k → m = kNat.add_left_cancel

theorem Nat.add_left_cancel (a b c:Nat) (habc: a + b = a + c) : b = c := a:Natb:Natc:Nathabc:a + b = a + cb = c -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. b:Natc:Nat (a : Nat), a + b = a + c b = c; b:Natc:Nat0 + b = 0 + c b = cb:Natc:Nat (n : Nat), (n + b = n + c b = c) n++ + b = n++ + c b = c b:Natc:Nat0 + b = 0 + c b = c b:Natc:Nathbc:0 + b = 0 + cb = c rwa [zero_add, zero_addb:Natc:Nathbc:b = cb = c at hbc b:Natc:Nata:Natih:a + b = a + c b = ca++ + b = a++ + c b = c b:Natc:Nata:Natih:a + b = a + c b = chbc:a++ + b = a++ + cb = c b:Natc:Nata:Natih:a + b = a + c b = chbc:(a + b)++ = (a + c)++b = c b:Natc:Nata:Natih:a + b = a + c b = chbc:a + b = a + cb = c All goals completed! 🐙

(Не із книги) Типу Nat можна дати структуру комутативного адітивного моноїда.

instance Nat.addCommMonoid : AddCommMonoid Nat where add_assoc := add_assoc add_comm := add_comm zero_add := zero_add add_zero := add_zero nsmul := nsmulRec

Визначення 2.2.7 (Додатні натуральні числе).

def Nat.isPos (n:Nat) : Prop := n 0
theorem Nat.isPos_iff (n:Nat) : n.isPos n 0 := n:Natn.isPos n 0 All goals completed! 🐙

Твердження 2.2.8 (Додатне плюс натуральне число буде додатним). Порівняйте із Mathlib-овським Nat.add_pos_left {m : ℕ} (h : 0 < m) (n : ℕ) : 0 < m + nNat.add_pos_left

theorem Nat.add_pos_left {a:Nat} (b:Nat) (ha: a.isPos) : (a + b).isPos := a:Natb:Natha:a.isPos(a + b).isPos -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. a:Natha:a.isPos (b : Nat), (a + b).isPos; a:Natha:a.isPos(a + 0).isPosa:Natha:a.isPos (n : Nat), (a + n).isPos (a + n++).isPos a:Natha:a.isPos(a + 0).isPos rwa [add_zeroa:Natha:a.isPosa.isPos a:Natha:a.isPosb:Nathab:(a + b).isPos(a + b++).isPos a:Natha:a.isPosb:Nathab:(a + b).isPos(a + b)++.isPos a:Natha:a.isPosb:Nathab:(a + b).isPosthis:(a + b)++ 0(a + b)++.isPos All goals completed! 🐙

Порівняйте із Mathlib-овським Nat.add_pos_right {n : ℕ} (m : ℕ) (h : 0 < n) : 0 < m + nNat.add_pos_right

theorem Nat.add_pos_right {a:Nat} (b:Nat) (ha: a.isPos) : (b + a).isPos := a:Natb:Natha:a.isPos(b + a).isPos a:Natb:Natha:a.isPos(a + b).isPos All goals completed! 🐙

Наслідок 2.2.9 (якщо сума дорівнює нулю, тоді доданки дорівнюють нулю). Порівняйте із Mathlib-овським Nat.add_eq_zero {m n : ℕ} : m + n = 0 ↔ m = 0 ∧ n = 0Nat.add_eq_zero

theorem Nat.add_eq_zero (a b:Nat) (hab: a + b = 0) : a = 0 b = 0 := a:Natb:Nathab:a + b = 0a = 0 b = 0 -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. a:Natb:Nathab:a + b = 0h:¬(a = 0 b = 0)False a:Natb:Nathab:a + b = 0h:a 0 b 0False a:Natb:Nathab:a + b = 0ha:a 0Falsea:Natb:Nathab:a + b = 0hb:b 0False a:Natb:Nathab:a + b = 0ha:a 0False a:Natb:Nathab:a + b = 0ha:a.isPosFalse a:Natb:Nathab:a + b = 0ha:a.isPosthis:(a + b).isPosFalse All goals completed! 🐙 a:Natb:Nathab:a + b = 0hb:b.isPosFalse a:Natb:Nathab:a + b = 0hb:b.isPosthis:(a + b).isPosFalse All goals completed! 🐙
/- Наступне API для ∃! може бути корисним для наступної проблеми. Також, тактика `obtain` корисна для вилучення змінної предіката із кванторів існування; наприклад, `obtain ⟨ x, hx ⟩ := h` вилучає змінну предіката `x` та доказ `hx : P x` властивості із гіпотези `h : ∃ x, P x`. -/ existsUnique_of_exists_of_unique.{u_1} {α : Sort u_1} {p : α → Prop} (hex : ∃ x, p x) (hunique : ∀ (y₁ y₂ : α), p y₁ → p y₂ → y₁ = y₂) : ∃! x, p x#check existsUnique_of_exists_of_unique
existsUnique_of_exists_of_unique.{u_1} {α : Sort u_1} {p : α → Prop} (hex : ∃ x, p x)
  (hunique : ∀ (y₁ y₂ : α), p y₁ → p y₂ → y₁ = y₂) : ∃! x, p x
ExistsUnique.exists.{u_1} {α : Sort u_1} {p : α → Prop} : (∃! x, p x) → ∃ x, p x#check ExistsUnique.exists
ExistsUnique.exists.{u_1} {α : Sort u_1} {p : α → Prop} : (∃! x, p x) → ∃ x, p x
ExistsUnique.unique.{u_1} {α : Sort u_1} {p : α → Prop} (h : ∃! x, p x) {y₁ y₂ : α} (py₁ : p y₁) (py₂ : p y₂) : y₁ = y₂#check ExistsUnique.unique
ExistsUnique.unique.{u_1} {α : Sort u_1} {p : α → Prop} (h : ∃! x, p x) {y₁ y₂ : α} (py₁ : p y₁) (py₂ : p y₂) : y₁ = y₂

Лема 2.2.10 (унікальний попередник) / Вправа 2.2.2

lemma declaration uses 'sorry'Nat.uniq_succ_eq (a:Nat) (ha: a.isPos) : ∃! b, b++ = a := a:Natha:a.isPos∃! b, b++ = a All goals completed! 🐙

Визначення 2.2.11 (Порядок натуральних чисел) Це визначає операцію на натуральних числах.

instance Nat.instLE : LE Nat where le n m := a:Nat, m = n + a

Визначення 2.2.11 (Порядок натуральних чисел) Це визначає операцію на натуральних числах.

instance Nat.instLT : LT Nat where lt n m := n m n m
lemma Nat.le_iff (n m:Nat) : n m a:Nat, m = n + a := n:Natm:Natn m a, m = n + a All goals completed! 🐙lemma Nat.lt_iff (n m:Nat) : n < m ( a:Nat, m = n + a) n m := n:Natm:Natn < m (∃ a, m = n + a) n m All goals completed! 🐙

Порівняйте із Mathlib-овським ge_iff_le.{u_1} {α : Type u_1} [LE α] {x y : α} : x ≥ y ↔ y ≤ xge_iff_le

lemma Nat.ge_iff_le (n m:Nat) : n m m n := n:Natm:Natn m m n All goals completed! 🐙

Порівняйте із Mathlib-овським gt_iff_lt.{u_1} {α : Type u_1} [LT α] {x y : α} : x > y ↔ y < xgt_iff_lt

lemma Nat.gt_iff_lt (n m:Nat) : n > m m < n := n:Natm:Natn > m m < n All goals completed! 🐙

Порівняйте із Mathlib-овським Nat.le_of_lt {n m : ℕ} : n < m → n ≤ mNat.le_of_lt

lemma Nat.le_of_lt {n m:Nat} (hnm: n < m) : n m := hnm.1

Порівняйте із Mathlib-овським Nat.le_iff_lt_or_eq {n m : ℕ} : n ≤ m ↔ n < m ∨ n = mNat.le_iff_lt_or_eq

lemma Nat.le_iff_lt_or_eq (n m:Nat) : n m n < m n = m := n:Natm:Natn m n < m n = m n:Natm:Nat(∃ a, m = n + a) (∃ a, m = n + a) n m n = m n:Natm:Nath:n = m(∃ a, m = n + a) (∃ a, m = n + a) n m n = mn:Natm:Nath:¬n = m(∃ a, m = n + a) (∃ a, m = n + a) n m n = m n:Natm:Nath:n = m(∃ a, m = n + a) (∃ a, m = n + a) n m n = m n:Natm:Nath:n = m a, m = m + a n:Natm:Nath:n = mm = m + 0 All goals completed! 🐙 All goals completed! 🐙
example : (8:Nat) > 5 := 8 > 5 (∃ a, 8 = 5 + a) 5 8 a, 8 = 5 + a5 8 a, 8 = 5 + a have : (8:Nat) = 5 + 3 := 8 > 5 All goals completed! 🐙 this:8 = 5 + 3 a, 5 + 3 = 5 + a All goals completed! 🐙 All goals completed! 🐙

Порівняйте із Mathlib-овським Nat.lt_succ_self (n : ℕ) : n < n.succNat.lt_succ_self

theorem declaration uses 'sorry'Nat.succ_gt_self (n:Nat) : n++ > n := n:Natn++ > n All goals completed! 🐙

Твердження 2.2.12 (Базові властивості порядку для натуральних чисел) / Вправа 2.2.3

(a) (Порядок рефлексівен). Порівняйте із Mathlib-овським Nat.le_refl (n : ℕ) : n ≤ nNat.le_refl

theorem declaration uses 'sorry'Nat.ge_refl (a:Nat) : a a := a:Nata a All goals completed! 🐙

(b) (Порядок транзітивен). Тут буде корисною тактика unknown identifier 'obtain'obtain. Порівняйте із Mathlib-овським Nat.le_trans {n m k : ℕ} : n ≤ m → m ≤ k → n ≤ kNat.le_trans

theorem declaration uses 'sorry'Nat.ge_trans {a b c:Nat} (hab: a b) (hbc: b c) : a c := a:Natb:Natc:Nathab:a bhbc:b ca c All goals completed! 🐙

(c) (Порядок антисіметричен). Порівняйте із Mathlib-овським Nat.le_antisymm {n m : ℕ} (h₁ : n ≤ m) (h₂ : m ≤ n) : n = mNat.le_antisymm

theorem declaration uses 'sorry'Nat.ge_antisymm {a b:Nat} (hab: a b) (hba: b a) : a = b := a:Natb:Nathab:a bhba:b aa = b All goals completed! 🐙

(d) (Додавання зберігає порядок). Порівняйте із Mathlib-овським Nat.add_le_add_right {n m : ℕ} (h : n ≤ m) (k : ℕ) : n + k ≤ m + kNat.add_le_add_right

theorem declaration uses 'sorry'Nat.add_ge_add_right (a b c:Nat) : a b a + c b + c := a:Natb:Natc:Nata b a + c b + c All goals completed! 🐙

(d) (Додавання зберігає порядок). Порівняйте із Mathlib-овським Nat.add_le_add_left {n m : ℕ} (h : n ≤ m) (k : ℕ) : k + n ≤ k + mNat.add_le_add_left

theorem Nat.add_ge_add_left (a b c:Nat) : a b c + a c + b := a:Natb:Natc:Nata b c + a c + b a:Natb:Natc:Nata b a + c b + c All goals completed! 🐙

(d) (Додавання зберігає порядок). Порівняйте із Mathlib-овським Nat.add_le_add_right {n m : ℕ} (h : n ≤ m) (k : ℕ) : n + k ≤ m + kNat.add_le_add_right

theorem Nat.add_le_add_right (a b c:Nat) : a b a + c b + c := add_ge_add_right _ _ _

(d) (Додавання зберігає порядок). Порівняйте із Mathlib-овським Nat.add_le_add_left {n m : ℕ} (h : n ≤ m) (k : ℕ) : k + n ≤ k + mNat.add_le_add_left

theorem Nat.add_le_add_left (a b c:Nat) : a b c + a c + b := add_ge_add_left _ _ _

(e) a < b iff a++ ≤ b. Порівняйте із Mathlib-овським Nat.succ_le_iff {m n : ℕ} : m.succ ≤ n ↔ m < nNat.succ_le_iff

theorem declaration uses 'sorry'Nat.lt_iff_succ_le (a b:Nat) : a < b a++ b := a:Natb:Nata < b a++ b All goals completed! 🐙

(f) a < b if and only if b = a + d for positive d.

theorem declaration uses 'sorry'Nat.lt_iff_add_pos (a b:Nat) : a < b d:Nat, d.isPos b = a + d := a:Natb:Nata < b d, d.isPos b = a + d All goals completed! 🐙

Якщо a < b тоді a ̸= b,

theorem Nat.ne_of_lt (a b:Nat) : a < b a b := a:Natb:Nata < b a b a:Natb:Nath:a < ba b; All goals completed! 🐙

Якщо a > b тоді a ̸= b.

theorem Nat.ne_of_gt (a b:Nat) : a > b a b := a:Natb:Nata > b a b a:Natb:Nath:a > ba b; All goals completed! 🐙

Якщо a > b та a < b тоді протиріччя

theorem Nat.not_lt_of_gt (a b:Nat) : a < b a > b False := a:Natb:Nata < b a > b False a:Natb:Nath:a < b a > bFalse a:Natb:Nath:a < b a > bthis:a = bFalse a:Natb:Nath:a < b a > bthis✝:a = bthis:a bFalse All goals completed! 🐙

Твердження 2.2.13 (Тріхотомія порядку для натуральних чисел) / Вправа 2.2.4 Порівняйте із Mathlib-овським trichotomous.{u_1} {α : Sort u_1} {r : α → α → Prop} [IsTrichotomous α r] (a b : α) : r a b ∨ a = b ∨ r b atrichotomous

theorem declaration uses 'sorry'Nat.trichotomous (a b:Nat) : a < b a = b a > b := a:Natb:Nata < b a = b a > b -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. b:Nat (a : Nat), a < b a = b a > b; b:Nat0 < b 0 = b 0 > bb:Nat (n : Nat), n < b n = b n > b n++ < b n++ = b n++ > b b:Nat0 < b 0 = b 0 > b have why : 0 b := a:Natb:Nata < b a = b a > b All goals completed! 🐙 b:Natwhy:0 < b 0 = b0 < b 0 = b 0 > b All goals completed! 🐙 b:Nata:Natih:a < b a = b a > ba++ < b a++ = b a++ > b b:Nata:Natcase1:a < ba++ < b a++ = b a++ > bb:Nata:Natcase2:a = ba++ < b a++ = b a++ > bb:Nata:Natcase3:a > ba++ < b a++ = b a++ > b b:Nata:Natcase1:a < ba++ < b a++ = b a++ > b b:Nata:Natcase1:a++ ba++ < b a++ = b a++ > b b:Nata:Natcase1:a++ < b a++ = ba++ < b a++ = b a++ > b All goals completed! 🐙 b:Nata:Natcase2:a = ba++ < b a++ = b a++ > b have why : a++ > b := a:Natb:Nata < b a = b a > b All goals completed! 🐙 All goals completed! 🐙 have why : a++ > b := a:Natb:Nata < b a = b a > b All goals completed! 🐙 All goals completed! 🐙

(Не із книги) Встановіть алгоритмічну розв'язність для цього порядку обчислювальним шляхом. Частина доказу, що стосується розв'язності, наведена; решта sorry : ?m.18744sorry стосуються тверджень про натуральні числа. Цей результат також можна було б встановити за допомогою тактики unknown identifier 'classical'classical з подальшим використанням unknown identifier 'exact'exact Classical.decRel _, але це зробило б це визначення (а також деякі приклади нижче) необчислювальним.

Порівняйте із Mathlib-овським Nat.decLe (n m : ℕ) : Decidable (n ≤ m)Nat.decLe

def declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'Nat.decLe : (a b : Nat) Decidable (a b) b:NatDecidable (0 b) b:NatDecidable (0 b) b:Nat0 b All goals completed! 🐙 a:Natb:NatDecidable (a++ b) a:Natb:NatDecidable (a++ b) cases decLe a b with a:Natb:Nath:a bDecidable (a++ b) cases decEq a b with a:Natb:Nath✝:a bh:a = bDecidable (a++ b) a:Natb:Nath✝:a bh:a = b¬a++ b All goals completed! 🐙 a:Natb:Nath✝:a bh:¬a = bDecidable (a++ b) a:Natb:Nath✝:a bh:¬a = ba++ b All goals completed! 🐙 a:Natb:Nath:¬a bDecidable (a++ b) a:Natb:Nath:¬a b¬a++ b All goals completed! 🐙
instance Nat.decidableRel : DecidableRel (· · : Nat Nat Prop) := Nat.decLe

(Не із книги) Nat має структуру лінійне впорядкування.

instance declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'Nat.linearOrder : LinearOrder Nat where le_refl := ge_refl le_trans a b c hab hbc := ge_trans hbc hab lt_iff_le_not_le := sorry le_antisymm a b hab hba := ge_antisymm hba hab le_total := sorry toDecidableLE := decidableRel

(Не із книги) Nat має структуру впорядкованого моноїда.

instance Nat.isOrderedAddMonoid : IsOrderedAddMonoid Nat where add_le_add_left := (a b : Nat), a b (c : Nat), c + a c + b a:Natb:Nathab:a bc:Natc + a c + b All goals completed! 🐙

Твердження 2.2.14 (Сильний принцип індукції) / Вправа 2.2.5 Порівняйте із Mathlib-овським Nat.strong_induction_on {p : ℕ → Prop} (n : ℕ) (h : ∀ (n : ℕ), (∀ m < n, p m) → p n) : p nNat.strong_induction_on

theorem declaration uses 'sorry'Nat.strong_induction {m₀:Nat} {P: Nat Prop} (hind: m, m m₀ ( m', m₀ m' m' < m P m') P m) : m, m m₀ P m := m₀:NatP:Nat Prophind: m m₀, (∀ (m' : Nat), m₀ m' m' < m P m') P m m m₀, P m All goals completed! 🐙

Вправа 2.2.6 (індукція у зворотньому напрямку) Порівняйте із Mathlib-овським Nat.decreasingInduction.{u_1} {n : ℕ} {motive : (m : ℕ) → m ≤ n → Sort u_1} (of_succ : (k : ℕ) → (h : k < n) → motive (k + 1) h → motive k ⋯) (self : motive n ⋯) {m : ℕ} (mn : m ≤ n) : motive m mnNat.decreasingInduction

theorem declaration uses 'sorry'Nat.backwards_induction {n:Nat} {P: Nat Prop} (hind: m, P (m++) P m) (hn: P n) : m, m n P m := n:NatP:Nat Prophind: (m : Nat), P (m++) P mhn:P n m n, P m All goals completed! 🐙

Вправа 2.2.7 (індукція із початкової точки) Порівняйте із Mathlib-овським Nat.le_induction {m : ℕ} {P : (n : ℕ) → m ≤ n → Prop} (base : P m ⋯) (succ : ∀ (n : ℕ) (hmn : m ≤ n), P n hmn → P (n + 1) ⋯) (n : ℕ) (hmn : m ≤ n) : P n hmnNat.le_induction

theorem declaration uses 'sorry'Nat.induction_from {n:Nat} {P: Nat Prop} (hind: m, P m P (m++)) : P n m, m n P m := n:NatP:Nat Prophind: (m : Nat), P m P (m++)P n m n, P m All goals completed! 🐙
end Chapter2