# A9: (1) fibre count of nu_n: #{L in Gr_{<=n}: g_L^{-1} gamma in L^+X} vs max(0,n+1-d(v0,gamma));
#     Gr_{<=n} enumerated by Hermite normal forms [[t^i, x],[0,t^j]], i+j=n, deg x<i.
# (2) (T_s0+1) f_n = f^(1)_{n+1} + q f^(1)_{n-1}, (T_s1+1) f_n = (q+1) f_n, evaluated pointwise.
import sys, random, itertools, importlib.util, os
here=os.path.dirname(os.path.abspath(__file__))
spec=importlib.util.spec_from_file_location('mc',os.path.join(here,'mobius_check.py'))
p=int(sys.argv[1]); trials=int(sys.argv[2]); NMAX=int(sys.argv[3])
sys.argv=['x',str(p),'0','7']
mc=importlib.util.module_from_spec(spec); spec.loader.exec_module(mc)
q=p
def d0(g): return mc.dvert(mc.ZERO,0,*g)
def d1(g): return mc.dvert(mc.ZERO,-1,*g)
def f(n,g): return max(0,n+1-d0(g))
def f1(n,g): return max(0,n+1-d1(g)) if n>=0 else 0
def ginv_hnf(i,j,x):  # inverse of [[t^i,x],[0,t^j]] up to scalar t^{i+j}: [[t^j,-x],[0,t^i]]
    return [[mc.tp(j),mc.neg(x)],[[],mc.tp(i)]]
def gr_count(n,g):
    a,b=g; c=0
    for i in range(n+1):
        j=n-i
        for xs in itertools.product(range(p),repeat=i):
            x=mc.norm(list(xs)); M=ginv_hnf(i,j,x)
            h=(mc.mob(M,a),mc.mob(M,b))
            if d0(h)==0: c+=1
    return c
bad=0; n1=0; n2=0
random.seed(11)
for _ in range(trials):
    a=mc.rand_end(3,3); b=mc.rand_end(3,3)
    if mc.isinf(a) and mc.isinf(b): continue
    if not mc.isinf(a) and not mc.isinf(b) and mc.diff_ord(a,b) is None: continue
    g=(a,b)
    if d0(g)>NMAX+1: continue
    for n in range(NMAX+1):
        n1+=1
        if gr_count(n,g)!=f(n,g): bad+=1; print('FIBRE MISMATCH',n,d0(g),gr_count(n,g))
        # full panels: s1 panel = {I} u I s1 I ; s0 panel = {I} u I s0 I
        T1=f(n,g)+sum(f(n,(mc.mob(mc.s1inv(c),a),mc.mob(mc.s1inv(c),b))) for c in range(q))
        T0=f(n,g)+sum(f(n,(mc.mob(mc.s0inv(c),a),mc.mob(mc.s0inv(c),b))) for c in range(q))
        n2+=1
        if T1!=(q+1)*f(n,g): bad+=1; print('T1 MISMATCH',n,cls)
        if T0!=f1(n+1,g)+q*f1(n-1,g): bad+=1; print('T0 MISMATCH',n,mc.cls(g),T0,f1(n+1,g),f1(n-1,g))
print('p',p,'fibre checks',n1,'Hecke checks',n2,'mismatches',bad)
