|
| 1 | +/- |
| 2 | +Copyright (c) 2018 Guy Leroy. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Sangwoo Jo (aka Jason), Guy Leroy |
| 5 | +
|
| 6 | +Lemmas and extended definitions and properties of gcd and lcm for integers. |
| 7 | +-/ |
| 8 | + |
| 9 | +import data.int.basic data.nat.basic data.nat.gcd |
| 10 | + |
| 11 | +namespace int |
| 12 | + |
| 13 | +/- gcd -/ |
| 14 | + |
| 15 | +@[simp] theorem gcd_self (i : ℤ) : gcd i i = nat_abs i := |
| 16 | +by cases i; simp [gcd, mod_self] |
| 17 | + |
| 18 | +@[simp] theorem gcd_zero_left (i : ℤ) : gcd 0 i = nat_abs i := by simp [gcd] |
| 19 | + |
| 20 | +@[simp] theorem gcd_zero_right (i : ℤ) : gcd i 0 = nat_abs i := |
| 21 | +by cases i; simp [gcd] |
| 22 | + |
| 23 | +theorem gcd_dvd_left (i j : ℤ) : (gcd i j : ℤ) ∣ i := |
| 24 | +dvd_nat_abs.mp (coe_nat_dvd.mpr (nat.gcd_dvd_left (nat_abs i) (nat_abs j))) |
| 25 | + |
| 26 | +theorem gcd_dvd_right (i j : ℤ) : (gcd i j : ℤ) ∣ j := |
| 27 | +dvd_nat_abs.mp (coe_nat_dvd.mpr (nat.gcd_dvd_right (nat_abs i) (nat_abs j))) |
| 28 | + |
| 29 | +theorem gcd_dvd (i j : ℤ) : ((gcd i j : ℤ) ∣ i) ∧ ((gcd i j : ℤ) ∣ j) := |
| 30 | +⟨gcd_dvd_left i j, gcd_dvd_right i j⟩ |
| 31 | + |
| 32 | +theorem dvd_gcd {i j k : ℤ} : k ∣ i → k ∣ j → k ∣ gcd i j := |
| 33 | +by intros H1 H2; |
| 34 | +exact nat_abs_dvd.mp (coe_nat_dvd.mpr (nat.dvd_gcd (nat_abs_dvd_abs_iff.mpr H1) |
| 35 | + (nat_abs_dvd_abs_iff.mpr H2))) |
| 36 | + |
| 37 | +theorem gcd_comm (i j : ℤ) : gcd i j = gcd j i := |
| 38 | +nat.gcd_comm (nat_abs i) (nat_abs j) |
| 39 | + |
| 40 | +theorem gcd_assoc (i j k : ℤ) : gcd (gcd i j) k = gcd i (gcd j k) := |
| 41 | +nat.gcd_assoc (nat_abs i) (nat_abs j) (nat_abs k) |
| 42 | + |
| 43 | +@[simp] theorem gcd_one_left (i : ℤ) : gcd 1 i = 1 := nat.gcd_one_left _ |
| 44 | + |
| 45 | +@[simp] theorem gcd_one_right (i : ℤ) : gcd i 1 = 1 := |
| 46 | +eq.trans (gcd_comm i 1) $ gcd_one_left i |
| 47 | + |
| 48 | +theorem gcd_mul_left (i j k : ℤ) : gcd (i * j) (i * k) = nat_abs i * gcd j k := |
| 49 | +by rw [gcd, nat_abs_mul, nat_abs_mul]; |
| 50 | +exact nat.gcd_mul_left (nat_abs i) (nat_abs j) (nat_abs k) |
| 51 | + |
| 52 | +theorem gcd_mul_right (i j k : ℤ) : gcd (i * j) (k * j) = gcd i k * nat_abs j := |
| 53 | +by rw [gcd, nat_abs_mul, nat_abs_mul]; |
| 54 | +exact nat.gcd_mul_right (nat_abs i) (nat_abs j) (nat_abs k) |
| 55 | + |
| 56 | +theorem gcd_pos_of_non_zero_left {i : ℤ} (j : ℤ) (i_non_zero : i ≠ 0) : gcd i j > 0 := |
| 57 | +nat.gcd_pos_of_pos_left (nat_abs j) (nat_abs_pos_of_ne_zero i_non_zero) |
| 58 | + |
| 59 | +theorem gcd_pos_of_non_zero_right (i : ℤ) {j : ℤ} (j_non_zero : j ≠ 0) : gcd i j > 0 := |
| 60 | +nat.gcd_pos_of_pos_right (nat_abs i) (nat_abs_pos_of_ne_zero j_non_zero) |
| 61 | + |
| 62 | +theorem eq_zero_of_gcd_eq_zero_left {i j : ℤ} (H : gcd i j = 0) : i = 0 := |
| 63 | +eq_zero_of_nat_abs_eq_zero (nat.eq_zero_of_gcd_eq_zero_left H) |
| 64 | + |
| 65 | +theorem eq_zero_of_gcd_eq_zero_right {i j : ℤ} (H : gcd i j = 0) : j = 0 := |
| 66 | +eq_zero_of_nat_abs_eq_zero (nat.eq_zero_of_gcd_eq_zero_right H) |
| 67 | + |
| 68 | +theorem gcd_div {i j k : ℤ} (H1 : k ∣ i) (H2 : k ∣ j) : |
| 69 | + gcd (i / k) (j / k) = gcd i j / nat_abs k := |
| 70 | +by rw [gcd, nat_abs_div i k H1, nat_abs_div j k H2]; |
| 71 | +exact nat.gcd_div (nat_abs_dvd_abs_iff.mpr H1) (nat_abs_dvd_abs_iff.mpr H2) |
| 72 | + |
| 73 | +theorem gcd_dvd_gcd_of_dvd_left {i k : ℤ} (j : ℤ) (H : i ∣ k) : gcd i j ∣ gcd k j := |
| 74 | +int.coe_nat_dvd.1 $ dvd_gcd (dvd.trans (gcd_dvd_left i j) H) (gcd_dvd_right i j) |
| 75 | + |
| 76 | +theorem gcd_dvd_gcd_of_dvd_right {i k : ℤ} (j : ℤ) (H : i ∣ k) : gcd j i ∣ gcd j k := |
| 77 | +int.coe_nat_dvd.1 $ dvd_gcd (gcd_dvd_left j i) (dvd.trans (gcd_dvd_right j i) H) |
| 78 | + |
| 79 | +theorem gcd_dvd_gcd_mul_left (i j k : ℤ) : gcd i j ∣ gcd (k * i) j := |
| 80 | +gcd_dvd_gcd_of_dvd_left _ (dvd_mul_left _ _) |
| 81 | + |
| 82 | +theorem gcd_dvd_gcd_mul_right (i j k : ℤ) : gcd i j ∣ gcd (i * k) j := |
| 83 | +gcd_dvd_gcd_of_dvd_left _ (dvd_mul_right _ _) |
| 84 | + |
| 85 | +theorem gcd_dvd_gcd_mul_left_right (i j k : ℤ) : gcd i j ∣ gcd i (k * j) := |
| 86 | +gcd_dvd_gcd_of_dvd_right _ (dvd_mul_left _ _) |
| 87 | + |
| 88 | +theorem gcd_dvd_gcd_mul_right_right (i j k : ℤ) : gcd i j ∣ gcd i (j * k) := |
| 89 | +gcd_dvd_gcd_of_dvd_right _ (dvd_mul_right _ _) |
| 90 | + |
| 91 | +theorem gcd_eq_left {i j : ℤ} (H : i ∣ j) : gcd i j = nat_abs i := |
| 92 | +nat.dvd_antisymm (by unfold gcd; exact nat.gcd_dvd_left _ _) |
| 93 | + (by unfold gcd; exact nat.dvd_gcd (dvd_refl _) (nat_abs_dvd_abs_iff.mpr H)) |
| 94 | + |
| 95 | +theorem gcd_eq_right {i j : ℤ} (H : j ∣ i) : gcd i j = nat_abs j := |
| 96 | +by rw [gcd_comm, gcd_eq_left H] |
| 97 | + |
| 98 | +/- lcm -/ |
| 99 | + |
| 100 | +def lcm (i j : ℤ) : ℕ := nat_abs(i * j) / (gcd i j) |
| 101 | + |
| 102 | +theorem lcm_def (i j : ℤ) : lcm i j = nat.lcm (nat_abs i) (nat_abs j) := |
| 103 | +by rw [lcm, nat.lcm, gcd, nat_abs_mul] |
| 104 | + |
| 105 | +theorem lcm_comm (i j : ℤ) : lcm i j = lcm j i := |
| 106 | +by delta lcm; rw [mul_comm, gcd_comm] |
| 107 | + |
| 108 | +theorem lcm_zero_left (i : ℤ) : lcm 0 i = 0 := |
| 109 | +by rw [lcm, zero_mul, gcd_zero_left]; by simp |
| 110 | + |
| 111 | +theorem lcm_zero_right (i : ℤ) : lcm i 0 = 0 := lcm_comm 0 i ▸ lcm_zero_left i |
| 112 | + |
| 113 | +theorem lcm_one_left (i : ℤ) : lcm 1 i = nat_abs i := |
| 114 | +by rw [lcm, one_mul, gcd_one_left, nat.div_one] |
| 115 | + |
| 116 | +theorem lcm_one_right (i : ℤ) : lcm i 1 = nat_abs i := |
| 117 | +by unfold lcm; simp |
| 118 | + |
| 119 | +theorem lcm_self (i : ℤ) : lcm i i = nat_abs i := |
| 120 | +by rw [lcm, gcd_self, nat_abs_mul, nat.mul_div_assoc, mul_comm, nat.div_mul_cancel]; |
| 121 | +simp; simp |
| 122 | + |
| 123 | +theorem dvd_lcm_left (i j : ℤ) : i ∣ lcm i j := |
| 124 | +nat_abs_dvd.mp (coe_nat_dvd.mpr (eq.subst (eq.symm (lcm_def i j)) |
| 125 | + (nat.dvd_lcm_left (nat_abs i) (nat_abs j)))) |
| 126 | + |
| 127 | +theorem dvd_lcm_right (i j : ℤ) : j ∣ lcm i j := |
| 128 | +lcm_comm j i ▸ dvd_lcm_left j i |
| 129 | + |
| 130 | +theorem gcd_mul_lcm (i j : ℤ) : gcd i j * lcm i j = nat_abs (i * j) := |
| 131 | +begin |
| 132 | + rw [lcm, mul_comm, nat.div_mul_cancel], |
| 133 | + exact eq.subst (eq.symm (nat_abs_mul i j)) |
| 134 | + (dvd_mul_of_dvd_left (coe_nat_dvd.mp (dvd_nat_abs.mpr (gcd_dvd_left i j))) _), |
| 135 | +end |
| 136 | + |
| 137 | +theorem lcm_dvd {i j k : ℤ} (H1 : i ∣ k) (H2 : j ∣ k) : (lcm i j : ℤ) ∣ k := |
| 138 | +dvd_nat_abs.mp (coe_nat_dvd.mpr (eq.subst (eq.symm (lcm_def i j)) |
| 139 | + (nat.lcm_dvd (nat_abs_dvd_abs_iff.mpr H1) |
| 140 | + (nat_abs_dvd_abs_iff.mpr H2)))) |
| 141 | + |
| 142 | +theorem lcm_assoc (i j k : ℤ) : lcm (lcm i j) k = lcm i (lcm j k) := |
| 143 | +by rw [lcm_def, lcm_def, lcm_def, lcm_def]; |
| 144 | +exact nat.lcm_assoc (nat_abs i) (nat_abs j) (nat_abs k) |
| 145 | + |
| 146 | +/- lemmas -/ |
| 147 | + |
| 148 | +theorem dvd_of_mul_dvd_mul_left {i j k : ℤ} (k_non_zero : k ≠ 0) (H : k * i ∣ k * j) : i ∣ j := |
| 149 | +dvd.elim H (λl H1, by rw mul_assoc at H1; exact ⟨_, eq_of_mul_eq_mul_left k_non_zero H1⟩) |
| 150 | + |
| 151 | +theorem dvd_of_mul_dvd_mul_right {i j k : ℤ} (k_non_zero : k ≠ 0) (H : i * k ∣ j * k) : i ∣ j := |
| 152 | +by rw [mul_comm i k, mul_comm j k] at H; exact dvd_of_mul_dvd_mul_left k_non_zero H |
| 153 | + |
| 154 | + |
| 155 | +end int |
0 commit comments