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

Commit d2d6652

Browse files
feat(number_theory/legendre_symbol/jacobi_symbol): add new file with the definition and properties of the Jacobi symbol (#16395)
This PR consists of a new file, `number_theory.legendre_symbol.jacobi_symbol`, that contains a definition of the Jacobi symbol (and sets up notation `[a | b]ⱼ` for it) and then proves a number of results, e.g., multiplicativity in both arguments, expressions for the cases `a = -1`, `a = 2`, `a = -2`, and several versions of quadratic reciprocity. It also proves that the symbol depends on a only through its residue class `mod b` and that it depends on `b` only through its residue class `mod 4*a` (quadratic reciprocity is needed for the latter). The code has already been quite thoroughly reviewed while it was part of #16290 (which then was reduced to the auxiliary results needed for the Jacobi symbol code). Discussion on [Zulip](https://leanprover.zulipchat.com/#narrow/stream/116395-maths/topic/Jacobi.20symbol/near/295816984)
1 parent 662786a commit d2d6652

File tree

1 file changed

+385
-0
lines changed

1 file changed

+385
-0
lines changed
Lines changed: 385 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,385 @@
1+
/-
2+
Copyright (c) 2022 Michael Stoll. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Michael Stoll
5+
-/
6+
import number_theory.legendre_symbol.quadratic_reciprocity
7+
import data.zmod.coprime
8+
9+
/-!
10+
# The Jacobi Symbol
11+
12+
We define the Jacobi symbol and prove its main properties.
13+
14+
## Main definitions
15+
16+
We define the Jacobi symbol, `jacobi_sym a b`, for integers `a` and natural numbers `b`
17+
as the product over the prime factors `p` of `b` of the Legendre symbols `zmod.legendre_sym p a`.
18+
This agrees with the mathematical definition when `b` is odd.
19+
20+
The prime factors are obtained via `nat.factors`. Since `nat.factors 0 = []`,
21+
this implies in particular that `jacobi_sym a 0 = 1` for all `a`.
22+
23+
## Main statements
24+
25+
We prove the main properties of the Jacobi symbol, including the following.
26+
27+
* Multiplicativity in both arguments (`jacobi_sym_mul_left`, `jacobi_sym_mul_right`)
28+
29+
* The value of the symbol is `1` or `-1` when the arguments are coprime
30+
(`jacobi_sym_eq_one_or_neg_one`)
31+
32+
* The symbol vanishes if and only if `b ≠ 0` and the arguments are not coprime
33+
(`jacobi_sym_eq_zero_iff`)
34+
35+
* If the symbol has the value `-1`, then `a : zmod b` is not a square
36+
(`nonsquare_of_jacobi_sym_eq_neg_one`); the converse holds when `b = p` is a prime
37+
(`nonsquare_iff_jacobi_sym_eq_neg_one`); in particular, in this case `a` is a
38+
square mod `p` when the symbol has the value `1` (`is_square_of_jacobi_sym_eq_one`).
39+
40+
* Quadratic reciprocity (`jacobi_sym_quadratic_reciprocity`,
41+
`jacobi_sym_quadratic_reciprocity_one_mod_four`,
42+
`jacobi_sym_quadratic_reciprocity_three_mod_four`)
43+
44+
* The supplementary laws for `a = -1`, `a = 2`, `a = -2` (`jacobi_sym_neg_one`, `jacobi_sym_two`,
45+
`jacobi_sym_neg_two`)
46+
47+
* The symbol depends on `a` only via its residue class mod `b` (`jacobi_sym_mod_left`)
48+
and on `b` only via its residue class mod `4*a` (`jacobi_sym_mod_right`)
49+
50+
## Notations
51+
52+
We define the notation `J(a | b)` for `jacobi_sym a b`, localized to `number_theory_symbols`.
53+
54+
## Tags
55+
Jacobi symbol, quadratic reciprocity
56+
-/
57+
58+
section jacobi
59+
60+
/-!
61+
### Definition of the Jacobi symbol
62+
63+
We define the Jacobi symbol $\Bigl\frac{a}{b}\Bigr$ for integers `a` and natural numbers `b` as the
64+
product of the Legendre symbols $\Bigl\frac{a}{p}\Bigr$, where `p` runs through the prime divisors
65+
(with multiplicity) of `b`, as provided by `b.factors`. This agrees with the Jacobi symbol
66+
when `b` is odd and gives less meaningful values when it is not (e.g., the symbol is `1`
67+
when `b = 0`). This is called `jacobi_sym a b`.
68+
69+
We define localized notation (locale `number_theory_symbols`) `J(a | b)` for the Jacobi
70+
symbol `jacobi_sym a b`. (Unfortunately, there is no subscript "J" in unicode.)
71+
-/
72+
73+
namespace zmod
74+
open nat
75+
76+
/-- The Jacobi symbol of `a` and `b` -/
77+
-- Since we need the fact that the factors are prime, we use `list.pmap`.
78+
def jacobi_sym (a : ℤ) (b : ℕ) : ℤ :=
79+
(b.factors.pmap (λ p pp, @legendre_sym p ⟨pp⟩ a) (λ p pf, prime_of_mem_factors pf)).prod
80+
81+
-- Notation for the Jacobi symbol.
82+
localized "notation `J(` a ` | ` b `)` := jacobi_sym a b" in number_theory_symbols
83+
84+
/-!
85+
### Properties of the Jacobi symbol
86+
-/
87+
88+
/-- The symbol `J(a | 0)` has the value `1`. -/
89+
@[simp] lemma jacobi_sym_zero_right (a : ℤ) : J(a | 0) = 1 :=
90+
by simp only [jacobi_sym, factors_zero, list.prod_nil, list.pmap]
91+
92+
/-- The symbol `J(a | 1)` has the value `1`. -/
93+
@[simp] lemma jacobi_sym_one_right (a : ℤ) : J(a | 1) = 1 :=
94+
by simp only [jacobi_sym, factors_one, list.prod_nil, list.pmap]
95+
96+
/-- The Legendre symbol `legendre_sym p a` with an integer `a` and a prime number `p`
97+
is the same as the Jacobi symbol `J(a | p)`. -/
98+
lemma legendre_sym.to_jacobi_sym {p : ℕ} [fp : fact p.prime] {a : ℤ} :
99+
legendre_sym p a = J(a | p) :=
100+
by simp only [jacobi_sym, factors_prime fp.1, list.prod_cons, list.prod_nil, mul_one, list.pmap]
101+
102+
/-- The Jacobi symbol is multiplicative in its second argument. -/
103+
lemma jacobi_sym_mul_right' (a : ℤ) {b₁ b₂ : ℕ} (hb₁ : b₁ ≠ 0) (hb₂ : b₂ ≠ 0) :
104+
J(a | b₁ * b₂) = J(a | b₁) * J(a | b₂) :=
105+
begin
106+
rw [jacobi_sym, ((perm_factors_mul hb₁ hb₂).pmap _).prod_eq, list.pmap_append, list.prod_append],
107+
exacts [rfl, λ p hp, (list.mem_append.mp hp).elim prime_of_mem_factors prime_of_mem_factors],
108+
end
109+
110+
/-- The Jacobi symbol is multiplicative in its second argument. -/
111+
lemma jacobi_sym_mul_right (a : ℤ) (b₁ b₂ : ℕ) [ne_zero b₁] [ne_zero b₂] :
112+
J(a | b₁ * b₂) = J(a | b₁) * J(a | b₂) :=
113+
jacobi_sym_mul_right' a (ne_zero.ne b₁) (ne_zero.ne b₂)
114+
115+
/-- The Jacobi symbol takes only the values `0`, `1` and `-1`. -/
116+
lemma jacobi_sym_trichotomy (a : ℤ) (b : ℕ) : J(a | b) = 0 ∨ J(a | b) = 1 ∨ J(a | b) = -1 :=
117+
((@sign_type.cast_hom ℤ _ _).to_monoid_hom.mrange.copy {0, 1, -1} $
118+
by {rw set.pair_comm, exact (sign_type.range_eq sign_type.cast_hom).symm}).list_prod_mem
119+
begin
120+
intros _ ha',
121+
rcases list.mem_pmap.mp ha' with ⟨p, hp, rfl⟩,
122+
haveI : fact p.prime := ⟨prime_of_mem_factors hp⟩,
123+
exact quadratic_char_is_quadratic (zmod p) a,
124+
end
125+
126+
/-- The symbol `J(1 | b)` has the value `1`. -/
127+
@[simp] lemma jacobi_sym_one_left (b : ℕ) : J(1 | b) = 1 :=
128+
list.prod_eq_one (λ z hz, let ⟨p, hp, he⟩ := list.mem_pmap.1 hz in by rw [← he, legendre_sym_one])
129+
130+
/-- The Jacobi symbol is multiplicative in its first argument. -/
131+
lemma jacobi_sym_mul_left (a₁ a₂ : ℤ) (b : ℕ) : J(a₁ * a₂ | b) = J(a₁ | b) * J(a₂ | b) :=
132+
by { simp_rw [jacobi_sym, list.pmap_eq_map_attach, legendre_sym_mul], exact list.prod_map_mul }
133+
134+
/-- The symbol `J(a | b)` vanishes iff `a` and `b` are not coprime (assuming `b ≠ 0`). -/
135+
lemma jacobi_sym_eq_zero_iff_not_coprime {a : ℤ} {b : ℕ} [ne_zero b] :
136+
J(a | b) = 0 ↔ a.gcd b ≠ 1 :=
137+
list.prod_eq_zero_iff.trans begin
138+
rw [list.mem_pmap, int.gcd_eq_nat_abs, ne, prime.not_coprime_iff_dvd],
139+
simp_rw [legendre_sym_eq_zero_iff, int_coe_zmod_eq_zero_iff_dvd, mem_factors (ne_zero.ne b),
140+
← int.coe_nat_dvd_left, int.coe_nat_dvd, exists_prop, and_assoc, and_comm],
141+
end
142+
143+
/-- The symbol `J(a | b)` is nonzero when `a` and `b` are coprime. -/
144+
lemma jacobi_sym_ne_zero {a : ℤ} {b : ℕ} (h : a.gcd b = 1) : J(a | b) ≠ 0 :=
145+
begin
146+
casesI eq_zero_or_ne_zero b with hb,
147+
{ rw [hb, jacobi_sym_zero_right],
148+
exact one_ne_zero },
149+
{ contrapose! h, exact jacobi_sym_eq_zero_iff_not_coprime.1 h },
150+
end
151+
152+
/-- The symbol `J(a | b)` vanishes if and only if `b ≠ 0` and `a` and `b` are not coprime. -/
153+
lemma jacobi_sym_eq_zero_iff {a : ℤ} {b : ℕ} : J(a | b) = 0 ↔ b ≠ 0 ∧ a.gcd b ≠ 1 :=
154+
⟨λ h, begin
155+
casesI eq_or_ne b 0 with hb hb,
156+
{ rw [hb, jacobi_sym_zero_right] at h, cases h },
157+
exact ⟨hb, mt jacobi_sym_ne_zero $ not_not.2 h⟩,
158+
end, λ ⟨hb, h⟩, by { rw ← ne_zero_iff at hb, exactI jacobi_sym_eq_zero_iff_not_coprime.2 h }⟩
159+
160+
/-- The symbol `J(0 | b)` vanishes when `b > 1`. -/
161+
lemma jacobi_sym_zero_left {b : ℕ} (hb : 1 < b) : J(0 | b) = 0 :=
162+
(@jacobi_sym_eq_zero_iff_not_coprime 0 b ⟨ne_zero_of_lt hb⟩).mpr $
163+
by { rw [int.gcd_zero_left, int.nat_abs_of_nat], exact hb.ne' }
164+
165+
/-- The symbol `J(a | b)` takes the value `1` or `-1` if `a` and `b` are coprime. -/
166+
lemma jacobi_sym_eq_one_or_neg_one {a : ℤ} {b : ℕ} (h : a.gcd b = 1) :
167+
J(a | b) = 1 ∨ J(a | b) = -1 :=
168+
(jacobi_sym_trichotomy a b).resolve_left $ jacobi_sym_ne_zero h
169+
170+
/-- We have that `J(a^e | b) = J(a | b)^e`. -/
171+
lemma jacobi_sym_pow_left (a : ℤ) (e b : ℕ) : J(a ^ e | b) = J(a | b) ^ e :=
172+
nat.rec_on e (by rw [pow_zero, pow_zero, jacobi_sym_one_left]) $
173+
λ _ ih, by rw [pow_succ, pow_succ, jacobi_sym_mul_left, ih]
174+
175+
/-- We have that `J(a | b^e) = J(a | b)^e`. -/
176+
lemma jacobi_sym_pow_right (a : ℤ) (b e : ℕ) : J(a | b ^ e) = J(a | b) ^ e :=
177+
begin
178+
induction e with e ih,
179+
{ rw [pow_zero, pow_zero, jacobi_sym_one_right], },
180+
{ casesI eq_zero_or_ne_zero b with hb,
181+
{ rw [hb, zero_pow (succ_pos e), jacobi_sym_zero_right, one_pow], },
182+
{ rw [pow_succ, pow_succ, jacobi_sym_mul_right, ih], } }
183+
end
184+
185+
/-- The square of `J(a | b)` is `1` when `a` and `b` are coprime. -/
186+
lemma jacobi_sym_sq_one {a : ℤ} {b : ℕ} (h : a.gcd b = 1) : J(a | b) ^ 2 = 1 :=
187+
by cases jacobi_sym_eq_one_or_neg_one h with h₁ h₁; rw h₁; refl
188+
189+
/-- The symbol `J(a^2 | b)` is `1` when `a` and `b` are coprime. -/
190+
lemma jacobi_sym_sq_one' {a : ℤ} {b : ℕ} (h : a.gcd b = 1) : J(a ^ 2 | b) = 1 :=
191+
by rw [jacobi_sym_pow_left, jacobi_sym_sq_one h]
192+
193+
/-- The symbol `J(a | b)` depends only on `a` mod `b`. -/
194+
lemma jacobi_sym_mod_left (a : ℤ) (b : ℕ) : J(a | b) = J(a % b | b) :=
195+
congr_arg list.prod $ list.pmap_congr _ begin
196+
rintro p hp _ _,
197+
conv_rhs { rw [legendre_sym_mod, int.mod_mod_of_dvd _
198+
(int.coe_nat_dvd.2 $ dvd_of_mem_factors hp), ← legendre_sym_mod] },
199+
end
200+
201+
/-- The symbol `J(a | b)` depends only on `a` mod `b`. -/
202+
lemma jacobi_sym_mod_left' {a₁ a₂ : ℤ} {b : ℕ} (h : a₁ % b = a₂ % b) : J(a₁ | b) = J(a₂ | b) :=
203+
by rw [jacobi_sym_mod_left, h, ← jacobi_sym_mod_left]
204+
205+
/-- If `J(a | b)` is `-1`, then `a` is not a square modulo `b`. -/
206+
lemma nonsquare_of_jacobi_sym_eq_neg_one {a : ℤ} {b : ℕ} (h : J(a | b) = -1) :
207+
¬ is_square (a : zmod b) :=
208+
λ ⟨r, ha⟩, begin
209+
rw [← r.coe_val_min_abs, ← int.cast_mul, int_coe_eq_int_coe_iff', ← sq] at ha,
210+
apply (by norm_num : ¬ (0 : ℤ) ≤ -1),
211+
rw [← h, jacobi_sym_mod_left, ha, ← jacobi_sym_mod_left, jacobi_sym_pow_left],
212+
apply sq_nonneg,
213+
end
214+
215+
/-- If `p` is prime, then `J(a | p)` is `-1` iff `a` is not a square modulo `p`. -/
216+
lemma nonsquare_iff_jacobi_sym_eq_neg_one {a : ℤ} {p : ℕ} [fact p.prime] :
217+
J(a | p) = -1 ↔ ¬ is_square (a : zmod p) :=
218+
by { rw [← legendre_sym.to_jacobi_sym], exact legendre_sym_eq_neg_one_iff p }
219+
220+
/-- If `p` is prime and `J(a | p) = 1`, then `a` is q square mod `p`. -/
221+
lemma is_square_of_jacobi_sym_eq_one {a : ℤ} {p : ℕ} [fact p.prime] (h : J(a | p) = 1) :
222+
is_square (a : zmod p) :=
223+
not_not.mp $ mt nonsquare_iff_jacobi_sym_eq_neg_one.mpr $
224+
λ hf, one_ne_zero $ neg_eq_self_iff.mp $ hf.symm.trans h
225+
226+
/-!
227+
### Values at `-1`, `2` and `-2`
228+
-/
229+
230+
/-- If `χ` is a multiplicative function such that `J(a | p) = χ p` for all odd primes `p`,
231+
then `J(a | b)` equals `χ b` for all odd natural numbers `b`. -/
232+
lemma jacobi_sym_value (a : ℤ) {R : Type*} [comm_semiring R] (χ : R →* ℤ)
233+
(hp : ∀ (p : ℕ) (pp : p.prime) (h2 : p ≠ 2), @legendre_sym p ⟨pp⟩ a = χ p) {b : ℕ} (hb : odd b) :
234+
J(a | b) = χ b :=
235+
begin
236+
conv_rhs { rw [← prod_factors hb.pos.ne', cast_list_prod, χ.map_list_prod] },
237+
rw [jacobi_sym, list.map_map, ← list.pmap_eq_map nat.prime _ _ (λ _, prime_of_mem_factors)],
238+
congr' 1, apply list.pmap_congr,
239+
exact λ p h pp _, hp p pp (hb.factors_ne_two h),
240+
end
241+
242+
/-- If `b` is odd, then `J(-1 | b)` is given by `χ₄ b`. -/
243+
lemma jacobi_sym_neg_one {b : ℕ} (hb : odd b) : J(-1 | b) = χ₄ b :=
244+
jacobi_sym_value (-1) χ₄ (λ p pp, @legendre_sym_neg_one p ⟨pp⟩) hb
245+
246+
/-- If `b` is odd, then `J(-a | b) = χ₄ b * J(a | b)`. -/
247+
lemma jacobi_sym_neg (a : ℤ) {b : ℕ} (hb : odd b) : J(-a | b) = χ₄ b * J(a | b) :=
248+
by rw [neg_eq_neg_one_mul, jacobi_sym_mul_left, jacobi_sym_neg_one hb]
249+
250+
/-- If `b` is odd, then `J(2 | b)` is given by `χ₈ b`. -/
251+
lemma jacobi_sym_two {b : ℕ} (hb : odd b) : J(2 | b) = χ₈ b :=
252+
jacobi_sym_value 2 χ₈ (λ p pp, @legendre_sym_two p ⟨pp⟩) hb
253+
254+
/-- If `b` is odd, then `J(-2 | b)` is given by `χ₈' b`. -/
255+
lemma jacobi_sym_neg_two {b : ℕ} (hb : odd b) : J(-2 | b) = χ₈' b :=
256+
jacobi_sym_value (-2) χ₈' (λ p pp, @legendre_sym_neg_two p ⟨pp⟩) hb
257+
258+
259+
/-!
260+
### Quadratic Reciprocity
261+
-/
262+
263+
/-- The bi-multiplicative map giving the sign in the Law of Quadratic Reciprocity -/
264+
def qr_sign (m n : ℕ) : ℤ := J(χ₄ m | n)
265+
266+
/-- We can express `qr_sign m n` as a power of `-1` when `m` and `n` are odd. -/
267+
lemma qr_sign_neg_one_pow {m n : ℕ} (hm : odd m) (hn : odd n) :
268+
qr_sign m n = (-1) ^ ((m / 2) * (n / 2)) :=
269+
begin
270+
rw [qr_sign, pow_mul, ← χ₄_eq_neg_one_pow (odd_iff.mp hm)],
271+
cases odd_mod_four_iff.mp (odd_iff.mp hm) with h h,
272+
{ rw [χ₄_nat_one_mod_four h, jacobi_sym_one_left, one_pow], },
273+
{ rw [χ₄_nat_three_mod_four h, ← χ₄_eq_neg_one_pow (odd_iff.mp hn), jacobi_sym_neg_one hn], }
274+
end
275+
276+
/-- When `m` and `n` are odd, then the square of `qr_sign m n` is `1`. -/
277+
lemma qr_sign_sq_eq_one {m n : ℕ} (hm : odd m) (hn : odd n) : (qr_sign m n) ^ 2 = 1 :=
278+
by rw [qr_sign_neg_one_pow hm hn, ← pow_mul, mul_comm, pow_mul, neg_one_sq, one_pow]
279+
280+
/-- `qr_sign` is multiplicative in the first argument. -/
281+
lemma qr_sign_mul_left (m₁ m₂ n : ℕ) : qr_sign (m₁ * m₂) n = qr_sign m₁ n * qr_sign m₂ n :=
282+
by simp_rw [qr_sign, nat.cast_mul, map_mul, jacobi_sym_mul_left]
283+
284+
/-- `qr_sign` is multiplicative in the second argument. -/
285+
lemma qr_sign_mul_right (m n₁ n₂ : ℕ) [ne_zero n₁] [ne_zero n₂] :
286+
qr_sign m (n₁ * n₂) = qr_sign m n₁ * qr_sign m n₂ :=
287+
jacobi_sym_mul_right (χ₄ m) n₁ n₂
288+
289+
/-- `qr_sign` is symmetric when both arguments are odd. -/
290+
lemma qr_sign_symm {m n : ℕ} (hm : odd m) (hn : odd n) : qr_sign m n = qr_sign n m :=
291+
by rw [qr_sign_neg_one_pow hm hn, qr_sign_neg_one_pow hn hm, mul_comm (m / 2)]
292+
293+
/-- We can move `qr_sign m n` from one side of an equality to the other when `m` and `n` are odd. -/
294+
lemma qr_sign_eq_iff_eq {m n : ℕ} (hm : odd m) (hn : odd n) (x y : ℤ) :
295+
qr_sign m n * x = y ↔ x = qr_sign m n * y :=
296+
by refine ⟨λ h', let h := h'.symm in _, λ h, _⟩;
297+
rw [h, ← mul_assoc, ← pow_two, qr_sign_sq_eq_one hm hn, one_mul]
298+
299+
/-- The Law of Quadratic Reciprocity for the Jacobi symbol, version with `qr_sign` -/
300+
lemma jacobi_sym_quadratic_reciprocity' {a b : ℕ} (ha : odd a) (hb : odd b) :
301+
J(a | b) = qr_sign b a * J(b | a) :=
302+
begin
303+
-- define the right hand side for fixed `a` as a `ℕ →* ℤ`
304+
let rhs : ℕ → ℕ →* ℤ := λ a,
305+
{ to_fun := λ x, qr_sign x a * J(x | a),
306+
map_one' := by { convert ← mul_one _, symmetry, all_goals { apply jacobi_sym_one_left } },
307+
map_mul' := λ x y, by rw [qr_sign_mul_left, nat.cast_mul, jacobi_sym_mul_left,
308+
mul_mul_mul_comm] },
309+
have rhs_apply : ∀ (a b : ℕ), rhs a b = qr_sign b a * J(b | a) := λ a b, rfl,
310+
refine jacobi_sym_value a (rhs a) (λ p pp hp, eq.symm _) hb,
311+
have hpo := pp.eq_two_or_odd'.resolve_left hp,
312+
rw [@legendre_sym.to_jacobi_sym p ⟨pp⟩, rhs_apply, nat.cast_id,
313+
qr_sign_eq_iff_eq hpo ha, qr_sign_symm hpo ha],
314+
refine jacobi_sym_value p (rhs p) (λ q pq hq, _) ha,
315+
have hqo := pq.eq_two_or_odd'.resolve_left hq,
316+
rw [rhs_apply, nat.cast_id, ← @legendre_sym.to_jacobi_sym p ⟨pp⟩, qr_sign_symm hqo hpo,
317+
qr_sign_neg_one_pow hpo hqo, @quadratic_reciprocity' p q ⟨pp⟩ ⟨pq⟩ hp hq],
318+
end
319+
320+
/-- The Law of Quadratic Reciprocity for the Jacobi symbol -/
321+
lemma jacobi_sym_quadratic_reciprocity {a b : ℕ} (ha : odd a) (hb : odd b) :
322+
J(a | b) = (-1) ^ ((a / 2) * (b / 2)) * J(b | a) :=
323+
by rw [← qr_sign_neg_one_pow ha hb, qr_sign_symm ha hb, jacobi_sym_quadratic_reciprocity' ha hb]
324+
325+
/-- The Law of Quadratic Reciprocity for the Jacobi symbol: if `a` and `b` are natural numbers
326+
with `a % 4 = 1` and `b` odd, then `J(a | b) = J(b | a)`. -/
327+
theorem jacobi_sym_quadratic_reciprocity_one_mod_four {a b : ℕ} (ha : a % 4 = 1) (hb : odd b) :
328+
J(a | b) = J(b | a) :=
329+
by rw [jacobi_sym_quadratic_reciprocity (odd_iff.mpr (odd_of_mod_four_eq_one ha)) hb,
330+
pow_mul, neg_one_pow_div_two_of_one_mod_four ha, one_pow, one_mul]
331+
332+
/-- The Law of Quadratic Reciprocity for the Jacobi symbol: if `a` and `b` are natural numbers
333+
with `a` odd and `b % 4 = 1`, then `J(a | b) = J(b | a)`. -/
334+
theorem jacobi_sym_quadratic_reciprocity_one_mod_four' {a b : ℕ} (ha : odd a) (hb : b % 4 = 1) :
335+
J(a | b) = J(b | a) :=
336+
(jacobi_sym_quadratic_reciprocity_one_mod_four hb ha).symm
337+
338+
/-- The Law of Quadratic Reciprocityfor the Jacobi symbol: if `a` and `b` are natural numbers
339+
both congruent to `3` mod `4`, then `J(a | b) = -J(b | a)`. -/
340+
theorem jacobi_sym_quadratic_reciprocity_three_mod_four
341+
{a b : ℕ} (ha : a % 4 = 3) (hb : b % 4 = 3) :
342+
J(a | b) = - J(b | a) :=
343+
let nop := @neg_one_pow_div_two_of_three_mod_four in begin
344+
rw [jacobi_sym_quadratic_reciprocity, pow_mul, nop ha, nop hb, neg_one_mul];
345+
rwa [odd_iff, odd_of_mod_four_eq_three],
346+
end
347+
348+
/-- The Jacobi symbol `J(a | b)` depends only on `b` mod `4*a` (version for `a : ℕ`). -/
349+
lemma jacobi_sym_mod_right' (a : ℕ) {b : ℕ} (hb : odd b) : J(a | b) = J(a | b % (4 * a)) :=
350+
begin
351+
rcases eq_or_ne a 0 with rfl | ha₀,
352+
{ rw [mul_zero, mod_zero], },
353+
have hb' : odd (b % (4 * a)) := hb.mod_even (even.mul_right (by norm_num) _),
354+
rcases exists_eq_pow_mul_and_not_dvd ha₀ 2 (by norm_num) with ⟨e, a', ha₁', ha₂⟩,
355+
have ha₁ := odd_iff.mpr (two_dvd_ne_zero.mp ha₁'),
356+
nth_rewrite 1 [ha₂], nth_rewrite 0 [ha₂],
357+
rw [nat.cast_mul, jacobi_sym_mul_left, jacobi_sym_mul_left,
358+
jacobi_sym_quadratic_reciprocity' ha₁ hb, jacobi_sym_quadratic_reciprocity' ha₁ hb',
359+
nat.cast_pow, jacobi_sym_pow_left, jacobi_sym_pow_left,
360+
(show ((2 : ℕ) : ℤ) = 2, by refl), jacobi_sym_two hb, jacobi_sym_two hb'],
361+
congr' 1, swap, congr' 1,
362+
{ simp_rw [qr_sign],
363+
rw [χ₄_nat_mod_four, χ₄_nat_mod_four (b % (4 * a)), mod_mod_of_dvd b (dvd_mul_right 4 a) ] },
364+
{ rw [jacobi_sym_mod_left ↑(b % _), jacobi_sym_mod_left b, int.coe_nat_mod,
365+
int.mod_mod_of_dvd b],
366+
simp only [ha₂, nat.cast_mul, ← mul_assoc],
367+
exact dvd_mul_left a' _, },
368+
cases e, { refl },
369+
{ rw [χ₈_nat_mod_eight, χ₈_nat_mod_eight (b % (4 * a)), mod_mod_of_dvd b],
370+
use 2 ^ e * a', rw [ha₂, pow_succ], ring, }
371+
end
372+
373+
/-- The Jacobi symbol `J(a | b)` depends only on `b` mod `4*a`. -/
374+
lemma jacobi_sym_mod_right (a : ℤ) {b : ℕ} (hb : odd b) : J(a | b) = J(a | b % (4 * a.nat_abs)) :=
375+
begin
376+
cases int.nat_abs_eq a with ha ha; nth_rewrite 1 [ha]; nth_rewrite 0 [ha],
377+
{ exact jacobi_sym_mod_right' a.nat_abs hb, },
378+
{ have hb' : odd (b % (4 * a.nat_abs)) := hb.mod_even (even.mul_right (by norm_num) _),
379+
rw [jacobi_sym_neg _ hb, jacobi_sym_neg _ hb', jacobi_sym_mod_right' _ hb, χ₄_nat_mod_four,
380+
χ₄_nat_mod_four (b % (4 * _)), mod_mod_of_dvd b (dvd_mul_right 4 _)], }
381+
end
382+
383+
end zmod
384+
385+
end jacobi

0 commit comments

Comments
 (0)