import sys; sys.path.insert(0, '/private/tmp/claude-501/-Users-miltonlin-Projects-Trees/75c2c3d9-ef06-4644-b59b-d12583740b0c/scratchpad/anim/work/G5/scripts')
from e6_restr import *
def rank_and_null(rows):
    # rows: list of vectors (over Q). returns rank and basis of the right null space
    R = [r[:] for r in rows]; m = len(R[0]); piv = []; r = 0
    for c in range(m):
        p = next((i for i in range(r, len(R)) if R[i][c] != 0), None)
        if p is None: continue
        R[r], R[p] = R[p], R[r]; pv = R[r][c]; R[r] = [x / pv for x in R[r]]
        for i in range(len(R)):
            if i != r and R[i][c] != 0:
                f = R[i][c]; R[i] = [x - f * y for x, y in zip(R[i], R[r])]
        piv.append(c); r += 1
    free = [c for c in range(m) if c not in piv]
    null = []
    for fc in free:
        v = [F(0)] * m; v[fc] = F(1)
        for i, c in enumerate(piv): v[c] = -R[i][fc]
        null.append(v)
    return len(piv), null
def M_at(k, lu, lv, q):
    # M_kappa at the positive real point with log_q u = lu, log_q v = lv: y^(a,b) = u^{(2a+b)/3} v^{(a+2b)/3}
    tot = F(0)
    for (a, b) in wx_orbit(k):
        c1 = F(2 * a + b, 3); c6 = F(a + 2 * b, 3)
        e = c1 * lu + c6 * lv
        assert e.denominator == 1
        tot += F(q) ** int(e)
    return tot
doms = dominant_coweights(24)
for N in (12, 16, 20, 24):
    mus = [d for d in doms if 0 < d[2] <= N]
    data = [r_of(d[1]) for d in mus]
    kappas = sorted({k for R in data for k in R})
    for q in (F(4), F(9), F(25), F(49), F(121, 9)):   # q = t^2 with t = 2,3,5,7,11/3
        # rows = mu (images r(m_mu) as vectors in the M_kappa basis)
        rows = [[ev(R.get(k, {}), q) for k in kappas] for R in data]
        rk, null = rank_and_null(rows)
        # is M_(3,0) in the row space?  augment
        e30 = [F(int(k == (3, 0))) for k in kappas]
        rk2, _ = rank_and_null(rows + [e30])
        e11 = [F(int(k == (1, 1))) for k in kappas]; e22 = [F(int(k == (2, 2))) for k in kappas]
        in11 = rank_and_null(rows + [e11])[0] == rk; in22 = rank_and_null(rows + [e22])[0] == rk
        # compare null vector with l(g) = g(y1) - g(sigma y1), y1 = (-5, 1), sigma y1 = (1, -5)
        ltrue = [M_at(k, -5, 1, q) - M_at(k, 1, -5, q) for k in kappas]
        prop = None
        if len(null) == 1:
            v = null[0]
            # find scalar
            idx = next(i for i in range(len(v)) if v[i] != 0)
            lam = ltrue[idx] / v[idx]
            prop = all(ltrue[i] == lam * v[i] for i in range(len(v)))
        if q == F(4):
            nz = [k for k, x in zip(kappas, ltrue) if x != 0 and k[0] > k[1]]
        print('norm<=%d: #mu=%d #kappa=%d q=%s rank=%d  M30 in span: %s  M11,M22 in span: %s,%s  null dim=%d  null ~ g(y1)-g(sigma y1): %s' % (
            N, len(mus), len(kappas), q, rk, rk2 == rk, in11, in22, len(null), prop))
    print('   kappas:', kappas)
    print('   sigma-odd functional nonzero on (a>b):', nz)
