Research source · python
check_branching_coefficient_readers.py
tools/research/check_branching_coefficient_readers.py
298 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 2d565221590d1fb835ceaeea9081a698f22b309129351e614bee8f7d88295d31
#!/usr/bin/env python3
"""Finite independent audit of prepared branching readers, not a native scheduler."""
from dataclasses import dataclass
from collections import Counter
from itertools import product
import json
import random
@dataclass(frozen=True)
class Trie:
refs: int = 0
zero: object = None
one: object = None
@dataclass(frozen=True)
class Profile:
count: int
bad: bool
tail: object
def change(root, word, delta, breadth):
"""Persistent path copy and a separately maintained depth-count profile."""
changes = [0] * len(word)
touches = 0
def walk(node, i):
nonlocal touches
touches += 1
old = node
node = node or Trie()
if i == len(word):
refs = node.refs + delta
assert refs >= 0
out = Trie(refs, node.zero, node.one)
else:
bit = word[i]
child = walk(node.one if bit else node.zero, i + 1)
out = Trie(node.refs, node.zero if bit else child,
child if bit else node.one)
if out.refs == 0 and out.zero is None and out.one is None:
out = None
if i:
changes[i - 1] = int(out is not None) - int(old is not None)
return out
new = walk(root, 0)
def adjust(cell, i):
nonlocal touches
if i == len(changes):
return cell
touches += 1
count = (cell.count if cell else 0) + changes[i]
assert count >= 0
tail = adjust(cell.tail if cell else None, i + 1)
return Profile(count, count > LIMIT or bool(tail and tail.bad), tail)
profile = adjust(breadth, 0)
assert touches == 2 * len(word) + 1
return new, profile, touches
def terminals(root, prefix=()):
if root is None:
return {}
out = {prefix: root.refs} if root.refs else {}
out.update(terminals(root.zero, prefix + (0,)))
out.update(terminals(root.one, prefix + (1,)))
return out
def literal_counts(words):
return [len({w[:t] for w in words if len(w) >= t})
for t in range(1, max(map(len, words), default=0) + 1)]
def check_profile(profile, words):
expected = literal_counts(words)
got = []
cell = profile
while cell:
got.append(cell.count)
assert cell.bad == (cell.count > LIMIT or bool(cell.tail and cell.tail.bad))
cell = cell.tail
assert got[:len(expected)] == expected
assert not any(got[len(expected):])
assert bool(profile and profile.bad) == any(x > LIMIT for x in expected)
def advance(frontier, bit):
out = []
for node, parity in frontier:
if node.zero:
out.append((node.zero, parity))
if node.one:
out.append((node.one, parity ^ bit))
assert len(out) <= LIMIT
return out
def syndromes(root, query):
frontier = [(root, 0)] if root else []
answer = []
for bit in query:
frontier = advance(frontier, bit)
answer.append(tuple(v for node, v in frontier if node.refs))
return answer
def dot(word, query):
return sum(a * b for a, b in zip(word, query)) % 2
def conversion(global_root, local_root, masks, bound):
"""Track prefix injection only through ordered child labels, no identities."""
g = [global_root] if global_root else []
l = [local_root] if local_root else []
injection = [0] if local_root else []
profiles = {}
for depth in range(1, bound + 1):
ng, edge_to_slot = [], {}
for i, node in enumerate(g):
for bit, child in enumerate((node.zero, node.one)):
if child:
edge_to_slot[i, bit] = len(ng)
ng.append(child)
nl, ni = [], []
for i, node in enumerate(l):
for bit, child in enumerate((node.zero, node.one)):
if child:
ni.append(edge_to_slot[injection[i], bit])
nl.append(child)
g, l, injection = ng, nl, ni
assert len(g) <= LIMIT and len(l) <= LIMIT
terminal_positions = {i: k for k, i in enumerate(
i for i, node in enumerate(g) if node.refs)}
take = [terminal_positions[injection[i]] for i, node in enumerate(l) if node.refs]
table = masks.get(depth, (0,))
assert len(table) == 1 << len(take)
values = {}
for assignment in product((0, 1), repeat=len(terminal_positions)):
ix = 0
for pos in take:
ix = (ix << 1) | assignment[pos]
values[assignment] = table[ix]
profiles[depth] = values
return profiles
def build(words):
root = profile = None
for w in words:
root, profile, _ = change(root, w, 1, profile)
return root, profile
def main():
global LIMIT
rng = random.Random(167)
counts = Counter()
LIMIT = 4
root = profile = None
literal = Counter()
versions = []
universe = [tuple(rng.randrange(2) for _ in range(n)) for n in range(1, 13) for _ in range(8)]
for _ in range(3000):
if literal and rng.randrange(3) == 0:
w = rng.choice(list(literal))
delta = -1
else:
w, delta = rng.choice(universe), 1
root, profile, touches = change(root, w, delta, profile)
literal[w] += delta
if not literal[w]:
del literal[w]
check_profile(profile, literal)
counts['updates'] += 1
counts['path_and_profile_visits'] += touches
counts['wide_intermediate_versions'] += bool(profile and profile.bad)
if rng.randrange(37) == 0:
versions.append((root, profile, dict(literal)))
# Delete everything but a final prefix-compatible family. Multiplicity is exact.
for w, refs in list(literal.items()):
for _ in range(refs):
root, profile, _ = change(root, w, -1, profile)
literal[w] -= 1
if not literal[w]:
del literal[w]
check_profile(profile, literal)
counts['recovery_deletions'] += 1
assert root is None and not profile.bad
for old_root, old_profile, words in versions:
check_profile(old_profile, words)
assert terminals(old_root) == words
counts['retained_versions'] += 1
# Final-rank examples: at each width supports use the first two coordinates.
global_words = set()
rows = []
for _ in range(25):
words, masks = set(), {}
for n in range(2, 11):
available = sorted(tuple(a) + (0,) * (n - 2)
for a in ((0, 1), (1, 0), (1, 1)))
chosen = [w for w in available if rng.randrange(2)]
words.update(chosen)
masks[n] = tuple(rng.randrange(2) for _ in range(1 << len(chosen)))
rows.append((words, masks))
global_words.update(words)
groot, gp = build(global_words)
check_profile(gp, global_words)
assert not gp.bad
for words, masks in rows:
lroot, lp = build(words)
conv = conversion(groot, lroot, masks, 12)
for n in range(1, 13):
for _ in range(30):
query = tuple(rng.randrange(2) for _ in range(n))
gs = syndromes(groot, query)
ls = syndromes(lroot, query)
for t in range(1, n + 1):
gexpected = tuple(dot(w, query[:t]) for w in sorted(global_words) if len(w) == t)
lexpected = tuple(dot(w, query[:t]) for w in sorted(words) if len(w) == t)
assert gs[t - 1] == gexpected and ls[t - 1] == lexpected
ix = 0
for v in lexpected:
ix = (ix << 1) | v
expected = masks.get(t, (0,))[ix]
assert conv[t][gexpected] == expected
counts['converted_prefix_answers'] += 1
counts['queries'] += 1
# Irregular branch/termination patterns exercise frontier renumbering.
for _ in range(100):
frontier, all_words = [()], set()
for depth in range(1, 10):
children = [p + (bit,) for p in frontier for bit in (0, 1)]
rng.shuffle(children)
frontier = sorted(children[:rng.randint(1, min(LIMIT, len(children)))])
all_words.update(p for p in frontier if any(p) and rng.randrange(3) == 0)
gr, _ = build(all_words)
subset = {w for w in all_words if rng.randrange(2)}
lr, _ = build(subset)
tables = {n: tuple(rng.randrange(2) for _ in range(1 << sum(len(w) == n for w in subset)))
for n in range(1, 10)}
converted = conversion(gr, lr, tables, 11)
for _ in range(20):
query = tuple(rng.randrange(2) for _ in range(11))
got = syndromes(gr, query)
for t in range(1, 12):
expected = tuple(dot(w, query[:t]) for w in sorted(all_words) if len(w) == t)
assert got[t - 1] == expected
local = tuple(dot(w, query[:t]) for w in sorted(subset) if len(w) == t)
index = 0
for bit in local:
index = 2 * index + bit
assert converted[t][expected] == tables.get(t, (0,))[index]
counts['irregular_frontier_answers'] += 1
# Constant masks survive empty coefficient frontiers.
empty = conversion(None, None, {3: (1,), 7: (1,)}, 10)
assert [empty[t][()] for t in range(1, 11)] == [0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
# Short deletions cannot change longer suffix breadth, even while wide.
for depth in (8, 12, 16):
words = {(1,) + tuple((i >> j) & 1 for j in range(depth - 1)) for i in range(16)}
rr, pp = build(words)
rr, pp, _ = change(rr, (0, 0), 1, pp)
suffix = pp.tail.tail
rr, pp, _ = change(rr, (0, 0), -1, pp)
assert pp.tail.tail is suffix # Implementation sharing check, never a semantic channel.
check_profile(pp, words)
counts['unchanged_suffix_checks'] += 1
# Breadth four need not mean rank at most two.
independent = {tuple(int(i == j) for i in range(4)) for j in range(4)}
ir, ip = build(independent)
assert not ip.bad and literal_counts(independent)[-1] == 4
for query in product((0, 1), repeat=4):
assert syndromes(ir, query)[-1] == tuple(dot(w, query) for w in sorted(independent))
counts['broader_gate_queries'] += 1
# Different widths expire, allowing unbounded total coefficient rank.
rolling = {tuple(int(i == n - 1) for i in range(n)) for n in range(2, 33)}
rr, rp = build(rolling)
assert not rp.bad and max(literal_counts(rolling)) <= 2
for _ in range(100):
query = tuple(rng.randrange(2) for _ in range(35))
got = syndromes(rr, query)
for t in range(1, 36):
assert got[t - 1] == tuple(dot(w, query[:t]) for w in sorted(rolling) if len(w) == t)
counts['rolling_width_answers'] += 1
# Count alone cannot discharge a last delayed point.
candidate = {(0, 0), (0, 1)}
observed = {(0, 0), (1, 0)}
assert len(candidate) == len(observed) and candidate != observed
print(json.dumps({'status': 'passed', **dict(sorted(counts.items()))}, indent=2))
if __name__ == '__main__':
main()