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

Commit 2bdeda9

Browse files
doc(number_theory/*): provide docstrings for basic and dioph (#6063)
The main purpose of this PR is to provide docstrings for the two remaining files without docstring in number_theory, basic and dioph. Furthermore, lines are split in other files, so that there should be no number_theory entries in the style_exceptions file. Co-authored-by: Julian-Kuelshammer <68201724+Julian-Kuelshammer@users.noreply.github.com>
1 parent d951b2b commit 2bdeda9

File tree

7 files changed

+104
-31
lines changed

7 files changed

+104
-31
lines changed

src/number_theory/basic.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ Authors: Johan Commelin, Kenny Lau
77
import algebra.geom_sum
88
import ring_theory.ideal.basic
99

10+
/-!
11+
# Basic results in number theory
12+
13+
This file should contain basic results in number theory. So far, it only contains the essential
14+
lemma in the construction of the ring of Witt vectors.
15+
16+
## Main statement
17+
18+
`dvd_sub_pow_of_dvd_sub` proves that for elements `a` and `b` in a commutative ring `R` and for
19+
all natural numbers `p` and `k` if `p` divides `a-b` in `R`, then `p ^ (k + 1)` divides
20+
`a ^ (p ^ k) - b ^ (p ^ k)`.
21+
-/
22+
1023
section
1124

1225
open ideal ideal.quotient

src/number_theory/dioph.lean

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,50 @@ Copyright (c) 2017 Mario Carneiro. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Mario Carneiro
55
-/
6+
67
import number_theory.pell
78
import data.pfun
89
import data.fin2
910

11+
/-!
12+
# Diophantine functions and Matiyasevic's theorem
13+
14+
Hilbert's tenth problem asked whether there exists an algorithm which for a given integer polynomial
15+
determines whether this polynomial has integer solutions. It was answered in the negative in 1970,
16+
the final step being completed by Matiyasevic who showed that the power function is Diophantine.
17+
18+
Here a function is called Diophantine if its graph is Diophantine as a set. A subset `S ⊆ ℕ ^ α` in
19+
turn is called Diophantine if there exists an integer polynomial on `α ⊕ β` such that `v ∈ S` iff
20+
there exists `t : ℕ^β` with `p (v, t) = 0`.
21+
22+
## Main definitions
23+
24+
* `is_poly`: a predicate stating that a function is a multivariate integer polynomial.
25+
* `poly`: the type of multivariate integer polynomial functions.
26+
* `dioph`: a predicate stating that a set `S ⊆ ℕ^α` is Diophantine, i.e. that
27+
* `dioph_fn`: a predicate on a function stating that it is Diophantine in the sense that its graph
28+
is Diophantine as a set.
29+
30+
## Main statements
31+
32+
* `pell_dioph` states that solutions to Pell's equation form a Diophantine set.
33+
* `pow_dioph` states that the power function is Diophantine, a version of Matiyasevic's theorem.
34+
35+
## References
36+
37+
* [M. Carneiro, _A Lean formalization of Matiyasevic's theorem_][carneiro2018matiyasevic]
38+
* [M. Davis, _Hilbert's tenth problem is unsolvable_][MR317916]
39+
40+
## Tags
41+
42+
Matiyasevic's theorem, Hilbert's tenth problem
43+
44+
## TODO
45+
46+
* Finish the solution of Hilbert's tenth problem.
47+
* Connect `poly` to `mv_polynomial`
48+
-/
49+
1050
universe u
1151

1252
open nat function
@@ -389,7 +429,7 @@ end option
389429

390430
/- dioph -/
391431

392-
/-- A set `S ⊆ ℕ^α` is diophantine if there exists a polynomial on
432+
/-- A set `S ⊆ ℕ^α` is Diophantine if there exists a polynomial on
393433
`α ⊕ β` such that `v ∈ S` iff there exists `t : ℕ^β` with `p (v, t) = 0`. -/
394434
def dioph {α : Type u} (S : set (α → ℕ)) : Prop :=
395435
∃ {β : Type u} (p : poly (α ⊕ β)), ∀ (v : α → ℕ), S v ↔ ∃t, p (v ⊗ t) = 0

src/number_theory/lucas_lehmer.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ begin
398398
{ norm_num, },
399399
{ intro o,
400400
have ω_pow := order_of_dvd_iff_pow_eq_one.1 o,
401-
replace ω_pow := congr_arg (units.coe_hom (X (q (p'+2))) : units (X (q (p'+2))) → X (q (p'+2))) ω_pow,
401+
replace ω_pow := congr_arg (units.coe_hom (X (q (p'+2))) :
402+
units (X (q (p'+2))) → X (q (p'+2))) ω_pow,
402403
simp at ω_pow,
403404
have h : (1 : zmod (q (p'+2))) = -1 :=
404405
congr_arg (prod.fst) ((ω_pow.symm).trans (ω_pow_eq_neg_one p' h)),

src/number_theory/pell.lean

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import tactic.omega
1414
This file solves Pell's equation, i.e. integer solutions to `x ^ 2 - d * y ^ 2 = 1` in the special
1515
case that `d = a ^ 2 - 1`. This is then applied to prove Matiyasevic's theorem that the power
1616
function is Diophantine, which is the last key ingredient in the solution to Hilbert's tenth
17-
problem.
17+
problem. For the definition of Diophantine function, see `dioph.lean`.
1818
1919
## Main definition
2020
@@ -113,8 +113,10 @@ section
113113
def is_pell : ℤ√d → Prop | ⟨x, y⟩ := x*x - d*y*y = 1
114114

115115
theorem is_pell_nat {x y : ℕ} : is_pell ⟨x, y⟩ ↔ x*x - d*y*y = 1 :=
116-
⟨λh, int.coe_nat_inj (by rw int.coe_nat_sub (int.le_of_coe_nat_le_coe_nat $ int.le.intro_sub h); exact h),
117-
λh, show ((x*x : ℕ) - (d*y*y:ℕ) : ℤ) = 1, by rw [← int.coe_nat_sub $ le_of_lt $ nat.lt_of_sub_eq_succ h, h]; refl⟩
116+
⟨λh, int.coe_nat_inj
117+
(by rw int.coe_nat_sub (int.le_of_coe_nat_le_coe_nat $ int.le.intro_sub h); exact h),
118+
λh, show ((x*x : ℕ) - (d*y*y:ℕ) : ℤ) = 1,
119+
by rw [← int.coe_nat_sub $ le_of_lt $ nat.lt_of_sub_eq_succ h, h]; refl⟩
118120

119121
theorem is_pell_norm : Π {b : ℤ√d}, is_pell b ↔ b * b.conj = 1
120122
| ⟨x, y⟩ := by simp [zsqrtd.ext, is_pell, mul_comm]; ring
@@ -151,7 +153,7 @@ section
151153
have na : n < a, from nat.mul_self_lt_mul_self_iff.2 (by rw ← this; exact nat.lt_succ_self _),
152154
have (n+1)*(n+1) ≤ n*n + 1, by rw this; exact nat.mul_self_le_mul_self na,
153155
have n+n ≤ 0, from @nat.le_of_add_le_add_right (n*n + 1) _ _ (by ring at this ⊢; assumption),
154-
ne_of_gt d_pos $ by rw nat.eq_zero_of_le_zero (le_trans (nat.le_add_left _ _) this) at h; exact h⟩
156+
ne_of_gt d_pos $ by rwa nat.eq_zero_of_le_zero ((nat.le_add_left _ _).trans this) at h⟩
155157

156158
theorem xn_ge_a_pow : ∀ (n : ℕ), a^n ≤ xn n
157159
| 0 := le_refl 1
@@ -450,7 +452,8 @@ section
450452
(lt_or_eq_of_le (nat.le_of_succ_le_succ ij)).elim
451453
(λh, lt_trans (eq_of_xn_modeq_lem1 h (le_of_lt jn)) this)
452454
(λh, by rw h; exact this),
453-
by rw [nat.mod_eq_of_lt (x_increasing _ (nat.lt_of_succ_lt jn)), nat.mod_eq_of_lt (x_increasing _ jn)];
455+
by rw [nat.mod_eq_of_lt (x_increasing _ (nat.lt_of_succ_lt jn)),
456+
nat.mod_eq_of_lt (x_increasing _ jn)];
454457
exact x_increasing _ (nat.lt_succ_self _)
455458

456459
theorem eq_of_xn_modeq_lem2 {n} (h : 2 * xn n = xn (n + 1)) : a = 2 ∧ n = 0 :=
@@ -487,23 +490,25 @@ section
487490
cases (lt_or_eq_of_le $ nat.le_of_succ_le_succ ij) with lin ein,
488491
{ rw nat.mod_eq_of_lt (x_increasing _ lin),
489492
have ll : xn a1 (n-1) + xn a1 (n-1) ≤ xn a1 n,
490-
{ rw [← two_mul, mul_comm, show xn a1 n = xn a1 (n-1+1), by rw [nat.sub_add_cancel npos], xn_succ],
493+
{ rw [← two_mul, mul_comm, show xn a1 n = xn a1 (n-1+1),
494+
by rw [nat.sub_add_cancel npos], xn_succ],
491495
exact le_trans (nat.mul_le_mul_left _ a1) (nat.le_add_right _ _) },
492496
have npm : (n-1).succ = n := nat.succ_pred_eq_of_pos npos,
493-
have il : i ≤ n - 1 := by apply nat.le_of_succ_le_succ; rw npm; exact lin,
497+
have il : i ≤ n - 1, { apply nat.le_of_succ_le_succ, rw npm, exact lin },
494498
cases lt_or_eq_of_le il with ill ile,
495499
{ exact lt_of_lt_of_le (nat.add_lt_add_left (x_increasing a1 ill) _) ll },
496500
{ rw ile,
497501
apply lt_of_le_of_ne ll,
498502
rw ← two_mul,
499503
exact λe, ntriv $
500-
let ⟨a2, s1⟩ := @eq_of_xn_modeq_lem2 _ a1 (n-1) (by rw[nat.sub_add_cancel npos]; exact e) in
504+
let ⟨a2, s1⟩ := @eq_of_xn_modeq_lem2 _ a1 (n-1) (by rwa [nat.sub_add_cancel npos]) in
501505
have n1 : n = 1, from le_antisymm (nat.le_of_sub_eq_zero s1) npos,
502506
by rw [ile, a2, n1]; exact ⟨rfl, rfl, rfl, rfl⟩ } },
503507
{ rw [ein, nat.mod_self, add_zero],
504508
exact x_increasing _ (nat.pred_lt $ ne_of_gt npos) } })
505509
(λ (jn : j > n),
506-
have lem1 : j ≠ n → xn j % xn n < xn (j + 1) % xn n → xn i % xn n < xn (j + 1) % xn n, from λjn s,
510+
have lem1 : j ≠ n → xn j % xn n < xn (j + 1) % xn n → xn i % xn n < xn (j + 1) % xn n,
511+
from λjn s,
507512
(lt_or_eq_of_le (nat.le_of_succ_le_succ ij)).elim
508513
(λh, lt_trans (eq_of_xn_modeq_lem3 h (le_of_lt j2n) jn $ λ⟨a1, n1, i0, j2⟩,
509514
by rw [n1, j2] at j2n; exact absurd j2n dec_trivial) s)
@@ -533,10 +538,11 @@ section
533538
i = j :=
534539
(le_total i j).elim
535540
(λij, eq_of_xn_modeq_le npos ij j2n h $ λ⟨a2, n1, i0, j2⟩, (ntriv a2 n1).left i0 j2)
536-
(λij, (eq_of_xn_modeq_le npos ij i2n h.symm $ λ⟨a2, n1, j0, i2⟩, (ntriv a2 n1).right i2 j0).symm)
541+
(λij, (eq_of_xn_modeq_le npos ij i2n h.symm $ λ⟨a2, n1, j0, i2⟩,
542+
(ntriv a2 n1).right i2 j0).symm)
537543

538-
theorem eq_of_xn_modeq' {i j n} (ipos : 0 < i) (hin : i ≤ n) (j4n : j ≤ 4 * n) (h : xn j ≡ xn i [MOD xn n]) :
539-
j = i ∨ j + i = 4 * n :=
544+
theorem eq_of_xn_modeq' {i j n} (ipos : 0 < i) (hin : i ≤ n) (j4n : j ≤ 4 * n)
545+
(h : xn j ≡ xn i [MOD xn n]) : j = i ∨ j + i = 4 * n :=
540546
have i2n : i ≤ 2*n, by apply le_trans hin; rw two_mul; apply nat.le_add_left,
541547
have npos : 0 < n, from lt_of_lt_of_le ipos hin,
542548
(le_or_gt j (2 * n)).imp
@@ -549,7 +555,8 @@ section
549555
exact nat.add_le_add_left (le_of_lt j2n) _,
550556
eq_of_xn_modeq npos i2n j42n
551557
(h.symm.trans $ let t := xn_modeq_x4n_sub j42n in by rwa [nat.sub_sub_self j4n] at t)
552-
(λa2 n1, ⟨λi0, absurd i0 (ne_of_gt ipos), λi2, by rw[n1, i2] at hin; exact absurd hin dec_trivial⟩))
558+
(λa2 n1, ⟨λi0, absurd i0 (ne_of_gt ipos), λi2, by { rw [n1, i2] at hin,
559+
exact absurd hin dec_trivial }⟩))
553560

554561
theorem modeq_of_xn_modeq {i j n} (ipos : 0 < i) (hin : i ≤ n) (h : xn j ≡ xn i [MOD xn n]) :
555562
j ≡ i [MOD 4 * n] ∨ j + i ≡ 0 [MOD 4 * n] :=

src/number_theory/primorial.lean

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ begin
3636
{ linarith, },
3737
{ exfalso,
3838
rw ←not_even_iff at n_even r,
39-
have e : even (n + 1 - n), exact (even_sub (le_of_lt (lt_add_one n))).2 (iff_of_false n_even r),
39+
have e : even (n + 1 - n) := (even_sub (lt_add_one n).le).2 (iff_of_false n_even r),
4040
simp only [nat.add_sub_cancel_left, not_even_one] at e,
4141
exact e, }, },
4242
apply finset.prod_congr,
@@ -120,31 +120,36 @@ lemma primorial_le_4_pow : ∀ (n : ℕ), n# ≤ 4 ^ n
120120
simp only [add_le_add_iff_right],
121121
linarith,
122122
end
123-
... = ∏ i in (filter prime (finset.Ico (m + 2) (2 * m + 2)) ∪ (filter prime (range (m + 2)))), i :
123+
... = ∏ i in (filter prime (finset.Ico (m + 2) (2 * m + 2))
124+
∪ (filter prime (range (m + 2)))), i :
124125
by rw filter_union
125126
... = (∏ i in filter prime (finset.Ico (m + 2) (2 * m + 2)), i)
126127
* (∏ i in filter prime (range (m + 2)), i) :
127128
begin
128129
apply finset.prod_union,
129130
have disj : disjoint (finset.Ico (m + 2) (2 * m + 2)) (range (m + 2)),
130-
{ simp only [finset.disjoint_left, and_imp, finset.Ico.mem, not_lt, finset.mem_range],
131+
{ simp only [finset.disjoint_left, and_imp, finset.Ico.mem, not_lt,
132+
finset.mem_range],
131133
intros _ pr _, exact pr, },
132134
exact finset.disjoint_filter_filter disj,
133135
end
134136
... ≤ (∏ i in filter prime (finset.Ico (m + 2) (2 * m + 2)), i) * 4 ^ (m + 1) :
135137
by exact nat.mul_le_mul_left _ (primorial_le_4_pow (m + 1))
136138
... ≤ (choose (2 * m + 1) (m + 1)) * 4 ^ (m + 1) :
137139
begin
138-
have s : ∏ i in filter prime (finset.Ico (m + 2) (2 * m + 2)), i ∣ choose (2 * m + 1) (m + 1),
140+
have s : ∏ i in filter prime (finset.Ico (m + 2) (2 * m + 2)),
141+
i ∣ choose (2 * m + 1) (m + 1),
139142
{ refine prod_primes_dvd (choose (2 * m + 1) (m + 1)) _ _,
140143
{ intros a, rw finset.mem_filter, cc, },
141144
{ intros a, rw finset.mem_filter,
142145
intros pr,
143146
rcases pr with ⟨ size, is_prime ⟩,
144147
simp only [finset.Ico.mem] at size,
145148
rcases size with ⟨ a_big , a_small ⟩,
146-
exact dvd_choose_of_middling_prime a is_prime m a_big (nat.lt_succ_iff.mp a_small), }, },
147-
have r : ∏ i in filter prime (finset.Ico (m + 2) (2 * m + 2)), i ≤ choose (2 * m + 1) (m + 1),
149+
exact dvd_choose_of_middling_prime a is_prime m a_big
150+
(nat.lt_succ_iff.mp a_small), }, },
151+
have r : ∏ i in filter prime (finset.Ico (m + 2) (2 * m + 2)),
152+
i ≤ choose (2 * m + 1) (m + 1),
148153
{ refine @nat.le_of_dvd _ _ _ s,
149154
exact @choose_pos (2 * m + 1) (m + 1) (by linarith), },
150155
exact nat.mul_le_mul_right _ r,

src/number_theory/pythagorean_triples.lean

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import tactic.field_simp
1212

1313
/-!
1414
# Pythagorean Triples
15-
The main result is the classification of pythagorean triples. The final result is for general
16-
pythagorean triples. It follows from the more interesting relatively prime case. We use the
15+
16+
The main result is the classification of Pythagorean triples. The final result is for general
17+
Pythagorean triples. It follows from the more interesting relatively prime case. We use the
1718
"rational parametrization of the circle" method for the proof. The parametrization maps the point
1819
`(x / z, y / z)` to the slope of the line through `(-1 , 0)` and `(x / z, y / z)`. This quickly
1920
shows that `(x / z, y / z) = (2 * m * n / (m ^ 2 + n ^ 2), (m ^ 2 - n ^ 2) / (m ^ 2 + n ^ 2))` where
@@ -80,7 +81,8 @@ end
8081

8182
include h
8283

83-
/-- A pythogorean triple `x, y, z` is “classified” if there exist integers `k, m, n` such that either
84+
/-- A Pythagorean triple `x, y, z` is “classified” if there exist integers `k, m, n` such that
85+
either
8486
* `x = k * (m ^ 2 - n ^ 2)` and `y = k * (2 * m * n)`, or
8587
* `x = k * (2 * m * n)` and `y = k * (m ^ 2 - n ^ 2)`. -/
8688
@[nolint unused_arguments] def is_classified := ∃ (k m n : ℤ),
@@ -177,8 +179,8 @@ begin
177179
{ apply and.intro _ co, rw one_mul, rw one_mul, tauto }
178180
end
179181

180-
lemma is_classified_of_normalize_is_primitive_classified (hc : h.normalize.is_primitive_classified) :
181-
h.is_classified :=
182+
lemma is_classified_of_normalize_is_primitive_classified
183+
(hc : h.normalize.is_primitive_classified) : h.is_classified :=
182184
begin
183185
convert h.normalize.mul_is_classified (int.gcd x y)
184186
(is_classified_of_is_primitive_classified h.normalize hc);
@@ -281,8 +283,10 @@ begin
281283
rw ← int.coe_nat_dvd_left at hp1 hp2,
282284
have h2m : (p : ℤ) ∣ 2 * m ^ 2, { convert dvd_add hp2 hp1, ring },
283285
have h2n : (p : ℤ) ∣ 2 * n ^ 2, { convert dvd_sub hp2 hp1, ring },
284-
have hmc : p = 2 ∨ p ∣ int.nat_abs m, { exact prime_two_or_dvd_of_dvd_two_mul_pow_self_two hp h2m },
285-
have hnc : p = 2 ∨ p ∣ int.nat_abs n, { exact prime_two_or_dvd_of_dvd_two_mul_pow_self_two hp h2n },
286+
have hmc : p = 2 ∨ p ∣ int.nat_abs m :=
287+
prime_two_or_dvd_of_dvd_two_mul_pow_self_two hp h2m,
288+
have hnc : p = 2 ∨ p ∣ int.nat_abs n :=
289+
prime_two_or_dvd_of_dvd_two_mul_pow_self_two hp h2n,
286290
by_cases h2 : p = 2,
287291
{ have h3 : (m ^ 2 + n ^ 2) % 2 = 1, { norm_num [pow_two, int.add_mod, int.mul_mod, hm, hn] },
288292
have h4 : (m ^ 2 + n ^ 2) % 2 = 0, { apply int.mod_eq_zero_of_dvd, rwa h2 at hp2 },
@@ -313,7 +317,7 @@ begin
313317
cases int.prime.dvd_mul hp hp2 with hp2m hpn,
314318
{ rw int.nat_abs_mul at hp2m,
315319
cases (nat.prime.dvd_mul hp).mp hp2m with hp2 hpm,
316-
{ have hp2' : p = 2, { exact le_antisymm (nat.le_of_dvd zero_lt_two hp2) (nat.prime.two_le hp) },
320+
{ have hp2' : p = 2 := (nat.le_of_dvd zero_lt_two hp2).antisymm hp.two_le,
317321
revert hp1, rw hp2',
318322
apply mt int.mod_eq_zero_of_dvd,
319323
norm_num [pow_two, int.sub_mod, int.mul_mod, hm, hn],
@@ -417,7 +421,9 @@ begin
417421
{ field_simp [hz, pow_two], norm_cast, exact h },
418422
have hvz : v ≠ 0, { field_simp [hz], exact h0 },
419423
have hw1 : w ≠ -1,
420-
{ contrapose! hvz with hw1, rw [hw1, neg_square, one_pow, add_left_eq_self] at hq, exact pow_eq_zero hq, },
424+
{ contrapose! hvz with hw1,
425+
rw [hw1, neg_square, one_pow, add_left_eq_self] at hq,
426+
exact pow_eq_zero hq, },
421427
have hQ : ∀ x : ℚ, 1 + x^20,
422428
{ intro q, apply ne_of_gt, exact lt_add_of_pos_of_le zero_lt_one (pow_two_nonneg q) },
423429
have hp : (⟨v, w⟩ : ℚ × ℚ) ∈ {p : ℚ × ℚ | p.1^2 + p.2^2 = 1 ∧ p.2 ≠ -1} := ⟨hq, hw1⟩,

src/number_theory/quadratic_reciprocity.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ have hx2 : ∀ x ∈ Ico 1 (p / 2).succ, (2 * x : zmod p).val = 2 * x,
440440
from λ x hx, have h2xp : 2 * x < p,
441441
from calc 2 * x ≤ 2 * (p / 2) : mul_le_mul_of_nonneg_left
442442
(le_of_lt_succ $ by finish) dec_trivial
443-
... < _ : by conv_rhs {rw [← div_add_mod p 2, show p % 2 = 1, from hp1]}; exact lt_succ_self _,
443+
... < _ :
444+
by conv_rhs {rw [← div_add_mod p 2, show p % 2 = 1, from hp1]}; exact lt_succ_self _,
444445
by rw [← nat.cast_two, ← nat.cast_mul, val_cast_of_lt h2xp],
445446
have hdisj : disjoint
446447
((Ico 1 (p / 2).succ).filter (λ x, p / 2 < ((2 : ℕ) * x : zmod p).val))

0 commit comments

Comments
 (0)