Addition
Analysis I, Section 2.2: Addition
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:
-
Definition of addition and order for the "Chapter 2" natural numbers,
Chapter2.Nat. -
Establishment of basic properties of addition and order.
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.
Tips from past users
Users of the companion who have completed the exercises in this section are welcome to send their tips for future users in this section as PRs.
-
(Add tip here)
namespace Chapter2
Definition 2.2.1. (Addition of natural numbers).
Compare with Mathlib's Nat.add
abbrev Nat.add (n m : Nat) : Nat := Nat.recurse (fun _ sum ↦ sum++) m n
This instance allows for the notation to be used for natural number addition.
instance Nat.instAdd : Add Nat where
add := add
Compare with Mathlib's Nat.zero_add.
@[simp]
theorem Nat.zero_add (m: Nat) : 0 + m = m := recurse_zero (fun _ sum ↦ sum++) _
Compare with Mathlib's Nat.succ_add.
theorem Nat.succ_add (n m: Nat) : n++ + m = (n+m)++ := n:Natm:Nat⊢ n++ + m = (n + m)++ All goals completed! 🐙
Compare with Mathlib's Nat.one_add.
theorem Nat.one_add (m:Nat) : 1 + m = m++ := m:Nat⊢ 1 + m = m++
All goals completed! 🐙theorem Nat.two_add (m:Nat) : 2 + m = (m++)++ := m:Nat⊢ 2 + m = m++++
All goals completed! 🐙example : (2:Nat) + 3 = 5 := ⊢ 2 + 3 = 5
All goals completed! 🐙
Lemma 2.2.2 (n + 0 = n). Compare with Mathlib's Nat.add_zero.
@[simp]
lemma Nat.add_zero (n:Nat) : n + 0 = n := n:Nat⊢ n + 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 = n → n++ + 0 = n++
⊢ 0 + 0 = 0 All goals completed! 🐙
n:Natih:n + 0 = n⊢ n++ + 0 = n++
calc
(n++) + 0 = (n + 0)++ := n:Natih:n + 0 = n⊢ n++ + 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)++). Compare with Mathlib's Nat.add_succ.
lemma Nat.add_succ (n m:Nat) : n + (m++) = (n + m)++ := n:Natm:Nat⊢ n + m++ = (n + m)++
-- this proof is written to follow the structure of the original text.
m:Nat⊢ ∀ (n : Nat), n + m++ = (n + m)++; m:Nat⊢ 0 + m++ = (0 + m)++m:Nat⊢ ∀ (n : Nat), n + m++ = (n + m)++ → n++ + m++ = (n++ + m)++
m:Nat⊢ 0 + 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?). Compare with Mathlib's Nat.succ_eq_add_one
theorem Nat.succ_eq_add_one (n:Nat) : n++ = n + 1 := n:Nat⊢ n++ = n + 1
All goals completed! 🐙
Proposition 2.2.4 (Addition is commutative). Compare with Mathlib's Nat.add_comm
theorem Nat.add_comm (n m:Nat) : n + m = m + n := n:Natm:Nat⊢ n + m = m + n
-- this proof is written to follow the structure of the original text.
m:Nat⊢ ∀ (n : Nat), n + m = m + n; m:Nat⊢ 0 + m = m + 0m:Nat⊢ ∀ (n : Nat), n + m = m + n → n++ + m = m + n++
m:Nat⊢ 0 + m = m + 0 All goals completed! 🐙
m:Natn:Natih:n + m = m + n⊢ n++ + 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
Compare with Mathlib's Nat.add_assoc.
theorem Nat.add_assoc (a b c:Nat) : (a + b) + c = a + (b + c) := a:Natb:Natc:Nat⊢ a + b + c = a + (b + c)
All goals completed! 🐙
Proposition 2.2.6 (Cancellation law).
Compare with Mathlib's Nat.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 + c⊢ b = c
-- This proof is written to follow the structure of the original text.
b:Natc:Nat⊢ ∀ (a : Nat), a + b = a + c → b = c; b:Natc:Nat⊢ 0 + b = 0 + c → b = cb:Natc:Nat⊢ ∀ (n : Nat), (n + b = n + c → b = c) → n++ + b = n++ + c → b = c
b:Natc:Nat⊢ 0 + b = 0 + c → b = c b:Natc:Nathbc:0 + b = 0 + c⊢ b = c
rwa [zero_add, zero_addb:Natc:Nathbc:b = c⊢ b = c at hbc
b:Natc:Nata:Natih:a + b = a + c → b = c⊢ a++ + b = a++ + c → b = 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 + c)++⊢ b = c
b:Natc:Nata:Natih:a + b = a + c → b = chbc:?_mvar.2309 := Chapter2.Nat.succ_cancel _fvar.2300⊢ b = c
All goals completed! 🐙
(Not from textbook) Nat can be given the structure of a commutative additive monoid.
This permits tactics such as abel to apply to the Chapter 2 natural numbers.
instance Nat.addCommMonoid : AddCommMonoid Nat where
add_assoc := add_assoc
add_comm := add_comm
zero_add := zero_add
add_zero := add_zero
nsmul := nsmulRec
This illustration of the abel tactic is not from the
textbook.
example (a b c d:Nat) : (a+b)+(c+0+d) = (b+c)+(d+a) := a:Natb:Natc:Natd:Nat⊢ a + b + (c + 0 + d) = b + c + (d + a) All goals completed! 🐙theorem Nat.isPos_iff (n:Nat) : n.IsPos ↔ n ≠ 0 := n:Nat⊢ n.IsPos ↔ n ≠ 0 All goals completed! 🐙
Proposition 2.2.8 (positive plus natural number is positive).
Compare with Mathlib's Nat.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
-- 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.IsPos⊢ a.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:(_fvar.4023 + _fvar.4071)++ ≠ 0 := Chapter2.Nat.succ_ne ?_mvar.4176⊢ (a + b)++.IsPos
All goals completed! 🐙
Compare with Mathlib's Nat.add_pos_right.
This theorem is a consequence of the previous theorem and add_comm, and grind can automatically discover such proofs.
theorem Nat.add_pos_right {a:Nat} (b:Nat) (ha: a.IsPos) : (b + a).IsPos := a:Natb:Natha:a.IsPos⊢ (b + a).IsPos
All goals completed! 🐙
Corollary 2.2.9 (if sum vanishes, then summands vanish).
Compare with Mathlib's Nat.add_eq_zero.
theorem Nat.add_eq_zero (a b:Nat) (hab: a + b = 0) : a = 0 ∧ b = 0 := a:Natb:Nathab:a + b = 0⊢ a = 0 ∧ b = 0
-- This proof is written to follow the structure of the original text.
a:Natb:Nathab:a + b = 0h:¬(a = 0 ∧ b = 0)⊢ False
a:Natb:Nathab:a + b = 0h:a ≠ 0 ∨ b ≠ 0⊢ False
a:Natb:Nathab:a + b = 0ha:a ≠ 0⊢ Falsea:Natb:Nathab:a + b = 0hb:b ≠ 0⊢ False
a:Natb:Nathab:a + b = 0ha:a ≠ 0⊢ False a:Natb:Nathab:a + b = 0ha:a.IsPos⊢ False
a:Natb:Nathab:a + b = 0ha:a.IsPosthis:(a + b).IsPos⊢ False
All goals completed! 🐙
a:Natb:Nathab:a + b = 0hb:b.IsPos⊢ False
a:Natb:Nathab:a + b = 0hb:b.IsPosthis:(a + b).IsPos⊢ False
All goals completed! 🐙Lemma 2.2.10 (unique predecessor) / Exercise 2.2.2
lemma 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).
This defines the notation on 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).
This defines the notation on the natural numbers.
instance Nat.instLT : LT Nat where
lt n m := n ≤ m ∧ n ≠ mlemma Nat.le_iff (n m:Nat) : n ≤ m ↔ ∃ a:Nat, m = n + a := n:Natm:Nat⊢ n ≤ 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:Nat⊢ n < m ↔ (∃ a, m = n + a) ∧ n ≠ m All goals completed! 🐙
Compare with Mathlib's ge_iff_le.
@[symm]
lemma Nat.ge_iff_le (n m:Nat) : n ≥ m ↔ m ≤ n := n:Natm:Nat⊢ n ≥ m ↔ m ≤ n All goals completed! 🐙
Compare with Mathlib's gt_iff_lt.
@[symm]
lemma Nat.gt_iff_lt (n m:Nat) : n > m ↔ m < n := n:Natm:Nat⊢ n > m ↔ m < n All goals completed! 🐙
Compare with Mathlib's Nat.le_iff_lt_or_eq.
lemma Nat.le_iff_lt_or_eq (n m:Nat) : n ≤ m ↔ n < m ∨ n = m := n:Natm:Nat⊢ n ≤ 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 = m⊢ m = m + 0
All goals completed! 🐙
All goals completed! 🐙example : (8:Nat) > 5 := ⊢ 8 > 5
⊢ (∃ a, 8 = 5 + a) ∧ 5 ≠ 8
⊢ ∃ a, 8 = 5 + a⊢ 5 ≠ 8
⊢ ∃ a, 8 = 5 + a have : (8:Nat) = 5 + 3 := ⊢ 8 > 5 All goals completed! 🐙
this:8 = 5 + 3 := ?_mvar.63377⊢ ∃ a, 5 + 3 = 5 + a
All goals completed! 🐙
All goals completed! 🐙
Compare with Mathlib's Nat.lt_succ_self.
theorem Nat.succ_gt_self (n:Nat) : n++ > n := n:Nat⊢ n++ > n
All goals completed! 🐙Proposition 2.2.12 (Basic properties of order for natural numbers) / Exercise 2.2.3
(a) (Order is reflexive). Compare with Mathlib's Nat.le_refl.
theorem Nat.ge_refl (a:Nat) : a ≥ a := a:Nat⊢ a ≥ a
All goals completed! 🐙@[refl]
theorem Nat.le_refl (a:Nat) : a ≤ a := a.ge_refl
The refl tag allows for the rfl tactic to work for inequalities.
example (a b:Nat): a+b ≥ a+b := a:Natb:Nat⊢ a + b ≥ a + b All goals completed! 🐙
(b) (Order is transitive). The obtain tactic will be useful here.
Compare with Mathlib's Nat.le_trans.
theorem Nat.ge_trans {a b c:Nat} (hab: a ≥ b) (hbc: b ≥ c) : a ≥ c := a:Natb:Natc:Nathab:a ≥ bhbc:b ≥ c⊢ a ≥ c
All goals completed! 🐙theorem Nat.le_trans {a b c:Nat} (hab: a ≤ b) (hbc: b ≤ c) : a ≤ c := Nat.ge_trans hbc hab
(c) (Order is anti-symmetric). Compare with Mathlib's Nat.le_antisymm.
theorem Nat.ge_antisymm {a b:Nat} (hab: a ≥ b) (hba: b ≥ a) : a = b := a:Natb:Nathab:a ≥ bhba:b ≥ a⊢ a = b
All goals completed! 🐙
(d) (Addition preserves order). Compare with Mathlib's Nat.add_le_add_right.
theorem Nat.add_ge_add_right (a b c:Nat) : a ≥ b ↔ a + c ≥ b + c := a:Natb:Natc:Nat⊢ a ≥ b ↔ a + c ≥ b + c
All goals completed! 🐙
(d) (Addition preserves order). Compare with Mathlib's Nat.add_le_add_left.
theorem Nat.add_ge_add_left (a b c:Nat) : a ≥ b ↔ c + a ≥ c + b := a:Natb:Natc:Nat⊢ a ≥ b ↔ c + a ≥ c + b
a:Natb:Natc:Nat⊢ a ≥ b ↔ a + c ≥ b + c
All goals completed! 🐙
(d) (Addition preserves order). Compare with Mathlib's Nat.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) (Addition preserves order). Compare with Mathlib's Nat.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. Compare with Mathlib's Nat.succ_le_iff.
theorem Nat.lt_iff_succ_le (a b:Nat) : a < b ↔ a++ ≤ b := a:Natb:Nat⊢ a < b ↔ a++ ≤ b
All goals completed! 🐙(f) a < b if and only if b = a + d for positive d.
theorem Nat.lt_iff_add_pos (a b:Nat) : a < b ↔ ∃ d:Nat, d.IsPos ∧ b = a + d := a:Natb:Nat⊢ a < b ↔ ∃ d, d.IsPos ∧ b = 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:Nat⊢ a < b → a ≠ b
a:Natb:Nath:a < b⊢ a ≠ b; All goals completed! 🐙if a > b then a ̸= b.
theorem Nat.ne_of_gt (a b:Nat) : a > b → a ≠ b := a:Natb:Nat⊢ a > b → a ≠ b
a:Natb:Nath:a > b⊢ a ≠ b; 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:Nat⊢ a < b ∧ a > b → False
a:Natb:Nath:a < b ∧ a > b⊢ False
a:Natb:Nath:a < b ∧ a > bthis:?_mvar.64965 := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)⊢ False
a:Natb:Nath:a < b ∧ a > bthis✝:?_mvar.64965 := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)this:?_mvar.65002 := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)⊢ False
All goals completed! 🐙theorem Nat.not_lt_self {a: Nat} (h : a < a) : False := a:Nath:a < a⊢ False
a:Nath:a < a⊢ a < a ∧ a > a
All goals completed! 🐙theorem Nat.lt_of_le_of_lt {a b c : Nat} (hab: a ≤ b) (hbc: b < c) : a < c := a:Natb:Natc:Nathab:a ≤ bhbc:b < c⊢ a < c
a:Natb:Natc:Nathab:a ≤ bhbc:∃ d, d.IsPos ∧ c = b + d⊢ ∃ d, d.IsPos ∧ c = a + d
a:Natb:Natc:Nathbc:∃ d, d.IsPos ∧ c = b + dd:Nathd:b = a + d⊢ ∃ d, d.IsPos ∧ c = a + d
a:Natb:Natc:Natd:Nathd:b = a + de:Nathe1:e.IsPoshe2:c = b + e⊢ ∃ d, d.IsPos ∧ c = a + d
a:Natb:Natc:Natd:Nathd:b = a + de:Nathe1:e.IsPoshe2:c = b + e⊢ (d + e).IsPos ∧ c = a + (d + e); a:Natb:Natc:Natd:Nathd:b = a + de:Nathe1:e.IsPoshe2:c = b + e⊢ (d + e).IsPosa:Natb:Natc:Natd:Nathd:b = a + de:Nathe1:e.IsPoshe2:c = b + e⊢ c = a + (d + e)
a:Natb:Natc:Natd:Nathd:b = a + de:Nathe1:e.IsPoshe2:c = b + e⊢ (d + e).IsPos All goals completed! 🐙
a:Natb:Natc:Natd:Nathd:b = a + de:Nathe1:e.IsPoshe2:c = b + e⊢ c = a + (d + e) All goals completed! 🐙
This lemma was a why? statement from Proposition 2.2.13,
but is more broadly useful, so is extracted here.
theorem Nat.zero_le (a:Nat) : 0 ≤ a := a:Nat⊢ 0 ≤ a
All goals completed! 🐙
Proposition 2.2.13 (Trichotomy of order for natural numbers) / Exercise 2.2.4
Compare with Mathlib's trichotomous. Parts of this theorem have been placed
in the preceding Lean theorems.
theorem Nat.trichotomous (a b:Nat) : a < b ∨ a = b ∨ a > b := a:Natb:Nat⊢ a < b ∨ a = b ∨ a > b
-- This proof is written to follow the structure of the original text.
b:Nat⊢ ∀ (a : Nat), a < b ∨ a = b ∨ a > b; b:Nat⊢ 0 < b ∨ 0 = b ∨ 0 > bb:Nat⊢ ∀ (n : Nat), n < b ∨ n = b ∨ n > b → n++ < b ∨ n++ = b ∨ n++ > b
b:Nat⊢ 0 < b ∨ 0 = b ∨ 0 > b b:Natwhy:0 ≤ b⊢ 0 < b ∨ 0 = b ∨ 0 > b
b:Natwhy:0 < b ∨ 0 = b⊢ 0 < b ∨ 0 = b ∨ 0 > b
All goals completed! 🐙
b:Nata:Natih:a < b ∨ a = b ∨ a > b⊢ a++ < b ∨ a++ = b ∨ a++ > b
b:Nata:Natcase1:a < b⊢ a++ < b ∨ a++ = b ∨ a++ > bb:Nata:Natcase2:a = b⊢ a++ < b ∨ a++ = b ∨ a++ > bb:Nata:Natcase3:a > b⊢ a++ < b ∨ a++ = b ∨ a++ > b
b:Nata:Natcase1:a < b⊢ a++ < b ∨ a++ = b ∨ a++ > b b:Nata:Natcase1:a++ ≤ b⊢ a++ < b ∨ a++ = b ∨ a++ > b
b:Nata:Natcase1:a++ < b ∨ a++ = b⊢ a++ < b ∨ a++ = b ∨ a++ > b
All goals completed! 🐙
b:Nata:Natcase2:a = b⊢ a++ < b ∨ a++ = b ∨ a++ > b have why : a++ > b := a:Natb:Nat⊢ a < b ∨ a = b ∨ a > b All goals completed! 🐙
All goals completed! 🐙
have why : a++ > b := a:Natb:Nat⊢ a < b ∨ a = b ∨ a > b All goals completed! 🐙
All goals completed! 🐙
(Not from textbook) Establish the decidability of this order computably. The portion of the
proof involving decidability has been provided; the remaining sorries involve claims about the
natural numbers. One could also have established this result by the classical tactic
followed by exact Classical.decRel _, but this would make this definition (as well as some
instances below) noncomputable.
Compare with Mathlib's Nat.decLe.
def Nat.decLe : (a b : Nat) → Decidable (a ≤ b)
b:Nat⊢ Decidable (0 ≤ b) b:Nat⊢ Decidable (0 ≤ b)
b:Nat⊢ 0 ≤ b
All goals completed! 🐙
a:Natb:Nat⊢ Decidable (a++ ≤ b) a:Natb:Nat⊢ Decidable (a++ ≤ b)
cases decLe a b with
a:Natb:Nath:a ≤ b⊢ Decidable (a++ ≤ b)
cases decEq a b with
a:Natb:Nath✝:a ≤ bh:a = b⊢ Decidable (a++ ≤ b)
a:Natb:Nath✝:a ≤ bh:a = b⊢ ¬a++ ≤ b
All goals completed! 🐙
a:Natb:Nath✝:a ≤ bh:¬a = b⊢ Decidable (a++ ≤ b)
a:Natb:Nath✝:a ≤ bh:¬a = b⊢ a++ ≤ b
All goals completed! 🐙
a:Natb:Nath:¬a ≤ b⊢ Decidable (a++ ≤ b)
a:Natb:Nath:¬a ≤ b⊢ ¬a++ ≤ b
All goals completed! 🐙instance Nat.decidableRel : DecidableRel (·≤ ·: Nat → Nat → Prop) := Nat.decLe
(Not from textbook) Nat has the structure of a linear ordering. This allows for tactics
such as order and to be applicable to the Chapter 2 natural numbers.
instance Nat.instLinearOrder : LinearOrder Nat where
le_refl := ge_refl
le_trans a b c hab hbc := ge_trans hbc hab
lt_iff_le_not_ge a b := a:Natb:Nat⊢ a < b ↔ a ≤ b ∧ ¬b ≤ a
a:Natb:Nat⊢ a < b → a ≤ b ∧ ¬b ≤ aa:Natb:Nat⊢ a ≤ b ∧ ¬b ≤ a → a < b
a:Natb:Nat⊢ a < b → a ≤ b ∧ ¬b ≤ a a:Natb:Nath:a < b⊢ a ≤ b ∧ ¬b ≤ a; a:Natb:Nath:a < b⊢ ¬b ≤ a
a:Natb:Nath:a < bh':b ≤ a⊢ False
All goals completed! 🐙
a:Natb:Nath1:a ≤ bh2:¬b ≤ a⊢ a < b
a:Natb:Nath1:a ≤ bh2:¬b ≤ a⊢ a ≤ b ∧ a ≠ b; a:Natb:Nath1:a ≤ bh2:¬b ≤ a⊢ a ≠ b
a:Natb:Nath1:a ≤ bh2:¬b ≤ ah:a = b⊢ False
a:Nath1:a ≤ ah2:¬a ≤ a⊢ False
All goals completed! 🐙
le_antisymm a b hab hba := ge_antisymm hba hab
le_total a b := a:Natb:Nat⊢ a ≤ b ∨ b ≤ a
a:Natb:Nath:a < b⊢ a ≤ b ∨ b ≤ aa:Nat⊢ a ≤ a ∨ a ≤ aa:Natb:Nath:a > b⊢ a ≤ b ∨ b ≤ a
a:Natb:Nath:a < b⊢ a ≤ b ∨ b ≤ a a:Natb:Nath:a < b⊢ a ≤ b; All goals completed! 🐙
a:Nat⊢ a ≤ a ∨ a ≤ a All goals completed! 🐙
a:Natb:Nath:a > b⊢ a ≤ b ∨ b ≤ a a:Natb:Nath:a > b⊢ b ≤ a; All goals completed! 🐙
toDecidableLE := decidableRel
This illustration of the order tactic is not from the
textbook.
example (a b c d:Nat) (hab: a ≤ b) (hbc: b ≤ c) (hcd: c ≤ d)
(hda: d ≤ a) : a = c := a:Natb:Natc:Natd:Nathab:a ≤ bhbc:b ≤ chcd:c ≤ dhda:d ≤ a⊢ a = c All goals completed! 🐙
An illustration of the tactic with .
example (a b c d e:Nat) (hab: a ≤ b) (hbc: b < c) (hcd: c ≤ d)
(hde: d ≤ e) : a + 0 < e := a:Natb:Natc:Natd:Nate:Nathab:a ≤ bhbc:b < chcd:c ≤ dhde:d ≤ e⊢ a + 0 < e
calc
a + 0 = a := a:Natb:Natc:Natd:Nate:Nathab:a ≤ bhbc:b < chcd:c ≤ dhde:d ≤ e⊢ a + 0 = a All goals completed! 🐙
_ ≤ b := hab
_ < c := hbc
_ ≤ d := hcd
_ ≤ e := hde
(Not from textbook) Nat has the structure of an ordered monoid. This allows for tactics
such as gcongr to be applicable to the Chapter 2 natural numbers.
instance Nat.isOrderedAddMonoid : IsOrderedAddMonoid Nat where
add_le_add_left a b hab c := (add_le_add_left a b c).mp hab
This illustration of the gcongr tactic is not from the
textbook.
example (a b c d e:Nat) (hab: a ≤ b) (hbc: b < c) (hde: d < e) :
a + d ≤ c + e := a:Natb:Natc:Natd:Nate:Nathab:a ≤ bhbc:b < chde:d < e⊢ a + d ≤ c + e
a:Natb:Natc:Natd:Nate:Nathab:a ≤ bhbc:b < chde:d < e⊢ a ≤ c
All goals completed! 🐙
Proposition 2.2.14 (Strong principle of induction) / Exercise 2.2.5
Compare with Mathlib's Nat.strong_induction_on.
theorem 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! 🐙
Exercise 2.2.6 (backwards induction)
Compare with Mathlib's Nat.decreasingInduction.
theorem 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! 🐙
Exercise 2.2.7 (induction from a starting point)
Compare with Mathlib's Nat.le_induction.
theorem 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