|
| 1 | +import Mathlib.Data.Nat.Basic |
| 2 | +import Game.Levels.PowGroup |
| 3 | + |
| 4 | +namespace MyAlgebra |
| 5 | + |
| 6 | +def isFiniteOrder {M : Type} [Monoid M] (x : M): Prop := ∃ (n : ℕ), n ≠ 0 ∧ x ^ n = 1 |
| 7 | + |
| 8 | +noncomputable def order {M : Type} [Monoid M] (x : M) : ℕ := by |
| 9 | + classical exact if h : isFiniteOrder x then Nat.find h else 0 |
| 10 | + |
| 11 | +/-- If m^x = 1 → n = 0 -/ |
| 12 | +lemma mpow_order_zero (m : M) [Monoid M] (h0 : order m = 0) : m ^ x = 1 → x = 0 := by |
| 13 | + intro hn |
| 14 | + dsimp [order] at h0 |
| 15 | + split_ifs at h0 with h |
| 16 | + · absurd h0 |
| 17 | + classical have hFinite : ¬(Nat.find h) = 0 ∧ m ^ (Nat.find h) = 1 := Nat.find_spec h |
| 18 | + exact hFinite.left |
| 19 | + · contrapose! h |
| 20 | + use x |
| 21 | + |
| 22 | +/-- If x is the order of m, then m^x = 1 -/ |
| 23 | +lemma mpow_order (m : M) [Monoid M] : m ^ (order m) = 1 := by |
| 24 | + set n := order m with hn |
| 25 | + rw [order] at hn |
| 26 | + split_ifs at hn with h <;> rw [hn] |
| 27 | + · classical exact (Nat.find_spec h).right |
| 28 | + · rfl |
| 29 | + |
| 30 | + |
| 31 | +/-- Let x be the order of m. Write x = nq + r with 0 ≤ r < x. Then, m^r = m^x -/ |
| 32 | +lemma mpow_mod_order (m : M) (x : ℕ) [Monoid M] : m ^ (x % order m) = m ^ x := by |
| 33 | + set n := order m |
| 34 | + nth_rw 2 [←Nat.mod_add_div x n] |
| 35 | + rw [mpow_add, mpow_mul, mpow_order, mpow_id, mul_one] |
| 36 | + done |
| 37 | + |
| 38 | +/-- Let n be the order of m. m^x = 1 ↔ n | x -/ |
| 39 | +lemma order_divides_iff_mpow_id (m : M) [Monoid M] : m ^ x = 1 ↔ order m ∣ x := by |
| 40 | + apply Iff.intro |
| 41 | + · intro hm |
| 42 | + by_cases hm0 : x = 0 |
| 43 | + · use 0 |
| 44 | + rw [mul_zero, hm0] |
| 45 | + · set n := order m with hn |
| 46 | + rw [order] at hn |
| 47 | + split_ifs at hn with h |
| 48 | + · by_contra hnm |
| 49 | + have : x % n < n |
| 50 | + · apply Nat.mod_lt |
| 51 | + rw [hn, GT.gt, pos_iff_ne_zero] |
| 52 | + classical exact (Nat.find_spec h).left |
| 53 | + · nth_rw 2 [hn] at this |
| 54 | + classical apply Nat.find_min h this |
| 55 | + apply And.intro |
| 56 | + · rw [ne_eq, ←Nat.dvd_iff_mod_eq_zero n x] |
| 57 | + exact hnm |
| 58 | + · rw [mpow_mod_order, hm] |
| 59 | + · exfalso |
| 60 | + apply h |
| 61 | + use x |
| 62 | + · rintro ⟨k, rfl⟩ |
| 63 | + rw [mpow_mul, mpow_order, mpow_id] |
| 64 | + done |
| 65 | + |
| 66 | + |
| 67 | +/-- The order of m is nonzero if and only if there exists an n : ℕ such that mⁿ = e -/ |
| 68 | +lemma order_nonzero_iff (m : M) [Monoid M] : order m ≠ 0 ↔ ∃ n ≠ 0, m ^ n = 1 := by |
| 69 | + apply Iff.intro |
| 70 | + · intro h |
| 71 | + use order m |
| 72 | + apply And.intro h |
| 73 | + exact mpow_order m |
| 74 | + · intro ⟨n, hn⟩ |
| 75 | + by_contra! c0 |
| 76 | + absurd hn.left |
| 77 | + apply mpow_order_zero m c0 |
| 78 | + exact hn.right |
| 79 | + |
| 80 | + |
| 81 | +/-- The order of the identity element, 1, in any monoid is 1. -/ |
| 82 | +lemma order_id [Monoid M] : order (1 : M) = 1 := by |
| 83 | + unfold order |
| 84 | + split |
| 85 | + · case _ h => |
| 86 | + unfold isFiniteOrder at h |
| 87 | + classical rw [Nat.find_eq_iff] |
| 88 | + apply And.intro |
| 89 | + · apply And.intro |
| 90 | + · exact Nat.one_ne_zero |
| 91 | + · exact mpow_id 1 |
| 92 | + · intro n hn |
| 93 | + rw [and_iff_not_or_not, not_not] |
| 94 | + left |
| 95 | + push_neg |
| 96 | + exact Nat.lt_one_iff.mp hn |
| 97 | + · case _ h => |
| 98 | + absurd h |
| 99 | + use 1 |
| 100 | + apply And.intro |
| 101 | + · exact Nat.one_ne_zero |
| 102 | + · exact mpow_id 1 |
| 103 | + |
| 104 | +/-- Let x be the order of m and let n : ℕ with n ≠ 0. If m ≠ 0, then the order of mⁿ is nonzero -/ |
| 105 | +lemma mpow_nonzero_order (m : M) [Monoid M] (n : ℕ) (h : order m ≠ 0) : order (m ^ n) ≠ 0 := by |
| 106 | + obtain ⟨x, hm⟩ := (order_nonzero_iff m).mp h |
| 107 | + suffices : ∃ k ≠ 0, (m ^ n) ^ k = 1 |
| 108 | + · rw [order_nonzero_iff] |
| 109 | + exact this |
| 110 | + use x |
| 111 | + apply And.intro |
| 112 | + · exact hm.left |
| 113 | + · rw [←mpow_mul, Nat.mul_comm, mpow_mul, hm.right, mpow_id] |
| 114 | + |
| 115 | +/- |
| 116 | +In any monoid, if the order of m is nonzero, then there is an element n that serves as both a left |
| 117 | +and right inverse to m. |
| 118 | +-/ |
| 119 | +lemma inverse_of_nonzero_order (m : M) [Monoid M] (h : order m ≠ 0) : ∃ (n : M), m * n = 1 ∧ n * m = 1 := by |
| 120 | + use m ^ (order m - 1) |
| 121 | + apply And.intro |
| 122 | + · nth_rw 1 [←mpow_one m] |
| 123 | + rw [←mpow_add, Nat.add_comm] |
| 124 | + rw [Nat.sub_add_cancel] |
| 125 | + · exact mpow_order m |
| 126 | + · exact Nat.one_le_iff_ne_zero.mpr h |
| 127 | + · nth_rw 3 [←mpow_one m] |
| 128 | + rw [←mpow_add] |
| 129 | + rw [Nat.sub_add_cancel] |
| 130 | + · exact mpow_order m |
| 131 | + · exact Nat.one_le_iff_ne_zero.mpr h |
| 132 | + |
| 133 | +/-- Suppose x, y < `order m`. If m^x = m^y, then x = y -/ |
| 134 | +lemma mpow_inj_of_lt_order (m : M) [Monoid M] (x y : ℕ) (hx : x < order m) (hy : y < order m) |
| 135 | + (h : m ^ x = m ^ y) : x = y := by |
| 136 | + wlog hxy : x ≤ y |
| 137 | + · symm |
| 138 | + exact this m y x hy hx (Eq.symm h) (Nat.le_of_not_ge hxy) |
| 139 | + obtain ⟨k, hk⟩ := Nat.le.dest hxy |
| 140 | + suffices : k = 0 |
| 141 | + · rw [this, add_zero] at hk |
| 142 | + exact hk |
| 143 | + apply Nat.eq_zero_of_dvd_of_lt |
| 144 | + · rw [←order_divides_iff_mpow_id m] |
| 145 | + have op_cancel_left : ∀ u v : M, (m ^ x) * u = (m ^ x) * v → u = v |
| 146 | + · intro u v heq |
| 147 | + rw [←one_mul u, ←one_mul v] |
| 148 | + have : ∃ (m' : M), m' * (m ^ x) = 1 |
| 149 | + · have : order m ≠ 0 := by linarith |
| 150 | + by_cases hm' : x = 0 |
| 151 | + · use 1 |
| 152 | + rw [one_mul, hm', mpow_zero] |
| 153 | + · have this := mpow_nonzero_order m x this |
| 154 | + obtain ⟨m', hx'⟩ := inverse_of_nonzero_order (m ^ x) this |
| 155 | + use m' |
| 156 | + exact hx'.right |
| 157 | + obtain ⟨m', op_inv⟩ := this |
| 158 | + repeat rw [←op_inv] |
| 159 | + repeat rw [mul_assoc] |
| 160 | + rw [heq] |
| 161 | + apply op_cancel_left |
| 162 | + rw [mul_one, ←mpow_add, hk] |
| 163 | + exact Eq.symm h |
| 164 | + · rw [←hk] at hy |
| 165 | + linarith |
| 166 | + |
| 167 | +/-- Let r ≠ 0 be the order of m. If m^x = m^y, then y is congruent to x (mod r) -/ |
| 168 | +lemma mod_order_eq_of_mpow_eq (m : M) [Monoid M] (h : order m ≠ 0) (x y : ℕ) |
| 169 | + : m ^ x = m ^ y → x % (order m) = y % (order m) := by |
| 170 | + intro heq |
| 171 | + apply mpow_inj_of_lt_order m (x % order m) (y % order m) |
| 172 | + · apply Nat.mod_lt |
| 173 | + exact Nat.zero_lt_of_ne_zero h |
| 174 | + · apply Nat.mod_lt |
| 175 | + exact Nat.zero_lt_of_ne_zero h |
| 176 | + · repeat rw [mpow_mod_order] |
| 177 | + exact heq |
| 178 | + done |
| 179 | + |
| 180 | + |
| 181 | +/-- Let x be the order g. Then, g^x = 1 -/ |
| 182 | +lemma gpow_order (g : G) [Group G] : g ^ (order g) = 1 := by |
| 183 | + rw [gpow_ofNat, mpow_order] |
| 184 | + |
| 185 | +/- For any integer x, 1^x = 1, if 1 is the identity of a group G. -/ |
| 186 | +lemma gpow_id (x : ℤ) [Group G] : (1 : G) ^ x = 1 := by |
| 187 | + cases x with |
| 188 | + | ofNat x => |
| 189 | + rw [Int.ofNat_eq_coe] |
| 190 | + exact mpow_id x |
| 191 | + | negSucc x => |
| 192 | + rw [gpow_negSucc, mpow_succ_right, ← inv_id, mul_one, mpow_id] |
| 193 | + |
| 194 | +/-- Suppose the order of g is 0. Then if g^x = 1, x = 0 -/ |
| 195 | +lemma gpow_order_zero (g : G) [Group G] {x : ℤ} (h0 : order g = 0) : g ^ x = 1 → x = 0 := by |
| 196 | + intro h |
| 197 | + cases x with |
| 198 | + | ofNat x => |
| 199 | + -- Directly go to the `mpow_order_zero` case for natural numbers |
| 200 | + congr |
| 201 | + exact mpow_order_zero g h0 h |
| 202 | + | negSucc x => |
| 203 | + -- Handle negative case |
| 204 | + exfalso |
| 205 | + absurd h0 |
| 206 | + push_neg |
| 207 | + rw [order_nonzero_iff] |
| 208 | + use x + 1 |
| 209 | + apply And.intro |
| 210 | + · exact Nat.succ_ne_zero x |
| 211 | + · have q := inv_inj (g^(x + 1)) 1 |
| 212 | + rw [← q] |
| 213 | + rw [← inv_id, inv_mpow] |
| 214 | + exact h |
| 215 | + |
| 216 | +/-- Let x be the order g. Write x = q * n + r with 0 ≤ r < x. Then, g^r = g^n -/ |
| 217 | +lemma gpow_mod_order (g : G) [Group G] {x : ℤ} : g ^ (x % order g) = g ^ x := by |
| 218 | + -- Deal with the integer cases |
| 219 | + cases x with |
| 220 | + | ofNat x => |
| 221 | + have : (x : ℤ) % (↑(order g)) = (x % order g : ℕ) := rfl |
| 222 | + rw [Int.ofNat_eq_coe] |
| 223 | + rw [this] |
| 224 | + have q := mpow_mod_order g x |
| 225 | + simp at q |
| 226 | + exact q |
| 227 | + | negSucc x => |
| 228 | + nth_rw 2 [←Int.emod_add_ediv (Int.negSucc x) (order g)] |
| 229 | + rw [←gpow_add, gpow_mul] |
| 230 | + -- rw [gpow_order, gpow_id, mul_one] |
| 231 | + sorry |
| 232 | + |
| 233 | +/-- Suppose the order of g is 0. Then g^x = g^y → x = y -/ |
| 234 | +lemma gpow_inj_of_order_zero (g : G) [Group G] {x y : ℤ} (h : order g = 0) (heq : g ^ x = g ^ y) : x = y := by |
| 235 | + induction y using Int.induction_on generalizing x with |
| 236 | + | hz => |
| 237 | + apply gpow_order_zero g h |
| 238 | + exact heq |
| 239 | + | hp y ih => |
| 240 | + rw [←Int.sub_add_cancel x 1] |
| 241 | + congr 1 |
| 242 | + apply ih |
| 243 | + rw [←gpow_pred, heq, gpow_succ, mul_assoc, mul_inv, mul_one] |
| 244 | + | hn y ih => |
| 245 | + rw [←Int.add_sub_cancel x 1] |
| 246 | + congr 1 |
| 247 | + apply ih |
| 248 | + rw [gpow_succ, heq, ←gpow_pred, mul_assoc, inv_mul, mul_one] |
| 249 | + |
| 250 | +/- |
| 251 | +This lemma has nothing to do with `order`, but it is essential to the following theorem. |
| 252 | +If `x` is a positive integer, then every integer is congruent [MOD x] to some natural number. |
| 253 | +-/ |
| 254 | +lemma emod_has_nat {y : ℕ} (x : ℤ) (hy : 0 < y) : ∃ (z : ℕ), x % y = z % y := by |
| 255 | + -- cases x with |
| 256 | + -- | ofNat x => |
| 257 | + -- use x |
| 258 | + -- rfl |
| 259 | + -- | negSucc x => |
| 260 | + -- use y - 1 - x % y |
| 261 | + |
| 262 | + -- rw [Int.natCast_sub, Int.natCast_sub] |
| 263 | + -- · rw [Int.ofNat_emod x y, Nat.cast_one] |
| 264 | + -- rw [←@Int.negSucc_emod x y] |
| 265 | + -- symm |
| 266 | + -- apply Int.emod_emod |
| 267 | + -- rw [Int.ofNat_pos] |
| 268 | + -- exact hy |
| 269 | + -- · exact hy |
| 270 | + -- · apply Nat.le_sub_one_of_lt |
| 271 | + -- apply Nat.mod_lt |
| 272 | + -- exact hy |
| 273 | + sorry |
| 274 | + |
| 275 | +/-- |
| 276 | +The capstone theorem of `gpow`: let r = order g. Then if two integers `x` and `y` satisfy g^x = g^y, |
| 277 | +then x ≡ y [MOD order g]. If r = 0, then x = y. |
| 278 | +-/ |
| 279 | +lemma mod_order_eq_of_gpow_eq (g : G) [Group G] {x y : ℤ} |
| 280 | + : g ^ x = g ^ y → x % (order g) = y % (order g) := by |
| 281 | + intro h |
| 282 | + by_cases h₀ : order g = 0 |
| 283 | + · rw [h₀] |
| 284 | + simp |
| 285 | + exact gpow_inj_of_order_zero g h₀ h |
| 286 | + · obtain ⟨x', hx'⟩ := emod_has_nat x (Nat.zero_lt_of_ne_zero h₀) |
| 287 | + obtain ⟨y', hy'⟩ := emod_has_nat y (Nat.zero_lt_of_ne_zero h₀) |
| 288 | + rw [hx', hy'] |
| 289 | + repeat rw [←Int.ofNat_emod] |
| 290 | + congr 1 |
| 291 | + have q := mod_order_eq_of_mpow_eq g h₀ x' y' |
| 292 | + rw [q] |
| 293 | + rw [←mpow_mod_order g x', ←mpow_mod_order g y'] |
| 294 | + rw [← Int.ofNat_emod] at hx' hy' |
| 295 | + -- have : g ^ x' = g ^ y' := |
| 296 | + sorry |
| 297 | + -- rw [←hx', ←hy'] |
| 298 | + -- repeat rw [gpow_mod_order] |
| 299 | + -- exact h |
0 commit comments