Research source · python
check_bounded_omission_basis.py
tools/research/check_bounded_omission_basis.py
82 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: f751779a19fe8abdfe25fa3503583805f5eaf67999c90af5d51f759e9ce01bc0
#!/usr/bin/env python3
"""Finite semantic audit. Set operations and field arithmetic are oracle costs."""
from itertools import combinations, product
import json
counts = dict(sequences=0, prefix_queries=0, selector_failures=0, polynomial_pairs=0)
U = frozenset(range(4))
holes = [frozenset(c) for k in range(3) for c in combinations(U, k)]
rows = [U - h for h in holes]
for seq in product(rows, repeat=4):
basis, union, truth = [], frozenset(), frozenset()
for row in seq:
if not basis or not row <= union:
basis.append(row)
union |= row
assert len(basis) <= 3
truth |= row
assert union == truth
counts['prefix_queries'] += len(U)
for q in U:
assert (q in union) == any(q in b for b in basis)
assert union == frozenset().union(*seq)
counts['sequences'] += 1
# Every proper selected subset of r+1 distinct tokens can be defeated.
for r in range(1, 7):
V = frozenset(range(r + 4))
for k in range(r + 1):
for chosen in combinations(range(r + 1), k):
j = next(i for i in range(r + 1) if i not in chosen)
H = [frozenset((0, i + 1)) if i != j else frozenset((r + 2, r + 3)) for i in range(r + 1)]
assert len(set(H)) == r + 1
all_rows = [V - h for h in H]
assert 0 in frozenset().union(*all_rows)
assert 0 not in frozenset().union(*(all_rows[i] for i in chosen))
counts['selector_failures'] += 1
# Characteristic polynomial reconstruction for bounded missing sets in F_17.
p = 17
V = frozenset(range(8))
def poly(H):
c = [1]
for a in H:
d = [0] * (len(c) + 1)
for i, x in enumerate(c):
d[i] = (d[i] - a*x) % p
d[i+1] = (d[i+1] + x) % p
c = d
return tuple(c)
def value(c, x):
z = 0
for a in reversed(c): z = (z*x + a) % p
return z
missing = [frozenset(c) for k in range(3) for c in combinations(V,k)]
def e1(S): return sum(S) % p
def e2(S): return sum(a*b for a,b in combinations(S,2)) % p
def gcd(a,b):
def trim(c):
while len(c)>1 and c[-1]==0: c.pop()
return c
a,b=list(a),list(b)
while b != [0]:
c=a[:]
while c != [0] and len(c)>=len(b):
shift=len(c)-len(b); factor=c[-1]*pow(b[-1],-1,p)%p
for i,x in enumerate(b): c[i+shift]=(c[i+shift]-factor*x)%p
trim(c)
a,b=b,c
return tuple(x*pow(a[-1],-1,p)%p for x in a)
for H in missing:
X = V-H
h1=(e1(V)-e1(X))%p
h2=(e2(V)-e2(X)-e1(X)*h1)%p
assert h1==e1(H) and h2==e2(H)
for z in (8,9,10):
assert value(poly(V),z)*pow(value(poly(X),z),-1,p)%p == value(poly(H),z)
assert frozenset(q for q in V if value(poly(H),q)==0) == H
for K in missing:
G=H & K
assert gcd(poly(H),poly(K)) == poly(G)
assert (G != H) == bool((V-K) - (V-H))
counts['polynomial_pairs'] += 1
assert len({poly(H) for H in missing}) == len(missing)
print(json.dumps(counts, sort_keys=True))