Research source · python
check_name_dominated_suffix.py
tools/research/check_name_dominated_suffix.py
220 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 7c16f692923a2e409c4e3dc865cc835a8ad1446412e41b506db90852e46e4ec7
#!/usr/bin/env python3
"""Immutable stage/readout audit. Python containers are finite model machinery.
The production argument implements the same bounded transitions with unary
fuel, numeral cursors and persistent trie frames; Python time is not its cost.
"""
from dataclasses import dataclass, replace
from random import Random
from itertools import combinations
import json
@dataclass(frozen=True)
class Row:
lower: int
bits: tuple
@staticmethod
def make(n):
return Row(n, tuple(int(x) for x in bin(n)[:1:-1]))
@dataclass(frozen=True)
class Node:
row: object = None
left: object = None
right: object = None
def put(root, name, row):
path = []
p = root or Node()
for bit in name:
path.append((p, bit))
p = (p.left if bit == '0' else p.right) or Node()
p = replace(p, row=row)
for parent, bit in reversed(path):
p = replace(parent, **{'left' if bit == '0' else 'right': p})
return p
@dataclass(frozen=True)
class Worker:
cap: int
todo: tuple
best: object = None
mode: str = 'tree'
row: object = None
cursor: int = 0
order: int = 0
spent: int = 0
done: bool = False
def step(self):
assert not self.done
s = replace(self, spent=self.spent + 1)
if s.mode == 'tree':
if not s.todo:
return replace(s, done=True)
(node, depth), *rest = s.todo
todo = tuple(rest)
if depth:
# Bounded two-child push. An immutable implementation uses frames.
for child in (node.right, node.left):
if child is not None:
todo = ((child, depth - 1),) + todo
return replace(s, todo=todo, row=node.row, cursor=0,
mode='read' if node.row else 'tree')
if s.mode == 'read':
if s.cursor == len(s.row.bits):
if s.best is None:
return replace(s, best=s.row, mode='tree')
return replace(s, mode='compare', cursor=0, order=0)
if s.cursor == s.cap:
return replace(s, mode='tree')
return replace(s, cursor=s.cursor + 1)
assert s.mode == 'compare'
i = s.cursor
a, b = s.row.bits, s.best.bits
if i == len(a) or i == len(b):
order = s.order if len(a) == len(b) else (-1 if len(a) < len(b) else 1)
return replace(s, best=s.row if order < 0 else s.best, mode='tree')
order = s.order if a[i] == b[i] else (-1 if a[i] < b[i] else 1)
return replace(s, cursor=i + 1, order=order)
@dataclass(frozen=True)
class Query:
root: object
common: int
c: int = 2
time: int = 0
worker: object = None
candidate: object = None
remaining: int = 0
lag: int = 0
found_at: int = 0
aligned_at: int = 0
stages: int = 0
worker_steps: int = 0
def tick(self):
t = self.time + 1
s = replace(self, time=t)
if self.candidate is not None:
if self.lag:
lag, rem = self.lag + 1, self.remaining
for _ in range(4):
if lag:
lag -= 1
rem -= 1
assert rem > 0 or lag == 0
s = replace(s, lag=lag, remaining=rem,
aligned_at=self.aligned_at or (t if not lag else 0))
else:
s = replace(s, remaining=self.remaining - 1)
return s
if t & (t - 1) == 0:
assert s.worker is None
k = t.bit_length() + 3
todo = ((s.root, k // s.c),) if s.root is not None else ()
s = replace(s, worker=Worker(k, todo), stages=s.stages + 1)
worker = s.worker
if worker:
before = worker.spent
for _ in range(512): # Q=64A, A=8 for the model transitions.
worker = worker.step()
if worker.done:
break
s = replace(s, worker_steps=s.worker_steps + worker.spent - before)
if worker.done:
bound = 8 * (worker.cap + 1) * 2 ** (worker.cap // s.c + 1)
assert worker.spent <= bound
s = replace(s, worker=None)
if worker.best is not None:
lag = max(0, t - 4)
rem = worker.best.lower - min(t, 4)
assert t < worker.best.lower
s = replace(s, candidate=worker.best, lag=lag, remaining=rem,
found_at=t, aligned_at=t if not lag else 0)
else:
s = replace(s, worker=worker)
return s
def answer(self):
return self.candidate is not None and self.lag == 0 and self.remaining <= 0 and self.time <= self.common
def main():
rng = Random(189)
prefixes = stages = steps = forks = delayed = 0
for trial in range(120):
c = rng.choice((2, 3, 4))
root = None
mapping = {}
versions = []
for _ in range(rng.randrange(2, 55)):
length = rng.randrange(1, 7)
name = ''.join(rng.choice('01') for _ in range(length))
b = (1 << (c * length)) + rng.randrange(0, 300)
# Some payloads remain far longer than every tested stage cap.
if rng.randrange(7) == 0:
b = 1 << 100
mapping[name] = Row.make(b)
root = put(root, name, mapping[name])
versions.append((root, dict(mapping)))
for root, rows in versions[::max(1, len(versions)//3)]:
common = max(row.lower for row in rows.values()) + 100
truth = min(row.lower for row in rows.values())
query = Query(root, common, c)
saved = []
for n in range(1, min(common + 2, 1400) + 1):
if n % 137 == 0:
saved.append(query)
query = query.tick()
assert query.answer() == (truth <= n <= common)
prefixes += 1
if query.aligned_at > query.found_at:
delayed += 1
stages += query.stages
steps += query.worker_steps
for old in saved:
newer = old.tick()
assert old.time + 1 == newer.time
assert newer.answer() == (truth <= newer.time <= common)
forks += 1
# Dense same-length family; a final relevant scan and nontrivial catch-up.
root = None
for i in range(128):
name = format(i, '07b')
root = put(root, name, Row.make(16384 + i))
query = Query(root, 17000)
for n in range(1, 17003):
query = query.tick()
assert query.answer() == (16384 <= n <= 17000)
prefixes += 1
assert query.aligned_at > query.found_at
# Producer component update is checked against independent sorted runs.
producer = 0
for mask in range(1 << 9):
widths = {i + 1 for i in range(9) if mask >> i & 1}
old = sum(j - 1 not in widths for j in widths)
for n in range(1, 12):
updated = old if n in widths else old + 1 - int(n - 1 in widths) - int(n + 1 in widths)
new = widths | {n}
assert updated == sum(j - 1 not in new for j in new)
assert (updated == 1) == (len(new) == max(new) - min(new) + 1)
producer += 1
# Exact phase inequality, including the first phase and ceiling endpoints.
for c in range(2, 9):
for k in range(4, 201):
w = 8 * (k + 1) * 2 ** (k // c + 1)
start = 2 ** (k - 4)
finish = start + (w + 511) // 512 - 1
assert finish < 2 * start
if k > 4:
assert finish + (finish + 2) // 3 < 2 ** (k - 1)
print(json.dumps(dict(query_prefixes=prefixes, retained_query_forks=forks,
stages=stages, worker_steps=steps, delayed_random_alignments=delayed,
dense_found_at=query.found_at, dense_aligned_at=query.aligned_at,
component_updates=producer, phase_inequalities=7*197), indent=2))
if __name__ == '__main__':
main()