#!/usr/bin/env python3
import collections
import lzma
import sys


def open_formula(path):
    return lzma.open(path, "rt") if path.endswith(".xz") else open(path, "rt")


def clauses(path):
    with open_formula(path) as f:
        for line in f:
            if not line or line[0] in "cp":
                continue
            xs = [int(x) for x in line.split()]
            if xs and xs[-1] == 0:
                xs.pop()
            if xs:
                yield xs


def signature(group):
    v = abs(group[0][0])
    every_first = all(abs(c[0]) == v for c in group)
    every_contains = all(any(abs(x) == v for x in c) for c in group)
    sizes = tuple(sorted(collections.Counter(len(c) for c in group).items()))
    signs = collections.Counter()
    for c in group:
        pos = sum(x > 0 for x in c)
        signs[(len(c), pos)] += 1
    return every_first, every_contains, sizes, tuple(sorted(signs.items()))


def main():
    path = sys.argv[1]
    groups = []
    cur_v = None
    cur = []
    units = 0
    for c in clauses(path):
        if len(c) == 1:
            units += 1
        v = abs(c[0])
        if cur_v is None or v == cur_v:
            cur.append(c)
            cur_v = v
        else:
            groups.append((cur_v, cur))
            cur = [c]
            cur_v = v
    if cur:
        groups.append((cur_v, cur))
    print("groups", len(groups), "units", units)
    size_hist = collections.Counter(len(g) for _, g in groups)
    print("group size hist top")
    for k, v in size_hist.most_common(50):
        print(k, v)
    sig_hist = collections.Counter()
    weird = []
    for v, g in groups:
        sig = signature(g)
        sig_hist[sig] += 1
        if (not sig[0] or not sig[1]) and len(weird) < 20:
            weird.append((v, g[:5], sig))
    print("signature top")
    for sig, cnt in sig_hist.most_common(40):
        print("cnt", cnt, "sig", sig)
    print("weird samples")
    for v, g, sig in weird:
        print("var", v, "sig", sig)
        for c in g:
            print(" ", c)


if __name__ == "__main__":
    main()
