#!/usr/bin/env python3
import itertools
import lzma
import math
import sys
from collections import Counter


def read_dimacs(path):
    opener = lzma.open if path.endswith(".xz") else open
    nvars = nclauses = None
    clauses = []
    with opener(path, "rt") as f:
        for line in f:
            if not line or line[0] == "c":
                continue
            if line[0] == "p":
                _, _, nvars, nclauses = line.split()[:4]
                nvars, nclauses = int(nvars), int(nclauses)
                continue
            lits = [int(x) for x in line.split()]
            if lits and lits[-1] == 0:
                lits.pop()
            if lits:
                clauses.append(lits)
    return nvars, nclauses, clauses


def tri_n(m):
    d = 1 + 8 * m
    r = int(math.isqrt(d))
    if r * r == d and (1 + r) % 2 == 0:
        n = (1 + r) // 2
        if n * (n - 1) // 2 == m:
            return n
    return None


def main(paths):
    for path in paths:
        nvars, nclauses, clauses = read_dimacs(path)
        n = tri_n(nvars)
        sizes = Counter(map(len, clauses))
        signs = Counter(("pos" if all(x > 0 for x in c) else "neg" if all(x < 0 for x in c) else "mixed", len(c)) for c in clauses)
        print(path)
        print("  vars", nvars, "graph_n", n, "clauses", len(clauses), "header", nclauses)
        print("  sizes", dict(sorted(sizes.items())))
        print("  signs", dict(sorted(signs.items())))
        if n is not None:
            for r in range(2, 10):
                c = math.comb(n, r)
                if c in sizes.values() or 2 * c == len(clauses):
                    print("  C(n,%d)=" % r, c)


if __name__ == "__main__":
    main(sys.argv[1:])
