# Enumerate W(E6) as integer matrices on simple-coroot coordinates; W_X; the explicit w of the run.
import sys, pickle, os; sys.path.insert(0, '/private/tmp/claude-501/-Users-miltonlin-Projects-Trees/75c2c3d9-ef06-4644-b59b-d12583740b0c/scratchpad/anim/work/G5/scripts')
from e6model import EXP
A = EXP  # A[i][j] = <alpha_i, alpha_j^vee>, symmetric
n = 6
# a vector lam = sum c_i alpha_i^vee ; s_j(lam) = lam - <alpha_j, lam> alpha_j^vee, <alpha_j, lam> = sum_i A[j][i] c_i
def s(j, c):
    p = sum(A[j][i] * c[i] for i in range(n)); c = list(c); c[j] -= p; return tuple(c)
I = tuple(tuple(1 if i == j else 0 for i in range(n)) for j in range(n))   # columns e_j
def mat_apply(w, c):  # w given by columns w[j] = w(alpha_j^vee)
    return tuple(sum(w[j][i] * c[j] for j in range(n)) for i in range(n))
def left(j, w): return tuple(s(j, col) for col in w)
cache = '/private/tmp/claude-501/-Users-miltonlin-Projects-Trees/75c2c3d9-ef06-4644-b59b-d12583740b0c/scratchpad/anim/work/G5/W_E6.pkl'
if os.path.exists(cache):
    W = pickle.load(open(cache, 'rb'))
else:
    W = {I}; fr = [I]
    while fr:
        nf = []
        for w in fr:
            for j in range(n):
                w2 = left(j, w)
                if w2 not in W: W.add(w2); nf.append(w2)
        fr = nf
    W = sorted(W); pickle.dump(W, open(cache, 'wb'))
if __name__ == '__main__':
    print('|W| =', len(W))
    # theta matrix (columns theta(alpha_j^vee)) from the page, already verified equal to -w_L in e6_theta.py
    TH = [[-1,0,0,0,0,0],[-1,1,0,0,0,-1],[-2,0,1,0,0,-1],[-2,0,0,1,0,-2],[-1,0,0,0,1,-2],[0,0,0,0,0,-1]]
    thcols = tuple(tuple(TH[i][j] for i in range(n)) for j in range(n))
    def th(c): return mat_apply(thcols, c)
    e1 = tuple(I[0][i] - th(I[0])[i] for i in range(n)); e6 = tuple(I[5][i] - th(I[5])[i] for i in range(n))
    def ab(c):  # (a,b) coordinates of a vector in Lambda_S: a=<alpha_1,c>, b=<alpha_6,c>
        return (sum(A[0][i] * c[i] for i in range(n)), sum(A[5][i] * c[i] for i in range(n)))
    def in_minus(c): return th(c) == tuple(-x for x in c)
    blackpos = []
    # positive roots of L as coroot vectors: theta-fixed positive roots; generate all positive roots first
    roots = set(); fr = list(I); roots |= set(I)
    while fr:
        nf = []
        for c in fr:
            for j in range(n):
                d = s(j, c)
                if d not in roots: roots.add(d); nf.append(d)
        fr = nf
    roots |= {tuple(-x for x in c) for c in roots}
    assert len(roots) == 72
    PhiLpos = [c for c in roots if all(x >= 0 for x in c) and th(c) == c]
    assert len(PhiLpos) == 12
    PhiLposset = set(PhiLpos)
    WX = [w for w in W if in_minus(mat_apply(w, e1)) and in_minus(mat_apply(w, e6)) and all(mat_apply(w, c) in PhiLposset for c in PhiLpos)]
    print('|{w in W: w preserves Lambda_S (x) Q and Phi_L^+}| =', len(WX))
    for w in WX:
        print('  action on (a,b): e1 ->', ab(mat_apply(w, e1)), ' e6 ->', ab(mat_apply(w, e6)))
    # explicit w of the run (columns w(alpha_j^vee)):
    wrun = ((1,0,0,0,0,0),(0,0,0,1,0,0),(-1,-1,-1,-2,-2,-1),(0,0,0,0,1,0),(0,0,0,0,0,1),(1,1,2,2,1,0))
    print('explicit w of the run lies in W(E6):', wrun in set(W))
    # check lambda2* = w lambda1*: <lambda1*, mu> = <lambda2*, w mu> on simple coroots
    l1 = (-8,1,1,1,1,-2); l2 = (-8,1,1,1,1,1)   # fundamental-weight coords = values on simple coroots
    def pair(lfund, c): return sum(lfund[i] * c[i] for i in range(n))
    print('<l1, a_j^v> == <l2, w a_j^v> for all j:', all(pair(l1, I[j]) == pair(l2, wrun[j]) for j in range(n)))
    # count elements with w(lambda1*) = lambda2*  (should be |Stab| = 2)
    # w acts on weights contragrediently: <w l, mu> = <l, w^{-1} mu>. Count w with <l1,mu> = <l2, w mu> for all mu.
    cnt = sum(1 for w in W if all(pair(l1, I[j]) == pair(l2, w[j]) for j in range(n)))
    print('number of w with x1(mu)=x2(w mu) for all mu:', cnt)
