|
| 1 | +/- |
| 2 | +Copyright (c) 2015 Jeremy Avigad. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Jeremy Avigad, Robert Y. Lewis |
| 5 | +Ported by: Joël Riou |
| 6 | +-/ |
| 7 | + |
| 8 | +import Mathlib.Algebra.GroupPower.Basic |
| 9 | +import Mathlib.Algebra.GroupWithZero.Commute |
| 10 | +import Mathlib.Algebra.Hom.Ring |
| 11 | +import Mathlib.Algebra.Ring.Commute |
| 12 | +import Mathlib.Algebra.GroupWithZero.Divisibility |
| 13 | +import Mathlib.Algebra.Ring.Divisibility |
| 14 | +import Mathlib.Data.Nat.Order.Basic |
| 15 | + |
| 16 | +/-! |
| 17 | +# Power operations on monoids with zero, semirings, and rings |
| 18 | +
|
| 19 | +This file provides additional lemmas about the natural power operator on rings and semirings. |
| 20 | +Further lemmas about ordered semirings and rings can be found in `Algebra.GroupPower.Lemmas`. |
| 21 | +
|
| 22 | +-/ |
| 23 | + |
| 24 | +variable {R S M : Type _} |
| 25 | + |
| 26 | +section MonoidWithZero |
| 27 | + |
| 28 | +variable [MonoidWithZero M] |
| 29 | + |
| 30 | +theorem zero_pow : ∀ {n : ℕ}, 0 < n → (0 : M) ^ n = 0 |
| 31 | + | n + 1, _ => by rw [pow_succ, zero_mul] |
| 32 | + |
| 33 | +@[simp] |
| 34 | +theorem zero_pow' : ∀ n : ℕ, n ≠ 0 → (0 : M) ^ n = 0 |
| 35 | + | 0, h => absurd rfl h |
| 36 | + | k + 1, _ => by |
| 37 | + rw [pow_succ] |
| 38 | + exact zero_mul _ |
| 39 | + |
| 40 | +theorem zero_pow_eq (n : ℕ) : (0 : M) ^ n = if n = 0 then 1 else 0 := by |
| 41 | + split_ifs with h |
| 42 | + · rw [h, pow_zero] |
| 43 | + · rw [zero_pow (Nat.pos_of_ne_zero h)] |
| 44 | + |
| 45 | +theorem pow_eq_zero_of_le {x : M} {n m : ℕ} (hn : n ≤ m) (hx : x ^ n = 0) : x ^ m = 0 := by |
| 46 | + rw [← tsub_add_cancel_of_le hn, pow_add, hx, mul_zero] |
| 47 | + |
| 48 | +theorem pow_eq_zero [NoZeroDivisors M] {x : M} {n : ℕ} (H : x ^ n = 0) : x = 0 := by |
| 49 | + induction' n with n ih |
| 50 | + · rw [pow_zero] at H |
| 51 | + rw [← mul_one x, H, mul_zero] |
| 52 | + · rw [pow_succ] at H |
| 53 | + exact Or.casesOn (mul_eq_zero.1 H) id ih |
| 54 | + |
| 55 | +@[simp] |
| 56 | +theorem pow_eq_zero_iff [NoZeroDivisors M] {a : M} {n : ℕ} (hn : 0 < n) : a ^ n = 0 ↔ a = 0 := by |
| 57 | + refine' ⟨pow_eq_zero, _⟩ |
| 58 | + rintro rfl |
| 59 | + exact zero_pow hn |
| 60 | + |
| 61 | +theorem pow_eq_zero_iff' [NoZeroDivisors M] [Nontrivial M] {a : M} {n : ℕ} : |
| 62 | + a ^ n = 0 ↔ a = 0 ∧ n ≠ 0 := by cases (zero_le n).eq_or_gt <;> simp [*, ne_of_gt] |
| 63 | + |
| 64 | +theorem pow_ne_zero_iff [NoZeroDivisors M] {a : M} {n : ℕ} (hn : 0 < n) : a ^ n ≠ 0 ↔ a ≠ 0 := |
| 65 | + (pow_eq_zero_iff hn).not |
| 66 | + |
| 67 | +theorem ne_zero_pow {a : M} {n : ℕ} (hn : n ≠ 0) : a ^ n ≠ 0 → a ≠ 0 := by |
| 68 | + contrapose! |
| 69 | + rintro rfl |
| 70 | + exact zero_pow' n hn |
| 71 | +#align ne_zero_pow ne_zero_pow |
| 72 | + |
| 73 | +@[field_simps] |
| 74 | +theorem pow_ne_zero [NoZeroDivisors M] {a : M} (n : ℕ) (h : a ≠ 0) : a ^ n ≠ 0 := |
| 75 | + mt pow_eq_zero h |
| 76 | +#align pow_ne_zero pow_ne_zero |
| 77 | + |
| 78 | +instance NeZero.pow [NoZeroDivisors M] {x : M} [NeZero x] {n : ℕ} : NeZero (x ^ n) := |
| 79 | + ⟨pow_ne_zero n NeZero.out⟩ |
| 80 | +#align ne_zero.pow NeZero.pow |
| 81 | + |
| 82 | +theorem sq_eq_zero_iff [NoZeroDivisors M] {a : M} : a ^ 2 = 0 ↔ a = 0 := |
| 83 | + pow_eq_zero_iff two_pos |
| 84 | +#align sq_eq_zero_iff sq_eq_zero_iff |
| 85 | + |
| 86 | +@[simp] |
| 87 | +theorem zero_pow_eq_zero [Nontrivial M] {n : ℕ} : (0 : M) ^ n = 0 ↔ 0 < n := by |
| 88 | + constructor <;> intro h |
| 89 | + · rw [pos_iff_ne_zero] |
| 90 | + rintro rfl |
| 91 | + simp at h |
| 92 | + · exact zero_pow' n h.ne.symm |
| 93 | + |
| 94 | +theorem Ring.inverse_pow (r : M) : ∀ n : ℕ, Ring.inverse r ^ n = Ring.inverse (r ^ n) |
| 95 | + | 0 => by rw [pow_zero, pow_zero, Ring.inverse_one] |
| 96 | + | n + 1 => by |
| 97 | + rw [pow_succ, pow_succ', Ring.mul_inverse_rev' ((Commute.refl r).pow_left n), |
| 98 | + Ring.inverse_pow r n] |
| 99 | + |
| 100 | +end MonoidWithZero |
| 101 | + |
| 102 | +section CommMonoidWithZero |
| 103 | + |
| 104 | +variable [CommMonoidWithZero M] {n : ℕ} (hn : 0 < n) |
| 105 | + |
| 106 | +/-- We define `x ↦ x^n` (for positive `n : ℕ`) as a `monoid_with_zero_hom` -/ |
| 107 | +def powMonoidWithZeroHom : M →*₀ M := |
| 108 | + { powMonoidHom n with map_zero' := zero_pow hn } |
| 109 | + |
| 110 | +@[simp] |
| 111 | +theorem coe_powMonoidWithZeroHom : (powMonoidWithZeroHom hn : M → M) = fun x ↦ (x^n : M) := rfl |
| 112 | +#align coe_pow_monoid_with_zero_hom coe_powMonoidWithZeroHom |
| 113 | + |
| 114 | +@[simp] |
| 115 | +theorem powMonoidWithZeroHom_apply (a : M) : powMonoidWithZeroHom hn a = a ^ n := |
| 116 | + rfl |
| 117 | +#align pow_monoid_with_zero_hom_apply powMonoidWithZeroHom_apply |
| 118 | + |
| 119 | +end CommMonoidWithZero |
| 120 | + |
| 121 | +theorem pow_dvd_pow_iff [CancelCommMonoidWithZero R] {x : R} {n m : ℕ} (h0 : x ≠ 0) |
| 122 | + (h1 : ¬IsUnit x) : x ^ n ∣ x ^ m ↔ n ≤ m := by |
| 123 | + constructor |
| 124 | + · intro h |
| 125 | + rw [← not_lt] |
| 126 | + intro hmn |
| 127 | + apply h1 |
| 128 | + have : x ^ m * x ∣ x ^ m * 1 := by |
| 129 | + rw [← pow_succ', mul_one] |
| 130 | + exact (pow_dvd_pow _ (Nat.succ_le_of_lt hmn)).trans h |
| 131 | + rwa [mul_dvd_mul_iff_left, ← isUnit_iff_dvd_one] at this |
| 132 | + apply pow_ne_zero m h0 |
| 133 | + · apply pow_dvd_pow |
| 134 | + |
| 135 | +section Semiring |
| 136 | + |
| 137 | +variable [Semiring R] [Semiring S] |
| 138 | + |
| 139 | +protected theorem RingHom.map_pow (f : R →+* S) (a) : ∀ n : ℕ, f (a ^ n) = f a ^ n := |
| 140 | + map_pow f a |
| 141 | +#align ring_hom.map_pow RingHom.map_pow |
| 142 | + |
| 143 | +theorem min_pow_dvd_add {n m : ℕ} {a b c : R} (ha : c ^ n ∣ a) (hb : c ^ m ∣ b) : |
| 144 | + c ^ min n m ∣ a + b := by |
| 145 | + replace ha := (pow_dvd_pow c (min_le_left n m)).trans ha |
| 146 | + replace hb := (pow_dvd_pow c (min_le_right n m)).trans hb |
| 147 | + exact dvd_add ha hb |
| 148 | + |
| 149 | +end Semiring |
| 150 | + |
| 151 | +section CommSemiring |
| 152 | + |
| 153 | +variable [CommSemiring R] |
| 154 | + |
| 155 | +theorem add_sq (a b : R) : (a + b) ^ 2 = a ^ 2 + 2 * a * b + b ^ 2 := by |
| 156 | + simp only [sq, add_mul_self_eq] |
| 157 | +#align add_sq add_sq |
| 158 | + |
| 159 | +theorem add_sq' (a b : R) : (a + b) ^ 2 = a ^ 2 + b ^ 2 + 2 * a * b := by |
| 160 | + rw [add_sq, add_assoc, add_comm _ (b ^ 2), add_assoc] |
| 161 | +#align add_sq' add_sq' |
| 162 | + |
| 163 | +alias add_sq ← add_pow_two |
| 164 | + |
| 165 | +end CommSemiring |
| 166 | + |
| 167 | +section HasDistribNeg |
| 168 | + |
| 169 | +variable [Monoid R] [HasDistribNeg R] |
| 170 | + |
| 171 | +variable (R) |
| 172 | + |
| 173 | +theorem neg_one_pow_eq_or : ∀ n : ℕ, (-1 : R) ^ n = 1 ∨ (-1 : R) ^ n = -1 |
| 174 | + | 0 => Or.inl (pow_zero _) |
| 175 | + | n + 1 => (neg_one_pow_eq_or n).symm.imp |
| 176 | + (fun h ↦ by rw [pow_succ, h, neg_one_mul, neg_neg]) |
| 177 | + (fun h ↦ by rw [pow_succ, h, mul_one]) |
| 178 | + |
| 179 | +variable {R} |
| 180 | + |
| 181 | +theorem neg_pow (a : R) (n : ℕ) : (-a) ^ n = (-1) ^ n * a ^ n := |
| 182 | + neg_one_mul a ▸ (Commute.neg_one_left a).mul_pow n |
| 183 | + |
| 184 | +section |
| 185 | +set_option linter.deprecated false |
| 186 | + |
| 187 | +@[simp] |
| 188 | +theorem neg_pow_bit0 (a : R) (n : ℕ) : (-a) ^ bit0 n = a ^ bit0 n := by |
| 189 | + rw [pow_bit0', neg_mul_neg, pow_bit0'] |
| 190 | +#align neg_pow_bit0 neg_pow_bit0 |
| 191 | + |
| 192 | +@[simp] |
| 193 | +theorem neg_pow_bit1 (a : R) (n : ℕ) : (-a) ^ bit1 n = -a ^ bit1 n := by |
| 194 | + simp only [bit1, pow_succ, neg_pow_bit0, neg_mul_eq_neg_mul] |
| 195 | +#align neg_pow_bit1 neg_pow_bit1 |
| 196 | + |
| 197 | +end |
| 198 | + |
| 199 | +@[simp] |
| 200 | +theorem neg_sq (a : R) : (-a) ^ 2 = a ^ 2 := by simp [sq] |
| 201 | + |
| 202 | +-- Porting note: removed the simp attribute to please the simpNF linter |
| 203 | +theorem neg_one_sq : (-1 : R) ^ 2 = 1 := by simp [neg_sq, one_pow] |
| 204 | + |
| 205 | +alias neg_sq ← neg_pow_two |
| 206 | + |
| 207 | +alias neg_one_sq ← neg_one_pow_two |
| 208 | + |
| 209 | +end HasDistribNeg |
| 210 | + |
| 211 | +section Ring |
| 212 | + |
| 213 | +variable [Ring R] {a b : R} |
| 214 | + |
| 215 | +protected theorem Commute.sq_sub_sq (h : Commute a b) : a ^ 2 - b ^ 2 = (a + b) * (a - b) := by |
| 216 | + rw [sq, sq, h.mul_self_sub_mul_self_eq] |
| 217 | + |
| 218 | +@[simp] |
| 219 | +theorem neg_one_pow_mul_eq_zero_iff {n : ℕ} {r : R} : (-1) ^ n * r = 0 ↔ r = 0 := by |
| 220 | + rcases neg_one_pow_eq_or R n with h | h <;> simp [h] |
| 221 | + |
| 222 | +@[simp] |
| 223 | +theorem mul_neg_one_pow_eq_zero_iff {n : ℕ} {r : R} : r * (-1) ^ n = 0 ↔ r = 0 := by |
| 224 | + rcases neg_one_pow_eq_or R n with h | h <;> simp [h] |
| 225 | + |
| 226 | +variable [NoZeroDivisors R] |
| 227 | + |
| 228 | +protected theorem Commute.sq_eq_sq_iff_eq_or_eq_neg (h : Commute a b) : |
| 229 | + a ^ 2 = b ^ 2 ↔ a = b ∨ a = -b := by |
| 230 | + rw [← sub_eq_zero, h.sq_sub_sq, mul_eq_zero, add_eq_zero_iff_eq_neg, sub_eq_zero, or_comm] |
| 231 | +#align commute.sq_eq_sq_iff_eq_or_eq_neg Commute.sq_eq_sq_iff_eq_or_eq_neg |
| 232 | + |
| 233 | +@[simp] |
| 234 | +theorem sq_eq_one_iff : a ^ 2 = 1 ↔ a = 1 ∨ a = -1 := by |
| 235 | + rw [← (Commute.one_right a).sq_eq_sq_iff_eq_or_eq_neg, one_pow] |
| 236 | +#align sq_eq_one_iff sq_eq_one_iff |
| 237 | + |
| 238 | +theorem sq_ne_one_iff : a ^ 2 ≠ 1 ↔ a ≠ 1 ∧ a ≠ -1 := |
| 239 | + sq_eq_one_iff.not.trans not_or |
| 240 | +#align sq_ne_one_iff sq_ne_one_iff |
| 241 | + |
| 242 | +end Ring |
| 243 | + |
| 244 | +section CommRing |
| 245 | + |
| 246 | +variable [CommRing R] |
| 247 | + |
| 248 | +theorem sq_sub_sq (a b : R) : a ^ 2 - b ^ 2 = (a + b) * (a - b) := |
| 249 | + (Commute.all a b).sq_sub_sq |
| 250 | + |
| 251 | +alias sq_sub_sq ← pow_two_sub_pow_two |
| 252 | + |
| 253 | +theorem sub_sq (a b : R) : (a - b) ^ 2 = a ^ 2 - 2 * a * b + b ^ 2 := by |
| 254 | + rw [sub_eq_add_neg, add_sq, neg_sq, mul_neg, ← sub_eq_add_neg] |
| 255 | + |
| 256 | +alias sub_sq ← sub_pow_two |
| 257 | + |
| 258 | +theorem sub_sq' (a b : R) : (a - b) ^ 2 = a ^ 2 + b ^ 2 - 2 * a * b := by |
| 259 | + rw [sub_eq_add_neg, add_sq', neg_sq, mul_neg, ← sub_eq_add_neg] |
| 260 | + |
| 261 | +variable [NoZeroDivisors R] {a b : R} |
| 262 | + |
| 263 | +theorem sq_eq_sq_iff_eq_or_eq_neg : a ^ 2 = b ^ 2 ↔ a = b ∨ a = -b := |
| 264 | + (Commute.all a b).sq_eq_sq_iff_eq_or_eq_neg |
| 265 | + |
| 266 | +theorem eq_or_eq_neg_of_sq_eq_sq (a b : R) : a ^ 2 = b ^ 2 → a = b ∨ a = -b := |
| 267 | + sq_eq_sq_iff_eq_or_eq_neg.1 |
| 268 | + |
| 269 | +-- Copies of the above CommRing lemmas for `Units R`. |
| 270 | +namespace Units |
| 271 | + |
| 272 | +protected theorem sq_eq_sq_iff_eq_or_eq_neg {a b : Rˣ} : a ^ 2 = b ^ 2 ↔ a = b ∨ a = -b := by |
| 273 | + simp_rw [ext_iff, val_pow_eq_pow_val, sq_eq_sq_iff_eq_or_eq_neg, Units.val_neg, iff_self] |
| 274 | + |
| 275 | +protected theorem eq_or_eq_neg_of_sq_eq_sq (a b : Rˣ) (h : a ^ 2 = b ^ 2) : a = b ∨ a = -b := |
| 276 | + Units.sq_eq_sq_iff_eq_or_eq_neg.1 h |
| 277 | + |
| 278 | +end Units |
| 279 | + |
| 280 | +end CommRing |
0 commit comments