Аналіз I, Розділ 2, Епілог

У цьому (технічному) епілозі ми показуємо, що натуральні числа Chapter2.Nat : TypeChapter2.Nat з "Розділу 2" ізоморфні стандартним натуральним числам ℕ : Type у різних типових сенсах.

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

Для заповнення цих вибачень потрібні як Chapter2.Nat API, так і Mathlib API для стандартних натуральних чисел ℕ : Type. Таким чином, вони є чудовими вправами для підготовки до вищезгаданого переходу.

У другій половині цього розділу ми також наводимо повністю аксіоматичне трактування натуральних чисел за допомогою аксіом Пеано. Розгляд у попередніх трьох розділах був лише частково аксіоматичним, оскільки ми використовували специфічну конструкцію Chapter2.Nat : TypeChapter2.Nat натуральних чисел, яка була індуктивного типу, і використовували цей індуктивний тип для побудови рекурсора. Тут ми наводимо кілька вправ, щоб показати, як можна виконати ті ж завдання безпосередньо з аксіом Пеано, не знаючи конкретної реалізації натуральних чисел.

abbrev Chapter2.Nat.toNat (n : Chapter2.Nat) : := match n with | zero => 0 | succ n' => n'.toNat + 1lemma Chapter2.Nat.zero_toNat : (0 : Chapter2.Nat).toNat = 0 := rfllemma Chapter2.Nat.succ_toNat (n : Chapter2.Nat) : (n++).toNat = n.toNat + 1 := rflabbrev Chapter2.Nat.equivNat : Chapter2.Nat where toFun := toNat invFun n := (n:Chapter2.Nat) left_inv n := n:Nat(fun n => n) n.toNat = n (fun n => n) zero.toNat = zeron:Nathn:(fun n => n) n.toNat = n(fun n => n) n++.toNat = n++ (fun n => n) zero.toNat = zero All goals completed! 🐙 n:Nathn:(fun n => n) n.toNat = nn + 1 = n++ n:Nathn:(fun n => n) n.toNat = nn++ = n + 1 All goals completed! 🐙 right_inv n := n:((fun n => n) n).toNat = n ((fun n => n) 0).toNat = 0n:hn:((fun n => n) n).toNat = n((fun n => n) (n + 1)).toNat = n + 1 ((fun n => n) 0).toNat = 0 All goals completed! 🐙 n:hn:((fun n => n) n).toNat = n(↑n).toNat = n All goals completed! 🐙abbrev declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'Chapter2.Nat.equivNat_ordered_ring : Chapter2.Nat ≃+*o where toEquiv := equivNat map_add' := (x y : Nat), equivNat.toFun (x + y) = equivNat.toFun x + equivNat.toFun y n:Natm:NatequivNat.toFun (n + m) = equivNat.toFun n + equivNat.toFun m n:Natm:Nat(n + m).toNat = n.toNat + m.toNat All goals completed! 🐙 map_mul' := (x y : Nat), equivNat.toFun (x * y) = equivNat.toFun x * equivNat.toFun y n:Natm:NatequivNat.toFun (n * m) = equivNat.toFun n * equivNat.toFun m n:Natm:Nat(n * m).toNat = n.toNat * m.toNat All goals completed! 🐙 map_le_map_iff' := {a b : Nat}, equivNat.toFun a equivNat.toFun b a b All goals completed! 🐙lemma declaration uses 'sorry'Chapter2.Nat.pow_eq_pow (n m : Chapter2.Nat) : n.toNat ^ m.toNat = n^m := n:Natm:Natn.toNat ^ m.toNat = n ^ m All goals completed! 🐙

Аксіоми Пеано для абстрактного типу Nat : TypeNat

@[ext] class PeanoAxioms where Nat : Type zero : Nat -- Аксіома 2.1 succ : Nat Nat -- Аксіома 2.2 succ_ne : n : Nat, succ n zero -- Аксіома 2.3 succ_cancel : {n m : Nat}, succ n = succ m n = m -- Аксіома 2.4 induction : (P : Nat Prop), P zero ( n : Nat, P n P (succ n)) n : Nat, P n -- Аксіома 2.5
namespace PeanoAxioms

Натуральні числа розділу 2 дотримуються аксіом Пеано.

def Chapter2.Nat : PeanoAxioms where Nat := _root_.Chapter2.Nat zero := Chapter2.Nat.zero succ := Chapter2.Nat.succ succ_ne := Chapter2.Nat.succ_ne succ_cancel := Chapter2.Nat.succ_cancel induction := Chapter2.Nat.induction

Натуральні числа Mathlib дотримуються аксіом Пеано.

def Mathlib.Nat : PeanoAxioms where Nat := zero := 0 succ := Nat.succ succ_ne := Nat.succ_ne_zero succ_cancel := Nat.succ_inj.mp induction _ := Nat.rec

Ви можете співставити натуральні числа Mathlib у іншу струкруту яка дотримується аксіом Пеано.

abbrev natCast (P : PeanoAxioms) : P.Nat := fun n match n with | Nat.zero => P.zero | Nat.succ n => P.succ (natCast P n)
theorem declaration uses 'sorry'natCast_injective (P : PeanoAxioms) : Function.Injective P.natCast := P:PeanoAxiomsFunction.Injective P.natCast All goals completed! 🐙theorem declaration uses 'sorry'natCast_surjective (P : PeanoAxioms) : Function.Surjective P.natCast := P:PeanoAxiomsFunction.Surjective P.natCast All goals completed! 🐙

Поняття еквівалентності між двома структурами, що дотримуються аксіом Пеано

class Equiv (P Q : PeanoAxioms) where equiv : P.Nat Q.Nat equiv_zero : equiv P.zero = Q.zero equiv_succ : n : P.Nat, equiv (P.succ n) = Q.succ (equiv n)
abbrev declaration uses 'sorry'declaration uses 'sorry'Equiv.symm (equiv : Equiv P Q) : Equiv Q P where equiv := equiv.equiv.symm equiv_zero := P:PeanoAxiomsQ:PeanoAxiomsequiv:P.Equiv QPeanoAxioms.Equiv.equiv.symm zero = zero All goals completed! 🐙 equiv_succ n := P:PeanoAxiomsQ:PeanoAxiomsequiv:P.Equiv Qn:NatPeanoAxioms.Equiv.equiv.symm (succ n) = succ (PeanoAxioms.Equiv.equiv.symm n) All goals completed! 🐙abbrev declaration uses 'sorry'declaration uses 'sorry'Equiv.trans (equiv1 : Equiv P Q) (equiv2 : Equiv Q R) : Equiv P R where equiv := equiv1.equiv.trans equiv2.equiv equiv_zero := P:PeanoAxiomsQ:PeanoAxiomsR:PeanoAxiomsequiv1:P.Equiv Qequiv2:Q.Equiv R(equiv.trans equiv) zero = zero All goals completed! 🐙 equiv_succ n := P:PeanoAxiomsQ:PeanoAxiomsR:PeanoAxiomsequiv1:P.Equiv Qequiv2:Q.Equiv Rn:Nat(equiv.trans equiv) (succ n) = succ ((equiv.trans equiv) n) All goals completed! 🐙

Примітка: Я підозрюю, що ця конструкція не є обчислювальною та вимагає класичної логіки.

noncomputable abbrev declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'Equiv.fromNat (P : PeanoAxioms) : Equiv Mathlib.Nat P where equiv := { toFun := P.natCast invFun := P:PeanoAxiomsNat Nat All goals completed! 🐙 left_inv := P:PeanoAxiomsFunction.LeftInverse sorry P.natCast All goals completed! 🐙 right_inv := P:PeanoAxiomsFunction.RightInverse sorry P.natCast All goals completed! 🐙 } equiv_zero := P:PeanoAxioms{ toFun := P.natCast, invFun := sorry, left_inv := , right_inv := } zero = zero All goals completed! 🐙 equiv_succ n := P:PeanoAxiomsn:Nat{ toFun := P.natCast, invFun := sorry, left_inv := , right_inv := } (succ n) = succ ({ toFun := P.natCast, invFun := sorry, left_inv := , right_inv := } n) All goals completed! 🐙
noncomputable abbrev declaration uses 'sorry'Equiv.mk' (P Q : PeanoAxioms) : Equiv P Q := P:PeanoAxiomsQ:PeanoAxiomsP.Equiv Q All goals completed! 🐙theorem declaration uses 'sorry'Equiv.uniq {P Q : PeanoAxioms} (equiv1 equiv2 : PeanoAxioms.Equiv P Q) : equiv1 = equiv2 := P:PeanoAxiomsQ:PeanoAxiomsequiv1:P.Equiv Qequiv2:P.Equiv Qequiv1 = equiv2 All goals completed! 🐙

Приклад результату: рекурсія коректно визначена на будь-якій структурі, що підпорядковується аксіомам Пеано.

theorem declaration uses 'sorry'Nat.recurse_uniq {P : PeanoAxioms} (f: P.Nat P.Nat P.Nat) (c: P.Nat) : ∃! (a: P.Nat P.Nat), a P.zero = c n, a (P.succ n) = f n (a n) := P:PeanoAxiomsf:Nat Nat Natc:Nat∃! a, a zero = c (n : Nat), a (succ n) = f n (a n) All goals completed! 🐙
end PeanoAxioms