Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,19 +1,16 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
-
PRACTICALITY SYSTEM
|
| 4 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 5 |
-
|
| 6 |
-
Β·
|
| 7 |
-
|
| 8 |
-
Β·
|
| 9 |
-
Β·
|
| 10 |
-
|
| 11 |
-
Β· PhaseCollider redesigned to be provably feasible
|
| 12 |
-
Β· StructuralModel moved before solve_by_hypothesis (no more _SM hack)
|
| 13 |
-
Β· HypothesisOracle accepts DomainStrategy, applies confidence weights
|
| 14 |
"""
|
| 15 |
|
| 16 |
-
import time, random, math, threading, asyncio, warnings, itertools
|
| 17 |
from functools import reduce
|
| 18 |
from typing import Optional, Callable, List, Dict, Tuple, Any, Set
|
| 19 |
from dataclasses import dataclass, field
|
|
@@ -26,13 +23,13 @@ import sympy as sp
|
|
| 26 |
from sympy.parsing.sympy_parser import parse_expr
|
| 27 |
import torch
|
| 28 |
from fastapi import FastAPI
|
| 29 |
-
from fastapi.responses import HTMLResponse
|
| 30 |
import uvicorn
|
| 31 |
|
| 32 |
warnings.filterwarnings("ignore")
|
| 33 |
USE_GPU = torch.cuda.is_available()
|
| 34 |
DEVICE = torch.device("cuda" if USE_GPU else "cpu")
|
| 35 |
-
print(f"[SYSTEM
|
| 36 |
|
| 37 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 38 |
# SECTION 1: CONSTANTS
|
|
@@ -139,12 +136,10 @@ def parse_psl(text:str) -> PSLProgram:
|
|
| 139 |
lines=[l.strip() for l in text.strip().split('\n') if l.strip() and not l.strip().startswith('#')]
|
| 140 |
prog=PSLProgram("unnamed",[],[],[],[])
|
| 141 |
i=0
|
| 142 |
-
def advance():
|
| 143 |
-
nonlocal i; l=lines[i]; i+=1; return l
|
| 144 |
def peek(): return lines[i] if i<len(lines) else ""
|
| 145 |
def pvar(rest):
|
| 146 |
-
p=rest.split()
|
| 147 |
-
return PSLVar(p[0],float(p[1]),float(p[2])) if len(p)>=3 else None
|
| 148 |
def pw(rest):
|
| 149 |
if 'WEIGHT' in rest:
|
| 150 |
p=rest.split('WEIGHT'); return p[0].strip(), float(p[1].split()[0])
|
|
@@ -172,7 +167,7 @@ def parse_psl(text:str) -> PSLProgram:
|
|
| 172 |
advance()
|
| 173 |
scons.append(PSLConstraint("or_eq","",scope=sname,weight=1.0,branches=opts))
|
| 174 |
elif kw=="ANNOTATE":
|
| 175 |
-
parts=rest.split()
|
| 176 |
if len(parts)>=3: prog.annotations[parts[0]]=parts[2]
|
| 177 |
return PSLScope(sname,order,depends or [],svars,links,scons)
|
| 178 |
|
|
@@ -195,7 +190,7 @@ def parse_psl(text:str) -> PSLProgram:
|
|
| 195 |
advance()
|
| 196 |
prog.constraints.append(PSLConstraint("or_eq","",weight=1.0,branches=opts))
|
| 197 |
elif kw=="ANNOTATE":
|
| 198 |
-
parts=rest.split()
|
| 199 |
if len(parts)>=3: prog.annotations[parts[0]]=parts[2]
|
| 200 |
elif kw=="SCOPE":
|
| 201 |
parts=rest.split(); sname=parts[0] if parts else f"s{len(prog.scopes)}"
|
|
@@ -254,14 +249,11 @@ def expand_psl(prog:PSLProgram) -> ExpandedProblem:
|
|
| 254 |
for sc in prog.scopes:
|
| 255 |
for v in sc.vars: add_var(v.name,v.lo,v.hi,sc.name)
|
| 256 |
for vname in sc.links:
|
| 257 |
-
if vname in bounds and vname not in scope_vars[sc.name]:
|
| 258 |
-
scope_vars[sc.name].append(vname)
|
| 259 |
for c in sc.constraints:
|
| 260 |
kind="or_eq" if c.kind=="or_eq" else "equality" if c.kind=="eq" else "inequality"
|
| 261 |
add_con(kind,c.expr,c.kind,sc.name,c.weight,c.branches)
|
| 262 |
-
return ExpandedProblem(variables,bounds,constraints,
|
| 263 |
-
dict(scope_groups),dict(scope_vars),
|
| 264 |
-
prog.scope_order,prog.annotations)
|
| 265 |
|
| 266 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββοΏ½οΏ½οΏ½ββββββββββββββββ
|
| 267 |
# SECTION 4: AXL LAYER
|
|
@@ -279,7 +271,6 @@ class AXLProblemDef:
|
|
| 279 |
def variables_list(self): return [v["name"] for v in self.variables]
|
| 280 |
|
| 281 |
class AXLtoPSLCompiler:
|
| 282 |
-
"""Compile AXL directly to PSL β used only for the BASE problem oracle."""
|
| 283 |
TEND_WEIGHT=0.3
|
| 284 |
def compile(self,prob:AXLProblemDef) -> str:
|
| 285 |
lines=[f"SPACE base_{prob.name}"]
|
|
@@ -525,70 +516,86 @@ class VerifyLayer:
|
|
| 525 |
VERIFY_LAYER=VerifyLayer()
|
| 526 |
|
| 527 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 528 |
-
# SECTION 7:
|
| 529 |
-
#
|
| 530 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 531 |
@dataclass
|
| 532 |
class DomainStrategy:
|
| 533 |
name: str
|
| 534 |
-
hyp_weights: Dict[str,float] #
|
| 535 |
polish: str # "adam" | "gradient" | "both"
|
| 536 |
-
explore_early: bool
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
"
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
"
|
| 548 |
-
"
|
| 549 |
-
|
| 550 |
-
|
| 551 |
-
"
|
| 552 |
-
"
|
| 553 |
-
|
| 554 |
-
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
"
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
"
|
| 564 |
-
"
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
"
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
{"branch":1.0,"manifold":0.5,"chain":2.0,"residual_chain":1.3},
|
| 571 |
-
"gradient", False, "ordered",
|
| 572 |
-
"Scheduling β chain + ordering; manifold less useful for discrete"),
|
| 573 |
-
"FluidContinuum": DomainStrategy("FluidContinuum",
|
| 574 |
-
{"branch":1.1,"manifold":1.8,"chain":0.8,"residual_chain":1.0},
|
| 575 |
-
"adam", True, "natural",
|
| 576 |
-
"Continuous flow β manifold tangents + Adam; explore broadly"),
|
| 577 |
-
}
|
| 578 |
-
|
| 579 |
-
DEFAULT_STRATEGY=DomainStrategy("Default",
|
| 580 |
-
{"branch":1.0,"manifold":1.0,"chain":1.0,"residual_chain":1.0},
|
| 581 |
-
"both", False, "natural")
|
| 582 |
-
|
| 583 |
-
def get_strategy(domain_name:str) -> DomainStrategy:
|
| 584 |
-
# Check exact match, then prefix match for derived domains (unions, duals)
|
| 585 |
-
if domain_name in DOMAIN_STRATEGIES: return DOMAIN_STRATEGIES[domain_name]
|
| 586 |
-
for k,v in DOMAIN_STRATEGIES.items():
|
| 587 |
-
if k in domain_name: return v
|
| 588 |
-
return DEFAULT_STRATEGY
|
| 589 |
|
| 590 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 591 |
-
# SECTION 8: SHARED
|
| 592 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 593 |
@dataclass
|
| 594 |
class Hypothesis:
|
|
@@ -598,10 +605,9 @@ class Hypothesis:
|
|
| 598 |
|
| 599 |
@dataclass
|
| 600 |
class HypothesisTrace:
|
| 601 |
-
hid:str; round_idx:int;
|
| 602 |
ce_before:float; ce_after:float
|
| 603 |
verify:Optional[VerifyResult]; survived:bool; elapsed_ms:float
|
| 604 |
-
strategy_note:str=""
|
| 605 |
|
| 606 |
@dataclass
|
| 607 |
class StructuralModel:
|
|
@@ -793,8 +799,7 @@ def _adam_polish(problem,binding,steps=ADAM_STEPS):
|
|
| 793 |
if nce<best_ce: best_ce=nce; best_b=dict(b)
|
| 794 |
return best_b,best_ce
|
| 795 |
|
| 796 |
-
def solve_by_hypothesis(problem:Problem, budget:int=TOTAL_BUDGET,
|
| 797 |
-
strategy:Optional[DomainStrategy]=None) -> Dict:
|
| 798 |
t0=time.time()
|
| 799 |
explore_trigger = 2 if (strategy and strategy.explore_early) else 4
|
| 800 |
polish_pref = strategy.polish if strategy else "both"
|
|
@@ -813,8 +818,7 @@ def solve_by_hypothesis(problem:Problem, budget:int=TOTAL_BUDGET,
|
|
| 813 |
if model.best_ce<SOLVE_THRESHOLD:
|
| 814 |
l7=TOPOLOGY_ORACLE.evaluate(problem,active_scopes)
|
| 815 |
l9=RESIDUAL_ORACLE.evaluate(model.best_binding,problem,l7.hub_vars)
|
| 816 |
-
return {"binding":model.best_binding,"ce":model.best_ce,"solved":True,
|
| 817 |
-
"l7":l7,"l9":l9,"time":round(time.time()-t0,3)}
|
| 818 |
|
| 819 |
oracle=HypothesisOracle(strategy=strategy); consec=0
|
| 820 |
for round_idx in range(HYPOTHESIS_MAX_ROUNDS):
|
|
@@ -840,17 +844,13 @@ def solve_by_hypothesis(problem:Problem, budget:int=TOTAL_BUDGET,
|
|
| 840 |
eb,ece=_mprt_sample(problem,work_box,N_MPRT_EXPLORE)
|
| 841 |
if ece<model.best_ce: model.best_ce=ece; model.best_binding=dict(eb); consec=0
|
| 842 |
|
| 843 |
-
#
|
| 844 |
if polish_pref in ("gradient","both") and SOLVE_THRESHOLD<model.best_ce<2.0:
|
| 845 |
gb,gce=_gradient_polish(problem,model.best_binding)
|
| 846 |
if gce<model.best_ce: model.best_ce=gce; model.best_binding=gb
|
| 847 |
if polish_pref in ("adam","both") and SOLVE_THRESHOLD<model.best_ce<1.0:
|
| 848 |
ab,ace=_adam_polish(problem,model.best_binding)
|
| 849 |
if ace<model.best_ce: model.best_ce=ace; model.best_binding=ab
|
| 850 |
-
# Always try Adam as last resort if still not solved
|
| 851 |
-
if SOLVE_THRESHOLD<model.best_ce<0.5 and polish_pref=="gradient":
|
| 852 |
-
ab,ace=_adam_polish(problem,model.best_binding,steps=60)
|
| 853 |
-
if ace<model.best_ce: model.best_ce=ace; model.best_binding=ab
|
| 854 |
|
| 855 |
final_l7=TOPOLOGY_ORACLE.evaluate(problem,active_scopes)
|
| 856 |
final_l9=RESIDUAL_ORACLE.evaluate(model.best_binding,problem,final_l7.hub_vars)
|
|
@@ -858,7 +858,7 @@ def solve_by_hypothesis(problem:Problem, budget:int=TOTAL_BUDGET,
|
|
| 858 |
"l7":final_l7,"l9":final_l9,"time":round(time.time()-t0,3)}
|
| 859 |
|
| 860 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 861 |
-
# SECTION 11: HYPOTHESIS ENGINE
|
| 862 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 863 |
class HypothesisOracle:
|
| 864 |
def __init__(self, strategy:Optional[DomainStrategy]=None):
|
|
@@ -866,16 +866,24 @@ class HypothesisOracle:
|
|
| 866 |
|
| 867 |
def generate(self,problem,model,l7,l8,l9,round_idx):
|
| 868 |
hyps=[]
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
| 873 |
-
|
| 874 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 875 |
if self.strategy:
|
| 876 |
for hyp in hyps:
|
| 877 |
w=self.strategy.hyp_weights.get(hyp.h_type,1.0)
|
| 878 |
hyp.confidence=min(0.99,hyp.confidence*w)
|
|
|
|
| 879 |
hyps=[h for h in hyps if h.hid not in model.failure_patterns]
|
| 880 |
return sorted(hyps,key=lambda h:-h.confidence)
|
| 881 |
|
|
@@ -1008,305 +1016,94 @@ def _test_hypothesis(problem,hyp):
|
|
| 1008 |
return best_b,best_ce
|
| 1009 |
|
| 1010 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1011 |
-
# SECTION 12:
|
| 1012 |
-
#
|
| 1013 |
-
# domain PSL = base constraints (real, full weight) +
|
| 1014 |
-
# soft domain structural hints (weight 0.15)
|
| 1015 |
-
# observations pin variables via zero-width VAR bounds
|
| 1016 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1017 |
-
class Axiom:
|
| 1018 |
-
DISCRETE="DISCRETE"; CONTINUOUS="CONTINUOUS"; METRIC="METRIC"; NETWORK="NETWORK"
|
| 1019 |
-
INJECTIVE="INJECTIVE"; SURJECTIVE="SURJECTIVE"; CONSERVED="CONSERVED"; MUTABLE="MUTABLE"
|
| 1020 |
-
QUADRATIC="QUADRATIC"; BILINEAR="BILINEAR"; ORDERED="ORDERED"; SYMMETRIC="SYMMETRIC"
|
| 1021 |
-
TRANSITIVE="TRANSITIVE"; ATOMIC="ATOMIC"; COMPOSITE="COMPOSITE"
|
| 1022 |
-
|
| 1023 |
-
AXIOM_CONTRADICTIONS=[
|
| 1024 |
-
{Axiom.DISCRETE,Axiom.CONTINUOUS},{Axiom.INJECTIVE,Axiom.SURJECTIVE},
|
| 1025 |
-
{Axiom.ORDERED,Axiom.SYMMETRIC},{Axiom.ATOMIC,Axiom.COMPOSITE},
|
| 1026 |
-
{Axiom.CONSERVED,Axiom.MUTABLE}]
|
| 1027 |
-
|
| 1028 |
-
@dataclass
|
| 1029 |
-
class AbstractDomain:
|
| 1030 |
-
name:str; axioms:Set[str]; derivation:str="Base"; confidence:float=1.0
|
| 1031 |
-
def is_consistent(self): return not any(p.issubset(self.axioms) for p in AXIOM_CONTRADICTIONS)
|
| 1032 |
-
|
| 1033 |
-
BASE_LIBRARY=[
|
| 1034 |
-
AbstractDomain("GraphSpace",{Axiom.DISCRETE,Axiom.NETWORK,Axiom.SYMMETRIC,Axiom.ATOMIC}),
|
| 1035 |
-
AbstractDomain("MetricPacking",{Axiom.DISCRETE,Axiom.METRIC,Axiom.INJECTIVE,Axiom.CONSERVED}),
|
| 1036 |
-
AbstractDomain("FluidContinuum",{Axiom.CONTINUOUS,Axiom.METRIC,Axiom.SURJECTIVE,Axiom.CONSERVED,Axiom.MUTABLE}),
|
| 1037 |
-
AbstractDomain("SequentialChain",{Axiom.DISCRETE,Axiom.ORDERED,Axiom.TRANSITIVE,Axiom.BILINEAR,Axiom.ATOMIC}),
|
| 1038 |
-
AbstractDomain("HierarchicalTree",{Axiom.DISCRETE,Axiom.NETWORK,Axiom.ORDERED,Axiom.COMPOSITE}),
|
| 1039 |
-
AbstractDomain("NormManifold",{Axiom.CONTINUOUS,Axiom.QUADRATIC,Axiom.CONSERVED,Axiom.METRIC,Axiom.SYMMETRIC}),
|
| 1040 |
-
AbstractDomain("BilinearCoupling",{Axiom.CONTINUOUS,Axiom.BILINEAR,Axiom.NETWORK,Axiom.CONSERVED,Axiom.MUTABLE}),
|
| 1041 |
-
AbstractDomain("DiscreteSchedule",{Axiom.DISCRETE,Axiom.ORDERED,Axiom.INJECTIVE,Axiom.CONSERVED,Axiom.ATOMIC}),
|
| 1042 |
-
AbstractDomain("PhaseJump",{Axiom.DISCRETE,Axiom.MUTABLE,Axiom.SYMMETRIC,Axiom.NETWORK,Axiom.ATOMIC}),
|
| 1043 |
-
]
|
| 1044 |
-
|
| 1045 |
-
class WisdomOps:
|
| 1046 |
-
@staticmethod
|
| 1047 |
-
def _fn(n): return n if len(n)<22 else n[:19]+"..."
|
| 1048 |
-
@staticmethod
|
| 1049 |
-
def union(d1,d2):
|
| 1050 |
-
merged=d1.axioms|d2.axioms
|
| 1051 |
-
c=AbstractDomain(WisdomOps._fn(f"{d1.name}U{d2.name}"),merged,"Union",(d1.confidence+d2.confidence)/2)
|
| 1052 |
-
for pair in AXIOM_CONTRADICTIONS:
|
| 1053 |
-
if pair.issubset(c.axioms):
|
| 1054 |
-
counts={ax:sum(ax in d.axioms for d in BASE_LIBRARY) for ax in pair}
|
| 1055 |
-
c.axioms.discard(min(counts,key=counts.get))
|
| 1056 |
-
return c
|
| 1057 |
-
@staticmethod
|
| 1058 |
-
def relax(d,axioms): return AbstractDomain(WisdomOps._fn(f"{d.name}_Rlx"),d.axioms-axioms,"Relax",d.confidence*0.85)
|
| 1059 |
-
@staticmethod
|
| 1060 |
-
def inject(d,axioms):
|
| 1061 |
-
merged=d.axioms|axioms; ax_str="".join(a[:2] for a in axioms)
|
| 1062 |
-
c=AbstractDomain(WisdomOps._fn(f"{d.name}+{ax_str}"),merged,"Inject",d.confidence*0.9)
|
| 1063 |
-
for pair in AXIOM_CONTRADICTIONS:
|
| 1064 |
-
if pair.issubset(c.axioms):
|
| 1065 |
-
to_rm=pair-d.axioms
|
| 1066 |
-
if to_rm: c.axioms-=to_rm
|
| 1067 |
-
return c
|
| 1068 |
-
@staticmethod
|
| 1069 |
-
def dual(d):
|
| 1070 |
-
fm={Axiom.DISCRETE:Axiom.CONTINUOUS,Axiom.CONTINUOUS:Axiom.DISCRETE,
|
| 1071 |
-
Axiom.INJECTIVE:Axiom.SURJECTIVE,Axiom.SURJECTIVE:Axiom.INJECTIVE,
|
| 1072 |
-
Axiom.ORDERED:Axiom.SYMMETRIC,Axiom.SYMMETRIC:Axiom.ORDERED,
|
| 1073 |
-
Axiom.CONSERVED:Axiom.MUTABLE,Axiom.MUTABLE:Axiom.CONSERVED,
|
| 1074 |
-
Axiom.ATOMIC:Axiom.COMPOSITE,Axiom.COMPOSITE:Axiom.ATOMIC}
|
| 1075 |
-
return AbstractDomain(WisdomOps._fn(f"{d.name}*"),{fm.get(ax,ax) for ax in d.axioms},"Dual",d.confidence*0.7)
|
| 1076 |
-
|
| 1077 |
-
class PSLTranslator:
|
| 1078 |
-
"""
|
| 1079 |
-
THE CORE FIX.
|
| 1080 |
-
Generates domain PSL = base constraints (full weight) + soft domain hints (0.15).
|
| 1081 |
-
Observations are pinned via zero-width VAR bounds.
|
| 1082 |
-
Domain NEVER replaces the base problem β it only adds soft guidance.
|
| 1083 |
-
"""
|
| 1084 |
-
SOFT = 0.15
|
| 1085 |
-
|
| 1086 |
-
def compile(self, domain:AbstractDomain, axl_def:AXLProblemDef) -> str:
|
| 1087 |
-
ax=domain.axioms; variables=axl_def.variables_list(); n=len(variables)
|
| 1088 |
-
lines=[f"SPACE domain_{domain.name.replace(' ','_')}"]
|
| 1089 |
-
|
| 1090 |
-
# ββ 1. Variables: use actual bounds, pin observations ββββββββββ
|
| 1091 |
-
for v in axl_def.variables:
|
| 1092 |
-
lo,hi=v["lo"],v["hi"]
|
| 1093 |
-
if v["name"] in axl_def.observations:
|
| 1094 |
-
val=axl_def.observations[v["name"]]; lo=hi=val # PINNED
|
| 1095 |
-
lines.append(f"VAR {v['name']} {lo} {hi}")
|
| 1096 |
-
|
| 1097 |
-
# ββ 2. Base global constraints β ALWAYS, full weight βββββββββββ
|
| 1098 |
-
for c in axl_def.constraints:
|
| 1099 |
-
wt=c.get("weight",1.0)
|
| 1100 |
-
if c["kind"]=="CONSERVE":
|
| 1101 |
-
lines.append(f"CONSERVE {c['expr']}")
|
| 1102 |
-
elif c["kind"]=="BRANCH":
|
| 1103 |
-
lines.append(f"BRANCH {c.get('name','br')}")
|
| 1104 |
-
for opt in c.get("options",[]): lines.append(f" OPTION {opt}")
|
| 1105 |
-
lines.append("END BRANCH")
|
| 1106 |
-
else:
|
| 1107 |
-
lines.append(f"{c['kind']} {c['expr']} WEIGHT {wt}")
|
| 1108 |
-
|
| 1109 |
-
# ββ 3. Base scopes β ALWAYS, at their original ORDER ββββββββββ
|
| 1110 |
-
for sc in axl_def.scopes:
|
| 1111 |
-
order=sc.get("order",0)
|
| 1112 |
-
dep=f" DEPENDS {' '.join(sc.get('depends',[]))}" if sc.get('depends') else ""
|
| 1113 |
-
lines.append(f"SCOPE {sc['name']} ORDER {order}{dep}")
|
| 1114 |
-
if sc.get("vars"): lines.append(f" LINK {' '.join(sc['vars'])}")
|
| 1115 |
-
for c in sc.get("constraints",[]):
|
| 1116 |
-
wt=c.get("weight",1.0)
|
| 1117 |
-
if c["kind"]=="CONSERVE":
|
| 1118 |
-
lines.append(f" CONSERVE {c['expr']}")
|
| 1119 |
-
elif c["kind"]=="BRANCH":
|
| 1120 |
-
lines.append(f" BRANCH {c.get('name','br')}")
|
| 1121 |
-
for opt in c.get("options",[]): lines.append(f" OPTION {opt}")
|
| 1122 |
-
lines.append(" END BRANCH")
|
| 1123 |
-
else:
|
| 1124 |
-
lines.append(f" {c['kind']} {c['expr']} WEIGHT {wt}")
|
| 1125 |
-
lines.append("END")
|
| 1126 |
-
|
| 1127 |
-
# ββ 4. Soft domain structural hints β ORDER 100+, weight 0.15 β
|
| 1128 |
-
# These nudge the search without overriding base constraints.
|
| 1129 |
-
si=100
|
| 1130 |
-
|
| 1131 |
-
if Axiom.ORDERED in ax and Axiom.BILINEAR not in ax and n>=2:
|
| 1132 |
-
lines.append(f"SCOPE domain_order ORDER {si}")
|
| 1133 |
-
lines.append(f" LINK {' '.join(variables)}")
|
| 1134 |
-
for i in range(n-1):
|
| 1135 |
-
lines.append(f" GEQ {variables[i+1]} - {variables[i]} WEIGHT {self.SOFT}")
|
| 1136 |
-
lines.append("END"); si+=1
|
| 1137 |
-
|
| 1138 |
-
if Axiom.SYMMETRIC in ax and Axiom.NETWORK in ax and n>=2:
|
| 1139 |
-
lines.append(f"SCOPE domain_sym ORDER {si}")
|
| 1140 |
-
lines.append(f" LINK {' '.join(variables[:min(4,n)])}")
|
| 1141 |
-
for i in range(0,min(4,n)-1,2):
|
| 1142 |
-
lines.append(f" EQ {variables[i]} + {variables[i+1]} WEIGHT {self.SOFT}")
|
| 1143 |
-
lines.append("END"); si+=1
|
| 1144 |
-
|
| 1145 |
-
if Axiom.METRIC in ax and Axiom.INJECTIVE in ax and n>=2:
|
| 1146 |
-
lines.append(f"SCOPE domain_sep ORDER {si}")
|
| 1147 |
-
lines.append(f" LINK {' '.join(variables[:min(4,n)])}")
|
| 1148 |
-
for a,b in itertools.combinations(range(min(4,n)),2):
|
| 1149 |
-
lines.append(f" GEQ ({variables[a]} - {variables[b]})**2 - 0.04 WEIGHT {self.SOFT}")
|
| 1150 |
-
lines.append("END"); si+=1
|
| 1151 |
-
|
| 1152 |
-
if Axiom.BILINEAR in ax and n>=2:
|
| 1153 |
-
lines.append(f"SCOPE domain_bilinear ORDER {si}")
|
| 1154 |
-
grp=variables[:min(3,n)]
|
| 1155 |
-
lines.append(f" LINK {' '.join(grp)}")
|
| 1156 |
-
for j in range(len(grp)-1):
|
| 1157 |
-
lines.append(f" EQ {grp[j]}*{grp[j+1]} WEIGHT {self.SOFT}")
|
| 1158 |
-
lines.append("END"); si+=1
|
| 1159 |
-
|
| 1160 |
-
if Axiom.MANIFOLD_HINT(ax) and n>=2:
|
| 1161 |
-
# Soft quadratic regularisation β only if base has no quadratic conserve
|
| 1162 |
-
has_quad=any("**2" in c.get("expr","") and c["kind"]=="CONSERVE" for c in axl_def.constraints)
|
| 1163 |
-
if not has_quad:
|
| 1164 |
-
lines.append(f"SCOPE domain_quad ORDER {si}")
|
| 1165 |
-
lines.append(f" LINK {' '.join(variables)}")
|
| 1166 |
-
lines.append(f" EQ {' + '.join(f'{v}**2' for v in variables)} - {float(n)*0.25:.2f} WEIGHT {self.SOFT}")
|
| 1167 |
-
lines.append("END"); si+=1
|
| 1168 |
-
|
| 1169 |
-
return "\n".join(lines)
|
| 1170 |
-
|
| 1171 |
-
# Small helper β avoid if-chain sprawl
|
| 1172 |
-
def _manifold_hint(ax): return Axiom.QUADRATIC in ax and Axiom.CONSERVED not in ax
|
| 1173 |
-
Axiom.MANIFOLD_HINT = staticmethod(_manifold_hint)
|
| 1174 |
-
|
| 1175 |
@dataclass
|
| 1176 |
-
class
|
| 1177 |
-
round_idx:int;
|
| 1178 |
-
ce:float; solved:bool;
|
| 1179 |
-
|
| 1180 |
-
|
| 1181 |
-
|
| 1182 |
-
|
| 1183 |
-
def
|
| 1184 |
-
self.
|
| 1185 |
-
|
| 1186 |
-
|
| 1187 |
-
|
| 1188 |
-
|
| 1189 |
-
|
| 1190 |
-
|
| 1191 |
-
|
| 1192 |
-
|
| 1193 |
-
|
| 1194 |
-
|
| 1195 |
-
|
| 1196 |
-
|
| 1197 |
-
|
| 1198 |
-
|
| 1199 |
-
|
| 1200 |
-
|
| 1201 |
-
|
| 1202 |
-
|
| 1203 |
-
|
| 1204 |
-
|
| 1205 |
-
|
| 1206 |
-
|
| 1207 |
-
|
| 1208 |
-
|
| 1209 |
-
|
| 1210 |
-
|
| 1211 |
-
|
| 1212 |
-
|
| 1213 |
-
|
| 1214 |
-
|
| 1215 |
-
|
| 1216 |
-
|
| 1217 |
-
|
| 1218 |
-
|
| 1219 |
-
|
| 1220 |
-
|
| 1221 |
-
|
| 1222 |
-
|
| 1223 |
-
|
| 1224 |
-
|
| 1225 |
-
|
| 1226 |
-
|
| 1227 |
-
|
| 1228 |
-
|
| 1229 |
-
|
| 1230 |
-
|
| 1231 |
-
|
| 1232 |
-
|
| 1233 |
-
|
| 1234 |
-
|
| 1235 |
-
|
| 1236 |
-
|
| 1237 |
-
|
| 1238 |
-
|
| 1239 |
-
|
| 1240 |
-
|
| 1241 |
-
binding=result["binding"]; ce=result["ce"]; solved=result["solved"]
|
| 1242 |
-
|
| 1243 |
-
# Verify against base problem + anchors
|
| 1244 |
-
verify=VERIFY_LAYER.run(binding,base_problem,axl_def.anchors)
|
| 1245 |
-
base_ce=verify.gate1_ce # this IS the true base CE now
|
| 1246 |
-
|
| 1247 |
-
trace=HypothesisTrace(
|
| 1248 |
-
hid=f"R{round_idx+1}_{winner.name[:10]}",
|
| 1249 |
-
round_idx=round_idx+1, domain_name=winner.name,
|
| 1250 |
-
action=action, ce_before=self.best_ce if self.best_ce<float('inf') else 99.0,
|
| 1251 |
-
ce_after=base_ce, verify=verify,
|
| 1252 |
-
survived=verify.overall_pass, elapsed_ms=elapsed,
|
| 1253 |
-
strategy_note=strategy.polish)
|
| 1254 |
-
round_traces.append(trace); self.all_traces.append(trace)
|
| 1255 |
-
|
| 1256 |
-
status="β SURVIVED" if verify.overall_pass else "β FAILED"
|
| 1257 |
-
print(f" DomCE={ce:.5f} BaseCE={base_ce:.5f} | "
|
| 1258 |
-
f"G1={'β' if verify.gate1_pass else 'β'} G2={'β' if verify.gate2_pass else 'β'} | {status}")
|
| 1259 |
-
for inv_name,(err,passed) in verify.gate2_results.items():
|
| 1260 |
-
print(f" [{'β' if passed else 'β'}] {inv_name}: |err|={err:.6f}")
|
| 1261 |
-
|
| 1262 |
-
if base_ce<self.best_ce:
|
| 1263 |
-
self.best_ce=base_ce; self.best_binding=dict(binding); self.best_domain=winner
|
| 1264 |
-
|
| 1265 |
-
if verify.overall_pass:
|
| 1266 |
-
self.history.append(DebateRound(round_idx,winner,psl_text,base_ce,
|
| 1267 |
-
verify.overall_pass,action,strategy.name,round_traces))
|
| 1268 |
-
print(f"\nβ VERIFIED + SOLVED in round {round_idx+1}"); break
|
| 1269 |
-
|
| 1270 |
-
except Exception as e:
|
| 1271 |
-
import traceback; traceback.print_exc()
|
| 1272 |
-
trace=HypothesisTrace(hid=f"R{round_idx+1}_ERR",round_idx=round_idx+1,
|
| 1273 |
-
domain_name=winner.name,action=action,ce_before=99.0,ce_after=99.0,
|
| 1274 |
-
verify=None,survived=False,elapsed_ms=0)
|
| 1275 |
-
round_traces.append(trace); self.all_traces.append(trace)
|
| 1276 |
-
|
| 1277 |
-
self.history.append(DebateRound(round_idx,winner,psl_text,
|
| 1278 |
-
self.best_ce,self.best_ce<SOLVE_THRESHOLD,action,strategy.name,round_traces))
|
| 1279 |
-
current=winner
|
| 1280 |
-
|
| 1281 |
-
print(f"\n{'β'*60}\nRESULT: BaseCE={self.best_ce:.5f} | Domain={self.best_domain.name if self.best_domain else '?'}")
|
| 1282 |
-
return self.best_binding,self.best_ce,self.history
|
| 1283 |
|
| 1284 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1285 |
-
# SECTION 13: HARDCODED AXL PROBLEMS
|
| 1286 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1287 |
AXL_PROBLEMS=[
|
| 1288 |
-
|
| 1289 |
-
# ββ PROBLEM 1: NormManifold4D βββββββββββββββββββββββββββββββββββββ
|
| 1290 |
-
# x1 pinned at 0.5. Find x2,x3,x4 on unit sphere summing to -0.5.
|
| 1291 |
-
# Known solution family: x2=-0.809, x3=0.309, x4=0 (and rotations)
|
| 1292 |
AXLProblemDef(
|
| 1293 |
name="NormManifold4D",
|
| 1294 |
description="4 vars on unit sphere, zero sum, x1 observed at 0.5",
|
| 1295 |
axioms={Axiom.CONTINUOUS,Axiom.QUADRATIC,Axiom.CONSERVED,Axiom.METRIC,Axiom.SYMMETRIC},
|
| 1296 |
variables=[
|
| 1297 |
-
{"name":"x1","lo":-1.0,"hi":1.0},
|
| 1298 |
-
{"name":"
|
| 1299 |
-
{"name":"x3","lo":-1.0,"hi":1.0},
|
| 1300 |
-
{"name":"x4","lo":-1.0,"hi":1.0},
|
| 1301 |
],
|
| 1302 |
constraints=[
|
| 1303 |
{"kind":"CONSERVE","expr":"x1**2 + x2**2 + x3**2 + x4**2 - 1.0"},
|
| 1304 |
{"kind":"EQ", "expr":"x1 + x2 + x3 + x4","weight":2.0},
|
| 1305 |
],
|
| 1306 |
scopes=[{"name":"sphere","order":0,"vars":["x1","x2","x3","x4"],
|
| 1307 |
-
"constraints":[
|
| 1308 |
-
{"kind":"EQ","expr":"x1**2 + x2**2 + x3**2 + x4**2 - 1.0","weight":5.0},
|
| 1309 |
-
]}],
|
| 1310 |
anchors=[
|
| 1311 |
AXLInvariant("unit_sphere","x1**2 + x2**2 + x3**2 + x4**2 - 1.0",1e-3),
|
| 1312 |
AXLInvariant("zero_sum","x1 + x2 + x3 + x4",1e-3),
|
|
@@ -1314,9 +1111,6 @@ AXL_PROBLEMS=[
|
|
| 1314 |
],
|
| 1315 |
observations={"x1":0.5},
|
| 1316 |
),
|
| 1317 |
-
|
| 1318 |
-
# ββ PROBLEM 2: BilinearChain6 βββββββββββββββββββββββββββββββββββββ
|
| 1319 |
-
# Known exact solution: t1=0.5,t2=1.0,t3=1.0,t4=2.0,t5=1.5,t6=3.0
|
| 1320 |
AXLProblemDef(
|
| 1321 |
name="BilinearChain6",
|
| 1322 |
description="6-var ordered chain with bilinear products and sum conservation",
|
|
@@ -1324,10 +1118,8 @@ AXL_PROBLEMS=[
|
|
| 1324 |
variables=[{"name":f"t{i}","lo":0.0,"hi":3.0} for i in range(1,7)],
|
| 1325 |
constraints=[
|
| 1326 |
{"kind":"CONSERVE","expr":"t1 + t2 + t3 + t4 + t5 + t6 - 9.0"},
|
| 1327 |
-
{"kind":"GEQ","expr":"t2 - t1","weight":1.0},
|
| 1328 |
-
{"kind":"GEQ","expr":"t3 -
|
| 1329 |
-
{"kind":"GEQ","expr":"t4 - t3","weight":1.0},
|
| 1330 |
-
{"kind":"GEQ","expr":"t5 - t4","weight":1.0},
|
| 1331 |
{"kind":"GEQ","expr":"t6 - t5","weight":1.0},
|
| 1332 |
],
|
| 1333 |
scopes=[{"name":"chain","order":0,"vars":[f"t{i}" for i in range(1,7)],
|
|
@@ -1343,59 +1135,40 @@ AXL_PROBLEMS=[
|
|
| 1343 |
AXLInvariant("bilinear_hi","t5*t6 - 4.5",0.05),
|
| 1344 |
],
|
| 1345 |
),
|
| 1346 |
-
|
| 1347 |
-
# ββ PROBLEM 3: PhaseCollider (FIXED β provably feasible) ββββββββββ
|
| 1348 |
-
# Conservation: p2 = -p1 (momentum = 0)
|
| 1349 |
-
# Phase A: |p1|=0.5, separation=1.0. Phase B: |p1|=1.0, separation=4.0
|
| 1350 |
-
# Branch on p1 radius; separation follows from conservation automatically.
|
| 1351 |
AXLProblemDef(
|
| 1352 |
name="PhaseCollider",
|
| 1353 |
description="2-particle symmetric collision: conservation + phase branch",
|
| 1354 |
axioms={Axiom.DISCRETE,Axiom.MUTABLE,Axiom.SYMMETRIC,Axiom.NETWORK,Axiom.CONSERVED},
|
| 1355 |
variables=[
|
| 1356 |
-
{"name":"p1x","lo":-2.0,"hi":2.0},
|
| 1357 |
-
{"name":"
|
| 1358 |
-
{"name":"p1y","lo":-2.0,"hi":2.0},
|
| 1359 |
-
{"name":"p2y","lo":-2.0,"hi":2.0},
|
| 1360 |
],
|
| 1361 |
constraints=[
|
| 1362 |
-
{"kind":"CONSERVE","expr":"p1x + p2x"},
|
| 1363 |
-
{"kind":"CONSERVE","expr":"p1y + p2y"}, # total momentum y = 0
|
| 1364 |
],
|
| 1365 |
scopes=[{"name":"phase","order":0,"vars":["p1x","p2x","p1y","p2y"],
|
| 1366 |
"constraints":[
|
| 1367 |
-
# Phase branch: p1 at radius 0.5 OR radius 1.0
|
| 1368 |
{"kind":"BRANCH","name":"phase_select","options":[
|
| 1369 |
-
"p1x**2 + p1y**2 - 0.25",
|
| 1370 |
-
"p1x**2 + p1y**2 - 1.0", # phase B: r=1.0
|
| 1371 |
]},
|
| 1372 |
-
# Symmetry: p2 = -p1 (follows from conservation, reinforced)
|
| 1373 |
{"kind":"EQ","expr":"p1x + p2x","weight":3.0},
|
| 1374 |
{"kind":"EQ","expr":"p1y + p2y","weight":3.0},
|
| 1375 |
]}],
|
| 1376 |
anchors=[
|
| 1377 |
AXLInvariant("momentum_x","p1x + p2x",1e-3),
|
| 1378 |
AXLInvariant("momentum_y","p1y + p2y",1e-3),
|
| 1379 |
-
|
| 1380 |
-
AXLInvariant("phase_A_or_B",
|
| 1381 |
-
"(p1x**2 + p1y**2 - 0.25)*(p1x**2 + p1y**2 - 1.0)",0.05),
|
| 1382 |
],
|
| 1383 |
),
|
| 1384 |
-
|
| 1385 |
-
# ββ PROBLEM 4: MetricPacking3D ββββββββββββββββββββββββββββββββββββ
|
| 1386 |
-
# Known solution: a=-sqrt(3), b=0, c=sqrt(3) β (-1.732, 0, 1.732)
|
| 1387 |
-
# centred: 0 β, sep_ab: 3 β₯ 1 β, sep_bc: 3 β₯ 1 β, sep_ac: 12 β₯ 4 β, norm: 6 β
|
| 1388 |
AXLProblemDef(
|
| 1389 |
name="MetricPacking3D",
|
| 1390 |
description="3 vars packed with min separation, centred, norm=6",
|
| 1391 |
axioms={Axiom.CONTINUOUS,Axiom.METRIC,Axiom.INJECTIVE,Axiom.CONSERVED,Axiom.SYMMETRIC},
|
| 1392 |
variables=[
|
| 1393 |
-
{"name":"a","lo":-3.0,"hi":3.0},
|
| 1394 |
-
{"name":"b","lo":-3.0,"hi":3.0},
|
| 1395 |
-
{"name":"c","lo":-3.0,"hi":3.0},
|
| 1396 |
],
|
| 1397 |
constraints=[
|
| 1398 |
-
{"kind":"CONSERVE","expr":"a + b + c"},
|
| 1399 |
{"kind":"GEQ","expr":"(a - b)**2 - 1.0","weight":2.0},
|
| 1400 |
{"kind":"GEQ","expr":"(b - c)**2 - 1.0","weight":2.0},
|
| 1401 |
{"kind":"GEQ","expr":"(a - c)**2 - 4.0","weight":2.0},
|
|
@@ -1406,7 +1179,7 @@ AXL_PROBLEMS=[
|
|
| 1406 |
]}],
|
| 1407 |
anchors=[
|
| 1408 |
AXLInvariant("centred","a + b + c",1e-3),
|
| 1409 |
-
AXLInvariant("sep_ab","(a - b)**2 - 1.0",0.5),
|
| 1410 |
AXLInvariant("sep_bc","(b - c)**2 - 1.0",0.5),
|
| 1411 |
AXLInvariant("norm_6","a**2 + b**2 + c**2 - 6.0",0.05),
|
| 1412 |
],
|
|
@@ -1426,46 +1199,41 @@ def build_base_problem(axl_def:AXLProblemDef) -> Problem:
|
|
| 1426 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1427 |
STATE_LOCK=threading.Lock()
|
| 1428 |
RUN_LOG:List[Dict]=[]
|
| 1429 |
-
|
| 1430 |
POOL=ThreadPoolExecutor(max_workers=2)
|
| 1431 |
|
| 1432 |
def _run_problem(axl_def:AXLProblemDef):
|
| 1433 |
-
t0=time.time()
|
| 1434 |
try:
|
| 1435 |
-
base_prob=build_base_problem(axl_def)
|
| 1436 |
-
binding,ce,rounds=
|
| 1437 |
-
|
| 1438 |
-
survived=[t for t in
|
| 1439 |
-
failed=[t for t in
|
| 1440 |
-
best_trace=min(
|
| 1441 |
-
|
| 1442 |
record={
|
| 1443 |
-
"problem":axl_def.name,
|
| 1444 |
-
"description":axl_def.description,
|
| 1445 |
-
"
|
| 1446 |
-
"
|
| 1447 |
-
"
|
| 1448 |
-
"
|
| 1449 |
-
"
|
| 1450 |
-
|
| 1451 |
-
|
| 1452 |
-
"
|
| 1453 |
-
"
|
| 1454 |
-
"
|
| 1455 |
-
"
|
| 1456 |
-
"
|
| 1457 |
-
|
| 1458 |
-
|
| 1459 |
-
|
| 1460 |
-
|
| 1461 |
-
} for t in DEBATE_ENGINE.all_traces],
|
| 1462 |
-
"survived_count":len(survived),
|
| 1463 |
-
"failed_count":len(failed),
|
| 1464 |
-
"best_domain":best_trace.domain_name if best_trace else "β",
|
| 1465 |
}
|
| 1466 |
with STATE_LOCK:
|
| 1467 |
RUN_LOG.append(record)
|
| 1468 |
-
if len(RUN_LOG)>40: RUN_LOG.pop(0)
|
| 1469 |
except Exception as e:
|
| 1470 |
import traceback; traceback.print_exc()
|
| 1471 |
print(f"[RUN ERROR] {axl_def.name}: {e}")
|
|
@@ -1474,7 +1242,7 @@ async def run_loop():
|
|
| 1474 |
loop=asyncio.get_event_loop()
|
| 1475 |
while True:
|
| 1476 |
prob=random.choice(AXL_PROBLEMS)
|
| 1477 |
-
await loop.run_in_executor(POOL,_run_problem,prob)
|
| 1478 |
await asyncio.sleep(0.3)
|
| 1479 |
|
| 1480 |
@asynccontextmanager
|
|
@@ -1486,7 +1254,7 @@ async def lifespan(app):
|
|
| 1486 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1487 |
# SECTION 15: FASTAPI + DASHBOARD
|
| 1488 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1489 |
-
app=FastAPI(title="Practicality
|
| 1490 |
|
| 1491 |
def _render_collapse(record:Dict) -> str:
|
| 1492 |
b=record["binding"]; traces=record["traces"]
|
|
@@ -1516,14 +1284,12 @@ def _render_collapse(record:Dict) -> str:
|
|
| 1516 |
|
| 1517 |
def trail_span(t):
|
| 1518 |
c="#4CAF50" if t["survived"] else "#333"
|
| 1519 |
-
star=" β
|
| 1520 |
-
strat=f" [{t.get('strategy','')}]" if t.get("strategy") else ""
|
| 1521 |
return (f"<div style='color:{c};font-size:0.78em;margin-bottom:3px'>"
|
| 1522 |
-
f"[R{t['round']}] <span style='color:#FF9800'>{t['
|
| 1523 |
-
f" CE={t['ce']:.5f}"
|
| 1524 |
-
f"
|
| 1525 |
-
f"
|
| 1526 |
-
f"<span style='color:#555'>{strat}</span>"
|
| 1527 |
f"<span style='color:#4CAF50;font-weight:700'>{star}</span></div>")
|
| 1528 |
|
| 1529 |
trail="".join(trail_span(t) for t in traces)
|
|
@@ -1534,7 +1300,6 @@ def _render_collapse(record:Dict) -> str:
|
|
| 1534 |
<span style='color:{ce_color};font-weight:700;font-size:1.05em'>{status}</span>
|
| 1535 |
<span style='color:#444;font-size:0.85em'>{record["problem"]}</span>
|
| 1536 |
<span style='color:#333;font-size:0.8em'>BaseCE={ce:.6f}</span>
|
| 1537 |
-
<span style='color:#555;font-size:0.75em'>{record["elapsed"]}s</span>
|
| 1538 |
<span style='color:#26C6DA;font-size:0.75em'>{record["survived_count"]} survived / {record["failed_count"]} failed</span>
|
| 1539 |
</div>
|
| 1540 |
<div style='display:flex'>
|
|
@@ -1542,7 +1307,7 @@ def _render_collapse(record:Dict) -> str:
|
|
| 1542 |
<div style='color:#333;font-size:0.7em;margin-bottom:5px'>BINDING</div>
|
| 1543 |
<table style='border-collapse:collapse;width:100%'>{binding_rows}</table>
|
| 1544 |
</div>
|
| 1545 |
-
<div style='flex:0 0
|
| 1546 |
<div style='color:#333;font-size:0.7em;margin-bottom:5px'>INVARIANTS (Gate 2)</div>
|
| 1547 |
<table style='border-collapse:collapse;width:100%'>
|
| 1548 |
{inv_rows or "<tr><td colspan='3' style='color:#222'>β</td></tr>"}
|
|
@@ -1550,7 +1315,7 @@ def _render_collapse(record:Dict) -> str:
|
|
| 1550 |
</div>
|
| 1551 |
<div style='flex:1;padding:10px 12px'>
|
| 1552 |
<div style='color:#333;font-size:0.7em;margin-bottom:5px'>
|
| 1553 |
-
|
| 1554 |
</div>
|
| 1555 |
{trail}
|
| 1556 |
</div>
|
|
@@ -1563,29 +1328,33 @@ async def dashboard():
|
|
| 1563 |
runs=len(RUN_LOG); solved=sum(1 for r in RUN_LOG if r.get("solved",False))
|
| 1564 |
avg_ce=round(sum(r["ce"] for r in RUN_LOG)/max(1,runs),5) if RUN_LOG else 0
|
| 1565 |
|
| 1566 |
-
|
| 1567 |
-
|
| 1568 |
-
for
|
| 1569 |
-
|
| 1570 |
-
|
| 1571 |
-
|
| 1572 |
-
|
| 1573 |
-
|
| 1574 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1575 |
f"<td style='color:#aaa'>{s['tried']}</td>"
|
| 1576 |
f"<td style='color:#4CAF50'>{s['survived']}</td>"
|
| 1577 |
f"<td style='color:#EF5350'>{s['tried']-s['survived']}</td>"
|
| 1578 |
f"<td style='color:#26C6DA'>{round(s['total_ce']/s['tried'],5) if s['tried'] else 0}</td>"
|
| 1579 |
-
f"<td style='color:#555'>{s['strategy']}</td>"
|
| 1580 |
f"<td style='color:{'#4CAF50' if s['survived']>0 else '#333'}'>"
|
| 1581 |
f"{round(s['survived']/s['tried']*100):.0f}%</td></tr>"
|
| 1582 |
-
for
|
| 1583 |
-
) or "<tr><td colspan='
|
| 1584 |
|
| 1585 |
collapses="".join(_render_collapse(r) for r in log) if log else \
|
| 1586 |
"<div style='color:#222;padding:20px'>Warming upβ¦</div>"
|
| 1587 |
|
| 1588 |
-
return f"""<!DOCTYPE html><html><head><title>Practicality
|
| 1589 |
<meta http-equiv="refresh" content="4">
|
| 1590 |
<style>
|
| 1591 |
body{{background:#090909;color:#e0e0e0;font-family:monospace;padding:20px;max-width:1400px}}
|
|
@@ -1596,21 +1365,21 @@ async def dashboard():
|
|
| 1596 |
th{{color:#2a2a2a;font-size:0.72em}}
|
| 1597 |
.badge{{display:inline-block;padding:3px 10px;border-radius:3px;background:#0e0e0e;margin:2px;font-size:0.78em;border:1px solid #1a1a1a}}
|
| 1598 |
</style></head><body>
|
| 1599 |
-
<h1>β Practicality
|
| 1600 |
<div style='color:#333;font-size:0.75em;margin-bottom:12px'>
|
| 1601 |
-
|
| 1602 |
</div>
|
| 1603 |
<div style='margin-bottom:16px'>
|
| 1604 |
<span class='badge' style='color:#aaa'>Runs: {runs}</span>
|
| 1605 |
<span class='badge' style='color:#4CAF50'>Solved: {solved}</span>
|
| 1606 |
<span class='badge' style='color:#26C6DA'>Avg BaseCE: {avg_ce}</span>
|
| 1607 |
<span class='badge' style='color:#FF9800'>Problems: {len(AXL_PROBLEMS)}</span>
|
| 1608 |
-
<span class='badge' style='color:#5C6BC0'>
|
| 1609 |
</div>
|
| 1610 |
-
<h3>
|
| 1611 |
<table>
|
| 1612 |
-
<tr><th>
|
| 1613 |
-
{
|
| 1614 |
</table>
|
| 1615 |
<h3>Collapse View β Recent Runs</h3>
|
| 1616 |
{collapses}
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
+
PRACTICALITY SYSTEM 12.0 β SET-BASED AXIOMATIC RAY TRACING
|
| 4 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 5 |
+
NEW IN 12.0:
|
| 6 |
+
Β· True Theorist Layer: Human-named domains deleted.
|
| 7 |
+
Β· Boolean Hypercube: 4,708 valid axiomatic permutations generated on boot.
|
| 8 |
+
Β· Strict Configuration: Axioms dictate Hypothesis weights directly (No soft constraints).
|
| 9 |
+
Β· Absolute Verification: Solver searches pure base problem, VerifyLayer arbitrates.
|
| 10 |
+
Β· Wavefront Search: Batches of rays are fired to deduce the problem signature.
|
|
|
|
|
|
|
|
|
|
| 11 |
"""
|
| 12 |
|
| 13 |
+
import time, random, math, threading, asyncio, warnings, itertools
|
| 14 |
from functools import reduce
|
| 15 |
from typing import Optional, Callable, List, Dict, Tuple, Any, Set
|
| 16 |
from dataclasses import dataclass, field
|
|
|
|
| 23 |
from sympy.parsing.sympy_parser import parse_expr
|
| 24 |
import torch
|
| 25 |
from fastapi import FastAPI
|
| 26 |
+
from fastapi.responses import HTMLResponse
|
| 27 |
import uvicorn
|
| 28 |
|
| 29 |
warnings.filterwarnings("ignore")
|
| 30 |
USE_GPU = torch.cuda.is_available()
|
| 31 |
DEVICE = torch.device("cuda" if USE_GPU else "cpu")
|
| 32 |
+
print(f"[SYSTEM 12.0] Compute: {'GPU' if USE_GPU else 'CPU'}")
|
| 33 |
|
| 34 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 35 |
# SECTION 1: CONSTANTS
|
|
|
|
| 136 |
lines=[l.strip() for l in text.strip().split('\n') if l.strip() and not l.strip().startswith('#')]
|
| 137 |
prog=PSLProgram("unnamed",[],[],[],[])
|
| 138 |
i=0
|
| 139 |
+
def advance(): nonlocal i; l=lines[i]; i+=1; return l
|
|
|
|
| 140 |
def peek(): return lines[i] if i<len(lines) else ""
|
| 141 |
def pvar(rest):
|
| 142 |
+
p=rest.split(); return PSLVar(p[0],float(p[1]),float(p[2])) if len(p)>=3 else None
|
|
|
|
| 143 |
def pw(rest):
|
| 144 |
if 'WEIGHT' in rest:
|
| 145 |
p=rest.split('WEIGHT'); return p[0].strip(), float(p[1].split()[0])
|
|
|
|
| 167 |
advance()
|
| 168 |
scons.append(PSLConstraint("or_eq","",scope=sname,weight=1.0,branches=opts))
|
| 169 |
elif kw=="ANNOTATE":
|
| 170 |
+
parts=rest.split();
|
| 171 |
if len(parts)>=3: prog.annotations[parts[0]]=parts[2]
|
| 172 |
return PSLScope(sname,order,depends or [],svars,links,scons)
|
| 173 |
|
|
|
|
| 190 |
advance()
|
| 191 |
prog.constraints.append(PSLConstraint("or_eq","",weight=1.0,branches=opts))
|
| 192 |
elif kw=="ANNOTATE":
|
| 193 |
+
parts=rest.split();
|
| 194 |
if len(parts)>=3: prog.annotations[parts[0]]=parts[2]
|
| 195 |
elif kw=="SCOPE":
|
| 196 |
parts=rest.split(); sname=parts[0] if parts else f"s{len(prog.scopes)}"
|
|
|
|
| 249 |
for sc in prog.scopes:
|
| 250 |
for v in sc.vars: add_var(v.name,v.lo,v.hi,sc.name)
|
| 251 |
for vname in sc.links:
|
| 252 |
+
if vname in bounds and vname not in scope_vars[sc.name]: scope_vars[sc.name].append(vname)
|
|
|
|
| 253 |
for c in sc.constraints:
|
| 254 |
kind="or_eq" if c.kind=="or_eq" else "equality" if c.kind=="eq" else "inequality"
|
| 255 |
add_con(kind,c.expr,c.kind,sc.name,c.weight,c.branches)
|
| 256 |
+
return ExpandedProblem(variables,bounds,constraints,dict(scope_groups),dict(scope_vars),prog.scope_order,prog.annotations)
|
|
|
|
|
|
|
| 257 |
|
| 258 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββοΏ½οΏ½οΏ½ββββββββββββββββ
|
| 259 |
# SECTION 4: AXL LAYER
|
|
|
|
| 271 |
def variables_list(self): return [v["name"] for v in self.variables]
|
| 272 |
|
| 273 |
class AXLtoPSLCompiler:
|
|
|
|
| 274 |
TEND_WEIGHT=0.3
|
| 275 |
def compile(self,prob:AXLProblemDef) -> str:
|
| 276 |
lines=[f"SPACE base_{prob.name}"]
|
|
|
|
| 516 |
VERIFY_LAYER=VerifyLayer()
|
| 517 |
|
| 518 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 519 |
+
# SECTION 7: HYPERCUBE SET-BASED THEORIST
|
| 520 |
+
# The fundamental engine. No names. No soft weights. Pure Logic.
|
| 521 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 522 |
+
class Axiom:
|
| 523 |
+
DISCRETE="DISCRETE"; CONTINUOUS="CONTINUOUS"; METRIC="METRIC"; NETWORK="NETWORK"
|
| 524 |
+
INJECTIVE="INJECTIVE"; SURJECTIVE="SURJECTIVE"; CONSERVED="CONSERVED"; MUTABLE="MUTABLE"
|
| 525 |
+
QUADRATIC="QUADRATIC"; BILINEAR="BILINEAR"; ORDERED="ORDERED"; SYMMETRIC="SYMMETRIC"
|
| 526 |
+
TRANSITIVE="TRANSITIVE"; ATOMIC="ATOMIC"; COMPOSITE="COMPOSITE"
|
| 527 |
+
|
| 528 |
+
ALL_AXIOMS = [
|
| 529 |
+
Axiom.DISCRETE, Axiom.CONTINUOUS, Axiom.METRIC, Axiom.NETWORK,
|
| 530 |
+
Axiom.INJECTIVE, Axiom.SURJECTIVE, Axiom.CONSERVED, Axiom.MUTABLE,
|
| 531 |
+
Axiom.QUADRATIC, Axiom.BILINEAR, Axiom.ORDERED, Axiom.SYMMETRIC,
|
| 532 |
+
Axiom.TRANSITIVE, Axiom.ATOMIC, Axiom.COMPOSITE
|
| 533 |
+
]
|
| 534 |
+
|
| 535 |
+
AXIOM_CONTRADICTIONS=[
|
| 536 |
+
{Axiom.DISCRETE,Axiom.CONTINUOUS},
|
| 537 |
+
{Axiom.INJECTIVE,Axiom.SURJECTIVE},
|
| 538 |
+
{Axiom.ORDERED,Axiom.SYMMETRIC},
|
| 539 |
+
{Axiom.ATOMIC,Axiom.COMPOSITE},
|
| 540 |
+
{Axiom.CONSERVED,Axiom.MUTABLE}
|
| 541 |
+
]
|
| 542 |
+
|
| 543 |
+
def build_hypercube() -> List[Set[str]]:
|
| 544 |
+
"""Generates all non-contradictory combinations of axioms up to length 6."""
|
| 545 |
+
valid = []
|
| 546 |
+
for r in range(1, 7):
|
| 547 |
+
for combo in itertools.combinations(ALL_AXIOMS, r):
|
| 548 |
+
cset = set(combo)
|
| 549 |
+
if not any(contra.issubset(cset) for contra in AXIOM_CONTRADICTIONS):
|
| 550 |
+
valid.append(cset)
|
| 551 |
+
return valid
|
| 552 |
+
|
| 553 |
+
# Boots instantly. Generates exactly 4,708 valid universal rays.
|
| 554 |
+
AXIOM_HYPERCUBE = build_hypercube()
|
| 555 |
+
print(f"[SYSTEM 12.0] Axiomatic Hypercube Booted: {len(AXIOM_HYPERCUBE)} valid rays.")
|
| 556 |
+
|
| 557 |
@dataclass
|
| 558 |
class DomainStrategy:
|
| 559 |
name: str
|
| 560 |
+
hyp_weights: Dict[str,float] # 0.0 strictly prunes hypothesis type
|
| 561 |
polish: str # "adam" | "gradient" | "both"
|
| 562 |
+
explore_early: bool
|
| 563 |
+
|
| 564 |
+
def compile_strategy(axioms: Set[str]) -> DomainStrategy:
|
| 565 |
+
"""Translates a pure axiom set into strict search constraints."""
|
| 566 |
+
name = "|".join(a[:3] for a in sorted(axioms)) if axioms else "BASE"
|
| 567 |
+
weights = {"branch": 0.0, "chain": 0.0, "coherence": 0.0, "residual_chain": 0.0, "manifold": 0.0}
|
| 568 |
+
polish = "both"
|
| 569 |
+
explore_early = False
|
| 570 |
+
|
| 571 |
+
if Axiom.CONTINUOUS in axioms:
|
| 572 |
+
weights["manifold"] = 1.5
|
| 573 |
+
weights["branch"] = 1.0
|
| 574 |
+
weights["residual_chain"] = 1.0
|
| 575 |
+
polish = "adam"
|
| 576 |
+
if Axiom.DISCRETE in axioms:
|
| 577 |
+
weights["chain"] = 2.0
|
| 578 |
+
weights["branch"] = 1.5
|
| 579 |
+
weights["coherence"] = 1.0
|
| 580 |
+
polish = "gradient"
|
| 581 |
+
explore_early = True
|
| 582 |
+
|
| 583 |
+
if Axiom.QUADRATIC in axioms or Axiom.METRIC in axioms:
|
| 584 |
+
weights["manifold"] += 1.0
|
| 585 |
+
weights["branch"] += 0.5
|
| 586 |
+
if Axiom.ORDERED in axioms or Axiom.NETWORK in axioms:
|
| 587 |
+
weights["chain"] += 1.0
|
| 588 |
+
if Axiom.MUTABLE in axioms or Axiom.BILINEAR in axioms:
|
| 589 |
+
weights["branch"] += 1.0
|
| 590 |
+
weights["residual_chain"] += 1.0
|
| 591 |
+
|
| 592 |
+
if sum(weights.values()) < 0.1:
|
| 593 |
+
weights = {"branch": 1.0, "chain": 1.0, "coherence": 1.0, "residual_chain": 1.0, "manifold": 1.0}
|
| 594 |
+
|
| 595 |
+
return DomainStrategy(name=f"[{name}]", hyp_weights=weights, polish=polish, explore_early=explore_early)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
|
| 597 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 598 |
+
# SECTION 8: SHARED DATACLASSES
|
| 599 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 600 |
@dataclass
|
| 601 |
class Hypothesis:
|
|
|
|
| 605 |
|
| 606 |
@dataclass
|
| 607 |
class HypothesisTrace:
|
| 608 |
+
hid:str; round_idx:int; ray_name:str; action:str
|
| 609 |
ce_before:float; ce_after:float
|
| 610 |
verify:Optional[VerifyResult]; survived:bool; elapsed_ms:float
|
|
|
|
| 611 |
|
| 612 |
@dataclass
|
| 613 |
class StructuralModel:
|
|
|
|
| 799 |
if nce<best_ce: best_ce=nce; best_b=dict(b)
|
| 800 |
return best_b,best_ce
|
| 801 |
|
| 802 |
+
def solve_by_hypothesis(problem:Problem, budget:int=TOTAL_BUDGET, strategy:Optional[DomainStrategy]=None) -> Dict:
|
|
|
|
| 803 |
t0=time.time()
|
| 804 |
explore_trigger = 2 if (strategy and strategy.explore_early) else 4
|
| 805 |
polish_pref = strategy.polish if strategy else "both"
|
|
|
|
| 818 |
if model.best_ce<SOLVE_THRESHOLD:
|
| 819 |
l7=TOPOLOGY_ORACLE.evaluate(problem,active_scopes)
|
| 820 |
l9=RESIDUAL_ORACLE.evaluate(model.best_binding,problem,l7.hub_vars)
|
| 821 |
+
return {"binding":model.best_binding,"ce":model.best_ce,"solved":True,"l7":l7,"l9":l9,"time":round(time.time()-t0,3)}
|
|
|
|
| 822 |
|
| 823 |
oracle=HypothesisOracle(strategy=strategy); consec=0
|
| 824 |
for round_idx in range(HYPOTHESIS_MAX_ROUNDS):
|
|
|
|
| 844 |
eb,ece=_mprt_sample(problem,work_box,N_MPRT_EXPLORE)
|
| 845 |
if ece<model.best_ce: model.best_ce=ece; model.best_binding=dict(eb); consec=0
|
| 846 |
|
| 847 |
+
# Strategy-directed polish
|
| 848 |
if polish_pref in ("gradient","both") and SOLVE_THRESHOLD<model.best_ce<2.0:
|
| 849 |
gb,gce=_gradient_polish(problem,model.best_binding)
|
| 850 |
if gce<model.best_ce: model.best_ce=gce; model.best_binding=gb
|
| 851 |
if polish_pref in ("adam","both") and SOLVE_THRESHOLD<model.best_ce<1.0:
|
| 852 |
ab,ace=_adam_polish(problem,model.best_binding)
|
| 853 |
if ace<model.best_ce: model.best_ce=ace; model.best_binding=ab
|
|
|
|
|
|
|
|
|
|
|
|
|
| 854 |
|
| 855 |
final_l7=TOPOLOGY_ORACLE.evaluate(problem,active_scopes)
|
| 856 |
final_l9=RESIDUAL_ORACLE.evaluate(model.best_binding,problem,final_l7.hub_vars)
|
|
|
|
| 858 |
"l7":final_l7,"l9":final_l9,"time":round(time.time()-t0,3)}
|
| 859 |
|
| 860 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 861 |
+
# SECTION 11: HYPOTHESIS ENGINE (Strict Pruning)
|
| 862 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 863 |
class HypothesisOracle:
|
| 864 |
def __init__(self, strategy:Optional[DomainStrategy]=None):
|
|
|
|
| 866 |
|
| 867 |
def generate(self,problem,model,l7,l8,l9,round_idx):
|
| 868 |
hyps=[]
|
| 869 |
+
# Strict pruning: If strategy assigns 0 weight, do NOT generate.
|
| 870 |
+
w_br = self.strategy.hyp_weights.get("branch",1.0) if self.strategy else 1.0
|
| 871 |
+
w_ch = self.strategy.hyp_weights.get("chain",1.0) if self.strategy else 1.0
|
| 872 |
+
w_co = self.strategy.hyp_weights.get("coherence",1.0) if self.strategy else 1.0
|
| 873 |
+
w_rc = self.strategy.hyp_weights.get("residual_chain",1.0) if self.strategy else 1.0
|
| 874 |
+
w_mf = self.strategy.hyp_weights.get("manifold",1.0) if self.strategy else 1.0
|
| 875 |
+
|
| 876 |
+
if w_br > 0.01: hyps.extend(self._branch_hypotheses(problem,model,l9))
|
| 877 |
+
if w_ch > 0.01: hyps.extend(self._chain_hypotheses(problem,model,l7))
|
| 878 |
+
if w_co > 0.01: hyps.extend(self._coherence_hypotheses(problem,model,l8))
|
| 879 |
+
if w_rc > 0.01: hyps.extend(self._residual_chain_hypotheses(problem,model,l9))
|
| 880 |
+
if w_mf > 0.01 and round_idx>=3: hyps.extend(self._manifold_tangent_hypotheses(problem,model,l9))
|
| 881 |
+
|
| 882 |
if self.strategy:
|
| 883 |
for hyp in hyps:
|
| 884 |
w=self.strategy.hyp_weights.get(hyp.h_type,1.0)
|
| 885 |
hyp.confidence=min(0.99,hyp.confidence*w)
|
| 886 |
+
|
| 887 |
hyps=[h for h in hyps if h.hid not in model.failure_patterns]
|
| 888 |
return sorted(hyps,key=lambda h:-h.confidence)
|
| 889 |
|
|
|
|
| 1016 |
return best_b,best_ce
|
| 1017 |
|
| 1018 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1019 |
+
# SECTION 12: AXIOMATIC RAY TRACER (THE THEORIST)
|
| 1020 |
+
# Fires strict conceptual sets at the base problem. VerifyLayer arbitrates.
|
|
|
|
|
|
|
|
|
|
| 1021 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1022 |
@dataclass
|
| 1023 |
+
class RayTraceRound:
|
| 1024 |
+
round_idx:int; ray_axioms:Set[str]; ray_name:str
|
| 1025 |
+
ce:float; solved:bool; traces:List[HypothesisTrace]=field(default_factory=list)
|
| 1026 |
+
|
| 1027 |
+
class AxiomRayTracer:
|
| 1028 |
+
WAVEFRONT_SIZE = 6
|
| 1029 |
+
|
| 1030 |
+
def trace(self, axl_def: AXLProblemDef, base_problem: Problem) -> Tuple[Dict, float, List[RayTraceRound]]:
|
| 1031 |
+
self.all_traces = []
|
| 1032 |
+
best_ce = float('inf')
|
| 1033 |
+
best_binding = {}
|
| 1034 |
+
best_ray = None
|
| 1035 |
+
history = []
|
| 1036 |
+
|
| 1037 |
+
# Phase 1: The Wavefront (Sample diverse universal rays)
|
| 1038 |
+
rays_to_test = random.sample(AXIOM_HYPERCUBE, self.WAVEFRONT_SIZE)
|
| 1039 |
+
|
| 1040 |
+
# Always test the explicitly defined axioms as a baseline ray
|
| 1041 |
+
if axl_def.axioms and axl_def.axioms not in rays_to_test:
|
| 1042 |
+
rays_to_test[0] = axl_def.axioms
|
| 1043 |
+
|
| 1044 |
+
print(f"\n{'β'*65}\nTHEORIST RAY TRACE: {axl_def.name}\n{'β'*65}")
|
| 1045 |
+
|
| 1046 |
+
for round_idx, ray_axioms in enumerate(rays_to_test):
|
| 1047 |
+
strategy = compile_strategy(ray_axioms)
|
| 1048 |
+
print(f"\n[Ray {round_idx+1}/{self.WAVEFRONT_SIZE}] Firing: {strategy.name}")
|
| 1049 |
+
|
| 1050 |
+
t_start = time.time()
|
| 1051 |
+
# Strict solver search using base problem + axiom strategy limits
|
| 1052 |
+
result = solve_by_hypothesis(base_problem, budget=TOTAL_BUDGET, strategy=strategy)
|
| 1053 |
+
elapsed = round((time.time()-t_start)*1000, 1)
|
| 1054 |
+
|
| 1055 |
+
binding = result["binding"]
|
| 1056 |
+
|
| 1057 |
+
# The VerifyLayer is the absolute arbiter.
|
| 1058 |
+
verify = VERIFY_LAYER.run(binding, base_problem, axl_def.anchors)
|
| 1059 |
+
base_ce = verify.gate1_ce
|
| 1060 |
+
|
| 1061 |
+
trace = HypothesisTrace(
|
| 1062 |
+
hid=f"R{round_idx+1}", round_idx=round_idx+1,
|
| 1063 |
+
ray_name=strategy.name, action="Wavefront",
|
| 1064 |
+
ce_before=best_ce if best_ce < float('inf') else 99.0,
|
| 1065 |
+
ce_after=base_ce, verify=verify,
|
| 1066 |
+
survived=verify.overall_pass, elapsed_ms=elapsed
|
| 1067 |
+
)
|
| 1068 |
+
self.all_traces.append(trace)
|
| 1069 |
+
|
| 1070 |
+
status = "β SURVIVED" if verify.overall_pass else "β FAILED"
|
| 1071 |
+
print(f" BaseCE={base_ce:.5f} | G1={'β' if verify.gate1_pass else 'β'} "
|
| 1072 |
+
f"G2={'β' if verify.gate2_pass else 'β'} | {status}")
|
| 1073 |
+
for inv_name, (err, passed) in verify.gate2_results.items():
|
| 1074 |
+
print(f" [{'β' if passed else 'β'}] {inv_name}: |err|={err:.6f}")
|
| 1075 |
+
|
| 1076 |
+
if base_ce < best_ce:
|
| 1077 |
+
best_ce = base_ce
|
| 1078 |
+
best_binding = dict(binding)
|
| 1079 |
+
best_ray = strategy.name
|
| 1080 |
+
|
| 1081 |
+
history.append(RayTraceRound(round_idx, ray_axioms, strategy.name, base_ce, verify.overall_pass, [trace]))
|
| 1082 |
+
|
| 1083 |
+
if verify.overall_pass:
|
| 1084 |
+
print(f"\nβ TRUE UNIVERSE FOUND in Ray {round_idx+1}"); break
|
| 1085 |
+
|
| 1086 |
+
print(f"\n{'β'*65}\nRESULT: BaseCE={best_ce:.5f} | Best Ray={best_ray}")
|
| 1087 |
+
return best_binding, best_ce, history
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1088 |
|
| 1089 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1090 |
+
# SECTION 13: HARDCODED AXL PROBLEMS
|
| 1091 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1092 |
AXL_PROBLEMS=[
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1093 |
AXLProblemDef(
|
| 1094 |
name="NormManifold4D",
|
| 1095 |
description="4 vars on unit sphere, zero sum, x1 observed at 0.5",
|
| 1096 |
axioms={Axiom.CONTINUOUS,Axiom.QUADRATIC,Axiom.CONSERVED,Axiom.METRIC,Axiom.SYMMETRIC},
|
| 1097 |
variables=[
|
| 1098 |
+
{"name":"x1","lo":-1.0,"hi":1.0}, {"name":"x2","lo":-1.0,"hi":1.0},
|
| 1099 |
+
{"name":"x3","lo":-1.0,"hi":1.0}, {"name":"x4","lo":-1.0,"hi":1.0},
|
|
|
|
|
|
|
| 1100 |
],
|
| 1101 |
constraints=[
|
| 1102 |
{"kind":"CONSERVE","expr":"x1**2 + x2**2 + x3**2 + x4**2 - 1.0"},
|
| 1103 |
{"kind":"EQ", "expr":"x1 + x2 + x3 + x4","weight":2.0},
|
| 1104 |
],
|
| 1105 |
scopes=[{"name":"sphere","order":0,"vars":["x1","x2","x3","x4"],
|
| 1106 |
+
"constraints":[{"kind":"EQ","expr":"x1**2 + x2**2 + x3**2 + x4**2 - 1.0","weight":5.0}]}],
|
|
|
|
|
|
|
| 1107 |
anchors=[
|
| 1108 |
AXLInvariant("unit_sphere","x1**2 + x2**2 + x3**2 + x4**2 - 1.0",1e-3),
|
| 1109 |
AXLInvariant("zero_sum","x1 + x2 + x3 + x4",1e-3),
|
|
|
|
| 1111 |
],
|
| 1112 |
observations={"x1":0.5},
|
| 1113 |
),
|
|
|
|
|
|
|
|
|
|
| 1114 |
AXLProblemDef(
|
| 1115 |
name="BilinearChain6",
|
| 1116 |
description="6-var ordered chain with bilinear products and sum conservation",
|
|
|
|
| 1118 |
variables=[{"name":f"t{i}","lo":0.0,"hi":3.0} for i in range(1,7)],
|
| 1119 |
constraints=[
|
| 1120 |
{"kind":"CONSERVE","expr":"t1 + t2 + t3 + t4 + t5 + t6 - 9.0"},
|
| 1121 |
+
{"kind":"GEQ","expr":"t2 - t1","weight":1.0}, {"kind":"GEQ","expr":"t3 - t2","weight":1.0},
|
| 1122 |
+
{"kind":"GEQ","expr":"t4 - t3","weight":1.0}, {"kind":"GEQ","expr":"t5 - t4","weight":1.0},
|
|
|
|
|
|
|
| 1123 |
{"kind":"GEQ","expr":"t6 - t5","weight":1.0},
|
| 1124 |
],
|
| 1125 |
scopes=[{"name":"chain","order":0,"vars":[f"t{i}" for i in range(1,7)],
|
|
|
|
| 1135 |
AXLInvariant("bilinear_hi","t5*t6 - 4.5",0.05),
|
| 1136 |
],
|
| 1137 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1138 |
AXLProblemDef(
|
| 1139 |
name="PhaseCollider",
|
| 1140 |
description="2-particle symmetric collision: conservation + phase branch",
|
| 1141 |
axioms={Axiom.DISCRETE,Axiom.MUTABLE,Axiom.SYMMETRIC,Axiom.NETWORK,Axiom.CONSERVED},
|
| 1142 |
variables=[
|
| 1143 |
+
{"name":"p1x","lo":-2.0,"hi":2.0}, {"name":"p2x","lo":-2.0,"hi":2.0},
|
| 1144 |
+
{"name":"p1y","lo":-2.0,"hi":2.0}, {"name":"p2y","lo":-2.0,"hi":2.0},
|
|
|
|
|
|
|
| 1145 |
],
|
| 1146 |
constraints=[
|
| 1147 |
+
{"kind":"CONSERVE","expr":"p1x + p2x"}, {"kind":"CONSERVE","expr":"p1y + p2y"},
|
|
|
|
| 1148 |
],
|
| 1149 |
scopes=[{"name":"phase","order":0,"vars":["p1x","p2x","p1y","p2y"],
|
| 1150 |
"constraints":[
|
|
|
|
| 1151 |
{"kind":"BRANCH","name":"phase_select","options":[
|
| 1152 |
+
"p1x**2 + p1y**2 - 0.25", "p1x**2 + p1y**2 - 1.0",
|
|
|
|
| 1153 |
]},
|
|
|
|
| 1154 |
{"kind":"EQ","expr":"p1x + p2x","weight":3.0},
|
| 1155 |
{"kind":"EQ","expr":"p1y + p2y","weight":3.0},
|
| 1156 |
]}],
|
| 1157 |
anchors=[
|
| 1158 |
AXLInvariant("momentum_x","p1x + p2x",1e-3),
|
| 1159 |
AXLInvariant("momentum_y","p1y + p2y",1e-3),
|
| 1160 |
+
AXLInvariant("phase_A_or_B","(p1x**2 + p1y**2 - 0.25)*(p1x**2 + p1y**2 - 1.0)",0.05),
|
|
|
|
|
|
|
| 1161 |
],
|
| 1162 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1163 |
AXLProblemDef(
|
| 1164 |
name="MetricPacking3D",
|
| 1165 |
description="3 vars packed with min separation, centred, norm=6",
|
| 1166 |
axioms={Axiom.CONTINUOUS,Axiom.METRIC,Axiom.INJECTIVE,Axiom.CONSERVED,Axiom.SYMMETRIC},
|
| 1167 |
variables=[
|
| 1168 |
+
{"name":"a","lo":-3.0,"hi":3.0}, {"name":"b","lo":-3.0,"hi":3.0}, {"name":"c","lo":-3.0,"hi":3.0},
|
|
|
|
|
|
|
| 1169 |
],
|
| 1170 |
constraints=[
|
| 1171 |
+
{"kind":"CONSERVE","expr":"a + b + c"},
|
| 1172 |
{"kind":"GEQ","expr":"(a - b)**2 - 1.0","weight":2.0},
|
| 1173 |
{"kind":"GEQ","expr":"(b - c)**2 - 1.0","weight":2.0},
|
| 1174 |
{"kind":"GEQ","expr":"(a - c)**2 - 4.0","weight":2.0},
|
|
|
|
| 1179 |
]}],
|
| 1180 |
anchors=[
|
| 1181 |
AXLInvariant("centred","a + b + c",1e-3),
|
| 1182 |
+
AXLInvariant("sep_ab","(a - b)**2 - 1.0",0.5),
|
| 1183 |
AXLInvariant("sep_bc","(b - c)**2 - 1.0",0.5),
|
| 1184 |
AXLInvariant("norm_6","a**2 + b**2 + c**2 - 6.0",0.05),
|
| 1185 |
],
|
|
|
|
| 1199 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1200 |
STATE_LOCK=threading.Lock()
|
| 1201 |
RUN_LOG:List[Dict]=[]
|
| 1202 |
+
THEORIST=AxiomRayTracer()
|
| 1203 |
POOL=ThreadPoolExecutor(max_workers=2)
|
| 1204 |
|
| 1205 |
def _run_problem(axl_def:AXLProblemDef):
|
|
|
|
| 1206 |
try:
|
| 1207 |
+
base_prob = build_base_problem(axl_def)
|
| 1208 |
+
binding, ce, rounds = THEORIST.trace(axl_def, base_prob)
|
| 1209 |
+
|
| 1210 |
+
survived = [t for t in THEORIST.all_traces if t.survived]
|
| 1211 |
+
failed = [t for t in THEORIST.all_traces if not t.survived]
|
| 1212 |
+
best_trace = min(survived, key=lambda t: t.ce_after, default=None)
|
| 1213 |
+
|
| 1214 |
record={
|
| 1215 |
+
"problem": axl_def.name,
|
| 1216 |
+
"description": axl_def.description,
|
| 1217 |
+
"ce": round(ce, 6),
|
| 1218 |
+
"solved": len(survived) > 0 and ce < SOLVE_THRESHOLD,
|
| 1219 |
+
"binding": {k: round(v, 5) for k, v in binding.items()},
|
| 1220 |
+
"observations": axl_def.observations,
|
| 1221 |
+
"traces": [{
|
| 1222 |
+
"round": t.round_idx, "ray": t.ray_name,
|
| 1223 |
+
"ce": round(t.ce_after, 5),
|
| 1224 |
+
"g1_ce": round(t.verify.gate1_ce, 5) if t.verify else None,
|
| 1225 |
+
"g1": t.verify.gate1_pass if t.verify else False,
|
| 1226 |
+
"g2": t.verify.gate2_pass if t.verify else False,
|
| 1227 |
+
"g2_detail": {k: (round(err, 6), ok) for k, (err, ok) in t.verify.gate2_results.items()} if t.verify else {},
|
| 1228 |
+
"survived": t.survived, "ms": t.elapsed_ms,
|
| 1229 |
+
} for t in THEORIST.all_traces],
|
| 1230 |
+
"survived_count": len(survived),
|
| 1231 |
+
"failed_count": len(failed),
|
| 1232 |
+
"best_ray": best_trace.ray_name if best_trace else "β",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1233 |
}
|
| 1234 |
with STATE_LOCK:
|
| 1235 |
RUN_LOG.append(record)
|
| 1236 |
+
if len(RUN_LOG) > 40: RUN_LOG.pop(0)
|
| 1237 |
except Exception as e:
|
| 1238 |
import traceback; traceback.print_exc()
|
| 1239 |
print(f"[RUN ERROR] {axl_def.name}: {e}")
|
|
|
|
| 1242 |
loop=asyncio.get_event_loop()
|
| 1243 |
while True:
|
| 1244 |
prob=random.choice(AXL_PROBLEMS)
|
| 1245 |
+
await loop.run_in_executor(POOL, _run_problem, prob)
|
| 1246 |
await asyncio.sleep(0.3)
|
| 1247 |
|
| 1248 |
@asynccontextmanager
|
|
|
|
| 1254 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1255 |
# SECTION 15: FASTAPI + DASHBOARD
|
| 1256 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1257 |
+
app=FastAPI(title="Practicality 12.0",lifespan=lifespan)
|
| 1258 |
|
| 1259 |
def _render_collapse(record:Dict) -> str:
|
| 1260 |
b=record["binding"]; traces=record["traces"]
|
|
|
|
| 1284 |
|
| 1285 |
def trail_span(t):
|
| 1286 |
c="#4CAF50" if t["survived"] else "#333"
|
| 1287 |
+
star=" β VERIFIED" if t["survived"] else ""
|
|
|
|
| 1288 |
return (f"<div style='color:{c};font-size:0.78em;margin-bottom:3px'>"
|
| 1289 |
+
f"[R{t['round']}] <span style='color:#FF9800'>{t['ray']}</span>"
|
| 1290 |
+
f" CE={t['ce']:.5f} | "
|
| 1291 |
+
f"G1={'β' if t['g1'] else 'β'}{t.get('g1_ce',0):.4f} "
|
| 1292 |
+
f"G2={'β' if t['g2'] else 'β'} "
|
|
|
|
| 1293 |
f"<span style='color:#4CAF50;font-weight:700'>{star}</span></div>")
|
| 1294 |
|
| 1295 |
trail="".join(trail_span(t) for t in traces)
|
|
|
|
| 1300 |
<span style='color:{ce_color};font-weight:700;font-size:1.05em'>{status}</span>
|
| 1301 |
<span style='color:#444;font-size:0.85em'>{record["problem"]}</span>
|
| 1302 |
<span style='color:#333;font-size:0.8em'>BaseCE={ce:.6f}</span>
|
|
|
|
| 1303 |
<span style='color:#26C6DA;font-size:0.75em'>{record["survived_count"]} survived / {record["failed_count"]} failed</span>
|
| 1304 |
</div>
|
| 1305 |
<div style='display:flex'>
|
|
|
|
| 1307 |
<div style='color:#333;font-size:0.7em;margin-bottom:5px'>BINDING</div>
|
| 1308 |
<table style='border-collapse:collapse;width:100%'>{binding_rows}</table>
|
| 1309 |
</div>
|
| 1310 |
+
<div style='flex:0 0 230px;padding:10px 12px;border-right:1px solid #1a1a1a'>
|
| 1311 |
<div style='color:#333;font-size:0.7em;margin-bottom:5px'>INVARIANTS (Gate 2)</div>
|
| 1312 |
<table style='border-collapse:collapse;width:100%'>
|
| 1313 |
{inv_rows or "<tr><td colspan='3' style='color:#222'>β</td></tr>"}
|
|
|
|
| 1315 |
</div>
|
| 1316 |
<div style='flex:1;padding:10px 12px'>
|
| 1317 |
<div style='color:#333;font-size:0.7em;margin-bottom:5px'>
|
| 1318 |
+
WAVEFRONT RAYS β best: <span style='color:#FF9800'>{record["best_ray"]}</span>
|
| 1319 |
</div>
|
| 1320 |
{trail}
|
| 1321 |
</div>
|
|
|
|
| 1328 |
runs=len(RUN_LOG); solved=sum(1 for r in RUN_LOG if r.get("solved",False))
|
| 1329 |
avg_ce=round(sum(r["ce"] for r in RUN_LOG)/max(1,runs),5) if RUN_LOG else 0
|
| 1330 |
|
| 1331 |
+
# Calculate efficacy by individual Axiom (very insightful)
|
| 1332 |
+
axiom_stats = defaultdict(lambda: {"tried": 0, "survived": 0, "total_ce": 0.0})
|
| 1333 |
+
for r in log:
|
| 1334 |
+
for t in r.get("traces", []):
|
| 1335 |
+
ray_str = t["ray"].strip("[]")
|
| 1336 |
+
axioms = ray_str.split("|")
|
| 1337 |
+
for ax in axioms:
|
| 1338 |
+
if not ax: continue
|
| 1339 |
+
axiom_stats[ax]["tried"] += 1
|
| 1340 |
+
axiom_stats[ax]["total_ce"] += t["ce"]
|
| 1341 |
+
if t["survived"]: axiom_stats[ax]["survived"] += 1
|
| 1342 |
+
|
| 1343 |
+
axiom_rows="".join(
|
| 1344 |
+
f"<tr><td style='color:#FF9800'>{ax}</td>"
|
| 1345 |
f"<td style='color:#aaa'>{s['tried']}</td>"
|
| 1346 |
f"<td style='color:#4CAF50'>{s['survived']}</td>"
|
| 1347 |
f"<td style='color:#EF5350'>{s['tried']-s['survived']}</td>"
|
| 1348 |
f"<td style='color:#26C6DA'>{round(s['total_ce']/s['tried'],5) if s['tried'] else 0}</td>"
|
|
|
|
| 1349 |
f"<td style='color:{'#4CAF50' if s['survived']>0 else '#333'}'>"
|
| 1350 |
f"{round(s['survived']/s['tried']*100):.0f}%</td></tr>"
|
| 1351 |
+
for ax,s in sorted(axiom_stats.items(),key=lambda x:-x[1]["survived"])
|
| 1352 |
+
) or "<tr><td colspan='6' style='color:#222'>Warming upβ¦</td></tr>"
|
| 1353 |
|
| 1354 |
collapses="".join(_render_collapse(r) for r in log) if log else \
|
| 1355 |
"<div style='color:#222;padding:20px'>Warming upβ¦</div>"
|
| 1356 |
|
| 1357 |
+
return f"""<!DOCTYPE html><html><head><title>Practicality 12.0</title>
|
| 1358 |
<meta http-equiv="refresh" content="4">
|
| 1359 |
<style>
|
| 1360 |
body{{background:#090909;color:#e0e0e0;font-family:monospace;padding:20px;max-width:1400px}}
|
|
|
|
| 1365 |
th{{color:#2a2a2a;font-size:0.72em}}
|
| 1366 |
.badge{{display:inline-block;padding:3px 10px;border-radius:3px;background:#0e0e0e;margin:2px;font-size:0.78em;border:1px solid #1a1a1a}}
|
| 1367 |
</style></head><body>
|
| 1368 |
+
<h1>β Practicality 12.0 β Axiomatic Ray Tracing</h1>
|
| 1369 |
<div style='color:#333;font-size:0.75em;margin-bottom:12px'>
|
| 1370 |
+
Boolean Hypercube β Wavefront Rays β Strict Solver Conf β Absolute Base Verify
|
| 1371 |
</div>
|
| 1372 |
<div style='margin-bottom:16px'>
|
| 1373 |
<span class='badge' style='color:#aaa'>Runs: {runs}</span>
|
| 1374 |
<span class='badge' style='color:#4CAF50'>Solved: {solved}</span>
|
| 1375 |
<span class='badge' style='color:#26C6DA'>Avg BaseCE: {avg_ce}</span>
|
| 1376 |
<span class='badge' style='color:#FF9800'>Problems: {len(AXL_PROBLEMS)}</span>
|
| 1377 |
+
<span class='badge' style='color:#5C6BC0'>Valid Universal Rays: {len(AXIOM_HYPERCUBE)}</span>
|
| 1378 |
</div>
|
| 1379 |
+
<h3>Axiom Efficacy Summary (Which properties describe reality best?)</h3>
|
| 1380 |
<table>
|
| 1381 |
+
<tr><th>Axiom</th><th>Tested</th><th>Survived</th><th>Failed</th><th>Avg BaseCE</th><th>Efficacy</th></tr>
|
| 1382 |
+
{axiom_rows}
|
| 1383 |
</table>
|
| 1384 |
<h3>Collapse View β Recent Runs</h3>
|
| 1385 |
{collapses}
|