Skip to content

Commit e6e5808

Browse files
committed
Add Order with Sorry
1 parent c75b654 commit e6e5808

1 file changed

Lines changed: 299 additions & 0 deletions

File tree

Game/MyAlgebra/Order.lean

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
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

Comments
 (0)