/machines/1RB0RA_1LC0LD_1LE1LD_0LB0RE_1RF0LA_---0RA/check_proof.py · raw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | #!/usr/bin/env python3 """check_proof.py, pool #7 = 1RB0RA_1LC0LD_1LE1LD_0LB0RE_1RF0LA_---0RA: the delta proof against kill #30 (1RB0RF_1RC1RF_1LD0RE_---0LE_1LA0LE_0RA0LC). Checks every claim of proof.md's delta section by direct simulation and with #30's own check functions, which are imported from #30's check_proof.py (not copied). python3 -B check_proof.py [--quick] [--seed S] (writes data/check_proof_seed<S>.json unless --quick) Claim ids (proof.md, section "Delta proof"): X0 the string is the holdout-list entry (740 list) X1 the renaming + mirror: the unique (permutation, orientation) mapping #7's table onto #30's; #7's A is #30's E X2 lockstep: #7 from the blank tape = the mirror image of #30's table run from the blank tape in state E, renamed X3 initial segment, #7's own table: every L-form configuration up to step 1059 (e1..e5), the exact tapes at steps 1059 (mirror of L(16, 0001)) and 1114 (mirror of K(1, 17, t1)), no halt X4 #30's orbit invariant (I1)-(I4) at e5, clause by clause; e1..e4 cannot serve as the base X5 rules-only orbit from e5 = the TM's left records (fresh Python run in #30's frame; stored C log if present) X6 no merge: #7's orbit shares no epoch with #30's or W4-1's below N = 20,000 (so #7 needs its own finite part) D #30's section D (Lemma D links, FIN, H3), its source run unchanged except for the start (e5 instead of #30's epoch 3) V the .v route: rules-only orbit from K(1,17,t1) to the first epoch with N >= 17,705 (687 epochs e5..e691, landing at e692), #30's Inv there, and Inv carried along the orbit to the end of section D RQ the Rocq draft of the plan (rocq/M7_draft.v) and its stored check_kill log (if present) #30's table-level sections (A, RP, LP, B, E, R, D6, H, D.3, threshold, ADV) run unchanged: they depend only on the transition table, which #7 shares with #30 up to X1.""" import sys, os, json, time, itertools, inspect, importlib.util HERE = os.path.dirname(os.path.abspath(__file__)) P30 = os.path.join(os.path.dirname(HERE), '1RB0RF_1RC1RF_1LD0RE_---0LE_1LA0LE_0RA0LC') _spec = importlib.util.spec_from_file_location('cp30', os.path.join(P30, 'check_proof.py')) cp30 = importlib.util.module_from_spec(_spec); _spec.loader.exec_module(cp30) # seeds random with --seed, reads --quick common, M, rec, RES = cp30.common, cp30.M, cp30.rec, cp30.RES from fs_val_rules import inG # #30's scripts dir is on sys.path now (cp30 put it there) QUICK, SEED = cp30.QUICK, cp30.SEED T0 = time.time() TM7 = '1RB0RA_1LC0LD_1LE1LD_0LB0RE_1RF0LA_---0RA' TM30 = common.TMS TMW41 = '1RB1RF_1LC0RD_---0LD_1LE0LD_1RA0RF_0RE0LB' # Wave 4 pick W4-1: the table's third start ST = 'ABCDEF' norm = cp30.norm def derive(fn, subs, name): """fn's source with each (old, new) substitution applied exactly once, compiled in fn's own module globals. Used to run #30's code unchanged except for its hard-coded start.""" src = inspect.getsource(fn) for old, new in subs: assert src.count(old) == 1, (fn.__name__, old) src = src.replace(old, new) g = fn.__globals__ exec(compile(src, f'<{name} derived from {fn.__module__}.{fn.__name__}>', 'exec'), g) return g[name] # common.events with the start state as a parameter (it is hard-coded to A there) events_from = derive(common.events, [('def events(end, size=1 << 16):', 'def events_from(q0, end, size=1 << 16):'), ('pos = off; q = 0;', 'pos = off; q = q0;')], 'events_from') # #30's section D with the start (epoch 3 = L(7, 000010001)) as a parameter section_D_from = derive(cp30.section_D, [('def section_D(maxN, Nstar):', 'def section_D_from(maxN, Nstar, k0, T0, ep0):'), ("k, T = 7, '000010001'", 'k, T = k0, T0'), ('ep = 2;', 'ep = ep0 - 1;'), ("'epochs_3..below_N*': ep - 3", "'epochs_base..below_N*': ep - ep0")], 'section_D_from') # --------------------------------------------------------------------------------------------------------------- def section_X0(): hd = os.path.join(HERE, '..', '..', 'data', 'holdouts') lines = [l.rstrip('\n') for l in open(os.path.join(hd, 'BB6_holdouts_740.txt'))] rec('X0 TM string is byte-exact in the 740-machine holdout list (line 381)', lines.count(TM7) == 1 and lines[380] == TM7, [i + 1 for i, l in enumerate(lines) if l == TM7]) lists = sorted(f for f in os.listdir(hd) if f.endswith('.txt')) counts = {f: [l.rstrip('\n') for l in open(os.path.join(hd, f))].count(TM7) for f in lists} rec('X0 TM string is byte-exact (once) in every stored holdout list', all(c == 1 for c in counts.values()) and len(counts) > 20, counts) def conjugacies(src, dst): """every (perm, mirror) with dst[perm q][s] = (w, +-d, perm q') whenever src[q][s] = (w, d, q'), and the same undefined transitions""" ts, td = common.table(src), common.table(dst) out = [] for perm in itertools.permutations(range(6)): for mirror in (False, True): ok = True for q in range(6): for s in (0, 1): a, b = ts[q][s], td[perm[q]][s] if a is None or b is None: ok &= a is None and b is None else: ok &= b == (a[0], -a[1] if mirror else a[1], perm[a[2]]) if ok: out.append((perm, mirror)) return out PERM = (4, 0, 1, 5, 2, 3) # #7 state -> #30 state: A->E, B->A, C->B, D->F, E->C, F->D (mirror) INV = tuple(PERM.index(i) for i in range(6)) def section_X1(): c = conjugacies(TM7, TM30) rec('X1 #7 = #30 mirrored, states A,B,C,D,E,F -> E,A,B,F,C,D; unique among 720 x 2', c == [(PERM, True)], c) rec("X1 #7's start A is #30's state E (the halting transition #7 F0 is #30's D0)", PERM[0] == 4 and common.table(TM7)[5][0] is None and common.table(TM30)[3][0] is None, None) c4 = conjugacies(TMW41, TM30) rec("X1 W4-1 = #30 renamed (no mirror), its start A is #30's state B: the third start of the same table", len(c4) == 1 and c4[0][1] is False and c4[0][0][0] == 1, c4) RES['_X1'] = {'perm #7->#30': ''.join(ST[PERM[q]] for q in range(6)), 'mirror': True, 'perm #30->#7': ''.join(ST[INV[q]] for q in range(6)), 'W4-1 perm W4-1->#30': ''.join(ST[i] for i in c4[0][0])} def section_X2(nsteps): """step-by-step: #7 at cell x in state q <-> #30's table at cell -x in state PERM[q], same tape mirrored""" t7, t30 = common.table(TM7), common.table(TM30) size = 1 << 16; off = size // 2 a7 = bytearray(size); a30 = bytearray(size); p7 = p30 = off; q7, q30 = 0, 4 ok = True; checks = 0; marks = {15, 81, 183, 573, 1059, 1114, 2915} for st in range(1, nsteps + 1): r7, r30 = t7[q7][a7[p7]], t30[q30][a30[p30]] if r7 is None or r30 is None: ok = False; break a7[p7] = r7[0]; p7 += r7[1]; q7 = r7[2] a30[p30] = r30[0]; p30 += r30[1]; q30 = r30[2] if q30 != PERM[q7] or p7 - off != off - p30: ok = False; break if st in marks or st % 100000 == 0: checks += 1 if a7[1:] != a30[:0:-1] or a7[0] or a30[0]: # a7[off + x] == a30[off - x] for every cell x ok = False; break rec('X2 lockstep: #7 from blank in A = mirror of #30 table from blank in E, renamed (every step; full tapes at checkpoints)', ok and checks > 0, (st, q7, q30, p7 - off, off - p30)) RES['_X2'] = {'steps': nsteps, 'full_tape_checks': checks} def lform_7(tape, pos, q, hi): """#7's frame: is this the mirror image of an L-form configuration 0^inf <A 101 (001)^k T 0^inf of #30's frame? (#30's A is #7's B; the head reads a blank, every cell right of it is blank, the cells left of it read 1,0,1 going left.) Returns (k, T) or None.""" if q != INV[0] or tape[pos] != 0 or (tape[pos - 1], tape[pos - 2], tape[pos - 3]) != (1, 0, 1): return None if any(tape[pos + 1:hi + 2]): return None lo = 0 while tape[lo] == 0: lo += 1 s = ''.join(map(str, tape[pos - 1:lo - 1 if lo else None:-1])) # read leftwards = #30's left-to-right j = 3; k = 0 while s[j:j + 3] == '001': j += 3; k += 1 return k, s[j:] E_RECORDS = [(15, 0, '0001'), (81, 1, '000010010001'), (183, 3, '0001000010001'), (573, 5, '000010010010001000110010001'), (1059, 16, '0001')] def section_X3(): t7 = common.table(TM7) size = 1 << 14; off = size // 2 tape = bytearray(size); pos = off; q = 0; hi = pos; got = []; halted = False; snap = {} for st in range(1, 1115): r = t7[q][tape[pos]] if r is None: halted = True; break tape[pos] = r[0]; pos += r[1]; q = r[2]; hi = max(hi, pos) L = lform_7(tape, pos, q, hi) if L: got.append((st, L[0], L[1])) if st in (1059, 1114): snap[st] = (bytes(tape), pos, q) rec('X3 #7 own table: the L-form configurations up to step 1059 are exactly e1..e5 (steps 15, 81, 183, 573, 1059)', not halted and got == E_RECORDS, got) # step 1059: 0^inf 1000 (100)^16 101 B> 0^inf = mirror of L(16, 0001) = 0^inf <A 101 (001)^16 0001 0^inf tp, p, q = snap[1059] w = '1000' + '100' * 16 + '101' ok = q == INV[0] and tp[p] == 0 and ''.join(map(str, tp[p - len(w):p])) == w and not any(tp[:p - len(w)]) and not any(tp[p:]) rec("X3 step 1059: #7's tape is exactly 0^inf 1000 (100)^16 101 B> 0^inf, the mirror of L(16, 0001)", ok, (p - off, ST[q])) # step 1114: 0^inf 1 <E (110)^17 0 011 0^inf = mirror of K(1, 17, t1) = 0^inf 110 0 (011)^17 C> 1 0^inf tp, p, q = snap[1114] w = '1' + '110' * 17 + '0' + '011' ok = q == INV[2] and ''.join(map(str, tp[p:p + len(w)])) == w and not any(tp[:p]) and not any(tp[p + len(w):]) rec("X3 step 1114: #7's tape is exactly 0^inf 1 <E (110)^17 0 011 0^inf, the mirror of K(1, 17, t1)", ok, (p - off, ST[q])) # the same records in #30's frame (start E), and the restart R: L(16, 000 1) -> K(1, 17, 1) in 3*16 + 7 = 55 steps ev = [] for e in events_from(4, 1115): if e[0] in ('L', 'HALT'): ev.append(e) if e[0] == 'K' and e[1] == 1114: ev.append(e) rec("X3 #30's frame from state E: the same left records, then K(1, 17, '1') at step 1114 = 1059 + 3*16 + 7", ev == [('L',) + r for r in E_RECORDS] + [('K', 1114, 1, 17, '1')], ev) # --------------------------------------------------------------------------------------------------------------- def section_X4(): """#30's invariant (proof.md D.6) at e5, clause by clause, and why no earlier record can be the base""" k, T = 16, '0001' a, N, Y = M.restart(k, T) rec('X4 e5 = L(16, 000 Y) with Y = 1, restart R gives K(1, N, Y) with N = k + 1 = 17', (a, N, Y) == (1, 17, '1'), (a, N, Y)) rec('X4 Y = 1 is in H (section 4), so Lemma H / the corollary of section 4 apply', cp30.inH(Y), Y) kind = cp30.classify(Y) rec('X4 (I1) Y is special: Y = t1 is in G', kind == 'G', kind) rec('X4 (I2) vacuous (Y is not ordinary, no W)', not Y.startswith('11'), Y) r = cp30.run_epoch(N, Y) G0, Dl0 = cp30.Gfix(0) # D.6's k_t is k(W_t), the number of blocks of W_t (0 for a special residue), not the record index k of L(k, T): # kappa_5 = k(W_5) = 0. Read with the record index 16, (I4) would fail at the base (N_lo(16) = 2^19 - 2^14 > 17). kW = 0 if kind else len(cp30.parse_residue(Y)[3]) rec('X4 kappa_5 = k(W_5) = 0 (special residue, no W), not the record index k = 16 of L(16, 0001)', kind != '' and kW == 0 and k == 16 and cp30.N_lo(16) == 2 ** 19 - 2 ** 14 > N, (kind, kW, cp30.N_lo(16))) rec('X4 (I3) k(W) = 0, c = 0 (special), kappa = 0: c <= Gamma(0, 0) = 0 and k(W) + c = 0 <= G(0) = 0', r['c'] == 0 and cp30.gamma_k(kW, 0, Dl0) == 0 and kW + r['c'] <= G0 == 0, (kW, r['c'], cp30.gamma_k(kW, 0, Dl0), G0)) rec('X4 (I4) N = 17 >= N_lo(kappa_5) = N_lo(0) = 2^3 - 2^(floor((G(0)+1)/2)+4) = -8', N >= cp30.N_lo(kW) == -8, cp30.N_lo(kW)) rec('X4 epoch e5 finishes: beta = 0 <= N - 2 (Y in G), next record = model', r['beta'] == 0 and (r['k2'], r['T2']) == (23, '0001000010001'), (r['beta'], r['k2'], r['T2'])) RES['_X4'] = {'N': N, 'Y': Y, 'record index k': k, 'k(W_5)': kW, 'kappa_5': kW, 'c': r['c'], 'G(0)': G0, 'Gamma(0,0)': cp30.gamma_k(0, 0, Dl0), 'N_lo(0)': cp30.N_lo(0), 'N_lo(16), not used': cp30.N_lo(16), 'next': (r['k2'], r['T2'])} # e1..e4: e1 has N = 1 (beta <= N - 2 is false although its eat is at a G word); e2 and e3 have special residues # whose digestion does not fit (beta = 2 > 0, beta = 11 > 2: the model meets an eat outside G); e4's residue is # not in H. So the induction cannot start before e5. def unsafe(N, Y): try: cp30.run_epoch(N, Y); return False except (M.Unsafe, M.Unknown): return True nb = [(1, '1', cp30.classify('1') == 'G' and 0 > 1 - 2), (2, '010010001', cp30.classify('010010001') == 'E*' and unsafe(2, '010010001')), (4, '1000010001', cp30.classify('1000010001') == 'E*' and unsafe(4, '1000010001')), (6, '010010010001000110010001', not cp30.inH('010010010001000110010001') and cp30.classify('010010010001000110010001') == '?')] for N_, Y_, ok in nb: rec('X4n e1..e4 are not a valid base (e1: N = 1; e2, e3: digestion does not fit, eat outside G; e4: Y not in H)', ok, (N_, Y_)) rec('X4n the restarts of e1..e4 match the records (N = k + 1)', [M.restart(k_, T_)[1:] for _, k_, T_ in E_RECORDS[:4]] == [(N_, Y_) for N_, Y_, _ in nb], None) # e4's epoch itself is computed by the rules (LP0/LP11/LPC on its prefix, then eats at G words) and ends at e5; # it is still outside the family because (I1) fails there (Y4 is neither ordinary nor special) try: e4 = M.epoch(1, 6, '010010010001000110010001') except (M.Unsafe, M.Unknown) as ex: e4 = str(ex) rec("X4n e4's epoch is rule-covered (eats at G words) and ends at e5 = L(16, 0001), but (I1) fails at e4", e4 == (16, '0001'), e4) def section_X5(): end = 3 * 10**6 if QUICK else 2 * 10**7 tmL = [(e[2], e[3]) for e in events_from(4, end) if e[0] == 'L'] M.FAST = True k, T = tmL[4]; ok = (k, T) == (16, '0001') for i in range(5, len(tmL)): a, b, w = M.restart(k, T); k, T = M.epoch(a, b, w) ok &= (k, T) == tmL[i] rec('X5 rules-only orbit from e5 = TM left records (fresh Python run, #30 frame from E)', ok and len(tmL) > 10, len(tmL)) RES['_X5_python'] = {'steps': end, 'records': len(tmL), 'from_e5': len(tmL) - 4} path = os.path.join(HERE, 'data', 'orbit_E_1e11_LE.txt') if os.path.exists(path): lines = open(path).read().split('\n') tm = [l.split() for l in lines if l.startswith('L ')] tmL = [(int(f[2]), f[3] if len(f) > 3 else '') for f in tm] halted = any(l.startswith(('HALT', 'EDGE')) for l in lines) end_line = [l for l in lines if l.startswith('END')] k, T = tmL[4]; good = 0 for i in range(5, len(tmL)): a, b, w = M.restart(k, T); k, T = M.epoch(a, b, w) good += (k, T) == tmL[i] rec('X5 rules-only orbit from e5 = stored C log (scripts/delta30/orbit_E.c, 1e11 steps), no halt', good == len(tmL) - 5 and not halted and bool(end_line), (good, len(tmL) - 5, end_line[:1])) RES['_X5_C'] = {'records': len(tmL), 'from_e5_checked': len(tmL) - 5, 'last_N': tmL[-1][0] + 1, 'end': end_line[:1]} def section_X6(Nmax=20000): """#7's orbit from e5 shares no epoch (N, Y) with #30's orbit from its epoch 3 or with W4-1's orbit from its first special-residue record (#30's table from state B: L(2, 0001) at step 42), up to N >= Nmax: #30's finite part cannot be reused, #7 needs its own""" ev = [e for e in events_from(1, 400) if e[0] in ('L', 'HALT')] rec("X6 W4-1 (#30's table from state B): left records L(0,'')@4, L(2,0001)@42, L(7,0001)@194", ev[:3] == [('L', 4, 0, ''), ('L', 42, 2, '0001'), ('L', 194, 7, '0001')], ev) M.FAST = True def orb(k, T): out = [] while True: a, b, w = M.restart(k, T); out.append((b, w)) if b >= Nmax: return out k, T = M.epoch(a, b, w) o7, o30, o41 = orb(16, '0001'), orb(7, '000010001'), orb(2, '0001') rec('X6 no merge: #7 (from e5), #30 (from epoch 3) and W4-1 (from L(2,0001)) share no epoch (N, Y) up to N >= %d' % Nmax, not (set(o7) & set(o30)) and not (set(o7) & set(o41)) and not (set(o30) & set(o41)), (len(o7), len(o30), len(o41))) RES['_X6'] = {'epochs to N >= %d' % Nmax: {'#7': len(o7), '#30': len(o30), 'W4-1': len(o41)}, 'first N': {'#7': [x[0] for x in o7[:8]], '#30': [x[0] for x in o30[:8]], 'W4-1': [x[0] for x in o41[:8]]}} # --------------------------------------------------------------------------------------------------------------- # the .v route (#30's .v, Sections 10-11): the bound functions, transcribed from the .v def w_(q): return 2 ** ((q + 1) // 2) def v2(q): return 2 ** (q // 2) def Ws(P): return sum(w_(q) for q in range(P)) def V2s(P): return sum(v2(q) for q in range(P)) def Pf(k): return max(12, k + 3) def Af(k): return 5 * Ws(Pf(k)) + 6 * w_(Pf(k)) + 2 * Ws(k) def Bf(k): return Af(k) + 5 * V2s(Pf(k)) + 6 * v2(Pf(k)) + 2 ** (k + 1) def Xf(k): return Af(k) + 5 * Pf(k) + 7 def Costf(k): return 2 * Xf(k) + 2 + 2 * Af(k) + 11 * Ws(Pf(k)) + 13 * w_(Pf(k)) def Nlo(k): return max(0, 2 ** (k + 3) - 8 * 2 ** ((Pf(k) + 3) // 2)) # nat subtraction NSTAR_V = 17705 SPECIAL_V = {'1', '010010001', '1000010001'} # t1, p01 1 t1, p10 (p00 t2) def Mw(es): return sum(w_(q) * e for q, e in enumerate(es)) def M2(es): return sum(2 ** (q + 1) * e for q, e in enumerate(es)) def inv_v(k, N, Y): """#30's Inv k N y, clause by clause: returns (ok, dict of clauses)""" Y = norm(Y); cl = {'N >= Nstar = 17705': N >= NSTAR_V, 'N >= Nlo(k) = %d' % Nlo(k): N >= Nlo(k)} if Y in SPECIAL_V: cl['Y special'] = True else: x, W, ds, es, t = cp30.parse_residue(Y) cl['Y = 11 a^x z W with W in G'] = Y.startswith('11') and t >= 0 and inG(W) cl['k(W) = %d <= k' % len(es)] = len(es) <= k cl['Mw(W) = %d <= Af(k) = %d' % (Mw(es), Af(k))] = Mw(es) <= Af(k) cl['M2(W) = %d <= Bf(k) = %d' % (M2(es), Bf(k))] = M2(es) <= Bf(k) cl['x = %d <= Xf(k) = %d' % (x, Xf(k))] = x <= Xf(k) return all(cl.values()), cl def orbit_v(N, Y, n): """the .v's orbit f n N y : n epochs of the rules-only model from K(1, N, Y)""" M.FAST = True for _ in range(n): k, T = M.epoch(1, N, Y); _, N, Y = M.restart(k, T) return N, Y def section_V(maxN): # transcription self-test against #30's write-up (section 8.3 table) and #30's fin694 / inv694 tab = {8: (12, 1419, 8725, 1024), 9: (12, 1451, 8853, 3072), 10: (13, 2219, 13471, 6144), 11: (14, 2923, 17705, 14336), 12: (15, 4459, 26931, 28672), 13: (16, 5867, 35389, 61440)} rec("V0 bound functions reproduce #30's table (P, A, Cost + 2, N_lo') for kappa = 8..13", all((Pf(k), Af(k), Costf(k) + 2, Nlo(k)) == v for k, v in tab.items()), {k: (Pf(k), Af(k), Costf(k) + 2, Nlo(k)) for k in tab}) rec('V0 #30 N2: Cost(k) + 2 <= 17,705 for k <= 11 and <= Nlo(k) for 12 <= k < 200', all(Costf(k) + 2 <= NSTAR_V for k in range(12)) and all(Costf(k) + 2 <= Nlo(k) for k in range(12, 200)), None) B694 = [(0, 17), (1, 1), (1, 1), (1, 1), (1, 1), (0, 1), (0, 1), (0, 1), (1, 1), (0, 0)] Y694 = norm('11' + '001' * 7 + '000' + M.build_G([d for d, _ in B694], [e for _, e in B694], 0)) N30, Yt = orbit_v(8, '010001', 691) ok30, cl30 = inv_v(10, N30, Yt) rec("V0 Python model = #30's fin694: orbit 691 8 t2 = (17713, Y694), and Inv 10 17713 Y694 (Mw 77, M2 1054)", (N30, Yt) == (17713, Y694) and ok30 and Mw([e for _, e in B694]) == 77 and M2([e for _, e in B694]) == 1054, (N30, cl30)) # #7: from K(1, 17, t1) to the first epoch with N >= 17,705 M.FAST = True N, Y, n = 17, '1', 0 while N < NSTAR_V: Nprev = N k, T = M.epoch(1, N, Y); _, N, Y = M.restart(k, T); n += 1 # orbit n runs the n epochs e5 .. e(n+4) and lands at e(n+5), the first record with N >= 17,705 rec('V1 orbit 687 17 t1 runs the 687 epochs e5..e691 and lands at e692 (N = 17,724), the first record with ' 'N >= 17,705; e691 has N = 17,670', (n, n + 4, n + 5, Nprev, N) == (687, 691, 692, 17670, 17724), (n, Nprev, N)) x, W, ds, es, t = cp30.parse_residue(Y) if not cp30.classify(Y) else (None, None, [], [], None) kap = len(es) ok, cl = inv_v(kap, N, Y) rec('V1 #7 finite part: orbit %d 17 t1 = (%d, Y_%d); Inv %d N Y holds there, clause by clause' % (n, N, n + 5, kap), ok, cl) good = [kk for kk in range(0, 40) if inv_v(kk, N, Y)[0]] RES['_V'] = {'epochs_from_K(1,17,t1)': n, 'epochs_run': 'e5..e%d' % (n + 4), 'N_e%d' % (n + 4): Nprev, 'epoch_index_#7': n + 5, 'N': N, 'x': x, 'blocks (d,e)': list(zip(ds, es)), 'tail': t, 'kappa': kap, 'm(W)': (4 + t) * 2 ** kap + sum(d << i for i, d in enumerate(ds)) if t is not None else None, 'clauses': cl, 'kappas_with_Inv': good} # Inv carried along: kappa' = max(kappa, k(W')), as in the .v's inv_step (proved there; checked here on the orbit) bad = 0; steps = 0 while N < maxN: k, T = M.epoch(1, N, Y); _, N, Y = M.restart(k, T); steps += 1 if not cp30.classify(Y): kap = max(kap, len(cp30.parse_residue(Y)[3])) bad += not inv_v(kap, N, Y)[0] rec("V2 #30's Inv holds at every later epoch of #7's orbit (kappa = running max), to the end of section D", bad == 0 and steps > 0, (bad, steps)) RES['_V']['carried_epochs'] = steps; RES['_V']['kappa_end'] = kap RES['_V']['_blocks_e692'] = list(zip(ds, es)) def section_RQ(): """the Rocq draft of section 6's plan (rocq/M7_draft.v) and its stored check_kill log: the log is a PASS for this exact file, the draft states init7 / fin7 / inv7 / nonhalt_E / perm7 / nonhalt as the plan says, and its Y692 blocks are the ones the Python model computes at e692 (section V)""" vf, lf = os.path.join(HERE, 'rocq', 'M7_draft.v'), os.path.join(HERE, 'rocq', 'check_kill_draft.out') if not (os.path.exists(vf) and os.path.exists(lf)): return import hashlib, re src = open(vf).read(); sha = hashlib.sha256(src.encode()).hexdigest() js = [json.loads(l[6:]) for l in open(lf) if l.startswith('JSON: ')] rec('RQ stored check_kill log: PASS for this exact draft (sha256), tm = #7, theorem nonhalt, 0 assumptions, coqchk pass', len(js) == 1 and js[0]['result'] == 'PASS' and js[0]['sha256'] == sha and js[0]['tm'] == TM7 and js[0]['theorem'] == 'nonhalt' and js[0]['assumptions'] == [] and js[0]['coqchk'] == 'pass', (sha[:16], js[0]['result'] if js else None)) stmts = ['Definition tm := Eval compute in (TM_from_str "%s").' % TM7, 'Definition tm30 := Eval compute in (TM_from_str "%s").' % TM30, 'Lemma fin7 : orbit 100000 687 17 t1 = Some (17724, Y692).', 'Lemma inv7 : Inv 10 17724 Y692.', 'Lemma init7 : E;; tape0 -->* K 17 t1.', 'Lemma nonhalt_E : ~ halts tm30 (E;; tape0).', 'Lemma perm7 : Perm (flip tm) tm30 phi.', 'Lemma nonhalt: ~halts tm c0.', 'match q with A => E | B => A | C => B | D => F | E => C | F => D end.', 'change (E, tape0) with (cconfig_to_config (nil,nil,S0,E));', 'cbn - [tape0]', 'Definition Y692 : word := p11 16 (gw B692 0).'] rec('RQ the draft states the plan of section 6 (init7, fin7, inv7, nonhalt_E, phi = sigma, perm7, nonhalt)', all(src.count(s) == 1 for s in stmts), [s for s in stmts if src.count(s) != 1]) m = re.search(r'Definition B692 : blks := \[(.*?)\]\.', src, re.S) b692 = [(d == 'true', int(e)) for d, e in re.findall(r'\((true|false),\s*(\d+)\)', m.group(1))] if m else None rec("RQ the draft's B692 = the blocks of W at e692 from the Python model (x = 16, 10 blocks, bare tail)", b692 == [(bool(d), e) for d, e in RES['_V']['_blocks_e692']] and RES['_V']['x'] == 16 and RES['_V']['tail'] == 0, b692) m = re.search(r'Definition phi \(q : Q\) : Q :=\s*match q with (.*?) end\.', src, re.S) perm = dict(re.findall(r'([A-F]) => ([A-F])', m.group(1))) if m else {} rec("RQ the draft's phi is X1's sigma (the unique conjugacy)", len(perm) == 6 and all(perm[ST[q]] == ST[PERM[q]] for q in range(6)), perm) RES['_RQ'] = {'draft_sha256': sha, 'compile_seconds': js[0].get('compile_seconds'), 'coqchk_seconds': js[0].get('coqchk_seconds'), 'checked_at': js[0].get('checked_at')} # --------------------------------------------------------------------------------------------------------------- def main(): section_X0(); section_X1(); section_X2(2 * 10**5 if QUICK else 2 * 10**6); section_X3() print('X0-X3 done', round(time.time() - T0, 1), flush=True) # #30's table-level sections, unchanged cp30.section_A(); cp30.section_RP(); cp30.section_LP(); cp30.section_B(); cp30.section_E(); cp30.section_R() cp30.section_D6(); cp30.section_H(); cp30.section_D3() print("#30 table-level sections done", round(time.time() - T0, 1), flush=True) cp30.TAU_ = cp30.tau(); cp30.TEND = cp30.end_extra() RES['_tau'] = cp30.TAU_; RES['_T_end_extra'] = cp30.TEND k0, Nstar, around = cp30.analytic_threshold(cp30.TAU_, 48 if QUICK else 160) RES['_analytic'] = {'tau': cp30.TAU_, 'T': cp30.TEND, 'last_failing_kappa': k0, 'N_star': Nstar} print('threshold done, N* =', Nstar, round(time.time() - T0, 1), flush=True) section_X4(); section_X5(); section_X6(); print('X4-X6 done', round(time.time() - T0, 1), flush=True) maxN = max(Nstar + 1, 400000) if not QUICK else max(Nstar + 1, 20000) section_D_from(maxN, Nstar, 16, '0001', 5); print('D done', round(time.time() - T0, 1), flush=True) section_V(maxN); section_RQ(); print('V, RQ done', round(time.time() - T0, 1), flush=True) cp30.section_ADV(1500 if not QUICK else 200, 40 if not QUICK else 8); print('ADV done', round(time.time() - T0, 1), flush=True) bad = 0 for cid in sorted(k for k in RES if not k.startswith('_')): r = RES[cid]; ok = r['pass'] == r['n']; bad += not ok print(('PASS ' if ok else 'FAIL ') + f"{r['pass']}/{r['n']} {cid}" + ('' if ok else ' e.g. ' + str(r['fail'][:1]))) for k in sorted(k for k in RES if k.startswith('_') and k not in ('_ESTAR',)): print(k, RES[k]) print('ALL PASS' if bad == 0 else f'{bad} CLAIMS FAIL', f'({round(time.time() - T0, 1)} s, seed {SEED})') if not QUICK: os.makedirs(os.path.join(HERE, 'data'), exist_ok=True) with open(os.path.join(HERE, f'data/check_proof_seed{SEED}.json'), 'w') as f: json.dump({'seed': SEED, 'seconds': round(time.time() - T0, 1), 'claims': RES}, f, indent=1, default=str) if __name__ == '__main__': main() |