central.py
Checks: TRIPLE: The weighted shortfall is a budget and a zero sum property.
Cited on: TRIPLE.
To run it: save central.py, with cubic.py, room.py beside it; needs mpmath.
"""central.py -- the explicit formula of zeta_H/zeta_K read as the budget
of a complex cubic field's principal shortfall, one nontrivial class at a
time.
QUESTION. Over the complex cubic fields with h >= 2, the trivial class is
short at the small primes: its level in prime powers misses a fixed
weight, about h - 1 times a per-class amount within a factor two across
h = 2 to 7, carried below a few hundred. Is that weight the budget the
explicit formula of zeta_H/zeta_K sets, per nontrivial class, from the
conductor |d_K| and the gamma factor alone?
THE ARGUMENT (written before the engine).
(1) THE L-FUNCTION. H the Hilbert class field of K, unramified at the
real place too. zeta_H/zeta_K = prod over chi != 1 of L(s, chi),
each Ind chi of degree 3, conductor |d_K| N f(chi) = |d_K|, gamma
Gamma_R(s)^2 Gamma_R(s + 1) (chi trivial at the real place), entire.
(2) THE COEFFICIENT. Each prime ideal P of K is its own Euler factor
(1 - chi(P) N(P)^-s)^-1, ramified over Q or not, so -L'/L summed
over chi != 1 has at p^k the coefficient log p C(p^k),
C(p^k) = sum over P | p with f_P | k of
f_P (h 1[(k/f_P)[P] = 0] - 1).
At an unramified degree-1 place and k = 1 it is l(P) - 1, l the
place's principal level (h when principal, 0 when not).
(3) THE FORMULA, summed over chi and its conjugate (real), with
Odlyzko's F_T(u) = f(u/T) of room.py:
H(T) = (h - 1) B(T) + D(T), B(T) = log |d_K| + G(T),
D(T) = -2 sum_{p^k < e^T} log p C(p^k) F_T(k log p) / p^(k/2),
H the sum of F_T^ over the zeros of every L(s, chi), >= 0 under
GRH. D is the weighted SHORTFALL: a principal place adds
-(h - 1) w, a non-principal one +w.
(4) THE BUDGET. phi(T) = -B(T) per nontrivial class, a function of
|d_K| and T alone, the same at every h. d = D/(h - 1) = phi + z,
z = H/(h - 1) the zero sum per class, so d >= phi under GRH.
(5) THE LIMIT. G(T) -> G(inf) = 2 psi(1/4) + psi(3/4) - 3 log pi =
-12.975 (e^-G(inf) = 431472). Under GRH with no zero at the
centre, each zero's T f^(gamma T) -> 0: for |x| >= 2 pi,
x^2 - pi^2 >= 3 x^2 / 4 gives f^(x) <= 128 pi^2 / (9 x^4), so once
T >= 2 pi / (least |gamma|) every term is at most 128 pi^2 /
(9 gamma^4 T^3), summable since each L(s, chi) has N(t) =
O(t log t) zeros to height t; G(T) -> G(inf) as F_T^ -> 2 pi
delta_0 against the continuous psi terms; so H(T) -> 0 and
D(T)/(h - 1) ->
log(431472/|d_K|). At width T the budget is positive only for
|d_K| < e^-G(T): 656, 2466, 6236, 12508, 21498, 33086, 46901 at
T = 2 .. 8.
THE ENGINE. cubic.py: every complex cubic field with h >= 2 and
|d_K| <= 12000, the certified class group, the class of every place
over p <= 2980 (= e^8), checkpointed; the degree-2 place over a
partial prime has class -[P1], an inert prime's place is trivial. G(T)
from room.py's quadrature, at 20 digits there only.
PREDICTIONS, frozen before the engine.
K1 at h = 2, H(T) from (2) equals room.py's H for L(s, rho), each
field read afresh by room.py's read_field and coefficient table,
T <= 6, to 1e-9.
K2 H(T) >= 0 at every field and width T = 2 .. 8 (GRH; an error).
K3 the formula at T = 7, 8 on zeta (first 100 zeros) and L(s, chi_-3)
(zeros to t = 60), within 1e-4 (a bar above zeta's zero side
itself, 1e-5 at T = 8: it reads the formula's cancellation).
K4 THE BREAK: every class drawn uniformly under the relations (the
split three summing to 0, [Q] = -2[P] at P^2 Q, P^3 in Cl[3])
makes H(8) < 0 at >= 0.8 of the fields.
K5 [Q] = -2[P] at P^2 Q, 3[P] = 0 at P^3, the split three summing to
0, every place placed.
Q1 median z(8) <= 0.1, median z(6) <= 0.3.
Q2 per h = 2 .. 7 (cells of >= 20 fields) mean d(8)/mean phi(8) in
[1, 1.15], while mean d(8)'s largest over least across h reads
above 1.15 only as phi's does.
Q3 the OLS slope of d(8) on log |d_K|: -1.2 to -0.8.
Q4 printed, not judged: D_1 (the degree-1 places over unramified
primes at k = 1; Q at P^2 Q is in D - D_1)
over D at T = 6, 8, by 2-rank; z(T) by T - T_0, T_0 the largest
width with phi <= 0 (1 where phi > 0 at every width).
KILL BUDGET. Z/PHI(8) = mean z(8) / mean phi(8) over the fields. The
shortfall per nontrivial class is the conductor's budget at wide
support only if Z/PHI(8) <= 0.2 and some h cell of Q2 exists with
none reading above 1.25 ("some cell exists" added after the full
run, when a rehearsal with none read the clause vacuously).
K1 reads h = 2 only, where -[P1] = [P1]; the degree-2 class's sign at
h >= 3 is checked by nothing and moves no coefficient, since m(-c) = 0
exactly when mc = 0. Breaking the factor f_P in (2) fails K1 (worst
0.99) and K2 (least H -1.41) at a rehearsal's 44 fields.
FINDINGS.
F0 CONTROLS (K1 to K5 held). The formula at T = 7, 8 on zeta and
L(s, chi_-3) to 2.5e-7; 1848 fields to |d_K| <= 12000, all
certified, 535 with h >= 2, no relation broken, no place unplaced;
at the 220 fields with h = 2, H equals room.py's to 0.0e+00 (the
same weights and integer coefficients in the same order); the least
H over fields and widths 0.0011; uniform classes drive H(8) below 0
at 456 of 535 (0.852).
F1 THE BUDGET CARRIES THE SHORTFALL (KILL BUDGET MISSED, Q1 held).
Per nontrivial class, mean d over mean phi at T = 5 .. 8: 1.270
against 0.801, 1.621 against 1.342, 1.953 against 1.773, 2.245
against 2.122; Z/PHI(8) = 0.058. The zero sum is skewed: median z
0.265, 0.058, 0.043, 0.031 at T = 5 .. 8 against means 0.470,
0.279, 0.179, 0.123. Below the budget's onset the zeros carry it:
at T = 2, 3, where phi averages -2.15 and -0.82, d is still 0.28
and 0.62.
F2 THE WEIGHTED FLATNESS ACROSS h IS THE BUDGET'S (Q2 held; the
question's delta is an unweighted count at a cut, not read
here). Mean d(8) over
mean phi(8) reads 1.013 (h = 2, 220 fields), 1.081 (3, 169), 1.053
(4, 45), 1.120 (5, 45), 1.109 (7, 23); h = 6 (19 fields, below the
cell's 20) 1.186. Across those five cells d(8)'s largest over least
is 1.164 and phi(8)'s 1.195, mean log |d_K| running 8.54 to
8.90: the budget spreads across h at least as much as the
shortfall does.
F3 THE CONDUCTOR'S SLOPE (Q3 held). d(8) on log |d_K|: -0.884 +-
0.024 (OLS over 535 fields, se naive), phi's own slope -1.
F4 printed, not judged. D_1/D: 0.483 (T = 6) and 0.562 (T = 8) at
2-rank 0 (244 fields), 1.248 and 1.346 at 2-rank 1 (288), 1.389
and 1.604 at 2-rank 2 (3): with a 2-torsion class the other
terms add principal weight that the first powers more than pay,
without one they carry about half (the squares the likely
carrier, a reading: no print splits D - D_1). Median z
by T - T_0 falls 2.891, 1.972, 1.190, 0.570, 0.180, 0.058, 0.037,
0.021, 0.009, 0.003 from -2 to +7 (+7 over the 7 fields with
phi > 0 at T = 2): by T_0 + 3, two widths past the
first width with phi > 0, the zeros' part is 0.058.
TIERS. (1) to (4) are property; F0's positivity is GRH read at 535
fields; F1 to F4 are observations over this population; (5)'s limit
is a property under GRH with no central zero, its proof the
dominated convergence written there.
RUN RECORD. 5/5 controls. A rehearsal at --dmax 2000 (44 fields with
h >= 2) stopped on an empty Q2 list, guarded before the full run; the
full run 155.0 s (the population 95.7 s, checkpointed), peak commit
199.1 MB under a memory guard (512 MB); from the checkpoint 59.9 s,
221.3 MB, every line reproduced. With K1 reading its 220 fields afresh
through room.py's read_field (no checkpoint of room.py read), --fresh
163.8 s, peak commit 182.9 MB, every line reproduced.
"""
import hashlib
import inspect
import json
import os
import random
import sys
import tempfile
import time
from math import exp, log, sqrt
os.environ.setdefault("OPENBLAS_NUM_THREADS", "1")
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import mpmath # noqa: E402
import cubic as C # noqa: E402
import room as R # noqa: E402
RESULTS = []
def _flag(name, default):
if name in sys.argv:
return sys.argv[sys.argv.index(name) + 1]
return default
DMAX = int(_flag("--dmax", 12000)) # the population: |d_K| <= DMAX
WIDTHS = [2, 3, 4, 5, 6, 7, 8]
PMAX = int(exp(max(WIDTHS))) # 2980
MIN_CELL = 20
SEED = 1657
def check(name, ok, detail=""):
RESULTS.append(bool(ok))
print(f" [{'PASS' if ok else 'FAIL'}] {name}"
+ (f" -- {detail}" if detail else ""))
def section(title):
print(f"\n{title}")
PRIMES = [p for p in C.PRIMES if p <= PMAX]
def weights(T):
"""{(p, k): 2 log p F_T(k log p) / p^(k/2)} over p^k < e^T."""
W = {}
for p in PRIMES:
k = 1
while k * log(p) < T:
W[(p, k)] = 2 * log(p) * R.f(k * log(p) / T) / p ** (k / 2)
k += 1
return W
W = {T: weights(T) for T in WIDTHS}
G = {}
# ---------------------------------------------------------------------------
# the population
def gneg(x, inv):
return tuple((-a) % n for a, n in zip(x, inv))
def gadd(x, y, inv):
return tuple((a + b) % n for a, b, n in zip(x, y, inv))
def gmul(k, x, inv):
return tuple((k * a) % n for a, n in zip(x, inv))
def read_field(key, dk):
"""[p, type, [[f, class], ...]] for every p <= PMAX; type n, s, p, r2
(P^2 Q, P listed first), r3."""
K = C.Field(key, dk)
if not K.class_group(always_cert=True):
return {"d": dk, "ok": False}
inv = list(K.cl)
rec = {"d": dk, "ok": True, "h": K.h, "inv": inv}
if K.h < 2:
return rec
zero = tuple(0 for _ in inv)
primes, bad, unplaced = [], 0, 0
for p in PRIMES:
typ = K.ptype(p)
if typ == ((3, 1),):
primes.append([p, "n", [[3, list(zero)]]])
continue
pls = [pl for pl in K.places(p) if pl.deg == 1]
try:
cs = [K.place_class(pl) for pl in pls]
except ValueError:
cs = [None]
if any(c is None for c in cs):
unplaced += 1
continue
cs = [tuple(c) for c in cs]
if typ == ((1, 1), (1, 1), (1, 1)):
bad += gadd(gadd(cs[0], cs[1], inv), cs[2], inv) != zero
primes.append([p, "s", [[1, list(c)] for c in cs]])
elif typ == ((1, 1), (2, 1)):
primes.append([p, "p", [[1, list(cs[0])],
[2, list(gneg(cs[0], inv))]]])
elif typ == ((1, 1), (1, 2)):
cP = [c for pl, c in zip(pls, cs) if pl.e == 2][0]
cQ = [c for pl, c in zip(pls, cs) if pl.e == 1][0]
bad += gadd(cQ, gmul(2, cP, inv), inv) != zero
primes.append([p, "r2", [[1, list(cP)], [1, list(cQ)]]])
elif typ == ((1, 3),):
bad += gmul(3, cs[0], inv) != zero
primes.append([p, "r3", [[1, list(cs[0])]]])
else:
raise ValueError("splitting %r" % (typ,))
rec.update(primes=primes, bad=bad, unplaced=unplaced)
return rec
_SRC = hashlib.sha1(
open(os.path.join(HERE, "cubic.py"), "rb").read()
.split(b'"""', 2)[2] + inspect.getsource(read_field).encode()
+ str(PMAX).encode()).hexdigest()[:12]
CKPT = os.path.join(tempfile.gettempdir(),
"central_%d_%s.json" % (DMAX, _SRC))
def population():
if "--fresh" not in sys.argv and os.path.exists(CKPT):
print(" read from the checkpoint %s" % CKPT)
with open(CKPT) as fh:
return json.load(fh)
t0 = time.time()
F = C.enumerate_fields(DMAX)
print(" %d complex cubic fields with |d_K| <= %d" % (len(F), DMAX))
recs = []
for i, (key, dk) in enumerate(sorted(F.items(),
key=lambda kv: (-kv[1], kv[0]))):
recs.append(read_field(key, dk))
if (i + 1) % 500 == 0:
print(" %d fields read, %.0f s" % (i + 1, time.time() - t0),
flush=True)
with open(CKPT, "w") as fh:
json.dump(recs, fh)
print(" read in %.1f s, checkpointed to %s" % (time.time() - t0, CKPT))
return recs
# ---------------------------------------------------------------------------
# one field's budget
def coeff(primes, h, inv):
"""{(p, k): C(p^k)} over p^k <= e^8, (2); and the k = 1 part over
unramified degree-1 places."""
out, one = {}, {}
for p, t, pls in primes:
k = 1
while k * log(p) < max(WIDTHS):
c = 0
for fP, cls in pls:
if k % fP == 0:
m = k // fP
c += fP * (h * all((m * a) % n == 0
for a, n in zip(cls, inv)) - 1)
out[(p, k)] = c
k += 1
if t in ("s", "p"):
one[p] = sum(h * all(a == 0 for a in cls) - 1
for fP, cls in pls if fP == 1)
return out, one
class Budget:
def __init__(self, rec, primes=None):
self.d, self.h, inv = rec["d"], rec["h"], rec["inv"]
self.inv = inv
self.rank2 = sum(1 for n in inv if n % 2 == 0)
logq = log(-self.d)
c, one = coeff(primes or rec["primes"], self.h, inv)
self.H, self.D, self.D1, self.phi = {}, {}, {}, {}
for T in WIDTHS:
D = -sum(w * c[pk] for pk, w in W[T].items())
D1 = -sum(w * one[p] for (p, k), w in W[T].items()
if k == 1 and p in one)
self.D[T], self.D1[T] = D, D1
self.phi[T] = -(logq + G[T])
self.H[T] = (self.h - 1) * (logq + G[T]) + D
def z(self, T):
return self.H[T] / (self.h - 1)
def dd(self, T):
return self.D[T] / (self.h - 1)
def planted(rec, rng):
"""Every class drawn uniformly under the relations (K4)."""
inv, h = rec["inv"], rec["h"]
zero = tuple(0 for _ in inv)
allg = [()]
for n in inv:
allg = [g + (a,) for g in allg for a in range(n)]
tors3 = [g for g in allg if gmul(3, g, inv) == zero]
out = []
for p, t, pls in rec["primes"]:
if t == "n":
out.append([p, t, pls])
elif t == "s":
a, b = rng.choice(allg), rng.choice(allg)
c = gneg(gadd(a, b, inv), inv)
out.append([p, t, [[1, list(a)], [1, list(b)], [1, list(c)]]])
elif t == "p":
a = rng.choice(allg)
out.append([p, t, [[1, list(a)], [2, list(gneg(a, inv))]]])
elif t == "r2":
a = rng.choice(allg)
out.append([p, t, [[1, list(a)],
[1, list(gneg(gmul(2, a, inv), inv))]]])
else:
out.append([p, t, [[1, list(rng.choice(tors3))]]])
return out
# ---------------------------------------------------------------------------
# controls on the formula past room.py's widths
def zeros_chi3(tmax=60.0, step=0.05):
zs = []
a, va = 0.01, R.lchi3(0.01)
while a < tmax:
b = a + step
vb = R.lchi3(b)
if va * vb < 0:
lo, hi, vlo = a, b, va
for _ in range(34):
mid = (lo + hi) / 2
vm = R.lchi3(mid)
if vm * vlo < 0:
hi = mid
else:
lo, vlo = mid, vm
zs.append((lo + hi) / 2)
a, va = b, vb
return zs
def control_wide():
zz = [float(mpmath.im(mpmath.zetazero(n))) for n in range(1, 101)]
z3 = zeros_chi3()
chi = {1: 1, 2: -1, 0: 0}
worst = 0.0
for T in (7, 8):
lhs = 2 * sum(T * float(R.fhat(g * T)) for g in zz)
rhs = R.pole(T) + R.gamma_piece(T, 0) - sum(W[T].values())
print(" zeta, T = %d: zeros %.8f, formula %.8f" % (T, lhs, rhs))
worst = max(worst, abs(lhs - rhs))
lhs = 2 * sum(T * float(R.fhat(g * T)) for g in z3)
rhs = log(3) + R.gamma_piece(T, 1) - sum(
w * chi[p % 3] ** k for (p, k), w in W[T].items())
print(" L(s, chi_-3), T = %d: %d zeros %.8f, formula %.8f"
% (T, len(z3), lhs, rhs))
worst = max(worst, abs(lhs - rhs))
check("K3 the formula at T = 7, 8 on zeta and L(s, chi_-3)",
worst < 1e-4, "worst %.1e" % worst)
def control_room(budgets):
"""K1: at h = 2 the budget's H is room.py's H for L(s, rho)."""
mine = {}
for b in budgets:
if b.h == 2:
mine.setdefault(b.d, []).append(b)
theirs = {}
for key, dk in C.enumerate_fields(DMAX).items():
if dk in mine:
r = R.read_field(key, dk)
if r.get("ok") and r.get("inv") == [2]:
theirs.setdefault(dk, []).append(r)
worst, n, skipped = 0.0, 0, 0
for d, bs in mine.items():
rs = theirs.get(d, [])
if len(bs) != 1 or len(rs) != 1:
skipped += 1
continue
r, b = rs[0], bs[0]
pr = {p: (t, v) for p, t, v in r["primes"]}
for T in WIDTHS:
if T > 6:
continue
h_room = log(-d) + G[T] - sum(
w * R.coeff(*pr[p], k) for (p, k), w in W[T].items())
worst = max(worst, abs(h_room - b.H[T]))
n += 1
check("K1 H at h = 2 is room.py's H for L(s, rho), T <= 6",
n > 0 and worst < 1e-9,
"%d fields, %d skipped (a shared discriminant), worst %.1e"
% (n, skipped, worst))
# ---------------------------------------------------------------------------
# statistics
def median(v):
v = sorted(v)
n = len(v)
return (v[n // 2] + v[(n - 1) // 2]) / 2
def mean(v):
return sum(v) / len(v)
def ols(x, y):
n = len(x)
mx, my = mean(x), mean(y)
sxx = sum((a - mx) ** 2 for a in x)
b = sum((a - mx) * (c - my) for a, c in zip(x, y)) / sxx
res = sum((c - my - b * (a - mx)) ** 2 for a, c in zip(x, y))
return b, sqrt(res / (n - 2) / sxx)
def main():
t0 = time.time()
section("A THE FORMULA")
with mpmath.workdps(20):
for T in WIDTHS:
G[T] = 2 * R.gamma_piece(T, 0) + R.gamma_piece(T, 1)
Ginf = float(2 * mpmath.digamma(0.25) + mpmath.digamma(0.75)
- 3 * mpmath.log(mpmath.pi))
print(" T G(T) e^-G(T)")
for T in WIDTHS:
print(" %-3g %9.4f %10.0f" % (T, G[T], exp(-G[T])))
print(" oo %9.4f %10.0f" % (Ginf, exp(-Ginf)))
control_wide()
section("B THE POPULATION")
recs = population()
pop = [r for r in recs if r["ok"] and "primes" in r]
bad = sum(r["bad"] for r in pop)
unpl = sum(r["unplaced"] for r in pop)
print(" fields %d, uncertified %d, h >= 2: %d"
% (len(recs), sum(not r["ok"] for r in recs), len(pop)))
check("K5 [Q] = -2[P], 3[P] = 0, split sum, every place placed",
bad == 0 and unpl == 0 and all(r["ok"] for r in recs),
"bad %d, unplaced %d" % (bad, unpl))
bs = [Budget(r) for r in pop]
control_room(bs)
least = min(b.H[T] for b in bs for T in WIDTHS)
check("K2 H(T) >= 0 at every field and width (GRH)", least >= -1e-9,
"least H %.4f" % least)
rng = random.Random(SEED)
neg = sum(Budget(r, planted(r, rng)).H[8] < 0 for r in pop)
check("K4 uniform classes drive H(8) below 0 at >= 0.8 of the fields",
neg >= 0.8 * len(pop), "%d of %d = %.3f"
% (neg, len(pop), neg / len(pop)))
if not all(RESULTS):
print("\na control failed; nothing below is read")
raise SystemExit(1)
section("C THE BUDGET PER NONTRIVIAL CLASS")
print(" T median z mean z mean phi mean d mean d1 Z/PHI")
for T in WIDTHS:
zs = [b.z(T) for b in bs]
ph = [b.phi[T] for b in bs]
print(" %d %9.4f %8.4f %9.4f %8.4f %8.4f %7.4f"
% (T, median(zs), mean(zs), mean(ph),
mean([b.dd(T) for b in bs]),
mean([b.D1[T] / (b.h - 1) for b in bs]),
mean(zs) / mean(ph)))
zp = mean([b.z(8) for b in bs]) / mean([b.phi[8] for b in bs])
print(" Q1 median z(8) %.4f (<= 0.1), median z(6) %.4f (<= 0.3)"
% (median([b.z(8) for b in bs]), median([b.z(6) for b in bs])))
section("D ACROSS h")
print(" h fields mean log|d_K| mean d(8) mean phi(8) ratio")
cells = {}
for b in bs:
cells.setdefault(b.h, []).append(b)
worst = 0.0
dm, pm = [], []
for h in sorted(cells):
c = cells[h]
md, mp = mean([b.dd(8) for b in c]), mean([b.phi[8] for b in c])
tag = ""
if 2 <= h <= 7 and len(c) >= MIN_CELL:
worst = max(worst, md / mp)
dm.append(md)
pm.append(mp)
tag = " *"
print(" %-3d %6d %13.3f %10.4f %12.4f %7.4f%s"
% (h, len(c), mean([log(-b.d) for b in c]), md, mp,
md / mp, tag))
if dm:
print(" (* a Q2 cell) d(8) largest over least %.3f, phi(8)'s %.3f;"
" largest cell ratio %.4f" % (max(dm) / min(dm),
max(pm) / min(pm), worst))
b3, se3 = ols([log(-b.d) for b in bs], [b.dd(8) for b in bs])
print(" Q3 slope of d(8) on log |d_K| %.3f +- %.3f (-1.2 to -0.8)"
% (b3, se3))
section("E WHERE IT SITS (printed)")
for T in (6, 8):
for r2 in sorted({b.rank2 for b in bs}):
c = [b for b in bs if b.rank2 == r2]
print(" T = %d, 2-rank %d (%d fields): D_1/D %.3f"
% (T, r2, len(c), sum(b.D1[T] for b in c)
/ sum(b.D[T] for b in c)))
print(" z = d - phi by T - T_0 (T_0 where phi changes sign):")
rows = {}
for b in bs:
lo = max([T for T in WIDTHS if b.phi[T] <= 0], default=None)
for T in WIDTHS:
key = T - (lo if lo is not None else 1)
rows.setdefault(key, []).append(b.z(T))
for key in sorted(rows):
print(" T - T_0 = %+d: median z %.4f (%d)"
% (key, median(rows[key]), len(rows[key])))
section("F THE VERDICT")
print(" Z/PHI(8) = %.4f" % zp)
alive = zp <= 0.2 and bool(dm) and worst <= 1.25
print(" KILL BUDGET %s: Z/PHI(8) %.4f (bar 0.2), largest h cell %.4f"
" (bar 1.25)" % ("MISSED" if alive else "FIRED", zp, worst))
print("\n%d/%d controls, %.1f s" % (sum(RESULTS), len(RESULTS),
time.time() - t0))
raise SystemExit(0 if all(RESULTS) else 1)
if __name__ == "__main__":
main()