import Mathlib.Tactic.Use import Mathlib.Tactic.ByContra import Mathlib.Tactic.Constructor import Lean4AnalysisTao.C02_NaturalNumbers.S01_PeanoAxioms -- Definition 2.2.1 axiom MyNat.add : MyNat β†’ MyNat β†’ MyNat infixl:65 " + " => MyNat.add axiom MyNat.zero_add : βˆ€ (m : MyNat), 𝟘 + m = m axiom MyNat.succ_add : βˆ€ (n m : MyNat), n++ + m = (n + m)++ -- Lemma 2.2.2 theorem MyNat.add_zero : βˆ€ (n : MyNat), n + 𝟘 = n := by have hbase : 𝟘 + 𝟘 = 𝟘 := by rw [MyNat.zero_add 𝟘] have hind : βˆ€ {n : MyNat}, n + 𝟘 = n β†’ n++ + 𝟘 = n++ := by intro n hn rw [MyNat.succ_add n 𝟘] rw [hn] exact MyNat.induction hbase hind -- Lemma 2.2.3 theorem MyNat.add_succ : βˆ€ (n m : MyNat), n + m++ = (n + m)++ := by have hbase : βˆ€ (m : MyNat), 𝟘 + m++ = (𝟘 + m)++ := by intro m rw [MyNat.zero_add m] rw [MyNat.zero_add (m++)] have hind : βˆ€ {n : MyNat}, (βˆ€ (m : MyNat), n + m++ = (n + m)++) β†’ βˆ€ (m : MyNat), n++ + m++ = (n++ + m)++ := by intro n hn intro m rw [MyNat.succ_add n m] rw [MyNat.succ_add n (m++)] rw [hn m] exact MyNat.induction hbase hind -- Proposition 2.2.4 theorem MyNat.add_comm : βˆ€ (n m : MyNat), n + m = m + n := by have hbase : βˆ€ (m : MyNat), 𝟘 + m = m + 𝟘 := by intro m rw [MyNat.zero_add m] rw [MyNat.add_zero m] have hind : βˆ€ {n : MyNat}, (βˆ€ (m : MyNat), n + m = m + n) β†’ βˆ€ (m : MyNat), n++ + m = m + n++ := by intro n hn intro m rw [MyNat.succ_add n m] rw [MyNat.add_succ m n] rw [hn m] exact MyNat.induction hbase hind -- Proposition 2.2.5 theorem MyNat.add_assoc : βˆ€ (a b c : MyNat), (a + b) + c = a + (b + c) := by have hbase : βˆ€ (b c : MyNat), (𝟘 + b) + c = 𝟘 + (b + c) := by intro b c rw [MyNat.zero_add b] rw [MyNat.zero_add (b + c)] have hind : βˆ€ {a : MyNat}, (βˆ€ (b c : MyNat), (a + b) + c = a + (b + c)) β†’ βˆ€ (b c : MyNat), (a++ + b) + c = a++ + (b + c) := by intro a ha intro b c rw [MyNat.succ_add a b] rw [MyNat.succ_add (a + b) c] rw [MyNat.succ_add a (b + c)] rw [ha b c] exact MyNat.induction hbase hind -- Proposition 2.2.6 theorem MyNat.add_left_cancel : βˆ€ {a b c : MyNat}, a + b = a + c β†’ b = c := by have hbase : βˆ€ {b c : MyNat}, 𝟘 + b = 𝟘 + c β†’ b = c := by intro b c h rw [MyNat.zero_add b] at h rw [MyNat.zero_add c] at h exact h have hind : βˆ€ {a : MyNat}, (βˆ€ {b c : MyNat}, a + b = a + c β†’ b = c) β†’ βˆ€ {b c : MyNat}, a++ + b = a++ + c β†’ b = c := by intro a ha intro b c h rw [MyNat.succ_add a b] at h rw [MyNat.succ_add a c] at h exact ha (MyNat.succ_inj h) exact MyNat.induction hbase hind -- Definition 2.2.7 def MyNat.is_positive (n : MyNat) : Prop := n β‰  𝟘 -- Proposition 2.2.8 theorem MyNat.pos_add {a : MyNat} (ha : a.is_positive) (b : MyNat) : (a + b).is_positive := by have : βˆ€ (b : MyNat), (a + b).is_positive := by have hbase : (a + 𝟘).is_positive := by rw [MyNat.add_zero a] exact ha have hind : βˆ€ {b : MyNat}, (a + b).is_positive β†’ (a + b++).is_positive := by intro b hb rw [MyNat.add_succ a b] exact MyNat.succ_ne_zero (a + b) exact MyNat.induction hbase hind exact this b theorem MyNat.pos_add' {a : MyNat} (ha : a.is_positive) (b : MyNat) : (b + a).is_positive := by rw [MyNat.add_comm b a] exact MyNat.pos_add ha b -- Corollary 2.2.9 theorem MyNat.zero_zero_of_add_zero : βˆ€ {a b : MyNat}, a + b = 𝟘 β†’ a = 𝟘 ∧ b = 𝟘 := by intro a b hab by_contra h rw [not_and_or] at h rcases h with (ha | hb) Β· have : (a + b).is_positive := MyNat.pos_add ha b exact this hab Β· have : (a + b).is_positive := MyNat.pos_add' hb a exact this hab -- Lemma 2.2.10 theorem MyNat.unique_pred_of_pos {a : MyNat} (ha : a.is_positive) : βˆƒ (b : MyNat), b++ = a ∧ (βˆ€ (c : MyNat), c++ = a β†’ b = c) := by have : βˆ€ (a : MyNat), a.is_positive β†’ (βˆƒ (b : MyNat), b++ = a ∧ (βˆ€ (c : MyNat), c++ = a β†’ b = c)) := by have hbase : 𝟘.is_positive β†’ βˆƒ (b : MyNat), b++ = 𝟘 ∧ (βˆ€ (c : MyNat), c++ = 𝟘 β†’ b = c) := by intro h rw [MyNat.is_positive] at h exact False.elim (h rfl) have hind : βˆ€ {a : MyNat}, (a.is_positive β†’ (βˆƒ (b : MyNat), b++ = a ∧ (βˆ€ (c : MyNat), c++ = a β†’ b = c))) β†’ ((a++).is_positive β†’ (βˆƒ (b : MyNat), b++ = a++ ∧ (βˆ€ (c : MyNat), c++ = a++ β†’ b = c))) := by intro a ha intro has use a constructor Β· exact rfl Β· intro c hc exact MyNat.succ_inj hc.symm exact MyNat.induction hbase hind exact this a ha -- Definition 2.2.11 def MyNat.ge : MyNat β†’ MyNat β†’ Prop := fun n m => βˆƒ (a : MyNat), n = m + a infixl:50 " β‰₯ " => MyNat.ge def MyNat.le : MyNat β†’ MyNat β†’ Prop := fun n m => m β‰₯ n infixl:50 " ≀ " => MyNat.le def MyNat.gt : MyNat β†’ MyNat β†’ Prop := fun n m => n β‰₯ m ∧ n β‰  m infixl:50 " > " => MyNat.gt def MyNat.lt : MyNat β†’ MyNat β†’ Prop := fun n m => m > n infixl:50 " < " => MyNat.lt -- Proposition 2.2.12 -- (a) theorem MyNat.ge_refl : βˆ€ (a : MyNat), a β‰₯ a := by intro a rw [MyNat.ge] use 𝟘 rw [MyNat.add_zero a] -- (b) theorem MyNat.ge_trans : βˆ€ {a b c : MyNat}, a β‰₯ b β†’ b β‰₯ c β†’ a β‰₯ c := by intro a b c intro hab hbc rcases hab with ⟨d, hd⟩ rcases hbc with ⟨e, he⟩ rw [MyNat.ge] use d + e rw [hd] rw [he] rw [MyNat.add_assoc c e d] rw [MyNat.add_comm e d] -- (c) theorem MyNat.ge_antisymm : βˆ€ {a b : MyNat}, a β‰₯ b β†’ b β‰₯ a β†’ a = b := by intro a b intro hab hba rcases hab with ⟨d, hd⟩ rcases hba with ⟨e, he⟩ have : 𝟘 = e + d := by rw [he] at hd rw [← MyNat.add_zero a] at hd rw [MyNat.add_assoc a 𝟘 e] at hd rw [MyNat.zero_add e] at hd rw [MyNat.add_assoc a e d] at hd exact MyNat.add_left_cancel hd have : e = 𝟘 ∧ d = 𝟘 := by exact MyNat.zero_zero_of_add_zero this.symm rw [this.right] at hd rw [MyNat.add_zero b] at hd exact hd -- (d) theorem MyNat.ge_iff_add_ge : βˆ€ {a b : MyNat} (c : MyNat), a β‰₯ b ↔ a + c β‰₯ b + c := by intro a b c constructor Β· intro hd rcases hd with ⟨d, hd⟩ rw [MyNat.ge] use d rw [hd] rw [MyNat.add_assoc b c d] rw [MyNat.add_comm c d] rw [MyNat.add_assoc b d c] Β· intro hd rcases hd with ⟨d, hd⟩ rw [MyNat.ge] use d rw [MyNat.add_comm a c] at hd rw [MyNat.add_comm b c] at hd rw [MyNat.add_assoc c b d] at hd exact MyNat.add_left_cancel hd -- (e) theorem MyNat.lt_iff_succ_le : βˆ€ {a b : MyNat}, a < b ↔ a++ ≀ b := by intro a b constructor Β· rw [MyNat.lt] rw [MyNat.gt] intro hba rcases hba with ⟨hba, hne⟩ rw [MyNat.ge] at hba rcases hba with ⟨d, hd⟩ have : d β‰  𝟘 := by by_contra h rw [h] at hd rw [MyNat.add_zero a] at hd exact hne hd rcases MyNat.unique_pred_of_pos this with ⟨e, he, huniq⟩ rw [MyNat.le] rw [MyNat.ge] use e rw [MyNat.succ_add a e] rw [← MyNat.add_succ a e] rw [he] exact hd Β· intro hasb rw [MyNat.le] at hasb rcases hasb with ⟨d, hd⟩ rw [MyNat.lt] rw [MyNat.gt] constructor Β· rw [MyNat.ge] use (d++) rw [hd] rw [MyNat.succ_add a d] rw [MyNat.add_succ a d] Β· by_contra h rw [h] at hd rw [MyNat.succ_add a] at hd rw [← MyNat.add_zero a] at hd rw [MyNat.add_assoc a 𝟘 d] at hd rw [MyNat.zero_add d] at hd rw [← MyNat.add_succ a d] at hd have := MyNat.add_left_cancel hd exact MyNat.succ_ne_zero d this.symm -- (f) theorem MyNat.lt_iff_eq_add : βˆ€ {a b : MyNat}, a < b ↔ βˆƒ (d : MyNat), d.is_positive ∧ b = a + d := by intro a b constructor Β· intro hba rw [MyNat.lt] at hba rcases hba with ⟨hba, hne⟩ rw [MyNat.ge] at hba rcases hba with ⟨d, hd⟩ have : d β‰  𝟘 := by by_contra h rw [h] at hd rw [MyNat.add_zero a] at hd exact hne hd use d constructor Β· exact this Β· exact hd Β· intro hd rcases hd with ⟨d, hd, hd'⟩ rw [MyNat.lt] rw [MyNat.gt] constructor Β· rw [MyNat.ge] use d Β· by_contra h rw [← MyNat.add_zero b] at hd' rw [h] at hd' have : 𝟘 = d := MyNat.add_left_cancel hd' exact hd this.symm -- Proposition 2.2.13 theorem MyNat.order_trichotomy (a b : MyNat) : ((a < b) ∧ Β¬(a = b) ∧ Β¬(a > b)) ∨ (Β¬(a < b) ∧ (a = b) ∧ Β¬(a > b)) ∨ (Β¬(a < b) ∧ Β¬(a = b) ∧ (a > b)) := by have h12 : Β¬((a < b) ∧ (a = b)) := by rintro ⟨h1, h2⟩ rw [MyNat.lt] at h1 rw [MyNat.gt] at h1 exact h1.right.symm h2 have h23 : Β¬((a = b) ∧ (a > b)) := by rintro ⟨h2, h3⟩ rw [MyNat.gt] at h3 exact h3.right h2 have h13 : Β¬((a < b) ∧ (a > b)) := by rintro ⟨h1, h3⟩ rw [MyNat.lt] at h1 rw [MyNat.gt] at h1 rw [MyNat.gt] at h3 have : a = b := MyNat.ge_antisymm h3.left h1.left exact h3.right this have h123 : βˆ€ (a b : MyNat), (a < b) ∨ (a = b) ∨ (a > b) := by have hbase : βˆ€ (b : MyNat), (𝟘 < b) ∨ (𝟘 = b) ∨ (𝟘 > b) := by have : βˆ€ (b : MyNat), 𝟘 ≀ b := by intro b rw [MyNat.le] rw [MyNat.ge] use b rw [MyNat.zero_add b] intro b have : 𝟘 = b ∨ 𝟘 < b := by by_cases h : 𝟘 = b Β· exact Or.inl h Β· rw [← Ne.eq_def] at h exact Or.inr ⟨this b, h.symm⟩ rcases this with (h1 | h2) Β· exact Or.inr (Or.inl h1) Β· exact Or.inl h2 have hind : βˆ€ {a : MyNat}, (βˆ€ (b : MyNat), (a < b) ∨ (a = b) ∨ (a > b)) β†’ βˆ€ (b : MyNat), (a++ < b) ∨ (a++ = b) ∨ (a++ > b) := by intro a ha intro b rcases ha b with (h1 | h2 | h3) Β· have := MyNat.lt_iff_succ_le.mp h1 by_cases h : a++ = b Β· exact Or.inr (Or.inl h) Β· rw [← Ne.eq_def] at h exact Or.inl ⟨this, h.symm⟩ Β· have : a++ > b := by rw [MyNat.gt] constructor Β· rw [MyNat.ge] use (𝟘++) rw [MyNat.add_succ b 𝟘] rw [MyNat.add_zero b] rw [h2] Β· rw [h2] by_contra h rw [← MyNat.add_zero b] at h rw [← MyNat.add_succ b 𝟘] at h have : 𝟘++ = 𝟘 := MyNat.add_left_cancel h exact MyNat.succ_ne_zero 𝟘 this exact Or.inr (Or.inr this) Β· have : a++ > b := by rcases MyNat.lt_iff_eq_add.mp h3 with ⟨d, hd, hd'⟩ rw [MyNat.gt] at h3 rcases h3 with ⟨hge, hne⟩ rw [MyNat.gt] constructor Β· rw [MyNat.ge] use (d++) rw [MyNat.add_succ b d] rw [hd'] Β· by_contra h rw [← MyNat.add_zero b] at h rw [hd'] at h rw [← MyNat.add_succ b d] at h have : d++ = 𝟘 := MyNat.add_left_cancel h exact MyNat.succ_ne_zero d this exact Or.inr (Or.inr this) exact MyNat.induction hbase hind rcases h123 a b with (h1 | h2 | h3) Β· have h2 : Β¬(a = b) := by rw [not_and] at h12 exact h12 h1 have h3 : Β¬(a > b) := by rw [not_and] at h13 exact h13 h1 exact Or.inl ⟨h1, h2, h3⟩ Β· have h1 : Β¬(a < b) := by rw [not_and'] at h12 exact h12 h2 have h3 : Β¬(a > b) := by rw [not_and] at h23 exact h23 h2 exact Or.inr (Or.inl ⟨h1, h2, h3⟩) Β· have h1 : Β¬(a < b) := by rw [not_and'] at h13 exact h13 h3 have h2 : Β¬(a = b) := by rw [not_and'] at h23 exact h23 h3 exact Or.inr (Or.inr ⟨h1, h2, h3⟩) -- Proposition 2.2.14 theorem MyNat.strong_induction {mβ‚€ : MyNat} {P : MyNat β†’ Prop} (hind : βˆ€ {m : MyNat}, m β‰₯ mβ‚€ β†’ ((βˆ€ (m' : MyNat), mβ‚€ ≀ m' β†’ m' < m β†’ P m') β†’ P m)) : βˆ€ {m : MyNat}, m β‰₯ mβ‚€ β†’ P m := by let Q : MyNat β†’ Prop := fun n => (βˆ€ (m : MyNat), mβ‚€ ≀ m β†’ m < n β†’ P m) have : βˆ€ (n : MyNat), Q n := by have hbase : Q 𝟘 := by dsimp [Q] intro m hm hm' rw [MyNat.lt] at hm' rw [MyNat.gt] at hm' rcases hm' with ⟨hm', hne⟩ rw [MyNat.ge] at hm' rcases hm' with ⟨d, hd⟩ have : m + d β‰  𝟘 := MyNat.pos_add hne.symm d exact False.elim (this hd.symm) have hind : βˆ€ {n : MyNat}, Q n β†’ Q n++ := by intro n hn dsimp [Q] dsimp [Q] at hn intro m hm hm' rcases MyNat.order_trichotomy m n with (h1 | h2 | h3) Β· rcases h1 with ⟨hlt, hneq, hngt⟩ exact hn m hm hlt Β· rcases h2 with ⟨hnlt, heq, hngt⟩ rw [heq] rw [heq] at hm rw [MyNat.le] at hm exact hind hm hn Β· rcases h3 with ⟨hnlt, hneq, hgt⟩ by_contra h rw [MyNat.lt] at hm' rw [MyNat.gt] at hm' rcases hm' with ⟨hm', hne⟩ have : n++ ≀ m := MyNat.lt_iff_succ_le.mp hgt have : n++ = m := ge_antisymm hm' this exact hne this exact MyNat.induction hbase hind intro m hm exact hind hm (this m) section Exercises -- Exercise 2.2.6 example {n : MyNat} {P : MyNat β†’ Prop} (hbase : P n) (hind : βˆ€ {m : MyNat}, P m++ β†’ P m) : βˆ€ {m : MyNat}, m ≀ n β†’ P m := by have : βˆ€ {n : MyNat}, P n β†’ βˆ€ {m : MyNat}, m ≀ n β†’ P m := by have hbase : P 𝟘 β†’ βˆ€ {m : MyNat}, m ≀ 𝟘 β†’ P m := by intro hbase intro m hm have : m = 𝟘 := by rw [MyNat.le] at hm rw [MyNat.ge] at hm rcases hm with ⟨d, hd⟩ rcases MyNat.zero_zero_of_add_zero hd.symm with ⟨hd, hd'⟩ exact hd rw [this] exact hbase have hind : βˆ€ {n : MyNat}, (P n β†’ βˆ€ {m : MyNat}, m ≀ n β†’ P m) β†’ (P n++ β†’ βˆ€ {m : MyNat}, m ≀ n++ β†’ P m) := by intro n hn intro hbase intro m hm rcases MyNat.order_trichotomy m (n++) with (h1 | h2 | h3) Β· rcases h1 with ⟨hlt, hneq, hngt⟩ have : m ≀ n := by have := MyNat.lt_iff_succ_le.mp hlt rw [MyNat.le] at this rw [MyNat.ge] at this rcases this with ⟨d, hd⟩ rw [MyNat.le] rw [MyNat.ge] use d rw [MyNat.succ_add m d] at hd exact MyNat.succ_inj hd exact hn (hind hbase) this Β· rcases h2 with ⟨hnlt, heq, hngt⟩ rw [heq] exact hbase Β· rcases h3 with ⟨hnlt, hneq, hgt⟩ by_contra h rw [MyNat.gt] at hgt rcases hgt with ⟨hge, hne⟩ have : m = n++ := MyNat.ge_antisymm hge hm exact hne this exact MyNat.induction hbase hind intro m exact this hbase -- Exercise 2.2.7 example {n : MyNat} {P : MyNat β†’ Prop} (hind : βˆ€ {m : MyNat}, P m β†’ P m++) : P n β†’ (βˆ€ {m : MyNat}, m β‰₯ n β†’ P m) := by intro hn have : βˆ€ {m : MyNat}, m β‰₯ n β†’ P m := by have hbase : 𝟘 β‰₯ n β†’ P 𝟘 := by intro hn' have : n = 𝟘 := by rw [MyNat.ge] at hn' rcases hn' with ⟨d, hd⟩ rcases MyNat.zero_zero_of_add_zero hd.symm with ⟨hd, hd'⟩ exact hd rw [this] at hn exact hn have hind : βˆ€ {m : MyNat}, (m β‰₯ n β†’ P m) β†’ (m++ β‰₯ n β†’ P m++) := by intro m hm intro hge rcases MyNat.order_trichotomy (m++) n with (h1 | h2 | h3) Β· rcases h1 with ⟨hlt, hneq, hngt⟩ rw [MyNat.lt] at hlt rw [MyNat.gt] at hlt rcases hlt with ⟨hle, hne⟩ have : m++ = n := MyNat.ge_antisymm hge hle rw [this] exact hn Β· rcases h2 with ⟨hnlt, heq, hngt⟩ rw [heq] exact hn Β· rcases h3 with ⟨hnlt, hneq, hgt⟩ rw [← MyNat.lt] at hgt have : m β‰₯ n := by have := MyNat.lt_iff_succ_le.mp hgt rw [MyNat.le] at this rw [MyNat.ge] at this rcases this with ⟨d, hd⟩ rw [MyNat.ge] use d rw [MyNat.succ_add n d] at hd exact MyNat.succ_inj hd have : P m := hm this exact hind this exact MyNat.induction hbase hind intro m hmn exact this hmn end Exercises