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

Commit e18ea79

Browse files
feat(number_theory/legendre_symbol/quadratic_reciprocity): replace [fact (p % 2 = 1)] arguments by (p ≠ 2) (#13474)
This removes implicit arguments of the form `[fact (p % 2 = 1)]` and replaces them by explicit arguments `(hp : p ≠ 2)`. (See the short discussion on April 9 in [this topic](https://leanprover.zulipchat.com/#narrow/stream/116395-maths/topic/Quadratic.20Hilbert.20symbol.20over.20.E2.84.9A).)
1 parent 82348a6 commit e18ea79

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

src/data/nat/prime.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,14 @@ p.mod_two_eq_zero_or_one.imp_left
429429
lemma prime.eq_two_or_odd' {p : ℕ} (hp : prime p) : p = 2 ∨ odd p :=
430430
or.imp_right (λ h, ⟨p / 2, (div_add_mod p 2).symm.trans (congr_arg _ h)⟩) hp.eq_two_or_odd
431431

432+
/-- A prime `p` satisfies `p % 2 = 1` if and only if `p ≠ 2`. -/
433+
lemma prime.mod_two_eq_one_iff_ne_two {p : ℕ} [fact p.prime] : p % 2 = 1 ↔ p ≠ 2 :=
434+
begin
435+
refine ⟨λ h hf, _, (nat.prime.eq_two_or_odd $ fact.out p.prime).resolve_left⟩,
436+
rw hf at h,
437+
simpa using h,
438+
end
439+
432440
theorem coprime_of_dvd {m n : ℕ} (H : ∀ k, prime k → k ∣ m → ¬ k ∣ n) : coprime m n :=
433441
begin
434442
rw [coprime_iff_gcd_eq_one],

src/number_theory/legendre_symbol/quadratic_reciprocity.lean

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,14 @@ end
156156

157157
/-- Gauss' lemma. The legendre symbol can be computed by considering the number of naturals less
158158
than `p/2` such that `(a * x) % p > p / 2` -/
159-
lemma gauss_lemma {a : ℤ} [fact (p % 2 = 1)] (ha0 : (a : zmod p) ≠ 0) :
159+
lemma gauss_lemma {a : ℤ} (hp : p ≠ 2) (ha0 : (a : zmod p) ≠ 0) :
160160
legendre_sym p a = (-1) ^ ((Ico 1 (p / 2).succ).filter
161161
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card :=
162-
have (legendre_sym p a : zmod p) = (((-1)^((Ico 1 (p / 2).succ).filter
163-
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card : ℤ) : zmod p),
164-
by rw [legendre_sym_eq_pow, legendre_symbol.gauss_lemma_aux p ha0]; simp,
165162
begin
163+
haveI hp' : fact (p % 2 = 1) := ⟨nat.prime.mod_two_eq_one_iff_ne_two.mpr hp⟩,
164+
have : (legendre_sym p a : zmod p) = (((-1)^((Ico 1 (p / 2).succ).filter
165+
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card : ℤ) : zmod p) :=
166+
by { rw [legendre_sym_eq_pow, legendre_symbol.gauss_lemma_aux p ha0]; simp },
166167
cases legendre_sym_eq_one_or_neg_one p a ha0;
167168
cases neg_one_pow_eq_or ℤ ((Ico 1 (p / 2).succ).filter
168169
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card;
@@ -178,34 +179,36 @@ begin
178179
{ simp only [h, iff_false], tauto }
179180
end
180181

181-
lemma eisenstein_lemma [fact (p % 2 = 1)] {a : ℕ} (ha1 : a % 2 = 1) (ha0 : (a : zmod p) ≠ 0) :
182+
lemma eisenstein_lemma (hp : p ≠ 2) {a : ℕ} (ha1 : a % 2 = 1) (ha0 : (a : zmod p) ≠ 0) :
182183
legendre_sym p a = (-1)^∑ x in Ico 1 (p / 2).succ, (x * a) / p :=
183184
begin
185+
haveI hp' : fact (p % 2 = 1) := ⟨nat.prime.mod_two_eq_one_iff_ne_two.mpr hp⟩,
184186
have ha0' : ((a : ℤ) : zmod p) ≠ 0 := by { norm_cast, exact ha0 },
185-
rw [neg_one_pow_eq_pow_mod_two, gauss_lemma p ha0', neg_one_pow_eq_pow_mod_two,
187+
rw [neg_one_pow_eq_pow_mod_two, gauss_lemma p hp ha0', neg_one_pow_eq_pow_mod_two,
186188
(by norm_cast : ((a : ℤ) : zmod p) = (a : zmod p)),
187189
show _ = _, from legendre_symbol.eisenstein_lemma_aux p ha1 ha0]
188190
end
189191

190192
/-- **Quadratic reciprocity theorem** -/
191-
theorem quadratic_reciprocity [hp1 : fact (p % 2 = 1)] [hq1 : fact (q % 2 = 1)] (hpq : p ≠ q) :
193+
theorem quadratic_reciprocity (hp1 : p ≠ 2) (hq1 : q ≠ 2) (hpq : p ≠ q) :
192194
legendre_sym q p * legendre_sym p q = (-1) ^ ((p / 2) * (q / 2)) :=
193195
have hpq0 : (p : zmod q) ≠ 0, from prime_ne_zero q p hpq.symm,
194196
have hqp0 : (q : zmod p) ≠ 0, from prime_ne_zero p q hpq,
195-
by rw [eisenstein_lemma q hp1.1 hpq0, eisenstein_lemma p hq1.1 hqp0,
197+
by rw [eisenstein_lemma q hq1 (nat.prime.mod_two_eq_one_iff_ne_two.mpr hp1) hpq0,
198+
eisenstein_lemma p hp1 (nat.prime.mod_two_eq_one_iff_ne_two.mpr hq1) hqp0,
196199
← pow_add, legendre_symbol.sum_mul_div_add_sum_mul_div_eq_mul q p hpq0, mul_comm]
197200

198-
lemma legendre_sym_two [hp1 : fact (p % 2 = 1)] : legendre_sym p 2 = (-1) ^ (p / 4 + p / 2) :=
201+
lemma legendre_sym_two (hp2 : p ≠ 2) : legendre_sym p 2 = (-1) ^ (p / 4 + p / 2) :=
199202
begin
200-
have hp2 : p ≠ 2, from mt (congr_arg (% 2)) (by simpa using hp1.1),
203+
have hp1 := nat.prime.mod_two_eq_one_iff_ne_two.mpr hp2,
201204
have hp22 : p / 2 / 2 = _ := legendre_symbol.div_eq_filter_card (show 0 < 2, from dec_trivial)
202205
(nat.div_le_self (p / 2) 2),
203206
have hcard : (Ico 1 (p / 2).succ).card = p / 2, by simp,
204207
have hx2 : ∀ x ∈ Ico 1 (p / 2).succ, (2 * x : zmod p).val = 2 * x,
205208
from λ x hx, have h2xp : 2 * x < p,
206209
from calc 2 * x ≤ 2 * (p / 2) : mul_le_mul_of_nonneg_left
207210
(le_of_lt_succ $ (mem_Ico.mp hx).2) dec_trivial
208-
... < _ : by conv_rhs {rw [← div_add_mod p 2, hp1.1]}; exact lt_succ_self _,
211+
... < _ : by conv_rhs {rw [← div_add_mod p 2, hp1]}; exact lt_succ_self _,
209212
by rw [← nat.cast_two, ← nat.cast_mul, val_cast_of_lt h2xp],
210213
have hdisj : disjoint
211214
((Ico 1 (p / 2).succ).filter (λ x, p / 2 < ((2 : ℕ) * x : zmod p).val))
@@ -222,44 +225,44 @@ begin
222225
end,
223226
have hp2' := prime_ne_zero p 2 hp2,
224227
rw (by norm_cast : ((2 : ℕ) : zmod p) = (2 : ℤ)) at *,
225-
erw [gauss_lemma p hp2',
228+
erw [gauss_lemma p hp2 hp2',
226229
neg_one_pow_eq_pow_mod_two, @neg_one_pow_eq_pow_mod_two _ _ (p / 4 + p / 2)],
227230
refine congr_arg2 _ rfl ((eq_iff_modeq_nat 2).1 _),
228231
rw [show 4 = 2 * 2, from rfl, ← nat.div_div_eq_div_mul, hp22, nat.cast_add,
229232
← sub_eq_iff_eq_add', sub_eq_add_neg, neg_eq_self_mod_two,
230233
← nat.cast_add, ← card_disjoint_union hdisj, hunion, hcard]
231234
end
232235

233-
lemma exists_sq_eq_two_iff [hp1 : fact (p % 2 = 1)] :
236+
lemma exists_sq_eq_two_iff (hp1 : p ≠ 2) :
234237
(∃ a : zmod p, a ^ 2 = 2) ↔ p % 8 = 1 ∨ p % 8 = 7 :=
235238
have hp2 : ((2 : ℤ) : zmod p) ≠ 0,
236-
from prime_ne_zero p 2 (λ h, by simpa [h] using hp1.1),
239+
from prime_ne_zero p 2 (λ h, by simpa [h] using hp1),
237240
have hpm4 : p % 4 = p % 8 % 4, from (nat.mod_mul_left_mod p 2 4).symm,
238241
have hpm2 : p % 2 = p % 8 % 2, from (nat.mod_mul_left_mod p 4 2).symm,
239242
begin
240243
rw [show (2 : zmod p) = (2 : ℤ), by simp, ← legendre_sym_eq_one_iff p hp2],
241-
erw [legendre_sym_two p, neg_one_pow_eq_one_iff_even (show (-1 : ℤ) ≠ 1, from dec_trivial),
244+
erw [legendre_sym_two p hp1, neg_one_pow_eq_one_iff_even (show (-1 : ℤ) ≠ 1, from dec_trivial),
242245
even_add, even_div, even_div],
243246
have := nat.mod_lt p (show 0 < 8, from dec_trivial),
244-
resetI, rw fact_iff at hp1,
245-
revert this hp1,
247+
have hp := nat.prime.mod_two_eq_one_iff_ne_two.mpr hp1,
248+
revert this hp,
246249
erw [hpm4, hpm2],
247250
generalize hm : p % 8 = m, unfreezingI {clear_dependent p},
248251
dec_trivial!,
249252
end
250253

251-
lemma exists_sq_eq_prime_iff_of_mod_four_eq_one (hp1 : p % 4 = 1) [hq1 : fact (q % 2 = 1)] :
254+
lemma exists_sq_eq_prime_iff_of_mod_four_eq_one (hp1 : p % 4 = 1) (hq1 : q ≠ 2) :
252255
(∃ a : zmod p, a ^ 2 = q) ↔ ∃ b : zmod q, b ^ 2 = p :=
253256
if hpq : p = q then by substI hpq else
254257
have h1 : ((p / 2) * (q / 2)) % 2 = 0,
255258
from (dvd_iff_mod_eq_zero _ _).1
256259
(dvd_mul_of_dvd_left ((dvd_iff_mod_eq_zero _ _).2 $
257260
by rw [← mod_mul_right_div_self, show 2 * 2 = 4, from rfl, hp1]; refl) _),
258261
begin
259-
haveI hp_odd : fact (p % 2 = 1) := ⟨odd_of_mod_four_eq_one hp1,
262+
have hp_odd : p ≠ 2 := by { by_contra, simp [h] at hp1, norm_num at hp1, },
260263
have hpq0 : (p : zmod q) ≠ 0 := prime_ne_zero q p (ne.symm hpq),
261264
have hqp0 : (q : zmod p) ≠ 0 := prime_ne_zero p q hpq,
262-
have := quadratic_reciprocity p q hpq,
265+
have := quadratic_reciprocity p q hp_odd hq1 hpq,
263266
rw [neg_one_pow_eq_pow_mod_two, h1, legendre_sym, legendre_sym, int.cast_coe_nat,
264267
int.cast_coe_nat, if_neg hqp0, if_neg hpq0] at this,
265268
rw [euler_criterion q hpq0, euler_criterion p hqp0],
@@ -273,11 +276,11 @@ have h1 : ((p / 2) * (q / 2)) % 2 = 1,
273276
(by rw [← mod_mul_right_div_self, show 2 * 2 = 4, from rfl, hp3]; refl)
274277
(by rw [← mod_mul_right_div_self, show 2 * 2 = 4, from rfl, hq3]; refl),
275278
begin
276-
haveI hp_odd : fact (p % 2 = 1) := ⟨odd_of_mod_four_eq_three hp3,
277-
haveI hq_odd : fact (q % 2 = 1) := ⟨odd_of_mod_four_eq_three hq3,
279+
have hp_odd : p ≠ 2 := by { by_contra, simp [h] at hp3, norm_num at hp3, },
280+
have hq_odd : q ≠ 2 := by { by_contra, simp [h] at hq3, norm_num at hq3, },
278281
have hpq0 : (p : zmod q) ≠ 0 := prime_ne_zero q p (ne.symm hpq),
279282
have hqp0 : (q : zmod p) ≠ 0 := prime_ne_zero p q hpq,
280-
have := quadratic_reciprocity p q hpq,
283+
have := quadratic_reciprocity p q hp_odd hq_odd hpq,
281284
rw [neg_one_pow_eq_pow_mod_two, h1, legendre_sym, legendre_sym, int.cast_coe_nat,
282285
int.cast_coe_nat, if_neg hpq0, if_neg hqp0] at this,
283286
rw [euler_criterion q hpq0, euler_criterion p hqp0],

0 commit comments

Comments
 (0)