Blueprint

SegmentoII_SinCeros.lean · SHA-256 766db62a24ec4dccb66f6979128635b0f1b44de13e8389e28b78235acbb597f1 (of the text shown) · blueprint

Comments edited for publication; the code is unchanged.

1
/- SegmentoII_SinCeros.lean — S(m) = ∑_{n≤m} n χ(n) has no positive zero for q = 179, 227.
2
   Author: Carles Marín  <karlesmarin@gmail.com>
3
4
   χ : ℕ → ℤ completely multiplicative, χ(n) = (n | q) (Legendre, via Euler's criterion on
5
   residues) for q ∤ n, χ(q) = 1.  Kernel-checked finite certificate (cone U, rays H, set R)
6
   verified by `decide +kernel` (no `native_decide`, no `ofReduceBool`).
7
   Structure:
8
     §1  digit recursion (copied from SegmentoII.lean, `digit_recursion`, s = 1).
9
     §2  `leg`, the residue table `chain` and its soundness `chain_sound`.
10
     §3  the certificate predicate `Valid` (a decidable Prop; `check := decide Valid`),
11
         analytic lemmas: tails of the cone, the three rays, forward invariance,
12
         accepting edges, backward closure of R ∪ H.
13
     §4  `no_zero_of_valid` : Valid → ∀ m ≥ 1, S χ m ≠ 0.
14
     §5  data (untrusted: certificate lists + residue tables) and
15
         `valid179`, `valid227` by `decide +kernel`; final theorems
16
         `S_ne_zero_179`, `S_ne_zero_227`.
17
     §6  negative controls (q = 59, which has zeros; corrupted R179 / table): checker = false.
18
     §7  bridge `leg = legendreSym` (Euler's criterion, Mathlib) and non-vacuity: the explicit
19
         completely multiplicative `chi0 q` satisfies the hypotheses (`chi0_spec`); corollaries
20
         `S_ne_zero_179_legendreSym`, `S_ne_zero_227_legendreSym`, `S_chi0_ne_zero_179/227`.
21
22
   Fast-loop build:
23
     lake env lean SegmentoII_SinCeros.lean   (inside a Lean 4 + Mathlib project) -/
24
import Mathlib.NumberTheory.LegendreSymbol.Basic
25
import Mathlib.Data.Nat.Factorization.Basic
26
import Mathlib.Tactic.NormNum.Prime
27
import Mathlib.Algebra.BigOperators.Intervals
28
import Mathlib.Algebra.BigOperators.Group.Finset.Basic
29
import Mathlib.Algebra.BigOperators.Group.Finset.Lemmas
30
import Mathlib.Tactic.Ring
31
import Mathlib.Tactic.Linarith
32
import Mathlib.Tactic.Push
33
import Mathlib.Tactic.LinearCombination
34
35
open Finset
36
37
namespace SegmentoIISinCeros
38
39
/-! ## §1 Digit recursion (copied from `SegmentoII.lean`) -/
40
41
/-- `S m = ∑_{n=1}^{m} n χ(n)`. -/
42
def S (χ : ℕ → ℤ) (m : ℕ) : ℤ := ∑ n ∈ Icc 1 m, (n : ℤ) * χ n
43
44
/-- `C r = ∑_{n=1}^{r} χ(n)`. -/
45
def C (χ : ℕ → ℤ) (r : ℕ) : ℤ := ∑ n ∈ Icc 1 r, χ n
46
47
/-- `T r = ∑_{n=1}^{r} n χ(n)`. -/
48
def T (χ : ℕ → ℤ) (r : ℕ) : ℤ := ∑ n ∈ Icc 1 r, (n : ℤ) * χ n
49
50
/-- `Tq = T (q-1)`. -/
51
def Tq (χ : ℕ → ℤ) (q : ℕ) : ℤ := T χ (q - 1)
52
53
lemma S_zero (χ : ℕ → ℤ) : S χ 0 = 0 := by simp [S]
54
lemma T_zero (χ : ℕ → ℤ) : T χ 0 = 0 := by simp [T]
55
lemma C_zero (χ : ℕ → ℤ) : C χ 0 = 0 := by simp [C]
56
57
lemma S_succ (χ : ℕ → ℤ) (n : ℕ) : S χ (n + 1) = S χ n + ((n : ℤ) + 1) * χ (n + 1) := by
58
  unfold S; rw [Finset.sum_Icc_succ_top (by omega)]; push_cast; ring
59
60
lemma T_succ (χ : ℕ → ℤ) (n : ℕ) : T χ (n + 1) = T χ n + ((n : ℤ) + 1) * χ (n + 1) :=
61
  S_succ χ n
62
63
lemma C_succ (χ : ℕ → ℤ) (n : ℕ) : C χ (n + 1) = C χ n + χ (n + 1) := by
64
  unfold C; rw [Finset.sum_Icc_succ_top (by omega)]
65
66
private lemma step_r (q : ℕ) (χ : ℕ → ℤ) (s : ℤ)
67
    (hper : ∀ j r, 1 ≤ r → r < q → χ (j * q + r) = χ r) (k r : ℕ) (hr : r + 1 < q)
68
    (ih : S χ (q * k + r) = s * q * S χ k + k * (Tq χ q + q * C χ r) + T χ r) :
69
    S χ (q * k + (r + 1)) = s * q * S χ k + k * (Tq χ q + q * C χ (r + 1)) + T χ (r + 1) := by
70
  have hχ : χ (q * k + r + 1) = χ (r + 1) := by
71
    rw [mul_comm q k, add_assoc]; exact hper k (r + 1) (by omega) hr
72
  have e : q * k + (r + 1) = (q * k + r) + 1 := by omega
73
  rw [e, S_succ, C_succ, T_succ, hχ, ih]
74
  push_cast; ring
75
76
private lemma step_k (q : ℕ) (hq : 1 ≤ q) (χ : ℕ → ℤ) (s : ℤ)
77
    (hmul : ∀ a b, χ (a * b) = χ a * χ b) (hs : χ q = s) (hsum0 : C χ (q - 1) = 0) (k : ℕ)
78
    (ih : S χ (q * k + (q - 1)) = s * q * S χ k + k * (Tq χ q + q * C χ (q - 1)) + T χ (q - 1)) :
79
    S χ (q * (k + 1) + 0) = s * q * S χ (k + 1) + ((k + 1 : ℕ) : ℤ) * (Tq χ q + q * C χ 0)
80
      + T χ 0 := by
81
  have e : q * (k + 1) + 0 = (q * k + (q - 1)) + 1 := by
82
    rw [Nat.mul_succ]; omega
83
  have hχ : χ (q * k + (q - 1) + 1) = s * χ (k + 1) := by
84
    rw [← e, add_zero, hmul, hs]
85
  have hcast : ((q * k + (q - 1) : ℕ) : ℤ) + 1 = (q : ℤ) * ((k : ℤ) + 1) := by
86
    have h2 : q * k + (q - 1) + 1 = q * (k + 1) := by rw [← e, add_zero]
87
    exact_mod_cast h2
88
  have hTq : Tq χ q = T χ (q - 1) := rfl
89
  rw [e, S_succ, hχ, ih, hcast, S_succ, C_zero, T_zero, hsum0, hTq]
90
  push_cast; ring
91
92
/-- Digit recursion (SegmentoII, Theorem 1). For `r < q`:
93
`S (q*k + r) = s*q*S k + k*(Tq + q*C r) + T r`. -/
94
theorem digit_recursion (q : ℕ) (hq : 2 ≤ q) (χ : ℕ → ℤ) (s : ℤ)
95
    (hmul : ∀ a b, χ (a * b) = χ a * χ b)
96
    (hper : ∀ j r, 1 ≤ r → r < q → χ (j * q + r) = χ r)
97
    (hs : χ q = s) (hsum0 : C χ (q - 1) = 0) (k r : ℕ) (hr : r < q) :
98
    S χ (q * k + r) = s * q * S χ k + k * (Tq χ q + q * C χ r) + T χ r := by
99
  have fill : ∀ k, (S χ (q * k + 0) = s * q * S χ k + k * (Tq χ q + q * C χ 0) + T χ 0) →
100
      ∀ r, r < q → S χ (q * k + r) = s * q * S χ k + k * (Tq χ q + q * C χ r) + T χ r := by
101
    intro k h0 r
102
    induction r with
103
    | zero => intro _; exact h0
104
    | succ r ihr => intro hr; exact step_r q χ s hper k r hr (ihr (by omega))
105
  revert r
106
  induction k with
107
  | zero =>
108
    apply fill 0
109
    simp [S_zero, T_zero, C_zero]
110
  | succ k ih =>
111
    apply fill (k + 1)
112
    exact step_k q (by omega) χ s hmul hs hsum0 k (ih (q - 1) (by omega))
113
114
/-! ## §2 Computable Legendre symbol and the residue table -/
115
116
/-- Legendre symbol of a residue `x` (`0 ≤ x < q`) by Euler's criterion `x^((q-1)/2) mod q`. -/
117
def legRes (q x : ℕ) : ℤ :=
118
  if x = 0 then 0 else if Nat.pow x ((q - 1) / 2) % q = 1 then 1 else -1
119
120
/-- `leg q n = (n | q)` computed on the residue `n % q`. -/
121
def leg (q n : ℕ) : ℤ := legRes q (n % q)
122
123
lemma leg_periodic (q j r : ℕ) : leg q (j * q + r) = leg q r := by
124
  unfold leg; rw [add_comm, Nat.add_mul_mod_self_right]
125
126
/-- The table `tab` lists `(r, C r - h, T r)` for `r = r₀, r₀+1, …, q-1`, built incrementally
127
from `leg`. `chain q r d t tab = true` checks it starting at `(r, d, t)`. -/
128
def chain (q : ℕ) : ℕ → ℤ → ℤ → List (ℕ × ℤ × ℤ) → Bool
129
  | r, _, _, [] => r == q
130
  | r, d, t, (r', d', t') :: rest =>
131
      r' == r && d' == d && t' == t &&
132
        chain q (r + 1) (d + leg q (r + 1)) (t + ((r : ℤ) + 1) * leg q (r + 1)) rest
133
134
/-- Soundness of the table: every `(r, C χ r - h, T χ r)`, `r₀ ≤ r < q`, is in `tab`. -/
135
theorem chain_sound (q : ℕ) (χ : ℕ → ℤ) (hleg : ∀ n, n % q ≠ 0 → χ n = leg q n) (h : ℤ) :
136
    ∀ (l : List (ℕ × ℤ × ℤ)) (r : ℕ), chain q r (C χ r - h) (T χ r) l = true →
137
      ∀ r', r ≤ r' → r' < q → (r', C χ r' - h, T χ r') ∈ l := by
138
  intro l
139
  induction l with
140
  | nil =>
141
    intro r hc r' h1 h2
142
    simp only [chain, beq_iff_eq] at hc
143
    omega
144
  | cons x rest ih =>
145
    intro r hc r' h1 h2
146
    obtain ⟨r0, d0, t0⟩ := x
147
    simp only [chain, Bool.and_eq_true, beq_iff_eq] at hc
148
    obtain ⟨⟨⟨e1, e2⟩, e3⟩, hrest⟩ := hc
149
    rcases Nat.eq_or_lt_of_le h1 with rfl | hlt
150
    · subst e1 e2 e3; exact List.mem_cons_self ..
151
    · apply List.mem_cons_of_mem
152
      have hr1 : r + 1 < q := by omega
153
      have hχ : χ (r + 1) = leg q (r + 1) := hleg _ (by rw [Nat.mod_eq_of_lt hr1]; omega)
154
      have eC : C χ (r + 1) - h = C χ r - h + leg q (r + 1) := by rw [C_succ, hχ]; ring
155
      have eT : T χ (r + 1) = T χ r + ((r : ℤ) + 1) * leg q (r + 1) := by rw [T_succ, hχ]
156
      apply ih (r + 1) (by rw [eC, eT]; exact hrest) r' (by omega) h2
157
158
/-! ## §3 The certificate predicate and the analytic lemmas -/
159
160
/-- The cone `U = {(a,b) : b(a+b) ≤ 0}`. -/
161
abbrev inU (a b : ℤ) : Prop := b * (a + b) ≤ 0
162
163
/-- The three rays `H`. -/
164
abbrev inH (a b : ℤ) : Prop := (23 ≤ a ∧ (b = 0 ∨ b = -a)) ∨ (a ≤ -23 ∧ 2 * b = -a)
165
166
/-- `W = R ∪ H`. -/
167
abbrev inW (R : List (ℤ × ℤ)) (a b : ℤ) : Prop := (a, b) ∈ R ∨ inH a b
168
169
/-- Per-entry facts of the residue table `e = (r, D r, T r)`. -/
170
abbrev EntryOK (q : ℕ) (h P : ℤ) (c : ℕ) (e : ℕ × ℤ × ℤ) : Prop :=
171
  e.1 < q ∧
172
  (e.1 = 0 → e.2.1 = -h ∧ e.2.2 = 0) ∧
173
  (e.1 ≠ 0 → 0 < e.2.2 + P * e.1 ∧ e.2.2 - 12 * e.1 < 0) ∧
174
  (e.1 + 1 = q → e.2.1 = -h ∧ e.2.2 = -(q : ℤ) * h) ∧
175
  (e.1 + 1 ≠ q → 0 < q * e.2.1 - e.2.2 + P * ((q : ℤ) - 1 - e.1) ∧
176
      q * e.2.1 - e.2.2 - 12 * ((q : ℤ) - 1 - e.1) < 0) ∧
177
  -6 ≤ e.2.1 ∧ e.2.1 ≤ 10 ∧
178
  (e.1 = c → e.2.1 = 2 * h ∧ e.2.2 = q * h) ∧
179
  (e.1 ≠ c →
180
    (2 ≤ 2 * (e.1 : ℤ) - q + 1 ∧
181
      -(13 * (2 * (e.1 : ℤ) - q + 1 - 1)) < 2 * e.2.2 - q * e.2.1 ∧
182
      2 * e.2.2 - q * e.2.1 < 13 * (2 * (e.1 : ℤ) - q + 1 - 1)) ∨
183
    (2 * (e.1 : ℤ) - q + 1 ≤ -2 ∧
184
      -(13 * (-(2 * (e.1 : ℤ) - q + 1) - 1)) < 2 * e.2.2 - q * e.2.1 ∧
185
      2 * e.2.2 - q * e.2.1 < 13 * (-(2 * (e.1 : ℤ) - q + 1) - 1)))
186
187
/-- Strip point `(a,b)`: every integral transition stays in `U`; accepting edges are listed. -/
188
abbrev StripPt (q : ℕ) (tab : List (ℕ × ℤ × ℤ)) (padres : List (ℤ × ℤ)) (a b : ℤ) : Prop :=
189
  inU a b → ∀ e ∈ tab, (b - e.2.2 - a * e.1) % (q : ℤ) = 0 →
190
    inU (a + e.2.1) ((b - e.2.2 - a * e.1) / q) ∧
191
    (e.1 ≠ 0 → (b - e.2.2 - a * e.1) / q = 0 → (a, b) ∈ padres)
192
193
/-- The finite strip `-12 < a < P`, `|b| ≤ 11` (enough: `U` forces `b` between `0` and `-a`). -/
194
abbrev StripOK (q : ℕ) (tab : List (ℕ × ℤ × ℤ)) (padres : List (ℤ × ℤ)) (P : ℤ) : Prop :=
195
  ∀ i ∈ List.range 24, ∀ j ∈ List.range 23,
196
    -11 + (i : ℤ) < P → StripPt q tab padres (-11 + i) (-11 + j)
197
198
/-- Backward closure of `R` inside `U`: every `U`-predecessor `G_r(p)` of `p ∈ R` is in `R ∪ H`. -/
199
abbrev BackOK (q : ℕ) (tab : List (ℕ × ℤ × ℤ)) (R : List (ℤ × ℤ)) : Prop :=
200
  ∀ p ∈ R, ∀ e ∈ tab, inU (p.1 - e.2.1) (q * p.2 + e.2.2 + (p.1 - e.2.1) * e.1) →
201
    inW R (p.1 - e.2.1) (q * p.2 + e.2.2 + (p.1 - e.2.1) * e.1)
202
203
/-- The whole certificate. -/
204
abbrev Valid (q : ℕ) (h P : ℤ) (c : ℕ) (tab : List (ℕ × ℤ × ℤ)) (R padres : List (ℤ × ℤ)) :
205
    Prop :=
206
  chain q 0 (-h) 0 tab = true ∧ (∀ e ∈ tab, EntryOK q h P c e) ∧
207
  0 ≤ P ∧ P ≤ 12 ∧ 0 ≤ h ∧ 2 * c + 1 = q ∧
208
  StripOK q tab padres P ∧ (∀ p ∈ padres, inW R p.1 p.2) ∧ BackOK q tab R ∧ (0, 0) ∉ R
209
210
-- `Valid` is a 10-fold conjunction; its `Decidable` instance needs a larger synthesis budget.
211
set_option synthInstance.maxSize 4096
212
213
/-- The Bool checker is the decision procedure of `Valid`. -/
214
def check (q : ℕ) (h P : ℤ) (c : ℕ) (tab : List (ℕ × ℤ × ℤ)) (R padres : List (ℤ × ℤ)) :
215
    Bool := decide (Valid q h P c tab R padres)
216
217
theorem check_sound {q : ℕ} {h P : ℤ} {c : ℕ} {tab : List (ℕ × ℤ × ℤ)} {R padres : List (ℤ × ℤ)}
218
    (hc : check q h P c tab R padres = true) : Valid q h P c tab R padres :=
219
  of_decide_eq_true hc
220
221
lemma U_pos {a b : ℤ} (hU : inU a b) (ha : 0 ≤ a) : b ≤ 0 ∧ 0 ≤ a + b := by
222
  constructor <;> by_contra hc <;> push Not at hc <;> nlinarith
223
224
lemma U_neg {a b : ℤ} (hU : inU a b) (ha : a ≤ 0) : 0 ≤ b ∧ a + b ≤ 0 := by
225
  constructor <;> by_contra hc <;> push Not at hc <;> nlinarith
226
227
section Analytic
228
229
variable {q : ℕ} {h P : ℤ} {c : ℕ} {tab : List (ℕ × ℤ × ℤ)} {R padres : List (ℤ × ℤ)}
230
231
/-- Strip coordinates. -/
232
lemma strip_of {q : ℕ} {tab : List (ℕ × ℤ × ℤ)} {padres : List (ℤ × ℤ)} {P a b : ℤ}
233
    (hS : StripOK q tab padres P) (hP : P ≤ 12) (hU : inU a b) (h1 : -12 < a) (h2 : a < P) :
234
    StripPt q tab padres a b := by
235
  have hb : -11 ≤ b ∧ b ≤ 11 := by
236
    rcases le_total 0 a with ha | ha
237
    · have := U_pos hU ha; constructor <;> linarith
238
    · have := U_neg hU ha; constructor <;> linarith
239
  have hi : (a + 11).toNat < 24 := by omega
240
  have hj : (b + 11).toNat < 23 := by omega
241
  have ea : -11 + (((a + 11).toNat : ℕ) : ℤ) = a := by omega
242
  have eb : -11 + (((b + 11).toNat : ℕ) : ℤ) = b := by omega
243
  have := hS _ (List.mem_range.2 hi) _ (List.mem_range.2 hj) (by rw [ea]; exact h2)
244
  rwa [ea, eb] at this
245
246
lemma emod_div_of_mul {q : ℕ} (hq : 0 < q) {x y : ℤ} (hx : (q : ℤ) * y = x) :
247
    x % q = 0 ∧ x / q = y := by
248
  subst hx
249
  refine ⟨Int.mul_emod_right _ _, Int.mul_ediv_cancel_left _ (by omega)⟩
250
251
/-- Forward invariance of `U`. -/
252
theorem fwd (hV : Valid q h P c tab R padres) {r : ℕ} {d t a b b' : ℤ} (he : (r, d, t) ∈ tab)
253
    (hU : inU a b) (hstep : (q : ℤ) * b' = b - t - a * r) : inU (a + d) b' := by
254
  obtain ⟨-, hE, hP0, hP12, -, -, hS, -, -, -⟩ := hV
255
  obtain ⟨hrq, h0, h1, hlast, hmid, hd1, hd2, -, -⟩ := hE _ he
256
  simp only at hrq h0 h1 hlast hmid hd1 hd2
257
  have hq : (0 : ℤ) < q := by omega
258
  have hr0 : (0 : ℤ) ≤ r := by omega
259
  have hs0 : (0 : ℤ) ≤ (q : ℤ) - 1 - r := by omega
260
  have key : (q : ℤ) * (a + d + b') = (a + b) + a * ((q : ℤ) - 1 - r) + (q * d - t) := by
261
    linear_combination hstep
262
  by_cases hA : P ≤ a
263
  · obtain ⟨hb, hab⟩ := U_pos hU (by linarith)
264
    have hb' : b' ≤ 0 := by
265
      by_cases hr : r = 0
266
      · subst hr; obtain ⟨-, ht⟩ := h0 rfl; simp at hstep; nlinarith
267
      · obtain ⟨h1a, -⟩ := h1 hr
268
        nlinarith [mul_le_mul_of_nonneg_right hA hr0]
269
    have hsum : 0 ≤ a + d + b' := by
270
      by_cases hl : r + 1 = q
271
      · obtain ⟨hd, ht⟩ := hlast hl
272
        have : (q : ℤ) - 1 - r = 0 := by omega
273
        rw [this, hd, ht] at key; nlinarith
274
      · obtain ⟨hm, -⟩ := hmid hl
275
        nlinarith [mul_le_mul_of_nonneg_right hA hs0]
276
    show b' * (a + d + b') ≤ 0
277
    nlinarith
278
  by_cases hB : a ≤ -12
279
  · obtain ⟨hb, hab⟩ := U_neg hU (by linarith)
280
    have hb' : 0 ≤ b' := by
281
      by_cases hr : r = 0
282
      · subst hr; obtain ⟨-, ht⟩ := h0 rfl; simp at hstep; nlinarith
283
      · obtain ⟨-, h1b⟩ := h1 hr
284
        nlinarith [mul_le_mul_of_nonneg_right hB hr0]
285
    have hsum : a + d + b' ≤ 0 := by
286
      by_cases hl : r + 1 = q
287
      · obtain ⟨hd, ht⟩ := hlast hl
288
        have : (q : ℤ) - 1 - r = 0 := by omega
289
        rw [this, hd, ht] at key; nlinarith
290
      · obtain ⟨-, hm⟩ := hmid hl
291
        nlinarith [mul_le_mul_of_nonneg_right hB hs0]
292
    show b' * (a + d + b') ≤ 0
293
    nlinarith
294
  push Not at hA hB
295
  have hpt := strip_of hS hP12 hU hB hA
296
  obtain ⟨hmod, hdiv⟩ := emod_div_of_mul (by omega) hstep
297
  have := (hpt hU _ he hmod).1
298
  simp only at this
299
  rwa [hdiv] at this
300
301
/-- Accepting edges start in `R ∪ H`. -/
302
theorem acc (hV : Valid q h P c tab R padres) {r : ℕ} {d t a b : ℤ} (he : (r, d, t) ∈ tab)
303
    (hr : r ≠ 0) (hU : inU a b) (hstep : (q : ℤ) * 0 = b - t - a * r) : inW R a b := by
304
  obtain ⟨-, hE, hP0, hP12, -, -, hS, hpad, -, -⟩ := hV
305
  obtain ⟨hrq, -, h1, -, -, -, -, -, -⟩ := hE _ he
306
  simp only at hrq h1
307
  obtain ⟨h1a, h1b⟩ := h1 hr
308
  have hr0 : (0 : ℤ) ≤ r := by omega
309
  by_cases hA : P ≤ a
310
  · obtain ⟨hb, -⟩ := U_pos hU (by linarith)
311
    nlinarith [mul_le_mul_of_nonneg_right hA hr0]
312
  by_cases hB : a ≤ -12
313
  · obtain ⟨hb, -⟩ := U_neg hU (by linarith)
314
    nlinarith [mul_le_mul_of_nonneg_right hB hr0]
315
  push Not at hA hB
316
  have hpt := strip_of hS hP12 hU hB hA
317
  obtain ⟨hmod, hdiv⟩ := emod_div_of_mul (by omega) hstep
318
  have := (hpt hU _ he hmod).2 hr hdiv
319
  exact hpad _ this
320
321
/-- Backward closure of the rays `H` relative to `U`. -/
322
theorem back_H (hV : Valid q h P c tab R padres) {r : ℕ} {d t a b A B : ℤ}
323
    (he : (r, d, t) ∈ tab) (hU : inU a b) (hA : A = a + d) (hstep : (q : ℤ) * B = b - t - a * r)
324
    (hH : inH A B) : inH a b := by
325
  obtain ⟨-, hE, hP0, hP12, hh, hc, -, -, -, -⟩ := hV
326
  obtain ⟨hrq, h0, h1, hlast, hmid, hd1, hd2, hcen, hoff⟩ := hE _ he
327
  simp only at hrq h0 h1 hlast hmid hd1 hd2 hcen hoff
328
  have hr0 : (0 : ℤ) ≤ r := by omega
329
  have hs0 : (0 : ℤ) ≤ (q : ℤ) - 1 - r := by omega
330
  rcases hH with ⟨hA23, hB0 | hBA⟩ | ⟨hA23, hB2⟩
331
  · -- ray (A, 0), A ≥ 23
332
    have ha : 13 ≤ a := by linarith
333
    obtain ⟨hb, -⟩ := U_pos hU (by linarith)
334
    by_cases hr : r = 0
335
    · subst hr
336
      obtain ⟨hd, ht⟩ := h0 rfl
337
      rw [hB0, ht] at hstep; simp at hstep
338
      left; exact ⟨by linarith, Or.inl (by linarith)⟩
339
    · obtain ⟨h1a, -⟩ := h1 hr
340
      have hPa : P ≤ a := by linarith
341
      rw [hB0] at hstep
342
      nlinarith [mul_le_mul_of_nonneg_right hPa hr0]
343
  · -- ray (A, -A), A ≥ 23
344
    have ha : 13 ≤ a := by linarith
345
    obtain ⟨-, hab⟩ := U_pos hU (by linarith)
346
    have key : (0 : ℤ) = (a + b) + a * ((q : ℤ) - 1 - r) + (q * d - t) := by
347
      have : (q : ℤ) * (A + B) = 0 := by rw [hBA]; ring
348
      linear_combination hstep - this + (q : ℤ) * hA
349
    by_cases hl : r + 1 = q
350
    · obtain ⟨hd, ht⟩ := hlast hl
351
      have h3 : (q : ℤ) - 1 - r = 0 := by omega
352
      rw [h3, hd, ht] at key
353
      left; exact ⟨by linarith, Or.inr (by linarith)⟩
354
    · obtain ⟨hm, -⟩ := hmid hl
355
      have hPa : P ≤ a := by linarith
356
      nlinarith [mul_le_mul_of_nonneg_right hPa hs0]
357
  · -- middle ray (A, -A/2), A ≤ -23
358
    have ha : a ≤ -17 := by linarith
359
    obtain ⟨hb, hab⟩ := U_neg hU (by linarith)
360
    have key : a + 2 * b = a * (2 * (r : ℤ) - q + 1) + (2 * t - q * d) := by
361
      linear_combination (-2 : ℤ) * hstep - (q : ℤ) * hA + (q : ℤ) * hB2
362
    by_cases hrc : r = c
363
    · obtain ⟨hd, ht⟩ := hcen hrc
364
      have hk : 2 * (r : ℤ) - q + 1 = 0 := by subst hrc; omega
365
      rw [hk, hd, ht] at key
366
      right; exact ⟨by linarith, by linarith⟩
367
    · rcases hoff hrc with ⟨hk, hM1, hM2⟩ | ⟨hk, hM1, hM2⟩
368
      · nlinarith [mul_nonneg (by linarith : (0 : ℤ) ≤ 2 * (r : ℤ) - q + 1 - 1)
369
          (by linarith : (0 : ℤ) ≤ -(a + 13))]
370
      · nlinarith [mul_nonneg (by linarith : (0 : ℤ) ≤ -(2 * (r : ℤ) - q + 1 + 1))
371
          (by linarith : (0 : ℤ) ≤ -(a + 13))]
372
373
/-- Backward closure of `R ∪ H` relative to `U`. -/
374
theorem back (hV : Valid q h P c tab R padres) {r : ℕ} {d t a b A B : ℤ}
375
    (he : (r, d, t) ∈ tab) (hU : inU a b) (hA : A = a + d) (hstep : (q : ℤ) * B = b - t - a * r)
376
    (hW : inW R A B) : inW R a b := by
377
  rcases hW with hR | hH
378
  · have hB := hV.2.2.2.2.2.2.2.2.1 _ hR _ he
379
    simp only at hB
380
    have e1 : A - d = a := by linarith
381
    have e2 : (q : ℤ) * B + t + a * r = b := by linarith
382
    rw [e1, e2] at hB
383
    exact hB hU
384
  · exact Or.inr (back_H hV he hU hA hstep hH)
385
386
end Analytic
387
388
/-! ## §4 Valid certificate ⇒ no positive zero -/
389
390
theorem no_zero_of_valid (q : ℕ) (hq : 2 ≤ q) (χ : ℕ → ℤ)
391
    (hmul : ∀ a b, χ (a * b) = χ a * χ b)
392
    (hleg : ∀ n, n % q ≠ 0 → χ n = leg q n) (hχq : χ q = 1)
393
    {h P : ℤ} {c : ℕ} {tab : List (ℕ × ℤ × ℤ)} {R padres : List (ℤ × ℤ)}
394
    (hV : Valid q h P c tab R padres) (m : ℕ) (hm : 0 < m) : S χ m ≠ 0 := by
395
  -- the table is the true table
396
  have hmem : ∀ r, r < q → (r, C χ r - h, T χ r) ∈ tab := by
397
    intro r hr
398
    have h0 : chain q 0 (C χ 0 - h) (T χ 0) tab = true := by
399
      rw [C_zero, T_zero, zero_sub]; exact hV.1
400
    exact chain_sound q χ hleg h tab 0 h0 r (Nat.zero_le _) hr
401
  have hlastE := (hV.2.1 _ (hmem (q - 1) (by omega))).2.2.2.1 (by simp only; omega)
402
  simp only at hlastE
403
  obtain ⟨hCl, hTl⟩ := hlastE
404
  have hsum0 : C χ (q - 1) = 0 := by linarith
405
  have hper : ∀ j r, 1 ≤ r → r < q → χ (j * q + r) = χ r := by
406
    intro j r h1 h2
407
    rw [hleg _ (by rw [Nat.add_comm, Nat.add_mul_mod_self_right, Nat.mod_eq_of_lt h2]; omega),
408
      hleg _ (by rw [Nat.mod_eq_of_lt h2]; omega), leg_periodic]
409
  have hdig : ∀ j r, r < q →
410
      S χ (q * j + r) = q * S χ j + q * j * (C χ r - h) + T χ r := by
411
    intro j r hr
412
    rw [digit_recursion q hq χ 1 hmul hper hχq hsum0 j r hr, Tq, hTl]
413
    ring
414
  -- main induction
415
  have main : ∀ k, ∀ a b : ℤ, inU a b → ¬ inW R a b → S χ k + a * k = b → 0 < k → False := by
416
    intro k
417
    induction k using Nat.strong_induction_on with
418
    | _ k ih =>
419
      intro a b hU hW hk hpos
420
      have hk' : q * (k / q) + k % q = k := Nat.div_add_mod k q
421
      have hrq : k % q < q := Nat.mod_lt _ (by omega)
422
      set j := k / q with hj
423
      set r := k % q with hr
424
      set d := C χ r - h
425
      set t := T χ r
426
      have he : (r, d, t) ∈ tab := hmem r hrq
427
      set b' := S χ j + (a + d) * j with hb'
428
      have hcast : (k : ℤ) = q * j + r := by exact_mod_cast hk'.symm
429
      have hSk : S χ k = q * S χ j + q * j * d + t := by rw [← hk']; exact hdig j r hrq
430
      have hstep : (q : ℤ) * b' = b - t - a * r := by
431
        rw [← hk, hSk, hcast, hb']; ring
432
      have hU' : inU (a + d) b' := fwd hV he hU hstep
433
      rcases Nat.eq_zero_or_pos j with hj0 | hjpos
434
      · have hb0 : b' = 0 := by rw [hb', hj0]; simp [S_zero]
435
        have hr0 : r ≠ 0 := by
436
          intro h0; rw [hj0, h0] at hk'; omega
437
        rw [hb0] at hstep
438
        exact hW (acc hV he hr0 hU hstep)
439
      · have hjk : j < k := Nat.div_lt_self hpos (by omega)
440
        refine ih j hjk (a + d) b' hU' ?_ rfl hjpos
441
        intro hW'
442
        exact hW (back hV he hU rfl hstep hW')
443
  intro hS0
444
  refine main m 0 0 (by simp) ?_ (by simp [hS0]) hm
445
  rintro (h00 | hH)
446
  · exact hV.2.2.2.2.2.2.2.2.2 h00
447
  · rcases hH with ⟨h1, -⟩ | ⟨h1, -⟩ <;> omega
448
449
/-! ## §5 Data (untrusted) and the kernel-checked certificates -/
450
451
-- Certificate data (computed by a backward search outside this file).
452
-- Untrusted witness: checked by the kernel below.
453
def R179 : List (Int × Int) := [(-22, 11), (-20, 10), (-16, 8), (-14, 7), (-12, 6), (-10, 5), (-9, 1), (-9, 2), (-9, 7), (-9, 8), (-8, 1), (-8, 7), (-7, 1), (-7, 6), (-6, 1), (-6, 3), (-4, 2), (-3, 0), (-3, 1), (-3, 2), (-2, 1), (-2, 2), (-1, 0), (1, -1), (1, 0), (2, -2), (2, 0), (3, -3), (4, 0), (5, -5), (6, -6), (6, 0), (7, -7), (7, 0), (8, -8), (9, 0), (10, -10), (11, -11), (11, 0), (12, -12), (12, 0), (13, -13), (14, 0), (15, -15), (16, -16), (16, 0), (17, -17), (17, 0), (18, -18), (19, 0), (20, -20), (21, -21), (21, 0), (22, -22), (22, 0)]
454
def padres179 : List (Int × Int) := [(-10, 5), (-6, 1), (-4, 2), (-3, 0), (-3, 2), (-2, 1), (-2, 2), (-1, 0), (1, -1), (1, 0), (2, -2), (2, 0), (5, -5)]
455
def R227 : List (Int × Int) := [(-20, 2), (-20, 10), (-20, 18), (-19, 0), (-19, 19), (-18, 0), (-18, 9), (-18, 18), (-16, 8), (-15, 2), (-15, 4), (-15, 5), (-15, 10), (-15, 11), (-15, 13), (-14, 0), (-14, 7), (-14, 14), (-13, 0), (-13, 13), (-11, 2), (-11, 9), (-10, 4), (-10, 5), (-10, 6), (-9, 0), (-9, 2), (-9, 7), (-9, 9), (-8, 0), (-8, 4), (-8, 8), (-7, 1), (-7, 3), (-7, 4), (-7, 6), (-6, 2), (-6, 3), (-6, 4), (-4, 0), (-4, 4), (-3, 0), (-3, 1), (-3, 2), (-3, 3), (-2, 0), (-2, 2), (-1, 0), (1, -1), (1, 0), (2, -2), (2, -1), (2, 0), (3, -3), (3, -2), (3, -1), (3, 0), (4, 0), (5, -5), (5, -4), (5, -1), (6, -6), (6, 0), (7, -7), (7, -6), (7, -4), (7, -3), (7, -1), (7, 0), (8, -8), (8, 0), (9, -5), (9, -4), (9, 0), (10, -10), (11, -11), (11, -10), (11, -8), (11, -3), (11, -1), (11, 0), (12, -12), (12, -10), (12, -6), (12, -2), (12, 0), (13, -13), (13, -12), (13, -1), (13, 0), (14, -12), (14, -2), (14, 0), (15, -15), (15, -9), (15, -8), (15, -7), (15, -6), (16, -16), (16, 0), (17, -17), (17, -11), (17, -6), (17, 0), (18, -18), (18, -11), (18, -7), (18, 0), (19, -14), (19, -5), (19, 0), (20, -20), (21, -21), (21, 0), (22, -22), (22, -19), (22, -16), (22, -12), (22, -10), (22, -6), (22, -3), (22, 0), (25, -17), (25, -8), (26, -18), (26, -16), (26, -10), (26, -8), (27, -17), (27, -10), (30, -26), (30, -4), (33, -27), (33, -6), (34, -31), (34, -3), (39, -35), (39, -4), (42, -39), (42, -28), (42, -14), (42, -3), (43, -38), (43, -33), (43, -10), (43, -5), (45, -42), (45, -39), (45, -6), (45, -3), (47, -43), (47, -29), (47, -18), (47, -4), (48, -37), (48, -28), (48, -20), (48, -11), (51, -48), (51, -3), (52, -31), (52, -21)]
456
def padres227 : List (Int × Int) := [(-10, 5), (-7, 1), (-6, 2), (-6, 3), (-3, 0), (-3, 1), (-2, 2), (-1, 0), (5, -5), (7, -4)]
457
458
-- Residue tables (r, C r - h, T r), 0 <= r < q, h = 5. Untrusted: checked by `chain`.
459
def tab179 : List (ℕ × ℤ × ℤ) := [(0, -5, 0), (1, -4, 1), (2, -5, -1), (3, -4, 2), (4, -3, 6), (5, -2, 11), (6, -3, 5), (7, -4, -2), (8, -5, -10), (9, -4, -1), (10, -5, -11), (11, -6, -22), (12, -5, -10), (13, -4, 3), (14, -3, 17), (15, -2, 32), (16, -1, 48), (17, 0, 65), (18, -1, 47), (19, 0, 66), (20, 1, 86), (21, 0, 65), (22, 1, 87), (23, 0, 64), (24, -1, 40), (25, 0, 65), (26, -1, 39), (27, 0, 66), (28, -1, 38), (29, 0, 67), (30, -1, 37), (31, 0, 68), (32, -1, 36), (33, -2, 3), (34, -3, -31), (35, -4, -66), (36, -3, -30), (37, -4, -67), (38, -5, -105), (39, -4, -66), (40, -5, -106), (41, -6, -147), (42, -5, -105), (43, -4, -62), (44, -5, -106), (45, -4, -61), (46, -3, -15), (47, -2, 32), (48, -1, 80), (49, 0, 129), (50, -1, 79), (51, 0, 130), (52, 1, 182), (53, 0, 129), (54, -1, 75), (55, -2, 20), (56, -1, 76), (57, 0, 133), (58, -1, 75), (59, 0, 134), (60, 1, 194), (61, 2, 255), (62, 1, 193), (63, 0, 130), (64, 1, 194), (65, 2, 259), (66, 3, 325), (67, 4, 392), (68, 5, 460), (69, 4, 391), (70, 5, 461), (71, 4, 390), (72, 3, 318), (73, 2, 245), (74, 3, 319), (75, 4, 394), (76, 5, 470), (77, 6, 547), (78, 5, 469), (79, 4, 390), (80, 5, 470), (81, 6, 551), (82, 7, 633), (83, 8, 716), (84, 7, 632), (85, 8, 717), (86, 7, 631), (87, 8, 718), (88, 9, 806), (89, 10, 895), (90, 9, 805), (91, 8, 714), (92, 7, 622), (93, 8, 715), (94, 7, 621), (95, 8, 716), (96, 7, 620), (97, 6, 523), (98, 5, 425), (99, 4, 326), (100, 5, 426), (101, 6, 527), (102, 5, 425), (103, 4, 322), (104, 3, 218), (105, 2, 113), (106, 3, 219), (107, 4, 326), (108, 5, 434), (109, 4, 325), (110, 5, 435), (111, 4, 324), (112, 3, 212), (113, 2, 99), (114, 1, -15), (115, 0, -130), (116, 1, -14), (117, 2, 103), (118, 1, -15), (119, 0, -134), (120, -1, -254), (121, 0, -133), (122, -1, -255), (123, -2, -378), (124, -1, -254), (125, 0, -129), (126, 1, -3), (127, 0, -130), (128, -1, -258), (129, 0, -129), (130, -1, -259), (131, -2, -390), (132, -3, -522), (133, -4, -655), (134, -5, -789), (135, -4, -654), (136, -5, -790), (137, -6, -927), (138, -5, -789), (139, -4, -650), (140, -5, -790), (141, -4, -649), (142, -3, -507), (143, -4, -650), (144, -3, -506), (145, -2, -361), (146, -1, -215), (147, 0, -68), (148, -1, -216), (149, 0, -67), (150, -1, -217), (151, 0, -66), (152, -1, -218), (153, 0, -65), (154, -1, -219), (155, 0, -64), (156, 1, 92), (157, 0, -65), (158, 1, 93), (159, 0, -66), (160, -1, -226), (161, 0, -65), (162, -1, -227), (163, -2, -390), (164, -3, -554), (165, -4, -719), (166, -5, -885), (167, -6, -1052), (168, -5, -884), (169, -4, -715), (170, -5, -885), (171, -4, -714), (172, -3, -542), (173, -2, -369), (174, -3, -543), (175, -4, -718), (176, -5, -894), (177, -4, -717), (178, -5, -895)]
460
def tab227 : List (ℕ × ℤ × ℤ) := [(0, -5, 0), (1, -4, 1), (2, -5, -1), (3, -4, 2), (4, -3, 6), (5, -4, 1), (6, -5, -5), (7, -4, 2), (8, -5, -6), (9, -4, 3), (10, -3, 13), (11, -2, 24), (12, -1, 36), (13, -2, 23), (14, -3, 9), (15, -4, -6), (16, -3, 10), (17, -4, -7), (18, -5, -25), (19, -4, -6), (20, -5, -26), (21, -4, -5), (22, -5, -27), (23, -4, -4), (24, -5, -28), (25, -4, -3), (26, -3, 23), (27, -2, 50), (28, -1, 78), (29, 0, 107), (30, 1, 137), (31, 0, 106), (32, -1, 74), (33, 0, 107), (34, 1, 141), (35, 0, 106), (36, 1, 142), (37, 0, 105), (38, -1, 67), (39, -2, 28), (40, -1, 68), (41, -2, 27), (42, -3, -15), (43, -2, 28), (44, -1, 72), (45, -2, 27), (46, -3, -19), (47, -2, 28), (48, -1, 76), (49, 0, 125), (50, -1, 75), (51, -2, 24), (52, -3, -28), (53, -2, 25), (54, -3, -29), (55, -4, -84), (56, -5, -140), (57, -4, -83), (58, -5, -141), (59, -4, -82), (60, -5, -142), (61, -6, -203), (62, -5, -141), (63, -4, -78), (64, -3, -14), (65, -2, 51), (66, -3, -15), (67, -4, -82), (68, -5, -150), (69, -4, -81), (70, -3, -11), (71, -2, 60), (72, -3, -12), (73, -2, 61), (74, -1, 135), (75, 0, 210), (76, 1, 286), (77, 2, 363), (78, 3, 441), (79, 4, 520), (80, 3, 440), (81, 4, 521), (82, 5, 603), (83, 4, 520), (84, 5, 604), (85, 6, 689), (86, 5, 603), (87, 6, 690), (88, 5, 602), (89, 6, 691), (90, 7, 781), (91, 6, 690), (92, 7, 782), (93, 6, 689), (94, 5, 595), (95, 4, 500), (96, 3, 404), (97, 4, 501), (98, 3, 403), (99, 4, 502), (100, 5, 602), (101, 6, 703), (102, 7, 805), (103, 8, 908), (104, 9, 1012), (105, 8, 907), (106, 7, 801), (107, 6, 694), (108, 7, 802), (109, 8, 911), (110, 9, 1021), (111, 8, 910), (112, 9, 1022), (113, 10, 1135), (114, 9, 1021), (115, 8, 906), (116, 9, 1022), (117, 8, 905), (118, 7, 787), (119, 6, 668), (120, 7, 788), (121, 8, 909), (122, 9, 1031), (123, 8, 908), (124, 7, 784), (125, 6, 659), (126, 5, 533), (127, 4, 406), (128, 3, 278), (129, 4, 407), (130, 3, 277), (131, 4, 408), (132, 5, 540), (133, 6, 673), (134, 7, 807), (135, 6, 672), (136, 7, 808), (137, 6, 671), (138, 5, 533), (139, 6, 672), (140, 5, 532), (141, 6, 673), (142, 5, 531), (143, 4, 388), (144, 5, 532), (145, 4, 387), (146, 3, 241), (147, 4, 388), (148, 3, 240), (149, 2, 91), (150, 1, -59), (151, 0, -210), (152, -1, -362), (153, -2, -515), (154, -3, -669), (155, -2, -514), (156, -3, -670), (157, -4, -827), (158, -5, -985), (159, -4, -826), (160, -3, -666), (161, -2, -505), (162, -3, -667), (163, -4, -830), (164, -5, -994), (165, -6, -1159), (166, -5, -993), (167, -4, -826), (168, -5, -994), (169, -4, -825), (170, -5, -995), (171, -4, -824), (172, -3, -652), (173, -2, -479), (174, -3, -653), (175, -2, -478), (176, -1, -302), (177, 0, -125), (178, -1, -303), (179, -2, -482), (180, -3, -662), (181, -2, -481), (182, -1, -299), (183, -2, -482), (184, -3, -666), (185, -2, -481), (186, -1, -295), (187, -2, -482), (188, -1, -294), (189, 0, -105), (190, 1, 85), (191, 0, -106), (192, 1, 86), (193, 0, -107), (194, -1, -301), (195, 0, -106), (196, 1, 90), (197, 0, -107), (198, -1, -305), (199, -2, -504), (200, -3, -704), (201, -4, -905), (202, -5, -1107), (203, -4, -904), (204, -5, -1108), (205, -4, -903), (206, -5, -1109), (207, -4, -902), (208, -5, -1110), (209, -4, -901), (210, -3, -691), (211, -4, -902), (212, -3, -690), (213, -2, -477), (214, -1, -263), (215, -2, -478), (216, -3, -694), (217, -4, -911), (218, -5, -1129), (219, -4, -910), (220, -5, -1130), (221, -4, -909), (222, -3, -687), (223, -4, -910), (224, -5, -1134), (225, -4, -909), (226, -5, -1135)]
461
462
theorem valid179 : Valid 179 5 7 89 tab179 R179 padres179 := by decide +kernel
463
464
theorem valid227 : Valid 227 5 8 113 tab227 R227 padres227 := by decide +kernel
465
466
/-- **No positive zero, q = 179.** -/
467
theorem S_ne_zero_179 (χ : ℕ → ℤ) (hmul : ∀ a b, χ (a * b) = χ a * χ b)
468
    (hleg : ∀ n, n % 179 ≠ 0 → χ n = leg 179 n) (hq : χ 179 = 1) (m : ℕ) (hm : 1 ≤ m) :
469
    S χ m ≠ 0 :=
470
  no_zero_of_valid 179 (by omega) χ hmul hleg hq valid179 m hm
471
472
/-- **No positive zero, q = 227.** -/
473
theorem S_ne_zero_227 (χ : ℕ → ℤ) (hmul : ∀ a b, χ (a * b) = χ a * χ b)
474
    (hleg : ∀ n, n % 227 ≠ 0 → χ n = leg 227 n) (hq : χ 227 = 1) (m : ℕ) (hm : 1 ≤ m) :
475
    S χ m ≠ 0 :=
476
  no_zero_of_valid 227 (by omega) χ hmul hleg hq valid227 m hm
477
478
/-! ## §6 Negative controls: the checker can fail
479
`q = 59` has positive zeros; its honest backward set `R59` (own search, |R| = 43)
480
contains the origin, and deleting the origin breaks closure.
481
Corrupting one point of `R179` or one table entry also makes the checker answer `false`. -/
482
483
-- Control data for q = 59 (own backward search).
484
def tab59 : List (ℕ × ℤ × ℤ) := [(0, -3, 0), (1, -2, 1), (2, -3, -1), (3, -2, 2), (4, -1, 6), (5, 0, 11), (6, -1, 5), (7, 0, 12), (8, -1, 4), (9, 0, 13), (10, -1, 3), (11, -2, -8), (12, -1, 4), (13, -2, -9), (14, -3, -23), (15, -2, -8), (16, -1, 8), (17, 0, 25), (18, -1, 7), (19, 0, 26), (20, 1, 46), (21, 2, 67), (22, 3, 89), (23, 2, 66), (24, 1, 42), (25, 2, 67), (26, 3, 93), (27, 4, 120), (28, 5, 148), (29, 6, 177), (30, 5, 147), (31, 4, 116), (32, 3, 84), (33, 2, 51), (34, 1, 17), (35, 2, 52), (36, 3, 88), (37, 2, 51), (38, 1, 13), (39, 0, -26), (40, -1, -66), (41, 0, -25), (42, -1, -67), (43, -2, -110), (44, -3, -154), (45, -2, -109), (46, -1, -63), (47, -2, -110), (48, -1, -62), (49, 0, -13), (50, -1, -63), (51, 0, -12), (52, -1, -64), (53, 0, -11), (54, -1, -65), (55, -2, -120), (56, -3, -176), (57, -2, -119), (58, -3, -177)]
485
def R59 : List (ℤ × ℤ) := [(-20, 10), (-18, 9), (-14, 7), (-12, 6), (-8, 4), (-6, 0), (-6, 3), (-5, 5), (-4, 1), (-3, 0), (-2, 1), (-2, 2), (-1, 0), (0, 0), (1, -1), (2, 0), (3, -3), (3, 0), (4, -4), (5, 0), (6, -6), (6, 0), (7, -7), (8, 0), (9, -9), (9, 0), (10, -10), (11, 0), (12, -12), (12, 0), (13, -13), (14, 0), (15, -15), (15, 0), (16, -16), (17, 0), (18, -18), (18, 0), (19, -19), (20, 0), (21, -21), (21, 0), (22, -22)]
486
def padres59 : List (ℤ × ℤ) := [(-6, 3), (-4, 1), (-2, 1), (-1, 0), (3, -3)]
487
488
example : check 59 3 4 29 tab59 R59 padres59 = false := by decide +kernel
489
example : check 59 3 4 29 tab59 (R59.erase (0, 0)) padres59 = false := by decide +kernel
490
example : check 179 5 7 89 tab179 (R179.erase (-22, 11)) padres179 = false := by decide +kernel
491
example : check 179 5 7 89 (tab179.set 5 (5, -1, 0)) R179 padres179 = false := by decide +kernel
492
493
/-! ## §7 Bridge to Mathlib's `legendreSym`, and non-vacuity -/
494
495
/-- `leg` is Mathlib's Legendre symbol off the multiples of `q` (Euler's criterion). -/
496
theorem leg_eq_legendreSym (q : ℕ) [hq : Fact q.Prime] (hq2 : q ≠ 2) (n : ℕ) (hn : n % q ≠ 0) :
497
    leg q n = legendreSym q n := by
498
  have hq1 : 2 < q := lt_of_le_of_ne hq.out.two_le (Ne.symm hq2)
499
  haveI : Fact (2 < q) := ⟨hq1⟩
500
  have hodd : (q - 1) / 2 = q / 2 := by
501
    rcases hq.out.eq_two_or_odd' with h | ⟨k, hk⟩
502
    · exact absurd h hq2
503
    · omega
504
  set x := n % q with hx
505
  have hxq : x < q := Nat.mod_lt _ (by omega)
506
  have hL : legendreSym q n = legendreSym q x := by
507
    rw [legendreSym.mod q (n : ℤ), hx]; push_cast; rfl
508
  have hx0 : ((x : ℤ) : ZMod q) ≠ 0 := by
509
    intro h
510
    have : ((x : ℕ) : ZMod q) = 0 := by exact_mod_cast h
511
    rw [ZMod.natCast_eq_zero_iff] at this
512
    exact hn (Nat.eq_zero_of_dvd_of_lt this hxq)
513
  have hpow := legendreSym.eq_pow q (x : ℤ)
514
  have hcast : ((x : ℤ) : ZMod q) ^ (q / 2) = ((x ^ (q / 2) : ℕ) : ZMod q) := by push_cast; rfl
515
  rw [hcast] at hpow
516
  unfold leg legRes
517
  rw [← hx, if_neg hn, hL, hodd]
518
  change (if x ^ (q / 2) % q = 1 then (1 : ℤ) else -1) = _
519
  rcases legendreSym.eq_one_or_neg_one q hx0 with h1 | h1
520
  · rw [h1] at hpow ⊢
521
    have : ((1 : ℕ) : ZMod q) = ((x ^ (q / 2) : ℕ) : ZMod q) := by push_cast at hpow ⊢; exact hpow
522
    rw [ZMod.natCast_eq_natCast_iff', Nat.mod_eq_of_lt (by omega : 1 < q)] at this
523
    rw [if_pos this.symm]
524
  · rw [h1] at hpow ⊢
525
    rw [if_neg]
526
    intro h
527
    have : ((x ^ (q / 2) : ℕ) : ZMod q) = ((1 : ℕ) : ZMod q) := by
528
      rw [ZMod.natCast_eq_natCast_iff', h, Nat.mod_eq_of_lt (by omega : 1 < q)]
529
    rw [← hpow] at this
530
    push_cast at this
531
    exact ZMod.neg_one_ne_one this
532
533
/-- The completely multiplicative extension: `χ₀ n = leg q (n / q^{v_q(n)})`, `χ₀ 0 = 0`. -/
534
def chi0 (q n : ℕ) : ℤ := if n = 0 then 0 else leg q (ordCompl[q] n)
535
536
/-- Non-vacuity: `chi0 q` satisfies the hypotheses of the main theorem. -/
537
theorem chi0_spec (q : ℕ) [hq : Fact q.Prime] (hq2 : q ≠ 2) :
538
    (∀ a b, chi0 q (a * b) = chi0 q a * chi0 q b) ∧
539
    (∀ n, n % q ≠ 0 → chi0 q n = leg q n) ∧ chi0 q q = 1 := by
540
  have hp := hq.out
541
  have hlegmul : ∀ a b, ¬ q ∣ a → ¬ q ∣ b → leg q (a * b) = leg q a * leg q b := by
542
    intro a b ha hb
543
    have hab : ¬ q ∣ a * b := fun h => (hp.dvd_mul.1 h).elim ha hb
544
    rw [leg_eq_legendreSym q hq2 _ (fun h => hab (Nat.dvd_of_mod_eq_zero h)),
545
      leg_eq_legendreSym q hq2 _ (fun h => ha (Nat.dvd_of_mod_eq_zero h)),
546
      leg_eq_legendreSym q hq2 _ (fun h => hb (Nat.dvd_of_mod_eq_zero h))]
547
    push_cast
548
    exact legendreSym.mul q _ _
549
  refine ⟨?_, ?_, ?_⟩
550
  · intro a b
551
    rcases Nat.eq_zero_or_pos a with rfl | ha
552
    · simp [chi0]
553
    rcases Nat.eq_zero_or_pos b with rfl | hb
554
    · simp [chi0]
555
    unfold chi0
556
    rw [if_neg (by positivity), if_neg (by omega), if_neg (by omega), Nat.ordCompl_mul]
557
    exact hlegmul _ _ (Nat.not_dvd_ordCompl hp (by omega)) (Nat.not_dvd_ordCompl hp (by omega))
558
  · intro n hn
559
    have hn0 : n ≠ 0 := by rintro rfl; simp at hn
560
    unfold chi0
561
    rw [if_neg hn0, (Nat.ordCompl_eq_self_iff_zero_or_not_dvd n hp).2
562
      (Or.inr (fun h => hn (Nat.mod_eq_zero_of_dvd h)))]
563
  · unfold chi0
564
    rw [if_neg hp.ne_zero]
565
    have : ordCompl[q] q = 1 := by simpa using Nat.ordCompl_self_pow (k := 1) hp
566
    rw [this, leg_eq_legendreSym q hq2 1 (by rw [Nat.mod_eq_of_lt hp.one_lt]; omega)]
567
    simp [legendreSym.at_one]
568
569
instance : Fact (Nat.Prime 179) := ⟨by norm_num⟩
570
instance : Fact (Nat.Prime 227) := ⟨by norm_num⟩
571
572
/-- **No positive zero, q = 179**, stated with Mathlib's `legendreSym`. -/
573
theorem S_ne_zero_179_legendreSym (χ : ℕ → ℤ) (hmul : ∀ a b, χ (a * b) = χ a * χ b)
574
    (hleg : ∀ n : ℕ, ¬ 179 ∣ n → χ n = legendreSym 179 n) (hq : χ 179 = 1) (m : ℕ)
575
    (hm : 1 ≤ m) : S χ m ≠ 0 :=
576
  S_ne_zero_179 χ hmul (fun n hn => by
577
    rw [hleg n (fun h => hn (Nat.mod_eq_zero_of_dvd h)), leg_eq_legendreSym 179 (by omega) n hn])
578
    hq m hm
579
580
/-- **No positive zero, q = 227**, stated with Mathlib's `legendreSym`. -/
581
theorem S_ne_zero_227_legendreSym (χ : ℕ → ℤ) (hmul : ∀ a b, χ (a * b) = χ a * χ b)
582
    (hleg : ∀ n : ℕ, ¬ 227 ∣ n → χ n = legendreSym 227 n) (hq : χ 227 = 1) (m : ℕ)
583
    (hm : 1 ≤ m) : S χ m ≠ 0 :=
584
  S_ne_zero_227 χ hmul (fun n hn => by
585
    rw [hleg n (fun h => hn (Nat.mod_eq_zero_of_dvd h)), leg_eq_legendreSym 227 (by omega) n hn])
586
    hq m hm
587
588
/-- The hypotheses are satisfiable: the theorem applies to the explicit `chi0 179`. -/
589
theorem S_chi0_ne_zero_179 (m : ℕ) (hm : 1 ≤ m) : S (chi0 179) m ≠ 0 :=
590
  let h := chi0_spec 179 (by omega)
591
  S_ne_zero_179 _ h.1 h.2.1 h.2.2 m hm
592
593
/-- The hypotheses are satisfiable: the theorem applies to the explicit `chi0 227`. -/
594
theorem S_chi0_ne_zero_227 (m : ℕ) (hm : 1 ≤ m) : S (chi0 227) m ≠ 0 :=
595
  let h := chi0_spec 227 (by omega)
596
  S_ne_zero_227 _ h.1 h.2.1 h.2.2 m hm
597
598
end SegmentoIISinCeros
599
600
#print axioms SegmentoIISinCeros.no_zero_of_valid
601
#print axioms SegmentoIISinCeros.valid179
602
#print axioms SegmentoIISinCeros.valid227
603
#print axioms SegmentoIISinCeros.S_ne_zero_179
604
#print axioms SegmentoIISinCeros.S_ne_zero_227
605
#print axioms SegmentoIISinCeros.leg_eq_legendreSym
606
#print axioms SegmentoIISinCeros.chi0_spec
607
#print axioms SegmentoIISinCeros.S_ne_zero_179_legendreSym
608
#print axioms SegmentoIISinCeros.S_ne_zero_227_legendreSym
609
#print axioms SegmentoIISinCeros.S_chi0_ne_zero_179
610
#print axioms SegmentoIISinCeros.S_chi0_ne_zero_227