#!/usr/bin/env python3
import collections
import lzma
import sys
from pathlib import Path


def open_dimacs(path: Path):
    if path.suffix == ".xz":
        return lzma.open(path, "rt", encoding="ascii")
    return path.open("rt", encoding="ascii")


def clauses(path: Path):
    with open_dimacs(path) as f:
        pending = []
        for line in f:
            if not line or line[0] in "cp":
                continue
            for tok in line.split():
                lit = int(tok)
                if lit == 0:
                    if pending:
                        yield tuple(pending)
                    pending = []
                else:
                    pending.append(lit)


def classify(block, z):
    sizes = tuple(sorted(len(c) for c in block))
    fanins = sorted({abs(x) for c in block for x in c if abs(x) != z})
    zpos = sum(1 for c in block for x in c if x == z)
    zneg = sum(1 for c in block for x in c if x == -z)
    return sizes, len(fanins), zpos, zneg


def main():
    for arg in sys.argv[1:]:
        path = Path(arg)
        counter = collections.Counter()
        examples = {}
        curz = None
        block = []
        total = 0
        for cl in clauses(path):
            m = max(abs(x) for x in cl)
            if m != curz:
                if block and curz is not None:
                    key = classify(block, curz)
                    counter[key] += 1
                    examples.setdefault(key, (curz, block[:]))
                    total += 1
                curz = m
                block = [cl]
            else:
                block.append(cl)
        if block and curz is not None:
            key = classify(block, curz)
            counter[key] += 1
            examples.setdefault(key, (curz, block[:]))
            total += 1
        print(path.name, "blocks", total)
        for key, n in counter.most_common(20):
            sizes, nf, zpos, zneg = key
            z, ex = examples[key]
            print(f"  n={n:7d} fanins={nf:3d} zpos={zpos:2d} zneg={zneg:2d} sizes={sizes}")
            print(f"    z={z} ex=" + " | ".join(" ".join(map(str, c)) for c in ex[:4]))


if __name__ == "__main__":
    main()
