# Numerical supplement to "Every even integer greater than 2 is a prime plus a product of at most 18 primes" This supplement, the anc/ directory of the record, holds every program and output behind the numerical statements of the paper (built from the TeX sources in the parent directory). The paper proves three results: - Theorem 1: at most 18 prime factors; - Theorem 2: at most 14, assuming that no Dirichlet L-function vanishes in Re s > 7/8; - Theorem 3: at most 9, under the generalised Riemann hypothesis. run_all.sh.txt (a bash script: run it with bash) reruns everything and compare.py checks the result. REPRODUCTION.md records a complete run, and SHA256SUMS.txt gives the SHA-256 hash of every file. The archive accepts only certain file types, so the stored text outputs in expected/ carry an extra .txt extension: expected/second/cert_C4.out.txt is the stored second/cert_C4.out, and so on. ## Contents | Directory | Contents | Arithmetic | |---|---|---| | author/ | cert_C3s.py (Lemma 6), with its helpers cert_C2.py and cert_C3.py (the coefficients of Lemma 4); cert_C3s_v7.py, the driver that prints the rows of Lemma 7 and two values used in remarks; cert_qrh_range.py (the margin of Lemma 20, imported by second/); fF_enclose.py (Appendix B's f and F) | mpmath iv, outward-rounded; fF_enclose.py uses python-flint | | second/ | cert_C3.py (Lemma 7), cert_C4.py (Lemma 10), cert_S4.py (Lemma 16, rational cells), cert_qrhB3.py and cert_qrhB3p.py (the grids of Theorem 2) | Arb via python-flint; direct float convolutions with relative-error inflation | | third/js_cert/ | tp_bound.py (the twin-prime constant), js_cert.py (the coefficient of (I4')) | mpmath iv | | third/t2_check/ | cert_S3P_K18.py (Lemma 16, the certificate of record), c3_grh.py (Lemmas 7 and 23), cert_grh_sieve.py (Lemma 25) | mpmath iv; direct float convolutions with inflation | | audit/ | audit_js.py (an independent audit of the coefficient of (I4')), independent_check.py (its helper), js_uniform.py (input to an older chain that audit_js.py reruns) | Arb (256-bit) | | audit/t2v6/ | audit_c4.py, audit_s4.py, audit_grh9.py, audit_v6.py, check_float_cells.py: independent audits of Lemmas 7, 10, 16, 23 and 25, of the 950 grid rows of Theorem 2 and of every float cell weight; frozen/second/: the two grid parameter files, as copied for the audit | Arb (256-bit) | | expected/ | the stored outputs that the paper quotes, in the same layout as a run | | The scripts under audit/ were written separately from the certificates and recompute the same quantities by other methods. The paper's computations section says which implementation certifies each step. **Code.** The code of every script is the code that produced the stored outputs, with these exceptions: - the file paths follow this layout: the grid scripts import ../author/cert_qrh_range.py, and audit/t2v6/audit_v6.py reads frozen/second/; - one descriptive string in a function that the supplement does not run has been reworded. Docstrings and comments were edited for publication, and they describe what each script certifies. **How the stored outputs were made.** They are the outputs of the runs behind the paper, renamed to the commands below, with two exceptions: - author/cert_C3s_v7.out comes from the driver; - second/cert_C3_e62.out is cert_C3.py at (e^62, 9), and agrees with an earlier run at the same parameters (< 0.24143871). **The grid parameter files.** audit/t2v6/frozen/second/*.json are second/'s grid files, as copied for the audit before a display change. They agree with expected/second/*.json in every endpoint and every parameter (M, lambda). They differ only in the last digits of the displayed float margins (relative difference at most 3.4·10⁻¹⁶). audit_v6.py uses those floats only to choose which rows its report samples; it recomputes every margin in Arb. **Where the hypotheses of Lemma 20 are checked (Theorem 2's grids).** - author/cert_qrh_range.py's `margin_iv` checks the conditions on M, L1, lambda, H, s1, s2, F(s1) and the V factors. Of the conditions on z1 it checks only z1 >= 694 and z1^(M-1) = N/z >= 10372. - The condition z1 >= 10372 is applied by second/cert_qrhB3.py and second/cert_qrhB3p.py themselves. Their search stops below log 10372 + 0.01, and an Arb assertion z1 > 10372 holds on every interval. - The condition z1 >= 8·10⁹ is asserted in Arb by second/cert_qrhB3p.py, inside `bad_up`, on every interval of the top grid. **An older chain.** audit/js_uniform.py evaluates an older whole-tail chain that used a misprinted definition. It is kept only because audit_js.py reruns that chain with the corrected exponent; it is not a certificate of (I4'). ## How to run PY=/path/to/python bash run_all.sh.txt [OUTDIR] PY must have mpmath, numpy and python-flint (`pip install mpmath numpy python-flint`). - **What it does.** run_all.sh.txt copies the code tree into OUTDIR (default ./out), because some scripts read and write files next to themselves. It then runs the 20 steps below single-threaded, at nice 10 where available, and finally runs compare.py. - **What compare.py checks.** - (1) It compares every output with expected/: text line by line, ignoring blank lines and `#` header lines; JSON value by value. - (2) It checks each numerical statement of the paper in the fresh outputs, by parsing the printed enclosures and comparing them with the paper's displayed bounds as exact decimals. - It prints `ALL REPRODUCED` and exits 0 only if everything passes. | Step | Command (in OUTDIR/...) | Writes | |---|---|---| | 1 | author/cert_C3s_v7.py | cert_C3s_v7.out | | 2 | author/fF_enclose.py | fF_enclose.out | | 3 | second/cert_C3.py 1800 4e18 0.2 18 | cert_C3_e1800.out | | 4 | second/cert_C3.py 350 4e18 0.2 13 14 16 | cert_C3_e350.out | | 5 | second/cert_C3.py 62 4e18 0.2 9 | cert_C3_e62.out | | 6 | second/cert_C4.py 2736.86 1800 0.02 0.02 17 18 | cert_C4.out | | 7 | second/cert_S4.py 400 0.01 17 18 | cert_S4_H400.out | | 8 | second/cert_qrhB3.py 14 350 51046 1.01 0.05 200 | cert_qrhB3_K14_low.out, cert_qrhB3_K14_350_51046.json | | 9 | second/cert_qrhB3p.py 14 51046 159011874857757 1.05 0.05 200 | cert_qrhB3p_K14_top.out, cert_qrhB3p_K14_51046_159011874857757.json | | 10 | third/js_cert/tp_bound.py | tp_bound.out | | 11 | third/js_cert/js_cert.py | js_cert.out, js_cert.json | | 12 | third/t2_check/cert_S3P_K18.py | cert_S3P_K18.out | | 13 | third/t2_check/c3_grh.py | c3_grh.out | | 14 | third/t2_check/cert_grh_sieve.py | cert_grh_sieve.out | | 15 | audit/audit_js.py (after copying js_uniform.py to original_js_uniform.py) | audit_js.out, audit_js.json | | 16 | audit/t2v6/audit_c4.py | resume1/audit_c4.json | | 17 | audit/t2v6/audit_s4.py | resume1/audit_s4.json | | 18 | audit/t2v6/audit_grh9.py | resume1/audit_grh9.json | | 19 | audit/t2v6/audit_v6.py | audit_v6.json (with an elapsed_seconds field that compare.py ignores) | | 20 | audit/t2v6/check_float_cells.py | check_float_cells.out, numpy_convolve_source.txt (numpy's source, for the record; not compared) | ## Statement -> script -> output Lemma, theorem and remark numbers are those of main.pdf. **UB** means an upper bound at fixed admissible parameters, which proves the condition. **LB** means a lower bound for the left side, which disproves it at the stated parameters only. | Paper statement | Kind | Script(s) | Output line | |---|---|---|---| | Lemma 7: (e^1800, 18) < 0.209801 | UB | author/cert_C3s_v7.py; second/cert_C3.py | cert_C3s_v7.out row 1; cert_C3_e1800.out | | Lemma 7: (e^1800, 17) > 0.5646 | LB | author/cert_C3s_v7.py | cert_C3s_v7.out row 2 | | Lemma 7: (e^350, 14) < 0.149761 | UB | author/cert_C3s_v7.py; second/cert_C3.py | cert_C3s_v7.out row 3; cert_C3_e350.out, K = 14 | | Lemma 7: (e^62, 9) < 0.241386 | UB | third/t2_check/c3_grh.py (row w = 11); also author/ and second/ (< 0.241439, < 0.2414388) | c3_grh.out; cert_C3s_v7.out row 4; cert_C3_e62.out | | Lemma 10: < 0.406804 against > 0.986659 | UB | second/cert_C4.py | cert_C4.out, K = 18 | | Lemma 16: < 1.34·10⁻⁶ and < 0.4481 | UB | third/t2_check/cert_S3P_K18.py (record); second/cert_S4.py | cert_S3P_K18.out, H = 400; cert_S4_H400.out, K = 18 | | Remark 17: Lemma 8 about 1.07, Lemma 15 about 14.3 at K = 17 | UB, not established | second/cert_C4.py; second/cert_S4.py | K = 17 rows | | Remark 17: (X2', 18) at delta = 1/5 > 0.628287, so the k-sum exceeds 0.4961 | LB | author/cert_C3s_v7.py | cert_C3s_v7.out row 5 | | Theorem 2: 501 and 449 intervals, margins 0.9030…, 0.4237…; z1 > 10493 (M ≤ 48) and log z1 ≥ 1595.1875 (M ≤ 32) | UB per interval | second/cert_qrhB3.py, cert_qrhB3p.py (with author/cert_qrh_range.py) | the two .out files and JSONs | | Lemma 23: < 0.147535 and < 0.139061 | UB | third/t2_check/c3_grh.py | rows w = 19, w = 23 | | Lemma 25: 238 intervals, max < 0.000265 | UB per interval | third/t2_check/cert_grh_sieve.py | K = 9, presieve = False | | Remark 26: K = 8 at e^73 (w = 29) > 0.363; Lemma 6's left side at (e^73, 8) about 1.004; the sieve range with Lemma 13 passes K = 8 | LB; LB; UB | c3_grh.py; author/cert_C3s_v7.py; cert_grh_sieve.py | rows w = 29, K = 8; cert_C3s_v7.out row 6; K = 8, presieve = True | | (I4'): c > 9.8036 on [L0, 3000], > 26.218 for L ≥ 3000 | UB of the error terms | third/js_cert/js_cert.py; audit/audit_js.py | js_cert.out; audit_js.json (direct_cover_*, tail_at_3000_*) | | Appendix B: 1 − f(6) < 1.05·10⁻⁴, F(7) − 1 < 5·10⁻⁶ | enclosures | author/fF_enclose.py | fF_enclose.out | | Section 8, the independent audit's bounds: < 0.2097564 (Lemma 7), < 0.4067970 (Lemma 10), < 0.448050660231 and < 0.454079084257 (Lemma 16), < 0.2413750, < 0.1475264, < 0.1390529 (Lemmas 7, 23), every row < 0.000265 (Lemma 25), > 0.42371750647 (Theorem 2) | UB / LB of margins | audit/t2v6/*.py | resume1/audit_*.json, audit_v6.json | | Section 8: the float cell weights and J values checked in Arb | check | audit/t2v6/check_float_cells.py | check_float_cells.out |