# W(E6) check: theta=-w_L, N_W(a) ∩ minimal reps of W/W_L, action on a; Bourbaki labels 1..6
import itertools
n=6
edges=[(1,3),(3,4),(4,5),(5,6),(2,4)]
A=[[2 if i==j else 0 for j in range(n)] for i in range(n)]
for a,b in edges: A[a-1][b-1]=A[b-1][a-1]=-1
def refl(i):  # matrix acting on column vectors in simple-root coords: s_i(v)=v-<alpha_i^vee,v> alpha_i
    M=[[1 if r==c else 0 for c in range(n)] for r in range(n)]
    for c in range(n): M[i][c]-=A[i][c]
    return tuple(tuple(r) for r in M)
def mul(X,Y): return tuple(tuple(sum(X[r][k]*Y[k][c] for k in range(n)) for c in range(n)) for r in range(n))
def app(X,v): return tuple(sum(X[r][k]*v[k] for k in range(n)) for r in range(n))
S=[refl(i) for i in range(n)]
I=tuple(tuple(1 if r==c else 0 for c in range(n)) for r in range(n))
W={I}; frontier=[I]
while frontier:
    nf=[]
    for w in frontier:
        for s in S:
            x=mul(s,w)
            if x not in W: W.add(x); nf.append(x)
    frontier=nf
print('|W|',len(W))
# positive roots
roots=set()
for w in W:
    for i in range(n):
        e=tuple(1 if k==i else 0 for k in range(n)); roots.add(app(w,e))
pos=[r for r in roots if all(c>=0 for c in r)]
print('#roots',len(roots),'#pos',len(pos))
L=[1,2,3,4]  # indices of nodes 2,3,4,5 (0-based)
posL=[r for r in pos if all(r[k]==0 for k in (0,5))]
# w_L: element of parabolic sending all posL to negative and generated by s_2..s_5
WL={I}; fr=[I]
while fr:
    nf=[]
    for w in fr:
        for i in L:
            x=mul(S[i],w)
            if x not in WL: WL.add(x); nf.append(x)
    fr=nf
wL=[w for w in WL if all(all(c<=0 for c in app(w,r)) for r in posL)][0]
print('|W_L|',len(WL))
theta=tuple(tuple(-c for c in row) for row in wL)
def e(i): return tuple(1 if k==i else 0 for k in range(n))
g1=tuple(a-b for a,b in zip(e(0),app(theta,e(0)))); g6=tuple(a-b for a,b in zip(e(5),app(theta,e(5))))
print('gamma1',g1,'gamma6',g6)
# a = span(g1,g6) (-1 eigenspace); check dimension of -1 eigenspace via rank of theta+I
def inspan(v):  # v in Q-span of g1,g6 ?
    import fractions
    M=[list(g1),list(g6),list(v)]
    # rank test via 2x2 minors
    def rank(rows):
        import fractions
        R=[[fractions.Fraction(x) for x in r] for r in rows]; rk=0; col=0
        m=len(R)
        for c in range(n):
            piv=None
            for r in range(rk,m):
                if R[r][c]!=0: piv=r;break
            if piv is None: continue
            R[rk],R[piv]=R[piv],R[rk]
            for r in range(m):
                if r!=rk and R[r][c]!=0:
                    f=R[r][c]/R[rk][c]; R[r]=[a-f*b for a,b in zip(R[r],R[rk])]
            rk+=1
        return rk
    return rank(M)==2
N=[w for w in W if inspan(app(w,g1)) and inspan(app(w,g6))]
print('|N_W(a)|',len(N),' |N_W(a)|/|W_L|',len(N)//len(WL))
minimal=[w for w in N if all(all(c>=0 for c in app(w,e(i))) for i in L)]
print('#N ∩ minimal reps',len(minimal))
closed=all(mul(x,y) in set(minimal) for x in minimal for y in minimal)
print('closed under mult',closed)
for w in minimal: print('w(g1)=',app(w,g1),' w(g6)=',app(w,g6))
