everydaytok commited on
Commit
ec36b08
Β·
verified Β·
1 Parent(s): 9fe0637

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +248 -479
app.py CHANGED
@@ -1,19 +1,16 @@
1
  #!/usr/bin/env python3
2
  """
3
- PRACTICALITY SYSTEM 11.1 β€” AXL/PSL PIPELINE
4
  ═══════════════════════════════════════════════════════════════════
5
- FIXED IN 11.1:
6
- Β· PSLTranslator now grounds domain PSL in actual base constraints
7
- Domain adds SOFT structural hints (weight 0.15), never replaces base
8
- Β· Observations pin variables in domain PSL (zero-width VAR bounds)
9
- Β· DomainStrategy: wisdom layer informs HOW to search, not WHAT to search
10
- Each domain maps to hypothesis weights + polish preference + explore trigger
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, json
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, JSONResponse
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 11.1] Compute: {'GPU' if USE_GPU else 'CPU'}")
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: DOMAIN STRATEGY ← NEW
529
- # Wisdom layer informs HOW to search, not WHAT to search.
530
  # ══════════════════════════════════════════════════════════════════════
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
  @dataclass
532
  class DomainStrategy:
533
  name: str
534
- hyp_weights: Dict[str,float] # h_type β†’ confidence multiplier
535
  polish: str # "adam" | "gradient" | "both"
536
- explore_early: bool # True β†’ explore_trigger=2, False β†’ 4
537
- scope_priority: str # "ordered" | "hub" | "natural"
538
- note: str=""
539
-
540
- DOMAIN_STRATEGIES: Dict[str,DomainStrategy] = {
541
- "NormManifold": DomainStrategy("NormManifold",
542
- {"branch":1.3,"manifold":2.0,"chain":0.8,"residual_chain":1.1},
543
- "adam", False, "hub",
544
- "Quadratic manifolds β†’ manifold tangents most useful; Adam navigates smooth bowl"),
545
- "MetricPacking": DomainStrategy("MetricPacking",
546
- {"branch":1.2,"manifold":0.8,"chain":1.5,"residual_chain":1.2},
547
- "gradient", True, "hub",
548
- "Separation constraints β†’ algebraic branches + early exploration"),
549
- "SequentialChain": DomainStrategy("SequentialChain",
550
- {"branch":0.9,"manifold":0.5,"chain":2.0,"residual_chain":1.5},
551
- "gradient", False, "ordered",
552
- "Ordered chains β†’ topology chain hypotheses dominate"),
553
- "BilinearCoupling":DomainStrategy("BilinearCoupling",
554
- {"branch":1.3,"manifold":1.6,"chain":1.0,"residual_chain":1.0},
555
- "adam", False, "natural",
556
- "Bilinear products β†’ manifold + branch both useful; Adam for coupling"),
557
- "PhaseJump": DomainStrategy("PhaseJump",
558
- {"branch":2.0,"manifold":1.0,"chain":0.7,"residual_chain":0.9},
559
- "adam", True, "natural",
560
- "OR constraints β†’ branch hypotheses highest priority; explore early"),
561
- "GraphSpace": DomainStrategy("GraphSpace",
562
- {"branch":1.0,"manifold":0.7,"chain":1.3,"residual_chain":1.0},
563
- "gradient", False, "hub",
564
- "Network hubs β†’ chain + gradient works well"),
565
- "HierarchicalTree":DomainStrategy("HierarchicalTree",
566
- {"branch":0.9,"manifold":0.6,"chain":1.8,"residual_chain":1.2},
567
- "gradient", False, "ordered",
568
- "Hierarchical ordering β†’ chain hypotheses + ordered scope priority"),
569
- "DiscreteSchedule":DomainStrategy("DiscreteSchedule",
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 TYPES (before solve_by_hypothesis to avoid forward refs)
592
  # ══════════════════════════════════════════════════════════════════════
593
  @dataclass
594
  class Hypothesis:
@@ -598,10 +605,9 @@ class Hypothesis:
598
 
599
  @dataclass
600
  class HypothesisTrace:
601
- hid:str; round_idx:int; domain_name:str; action:str
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
- # Polish β€” strategy-directed
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
- hyps.extend(self._branch_hypotheses(problem,model,l9))
870
- hyps.extend(self._chain_hypotheses(problem,model,l7))
871
- hyps.extend(self._coherence_hypotheses(problem,model,l8))
872
- hyps.extend(self._residual_chain_hypotheses(problem,model,l9))
873
- if round_idx>=3: hyps.extend(self._manifold_tangent_hypotheses(problem,model,l9))
874
- # Apply strategy confidence weights
 
 
 
 
 
 
 
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: WISDOM LAYER
1012
- # The PSLTranslator is the core fix:
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 DebateRound:
1177
- round_idx:int; domain:AbstractDomain; psl_text:str
1178
- ce:float; solved:bool; action:str; strategy_name:str=""
1179
- traces:List[HypothesisTrace]=field(default_factory=list)
1180
-
1181
- class WisdomDebate:
1182
- MAX_ROUNDS=6
1183
- def __init__(self,library=None):
1184
- self.library=library or list(BASE_LIBRARY)
1185
- self.translator=PSLTranslator()
1186
- self.history:List[DebateRound]=[]
1187
- self.best_ce=float('inf'); self.best_binding={}; self.best_domain=None
1188
- self.all_traces:List[HypothesisTrace]=[]
1189
-
1190
- def _critic_score(self,problem_axioms,domain):
1191
- unmapped=problem_axioms-domain.axioms; false_asm=domain.axioms-problem_axioms
1192
- score=len(unmapped)*2.0+len(false_asm)*1.0
1193
- if not domain.is_consistent(): score+=10.0
1194
- return score,unmapped,false_asm
1195
-
1196
- def _candidates(self,current,round_idx):
1197
- cands=[(d,"Library") for d in self.library]
1198
- for d1,d2 in itertools.combinations(self.library[:5],2):
1199
- cands.append((WisdomOps.union(d1,d2),"Union"))
1200
- for d in self.library[:4]: cands.append((WisdomOps.dual(d),"Dual"))
1201
- if round_idx>2:
1202
- chosen=random.sample([Axiom.BILINEAR,Axiom.QUADRATIC,Axiom.CONSERVED,Axiom.METRIC,Axiom.ORDERED],2)
1203
- cands.append((WisdomOps.inject(current,set(chosen)),"RandInject"))
1204
- return cands
1205
-
1206
- def debate(self,axl_def:AXLProblemDef,base_problem:Problem) -> Tuple[Dict,float,List[DebateRound]]:
1207
- problem_axioms=axl_def.axioms
1208
- current=min(self.library,key=lambda d:self._critic_score(problem_axioms,d)[0])
1209
- self.history=[]; self.best_ce=float('inf'); self.best_binding={}; self.all_traces=[]
1210
-
1211
- print(f"\n{'═'*60}\nDEBATE: {axl_def.name} | Axioms: {problem_axioms}\n{'═'*60}")
1212
-
1213
- for round_idx in range(self.MAX_ROUNDS):
1214
- cands=self._candidates(current,round_idx)
1215
- scored=[(self._critic_score(problem_axioms,d)[0],d,act) for d,act in cands]
1216
- scored.sort(key=lambda x:x[0])
1217
- tried={r.domain.name for r in self.history}
1218
- score,winner,action=next((s for s in scored if s[1].name not in tried),scored[0])
1219
- strategy=get_strategy(winner.name)
1220
-
1221
- print(f"\n[R{round_idx+1}] {winner.name} | {action} | score={score:.1f} | strategy={strategy.name}")
1222
- print(f" hint: {strategy.note[:60]}")
1223
-
1224
- # ── KEY FIX: translate generates base + soft hints ─────────
1225
- psl_text=self.translator.compile(winner,axl_def)
1226
- round_traces=[]
1227
-
1228
- try:
1229
- prog=parse_psl(psl_text); ep=expand_psl(prog)
1230
- if not ep.variables:
1231
- print(" βœ— No variables"); current=winner; continue
1232
-
1233
- dom_prob=Problem(pid=f"dom_{winner.name}",variables=ep.variables,
1234
- constraints=ep.constraints,bounds=ep.bounds,
1235
- scope_groups=ep.scope_groups,scope_vars=ep.scope_vars,
1236
- scope_order=ep.scope_order)
1237
- t_start=time.time()
1238
- # ── KEY FIX: solver receives domain strategy ───────────
1239
- result=solve_by_hypothesis(dom_prob,budget=TOTAL_BUDGET,strategy=strategy)
1240
- elapsed=round((time.time()-t_start)*1000,1)
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 (all verified feasible)
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":"x2","lo":-1.0,"hi":1.0},
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 - t2","weight":1.0},
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":"p2x","lo":-2.0,"hi":2.0},
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"}, # total momentum x = 0
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", # phase A: r=0.5
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
- # Phase satisfied: product of both phase residuals near 0
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"}, # centred at 0
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), # β‰₯ 1 (tolerance on residual)
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
- DEBATE_ENGINE=WisdomDebate()
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=DEBATE_ENGINE.debate(axl_def,base_prob)
1437
- elapsed=round(time.time()-t0,2)
1438
- survived=[t for t in DEBATE_ENGINE.all_traces if t.survived]
1439
- failed=[t for t in DEBATE_ENGINE.all_traces if not t.survived]
1440
- best_trace=min((t for t in survived),key=lambda t:t.ce_after,default=None)
1441
- actual_base_ce=base_prob.constraint_energy(binding)
1442
  record={
1443
- "problem":axl_def.name,
1444
- "description":axl_def.description,
1445
- "axioms":sorted(axl_def.axioms),
1446
- "ce":round(actual_base_ce,6),
1447
- "solved":len(survived)>0 and actual_base_ce<SOLVE_THRESHOLD,
1448
- "elapsed":elapsed,
1449
- "binding":{k:round(v,5) for k,v in binding.items()},
1450
- "observations":axl_def.observations,
1451
- "traces":[{
1452
- "hid":t.hid,"round":t.round_idx,"domain":t.domain_name,
1453
- "action":t.action,"strategy":t.strategy_note,
1454
- "ce":round(t.ce_after,5),
1455
- "g1_ce":round(t.verify.gate1_ce,5) if t.verify else None,
1456
- "g1":t.verify.gate1_pass if t.verify else False,
1457
- "g2":t.verify.gate2_pass if t.verify else False,
1458
- "g2_detail":{k:(round(err,6),ok)
1459
- for k,(err,ok) in t.verify.gate2_results.items()} if t.verify else {},
1460
- "survived":t.survived,"ms":t.elapsed_ms,
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 11.1",lifespan=lifespan)
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=" β—€ SURVIVED" if t["survived"] else ""
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['domain'][:14]}</span>"
1523
- f" CE={t['ce']:.5f}"
1524
- f" G1={'βœ“' if t['g1'] else 'βœ—'}{t.get('g1_ce',0):.4f}"
1525
- f" G2={'βœ“' if t['g2'] else 'βœ—'}"
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 200px;padding:10px 12px;border-right:1px solid #1a1a1a'>
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
- HYPOTHESIS TRAIL β€” best domain: <span style='color:#FF9800'>{record["best_domain"]}</span>
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
- all_traces=[t for r in log for t in r.get("traces",[])]
1567
- ds=defaultdict(lambda:{"tried":0,"survived":0,"total_ce":0.0,"strategy":""})
1568
- for t in all_traces:
1569
- ds[t["domain"]]["tried"]+=1
1570
- ds[t["domain"]]["total_ce"]+=t["ce"]
1571
- ds[t["domain"]]["strategy"]=t.get("strategy","")
1572
- if t["survived"]: ds[t["domain"]]["survived"]+=1
1573
- domain_rows="".join(
1574
- f"<tr><td style='color:#FF9800'>{d}</td>"
 
 
 
 
 
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 d,s in sorted(ds.items(),key=lambda x:-x[1]["survived"])
1583
- ) or "<tr><td colspan='7' style='color:#222'>Warming up…</td></tr>"
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 11.1</title>
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 11.1 β€” AXL/PSL Pipeline (fixed)</h1>
1600
  <div style='color:#333;font-size:0.75em;margin-bottom:12px'>
1601
- AXL β†’ PSL (base + soft domain hints) β†’ Solver [strategy-directed] β†’ Gate1 β†’ Gate2 β†’ Collapse
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'>Library: {len(DEBATE_ENGINE.library)}</span>
1609
  </div>
1610
- <h3>Domain Survival + Strategy</h3>
1611
  <table>
1612
- <tr><th>Domain</th><th>Tried</th><th>Survived</th><th>Failed</th><th>Avg BaseCE</th><th>Polish</th><th>Rate</th></tr>
1613
- {domain_rows}
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}