sizeless.py
Checks: GROWTH: The properness criterion criterion; GROWTH: The route is the deleted place's theorem; observation.
Cited on: GROWTH.
To run it: save sizeless.py, with growth.py beside it; standard library only.
"""sizeless.py -- growth with size taken out of the cost: what the
divisibility order alone can author, and what only the ordering of the
integers by size supplies.
QUESTION. Every growth law of growth.py extends by the LEAST
admissible m, so it orders its candidates by size, the archimedean
place the rungs delete. Take size out. Between candidate windows Z/m
the only canonical structure is the unital ring maps, and a
window-visible cost is one that order sees: invariant under the
order's automorphisms, which permute the primes, so a function of m's
factorization shape. Which of the primorial tower's
features (fields, squarefree-ness, every prime arriving, the
increasing order of arrival) can such a cost buy, and which are size's
alone?
THE ARGUMENT (written before the engine).
(1) THE HOM ORDER. A unital map Z/a -> Z/b sends 1 to 1, so it is
x mod b, well defined iff b | a. Window maps order the moves by
divisibility, and distinct primes are an antichain: nothing in
the window world ranks one prime above another.
(2) COSTLESS INDEPENDENCE. With no cost every m coprime to M is
admissible, composites and prime powers included: seed 2 may
pick 9 and lose squarefree-ness, and seed 3 may pick 5, 7, 11,
... with 2 never entering. So fields, squarefree-ness and
healing are authored by the selection, not by the demand.
(3) FIELDS ARE WINDOW-PURCHASABLE. Let the cost be integer-valued,
bounded below and STRICTLY MONOTONE under proper divisibility
(d | m, d < m gives c(d) < c(m)); Omega,
the prime factor count with multiplicity, is one. A composite
coprime to M has a prime divisor, also coprime and cheaper, so
every pick is a prime, under every tie-break.
(4) THE PROPERNESS CRITERION. Under such a cost a prime p enters
under every tie-break iff its SUBLEVEL SET {q prime : c(q) <=
c(p)} is finite. While p is admissible every pick costs at most
c(p), so picks come from the sublevel set, each consumed for
good; a finite set runs out. An infinite one feeds a tie-break
that picks the others forever: under Omega every prime costs 1,
and the tie-break preferring odd primes starves 2. So every
prime arrives under every tie-break iff the cost is PROPER, every
sublevel set finite.
(5) THE ROUTE. Rank the primes by any bijection rho with the positive
integers and put c(m) = sum of a rho(p) over p^a || m. It is
strictly monotone under proper divisibility and proper, and from 1
its greedy walk takes the primes in the order rho. So every
proper strictly monotone cost buys the destination, properness
alone making the least cost exist, and its ranking, up to the
tie-break among primes of equal cost, the route: every
enumeration is some proper cost's. (A
window-visible cost, a function of shape, is never proper: every
prime costs the same. Corrected on review from "window data buys
the destination".)
(6) THE PRATT ORDER. One arrival rule reads only the rings Z/q: admit q only
when every prime factor of q - 1, the order of the unit group of
Z/q, already divides the modulus. That is the Pratt certificate
order (the parents of q are the primes of q - 1). It forces 2
first, and while 2 is the only prime seated, exactly the Fermat
primes are admissible; the increasing order is one of its linear
extensions, since every parent is smaller than its child.
Counting the extensions measures how much route the
rule supplies against the log2(n!) bits of an
arbitrary enumeration of the first n primes.
DESIGN. Standard library and growth.py.
H the hom order: x mod b is a unital ring map Z/a -> Z/b iff b | a,
every a, b in 2..60, checked by well-definedness, additivity and
multiplicativity on all of Z/a.
I costless independence: the two specimens of (2) as legal
trajectories.
F fields: greedy under Omega from seeds 1..6 for 20 steps under
three tie-breaks (least, largest below 200, odd first), candidates
every m <= 200 coprime to M; every pick prime.
P properness: under Omega with the odd-first tie-break, 30 steps
from 1, 2 never picked. Under three scrambled rank costs on the
first 30 primes (fixed seeds), 30 steps from 1: the picks are the
primes in rank order, each run's window set the same 30 primes.
R the Pratt order on the first n primes: the primes admissible from
the empty set and from {2} among the first 20; the increasing
order an extension over the first 300 primes; the extension count
at n = 5, 10, 15, 20 by a dynamic programme over down-sets.
PREDICTIONS, fixed before the run (from the script this replaces).
H1 3481 pairs (a, b), a map exactly at b | a.
I1 seed 2 then 9 is legal and Z/18 not squarefree; seed 3 then
5, 7, ..., 37 is legal and 2 never enters.
F1 every pick prime at 3 x 6 x 20 steps.
P1 2 is starved for 30 steps; three scrambled costs give three
distinct routes, each the rank order, one destination.
R1 only 2 from the empty set; after {2} exactly 3, 5, 17 among the
first 20 primes; the increasing order extends Pratt at 300
primes; the counts 6, 6048, 108662400 and 8506240142400, so at
n = 20 the rule supplies about 18 of the 61 route bits.
A KILL is any printed disagreement.
FINDINGS. Every prediction landed: 8/8 checks PASS. (Review turned
four checks into prints: I1's two specimens and R1's extension of
Pratt, which held by construction, and P1's one destination, which
the three route checks imply; its three distinct routes are printed.)
H1 3481 pairs, x mod b a unital map exactly at b | a, 0 off.
I1 seed 2 may pick 9 (Z/18 not squarefree); seed 3 may pick 5, ...,
37 (M = 3710369067405, odd).
F1 every pick prime under Omega, 3 tie-breaks x 6 seeds x 20 steps,
which holds by construction, Omega being 1 exactly at primes: a
specimen of (3), whose proof is the argument's.
P1 under Omega the odd-first walk from 1 picks 3, 5, 7, 11, ... and
never 2 in 30 steps; three scrambled rank costs give three
distinct routes, each its rank order, one destination.
R1 from the empty set only 2 is admissible, from {2} exactly 3, 5,
17; the increasing order extends Pratt over 300 primes; the
extension counts 6, 6048, 108662400, 8506240142400 at n = 5, 10,
15, 20, so at 20 primes 42.95 of the 61.08 route bits stay free
and the rule supplies 18.13.
Tiers: the hom order is a property; fields by a strict cost a rule,
proved; the properness criterion a criterion, proved both ways (the
specimen realizes the converse); the route a theorem (any
enumeration is a proper cost's), the Pratt count a measurement at
n <= 20.
RUN RECORD. 8/8, 0.3 s wall, 10 MB peak commit under a memory guard.
"""
import random
from math import gcd, lgamma, log, log2
from growth import CHECKS, PRIMES, check, factor, section
def omega_mult(m):
return sum(factor(m).values())
def squarefree(n):
return all(e == 1 for e in factor(n).values())
def section_h():
section("H THE HOM ORDER: unital maps between windows")
bad = pairs = 0
for a in range(2, 61):
for b in range(2, 61):
pairs += 1
ok = True
for x in range(a):
for y in range(a):
if ((x + y) % a) % b != (x + y) % b or \
((x * y) % a) % b != (x * y) % b:
ok = False
break
if not ok:
break
bad += ok != (a % b == 0)
check("H1 x mod b is a unital map Z/a -> Z/b exactly when b | a",
bad == 0, f"{pairs} pairs, {bad} off")
def section_i():
section("I COSTLESS INDEPENDENCE: every coprime m admissible")
ok1 = gcd(9, 2) == 1 and not squarefree(18)
M, ok2 = 3, True
for p in PRIMES[2:12]:
ok2 = ok2 and gcd(p, M) == 1
M *= p
ok2 = ok2 and M % 2 == 1
print(f" specimen: seed 2 then 9 is legal, Z/18 not squarefree: {ok1}")
print(f" specimen: seed 3 then 5..37 is legal, M = {M}, odd: {ok2}")
def greedy(seed, steps, cost, tie):
M, picks = seed, []
for _ in range(steps):
cands = [m for m in range(2, 201) if gcd(m, M) == 1]
low = min(cost(m) for m in cands)
pick = tie([m for m in cands if cost(m) == low])
picks.append(pick)
M *= pick
return picks
TIES = {
"least": min,
"largest": max,
"odd first": lambda c: min([m for m in c if m % 2] or c),
}
def section_f():
section("F FIELDS: a divisibility-strict cost picks primes")
bad = 0
for name, tie in TIES.items():
for seed in range(1, 7):
picks = greedy(seed, 20, omega_mult, tie)
bad += sum(factor(p) != {p: 1} for p in picks)
check("F1 every pick prime under Omega, 3 tie-breaks x 6 seeds x 20 "
"steps", bad == 0, f"{bad} composite picks")
def section_p():
section("P PROPERNESS AND THE ROUTE")
picks = greedy(1, 30, omega_mult, TIES["odd first"])
print(" Omega, odd first, from 1:", picks[:8], "...")
check("P1 under Omega the odd-first tie-break starves 2 for 30 steps",
2 not in picks)
first = PRIMES[:30]
routes = []
for s in (1, 2, 3):
order = first[:]
random.Random(s).shuffle(order)
rank = {p: i + 1 for i, p in enumerate(order)}
rank.update({p: i + 1 for i, p in enumerate(PRIMES) if p not in rank})
def cost(m, rank=rank):
return sum(a * rank[p] for p, a in factor(m).items())
route = greedy(1, 30, cost, min)
routes.append(route)
check(f"P1 scrambled cost {s}: the route is its rank order",
route == order)
dest = {frozenset(r) for r in routes}
print(f" {len({tuple(r) for r in routes})} distinct routes, "
f"{len(dest)} destination, the first 30 primes: "
f"{dest == {frozenset(first)}}")
def section_r():
section("R THE PRATT ORDER: an arrival rule read off the rings Z/q")
parents = {p: set(factor(p - 1)) if p > 2 else set() for p in PRIMES}
first20 = PRIMES[:20]
from_empty = [p for p in first20 if parents[p] <= set()]
from_two = [p for p in first20 if p != 2 and parents[p] <= {2}]
print(" admissible from {}:", from_empty, " from {2}:", from_two)
check("R1 only 2 from the empty set; then exactly 3, 5, 17",
from_empty == [2] and from_two == [3, 5, 17])
print(" the increasing order extends Pratt (a parent divides p - 1): "
f"{all(max(parents[p], default=0) < p for p in PRIMES[:300])} "
"over the first 300 primes")
counts = {}
for n in (5, 10, 15, 20):
ps = PRIMES[:n]
idx = {p: i for i, p in enumerate(ps)}
need = [sum(1 << idx[q] for q in parents[p]) for p in ps]
full = (1 << n) - 1
memo = {full: 1}
def ext(mask):
if mask in memo:
return memo[mask]
tot = 0
for i in range(n):
if not mask >> i & 1 and need[i] & mask == need[i]:
tot += ext(mask | 1 << i)
memo[mask] = tot
return tot
counts[n] = ext(0)
bits = log2(counts[20])
total = lgamma(21) / log(2)
print(f" linear extensions: {counts}")
print(f" n = 20: {bits:.2f} bits of freedom left of {total:.2f}, the "
f"rule supplies {total - bits:.2f}")
check("R1 the counts 6, 6048, 108662400, 8506240142400",
counts == {5: 6, 10: 6048, 15: 108662400, 20: 8506240142400})
def main():
section_h()
section_i()
section_f()
section_p()
section_r()
print()
print(f"{sum(CHECKS)}/{len(CHECKS)} checks passed")
raise SystemExit(0 if all(CHECKS) else 1)
if __name__ == "__main__":
main()