import Lean4AnalysisTao.C02_NaturalNumbers.S02_Addition -- Definition 2.3.1 axiom MyNat.mul : MyNat โ†’ MyNat โ†’ MyNat infixl:70 " * " => MyNat.mul axiom MyNat.zero_mul : โˆ€ (m : MyNat), ๐Ÿ˜ * m = ๐Ÿ˜ axiom MyNat.succ_mul : โˆ€ (n m : MyNat), (n++) * m = n * m + m -- Lemma 2.3.2 theorem MyNat.mul_zero : โˆ€ (n : MyNat), n * ๐Ÿ˜ = ๐Ÿ˜ := by have hbase : ๐Ÿ˜ * ๐Ÿ˜ = ๐Ÿ˜ := by rw [MyNat.zero_mul ๐Ÿ˜] have hind : โˆ€ {n : MyNat}, n * ๐Ÿ˜ = ๐Ÿ˜ โ†’ n++ * ๐Ÿ˜ = ๐Ÿ˜ := by intro n hn rw [MyNat.succ_mul n ๐Ÿ˜] rw [hn] rw [MyNat.add_zero ๐Ÿ˜] exact MyNat.induction hbase hind theorem MyNat.mul_succ : โˆ€ (n m : MyNat), n * m++ = n * m + n := by have hbase : โˆ€ (m : MyNat), ๐Ÿ˜ * m++ = ๐Ÿ˜ * m + ๐Ÿ˜ := by intro m rw [MyNat.zero_mul m] rw [MyNat.zero_mul (m++)] rw [MyNat.zero_add ๐Ÿ˜] have hind : โˆ€ {n : MyNat}, (โˆ€ (m : MyNat), n * m++ = n * m + n) โ†’ โˆ€ (m : MyNat), n++ * m++ = n++ * m + n++ := by intro n hn intro m rw [MyNat.succ_mul n m] rw [MyNat.succ_mul n (m++)] rw [hn m] rw [MyNat.add_assoc (n * m) n (m++)] rw [MyNat.add_assoc (n * m) m (n++)] rw [MyNat.add_succ n m] rw [MyNat.add_comm m (n++)] rw [MyNat.succ_add n m] exact MyNat.induction hbase hind theorem MyNat.mul_comm : โˆ€ (n m : MyNat), n * m = m * n := by have hbase : โˆ€ (m : MyNat), ๐Ÿ˜ * m = m * ๐Ÿ˜ := by intro m rw [MyNat.zero_mul m] rw [MyNat.mul_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_mul n m] rw [MyNat.mul_succ m n] rw [hn m] exact MyNat.induction hbase hind -- Lemma 2.3.3 theorem MyNat.mul_pos {n m : MyNat} (hn : n.is_positive) (hm : m.is_positive) : (n * m).is_positive := by have : โˆ€ {n : MyNat}, n.is_positive โ†’ โˆ€ {m : MyNat}, m.is_positive โ†’ (n * m).is_positive := by have hbase : ๐Ÿ˜.is_positive โ†’ โˆ€ {m : MyNat}, m.is_positive โ†’ (๐Ÿ˜ * m).is_positive := by intro h intro m hm rw [MyNat.zero_mul m] exact h have hind : โˆ€ {n : MyNat}, (n.is_positive โ†’ โˆ€ {m : MyNat}, m.is_positive โ†’ (n * m).is_positive) โ†’ ((n++).is_positive โ†’ โˆ€ {m : MyNat}, m.is_positive โ†’ (n++ * m).is_positive) := by intro n hn intro hnspos intro m hmpos rw [MyNat.succ_mul n m] exact MyNat.pos_add' hmpos (n * m) exact MyNat.induction hbase hind exact this hn hm theorem MyNat.mul_eq_zero {n m : MyNat} : n * m = ๐Ÿ˜ โ†” n = ๐Ÿ˜ โˆจ m = ๐Ÿ˜ := by constructor ยท intro hnm by_contra hnm push_neg at hnm rcases hnm with โŸจhn, hmโŸฉ have : n * m โ‰  ๐Ÿ˜ := MyNat.mul_pos hn hm exact this hnm ยท intro hnm rcases hnm with (hn | hm) ยท rw [hn] rw [MyNat.zero_mul m] ยท rw [hm] rw [MyNat.mul_zero n] -- Proposition 2.3.4 theorem MyNat.mul_distrib (a b c : MyNat) : a * (b + c) = a * b + a * c := by have : โˆ€ (c : MyNat), a * (b + c) = a * b + a * c := by have hbase : a * (b + ๐Ÿ˜) = a * b + a * ๐Ÿ˜ := by rw [MyNat.add_zero] rw [MyNat.mul_zero] rw [MyNat.add_zero] have hind : โˆ€ {c : MyNat}, a * (b + c) = a * b + a * c โ†’ a * (b + c++) = a * b + a * (c++) := by intro c hc rw [MyNat.add_succ b c] rw [MyNat.mul_succ a (b + c)] rw [MyNat.mul_succ a c] rw [โ† MyNat.add_assoc (a * b) (a * c) a] rw [โ† hc] exact MyNat.induction hbase hind exact this c theorem MyNat.mul_distrib' (a b c : MyNat) : (b + c) * a = b * a + c * a := by rw [MyNat.mul_comm (b + c) a] rw [MyNat.mul_distrib a b c] rw [MyNat.mul_comm a b] rw [MyNat.mul_comm a c] -- Proposition 2.3.5 theorem MyNat.mul_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_mul b] rw [MyNat.zero_mul (b * c)] rw [MyNat.zero_mul 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_mul a b] rw [MyNat.mul_distrib' c (a * b) b] rw [MyNat.succ_mul a (b * c)] rw [ha b c] exact MyNat.induction hbase hind -- Proposition 2.3.6 theorem MyNat.mul_lt_mul_of_pos_right {a b c : MyNat} (hab : a < b) (hc : c.is_positive) : a * c < b * c := by rcases MyNat.lt_iff_eq_add.mp hab with โŸจd, hd, hโŸฉ have h' : b * c = a * c + d * c := by rw [h] rw [MyNat.mul_distrib'] have hdcpos : (d * c).is_positive := MyNat.mul_pos hd hc exact MyNat.lt_iff_eq_add.mpr โŸจd * c, hdcpos, h'โŸฉ -- Corollary 2.3.7 theorem MyNat.mul_cancel_of_pos (a b : MyNat) {c : MyNat} (hc : c โ‰  ๐Ÿ˜) (h : a * c = b * c): a = b := by rcases MyNat.order_trichotomy a b with (h | h | h) ยท rcases h with โŸจhlt, hne, hngtโŸฉ by_contra have : a * c < b * c := MyNat.mul_lt_mul_of_pos_right hlt hc exact this.right h.symm ยท rcases h with โŸจhngt, heq, hnltโŸฉ exact heq ยท rcases h with โŸจhnlt, hne, hgtโŸฉ by_contra have : b * c < a * c := MyNat.mul_lt_mul_of_pos_right hgt hc exact this.right h -- Proposition 2.3.9 theorem MyNat.euclid_division (n : MyNat) {q : MyNat} (hqpos : q.is_positive) : โˆƒ (m r : MyNat), ๐Ÿ˜ โ‰ค r โˆง r < q โˆง n = m * q + r := by have : โˆ€ (n : MyNat), โˆƒ (m r : MyNat), ๐Ÿ˜ โ‰ค r โˆง r < q โˆง n = m * q + r := by have hbase : โˆƒ (m r : MyNat), ๐Ÿ˜ โ‰ค r โˆง r < q โˆง ๐Ÿ˜ = m * q + r := by use ๐Ÿ˜, ๐Ÿ˜ constructor ยท rw [MyNat.le] exact ge_refl ๐Ÿ˜ ยท constructor ยท rw [MyNat.lt] rw [MyNat.gt] constructor ยท rw [MyNat.ge] use q rw [MyNat.zero_add] ยท exact hqpos ยท rw [MyNat.zero_mul q] rw [MyNat.zero_add ๐Ÿ˜] have hind : โˆ€ {n : MyNat}, (โˆƒ (m r : MyNat), ๐Ÿ˜ โ‰ค r โˆง r < q โˆง n = m * q + r) โ†’ โˆƒ (m r : MyNat), ๐Ÿ˜ โ‰ค r โˆง r < q โˆง n++ = m * q + r := by intro n hn rcases hn with โŸจm, r, hr, hrq, hโŸฉ rcases MyNat.lt_iff_eq_add.mp hrq with โŸจd, hdpos, h'โŸฉ by_cases h'' : d = ๐Ÿ™ ยท rw [h''] at hdpos use m++, ๐Ÿ˜ constructor ยท rw [MyNat.le] exact ge_refl ๐Ÿ˜ ยท constructor ยท rw [MyNat.lt] rw [MyNat.gt] constructor ยท rw [MyNat.ge] use q rw [MyNat.zero_add] ยท exact hqpos ยท rw [MyNat.add_zero (m++ * q)] rw [h''] at h' rw [MyNat.succ_mul m q] rw [h] rw [h'] rw [MyNat.mul_distrib m r ๐Ÿ™] rw [MyNat.add_succ r ๐Ÿ˜] rw [MyNat.add_zero r] rw [MyNat.add_succ (m * r + m * ๐Ÿ˜++) r] ยท use m, (r++) constructor ยท rw [MyNat.le] rw [MyNat.ge] use (r++) rw [MyNat.zero_add (r++)] ยท constructor ยท rw [MyNat.lt] rw [MyNat.gt] constructor ยท rw [MyNat.ge] rcases MyNat.unique_pred_of_pos hdpos with โŸจr', hr', h''โŸฉ use r' rw [MyNat.succ_add r r'] rw [โ† MyNat.add_succ r r'] rw [hr'] exact h' ยท have : โˆƒ (d : MyNat), d.is_positive โˆง q = (r++) + d := by rcases MyNat.unique_pred_of_pos hdpos with โŸจr', hr', h'''โŸฉ use r' rw [MyNat.succ_add r r'] rw [โ† MyNat.add_succ r r'] rw [hr'] constructor ยท rw [MyNat.is_positive] by_contra hr'npos rw [hr'npos] at hr' exact h'' hr'.symm ยท exact h' have := MyNat.lt_iff_eq_add.mpr this rw [MyNat.lt] at this rw [MyNat.gt] at this exact this.right ยท rw [MyNat.add_succ (m * q) r] rw [h] exact MyNat.induction hbase hind exact this n -- Definition 2.3.11 axiom MyNat.exp : MyNat โ†’ MyNat โ†’ MyNat infixr:80 " ^ " => MyNat.exp axiom MyNat.exp_zero : โˆ€ (m : MyNat), m ^ ๐Ÿ˜ = ๐Ÿ™ axiom MyNat.exp_succ : โˆ€ (m n : MyNat), m ^ (n++) = m ^ n * m -- Example 2.3.12 theorem MyNat.exp_one (x : MyNat) : x ^ ๐Ÿ™ = x := by rw [MyNat.exp_succ x ๐Ÿ˜] rw [MyNat.exp_zero x] rw [MyNat.succ_mul ๐Ÿ˜ x] rw [MyNat.zero_mul x] rw [MyNat.zero_add x] theorem MyNat.exp_two (x : MyNat) : x ^ ๐Ÿš = x * x := by rw [MyNat.exp_succ x ๐Ÿ™] rw [MyNat.exp_one x] section Exercises -- Exercise 2.3.4 example (a b : MyNat) : (a + b) ^ ๐Ÿš = a ^ ๐Ÿš + ๐Ÿš * a * b + b ^ ๐Ÿš := by rw [MyNat.exp_two (a + b)] rw [MyNat.mul_distrib (a + b) a b] rw [MyNat.mul_distrib' a a b] rw [MyNat.mul_distrib' b a b] rw [MyNat.mul_comm b a] rw [MyNat.add_assoc (a * a) (a * b) (a * b + b * b)] rw [โ† MyNat.add_assoc (a * b) (a * b) (b * b)] rw [MyNat.exp_two a] rw [MyNat.exp_two b] rw [MyNat.succ_mul ๐Ÿ™ a] rw [MyNat.succ_mul ๐Ÿ˜ a] rw [MyNat.zero_mul a] rw [MyNat.zero_add a] rw [โ† MyNat.mul_distrib' b a a] rw [MyNat.add_assoc (a * a)] end Exercises