firstmove.py
Checks: FORGET: The quarantine theorem theorem.
Cited on: FORGET.
To run it: save firstmove.py, with quarantine.py beside it; standard library only.
"""firstmove.py -- can a coprime grown world hide its FIRST MOVE at every
temperature, when it cannot hide the route?
QUESTION. quarantine.py proves that in a coprime grown world no two
routes to one dated fiber tie at every beta, so no fiber is robust for
the route. The coarser datum, the first move, is left open: a fiber
meeting two first moves or more is FLAT FOR THE FIRST MOVE at beta when
its first-move classes carry equal posterior mass there, and whether a
coprime fiber is flat for it at every beta asks for an identity between
SUMS of route weights, which the quarantine's collision of products
does not reach. quarantine.py measured it: 0 of 120,386 fibers of at
most eight routes. Is it a theorem?
THE ARGUMENT (written before the engine).
(A) INDEPENDENT VARIABLES. A route r of a fiber with endpoint N has
posterior proportional to 1 / D_r, D_r the product of the
normalizers Psi at the states r passes before its endpoint, the
seed's included (quarantine.py's (A)). Write x_q = q^-beta for
each prime q; n^-beta is the monomial prod x_q^(v_q(n)), distinct
n giving distinct monomials, so a Dirichlet polynomial is a
polynomial in the x_q with the same coefficients. Let S_c be the
sum of 1 / D_r over the routes whose first move is c. Flat for
the first move at every beta > 0 means S_a = S_b for every two
first moves a, b met; clearing denominators, a Dirichlet
polynomial vanishes on beta > 0, so all its coefficients vanish
(sums of n^-beta over distinct n are linearly independent), and
S_a = S_b holds as an identity of rational functions in the
independent x_q: at every positive assignment, not only on the
curve x_q = q^-beta. Every D_r holds the seed's Psi; dividing
it out leaves D'_r, the product over the later states, and the
identity S'_a = S'_b.
(B) A SEPARATING PRIME. Coprime menus share no prime with their
state, so every move after the first is prime to the first move
a, and v_q(N) = v_q(a) at every prime q of a; likewise for b. So
a and b are unitary divisors of N, and if they had the same
primes they would be equal. Hence, a != b, some prime p divides
one and not the other; name them so that p | a, p does not
divide b.
(C) THE CLASS OF a IS BLIND TO x_p. Every later state of a route
opening with a is divisible by a, hence by p, and its coprime
menu offers no multiple of p: every D'_r with r opening with a
has x_p-degree 0, so S'_a does not move with x_p.
(D) THE CLASS OF b DIES IN x_p. A route opening with b reaches N,
divisible by p, so p divides a later move m_j, j >= 2, drawn
from the menu at the state before it; that Psi holds the
monomial of m_j with coefficient 1 and x_p-degree v_p(m_j) >= 1.
Every coefficient is nonnegative, so with the other x_q held at
positive values, D'_r -> infinity as x_p -> infinity, and S'_b
-> 0, while S'_a stays at its positive value. So S'_a != S'_b as
functions, the cleared Dirichlet polynomial is nonzero, and it has
finitely many real zeros (no more than its sign changes,
Laguerre's extension of Descartes' rule).
THEOREM (to be ruled). In a coprime grown world, menus a function
of the route so far, no fiber meeting two first moves or more is
flat for the first move at every beta; it is flat at finitely many
beta at most. It holds on any set of routes of one age to one
endpoint, so no state map refining (state, age) cuts such a fiber
into blocks each spread and flat for the first move at every beta.
A hypothesis is the load: the depth column, menu {2, 3} at every
state, recycles the first move's primes and hides the first move at
every beta on the dated fiber (2^k 3^k, 2k) (forget.py's count
leak, zero when the two exponents agree).
(E) WHAT THE PROOF USES. Steps (B) and (C) read only that every menu
after the first move avoids the first move's primes; (D) reads
nothing of the menus. So the theorem holds in a FIRST-COPRIME
world, each later menu prime to the first move and free to
recycle the others, where the route itself can tie: menu(a) =
{b, c} and menu(a, b) = menu(a, c) = {b, c} put a,b,c and a,c,b
in one fiber with one D. The first move is quarantined by a
weaker hypothesis than the route.
THE CHECK. The proof is the verifier; the script reads its two steps
on the populations quarantine.py scans, with no cap on the routes:
for every fiber meeting two first moves or more and every pair (a, b)
of them, it looks for a separating prime p (B), takes the
x_p-degree of every D'_r (the largest v_p over its support) in the
class blind to p (C, every degree 0) and in the other (D, every degree
at least 1), and counts the pairs where a step fails.
POPULATIONS, as quarantine.py's arms, same seeds and walk order:
COPRIME-STATE and COPRIME-HISTORY (moves US, ages 2 and 3, 3000
worlds each, seeds 0 and 1), their large forms (moves UL, ages 2 to
4, 1000 each, seeds 4 and 5), and the exhaustive arm (87,885 tables
on the moves 2 to 6, ages 2 and 3).
CONTROLS, read first: the depth column's dated fiber (36, 4) is flat
for the first move at every beta (quarantine.first_move_robust) and
its step (C) fails; quarantine.py's last-move world's fiber (30, 3)
fails step (C); the LAST-HISTORY and FREE-STATE arms (seeds 2, 3)
fail a step at some pair. A step check that never fails off
coprimality reads nothing.
THE BOUNDARY ARM, FIRST-COPRIME: moves US, menus keyed by the route
so far, each later menu prime to the first move only, sizes 1 to 2,
ages 2 and 3, 3000 worlds, seed 6; its route ties are counted as
quarantine.ties counts them.
POPULATION CHECK: the fibers of at most eight routes meeting two first
moves or more number 120,386 over the five coprime arms, as
quarantine.py prints, or the populations differ.
PREDICTIONS (frozen before the engine).
(P1) Every control fails as stated; the depth column's (36, 4) is
flat for the first move.
(P2) The population check reads 120,386.
(P3) Over the five coprime arms, every pair has a separating prime,
and steps (C) and (D) hold at every pair: 0 failures.
(P4) The FIRST-COPRIME arm: 0 failures, and route ties above 0.
KILL: the script prints a failure count above 0 over the five coprime
arms (P3). A failure there is a coprime fiber the argument misreads:
the theorem is wrong as stated until that fiber is read by hand. A
failure on FIRST-COPRIME alone kills (E), not the theorem.
FINDINGS.
(P1) held: the depth column's (36, 4) is flat for the first move and
fails step C, the last-move world's (30, 3) fails step C, and
the LAST-HISTORY and FREE-STATE arms fail a step at 194 of 476
and 336 of 383 pairs (C at 156 and 263, B at 38 and 73).
(P2) held: 120386 capped fibers. Every fiber read held at most eight
routes (fibers = capped in every arm), so the uncapped read adds
no fiber to quarantine.py's population.
(P3) held, the kill missed: 0 failing of 145744 pairs over 120386
fibers of the five coprime arms.
(P4) held: FIRST-COPRIME, 0 failing of 369 pairs, 86 route ties: a
world prime to its first move only ties routes and still keeps
the argument's steps at every pair read.
The step counts read the generators more than the mathematics: D
failed at no pair of any arm, controls included, holding by
construction (a route reaching N must take p somewhere), and on the
coprime and FIRST-COPRIME arms C holds by construction too, their
menus drawn prime to the state or the first move; P3's 0 reads that
the arms are what they say. The conclusion is read directly by
quarantine.first_move_robust (exact formal Dirichlet sums), added
after the run when the steps were seen to be fixed by construction:
0 of 120386 coprime fibers (quarantine.py's own read, repeated) and
0 of 369 FIRST-COPRIME fibers (new) flat for the first move at every
beta, while the counter fires off coprimality (LAST-HISTORY 1,
FREE-STATE 2) and on the depth column's control.
The verifier is the argument, (A)..(E), by hand.
RUN RECORD. python firstmove.py: 8 of 8 checks, 1.2 s, peak commit
9.1 MB; with the two CONCLUSION checks added
after it, 10 of 10, 6.3 s, peak 12.7 MB.
"""
import random
import sys
import time
from collections import defaultdict
from math import gcd
import quarantine as Q
CHECKS = []
def check(name, ok, detail=""):
CHECKS.append(bool(ok))
print(f" [{'PASS' if ok else 'FAIL'}] {name}" + (f": {detail}" if detail
else ""))
def primes(n):
out, q = [], 2
while q * q <= n:
if n % q == 0:
out.append(q)
while n % q == 0:
n //= q
q += 1
return out + ([n] if n > 1 else [])
def vp(n, p):
k = 0
while n % p == 0:
n //= p
k += 1
return k
def degree(menus, p):
"""x_p-degree of the product of the Psi of these menus: each Psi's
degree is its menu's largest v_p, coefficients being nonnegative."""
return sum(max(vp(m, p) for m in mu) for mu in menus)
def steps(items):
"""Per pair of first moves of one fiber: the steps that fail.
Returns (pairs read, Counter of failing steps, failing pairs)."""
classes = defaultdict(list)
for r, ms in items:
classes[r[0]].append(ms[1:])
firsts = sorted(classes)
pairs = bad = 0
fails = defaultdict(int)
for i, a in enumerate(firsts):
for b in firsts[i + 1:]:
pairs += 1
seps = [(p, a, b) for p in primes(a) if b % p] + \
[(p, b, a) for p in primes(b) if a % p]
got = set()
if not seps:
got.add("B")
for p, blind, other in seps:
if any(degree(ms, p) > 0 for ms in classes[blind]):
got.add("C")
if any(degree(ms, p) == 0 for ms in classes[other]):
got.add("D")
for g in got:
fails[g] += 1
bad += bool(got)
return pairs, fails, bad
def read(menus, ages, tally_ties=False):
t = defaultdict(int)
for menu in menus:
t["worlds"] += 1
for age in ages:
for items in Q.fibers(menu, age).values():
if len({r[0] for r, _ in items}) < 2:
continue
t["fibers"] += 1
if len(items) <= 8:
t["capped"] += 1
pairs, fails, bad = steps(items)
t["pairs"] += pairs
t["failing pairs"] += bad
for g, c in fails.items():
t["step " + g] += c
if tally_ties:
w, f = Q.ties(items)
t["route ties"] += w + f
t["first move flat"] += Q.first_move_robust(items)
if tally_ties:
for items in Q.fibers(menu, age).values():
if len(items) >= 2 and \
len({r[0] for r, _ in items}) < 2:
w, f = Q.ties(items)
t["route ties"] += w + f
return dict(t)
def first_only(m, n, prefix):
return not prefix or gcd(m, prefix[0]) == 1
def main():
t0 = time.time()
print("CONTROLS")
depth = Q.fibers(lambda p, n: (2, 3), 4)[36]
check("depth column (36, 4) flat for the first move at every beta",
Q.first_move_robust(depth))
_, f, bad = steps(depth)
check("depth column (36, 4) fails step C", f.get("C", 0) > 0,
dict(f))
last = Q.fibers(Q.LAST, 3)[30]
_, f, bad = steps(last)
check("last-move world (30, 3) fails step C", f.get("C", 0) > 0,
dict(f))
arms = [("COPRIME-STATE", Q.US, Q.coprime, "state", (1, 2), (2, 3), 3000),
("COPRIME-HISTORY", Q.US, Q.coprime, "prefix", (1, 2), (2, 3),
3000),
("LAST-HISTORY", Q.US, Q.last_move, "prefix", (1, 2), (2, 3),
3000),
("FREE-STATE", Q.US, Q.free, "state", (1, 2), (2, 3), 3000),
("COPRIME-STATE large", Q.UL, Q.coprime, "state", (1, 3),
(2, 3, 4), 1000),
("COPRIME-HISTORY large", Q.UL, Q.coprime, "prefix", (1, 3),
(2, 3, 4), 1000),
("FIRST-COPRIME", Q.US, first_only, "prefix", (1, 2), (2, 3),
3000)]
out = {}
for seed, (name, uni, allowed, keyed, sizes, ages, count) in \
enumerate(arms):
rng = random.Random(seed)
menus = (Q.random_world(rng, uni, allowed, keyed, sizes)
for _ in range(count))
out[name] = read(menus, ages, tally_ties=name == "FIRST-COPRIME")
print(f" {name}: {out[name]}")
for name in ("LAST-HISTORY", "FREE-STATE"):
check(f"{name} fails a step at some pair",
out[name].get("failing pairs", 0) > 0)
out["EXHAUSTIVE"] = read(Q.exhaustive_worlds(), (2, 3))
print(f" EXHAUSTIVE: {out['EXHAUSTIVE']}")
co = ("COPRIME-STATE", "COPRIME-HISTORY", "COPRIME-STATE large",
"COPRIME-HISTORY large", "EXHAUSTIVE")
capped = sum(out[n].get("capped", 0) for n in co)
check("POPULATION: capped fibers over the five coprime arms 120,386",
capped == 120386, f"{capped}")
fibers = sum(out[n].get("fibers", 0) for n in co)
pairs = sum(out[n].get("pairs", 0) for n in co)
fails = sum(out[n].get("failing pairs", 0) for n in co)
print(f" the five coprime arms: {fibers} fibers meeting two first "
f"moves or more, {pairs} pairs, {fails} failing")
check("P3 KILL not fired: 0 failing pairs over the coprime arms",
fails == 0 and pairs > 0, f"{fails} of {pairs}")
fc = out["FIRST-COPRIME"]
flat = sum(out[n].get("first move flat", 0) for n in co)
check("CONCLUSION: no fiber of the coprime arms flat for the first "
"move at every beta", flat == 0, f"{flat} of {fibers}")
check("CONCLUSION: no FIRST-COPRIME fiber flat for the first move",
out["FIRST-COPRIME"].get("first move flat", 0) == 0,
f"{out['FIRST-COPRIME'].get('first move flat', 0)} of "
f"{out['FIRST-COPRIME'].get('fibers', 0)}")
check("P4 FIRST-COPRIME: 0 failing pairs, route ties above 0",
fc.get("failing pairs", 0) == 0 and fc.get("pairs", 0) > 0
and fc.get("route ties", 0) > 0,
f"{fc.get('failing pairs', 0)} of {fc.get('pairs', 0)} pairs, "
f"{fc.get('route ties', 0)} route ties")
wall = time.time() - t0
print(f"{sum(CHECKS)}/{len(CHECKS)} checks passed, {wall:.1f} s")
sys.exit(0 if all(CHECKS) else 1)
if __name__ == "__main__":
main()