"""Exhaustive checks of Lemmas 1-3 for GL_{2m}/Sp_{2m} on small labels.

For every label c (c_1>=...>=c_m>=0) with |c| <= bound:
  (V)  every Lagrangian submodule of M'_c has module type <=_dom c;
  (L2) the type c itself occurs (so N(lambda*(c), c) >= 1);
  (L1) Lagrangians of cyclic type (d) exist only for c = (d,0,...,0), and then
       there are q^(d-1)(q+1) of them.
Also prints the full count table for each c.

Usage: python3 -I check_V.py p bound mmax
"""
import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from symp_lagr import counts, dom_ge


def labels(m, total):
    def rec(prefix, remaining, maxpart, k):
        if k == 0:
            if remaining == 0:
                yield tuple(prefix)
            return
        for x in range(min(maxpart, remaining), -1, -1):
            yield from rec(prefix + [x], remaining - x, x, k - 1)
    yield from rec([], total, total, m)


if __name__ == '__main__':
    p = int(sys.argv[1]); bound = int(sys.argv[2]); mmax = int(sys.argv[3])
    ok = True
    for m in range(1, mmax + 1):
        for tot in range(1, bound + 1):
            for c in labels(m, tot):
                r = counts(c, p)
                cpart = tuple(x for x in c if x)
                for ty, n in r.items():
                    if not dom_ge(cpart, ty):
                        ok = False
                        print('VIOLATION (V):', c, ty, n)
                if r.get(cpart, 0) < 1:
                    ok = False
                    print('VIOLATION (L2):', c)
                for ty, n in r.items():
                    if len(ty) == 1:
                        d = ty[0]
                        if cpart != (d,) or n != p ** (d - 1) * (p + 1):
                            ok = False
                            print('VIOLATION (L1):', c, ty, n)
                if cpart == (tot,) and r.get((tot,), 0) != p ** (tot - 1) * (p + 1):
                    ok = False
                    print('VIOLATION (L1 count):', c, r)
                print('m=%d c=%s' % (m, c), dict(sorted(r.items(), reverse=True)))
    print('ALL CHECKS PASSED' if ok else 'SOME CHECK FAILED')
