@@ -4,6 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Oliver Nash
55-/
66import group_theory.divisible
7+ import group_theory.order_of_element
8+ import ring_theory.int.basic
79import algebra.order.floor
810import algebra.order.to_interval_mod
911import topology.instances.real
@@ -22,6 +24,8 @@ See also `circle` and `real.angle`. For the normed group structure on `add_circ
2224 * `unit_add_circle`: the special case `ℝ ⧸ ℤ`
2325 * `add_circle.equiv_add_circle`: the rescaling equivalence `add_circle p ≃+ add_circle q`
2426 * `add_circle.equiv_Ico`: the natural equivalence `add_circle p ≃ Ico 0 p`
27+ * `add_circle.add_order_of_div_of_gcd_eq_one`: rational points have finite order
28+ * `add_circle.exists_gcd_eq_one_of_is_of_fin_add_order`: finite-order points are rational
2529
2630 ## Implementation notes:
2731
@@ -38,7 +42,7 @@ the rational circle `add_circle (1 : ℚ)`, and so we set things up more general
3842
3943noncomputable theory
4044
41- open set int (hiding mem_zmultiples_iff) add_subgroup topological_space
45+ open set add_subgroup topological_space
4246
4347variables {𝕜 : Type *}
4448
@@ -54,6 +58,26 @@ section linear_ordered_field
5458
5559variables [linear_ordered_field 𝕜] [topological_space 𝕜] [order_topology 𝕜] (p q : 𝕜)
5660
61+ instance : coe_is_add_monoid_hom 𝕜 (add_circle p) :=
62+ { coe_zero := rfl,
63+ coe_add := λ x y, rfl }
64+
65+ lemma coe_eq_zero_iff {x : 𝕜} : (x : add_circle p) = 0 ↔ ∃ (n : ℤ), n • p = x :=
66+ by simp [add_subgroup.mem_zmultiples_iff]
67+
68+ lemma coe_eq_zero_of_pos_iff (hp : 0 < p) {x : 𝕜} (hx : 0 < x) :
69+ (x : add_circle p) = 0 ↔ ∃ (n : ℕ), n • p = x :=
70+ begin
71+ rw coe_eq_zero_iff,
72+ split;
73+ rintros ⟨n, rfl⟩,
74+ { replace hx : 0 < n,
75+ { contrapose! hx,
76+ simpa only [←neg_nonneg, ←zsmul_neg, zsmul_neg'] using zsmul_nonneg hp.le (neg_nonneg.2 hx) },
77+ exact ⟨n.to_nat, by rw [← coe_nat_zsmul, int.to_nat_of_nonneg hx.le]⟩, },
78+ { exact ⟨(n : ℤ), by simp⟩, },
79+ end
80+
5781@[continuity, nolint unused_arguments] protected lemma continuous_mk' :
5882 continuous (quotient_add_group.mk' (zmultiples p) : 𝕜 → add_circle p) :=
5983continuous_coinduced_rng
80104 (equiv_add_circle p q hp hq).symm (x : 𝕜) = (x * (q⁻¹ * p) : 𝕜) :=
81105rfl
82106
83- variables [floor_ring 𝕜] [ hp : fact (0 < p)]
107+ variables [hp : fact (0 < p)]
84108include hp
85109
110+ section floor_ring
111+
112+ variables [floor_ring 𝕜]
113+
86114/-- The natural equivalence between `add_circle p` and the half-open interval `[0, p)`. -/
87115def equiv_Ico : add_circle p ≃ Ico 0 p :=
88116{ inv_fun := quotient_add_group.mk' _ ∘ coe,
@@ -98,7 +126,7 @@ def equiv_Ico : add_circle p ≃ Ico 0 p :=
98126 end }
99127
100128@[simp] lemma coe_equiv_Ico_mk_apply (x : 𝕜) :
101- (equiv_Ico p $ quotient_add_group.mk x : 𝕜) = fract (x / p) * p :=
129+ (equiv_Ico p $ quotient_add_group.mk x : 𝕜) = int. fract (x / p) * p :=
102130to_Ico_mod_eq_fract_mul _ x
103131
104132@[continuity] lemma continuous_equiv_Ico_symm : continuous (equiv_Ico p).symm :=
@@ -126,6 +154,103 @@ instance : divisible_by (add_circle p) ℤ :=
126154 exact (equiv_Ico p).symm_apply_apply x,
127155 end , }
128156
157+ end floor_ring
158+
159+ section finite_order_points
160+
161+ variables {p}
162+
163+ lemma add_order_of_div_of_gcd_eq_one {m n : ℕ} (hn : 0 < n) (h : gcd m n = 1 ) :
164+ add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
165+ begin
166+ rcases m.eq_zero_or_pos with rfl | hm, { rw [gcd_zero_left, normalize_eq] at h, simp [h], },
167+ set x : add_circle p := ↑(↑m / ↑n * p),
168+ have hn₀ : (n : 𝕜) ≠ 0 , { norm_cast, exact ne_of_gt hn, },
169+ have hnx : n • x = 0 ,
170+ { rw [← _root_.coe_nsmul, nsmul_eq_mul, ← mul_assoc, mul_div, mul_div_cancel_left _ hn₀,
171+ ← nsmul_eq_mul, quotient_add_group.eq_zero_iff],
172+ exact nsmul_mem_zmultiples p m, },
173+ apply nat.dvd_antisymm (add_order_of_dvd_of_nsmul_eq_zero hnx),
174+ suffices : ∃ (z : ℕ), z * n = (add_order_of x) * m,
175+ { obtain ⟨z, hz⟩ := this ,
176+ simpa only [h, mul_one, gcd_comm n] using dvd_mul_gcd_of_dvd_mul (dvd.intro_left z hz), },
177+ replace hp := hp.out,
178+ have : 0 < add_order_of x • (↑m / ↑n * p) := smul_pos
179+ (add_order_of_pos' $ (is_of_fin_add_order_iff_nsmul_eq_zero _).2 ⟨n, hn, hnx⟩) (by positivity),
180+ obtain ⟨z, hz⟩ := (coe_eq_zero_of_pos_iff p hp this ).mp (add_order_of_nsmul_eq_zero x),
181+ rw [← smul_mul_assoc, nsmul_eq_mul, nsmul_eq_mul, mul_left_inj' hp.ne.symm, mul_div,
182+ eq_div_iff hn₀] at hz,
183+ norm_cast at hz,
184+ exact ⟨z, hz⟩,
185+ end
186+
187+ lemma add_order_of_div_of_gcd_eq_one' {m : ℤ} {n : ℕ} (hn : 0 < n) (h : gcd m.nat_abs n = 1 ) :
188+ add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
189+ begin
190+ induction m,
191+ { simp only [int.of_nat_eq_coe, int.cast_coe_nat, int.nat_abs_of_nat] at h ⊢,
192+ exact add_order_of_div_of_gcd_eq_one hn h, },
193+ { simp only [int.cast_neg_succ_of_nat, neg_div, neg_mul, _root_.coe_neg, order_of_neg],
194+ exact add_order_of_div_of_gcd_eq_one hn h, },
195+ end
196+
197+ lemma add_order_of_coe_rat {q : ℚ} : add_order_of (↑(↑q * p) : add_circle p) = q.denom :=
198+ begin
199+ have : (↑(q.denom : ℤ) : 𝕜) ≠ 0 , { norm_cast, exact q.pos.ne.symm, },
200+ rw [← @rat.num_denom q, rat.cast_mk_of_ne_zero _ _ this , int.cast_coe_nat, rat.num_denom,
201+ add_order_of_div_of_gcd_eq_one' q.pos q.cop],
202+ apply_instance,
203+ end
204+
205+ variables (p)
206+
207+ lemma gcd_mul_add_order_of_div_eq {n : ℕ} (m : ℕ) (hn : 0 < n) :
208+ gcd m n * add_order_of (↑(↑m / ↑n * p) : add_circle p) = n :=
209+ begin
210+ let n' := n / gcd m n,
211+ let m' := m / gcd m n,
212+ have h₀ : 0 < gcd m n,
213+ { rw zero_lt_iff at hn ⊢, contrapose! hn, exact ((gcd_eq_zero_iff m n).mp hn).2 , },
214+ have hk' : 0 < n' := nat.div_pos (nat.le_of_dvd hn $ gcd_dvd_right m n) h₀,
215+ have hgcd : gcd m' n' = 1 := nat.coprime_div_gcd_div_gcd h₀,
216+ simp only [mul_left_inj' hp.out.ne.symm,
217+ ← nat.cast_div_div_div_cancel_right (gcd_dvd_right m n) (gcd_dvd_left m n),
218+ add_order_of_div_of_gcd_eq_one hk' hgcd, mul_comm _ n', nat.div_mul_cancel (gcd_dvd_right m n)],
219+ end
220+
221+ variables {p} [floor_ring 𝕜]
222+
223+ lemma exists_gcd_eq_one_of_is_of_fin_add_order {u : add_circle p} (h : is_of_fin_add_order u) :
224+ ∃ m, gcd m (add_order_of u) = 1 ∧
225+ m < (add_order_of u) ∧
226+ ↑(((m : 𝕜) / add_order_of u) * p) = u :=
227+ begin
228+ rcases eq_or_ne u 0 with rfl | hu, { exact ⟨0 , by simp⟩, },
229+ set n := add_order_of u,
230+ change ∃ m, gcd m n = 1 ∧ m < n ∧ ↑((↑m / ↑n) * p) = u,
231+ have hn : 0 < n := add_order_of_pos' h,
232+ have hn₀ : (n : 𝕜) ≠ 0 , { norm_cast, exact ne_of_gt hn, },
233+ let x := (equiv_Ico p u : 𝕜),
234+ have hxu : (x : add_circle p) = u := (equiv_Ico p).symm_apply_apply u,
235+ have hx₀ : 0 < (add_order_of (x : add_circle p)), { rw ← hxu at h, exact add_order_of_pos' h, },
236+ have hx₁ : 0 < x,
237+ { refine lt_of_le_of_ne (equiv_Ico p u).2 .1 _,
238+ contrapose! hu,
239+ rw [← hxu, ← hu, quotient_add_group.coe_zero], },
240+ obtain ⟨m, hm : m • p = add_order_of ↑x • x⟩ := (coe_eq_zero_of_pos_iff p hp.out
241+ (by positivity)).mp (add_order_of_nsmul_eq_zero (x : add_circle p)),
242+ replace hm : ↑m * p = ↑n * x, { simpa only [hxu, nsmul_eq_mul] using hm, },
243+ have hux : ↑(↑m / ↑n * p) = u,
244+ { rw [← hxu, ← mul_div_right_comm, hm, mul_comm _ x, mul_div_cancel x hn₀], },
245+ refine ⟨m, (_ : gcd m n = 1 ), (_ : m < n), hux⟩,
246+ { have := gcd_mul_add_order_of_div_eq p m hn,
247+ rwa [hux, nat.mul_left_eq_self_iff hn] at this , },
248+ { have : n • x < n • p := smul_lt_smul_of_pos (equiv_Ico p u).2 .2 hn,
249+ rwa [nsmul_eq_mul, nsmul_eq_mul, ← hm, mul_lt_mul_right hp.out, nat.cast_lt] at this , },
250+ end
251+
252+ end finite_order_points
253+
129254end linear_ordered_field
130255
131256variables (p : ℝ)
0 commit comments