Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit a437a24

Browse files
alreadydoneocfnash
andcommitted
chore(topology/instances/add_circle): golf (#18020)
Net -23 lines. Also: + Switch the order of `exists_gcd_eq_one_of_is_of_fin_add_order` and `add_order_of_eq_pos_iff`. + Switch the order of `gcd_mul_add_order_of_div_eq` and `add_order_of_div_of_gcd_eq_one`. + Add easy lemmas `order_of_eq_iff`, `coe_period` and `add_order_of_period_div`. + Remove `[floor_ring]` hypothesis. + Replace `gcd` by `nat.gcd`. Co-authored-by: Oliver Nash <github@olivernash.org> Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>
1 parent 0959766 commit a437a24

File tree

2 files changed

+84
-107
lines changed

2 files changed

+84
-107
lines changed

src/group_theory/order_of_element.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ by rwa [order_of, minimal_period, dif_neg]
153153
order_of x = 0 ↔ ∀ n : ℕ, 0 < n → x ^ n ≠ 1 :=
154154
by simp_rw [order_of_eq_zero_iff, is_of_fin_order_iff_pow_eq_one, not_exists, not_and]
155155

156+
@[to_additive add_order_of_eq_iff] lemma order_of_eq_iff {n} (h : 0 < n) :
157+
order_of x = n ↔ x ^ n = 1 ∧ ∀ m, m < n → 0 < m → x ^ m ≠ 1 :=
158+
begin
159+
simp_rw [ne, ← is_periodic_pt_mul_iff_pow_eq_one, order_of, minimal_period],
160+
split_ifs with h1,
161+
{ rw [find_eq_iff, exists_prop_of_true h], push_neg, refl },
162+
{ rw iff_false_left h.ne, rintro ⟨h', -⟩, exact h1 ⟨n, h, h'⟩ },
163+
end
164+
156165
/-- A group element has finite order iff its order is positive. -/
157166
@[to_additive add_order_of_pos_iff
158167
"A group element has finite additive order iff its order is positive."]

src/topology/instances/add_circle.lean

Lines changed: 75 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ begin
9090
{ exact ⟨(n : ℤ), by simp⟩, },
9191
end
9292

93+
lemma coe_period : (p : add_circle p) = 0 :=
94+
(quotient_add_group.eq_zero_iff p).2 $ mem_zmultiples p
95+
9396
@[simp] lemma coe_add_period (x : 𝕜) : (((x + p) : 𝕜) : add_circle p) = x :=
94-
begin
95-
rw [quotient_add_group.coe_add, ←eq_sub_iff_add_eq', sub_self, quotient_add_group.eq_zero_iff],
96-
exact mem_zmultiples p,
97-
end
97+
by rw [coe_add, ←eq_sub_iff_add_eq', sub_self, coe_period]
9898

9999
@[continuity, nolint unused_arguments] protected lemma continuous_mk' :
100100
continuous (quotient_add_group.mk' (zmultiples p) : 𝕜 → add_circle p) :=
@@ -195,31 +195,37 @@ section finite_order_points
195195

196196
variables {p}
197197

198-
lemma add_order_of_div_of_gcd_eq_one {m n : ℕ} (hn : 0 < n) (h : gcd m n = 1) :
199-
add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
198+
lemma add_order_of_period_div {n : ℕ} (h : 0 < n) : add_order_of ((p / n : 𝕜) : add_circle p) = n :=
199+
begin
200+
rw [add_order_of_eq_iff h],
201+
replace h : 0 < (n : 𝕜) := nat.cast_pos.2 h,
202+
refine ⟨_, λ m hn h0, _⟩; simp only [ne, ← coe_nsmul, nsmul_eq_mul],
203+
{ rw [mul_div_cancel' _ h.ne', coe_period] },
204+
rw coe_eq_zero_of_pos_iff p hp.out (mul_pos (nat.cast_pos.2 h0) $ div_pos hp.out h),
205+
rintro ⟨k, hk⟩,
206+
rw [mul_div, eq_div_iff h.ne', nsmul_eq_mul, mul_right_comm, ← nat.cast_mul,
207+
(mul_left_injective₀ hp.out.ne').eq_iff, nat.cast_inj, mul_comm] at hk,
208+
exact (nat.le_of_dvd h0 ⟨_, hk.symm⟩).not_lt hn,
209+
end
210+
211+
variables (p)
212+
213+
lemma gcd_mul_add_order_of_div_eq {n : ℕ} (m : ℕ) (hn : 0 < n) :
214+
m.gcd n * add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
200215
begin
201-
rcases m.eq_zero_or_pos with rfl | hm, { rw [gcd_zero_left, normalize_eq] at h, simp [h], },
202-
set x : add_circle p := ↑(↑m / ↑n * p),
203-
have hn₀ : (n : 𝕜) ≠ 0, { norm_cast, exact ne_of_gt hn, },
204-
have hnx : n • x = 0,
205-
{ rw [← coe_nsmul, nsmul_eq_mul, ← mul_assoc, mul_div, mul_div_cancel_left _ hn₀,
206-
← nsmul_eq_mul, quotient_add_group.eq_zero_iff],
207-
exact nsmul_mem_zmultiples p m, },
208-
apply nat.dvd_antisymm (add_order_of_dvd_of_nsmul_eq_zero hnx),
209-
suffices : ∃ (z : ℕ), z * n = (add_order_of x) * m,
210-
{ obtain ⟨z, hz⟩ := this,
211-
simpa only [h, mul_one, gcd_comm n] using dvd_mul_gcd_of_dvd_mul (dvd.intro_left z hz), },
212-
replace hp := hp.out,
213-
have : 0 < add_order_of x • (↑m / ↑n * p) := smul_pos
214-
(add_order_of_pos' $ (is_of_fin_add_order_iff_nsmul_eq_zero _).2 ⟨n, hn, hnx⟩) (by positivity),
215-
obtain ⟨z, hz⟩ := (coe_eq_zero_of_pos_iff p hp this).mp (add_order_of_nsmul_eq_zero x),
216-
rw [← smul_mul_assoc, nsmul_eq_mul, nsmul_eq_mul, mul_left_inj' hp.ne.symm, mul_div,
217-
eq_div_iff hn₀] at hz,
218-
norm_cast at hz,
219-
exact ⟨z, hz⟩,
216+
rw [mul_comm_div, ← nsmul_eq_mul, coe_nsmul, add_order_of_nsmul''],
217+
{ rw [add_order_of_period_div hn, nat.gcd_comm, nat.mul_div_cancel'],
218+
exacts [n.gcd_dvd_left m, hp] },
219+
{ rw [← add_order_of_pos_iff, add_order_of_period_div hn], exacts [hn, hp] },
220220
end
221221

222-
lemma add_order_of_div_of_gcd_eq_one' {m : ℤ} {n : ℕ} (hn : 0 < n) (h : gcd m.nat_abs n = 1) :
222+
variable {p}
223+
224+
lemma add_order_of_div_of_gcd_eq_one {m n : ℕ} (hn : 0 < n) (h : m.gcd n = 1) :
225+
add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
226+
by { convert gcd_mul_add_order_of_div_eq p m hn, rw [h, one_mul] }
227+
228+
lemma add_order_of_div_of_gcd_eq_one' {m : ℤ} {n : ℕ} (hn : 0 < n) (h : m.nat_abs.gcd n = 1) :
223229
add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
224230
begin
225231
induction m,
@@ -237,97 +243,59 @@ begin
237243
apply_instance,
238244
end
239245

240-
variables (p)
241-
242-
lemma gcd_mul_add_order_of_div_eq {n : ℕ} (m : ℕ) (hn : 0 < n) :
243-
gcd m n * add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
246+
lemma add_order_of_eq_pos_iff {u : add_circle p} {n : ℕ} (h : 0 < n) :
247+
add_order_of u = n ↔ ∃ m < n, m.gcd n = 1 ∧ ↑(↑m / ↑n * p) = u :=
244248
begin
245-
let n' := n / gcd m n,
246-
let m' := m / gcd m n,
247-
have h₀ : 0 < gcd m n,
248-
{ rw zero_lt_iff at hn ⊢, contrapose! hn, exact ((gcd_eq_zero_iff m n).mp hn).2, },
249-
have hk' : 0 < n' := nat.div_pos (nat.le_of_dvd hn $ gcd_dvd_right m n) h₀,
250-
have hgcd : gcd m' n' = 1 := nat.coprime_div_gcd_div_gcd h₀,
251-
simp only [mul_left_inj' hp.out.ne.symm,
252-
← nat.cast_div_div_div_cancel_right (gcd_dvd_right m n) (gcd_dvd_left m n),
253-
add_order_of_div_of_gcd_eq_one hk' hgcd, mul_comm _ n', nat.div_mul_cancel (gcd_dvd_right m n)],
249+
refine ⟨quotient_add_group.induction_on' u (λ k hk, _), _⟩, swap,
250+
{ rintros ⟨m, h₀, h₁, rfl⟩, exact add_order_of_div_of_gcd_eq_one h h₁ },
251+
have h0 := add_order_of_nsmul_eq_zero (k : add_circle p),
252+
rw [hk, ← coe_nsmul, coe_eq_zero_iff] at h0,
253+
obtain ⟨a, ha⟩ := h0,
254+
have h0 : (_ : 𝕜) ≠ 0 := nat.cast_ne_zero.2 h.ne',
255+
rw [nsmul_eq_mul, mul_comm, ← div_eq_iff h0, ← a.div_add_mod' n, add_smul, add_div, zsmul_eq_mul,
256+
int.cast_mul, int.cast_coe_nat, mul_assoc, ← mul_div, mul_comm _ p, mul_div_cancel p h0] at ha,
257+
have han : _ = a % n := int.to_nat_of_nonneg (int.mod_nonneg _ $ by exact_mod_cast h.ne'),
258+
have he := _, refine ⟨(a % n).to_nat, _, _, he⟩,
259+
{ rw [← int.coe_nat_lt, han],
260+
exact int.mod_lt_of_pos _ (int.coe_nat_lt.2 h) },
261+
{ have := (gcd_mul_add_order_of_div_eq p _ h).trans ((congr_arg add_order_of he).trans hk).symm,
262+
rw [he, nat.mul_left_eq_self_iff] at this, { exact this }, { rwa hk } },
263+
convert congr_arg coe ha using 1,
264+
rw [coe_add, ← int.cast_coe_nat, han, zsmul_eq_mul, mul_div_right_comm,
265+
eq_comm, add_left_eq_self, ← zsmul_eq_mul, coe_zsmul, coe_period, smul_zero],
254266
end
255267

256-
variables {p} [floor_ring 𝕜]
257-
258268
lemma exists_gcd_eq_one_of_is_of_fin_add_order {u : add_circle p} (h : is_of_fin_add_order u) :
259-
∃ m, gcd m (add_order_of u) = 1
260-
m < (add_order_of u) ∧
261-
↑(((m : 𝕜) / add_order_of u) * p) = u :=
262-
begin
263-
rcases eq_or_ne u 0 with rfl | hu, { exact ⟨0, by simp⟩, },
264-
set n := add_order_of u,
265-
change ∃ m, gcd m n = 1 ∧ m < n ∧ ↑((↑m / ↑n) * p) = u,
266-
have hn : 0 < n := add_order_of_pos' h,
267-
have hn₀ : (n : 𝕜) ≠ 0, { norm_cast, exact ne_of_gt hn, },
268-
let x := (equiv_Ico p 0 u : 𝕜),
269-
have hxu : (x : add_circle p) = u := (equiv_Ico p 0).symm_apply_apply u,
270-
have hx₀ : 0 < (add_order_of (x : add_circle p)), { rw ← hxu at h, exact add_order_of_pos' h, },
271-
have hx₁ : 0 < x,
272-
{ refine lt_of_le_of_ne (equiv_Ico p 0 u).2.1 _,
273-
contrapose! hu,
274-
rw [← hxu, ← hu, quotient_add_group.coe_zero], },
275-
obtain ⟨m, hm : m • p = add_order_of ↑x • x⟩ := (coe_eq_zero_of_pos_iff p hp.out
276-
(by positivity)).mp (add_order_of_nsmul_eq_zero (x : add_circle p)),
277-
replace hm : ↑m * p = ↑n * x, { simpa only [hxu, nsmul_eq_mul] using hm, },
278-
have hux : ↑(↑m / ↑n * p) = u,
279-
{ rw [← hxu, ← mul_div_right_comm, hm, mul_comm _ x, mul_div_cancel x hn₀], },
280-
refine ⟨m, (_ : gcd m n = 1), (_ : m < n), hux⟩,
281-
{ have := gcd_mul_add_order_of_div_eq p m hn,
282-
rwa [hux, nat.mul_left_eq_self_iff hn] at this, },
283-
{ have : n • x < n • p := smul_lt_smul_of_pos _ hn,
284-
rwa [nsmul_eq_mul, nsmul_eq_mul, ← hm, mul_lt_mul_right hp.out, nat.cast_lt] at this,
285-
simpa [zero_add] using (equiv_Ico p 0 u).2.2, },
286-
end
287-
288-
lemma add_order_of_eq_pos_iff {u : add_circle p} {n : ℕ} (h : 0 < n) :
289-
add_order_of u = n ↔ ∃ m < n, gcd m n = 1 ∧ ↑(↑m / ↑n * p) = u :=
290-
begin
291-
refine ⟨λ hu, _, _⟩,
292-
{ rw ← hu at h,
293-
obtain ⟨m, h₀, h₁, h₂⟩ := exists_gcd_eq_one_of_is_of_fin_add_order (add_order_of_pos_iff.mp h),
294-
refine ⟨m, _, _, _⟩;
295-
rwa ← hu, },
296-
{ rintros ⟨m, h₀, h₁, rfl⟩,
297-
exact add_order_of_div_of_gcd_eq_one h h₁, },
298-
end
269+
∃ m : ℕ, m.gcd (add_order_of u) = 1
270+
m < (add_order_of u) ∧
271+
↑(((m : 𝕜) / add_order_of u) * p) = u :=
272+
let ⟨m, hl, hg, he⟩ := (add_order_of_eq_pos_iff $ add_order_of_pos' h).1 rfl in ⟨m, hg, hl, he⟩
299273

300274
variables (p)
301275

302276
/-- The natural bijection between points of order `n` and natural numbers less than and coprime to
303277
`n`. The inverse of the map sends `m ↦ (m/n * p : add_circle p)` where `m` is coprime to `n` and
304278
satisfies `0 ≤ m < n`. -/
305279
def set_add_order_of_equiv {n : ℕ} (hn : 0 < n) :
306-
{u : add_circle p | add_order_of u = n} ≃ {m | m < n ∧ gcd m n = 1} :=
307-
{ to_fun := λ u, by
308-
{ let h := (add_order_of_eq_pos_iff hn).mp u.property,
309-
exact ⟨classical.some h, classical.some (classical.some_spec h),
310-
(classical.some_spec (classical.some_spec h)).1⟩, },
311-
inv_fun := λ m, ⟨↑((m : 𝕜) / n * p), add_order_of_div_of_gcd_eq_one hn (m.property.2)⟩,
312-
left_inv := λ u, subtype.ext
313-
(classical.some_spec (classical.some_spec $ (add_order_of_eq_pos_iff hn).mp u.2)).2,
314-
right_inv :=
315-
begin
316-
rintros ⟨m, hm₁, hm₂⟩,
317-
let u : {u : add_circle p | add_order_of u = n} :=
318-
⟨↑((m : 𝕜) / n * p), add_order_of_div_of_gcd_eq_one hn hm₂⟩,
319-
let h := (add_order_of_eq_pos_iff hn).mp u.property,
320-
ext,
321-
let m' := classical.some h,
322-
change m' = m,
323-
obtain ⟨h₁ : m' < n, h₂ : gcd m' n = 1, h₃ : quotient_add_group.mk ((m' : 𝕜) / n * p) =
324-
quotient_add_group.mk ((m : 𝕜) / n * p)⟩ := classical.some_spec h,
325-
replace h₃ := congr_arg (coe : Ico 0 (0 + p) → 𝕜) (congr_arg (equiv_Ico p 0) h₃),
326-
simpa only [coe_equiv_Ico_mk_apply, mul_left_inj' hp.out.ne', mul_div_cancel _ hp.out.ne',
327-
int.fract_div_nat_cast_eq_div_nat_cast_mod,
328-
div_left_inj' (nat.cast_ne_zero.mpr hn.ne' : (n : 𝕜) ≠ 0), nat.cast_inj,
329-
(nat.mod_eq_iff_lt hn.ne').mpr hm₁, (nat.mod_eq_iff_lt hn.ne').mpr h₁] using h₃,
330-
end }
280+
{u : add_circle p | add_order_of u = n} ≃ {m | m < n ∧ m.gcd n = 1} :=
281+
equiv.symm $ equiv.of_bijective
282+
(λ m, ⟨↑((m : 𝕜) / n * p), add_order_of_div_of_gcd_eq_one hn (m.prop.2)⟩)
283+
begin
284+
refine ⟨λ m₁ m₂ h, subtype.ext _, λ u, _⟩,
285+
{ simp_rw [subtype.ext_iff, subtype.coe_mk] at h,
286+
rw [← sub_eq_zero, ← coe_sub, ← sub_mul, ← sub_div, coe_coe, coe_coe, ← int.cast_coe_nat m₁,
287+
← int.cast_coe_nat m₂, ← int.cast_sub, coe_eq_zero_iff] at h,
288+
obtain ⟨m, hm⟩ := h,
289+
rw [← mul_div_right_comm, eq_div_iff, mul_comm, ← zsmul_eq_mul, mul_smul_comm, ← nsmul_eq_mul,
290+
← coe_nat_zsmul, smul_smul, (zsmul_strict_mono_left hp.out).injective.eq_iff, mul_comm] at hm,
291+
swap, { exact nat.cast_ne_zero.2 hn.ne' },
292+
rw [← @nat.cast_inj ℤ, ← sub_eq_zero],
293+
refine int.eq_zero_of_abs_lt_dvd ⟨_, hm.symm⟩ (abs_sub_lt_iff.2 ⟨_, _⟩);
294+
apply (int.sub_le_self _ $ nat.cast_nonneg _).trans_lt (nat.cast_lt.2 _),
295+
exacts [m₁.2.1, m₂.2.1] },
296+
obtain ⟨m, hmn, hg, he⟩ := (add_order_of_eq_pos_iff hn).mp u.2,
297+
exact ⟨⟨m, hmn, hg⟩, subtype.ext he⟩,
298+
end
331299

332300
@[simp] lemma card_add_order_of_eq_totient {n : ℕ} :
333301
nat.card {u : add_circle p // add_order_of u = n} = n.totient :=
@@ -343,7 +311,7 @@ begin
343311
exact nat.card_of_is_empty, }, },
344312
{ rw [← coe_set_of, nat.card_congr (set_add_order_of_equiv p hn),
345313
n.totient_eq_card_lt_and_coprime],
346-
simpa only [@nat.coprime_comm _ n], },
314+
simp only [nat.gcd_comm], },
347315
end
348316

349317
lemma finite_set_of_add_order_eq {n : ℕ} (hn : 0 < n) :

0 commit comments

Comments
 (0)