# Further checks for E6/F4: T^theta connected (Smith form), C_W(w_L) = <W_L, n1, n6>, type-U stabilizer images,
# closure order of the 45 orbits from raising sequences, compared with the Bruhat order.
exec(open(__file__.replace('e6_checks.py', 'e6_orbits.py')).read().split("# per orbit data")[0])
# ---- (a) Smith normal form of theta^* - 1 on X^*(T) (fundamental-weight basis): matrix M^T - 1
M = [[roots[theta[idx[simple[j]]]][i] for j in range(n)] for i in range(n)]   # column j = theta(alpha_j) (= theta on coroots)
Mt = [[M[j][i] - (1 if i == j else 0) for j in range(n)] for i in range(n)]
def smith(a):
    a = [row[:] for row in a]; r, c = len(a), len(a[0]); diag = []; t = 0
    while t < min(r, c):
        piv = [(abs(a[i][j]), i, j) for i in range(t, r) for j in range(t, c) if a[i][j] != 0]
        if not piv: break
        _, i0, j0 = min(piv)
        a[t], a[i0] = a[i0], a[t]
        for row in a: row[t], row[j0] = row[j0], row[t]
        done = False
        while not done:
            done = True
            for i in range(t+1, r):
                q = a[i][t] // a[t][t]
                a[i] = [x - q*y for x, y in zip(a[i], a[t])]
                if a[i][t] != 0:
                    done = False; a[t], a[i] = a[i], a[t]
            for j in range(t+1, c):
                q = a[t][j] // a[t][t]
                for row in a: row[j] -= q*row[t]
                if a[t][j] != 0:
                    done = False
                    for row in a: row[t], row[j] = row[j], row[t]
            if done:
                bad = [(i, j) for i in range(t+1, r) for j in range(t+1, c) if a[i][j] % a[t][t] != 0]
                if bad:
                    i, j = bad[0]; a[t] = [x + y for x, y in zip(a[t], a[i])]; done = False
        diag.append(abs(a[t][t])); t += 1
    return diag
print("elementary divisors of theta^*-1 on X^*(T):", smith(Mt), "(rank", len(smith(Mt)), "; T^theta has dim", 6 - len(smith(Mt)), ")")
# ---- (b) C_W(w_L) generated by W_L and n_i = s_{alpha_i} s_{beta_i}, beta_i = -theta(alpha_i), i = 1, 6
def refl_root(k):   # reflection s_beta as permutation
    b = roots[k]
    def s(v):
        c = sum(v[i]*sum(b[j]*A[j][i] for j in range(n)) for i in range(n))  # <v, beta^vee> (simply laced: = (v, beta))
        return tuple(v[i] - c*b[i] for i in range(n))
    return tuple(idx[s(roots[m])] for m in range(N))
gens = [S[j] for j in black]
for i in (0, 5):
    a = idx[simple[i]]; b = neg(theta[a])
    gens.append(comp(refl_root(a), refl_root(b)))
grp = {ident}; fr = [ident]
while fr:
    new = []
    for g in fr:
        for h in gens:
            k = comp(h, g)
            if k not in grp: grp.add(k); new.append(k)
    fr = new
print("|<W_L, n1, n6>| =", len(grp), "; all commute with w_L:", all(comp(g, wL) == comp(wL, g) for g in grp))
# ---- (c) type-U stabilizer images and dimensions of stabilizers (Lie algebra counts; all imaginary roots compact)
xs = list(cls.keys())
def theta_x(x): return tuple(neg(x[k]) for k in range(N))
def stab_dim(th, Psi):   # dim of theta-fixed part of Lie(T) + root spaces in Psi (Psi theta-stable), imaginary compact
    imag = sum(1 for k in Psi if th[k] == k)
    cplx = sum(1 for k in Psi if th[k] != k)
    assert all(th[k] in Psi for k in Psi)
    return 4 + imag + cplx // 2
nU = 0
for x in xs:
    th = theta_x(x)
    PhiB = set(range(36))
    dB = stab_dim(th, PhiB & {th[k] for k in PhiB})
    c = sum(1 for k in range(36) if th[k] != k and ispos(th[k])) // 2
    assert dB == 16 + c
    for i in range(n):
        a = idx[simple[i]]; ma = neg(a)
        PhiP = PhiB | {ma}
        Psi = PhiP & {th[k] for k in PhiP}
        dP = stab_dim(th, Psi)
        if th[a] != a and ispos(th[a]): assert dP == dB      # U+: y in the smaller orbit, dim P_a y = dim B y + 1
        else: assert dP == dB + 1                             # G, U-: dim P_a y = dim B y
        if th[a] == a:                  # type G: +-alpha imaginary, both in Psi
            assert a in Psi and ma in Psi
        elif not ispos(th[a]):          # type U-: image of stabilizer in L_alpha is T U_{-alpha}
            nU += 1
            assert ma in Psi and a not in Psi
            delta = neg(th[a]); assert ispos(delta) and delta != a
            assert tuple(p+q for p, q in zip(roots[ma], roots[delta])) not in idx and roots[ma] != tuple(-t for t in roots[delta])
print("type U- pairs checked (Psi meets {+-alpha} in {-alpha}; -alpha+delta not a root):", nU)
# ---- (d) closure order from raising sequences; independence of the chosen U- root; comparison with Bruhat order
xinfo = {}
for x in xs:
    th = theta_x(x)
    xinfo[x] = ['G' if th[idx[simple[i]]] == idx[simple[i]] else ('U+' if ispos(th[idx[simple[i]]]) else 'U-') for i in range(n)]
conj = lambda i, x: comp(S[i], comp(x, S[i]))
def Pa(i, Sig):   # orbits in P_alpha_i . (union of orbits in Sig)
    out = set(Sig)
    for v in Sig:
        if xinfo[v][i] != 'G': out.add(conj(i, v))
    return frozenset(out)
memo = {}
def closure(x, choice=0):
    key = (x, choice)
    if key in memo: return memo[key]
    Ums = [i for i in range(n) if xinfo[x][i] == 'U-']
    if not Ums: res = frozenset([x])
    else:
        i = Ums[min(choice, len(Ums)-1)]
        res = Pa(i, closure(conj(i, x), choice))
    memo[key] = res; return res
same = all(len({closure(x, ch) for ch in range(6)}) == 1 for x in xs)
print("closure sets independent of the choice of U- roots:", same)
# Bruhat order (Deodhar's property Z): s in D_L(v) => (u <= v iff min(u, su) <= sv)
bmemo = {}
def leq(u, v):
    if (u, v) in bmemo: return bmemo[(u, v)]
    lu, lv = length(u), length(v)
    if lu > lv: r = False
    elif lv == 0: r = (u == ident)
    else:
        vi = inv(v); s = next(i for i in range(n) if not ispos(vi[idx[simple[i]]]))
        su, sv = comp(S[s], u), comp(S[s], v)
        r = leq(su if length(su) < lu else u, sv)
    bmemo[(u, v)] = r; return r
agree = all((xp in closure(x)) == leq(x, xp) for x in xs for xp in xs)
print("Y_x' in closure(Y_x)  <=>  x <= x' in the Bruhat order:", agree)
print("number of orbits in the closure of the open orbit:", len(closure(wL)), "; total relations:", sum(len(closure(x)) for x in xs))
