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

Commit bf71feb

Browse files
committed
feat(number_theory/quadratic_reciprocity): generalise legendre_sym to allow integer first argument (#11573)
Talking about the legendre symbol of -1 mod p is quite natural, so we generalize to include this case. So far in a minimal way without changing any existing lemmas
1 parent f7a597a commit bf71feb

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

src/number_theory/quadratic_reciprocity.lean

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ namespace zmod
356356
* `-1` otherwise.
357357
358358
-/
359-
def legendre_sym (a p : ℕ) : ℤ :=
359+
def legendre_sym (a : ℤ) (p : ℕ) : ℤ :=
360360
if (a : zmod p) = 0 then 0
361361
else if (a : zmod p) ^ (p / 2) = 1 then 1
362362
else -1
@@ -366,12 +366,13 @@ lemma legendre_sym_eq_pow (a p : ℕ) [hp : fact p.prime] :
366366
begin
367367
rw legendre_sym,
368368
by_cases ha : (a : zmod p) = 0,
369-
{ simp only [if_pos, ha, zero_pow (nat.div_pos (hp.1.two_le) (succ_pos 1)), int.cast_zero] },
369+
{ simp only [int.cast_coe_nat, if_pos, ha,
370+
zero_pow (nat.div_pos (hp.1.two_le) (succ_pos 1)), int.cast_zero] },
370371
cases hp.1.eq_two_or_odd with hp2 hp_odd,
371372
{ substI p,
372373
generalize : (a : (zmod 2)) = b, revert b, dec_trivial, },
373374
{ haveI := fact.mk hp_odd,
374-
rw if_neg ha,
375+
rw [int.cast_coe_nat, if_neg ha],
375376
have : (-1 : zmod p) ≠ 1, from (ne_neg_self p one_ne_zero).symm,
376377
cases pow_div_two_eq_neg_one_or_one p ha with h h,
377378
{ rw [if_pos h, h, int.cast_one], },
@@ -380,7 +381,11 @@ end
380381

381382
lemma legendre_sym_eq_one_or_neg_one (a p : ℕ) (ha : (a : zmod p) ≠ 0) :
382383
legendre_sym a p = -1 ∨ legendre_sym a p = 1 :=
383-
by unfold legendre_sym; split_ifs; simp only [*, eq_self_iff_true, or_true, true_or] at *
384+
begin
385+
unfold legendre_sym,
386+
split_ifs;
387+
simp only [*, eq_self_iff_true, or_true, true_or, int.cast_coe_nat] at *,
388+
end
384389

385390
lemma legendre_sym_eq_zero_iff (a p : ℕ) :
386391
legendre_sym a p = 0 ↔ (a : zmod p) = 0 :=
@@ -389,7 +394,7 @@ begin
389394
{ classical, contrapose,
390395
assume ha, cases legendre_sym_eq_one_or_neg_one a p ha with h h,
391396
all_goals { rw h, norm_num } },
392-
{ assume ha, rw [legendre_sym, if_pos ha] }
397+
{ assume ha, rw [legendre_sym, int.cast_coe_nat, if_pos ha] }
393398
end
394399

395400
/-- Gauss' lemma. The legendre symbol can be computed by considering the number of naturals less
@@ -410,7 +415,7 @@ end
410415
lemma legendre_sym_eq_one_iff {a : ℕ} (ha0 : (a : zmod p) ≠ 0) :
411416
legendre_sym a p = 1 ↔ (∃ b : zmod p, b ^ 2 = a) :=
412417
begin
413-
rw [euler_criterion p ha0, legendre_sym, if_neg ha0],
418+
rw [euler_criterion p ha0, legendre_sym, int.cast_coe_nat, if_neg ha0],
414419
split_ifs,
415420
{ simp only [h, eq_self_iff_true] },
416421
{ simp only [h, iff_false], tauto }
@@ -456,7 +461,7 @@ have hunion :
456461
exact filter_congr (λ x hx, by simp [hx2 _ hx, lt_or_le, mul_comm])
457462
end,
458463
begin
459-
rw [gauss_lemma p (prime_ne_zero p 2 hp2),
464+
erw [gauss_lemma p (prime_ne_zero p 2 hp2),
460465
neg_one_pow_eq_pow_mod_two, @neg_one_pow_eq_pow_mod_two _ _ (p / 4 + p / 2)],
461466
refine congr_arg2 _ rfl ((eq_iff_modeq_nat 2).1 _),
462467
rw [show 4 = 2 * 2, from rfl, ← nat.div_div_eq_div_mul, hp22, nat.cast_add,
@@ -471,8 +476,8 @@ have hp2 : ((2 : ℕ) : zmod p) ≠ 0,
471476
have hpm4 : p % 4 = p % 8 % 4, from (nat.mod_mul_left_mod p 2 4).symm,
472477
have hpm2 : p % 2 = p % 8 % 2, from (nat.mod_mul_left_mod p 4 2).symm,
473478
begin
474-
rw [show (2 : zmod p) = (2 : ℕ), by simp, ← legendre_sym_eq_one_iff p hp2,
475-
legendre_sym_two p, neg_one_pow_eq_one_iff_even (show (-1 : ℤ) ≠ 1, from dec_trivial),
479+
rw [show (2 : zmod p) = (2 : ℕ), by simp, ← legendre_sym_eq_one_iff p hp2],
480+
erw [legendre_sym_two p, neg_one_pow_eq_one_iff_even (show (-1 : ℤ) ≠ 1, from dec_trivial),
476481
even_add, even_div, even_div],
477482
have := nat.mod_lt p (show 0 < 8, from dec_trivial),
478483
resetI, rw fact_iff at hp1,
@@ -494,8 +499,8 @@ begin
494499
have hpq0 : (p : zmod q) ≠ 0 := prime_ne_zero q p (ne.symm hpq),
495500
have hqp0 : (q : zmod p) ≠ 0 := prime_ne_zero p q hpq,
496501
have := quadratic_reciprocity p q hpq,
497-
rw [neg_one_pow_eq_pow_mod_two, h1, legendre_sym, legendre_sym,
498-
if_neg hqp0, if_neg hpq0] at this,
502+
rw [neg_one_pow_eq_pow_mod_two, h1, legendre_sym, legendre_sym, int.cast_coe_nat,
503+
int.cast_coe_nat, if_neg hqp0, if_neg hpq0] at this,
499504
rw [euler_criterion q hpq0, euler_criterion p hqp0],
500505
split_ifs at this; simp *; contradiction,
501506
end
@@ -512,8 +517,8 @@ begin
512517
have hpq0 : (p : zmod q) ≠ 0 := prime_ne_zero q p (ne.symm hpq),
513518
have hqp0 : (q : zmod p) ≠ 0 := prime_ne_zero p q hpq,
514519
have := quadratic_reciprocity p q hpq,
515-
rw [neg_one_pow_eq_pow_mod_two, h1, legendre_sym, legendre_sym,
516-
if_neg hpq0, if_neg hqp0] at this,
520+
rw [neg_one_pow_eq_pow_mod_two, h1, legendre_sym, legendre_sym, int.cast_coe_nat,
521+
int.cast_coe_nat, if_neg hpq0, if_neg hqp0] at this,
517522
rw [euler_criterion q hpq0, euler_criterion p hqp0],
518523
split_ifs at this; simp *; contradiction
519524
end

0 commit comments

Comments
 (0)