#!/usr/bin/env python3 """68_suite_v080.py — v0.8.0: VEREDITO CONSOLIDADO das propostas Qwen3.8. Executa demo_qwen_v080 TRÊS vezes (a ablação JEPA usa o RNG global do candle na inicialização — gates direcionais agregados sobre execuções), herda os 73 gates da v0.7.0 (suite_v070_final.json) e adiciona os gates das 4 propostas analisadas/provadas/testadas em r-33: 1. Newton analítico (verificador) — N-1..N-4 2. Árvore pós-ordem iterativa — T-A7..T-A9 3. Cayley exato (FNH) — F-9..F-12 4. MoE vetorizada com gradiente restaurado (bug v080-1) — M-R6..M-R8 """ import json, os, sys def main(): pasta = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) R = os.path.join(pasta, "resultados") rel = {"versao": "0.8.0", "blocos": {}, "gates": {}} def carrega(arq): p = os.path.join(R, arq) if os.path.exists(p): with open(p) as f: return json.load(f) return None # ---- bloco legado v0.7.0 (se presente) legado = carrega("suite_v070_final.json") if legado: g_legado = legado.get("gates", legado) ok = sum(1 for v in g_legado.values() if v is True) rel["blocos"]["legado_v070"] = f"{ok}/{len(g_legado)}" for k, v in g_legado.items(): rel["gates"][f"legado_{k}"] = v # ---- demos v0.8.0 (3 execuções) import khtst_rust as k execucoes = [k.demo_qwen_v080() for _ in range(3)] # (1) Newton vs golden nvg = execucoes[0]["newton_vs_golden"] for nome, val in nvg["gates"].items(): rel["gates"][f"q1_newton_{nome}"] = val rel["blocos"]["q1_newton"] = f"{sum(1 for v in nvg['gates'].values() if v)}/{len(nvg['gates'])}" rel["medicoes"] = { "q1": {kk: nvg[kk] for kk in ("t_golden", "t_newton", "n_aval_newton", "nll_golden", "nll_newton", "tempo_golden_s", "tempo_newton_s")}, } # (2) Cayley vs polar cvp = execucoes[0]["cayley_vs_polar"] for nome, val in cvp["gates"].items(): rel["gates"][f"q3_cayley_{nome}"] = val rel["blocos"]["q3_cayley"] = f"{sum(1 for v in cvp['gates'].values() if v)}/{len(cvp['gates'])}" rel["medicoes"]["q3"] = {kk: cvp[kk] for kk in ("delta_ort_polar", "delta_ort_cayley", "tempo_polar_s", "tempo_cayley_s", "speedup")} # (3) árvore iterativa arv = execucoes[0]["arvore_iter_vs_rec"] for nome, val in arv["gates"].items(): rel["gates"][f"q2_arvore_{nome}"] = val rel["blocos"]["q2_arvore"] = f"{sum(1 for v in arv['gates'].values() if v)}/{len(arv['gates'])}" rel["medicoes"]["q2"] = {kk: arv[kk] for kk in ("n_nos", "total_iter", "tempo_iter_s", "tempo_rec_s")} # (4) MoE vetorizada (determinística — valores/gradientes) moe = execucoes[0]["moe_vetorizada"] for nome, val in moe["gates"].items(): rel["gates"][f"q4_moe_{nome}"] = val rel["blocos"]["q4_moe"] = f"{sum(1 for v in moe['gates'].values() if v)}/{len(moe['gates'])}" rel["medicoes"]["q4"] = {kk: moe[kk] for kk in ("max_dif_valores", "tempo_ref_s", "tempo_vet_s", "grad_roteador_vet", "grad_especialistas_vet")} # (5) ablação JEPA 3 braços — gates DIRECIONAIS nas 3 execuções quedas_moe, quedas_peq, quedas_den = [], [], [] for ex in execucoes: ab = ex["ablacao_jepa_3_bracos_v080"] quedas_moe.append(ab["moe"]["queda_pct"]) quedas_peq.append(ab["pequena"]["queda_pct"]) quedas_den.append(ab["densa"]["queda_pct"]) moe_min = min(quedas_moe) peq_max = max(quedas_peq) rel["gates"]["q5_ablacao_moe_aprende_3x"] = all(q > 30.0 for q in quedas_moe) rel["gates"]["q5_ablacao_moe_domina_pequena_3x"] = moe_min > peq_max rel["medicoes"]["q5"] = { "quedas_moe_pct": quedas_moe, "quedas_pequena_pct": quedas_peq, "quedas_densa_pct": quedas_den, "nota": "inicialização via RNG global do candle — gates direcionais", } rel["blocos"]["q5_ablacao"] = ( f"{sum(1 for v in (rel['gates']['q5_ablacao_moe_aprende_3x'], rel['gates']['q5_ablacao_moe_domina_pequena_3x']) if v)}/2") # ---- provas cargo (contagem) try: import subprocess, re res = subprocess.run( ["cargo", "test", "--manifest-path", os.path.join(pasta, "Cargo.toml")], capture_output=True, text=True, timeout=1800, env={**os.environ, "PATH": os.environ["PATH"] + ":" + os.path.expanduser("~/.cargo/bin")}, ) saida = res.stdout + res.stderr linhas = [l for l in saida.splitlines() if "test result:" in l] m = re.search(r"(\d+) passed; (\d+) failed", linhas[0] if linhas else "") if m: total_c = int(m.group(1)) + int(m.group(2)) rel["blocos"]["cargo"] = f"{m.group(1)}/{total_c}" rel["gates"]["cargo_todos_verdes"] = m.group(2) == "0" else: rel["blocos"]["cargo"] = "sem resultado" rel["gates"]["cargo_todos_verdes"] = False except Exception as e: rel["blocos"]["cargo"] = f"erro: {e}" rel["gates"]["cargo_todos_verdes"] = False # ---- veredito total = len(rel["gates"]) ok = sum(1 for v in rel["gates"].values() if v is True) rel["veredito"] = f"{ok}/{total}" with open(os.path.join(R, "suite_v080_final.json"), "w") as f: json.dump(rel, f, indent=1, ensure_ascii=False) print(json.dumps({"blocos": rel["blocos"], "veredito": rel["veredito"]}, indent=1, ensure_ascii=False)) sys.exit(0 if ok == total else 1) if __name__ == "__main__": main()