Analysis I, Section 2.2

This file is a translation of Section 2.2 of Analysis I to Lean 4. All numbering refers to the original text.

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:

Note: at the end of this chapter, the Chapter2.Nat class will be deprecated in favor of the standard Mathlib class _root_.Nat, or . However, we will develop the properties of Chapter2.Nat "by hand" for pedagogical purposes.

namespace Chapter2

Definition 2.2.1. (Addition of natural numbers).

abbrev Nat.add (n m : Nat) : Nat := Nat.recurse (fun _ sum sum++) m ninstance Nat.instAdd : Add Nat where add := addtheorem Nat.zero_add (m: Nat) : 0 + m = m := recurse_zero (fun _ sum sum++) _theorem Nat.succ_add (n m: Nat) : n++ + m = (n+m)++ := n:Natm:Natn++ + m = (n + m)++ All goals completed! 🐙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! 🐙-- sum of two natural numbers is again a natural number fun n m => n + m : Nat → Nat → Nat#check (fun (n m:Nat) n + m)
fun n m => n + m : Nat → Nat → Nat
/-- Lemma 2.2.2 (n + 0 = n) -/ lemma Nat.add_zero (n:Nat) : n + 0 = n := n:Natn + 0 = n -- this proof is written to follow the structure of the original text. ∀ (n : Nat), n + 0 = n; 0 + 0 = 0∀ (n : Nat), n + 0 = nn++ + 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! 🐙/-- Lemma 2.2.3 (n+(m++) = (n+m)++). -/ lemma Nat.add_succ (n m:Nat) : n + (m++) = (n + m)++ := n:Natm:Natn + m++ = (n + m)++ -- this proof is written to follow the structure of the original text. 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 (Why?)

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

Proposition 2.2.4 (Addition is commutative)

theorem Nat.add_comm (n m:Nat) : n + m = m + n := n:Natm:Natn + m = m + n -- this proof is written to follow the structure of the original text. m:Nat∀ (n : Nat), n + m = m + n; m:Nat0 + m = m + 0m:Nat∀ (n : Nat), n + m = m + nn++ + 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! 🐙

Proposition 2.2.5 (Addition is associative) / Exercise 2.2.1

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! 🐙

Proposition 2.2.6 (Cancellation law)

theorem Nat.add_cancel_left (a b c:Nat) (habc: a + b = a + c) : b = c := a:Natb:Natc:Nathabc:a + b = a + cb = c -- this proof is written to follow the structure of the original text. b:Natc:Nat∀ (a : Nat), a + b = a + cb = c; b:Natc:Nat0 + b = 0 + cb = cb:Natc:Nat∀ (n : Nat), (n + b = n + cb = c) → n++ + b = n++ + cb = c b:Natc:Nat0 + b = 0 + cb = 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 + cb = ca++ + b = a++ + cb = c b:Natc:Nata:Natih:a + b = a + cb = chbc:a++ + b = a++ + cb = c b:Natc:Nata:Natih:a + b = a + cb = chbc:(a + b)++ = (a + c)++b = c b:Natc:Nata:Natih:a + b = a + cb = chbc:a + b = a + cb = c All goals completed! 🐙

(Not from textbook) Nat can be given the structure of a commutative additive monoid.

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

Definition 2.2.7 (Positive natural numbers).

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

Proposition 2.2.8 (positive plus natural number is positive).

theorem Nat.pos_add {a:Nat} (b:Nat) (ha: a.isPos) : (a + b).isPos := a:Natb:Natha:a.isPos(a + b).isPos -- this proof is written to follow the structure of the original text. 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! 🐙theorem Nat.add_pos {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! 🐙

Corollary 2.2.9 (if sum vanishes, then summands vanish).

theorem Nat.add_eq_zero (a b:Nat) (hab: a + b = 0) : a = 0 b = 0 := a:Natb:Nathab:a + b = 0a = 0b = 0 -- this proof is written to follow the structure of the original text. a:Natb:Nathab:a + b = 0h:¬(a = 0b = 0)False a:Natb:Nathab:a + b = 0h:a0b0False a:Natb:Nathab:a + b = 0ha:a0Falsea:Natb:Nathab:a + b = 0hb:b0False a:Natb:Nathab:a + b = 0ha:a0False 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! 🐙/-- Lemma 2.2.10 (unique predecessor) / Exercise 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! 🐙

Definition 2.2.11 (Ordering of the natural numbers)

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

Definition 2.2.11 (Ordering of the natural numbers)

instance Nat.instLT : LT Nat where lt n m := ( a:Nat, m = n + a) n mlemma Nat.le_iff (n m:Nat) : n m a:Nat, m = n + a := n:Natm:Natnma, 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)nm All goals completed! 🐙lemma Nat.ge_iff_le (n m:Nat) : n m m n := n:Natm:Natnmmn All goals completed! 🐙lemma Nat.gt_iff_lt (n m:Nat) : n > m m < n := n:Natm:Natn > mm < n All goals completed! 🐙lemma Nat.le_of_lt {n m:Nat} (hnm: n < m) : n m := hnm.1lemma Nat.le_iff_lt_or_eq (n m:Nat) : n m n < m n = m := n:Natm:Natnmn < mn = m n:Natm:Nat(∃ a, m = n + a)(∃ a, m = n + a)nmn = m n:Natm:Nath:n = m(∃ a, m = n + a)(∃ a, m = n + a)nmn = mn:Natm:Nath:¬n = m(∃ a, m = n + a)(∃ a, m = n + a)nmn = m n:Natm:Nath:n = m(∃ a, m = n + a)(∃ a, m = n + a)nmn = m n:Natm:Nath:n = ma, 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)58 a, 8 = 5 + a58 a, 8 = 5 + a have : (8:Nat) = 5 + 3 := 8 > 5 All goals completed! 🐙 this:8 = 5 + 3a, 5 + 3 = 5 + a All goals completed! 🐙 All goals completed! 🐙theorem declaration uses 'sorry'Nat.succ_gt (n:Nat) : n++ > n := n:Natn++ > n All goals completed! 🐙

Proposition 2.2.12 (Basic properties of order for natural numbers) / Exercise 2.2.3

(a) (Order is reflexive).

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

(b) (Order is transitive)

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

(c) (Order is anti-symmetric)

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

(d) (Addition preserves order)

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

(d) (Addition preserves order)

theorem Nat.add_ge_add_left (a b c:Nat) : a b c + a c + b := a:Natb:Natc:Natabc + ac + b a:Natb:Natc:Nataba + cb + c All goals completed! 🐙

(d) (Addition preserves order)

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

(d) (Addition preserves order)

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.

theorem declaration uses 'sorry'Nat.lt_iff_succ_le (a b:Nat) : a < b a++ b := a:Natb:Nata < ba++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 < bd, d.isPosb = a + d All goals completed! 🐙

If a < b then a ̸= b,

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

if a > b then a ̸= b.

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

If a > b and a < b then contradiction

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

Proposition 2.2.13 (Trichotomy of order for natural numbers) / Exercise 2.2.4

theorem declaration uses 'sorry'Nat.trichotomous (a b:Nat) : a < b a = b a > b := a:Natb:Nata < ba = ba > b -- this proof is written to follow the structure of the original text. b:Nat∀ (a : Nat), a < ba = ba > b; b:Nat0 < b0 = b0 > bb:Nat∀ (n : Nat), n < bn = bn > bn++ < bn++ = bn++ > b b:Nat0 < b0 = b0 > b have why : 0 b := a:Natb:Nata < ba = ba > b All goals completed! 🐙 b:Natwhy:0 < b0 = b0 < b0 = b0 > b All goals completed! 🐙 b:Nata:Natih:a < ba = ba > ba++ < ba++ = ba++ > b b:Nata:Natcase1:a < ba++ < ba++ = ba++ > bb:Nata:Natcase2:a = ba++ < ba++ = ba++ > bb:Nata:Natcase3:a > ba++ < ba++ = ba++ > b b:Nata:Natcase1:a < ba++ < ba++ = ba++ > b b:Nata:Natcase1:a++ba++ < ba++ = ba++ > b b:Nata:Natcase1:a++ < ba++ = ba++ < ba++ = ba++ > b All goals completed! 🐙 b:Nata:Natcase2:a = ba++ < ba++ = ba++ > b have why : a++ > b := a:Natb:Nata < ba = ba > b All goals completed! 🐙 All goals completed! 🐙 have why : a++ > b := a:Natb:Nata < ba = ba > b All goals completed! 🐙 All goals completed! 🐙

(Not from textbook) The order is decidable. This exercise is only recommended for Lean experts.

instance declaration uses 'sorry'Nat.decidableRel : DecidableRel (· · : Nat Nat Prop) := DecidableRel fun x1 x2 => x1x2 All goals completed! 🐙

(Not from textbook) Nat has the structure of a linear ordering.

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

(Not from textbook) Nat has the structure of an ordered monoid.

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

Proposition 2.2.14 (Strong principle of induction) / Exercise 2.2.5

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:NatProphind:mm₀, (∀ (m' : Nat), m₀m'm' < mP m') → P mmm₀, P m All goals completed! 🐙

Exercise 2.2.6 (backwards induction)

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:NatProphind:∀ (m : Nat), P (m++)P mhn:P nmn, P m All goals completed! 🐙

Exercise 2.2.7 (induction from a starting point)

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:NatProphind:∀ (m : Nat), P mP (m++)P n → ∀ mn, P m All goals completed! 🐙end Chapter2