from closure import *

def report(name, F, P):
    Cstar, trace = predictive_closure(F, P)
    deltas, unique, _ = closure_spectrum(F, P)
    print("\n" + name)
    print("=" * len(name))
    print("C0 classes:", len(set(observation_partition(P).values())))
    print("refinement classes:", [len(set(x.values())) for x in unique])
    print("C* classes:", len(set(Cstar.values())))
    print("H(C*|P):", conditional_predictive_entropy(P, Cstar), "bits")
    print("Bmax:", fixed_width_missing_bits(P, Cstar), "bits")
    try:
        print("kappa:", closure_depth(F, P, Cstar))
    except ValueError:
        print("kappa: F not invertible")
    print("delta spectrum:", deltas)

F4={0:1,1:2,2:3,3:0}
report("4-cycle parity", F4, {0:"E",1:"O",2:"E",3:"O"})
report("4-cycle AABB", F4, {0:"A",1:"A",2:"B",3:"B"})

F8={i:(i+1)%8 for i in range(8)}
report("8-cycle AAAABBBB", F8, {i:("A" if i<4 else "B") for i in range(8)})

print("\nInfinite-shift counterexample (mathematical description):")
print("Two bi-infinite bit strings may agree at all indices <=0 but differ at index 1.")
print("Observation P(x)=x_0 gives identical entire observed past, different next output.")
print("Therefore history alone need not repair a deterministic projection in general.")
