everydaytok commited on
Commit
dce11bf
Β·
verified Β·
1 Parent(s): 2203336

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +688 -273
app.py CHANGED
@@ -1,4 +1,4 @@
1
-
2
  """
3
  PRACTICALITY SYSTEM 24.1 β€” STRUCTURAL SKETCH, QUANTUM ENGINE & HOMOTOPY CONTINUATION
4
  ══════════════════════════════════════════════════════════════════════════════════
@@ -9,11 +9,10 @@ ARCHITECTURE:
9
  β†’ [WISDOM LAYER] β†’ Sketch-weighted rays + Masked Deduction (with Homotopy)
10
  β†’ [GEMINI COLLAPSER] β†’ Domain-language explanation
11
 
12
- UPDATES:
13
- 1. Homotopy Continuation (Morphing Ray): PyTorch gradients now dynamically soften
14
- transcendental constraints and expand bounds early in the search, allowing Adam
15
- to map the linear skeleton before sinking into non-convex traps.
16
- 2. Quantum Anchor Fix: Correctly verifies correlators to prevent infinite 0.0 CE loops.
17
  """
18
 
19
  import os, time, random, math, threading, warnings, json, textwrap
@@ -43,13 +42,13 @@ except ImportError:
43
  # ══════════════════════════════════════════════════════════════════════
44
  # AI CONFIGURATION
45
  # ══════════════════════════════════════════════════════════════════════
46
- DEFAULT_GEMINI_API_KEY = os.environ.get("AI_Key", "")
47
- GEMINI_MODEL = "gemini-3-flash-preview" # "gemma-4-26b-a4b-it" #
48
 
49
  warnings.filterwarnings("ignore")
50
  USE_GPU = torch.cuda.is_available()
51
  DEVICE = torch.device("cuda" if USE_GPU else "cpu")
52
- print(f"[SYSTEM 24.1] Compute: {DEVICE.type.upper()} | Homotopy Continuation Active")
53
 
54
  # ══════════════════════════════════════════════════════════════════════
55
  # SECTION 1: CONSTANTS
@@ -80,18 +79,28 @@ SYMPY_TIMEOUT_SECS = 4.0
80
  STATE_LOCK = threading.Lock()
81
 
82
  GLOBAL_SOLVE_STATE = {
83
- "is_running": False, "phase": "IDLE", "best_ce": float('inf'), "total_fired": 0,
84
- "best_ray": "β€”", "recent_traces": deque(maxlen=25), "high_level_logs": [],
85
- "answer": "", "sketch_summary": "", "template_count": 0,
86
- "template_best_ce": float('inf'), "sympy_derivation": [],
 
 
 
 
 
 
 
 
87
  }
88
 
89
  def _update_state(**kwargs):
90
  with STATE_LOCK:
91
- for k, v in kwargs.items(): GLOBAL_SOLVE_STATE[k] = v
 
92
 
93
  def _add_log(line: str):
94
- with STATE_LOCK: GLOBAL_SOLVE_STATE["high_level_logs"].append(line)
 
95
 
96
  # ══════════════════════════════════════════════════════════════════════
97
  # SECTION 3: INTERVAL ARITHMETIC (HC4)
@@ -307,7 +316,8 @@ AXL_COMPILER=AXLtoPSLCompiler()
307
  # ══════════════════════════════════════════════════════════════════════
308
  @dataclass
309
  class Constraint:
310
- kind:str; expr:str; direction:str; weight:float=1.0; scope:str="root"; branches:List[str]=field(default_factory=list)
 
311
 
312
  @dataclass
313
  class MathConstraint:
@@ -489,59 +499,80 @@ def build_base_problem(axl_def:AXLProblemDef) -> Problem:
489
  # ══════════════════════════════════════════════════════════════════════
490
  @dataclass
491
  class StructuralSketch:
492
- axiom_affinities: Dict[str, float]; solvable_by_sympy: bool
493
- exact_solutions: List[Dict[str, float]]; sympy_derivation: List[str]
494
- n_free_dof: int; has_conservation: bool
495
- has_bilinear: bool; has_ordering: bool
496
- has_transcendental: bool; dominant_type: str; sketch_notes: List[str]
 
 
 
 
 
 
497
 
498
  @dataclass
499
  class HypothesisTemplate:
500
- template_id: str; pinned_vars: Dict[str,float]; free_vars: List[str]
501
- source: str; confidence: float; derivation: str
 
 
 
 
502
 
503
  def _try_sympy_solve(problem: Problem) -> Tuple[List[Dict[str, float]], bool, List[str]]:
504
  has_transcendental = any(
505
  mc.parsed is not None and (mc.parsed.has(sp.sin) or mc.parsed.has(sp.cos) or mc.parsed.has(sp.exp) or mc.parsed.has(sp.log))
506
  for mc in problem.compiled_constraints)
507
  if has_transcendental: return [], False, []
 
508
  eq_mcs = [mc for mc in problem.compiled_constraints if mc.kind == "equality" and mc.parsed is not None and mc.syms_used]
509
  if len(eq_mcs) < len(problem.variables): return [], False, []
 
510
  syms = [sp.Symbol(v) for v in problem.variables]
511
  equations = [mc.parsed for mc in eq_mcs]
512
 
513
- def _solve(): return sp.solve(equations, syms, dict=True)
 
514
 
515
  try:
516
  with concurrent.futures.ThreadPoolExecutor(max_workers=1) as ex:
517
  future = ex.submit(_solve)
518
  raw = future.result(timeout=SYMPY_TIMEOUT_SECS)
519
  except Exception: return [], False, []
 
520
  if not raw: return [], False, []
521
 
522
  derivation = ["SYSTEM HANDED TO SYMPY:"]
523
  for mc in eq_mcs: derivation.append(f" {mc.expr_str} = 0")
 
524
  for sol_idx, sol in enumerate(raw[:2]):
525
  derivation.append(f"\nSYMBOLIC SOLUTION #{sol_idx + 1}:")
526
  sorted_sol = sorted(sol.items(), key=lambda kv: len(kv[1].free_symbols))
527
  for sym, val in sorted_sol:
528
  simplified = sp.simplify(val); free_s = sorted(simplified.free_symbols, key=str)
529
  if not free_s:
530
- try: num = float(simplified.evalf()); derivation.append(f" {sym} = {simplified} = {num:.8g} [constant root]")
531
- except: derivation.append(f" {sym} = {simplified} [symbolic constant]")
532
- else: derivation.append(f" {sym} = {simplified} [eliminates {sym}, depends on {', '.join(str(s) for s in free_s)}]")
 
 
 
 
 
533
  if len(sorted_sol) == 1:
534
  sym, val = sorted_sol[0]
535
  try:
536
  poly = sp.Poly(equations[0], sp.Symbol(str(sym)))
537
- b_str = f"[{problem.bounds.get(str(sym), ('?','?'))[0]:.4g}, {problem.bounds.get(str(sym), ('?','?'))[1]:.4g}]"
538
- derivation.append(f" Univariate polynomial: degree {poly.degree()}, roots selected by bound check {b_str}")
539
  except: pass
540
 
541
  valid = []
542
  b_mid = {v: (problem.bounds[v][0] + problem.bounds[v][1]) / 2 for v in problem.variables}
543
  for sol in raw:
544
- binding = dict(b_mid); ok = True
 
545
  for sym, val in sol.items():
546
  try:
547
  num = float(val.evalf()); vn = str(sym)
@@ -553,18 +584,23 @@ def _try_sympy_solve(problem: Problem) -> Tuple[List[Dict[str, float]], bool, Li
553
  if ok:
554
  ce = problem.scalar_energy(binding)
555
  if ce < 1.0: valid.append((binding, ce))
 
556
  valid.sort(key=lambda x: x[1])
557
  if valid: derivation.append(f"\nBOUND-FILTERED: {len(valid)} of {len(raw)} symbolic solutions fall within domains.")
558
  else: derivation.append(f"\nBOUND CHECK: all {len(raw)} symbolic solutions lie outside variable domains.")
 
559
  return [v[0] for v in valid], len(valid) > 0, derivation
560
 
561
  def compute_sketch(problem: Problem) -> StructuralSketch:
562
- affinities = {a: 1.0 for a in _ALL_AXIOMS_PLACEHOLDER}; notes = []
563
- n_vars = len(problem.variables); n_eq = sum(1 for mc in problem.compiled_constraints if mc.kind == "equality")
 
 
564
 
565
  has_conservation = any(mc.weight >= 5.0 for mc in problem.compiled_constraints if mc.kind == "equality")
566
  if has_conservation:
567
- affinities["CONSERVED"] += 3.0; affinities["COMPOSITE"] += 1.5
 
568
  notes.append("Conservation laws β†’ CONSERVED/COMPOSITE boosted")
569
 
570
  if problem.bilinear_pairs:
@@ -572,38 +608,55 @@ def compute_sketch(problem: Problem) -> StructuralSketch:
572
  notes.append(f"{len(problem.bilinear_pairs)} bilinear pairs β†’ BILINEAR boosted")
573
 
574
  if problem.monotone_targets:
575
- affinities["MONOTONE_PRODUCT"] += 5.0; affinities["ORDERED"] += 2.5
 
576
  notes.append(f"{len(problem.monotone_targets)} monotone targets β†’ MPR strongly boosted")
577
 
578
  if problem.ordering_pairs:
579
- affinities["ORDERED"] += 2.0; affinities["DISCRETE"] += 1.0
 
580
  notes.append(f"{len(problem.ordering_pairs)} ordering constraints β†’ ORDERED boosted")
581
 
582
  if any(problem.scope_vars.values()):
583
- affinities["DISCRETE"] += 2.0; affinities["LOCALITY"] += 1.0
 
584
  notes.append("Scope structure detected β†’ DISCRETE boosted")
585
 
586
  n_proj = sum(1 for mc in problem.compiled_constraints if mc.projections)
587
  if n_proj > 0:
588
- affinities["ATOMIC"] += 2.0 + n_proj * 0.3; affinities["IMPLICATION"] += 1.5; affinities["TRANSITIVE"] += 1.5
 
 
589
  notes.append(f"{n_proj} projectable constraints β†’ ATOMIC/IMPLICATION boosted")
590
 
591
  has_sos = any(mc.parsed is not None and mc.parsed.is_Add and any(t.is_Pow and t.args[1] == 2 for t in mc.parsed.args) for mc in problem.compiled_constraints if mc.kind == "equality")
592
  if has_sos:
593
- affinities["METRIC"] += 2.5; affinities["QUADRATIC"] += 2.0; affinities["CONTINUOUS"] += 1.5
 
 
594
  notes.append("Sum-of-squares β†’ METRIC/QUADRATIC/CONTINUOUS boosted")
595
 
596
  tight = sum(1 for v in problem.variables if abs(problem.bounds[v][1] - problem.bounds[v][0]) < 10)
597
- if tight > n_vars // 2: affinities["PARSIMONY"] += 2.0; notes.append("Tight bounds β†’ PARSIMONY boosted")
 
 
598
 
599
- if n_vars >= 6: affinities["HOLISM"] += 1.5; affinities["NETWORK"] += 1.5; notes.append(f"High-D ({n_vars} vars) β†’ HOLISM/NETWORK boosted")
 
 
 
600
 
601
  bound_groups = defaultdict(list)
602
  for v in problem.variables: bound_groups[problem.bounds[v]].append(v)
603
- if any(len(g) >= 2 for g in bound_groups.values()): affinities["SYMMETRIC"] += 1.5; notes.append("Symmetric bounds β†’ SYMMETRIC boosted")
 
 
604
 
605
  has_transcendental = any(mc.parsed is not None and (mc.parsed.has(sp.sin) or mc.parsed.has(sp.cos) or mc.parsed.has(sp.exp)) for mc in problem.compiled_constraints)
606
- if has_transcendental: affinities["CONTINUOUS"] += 2.0; affinities["EQUILIBRIUM"] += 1.5; notes.append("Transcendental constraints β†’ CONTINUOUS/EQUILIBRIUM boosted")
 
 
 
607
 
608
  max_deg = 1
609
  for mc in problem.compiled_constraints:
@@ -622,19 +675,32 @@ def compute_sketch(problem: Problem) -> StructuralSketch:
622
  n_obs = sum(1 for v in problem.variables if problem.bounds[v][0] == problem.bounds[v][1])
623
  n_free_dof = max(0, n_vars - n_obs - n_eq)
624
 
625
- exact_solutions = []; solvable = False; sympy_derivation = []
 
 
626
  if n_vars <= SYMPY_MAX_VARS and dom_type in ("linear", "quadratic") and not has_transcendental:
627
  exact_solutions, solvable, sympy_derivation = _try_sympy_solve(problem)
628
- if solvable: notes.append(f"βœ“ SymPy found {len(exact_solutions)} exact solution(s) via {len(sympy_derivation)} steps")
629
- else: notes.append("SymPy attempted (no closed form) β€” proceeding to ray search")
630
-
631
- return StructuralSketch(axiom_affinities=affinities, solvable_by_sympy=solvable, exact_solutions=exact_solutions, sympy_derivation=sympy_derivation, n_free_dof=n_free_dof, has_conservation=has_conservation, has_bilinear=bool(problem.bilinear_pairs), has_ordering=bool(problem.ordering_pairs), has_transcendental=has_transcendental, dominant_type=dom_type, sketch_notes=notes)
 
 
 
 
 
 
 
632
 
633
  def generate_templates(problem: Problem, sketch: StructuralSketch) -> List[HypothesisTemplate]:
634
- templates = []; b_mid = {v: (problem.bounds[v][0] + problem.bounds[v][1]) / 2 for v in problem.variables}
 
635
 
636
  for i, sol in enumerate(sketch.exact_solutions):
637
- templates.append(HypothesisTemplate(template_id=f"sympy_{i}", pinned_vars=sol, free_vars=[v for v in problem.variables if v not in sol], source="sympy_exact", confidence=0.99, derivation=f"SymPy exact solution #{i+1}"))
 
 
 
638
 
639
  for mc in problem.compiled_constraints:
640
  if mc.kind != "equality" or mc.weight < 5.0 or not mc.projections: continue
@@ -644,27 +710,40 @@ def generate_templates(problem: Problem, sketch: StructuralSketch) -> List[Hypot
644
  try:
645
  val = float(proj["func"](*[b_mid.get(s, 0.0) for s in proj["syms"]]))
646
  if math.isfinite(val) and lo <= val <= hi:
647
- templates.append(HypothesisTemplate(template_id=f"cons_{v}_{hash(mc.expr_str)%9999}", pinned_vars={v: val}, free_vars=[u for u in problem.variables if u != v], source="conservation", confidence=0.75, derivation=f"Conservation {mc.expr_str} β†’ {v}={val:.4f}"))
 
 
 
648
  except: pass
649
 
650
  tb = _global_hc4_tighten_bounds(problem)
651
  for v_small, v_large, k in problem.monotone_targets:
652
- lo_s, hi_s = problem.bounds.get(v_small, (-1e9, 1e9)); lo_l, hi_l = problem.bounds.get(v_large, (-1e9, 1e9))
 
653
  for ratio in [0.1, 0.25, 0.5, 0.707, 0.9]:
654
  vs_sq = k * ratio
655
  if vs_sq <= 0: continue
656
  vs = math.sqrt(vs_sq); vl = k / vs
657
  if not (lo_s <= vs <= hi_s and lo_l <= vl <= hi_l and vs <= vl): continue
658
- nb = dict(b_mid); nb[v_small] = vs; nb[v_large] = vl
 
 
 
659
  box = {u: IV(*tb.get(u, problem.bounds.get(u, (-10, 10)))) for u in problem.variables}
660
- box[v_small] = IV(vs - 1e-6, vs + 1e-6); box[v_large] = IV(vl - 1e-6, vl + 1e-6)
 
661
  cont = _hc4(box, problem.compiled_constraints)
 
662
  pinned = {v_small: vs, v_large: vl}
663
  if cont:
664
  for u, iv in cont.items():
665
  if u in problem.bounds: nb[u] = iv.mid()
666
  pinned = {u: nb[u] for u in problem.variables if cont[u].width() < 1e-2}
667
- templates.append(HypothesisTemplate(template_id=f"mpr_{v_small}_{v_large}_r{int(ratio*100)}", pinned_vars=pinned, free_vars=[u for u in problem.variables if u not in pinned], source="monotone_prod", confidence=0.88, derivation=f"Monotone {v_small}={vs:.4f}≀{v_large}={vl:.4f}"))
 
 
 
 
668
 
669
  for mc in problem.compiled_constraints:
670
  if mc.kind != "equality" or not mc.projections: continue
@@ -674,29 +753,42 @@ def generate_templates(problem: Problem, sketch: StructuralSketch) -> List[Hypot
674
  try:
675
  val = float(proj["func"](*[b_mid.get(s, 0.0) for s in proj["syms"]]))
676
  if math.isfinite(val) and lo <= val <= hi:
677
- templates.append(HypothesisTemplate(template_id=f"proj_{v}_{hash(mc.expr_str)%9999}", pinned_vars={v: val}, free_vars=[u for u in problem.variables if u != v], source="projection", confidence=0.72, derivation=f"Root of {mc.expr_str[:30]} β†’ {v}={val:.4f}"))
 
 
 
678
  except: pass
679
 
680
  bound_groups = defaultdict(list)
681
  for v in problem.variables: bound_groups[problem.bounds[v]].append(v)
682
  for bnd, grp in bound_groups.items():
683
  if len(grp) < 2: continue
684
- avg = sum(b_mid[v] for v in grp) / len(grp); lo, hi = bnd
 
685
  if lo <= avg <= hi:
686
  pinned = {v: avg for v in grp}
687
- templates.append(HypothesisTemplate(template_id=f"sym_avg_{'_'.join(grp[:3])}", pinned_vars=pinned, free_vars=[u for u in problem.variables if u not in pinned], source="symmetry", confidence=0.55, derivation=f"Symmetry orbit: {grp} averaged to {avg:.4f}"))
 
 
 
688
 
689
  seen = set(); unique = []
690
  for t in sorted(templates, key=lambda t: -t.confidence):
691
  key = str(sorted(t.pinned_vars.items()))
692
- if key not in seen: seen.add(key); unique.append(t)
 
 
 
693
  return unique[:TEMPLATE_BATCH_SIZE]
694
 
695
  def templates_to_hypotheses(templates, problem, init_binding):
696
  hyps = []
697
  for t in templates:
698
- binding = dict(init_binding); binding.update(t.pinned_vars)
699
- hyps.append(Hypothesis(hid=t.template_id, binding=binding, h_type=t.source, claim=t.derivation, derivation=[t.source], pinned_vars=t.pinned_vars, free_vars=t.free_vars, confidence=t.confidence))
 
 
 
700
  return hyps
701
 
702
  _ALL_AXIOMS_PLACEHOLDER: List[str] = []
@@ -706,18 +798,36 @@ _ALL_AXIOMS_PLACEHOLDER: List[str] = []
706
  # ══════════════════════════════════════════════════════════════════════
707
  @dataclass
708
  class L9Certificate:
709
- residual_ce: float; dominant_vars: List[str]; dominant_exprs: List[str]; tension_class: str = "unknown"
 
 
 
710
 
711
  def _batched_deduce_and_evaluate(problem: Problem, hyps: List['Hypothesis']) -> List[Tuple[Dict, float, List[str], str]]:
712
  if not hyps: return []
713
- B = len(hyps); V = len(problem.variables)
714
- x_data = []; mask_data = []; target_data = []
 
 
 
 
 
715
  for hyp in hyps:
716
  xr, mr, tr = [], [], []
717
  for v in problem.variables:
718
- if v in hyp.pinned_vars: val = hyp.pinned_vars[v]; xr.append(val); mr.append(0.0); tr.append(val)
719
- else: val = hyp.binding.get(v, (problem.bounds[v][0] + problem.bounds[v][1]) / 2); xr.append(val); mr.append(1.0); tr.append(0.0)
720
- x_data.append(xr); mask_data.append(mr); target_data.append(tr)
 
 
 
 
 
 
 
 
 
 
721
 
722
  X = torch.tensor(x_data, device=DEVICE, dtype=torch.float32, requires_grad=True)
723
  mask = torch.tensor(mask_data, device=DEVICE, dtype=torch.float32)
@@ -731,14 +841,18 @@ def _batched_deduce_and_evaluate(problem: Problem, hyps: List['Hypothesis']) ->
731
  step_ratio = min(1.0, step / (DEDUCE_ADAM_STEPS * 0.8))
732
  ce = problem.tensor_energy(X, step_ratio)
733
 
734
- if isinstance(ce, torch.Tensor) and (ce < SOLVE_THRESHOLD).all() and step_ratio == 1.0: break
735
- loss = ce.sum(); loss.backward()
 
 
 
736
 
737
  with torch.no_grad():
738
  X.grad.clamp_(-10.0, 10.0)
739
  X.grad *= mask
740
  optimizer.step()
741
  X.data = torch.where(mask == 0.0, target, X.data)
 
742
  for j, v in enumerate(problem.variables):
743
  lo, hi = problem.bounds[v]
744
  margin = (hi - lo) * 0.1 * (1.0 - step_ratio) # Exploratory bounds fade to 0
@@ -750,26 +864,39 @@ def _batched_deduce_and_evaluate(problem: Problem, hyps: List['Hypothesis']) ->
750
 
751
  ce_vals = final_ce.detach().cpu().numpy()
752
  X_vals = X.detach().cpu().numpy()
753
- grads_abs = X.grad.abs(); _, topk_idx = torch.topk(grads_abs, k=min(3, V), dim=1)
754
- topk_idx_np = topk_idx.cpu().numpy(); grads_np = grads_abs.cpu().numpy()
 
 
 
755
 
756
  results = []
757
  for i in range(B):
758
  final_b = {problem.variables[j]: float(X_vals[i, j]) for j in range(V)}
759
  dom_vars = [problem.variables[idx] for idx in topk_idx_np[i] if float(grads_np[i, idx]) > 1e-4]
760
- n_dom = len(dom_vars); tension_class = ("isolated" if n_dom <= 1 else "relational" if n_dom == 2 else "systemic")
 
761
  results.append((final_b, float(ce_vals[i]), dom_vars, tension_class))
 
762
  return results
763
 
764
  def _mprt_sample(problem, work_box, N):
765
- var_list = problem.variables; V = len(var_list)
 
 
766
  lo_t = torch.tensor([max(problem.bounds.get(v, (-10.0, 10.0))[0], work_box[v].lo if v in work_box else problem.bounds.get(v, (-10, 10))[0]) for v in var_list], device=DEVICE, dtype=torch.float32)
767
  hi_t = torch.tensor([min(problem.bounds.get(v, (-10.0, 10.0))[1], work_box[v].hi if v in work_box else problem.bounds.get(v, (-10, 10))[1]) for v in var_list], device=DEVICE, dtype=torch.float32)
 
768
  for i in range(V):
769
- if lo_t[i] >= hi_t[i]: m = (lo_t[i] + hi_t[i]) / 2; lo_t[i] = m - 1e-6; hi_t[i] = m + 1e-6
 
 
 
 
770
  X = lo_t.unsqueeze(0) + (hi_t - lo_t).unsqueeze(0) * torch.rand((N, V), device=DEVICE)
771
  ce_batch = problem.tensor_energy(X, 1.0)
772
  best_idx = torch.argmin(ce_batch).item()
 
773
  return {v: float(X[best_idx, i].item()) for i, v in enumerate(var_list)}, ce_batch[best_idx].item()
774
 
775
  # ══════════════════════════════════════════════════════════════════════
@@ -788,7 +915,8 @@ class Axiom:
788
  COMPOSITE="COMPOSITE"; HOLISM="HOLISM"; PARSIMONY="PARSIMONY"; DUALITY="DUALITY"
789
 
790
  ALL_AXIOMS = [getattr(Axiom, a) for a in dir(Axiom) if not a.startswith("__")]
791
- AXIOM_ABBR = {a: a[:3] for a in ALL_AXIOMS}; AXIOM_ABBR[Axiom.MONOTONE_PRODUCT] = "MPR"
 
792
  _ALL_AXIOMS_PLACEHOLDER.extend(ALL_AXIOMS)
793
 
794
  ADJACENT_CONTRADICTIONS = [
@@ -813,41 +941,72 @@ RAY_TYPES = ["seed", "branch", "tension", "scout", "recombine", "invert", "targe
813
 
814
  @dataclass
815
  class Hypothesis:
816
- hid: str; binding: Dict[str, float]; h_type: str; claim: str
817
- derivation: List[str]; pinned_vars: Dict[str, float]; free_vars: List[str]
818
- confidence: float; ce: float = float('inf')
 
 
 
 
 
 
819
 
820
  @dataclass
821
  class Baton:
822
- binding: Dict[str, float]; ce: float
823
- ray_id: str = ""; depth: int = 0; l9: Optional[L9Certificate] = None
 
 
 
824
 
825
  @dataclass
826
  class AxiomRay:
827
- sequence: List[str]; ray_id: str; ray_type: str = "seed"
828
- depth: int = 0; parent_id: Optional[str] = None
829
- baton: Optional[Baton] = None; ce_prior: float = float('inf')
 
 
 
 
 
830
  @property
831
- def name(self) -> str: return "β†’".join(AXIOM_ABBR.get(a, a[:3]) for a in self.sequence)
 
 
832
  def extend(self, axiom: str, rtype: str, new_prior: float = float('inf')) -> Optional['AxiomRay']:
833
  new_seq = self.sequence + [axiom]
834
  if sequence_valid(new_seq):
835
- return AxiomRay(sequence=new_seq, ray_id=f"{self.ray_id}+{AXIOM_ABBR.get(axiom, '?')}",
836
- ray_type=rtype, depth=self.depth + 1, parent_id=self.ray_id, ce_prior=new_prior)
 
 
 
 
 
 
837
  return None
838
 
839
  @dataclass
840
  class HypothesisTrace:
841
- hid: str; round_idx: int; ray_name: str; ray_type: str
842
- ce_before: float; ce_after: float; survived: bool; elapsed_ms: float
843
- g1_pass: bool = False; g2_pass: bool = False
 
 
 
 
 
 
 
844
  binding: Dict[str, float] = field(default_factory=dict)
845
  invariant_results: Dict[str, Tuple[float, bool]] = field(default_factory=dict)
846
- tension_class: str = "unknown"; depth: int = 0
 
847
 
848
  @dataclass
849
  class StructuralModel:
850
- best_binding: Dict[str, float]; best_ce: float
 
851
  best_ray: str = "β€”"
852
  failure_patterns: Set[str] = field(default_factory=set)
853
  resonant_pairs: List[Tuple[str, str]] = field(default_factory=list)
@@ -859,11 +1018,15 @@ def _make_hyp(hid, binding, h_type, claim, derivation, pinned, free, conf):
859
  return Hypothesis(hid=hid, binding=binding, h_type=h_type, claim=claim,
860
  derivation=derivation, pinned_vars=pinned, free_vars=free, confidence=conf)
861
 
862
- def _hyp_continuous(p, bt, a, m): return [_make_hyp("cnt", bt.binding, "continuous", "Manifold", [], {}, p.variables, 0.45)]
 
 
863
  def _hyp_discrete(p, bt, a, m):
864
- b = dict(bt.binding); pinned = {}
 
865
  for sn in p.scope_order:
866
- svars = p.scope_vars.get(sn, []); smcs = [p.compiled_constraints[i] for i in p.scope_groups.get(sn, [])]
 
867
  if svars and smcs:
868
  box = {v: IV(b.get(v, 0) - max(0.05 * (p.bounds[v][1] - p.bounds[v][0]), 1e-4),
869
  b.get(v, 0) + max(0.05 * (p.bounds[v][1] - p.bounds[v][0]), 1e-4)) for v in svars if v in p.bounds}
@@ -871,82 +1034,114 @@ def _hyp_discrete(p, bt, a, m):
871
  if cont:
872
  for v, iv in cont.items():
873
  b[v] = iv.mid()
874
- if iv.width() < 1e-2: pinned[v] = b[v]
 
875
  return [_make_hyp("dis", b, "discrete", "TopoScope", [], pinned, p.variables, 0.80)]
876
 
877
  def _hyp_quadratic(p, bt, a, m):
878
- hyps = []; b = dict(bt.binding)
 
879
  if bt.l9 and bt.l9.dominant_vars:
880
- for v in bt.l9.dominant_vars[:2]: hyps.append(_make_hyp(f"qua_{v}", b, "quadratic", f"Root({v})", [], {v: b[v]}, p.variables, 0.70))
 
881
  return hyps
882
 
883
  def _hyp_bilinear(p, bt, a, m):
884
- hyps = []; b = dict(bt.binding)
 
885
  for vi, vj in p.bilinear_pairs:
886
- lo_i, hi_i = p.bounds.get(vi, (0, 10)); lo_j, hi_j = p.bounds.get(vj, (0, 10))
 
887
  product = abs(b.get(vi, 1) * b.get(vj, 1))
 
888
  if product <= 0: continue
889
  gm = math.sqrt(product)
 
890
  if lo_i <= gm <= hi_i and lo_j <= gm <= hi_j:
891
- nb = dict(b); nb[vi] = nb[vj] = gm
 
892
  hyps.append(_make_hyp(f"bil_eq_{vi}_{vj}", nb, "bilinear", f"GeoMean({vi}={vj}={gm:.3f})", ["bilinear"], {vi: gm, vj: gm}, [v for v in p.variables if v not in [vi, vj]], 0.70))
 
893
  for ratio in [0.4, 0.7071, 0.9]:
894
- vs = gm * ratio; vl = product / (vs + 1e-9)
 
895
  if lo_i <= vs <= hi_i and lo_j <= vl <= hi_j and vs < vl:
896
- nb2 = dict(b); nb2[vi] = vs; nb2[vj] = vl
 
 
897
  hyps.append(_make_hyp(f"bil_asc_{int(ratio*100)}_{vi}_{vj}", nb2, "bilinear", f"BilAsc({vi}={vs:.3f}<{vj}={vl:.3f})", ["bilinear"], {vi: vs, vj: vl}, [v for v in p.variables if v not in [vi, vj]], 0.75))
898
  return hyps
899
 
900
  def _hyp_monotone_product(p, bt, a, m):
901
- hyps = []; b = dict(bt.binding)
 
902
  if not p.monotone_targets: return hyps
903
  tb = _global_hc4_tighten_bounds(p)
 
904
  for v_small, v_large, k in p.monotone_targets:
905
- lo_s, hi_s = p.bounds.get(v_small, (-1e9, 1e9)); lo_l, hi_l = p.bounds.get(v_large, (-1e9, 1e9))
 
 
906
  for ratio in [0.25, 0.5, 0.707, 0.9]:
907
  vs_sq = k * ratio
908
  if vs_sq <= 0: continue
909
- vs = math.sqrt(vs_sq); vl = k / vs
 
910
  if not (lo_s <= vs <= hi_s and lo_l <= vl <= hi_l and vs <= vl): continue
911
- nb = dict(b); nb[v_small] = vs; nb[v_large] = vl
 
 
 
912
  box = {u: IV(*tb.get(u, p.bounds.get(u, (-10, 10)))) for u in p.variables}
913
- box[v_small] = IV(vs - 1e-6, vs + 1e-6); box[v_large] = IV(vl - 1e-6, vl + 1e-6)
 
914
  cont = _hc4(box, p.compiled_constraints)
 
915
  pinned = {v_small: vs, v_large: vl}
916
  if cont:
917
  for u, iv in cont.items():
918
  if u in p.bounds: nb[u] = iv.mid()
919
  pinned = {u: nb[u] for u in p.variables if cont[u].width() < 1e-2}
 
920
  hyps.append(_make_hyp(f"mpr_{v_small}_{v_large}_r{int(ratio*100)}", nb, "monotone_product", f"MonoProd({v_small}={vs:.4f}≀{v_large}={vl:.4f})", ["ordered", "hc4"], pinned, [u for u in p.variables if u not in pinned], 0.88))
921
  return hyps
922
 
923
  def _hyp_metric(p, bt, a, m):
924
- hyps = []; b = dict(bt.binding)
 
925
  for mc in p.compiled_constraints:
926
  if mc.kind != "equality" or not mc.parsed: continue
927
  if not mc.parsed.is_Add: continue
 
928
  sq_terms = [t for t in mc.parsed.args if t.is_Pow and t.args[1] == 2]
929
  if len(sq_terms) < 1: continue
930
  vars_in = [str(s) for s in mc.parsed.free_symbols if str(s) in p.variables]
931
  if not vars_in: continue
 
932
  const_terms = [float(t) for t in mc.parsed.args if t.is_Number]
933
  if not const_terms: continue
 
934
  target = -const_terms[0]
935
  if target <= 0: continue
 
936
  curr_val = sum(b.get(v, 0)**2 for v in vars_in)
937
  if curr_val < 1e-8: continue
 
938
  scale = math.sqrt(target / curr_val)
939
  nb = dict(b)
940
  for v in vars_in:
941
  lo, hi = p.bounds.get(v, (-10, 10))
942
  nb[v] = max(lo, min(hi, b.get(v, 0) * scale))
 
943
  hyps.append(_make_hyp(f"met_{hash(mc.expr_str)%9999}", nb, "metric", f"RadialProject(scale={scale:.4f},dim={len(vars_in)})", ["metric", mc.expr_str], {}, list(p.variables), 0.75))
944
  return hyps
945
 
946
  def _hyp_symmetric(p, bt, a, m):
947
- hyps = []; b = dict(bt.binding)
 
948
  groups_to_check = list(p.scope_vars.values()) if p.scope_vars else [p.variables]
949
- if not any(p.scope_vars.values()): groups_to_check = [p.variables]
 
950
 
951
  seen_pairs = set()
952
  for grp in groups_to_check:
@@ -957,14 +1152,21 @@ def _hyp_symmetric(p, bt, a, m):
957
  vi, vj = vl[i], vl[j]
958
  if (vi, vj) in seen_pairs: continue
959
  seen_pairs.add((vi, vj))
960
- lo_i, hi_i = p.bounds.get(vi, (-1e9, 1e9)); lo_j, hi_j = p.bounds.get(vj, (-1e9, 1e9))
 
 
961
  bvi, bvj = b.get(vi, 0), b.get(vj, 0)
 
962
  if lo_i <= bvj <= hi_i and lo_j <= bvi <= hi_j:
963
- nb = dict(b); nb[vi], nb[vj] = bvj, bvi
 
964
  hyps.append(_make_hyp(f"sym_{vi}_{vj}", nb, "symmetric", f"Swap({vi}↔{vj})", ["symmetric"], {vi: nb[vi], vj: nb[vj]}, [v for v in p.variables if v not in [vi, vj]], 0.60))
 
965
  avg = (bvi + bvj) / 2
966
  if lo_i <= avg <= hi_i and lo_j <= avg <= hi_j:
967
- nb2 = dict(b); nb2[vi] = avg; nb2[vj] = avg
 
 
968
  hyps.append(_make_hyp(f"sym_avg_{vi}_{vj}", nb2, "symmetric", f"Average({vi}={vj}={avg:.4f})", ["symmetric"], {vi: avg, vj: avg}, [v for v in p.variables if v not in [vi, vj]], 0.55))
969
  return hyps[:10]
970
 
@@ -975,24 +1177,29 @@ def _hyp_conserved(p, bt, a, m): return [_make_hyp("csv", bt.binding, "conserved
975
  def _hyp_mutable(p, bt, a, m):
976
  b = dict(bt.binding)
977
  if bt.l9 and bt.l9.dominant_vars:
978
- v = bt.l9.dominant_vars[0]; lo, hi = p.bounds.get(v, (-10, 10))
 
979
  b[v] = max(lo, min(hi, b.get(v, 0) + random.gauss(0, (hi - lo) * 0.05)))
980
  return [_make_hyp("mut", b, "mutable", "Perturb", [], {}, p.variables, 0.40)]
981
  def _hyp_network(p, bt, a, m): return [_make_hyp("net", bt.binding, "network", "HubProp", [], {}, p.variables, 0.65)]
982
  def _hyp_equilibrium(p, bt, a, m): return [_make_hyp("eql", bt.binding, "equilibrium", "GradBal", [], {}, p.variables, 0.72)]
983
  def _hyp_superposition(p, bt, a, m):
984
  if a and len(a) > 0:
985
- other = random.choice(a); lam = 0.5
 
986
  nb = {v: lam * bt.binding.get(v, 0) + (1 - lam) * other.binding.get(v, 0) for v in p.variables}
987
  return [_make_hyp("sup", nb, "superposition", "Superpose", [], {}, p.variables, 0.58)]
988
  return []
989
  def _hyp_locality(p, bt, a, m): return [_make_hyp("loc", bt.binding, "locality", "LocalFirst", [], {}, p.variables, 0.72)]
990
  def _hyp_extremal(p, bt, a, m):
991
- hyps = []; b = dict(bt.binding)
 
992
  if bt.l9 and bt.l9.dominant_vars:
993
- v = bt.l9.dominant_vars[0]; lo, hi = p.bounds.get(v, (0, 1))
 
994
  for val in [lo, hi, (lo + hi) / 2]:
995
- nb = dict(b); nb[v] = val
 
996
  hyps.append(_make_hyp(f"ext_{v}_{val:.3f}", nb, "extremal", f"PinBound({v}={val:.3f})", [], {v: val}, p.variables, 0.65))
997
  return hyps
998
  def _hyp_entropy(p, bt, a, m): return [_make_hyp("ent", {v: random.uniform(*p.bounds[v]) for v in p.variables}, "entropy", "MaxEnt", [], {}, p.variables, 0.48)]
@@ -1000,7 +1207,8 @@ def _hyp_injective(p, bt, a, m): return [_make_hyp("inj", bt.binding, "injective
1000
  def _hyp_surjective(p, bt, a, m): return [_make_hyp("sur", bt.binding, "surjective", "Sweep", [], {}, p.variables, 0.45)]
1001
  def _hyp_transitive(p, bt, a, m): return [_make_hyp("tra", bt.binding, "transitive", "TransSnap", [], {}, p.variables, 0.77)]
1002
  def _hyp_atomic(p, bt, a, m):
1003
- hyps = []; b = dict(bt.binding)
 
1004
  for mc in p.compiled_constraints:
1005
  if not mc.projections: continue
1006
  for v, projs in mc.projections.items():
@@ -1009,7 +1217,8 @@ def _hyp_atomic(p, bt, a, m):
1009
  val = float(proj["func"](*[b.get(s, 0.0) for s in proj["syms"]]))
1010
  lo, hi = p.bounds.get(v, (-1e9, 1e9))
1011
  if math.isfinite(val) and lo <= val <= hi:
1012
- nb = dict(b); nb[v] = val
 
1013
  hyps.append(_make_hyp(f"ato_{v}", nb, "atomic", f"Solve({v})", [], {v: val}, p.variables, 0.70))
1014
  break
1015
  except: pass
@@ -1022,11 +1231,14 @@ def _hyp_negation(p, bt, a, m):
1022
  def _hyp_composite(p, bt, a, m): return [_make_hyp("cmp", bt.binding, "composite", "Enz", [], {}, p.variables, 0.90)]
1023
  def _hyp_holism(p, bt, a, m): return [_make_hyp("hol", bt.binding, "holism", "Global", [], {}, p.variables, 0.73)]
1024
  def _hyp_parsimony(p, bt, a, m):
1025
- b = dict(bt.binding); nb = {}
 
1026
  max_val = max((abs(v) for v in b.values()), default=1.0)
1027
  for v in p.variables:
1028
- val = b[v]; lo, hi = p.bounds[v]
1029
- if abs(val) < 0.1 * max_val and lo <= 0.0 <= hi: nb[v] = 0.0
 
 
1030
  else:
1031
  candidates = [round(val * m) / m for m in [1, 2, 4] if lo <= round(val * m) / m <= hi]
1032
  nb[v] = min(candidates, key=lambda c: abs(c - val)) if candidates else val
@@ -1080,9 +1292,13 @@ class CreativeSeeder:
1080
  scored = []
1081
  for ax in remaining_axioms:
1082
  w_allos = 1.0
1083
- if n_dom == 1 and ax in isolated: w_allos += 5.0
1084
- elif n_dom == 2 and ax in relational: w_allos += 5.0
1085
- elif n_dom >= 3 and ax in systemic: w_allos += 5.0
 
 
 
 
1086
  w_sketch = sketch.axiom_affinities.get(ax, 1.0) if sketch else 1.0
1087
  scored.append((w_allos * w_sketch, ax))
1088
 
@@ -1090,7 +1306,9 @@ class CreativeSeeder:
1090
  children = []
1091
  for _, axiom in scored[:effective_width]:
1092
  child = ray.extend(axiom, "branch", new_prior=out_baton.ce)
1093
- if child: child.baton = out_baton; children.append(child)
 
 
1094
  return children
1095
 
1096
  def sketch_weighted_seeds(self, sketch: StructuralSketch, init_ce: float) -> List[AxiomRay]:
@@ -1109,17 +1327,24 @@ class CreativeSeeder:
1109
  if b2 in (a, b1, mid, c): continue
1110
  if frozenset([mid, b2]) not in _CONTRA_SET and frozenset([b2, c]) not in _CONTRA_SET:
1111
  results.append(AxiomRay([a, b1, mid, b2, c], f"T5_{AXIOM_ABBR.get(a, '?')}_{AXIOM_ABBR.get(c, '?')}", "tension"))
1112
- random.shuffle(results); return results[:max_n]
 
1113
 
1114
  def random_scouts(self, n: int = 600) -> List[AxiomRay]:
1115
- scouts = []; attempts = 0
 
1116
  while len(scouts) < n and attempts < n * 30:
1117
- attempts += 1; length = random.randint(3, 12)
1118
- pool = list(ALL_AXIOMS); random.shuffle(pool); seq = [pool[0]]
 
 
 
1119
  for ax in pool[1:]:
1120
  if len(seq) >= length: break
1121
- if ax != seq[-1] and frozenset([seq[-1], ax]) not in _CONTRA_SET: seq.append(ax)
1122
- if len(seq) >= 3: scouts.append(AxiomRay(seq, f"SC_{''.join(AXIOM_ABBR.get(a, a[:2]) for a in seq)}", "scout"))
 
 
1123
  return scouts
1124
 
1125
  def recombine(self, ray_a, ray_b, ba, bb) -> List[AxiomRay]:
@@ -1131,21 +1356,26 @@ class CreativeSeeder:
1131
  cut = min(len(ray_a.sequence), len(ray_b.sequence)) // 2
1132
  if cut > 0:
1133
  seq = ray_a.sequence[:cut] + [x for x in ray_b.sequence[cut:] if x not in ray_a.sequence[:cut]]
1134
- if sequence_valid(seq): results.append(AxiomRay(seq, f"RC_l{int(lam*100)}", "recombine", baton=ib_baton, ce_prior=ib_ce))
 
1135
  return results
1136
 
1137
  def invert(self, ray, parent_ce) -> Optional[AxiomRay]:
1138
  inv = list(reversed(ray.sequence))
1139
- if sequence_valid(inv) and inv != ray.sequence: return AxiomRay(inv, f"INV_{ray.ray_id}", "invert", parent_id=ray.ray_id, ce_prior=parent_ce)
 
1140
  return None
1141
 
1142
  def resonance_extensions(self, ray, parent_ce, resonant_pairs) -> List[AxiomRay]:
1143
  if not ray.sequence or not resonant_pairs: return []
1144
- last = ray.sequence[-1]; results = []
 
1145
  nexts = [b for (a, b) in resonant_pairs if a == last and b != last and frozenset([a, b]) not in _CONTRA_SET and b not in ray.sequence]
1146
  for b in nexts:
1147
  child = ray.extend(b, "branch", new_prior=parent_ce)
1148
- if child: child.ray_id = f"RES_{child.ray_id}"; results.append(child)
 
 
1149
  return results
1150
 
1151
  CREATIVE_SEEDER = CreativeSeeder()
@@ -1159,15 +1389,25 @@ def _verify(binding, base_problem, anchors):
1159
  g2 = {}
1160
  for inv in anchors:
1161
  try:
1162
- if inv.compiled_func: val = float(inv.compiled_func(*[binding.get(v, 0.0) for v in inv.syms_used]))
1163
- else: val = 999.0
 
 
 
1164
  err = abs(val)
1165
- if inv.mode == "eq": passed = err < inv.tolerance
1166
- elif inv.mode == "geq": passed = val >= -inv.tolerance
1167
- elif inv.mode == "leq": passed = val <= inv.tolerance
1168
- else: passed = err < inv.tolerance
 
 
 
 
 
1169
  g2[inv.name] = (round(val if inv.mode in ("geq", "leq") else err, 6), passed)
1170
- except: g2[inv.name] = (999.0, False)
 
 
1171
  g2_pass = all(v[1] for v in g2.values()) if g2 else True
1172
  return g1_pass, g2_pass, g2, round(g1_ce, 6)
1173
 
@@ -1178,55 +1418,77 @@ class SequenceRayTracer:
1178
 
1179
  def trace(self, axl_def: AXLProblemDef, base_problem: Problem):
1180
  hero_traces: List[HypothesisTrace] = []
1181
- baton_registry: Dict[str, Baton] = {}; baton_registry_keys: deque = deque()
1182
- successful_rays: List[AxiomRay] = []; resonant_pairs: List[Tuple[str, str]] = []
 
 
1183
 
1184
  for inv in axl_def.anchors:
1185
- if not inv.compiled_func: inv.compile(base_problem.variables)
 
1186
 
1187
- _update_state(phase="SKETCHING"); _add_log("πŸ—Ί Computing structural sketch…")
 
1188
  sketch = compute_sketch(base_problem)
1189
  _update_state(sketch_summary="; ".join(sketch.sketch_notes[:4]), sympy_derivation=sketch.sympy_derivation)
1190
  _add_log(f"βœ“ Sketch: {sketch.dominant_type} system, DOF={sketch.n_free_dof}")
1191
 
1192
- _update_state(phase="TEMPLATING"); _add_log("πŸ”¬ Generating hypothesis templates…")
 
1193
  templates = generate_templates(base_problem, sketch)
1194
  _update_state(template_count=len(templates))
1195
 
1196
  init_b, init_ce = _mprt_sample(base_problem, {v: IV(*base_problem.bounds[v]) for v in base_problem.variables}, N_MPRT_EXPLORE)
1197
  seed_baton = Baton(binding=init_b, ce=init_ce, ray_id="SEED", l9=L9Certificate(init_ce, base_problem.variables[:3], [], "systemic"))
1198
 
1199
- best_ce = init_ce; best_binding = dict(init_b)
 
 
1200
  if templates:
1201
  _add_log("βš— Evaluating templates (Phase 0 batch)…")
1202
  template_hyps = templates_to_hypotheses(templates, base_problem, init_b)
1203
  t_results = _batched_deduce_and_evaluate(base_problem, template_hyps)
 
1204
  for (th, template), (final_b, final_ce, dom_vars, tc) in zip(zip(template_hyps, templates), t_results):
1205
  g1p, g2p, inv_res, g1ce = _verify(final_b, base_problem, axl_def.anchors)
1206
  overall = g1p and g2p
 
1207
  if overall or final_ce < best_ce:
1208
  hero_traces.append(HypothesisTrace(
1209
  hid=template.template_id, round_idx=0, ray_name=f"template:{template.source}", ray_type="template",
1210
  ce_before=init_ce, ce_after=final_ce, survived=overall, elapsed_ms=0.0,
1211
  g1_pass=g1p, g2_pass=g2p, binding={k: round(v, 5) for k, v in final_b.items()},
1212
  invariant_results=inv_res, tension_class=tc, depth=0))
1213
- with STATE_LOCK: GLOBAL_SOLVE_STATE["recent_traces"].append(hero_traces[-1])
 
 
 
1214
  if final_ce < best_ce:
1215
- best_ce = final_ce; best_binding = dict(final_b)
 
1216
  _update_state(best_ce=best_ce)
 
1217
  if overall:
1218
  _add_log(f"βœ“ Template solved at Phase 0! Source: {template.source}")
1219
  _update_state(best_ce=best_ce, template_best_ce=best_ce, best_ray=f"template:{template.source}")
1220
  return best_binding, best_ce, hero_traces, 0, {"isolated": 0, "relational": 0, "systemic": 0}
 
1221
  _update_state(template_best_ce=best_ce)
1222
 
1223
  _update_state(phase="SEARCHING")
1224
  seed_rays = CREATIVE_SEEDER.sketch_weighted_seeds(sketch, best_ce)
1225
 
1226
- queues = {"core": seed_rays, "explore": CREATIVE_SEEDER.tension_seeds(3000) + CREATIVE_SEEDER.random_scouts(600), "genetic": CREATIVE_SEEDER.target_seeds(axl_def.anchors)}
1227
- random.shuffle(queues["explore"]); random.shuffle(queues["genetic"])
1228
-
1229
- queue_order = ["core", "explore", "genetic"]; q_idx = 0; total_fired = 0
 
 
 
 
 
 
 
1230
  allosteric_counts = {"isolated": 0, "relational": 0, "systemic": 0}
1231
  model = StructuralModel(best_binding, best_ce)
1232
  seed_baton = Baton(binding=best_binding, ce=best_ce, ray_id="SEED", l9=L9Certificate(best_ce, base_problem.variables[:3], [], "systemic"))
@@ -1239,31 +1501,39 @@ class SequenceRayTracer:
1239
  q_idx = (q_idx + 1) % 3
1240
  if q_idx == start_idx: break
1241
  if not any(queues[k] for k in queue_order): break
1242
- ray = queues[queue_order[q_idx]].pop(0); q_idx = (q_idx + 1) % 3
1243
- batch_rays.append(ray); total_fired += 1
 
 
 
1244
  if not batch_rays: break
1245
 
1246
  t0 = time.time()
1247
  historical_batons = list(baton_registry.values())
1248
  batch_hyps: List[Tuple[int, Hypothesis]] = []
 
1249
  for i, ray in enumerate(batch_rays):
1250
  p_baton = ray.baton or seed_baton
1251
  constructor = AXIOM_CONSTRUCTORS.get(ray.sequence[-1])
1252
  hyps = constructor(base_problem, p_baton, historical_batons, model) if constructor else []
1253
- if not hyps: hyps = [_make_hyp("fb", p_baton.binding, "fallback", "Pass", [], {}, base_problem.variables, 0.1)]
 
1254
  batch_hyps.append((i, hyps[0]))
1255
 
1256
  eval_results = _batched_deduce_and_evaluate(base_problem, [h for _, h in batch_hyps])
1257
  elapsed_ms = (time.time() - t0) * 1000 / max(1, len(batch_rays))
1258
 
1259
- solved = False; batch_heroes = []
 
 
1260
  for (ray_idx, hyp), (final_b, final_ce, dom_vars, tension_class) in zip(batch_hyps, eval_results):
1261
  ray = batch_rays[ray_idx]
1262
  parent_ce = (ray.baton or seed_baton).ce
1263
  allosteric_counts[tension_class] = allosteric_counts.get(tension_class, 0) + 1
1264
 
1265
  g1_pass, g2_pass, inv_results, g1_ce = _verify(final_b, base_problem, axl_def.anchors)
1266
- overall_pass = g1_pass and g2_pass; improved = final_ce < best_ce
 
1267
 
1268
  if improved or overall_pass or random.random() < 0.002:
1269
  trace = HypothesisTrace(
@@ -1277,21 +1547,30 @@ class SequenceRayTracer:
1277
  out_baton = Baton(binding=final_b, ce=final_ce, ray_id=ray.ray_id, l9=L9Certificate(final_ce, dom_vars, [], tension_class))
1278
 
1279
  if final_ce < BATON_REGISTRY_THRESHOLD:
1280
- if ray.ray_id in baton_registry: baton_registry[ray.ray_id] = out_baton
 
1281
  else:
1282
  if len(baton_registry) >= BATON_REGISTRY_MAX:
1283
- old_key = baton_registry_keys.popleft(); baton_registry.pop(old_key, None)
1284
- baton_registry[ray.ray_id] = out_baton; baton_registry_keys.append(ray.ray_id)
 
 
1285
 
1286
  if improved:
1287
- best_ce = final_ce; best_binding = dict(final_b); successful_rays.append(ray)
1288
- model.best_binding = best_binding; model.best_ce = best_ce; model.best_ray = ray.name
 
 
 
 
1289
 
1290
- if overall_pass: solved = True
 
1291
 
1292
  if improved and len(ray.sequence) >= 2:
1293
  pair = (ray.sequence[-2], ray.sequence[-1])
1294
- if pair not in resonant_pairs: resonant_pairs.append(pair)
 
1295
  model.resonant_pairs = resonant_pairs
1296
 
1297
  earned = (final_ce < parent_ce * CE_EARN_RATIO or ray.depth < 1)
@@ -1301,25 +1580,39 @@ class SequenceRayTracer:
1301
  remaining = [a for a in ALL_AXIOMS if a != ray.sequence[-1] and frozenset([ray.sequence[-1], a]) not in _CONTRA_SET and a not in ray.sequence]
1302
  new_children = []
1303
  new_children.extend(CREATIVE_SEEDER.intelligent_branch(ray, out_baton, remaining, BRANCH_WIDTH, sketch=sketch))
 
1304
  inv = CREATIVE_SEEDER.invert(ray, final_ce)
1305
- if inv: new_children.append(inv)
 
 
1306
  if len(successful_rays) >= 2:
1307
  candidates = [r for r in successful_rays if r.ray_id != ray.ray_id]
1308
  if candidates:
1309
- partner = random.choice(candidates); ba = baton_registry.get(ray.ray_id, out_baton); bb = baton_registry.get(partner.ray_id)
1310
- if bb is not None: new_children.extend(CREATIVE_SEEDER.recombine(ray, partner, ba, bb)[:3])
 
 
 
 
1311
  new_children.extend(CREATIVE_SEEDER.resonance_extensions(ray, final_ce, resonant_pairs))
 
1312
  for child in new_children:
1313
- if child.ray_type in ("seed", "branch", "target"): queues["core"].append(child)
1314
- elif child.ray_type in ("scout", "tension"): queues["explore"].append(child)
1315
- elif child.ray_type in ("recombine", "invert"): queues["genetic"].append(child)
 
 
 
1316
 
1317
  queues["core"].sort(key=lambda r: r.ce_prior + (r.depth * 0.0001))
1318
  queues["genetic"].sort(key=lambda r: r.ce_prior + (r.depth * 0.0001))
1319
 
1320
  with STATE_LOCK:
1321
- GLOBAL_SOLVE_STATE["best_ce"] = best_ce; GLOBAL_SOLVE_STATE["total_fired"] = total_fired; GLOBAL_SOLVE_STATE["best_ray"] = model.best_ray
1322
- for t in batch_heroes: GLOBAL_SOLVE_STATE["recent_traces"].append(t)
 
 
 
1323
 
1324
  if solved: break
1325
 
@@ -1363,84 +1656,149 @@ def encode_problem_to_axl(problem_text, api_key) -> AXLProblemDef:
1363
  resp = client.models.generate_content(model=GEMINI_MODEL, contents=[types.Content(role="user", parts=[types.Part.from_text(text=problem_text)])], config=config)
1364
 
1365
  text = resp.text.strip()
1366
- if text.startswith("```"): text = text.split("```")[1]; (text := text[4:]) if text.startswith("json") else text
 
 
 
 
1367
  text = text.strip().rstrip("`").strip()
1368
  d = json.loads(text)
1369
 
1370
  anchors = [AXLInvariant(name=a["name"], expr=a["expr"], tolerance=a.get("tolerance", VERIFY_G2_TOLERANCE), mode=a.get("mode", "eq")) for a in d.get("anchors", [])]
1371
  variables = [{"name": v["name"], "lo": float(v.get("lo", -1000.0)), "hi": float(v.get("hi", 1000.0))} for v in d["variables"]]
 
1372
  return AXLProblemDef(name=d["name"], description=d.get("description", ""), axioms=set(), variables=variables, constraints=d.get("constraints", []), scopes=d.get("scopes", []), anchors=anchors, observations=d.get("observations", {}))
1373
 
1374
  def collapse_solution(problem_text, axl_def, psl_text, binding, g1_pass, g2_pass, inv_results, best_ray, total_fired, sketch_notes, sympy_derivation, api_key) -> str:
1375
  if not api_key: return "ERROR: API Key required."
1376
  client = genai.Client(api_key=api_key)
1377
- payload = {"original_problem": problem_text, "solved": g1_pass and g2_pass, "binding": {k: round(v, 6) for k, v in binding.items()}, "psl_program_text": psl_text, "isomorphism_hypothesis": best_ray, "structural_sketch_notes": sketch_notes, "sympy_derivation_chain": sympy_derivation, "invariant_results": inv_results}
 
 
 
 
 
 
 
 
 
 
 
1378
  config = types.GenerateContentConfig(thinking_config=types.ThinkingConfig(thinking_level="HIGH"), system_instruction=[types.Part.from_text(text=COLLAPSER_SYSTEM_PROMPT)], temperature=0.2)
1379
  resp = client.models.generate_content(model=GEMINI_MODEL, contents=[types.Content(role="user", parts=[types.Part.from_text(text=json.dumps(payload, indent=2))])], config=config)
1380
  return resp.text
1381
 
1382
  # ══════════════════════════════════════════════════════════════════════
1383
- # SECTION 15: GLOBAL SOLVE TASK
1384
  # ══════════════════════════════════════════════════════════════════════
1385
  def global_solve_task(original_problem_text, api_key, prebuilt_axl=None):
1386
- _update_state(is_running=True, phase="ENCODING", high_level_logs=[], answer="", best_ce=float('inf'), total_fired=0, best_ray="β€”", recent_traces=deque(maxlen=25), sketch_summary="", template_count=0, template_best_ce=float('inf'), sympy_derivation=[])
1387
- MAX_ATTEMPTS = 3; current_text = original_problem_text; used_key = api_key or DEFAULT_GEMINI_API_KEY; sketch_notes = []
1388
-
1389
- for attempt in range(1, MAX_ATTEMPTS + 1):
1390
- if prebuilt_axl is not None:
1391
- _add_log("⚑ Bypassing Encoder: Using Pre-compiled Quantum AXL")
1392
- axl_def = prebuilt_axl
1393
- else:
1394
- _add_log(f"πŸ” Encoding (attempt {attempt}/{MAX_ATTEMPTS})…")
1395
- try: axl_def = encode_problem_to_axl(current_text, used_key)
1396
- except Exception as e: _add_log(f"βœ— Encode failed: {e}"); _update_state(is_running=False, phase="ERROR"); return
1397
-
1398
- _add_log(f"βœ“ `{axl_def.name}` | vars: {', '.join(v['name'] for v in axl_def.variables)}")
1399
- _update_state(phase="COMPILING")
1400
-
1401
- try: psl_text = AXL_COMPILER.compile(axl_def); base_prob = build_base_problem(axl_def)
1402
- except Exception as e: _add_log(f"βœ— Compile failed: {e}"); _update_state(is_running=False, phase="ERROR"); return
1403
-
1404
- try: tracer = SequenceRayTracer(); binding, ce, traces, total_fired, allosteric = tracer.trace(axl_def, base_prob)
1405
- except Exception as e: _add_log(f"βœ— Solver error: {e}"); _update_state(is_running=False, phase="ERROR"); return
1406
-
1407
- with STATE_LOCK: sketch_notes = GLOBAL_SOLVE_STATE.get("sketch_summary", "").split("; "); current_sympy_derivation = GLOBAL_SOLVE_STATE.get("sympy_derivation", [])
1408
-
1409
- survived = [t for t in traces if t.survived]; best_t = min(survived, key=lambda t: t.ce_after, default=None)
1410
-
1411
- for inv in axl_def.anchors:
1412
- if not inv.compiled_func: inv.compile(base_prob.variables)
1413
-
1414
- g1_ce = base_prob.scalar_energy(binding); g1_pass = g1_ce < VERIFY_G1_THRESHOLD; inv_results = {}
1415
- for inv in axl_def.anchors:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1416
  try:
1417
- val = float(inv.compiled_func(*[binding.get(v, 0.0) for v in inv.syms_used])); err = abs(val)
1418
- passed = (err < inv.tolerance if inv.mode == "eq" else val >= -inv.tolerance if inv.mode == "geq" else val <= inv.tolerance)
1419
- inv_results[inv.name] = (round(val, 6), passed)
1420
- except: inv_results[inv.name] = (999.0, False)
1421
- g2_pass = all(v[1] for v in inv_results.values())
1422
-
1423
- solved_str = "βœ“ SOLVED" if (g1_pass and g2_pass) else "~ PARTIAL" if g1_pass else "βœ— UNSOLVED"
1424
- best_ray = best_t.ray_name if best_t else "β€”"
1425
- _add_log(f"🏁 {solved_str} (CE: {ce:.5f}) | Ray: {best_ray}")
1426
-
1427
- if prebuilt_axl is None:
1428
- if not g1_pass and attempt < MAX_ATTEMPTS:
1429
- current_text = (original_problem_text + f"\n\nPREVIOUS ATTEMPT FAILED (Best CE: {ce}):\nGEOMETRIC SOLVER FAILED. Apply ALGEBRAIC REDUCTION: substitute simple equalities to eliminate variables, output simplified AXL.")
1430
- _add_log("⚠ Geometric solver failed. Triggering algebraic reduction…"); continue
1431
- if not g2_pass and attempt < MAX_ATTEMPTS:
1432
- failed = {k: v for k, (v, ok) in inv_results.items() if not ok}
1433
- current_text = (original_problem_text + f"\n\nPREVIOUS ATTEMPT FAILED:\nGate 2 failed:\n{json.dumps(failed, indent=2)}\nRevise constraint encoding to capture these conditions.")
1434
- _add_log("⚠ Gate 2 failed. Retrying with structural feedback…"); continue
1435
-
1436
- _add_log("πŸ”€ Collapsing isomorphism to domain language…")
1437
- _update_state(phase="COLLAPSING")
1438
- try:
1439
- answer = collapse_solution(original_problem_text, axl_def, psl_text, binding, g1_pass, g2_pass, inv_results, best_ray, total_fired, sketch_notes, current_sympy_derivation, used_key)
1440
- _update_state(answer=answer, phase="DONE"); _add_log("βœ“ Done.")
1441
- except Exception as e: _update_state(answer=f"Collapsing error: {e}", phase="ERROR"); _add_log("βœ— Collapse failed.")
1442
- break
1443
- _update_state(is_running=False)
1444
 
1445
  def trigger_solve(problem_text, api_key):
1446
  if GLOBAL_SOLVE_STATE["is_running"] or not problem_text.strip(): return
@@ -1448,28 +1806,46 @@ def trigger_solve(problem_text, api_key):
1448
 
1449
  def trigger_quantum_solve(example_name, api_key):
1450
  if not HAS_QUANTUM or GLOBAL_SOLVE_STATE["is_running"]: return
1451
- _update_state(is_running=True)
1452
 
1453
- if example_name == "Bell State": circ = QuantumCircuits.example_bell_state()
1454
- elif example_name == "VQE H2": circ = QuantumCircuits.example_vqe_h2()
1455
- elif example_name == "QAOA MaxCut": circ = QuantumCircuits.example_qaoa_maxcut_p1()
1456
- else: _update_state(is_running=False); return
1457
-
1458
- problem_desc = f"Quantum Circuit: {circ.name}\nDescription: {circ.description}\nTarget Observables: {circ.expected_observables}"
1459
-
1460
- try: axl_def = QuantumCircuits.build_quantum_axl(circ, AXLProblemDef, AXLInvariant)
1461
- except Exception as e: _add_log(f"βœ— Quantum compiler failed: {e}"); _update_state(is_running=False, phase="ERROR"); return
 
 
 
 
 
 
 
 
 
 
 
1462
 
1463
- threading.Thread(target=global_solve_task, args=(problem_desc, api_key, axl_def), daemon=True).start()
1464
 
1465
  # ══════════════════════════════════════════════════════════════════════
1466
  # SECTION 16: GRADIO INTERFACE
1467
  # ══════════════════════════════════════════════════════════════════════
1468
- CSS = """body{background:#090909;color:#e0e0e0;font-family:monospace;}
1469
- .solver-log{font-size:0.75em;background:#0d0d0d;border:1px solid #181818;}
1470
- .answer-box{font-size:0.85em;background:#0d0d0d;border:1px solid #222;padding:10px;}"""
 
 
 
 
 
 
 
 
 
1471
 
1472
- RAY_ICONS = {"seed": "🌱", "branch": "🌿", "tension": "⚑", "scout": "πŸ”­", "recombine": "🧬", "invert": "πŸ”„", "target": "🎯", "template": "πŸ—Ί", "fallback": "Β·"}
1473
  PLACEHOLDER_HINT = textwrap.dedent("""
1474
  Try any natural language problem. Gemini encodes it, the system finds the structural solution.
1475
  Examples:
@@ -1479,28 +1855,50 @@ PLACEHOLDER_HINT = textwrap.dedent("""
1479
 
1480
  def build_live_html():
1481
  with STATE_LOCK:
1482
- phase = GLOBAL_SOLVE_STATE["phase"]; ce = GLOBAL_SOLVE_STATE["best_ce"]
1483
- fired = GLOBAL_SOLVE_STATE["total_fired"]; best_ray = GLOBAL_SOLVE_STATE["best_ray"]
1484
- traces = list(GLOBAL_SOLVE_STATE["recent_traces"]); logs = GLOBAL_SOLVE_STATE["high_level_logs"]
 
 
 
1485
  sketch_summary = GLOBAL_SOLVE_STATE["sketch_summary"]
1486
- template_count = GLOBAL_SOLVE_STATE["template_count"]; template_best = GLOBAL_SOLVE_STATE["template_best_ce"]
 
1487
 
1488
  ce_color = "#4CAF50" if ce < SOLVE_THRESHOLD else "#FF9800"
1489
- phase_color = "#26C6DA" if phase in ["SEARCHING", "COLLAPSING", "ENCODING", "SKETCHING", "TEMPLATING"] else ("#4CAF50" if phase == "DONE" else "#888")
 
 
 
 
 
 
 
 
1490
 
1491
  log_html = "<ul style='margin:0;padding-left:20px;color:#aaa;font-size:0.82em'>"
1492
- for l in logs[-5:]: log_html += f"<li>{l}</li>"
 
1493
  log_html += "</ul>"
1494
 
1495
- sketch_html = (f"<div style='color:#555;font-size:0.72em;margin:6px 0;padding:4px 8px;border-left:2px solid #26C6DA;background:#0a0a0a'>πŸ—Ί <span style='color:#26C6DA'>Sketch</span>: {sketch_summary[:120]}</div>") if sketch_summary else ""
1496
- template_html = (f"<div style='color:#555;font-size:0.72em;margin:4px 0'>πŸ—Ί Templates: {template_count} generated | floor CE: {f'{template_best:.5f}' if template_best < float('inf') else 'β€”'}</div>") if template_count > 0 else ""
 
 
 
 
 
 
1497
 
1498
  ray_trail = ""
1499
  for t in reversed(traces):
1500
- icon = RAY_ICONS.get(t.ray_type, "Β·"); c = "#4CAF50" if t.survived else "#555"; star = " β—€" if t.survived else ""
 
 
1501
  ray_trail += f"<div style='color:{c};font-size:0.78em;margin-bottom:2px'>{icon} [{t.ray_name}] CE={t.ce_after:.4f} <span style='color:#888'>({t.tension_class[:3]})</span><span style='color:#4CAF50;font-weight:700'>{star}</span></div>"
1502
 
1503
- return f"""<div style='border:1px solid #222;border-radius:6px;padding:12px;background:#0d0d0d;min-height:440px;display:flex;flex-direction:column'>
 
1504
  <div style='color:{phase_color};font-weight:bold;margin-bottom:8px'>● Phase: {phase}</div>
1505
  <div style='margin-bottom:10px;border-bottom:1px solid #222;padding-bottom:8px'>{log_html}</div>
1506
  {sketch_html}{template_html}
@@ -1510,38 +1908,55 @@ def build_live_html():
1510
  </div>
1511
  <div style='color:#aaa;margin-bottom:8px;font-size:0.85em'>Best Iso: <span style='color:#FF9800'>{best_ray}</span></div>
1512
  <div style='flex:1;overflow-y:auto;border-top:1px solid #222;padding-top:8px'>{ray_trail}</div>
1513
- </div>"""
 
1514
 
1515
  with gr.Blocks(css=CSS, title="Practicality 24.1") as demo:
1516
  gr.Markdown("## βš— Practicality 24.1 β€” Structural Sketch, World Model Prior & Quantum Engine\n`[Gemini Encoder] β†’ [Structural Sketch / SymPy] β†’ [Morphing Ray Solver] β†’ [Gemini Collapser]`")
1517
- with gr.Row():
1518
- with gr.Column(scale=2):
 
1519
  api_key_input = gr.Textbox(label="Gemini API Key", type="password", placeholder="AIza...", value=DEFAULT_GEMINI_API_KEY, elem_classes=["solver-log"])
1520
  with gr.Tabs():
1521
  with gr.Tab("Natural Language"):
1522
  problem_input = gr.Textbox(label="Problem Description", placeholder=PLACEHOLDER_HINT, lines=5, elem_classes=["solver-log"])
1523
  with gr.Row():
1524
- solve_btn = gr.Button("βš— Solve Natural Language", variant="primary"); clear_btn = gr.Button("Clear")
 
 
1525
  if HAS_QUANTUM:
1526
  with gr.Tab("Quantum Circuits (Heisenberg Abstraction)"):
1527
  q_dropdown = gr.Dropdown(choices=["Bell State", "VQE H2", "QAOA MaxCut"], label="Select Circuit Template", value="Bell State")
1528
  q_solve_btn = gr.Button("βš› Run Quantum Solver (Bypass Encoder)", variant="primary")
1529
- with gr.Column(scale=1):
1530
- gr.Textbox(value=(f"Compute: {DEVICE.type.upper()}\nAxioms: {len(ALL_AXIOMS)}\nNew: SymPy Derivation Chain Capture\nNew: Quantum BBGKY Cumulant Expansion\nNew: Homotopy Continuation (Morphing Ray)\nNew: Anchor Fix (Gate 2 Sync)"), lines=7, interactive=False, elem_classes=["solver-log"])
1531
-
1532
- with gr.Row():
1533
- live_html = gr.HTML(value=build_live_html())
1534
- answer_box = gr.Textbox(label="Isomorphic Collapse", lines=20, interactive=False, elem_classes=["answer-box"])
 
 
 
 
 
 
 
 
 
1535
 
1536
  def fetch_ui():
1537
  while True:
1538
- time.sleep(1.0); yield build_live_html(), GLOBAL_SOLVE_STATE["answer"]
 
1539
 
1540
  solve_btn.click(fn=trigger_solve, inputs=[problem_input, api_key_input], outputs=None)
1541
  clear_btn.click(fn=lambda: ("", "", ""), inputs=[], outputs=[problem_input, live_html, answer_box])
1542
- if HAS_QUANTUM: q_solve_btn.click(fn=trigger_quantum_solve, inputs=[q_dropdown, api_key_input], outputs=None)
 
 
 
1543
  demo.load(fetch_ui, inputs=None, outputs=[live_html, answer_box])
1544
 
1545
  if __name__ == "__main__":
1546
  print(f"[SYSTEM 24.1] Compute: {DEVICE.type.upper()} | Feature Flags: Quantum={HAS_QUANTUM}")
1547
- demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
1
+ #!/usr/bin/env python3
2
  """
3
  PRACTICALITY SYSTEM 24.1 β€” STRUCTURAL SKETCH, QUANTUM ENGINE & HOMOTOPY CONTINUATION
4
  ══════════════════════════════════════════════════════════════════════════════════
 
9
  β†’ [WISDOM LAYER] β†’ Sketch-weighted rays + Masked Deduction (with Homotopy)
10
  β†’ [GEMINI COLLAPSER] β†’ Domain-language explanation
11
 
12
+ CRITICAL STABILITY FIXES:
13
+ 1. Thread Crash Safety: Entire solver loop wrapped in try/finally to prevent UI lockups.
14
+ 2. UI Responsive Layout: Unminified HTML generators and removed nested f-strings.
15
+ 3. Expanded Axiom Logic: Restored full readability of structural heuristics.
 
16
  """
17
 
18
  import os, time, random, math, threading, warnings, json, textwrap
 
42
  # ══════════════════════════════════════════════════════════════════════
43
  # AI CONFIGURATION
44
  # ══════════════════════════════════════════════════════════════════════
45
+ DEFAULT_GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
46
+ GEMINI_MODEL = "gemini-2.5-pro-preview-06-05"
47
 
48
  warnings.filterwarnings("ignore")
49
  USE_GPU = torch.cuda.is_available()
50
  DEVICE = torch.device("cuda" if USE_GPU else "cpu")
51
+ print(f"[SYSTEM 24.1] Compute: {DEVICE.type.upper()} | Homotopy Continuation + Thread Safety")
52
 
53
  # ══════════════════════════════════════════════════════════════════════
54
  # SECTION 1: CONSTANTS
 
79
  STATE_LOCK = threading.Lock()
80
 
81
  GLOBAL_SOLVE_STATE = {
82
+ "is_running": False,
83
+ "phase": "IDLE",
84
+ "best_ce": float('inf'),
85
+ "total_fired": 0,
86
+ "best_ray": "β€”",
87
+ "recent_traces": deque(maxlen=25),
88
+ "high_level_logs": [],
89
+ "answer": "",
90
+ "sketch_summary": "",
91
+ "template_count": 0,
92
+ "template_best_ce": float('inf'),
93
+ "sympy_derivation": [],
94
  }
95
 
96
  def _update_state(**kwargs):
97
  with STATE_LOCK:
98
+ for k, v in kwargs.items():
99
+ GLOBAL_SOLVE_STATE[k] = v
100
 
101
  def _add_log(line: str):
102
+ with STATE_LOCK:
103
+ GLOBAL_SOLVE_STATE["high_level_logs"].append(line)
104
 
105
  # ══════════════════════════════════════════════════════════════════════
106
  # SECTION 3: INTERVAL ARITHMETIC (HC4)
 
316
  # ══════════════════════════════════════════════════════════════════════
317
  @dataclass
318
  class Constraint:
319
+ kind:str; expr:str; direction:str; weight:float=1.0; scope:str="root"
320
+ branches:List[str]=field(default_factory=list)
321
 
322
  @dataclass
323
  class MathConstraint:
 
499
  # ══════════════════════════════════════════════════════════════════════
500
  @dataclass
501
  class StructuralSketch:
502
+ axiom_affinities: Dict[str, float]
503
+ solvable_by_sympy: bool
504
+ exact_solutions: List[Dict[str, float]]
505
+ sympy_derivation: List[str]
506
+ n_free_dof: int
507
+ has_conservation: bool
508
+ has_bilinear: bool
509
+ has_ordering: bool
510
+ has_transcendental: bool
511
+ dominant_type: str
512
+ sketch_notes: List[str]
513
 
514
  @dataclass
515
  class HypothesisTemplate:
516
+ template_id: str
517
+ pinned_vars: Dict[str,float]
518
+ free_vars: List[str]
519
+ source: str
520
+ confidence: float
521
+ derivation: str
522
 
523
  def _try_sympy_solve(problem: Problem) -> Tuple[List[Dict[str, float]], bool, List[str]]:
524
  has_transcendental = any(
525
  mc.parsed is not None and (mc.parsed.has(sp.sin) or mc.parsed.has(sp.cos) or mc.parsed.has(sp.exp) or mc.parsed.has(sp.log))
526
  for mc in problem.compiled_constraints)
527
  if has_transcendental: return [], False, []
528
+
529
  eq_mcs = [mc for mc in problem.compiled_constraints if mc.kind == "equality" and mc.parsed is not None and mc.syms_used]
530
  if len(eq_mcs) < len(problem.variables): return [], False, []
531
+
532
  syms = [sp.Symbol(v) for v in problem.variables]
533
  equations = [mc.parsed for mc in eq_mcs]
534
 
535
+ def _solve():
536
+ return sp.solve(equations, syms, dict=True)
537
 
538
  try:
539
  with concurrent.futures.ThreadPoolExecutor(max_workers=1) as ex:
540
  future = ex.submit(_solve)
541
  raw = future.result(timeout=SYMPY_TIMEOUT_SECS)
542
  except Exception: return [], False, []
543
+
544
  if not raw: return [], False, []
545
 
546
  derivation = ["SYSTEM HANDED TO SYMPY:"]
547
  for mc in eq_mcs: derivation.append(f" {mc.expr_str} = 0")
548
+
549
  for sol_idx, sol in enumerate(raw[:2]):
550
  derivation.append(f"\nSYMBOLIC SOLUTION #{sol_idx + 1}:")
551
  sorted_sol = sorted(sol.items(), key=lambda kv: len(kv[1].free_symbols))
552
  for sym, val in sorted_sol:
553
  simplified = sp.simplify(val); free_s = sorted(simplified.free_symbols, key=str)
554
  if not free_s:
555
+ try:
556
+ num = float(simplified.evalf())
557
+ derivation.append(f" {sym} = {simplified} = {num:.8g} [constant root]")
558
+ except:
559
+ derivation.append(f" {sym} = {simplified} [symbolic constant]")
560
+ else:
561
+ derivation.append(f" {sym} = {simplified} [eliminates {sym}, depends on {', '.join(str(s) for s in free_s)}]")
562
+
563
  if len(sorted_sol) == 1:
564
  sym, val = sorted_sol[0]
565
  try:
566
  poly = sp.Poly(equations[0], sp.Symbol(str(sym)))
567
+ b_lo, b_hi = problem.bounds.get(str(sym), ('?', '?'))
568
+ derivation.append(f" Univariate polynomial: degree {poly.degree()}, roots selected by bounds")
569
  except: pass
570
 
571
  valid = []
572
  b_mid = {v: (problem.bounds[v][0] + problem.bounds[v][1]) / 2 for v in problem.variables}
573
  for sol in raw:
574
+ binding = dict(b_mid)
575
+ ok = True
576
  for sym, val in sol.items():
577
  try:
578
  num = float(val.evalf()); vn = str(sym)
 
584
  if ok:
585
  ce = problem.scalar_energy(binding)
586
  if ce < 1.0: valid.append((binding, ce))
587
+
588
  valid.sort(key=lambda x: x[1])
589
  if valid: derivation.append(f"\nBOUND-FILTERED: {len(valid)} of {len(raw)} symbolic solutions fall within domains.")
590
  else: derivation.append(f"\nBOUND CHECK: all {len(raw)} symbolic solutions lie outside variable domains.")
591
+
592
  return [v[0] for v in valid], len(valid) > 0, derivation
593
 
594
  def compute_sketch(problem: Problem) -> StructuralSketch:
595
+ affinities = {a: 1.0 for a in _ALL_AXIOMS_PLACEHOLDER}
596
+ notes = []
597
+ n_vars = len(problem.variables)
598
+ n_eq = sum(1 for mc in problem.compiled_constraints if mc.kind == "equality")
599
 
600
  has_conservation = any(mc.weight >= 5.0 for mc in problem.compiled_constraints if mc.kind == "equality")
601
  if has_conservation:
602
+ affinities["CONSERVED"] += 3.0
603
+ affinities["COMPOSITE"] += 1.5
604
  notes.append("Conservation laws β†’ CONSERVED/COMPOSITE boosted")
605
 
606
  if problem.bilinear_pairs:
 
608
  notes.append(f"{len(problem.bilinear_pairs)} bilinear pairs β†’ BILINEAR boosted")
609
 
610
  if problem.monotone_targets:
611
+ affinities["MONOTONE_PRODUCT"] += 5.0
612
+ affinities["ORDERED"] += 2.5
613
  notes.append(f"{len(problem.monotone_targets)} monotone targets β†’ MPR strongly boosted")
614
 
615
  if problem.ordering_pairs:
616
+ affinities["ORDERED"] += 2.0
617
+ affinities["DISCRETE"] += 1.0
618
  notes.append(f"{len(problem.ordering_pairs)} ordering constraints β†’ ORDERED boosted")
619
 
620
  if any(problem.scope_vars.values()):
621
+ affinities["DISCRETE"] += 2.0
622
+ affinities["LOCALITY"] += 1.0
623
  notes.append("Scope structure detected β†’ DISCRETE boosted")
624
 
625
  n_proj = sum(1 for mc in problem.compiled_constraints if mc.projections)
626
  if n_proj > 0:
627
+ affinities["ATOMIC"] += 2.0 + n_proj * 0.3
628
+ affinities["IMPLICATION"] += 1.5
629
+ affinities["TRANSITIVE"] += 1.5
630
  notes.append(f"{n_proj} projectable constraints β†’ ATOMIC/IMPLICATION boosted")
631
 
632
  has_sos = any(mc.parsed is not None and mc.parsed.is_Add and any(t.is_Pow and t.args[1] == 2 for t in mc.parsed.args) for mc in problem.compiled_constraints if mc.kind == "equality")
633
  if has_sos:
634
+ affinities["METRIC"] += 2.5
635
+ affinities["QUADRATIC"] += 2.0
636
+ affinities["CONTINUOUS"] += 1.5
637
  notes.append("Sum-of-squares β†’ METRIC/QUADRATIC/CONTINUOUS boosted")
638
 
639
  tight = sum(1 for v in problem.variables if abs(problem.bounds[v][1] - problem.bounds[v][0]) < 10)
640
+ if tight > n_vars // 2:
641
+ affinities["PARSIMONY"] += 2.0
642
+ notes.append("Tight bounds β†’ PARSIMONY boosted")
643
 
644
+ if n_vars >= 6:
645
+ affinities["HOLISM"] += 1.5
646
+ affinities["NETWORK"] += 1.5
647
+ notes.append(f"High-D ({n_vars} vars) β†’ HOLISM/NETWORK boosted")
648
 
649
  bound_groups = defaultdict(list)
650
  for v in problem.variables: bound_groups[problem.bounds[v]].append(v)
651
+ if any(len(g) >= 2 for g in bound_groups.values()):
652
+ affinities["SYMMETRIC"] += 1.5
653
+ notes.append("Symmetric bounds β†’ SYMMETRIC boosted")
654
 
655
  has_transcendental = any(mc.parsed is not None and (mc.parsed.has(sp.sin) or mc.parsed.has(sp.cos) or mc.parsed.has(sp.exp)) for mc in problem.compiled_constraints)
656
+ if has_transcendental:
657
+ affinities["CONTINUOUS"] += 2.0
658
+ affinities["EQUILIBRIUM"] += 1.5
659
+ notes.append("Transcendental constraints β†’ CONTINUOUS/EQUILIBRIUM boosted")
660
 
661
  max_deg = 1
662
  for mc in problem.compiled_constraints:
 
675
  n_obs = sum(1 for v in problem.variables if problem.bounds[v][0] == problem.bounds[v][1])
676
  n_free_dof = max(0, n_vars - n_obs - n_eq)
677
 
678
+ exact_solutions = []
679
+ solvable = False
680
+ sympy_derivation = []
681
  if n_vars <= SYMPY_MAX_VARS and dom_type in ("linear", "quadratic") and not has_transcendental:
682
  exact_solutions, solvable, sympy_derivation = _try_sympy_solve(problem)
683
+ if solvable:
684
+ notes.append(f"βœ“ SymPy found {len(exact_solutions)} exact solution(s) via {len(sympy_derivation)} steps")
685
+ else:
686
+ notes.append("SymPy attempted (no closed form) β€” proceeding to ray search")
687
+
688
+ return StructuralSketch(
689
+ axiom_affinities=affinities, solvable_by_sympy=solvable,
690
+ exact_solutions=exact_solutions, sympy_derivation=sympy_derivation,
691
+ n_free_dof=n_free_dof, has_conservation=has_conservation,
692
+ has_bilinear=bool(problem.bilinear_pairs), has_ordering=bool(problem.ordering_pairs),
693
+ has_transcendental=has_transcendental, dominant_type=dom_type, sketch_notes=notes)
694
 
695
  def generate_templates(problem: Problem, sketch: StructuralSketch) -> List[HypothesisTemplate]:
696
+ templates = []
697
+ b_mid = {v: (problem.bounds[v][0] + problem.bounds[v][1]) / 2 for v in problem.variables}
698
 
699
  for i, sol in enumerate(sketch.exact_solutions):
700
+ templates.append(HypothesisTemplate(
701
+ template_id=f"sympy_{i}", pinned_vars=sol,
702
+ free_vars=[v for v in problem.variables if v not in sol],
703
+ source="sympy_exact", confidence=0.99, derivation=f"SymPy exact solution #{i+1}"))
704
 
705
  for mc in problem.compiled_constraints:
706
  if mc.kind != "equality" or mc.weight < 5.0 or not mc.projections: continue
 
710
  try:
711
  val = float(proj["func"](*[b_mid.get(s, 0.0) for s in proj["syms"]]))
712
  if math.isfinite(val) and lo <= val <= hi:
713
+ templates.append(HypothesisTemplate(
714
+ template_id=f"cons_{v}_{hash(mc.expr_str)%9999}", pinned_vars={v: val},
715
+ free_vars=[u for u in problem.variables if u != v], source="conservation",
716
+ confidence=0.75, derivation=f"Conservation {mc.expr_str} β†’ {v}={val:.4f}"))
717
  except: pass
718
 
719
  tb = _global_hc4_tighten_bounds(problem)
720
  for v_small, v_large, k in problem.monotone_targets:
721
+ lo_s, hi_s = problem.bounds.get(v_small, (-1e9, 1e9))
722
+ lo_l, hi_l = problem.bounds.get(v_large, (-1e9, 1e9))
723
  for ratio in [0.1, 0.25, 0.5, 0.707, 0.9]:
724
  vs_sq = k * ratio
725
  if vs_sq <= 0: continue
726
  vs = math.sqrt(vs_sq); vl = k / vs
727
  if not (lo_s <= vs <= hi_s and lo_l <= vl <= hi_l and vs <= vl): continue
728
+
729
+ nb = dict(b_mid)
730
+ nb[v_small] = vs
731
+ nb[v_large] = vl
732
  box = {u: IV(*tb.get(u, problem.bounds.get(u, (-10, 10)))) for u in problem.variables}
733
+ box[v_small] = IV(vs - 1e-6, vs + 1e-6)
734
+ box[v_large] = IV(vl - 1e-6, vl + 1e-6)
735
  cont = _hc4(box, problem.compiled_constraints)
736
+
737
  pinned = {v_small: vs, v_large: vl}
738
  if cont:
739
  for u, iv in cont.items():
740
  if u in problem.bounds: nb[u] = iv.mid()
741
  pinned = {u: nb[u] for u in problem.variables if cont[u].width() < 1e-2}
742
+
743
+ templates.append(HypothesisTemplate(
744
+ template_id=f"mpr_{v_small}_{v_large}_r{int(ratio*100)}", pinned_vars=pinned,
745
+ free_vars=[u for u in problem.variables if u not in pinned], source="monotone_prod",
746
+ confidence=0.88, derivation=f"Monotone {v_small}={vs:.4f}≀{v_large}={vl:.4f}"))
747
 
748
  for mc in problem.compiled_constraints:
749
  if mc.kind != "equality" or not mc.projections: continue
 
753
  try:
754
  val = float(proj["func"](*[b_mid.get(s, 0.0) for s in proj["syms"]]))
755
  if math.isfinite(val) and lo <= val <= hi:
756
+ templates.append(HypothesisTemplate(
757
+ template_id=f"proj_{v}_{hash(mc.expr_str)%9999}", pinned_vars={v: val},
758
+ free_vars=[u for u in problem.variables if u != v], source="projection",
759
+ confidence=0.72, derivation=f"Root of {mc.expr_str[:30]} β†’ {v}={val:.4f}"))
760
  except: pass
761
 
762
  bound_groups = defaultdict(list)
763
  for v in problem.variables: bound_groups[problem.bounds[v]].append(v)
764
  for bnd, grp in bound_groups.items():
765
  if len(grp) < 2: continue
766
+ avg = sum(b_mid[v] for v in grp) / len(grp)
767
+ lo, hi = bnd
768
  if lo <= avg <= hi:
769
  pinned = {v: avg for v in grp}
770
+ templates.append(HypothesisTemplate(
771
+ template_id=f"sym_avg_{'_'.join(grp[:3])}", pinned_vars=pinned,
772
+ free_vars=[u for u in problem.variables if u not in pinned], source="symmetry",
773
+ confidence=0.55, derivation=f"Symmetry orbit: {grp} averaged to {avg:.4f}"))
774
 
775
  seen = set(); unique = []
776
  for t in sorted(templates, key=lambda t: -t.confidence):
777
  key = str(sorted(t.pinned_vars.items()))
778
+ if key not in seen:
779
+ seen.add(key)
780
+ unique.append(t)
781
+
782
  return unique[:TEMPLATE_BATCH_SIZE]
783
 
784
  def templates_to_hypotheses(templates, problem, init_binding):
785
  hyps = []
786
  for t in templates:
787
+ binding = dict(init_binding)
788
+ binding.update(t.pinned_vars)
789
+ hyps.append(Hypothesis(
790
+ hid=t.template_id, binding=binding, h_type=t.source, claim=t.derivation,
791
+ derivation=[t.source], pinned_vars=t.pinned_vars, free_vars=t.free_vars, confidence=t.confidence))
792
  return hyps
793
 
794
  _ALL_AXIOMS_PLACEHOLDER: List[str] = []
 
798
  # ══════════════════════════════════════════════════════════════════════
799
  @dataclass
800
  class L9Certificate:
801
+ residual_ce: float
802
+ dominant_vars: List[str]
803
+ dominant_exprs: List[str]
804
+ tension_class: str = "unknown"
805
 
806
  def _batched_deduce_and_evaluate(problem: Problem, hyps: List['Hypothesis']) -> List[Tuple[Dict, float, List[str], str]]:
807
  if not hyps: return []
808
+ B = len(hyps)
809
+ V = len(problem.variables)
810
+
811
+ x_data = []
812
+ mask_data = []
813
+ target_data = []
814
+
815
  for hyp in hyps:
816
  xr, mr, tr = [], [], []
817
  for v in problem.variables:
818
+ if v in hyp.pinned_vars:
819
+ val = hyp.pinned_vars[v]
820
+ xr.append(val)
821
+ mr.append(0.0)
822
+ tr.append(val)
823
+ else:
824
+ val = hyp.binding.get(v, (problem.bounds[v][0] + problem.bounds[v][1]) / 2)
825
+ xr.append(val)
826
+ mr.append(1.0)
827
+ tr.append(0.0)
828
+ x_data.append(xr)
829
+ mask_data.append(mr)
830
+ target_data.append(tr)
831
 
832
  X = torch.tensor(x_data, device=DEVICE, dtype=torch.float32, requires_grad=True)
833
  mask = torch.tensor(mask_data, device=DEVICE, dtype=torch.float32)
 
841
  step_ratio = min(1.0, step / (DEDUCE_ADAM_STEPS * 0.8))
842
  ce = problem.tensor_energy(X, step_ratio)
843
 
844
+ if isinstance(ce, torch.Tensor) and (ce < SOLVE_THRESHOLD).all() and step_ratio == 1.0:
845
+ break
846
+
847
+ loss = ce.sum()
848
+ loss.backward()
849
 
850
  with torch.no_grad():
851
  X.grad.clamp_(-10.0, 10.0)
852
  X.grad *= mask
853
  optimizer.step()
854
  X.data = torch.where(mask == 0.0, target, X.data)
855
+
856
  for j, v in enumerate(problem.variables):
857
  lo, hi = problem.bounds[v]
858
  margin = (hi - lo) * 0.1 * (1.0 - step_ratio) # Exploratory bounds fade to 0
 
864
 
865
  ce_vals = final_ce.detach().cpu().numpy()
866
  X_vals = X.detach().cpu().numpy()
867
+ grads_abs = X.grad.abs()
868
+ _, topk_idx = torch.topk(grads_abs, k=min(3, V), dim=1)
869
+
870
+ topk_idx_np = topk_idx.cpu().numpy()
871
+ grads_np = grads_abs.cpu().numpy()
872
 
873
  results = []
874
  for i in range(B):
875
  final_b = {problem.variables[j]: float(X_vals[i, j]) for j in range(V)}
876
  dom_vars = [problem.variables[idx] for idx in topk_idx_np[i] if float(grads_np[i, idx]) > 1e-4]
877
+ n_dom = len(dom_vars)
878
+ tension_class = ("isolated" if n_dom <= 1 else "relational" if n_dom == 2 else "systemic")
879
  results.append((final_b, float(ce_vals[i]), dom_vars, tension_class))
880
+
881
  return results
882
 
883
  def _mprt_sample(problem, work_box, N):
884
+ var_list = problem.variables
885
+ V = len(var_list)
886
+
887
  lo_t = torch.tensor([max(problem.bounds.get(v, (-10.0, 10.0))[0], work_box[v].lo if v in work_box else problem.bounds.get(v, (-10, 10))[0]) for v in var_list], device=DEVICE, dtype=torch.float32)
888
  hi_t = torch.tensor([min(problem.bounds.get(v, (-10.0, 10.0))[1], work_box[v].hi if v in work_box else problem.bounds.get(v, (-10, 10))[1]) for v in var_list], device=DEVICE, dtype=torch.float32)
889
+
890
  for i in range(V):
891
+ if lo_t[i] >= hi_t[i]:
892
+ m = (lo_t[i] + hi_t[i]) / 2
893
+ lo_t[i] = m - 1e-6
894
+ hi_t[i] = m + 1e-6
895
+
896
  X = lo_t.unsqueeze(0) + (hi_t - lo_t).unsqueeze(0) * torch.rand((N, V), device=DEVICE)
897
  ce_batch = problem.tensor_energy(X, 1.0)
898
  best_idx = torch.argmin(ce_batch).item()
899
+
900
  return {v: float(X[best_idx, i].item()) for i, v in enumerate(var_list)}, ce_batch[best_idx].item()
901
 
902
  # ══════════════════════════════════════════════════════════════════════
 
915
  COMPOSITE="COMPOSITE"; HOLISM="HOLISM"; PARSIMONY="PARSIMONY"; DUALITY="DUALITY"
916
 
917
  ALL_AXIOMS = [getattr(Axiom, a) for a in dir(Axiom) if not a.startswith("__")]
918
+ AXIOM_ABBR = {a: a[:3] for a in ALL_AXIOMS}
919
+ AXIOM_ABBR[Axiom.MONOTONE_PRODUCT] = "MPR"
920
  _ALL_AXIOMS_PLACEHOLDER.extend(ALL_AXIOMS)
921
 
922
  ADJACENT_CONTRADICTIONS = [
 
941
 
942
  @dataclass
943
  class Hypothesis:
944
+ hid: str
945
+ binding: Dict[str, float]
946
+ h_type: str
947
+ claim: str
948
+ derivation: List[str]
949
+ pinned_vars: Dict[str, float]
950
+ free_vars: List[str]
951
+ confidence: float
952
+ ce: float = float('inf')
953
 
954
  @dataclass
955
  class Baton:
956
+ binding: Dict[str, float]
957
+ ce: float
958
+ ray_id: str = ""
959
+ depth: int = 0
960
+ l9: Optional[L9Certificate] = None
961
 
962
  @dataclass
963
  class AxiomRay:
964
+ sequence: List[str]
965
+ ray_id: str
966
+ ray_type: str = "seed"
967
+ depth: int = 0
968
+ parent_id: Optional[str] = None
969
+ baton: Optional[Baton] = None
970
+ ce_prior: float = float('inf')
971
+
972
  @property
973
+ def name(self) -> str:
974
+ return "β†’".join(AXIOM_ABBR.get(a, a[:3]) for a in self.sequence)
975
+
976
  def extend(self, axiom: str, rtype: str, new_prior: float = float('inf')) -> Optional['AxiomRay']:
977
  new_seq = self.sequence + [axiom]
978
  if sequence_valid(new_seq):
979
+ return AxiomRay(
980
+ sequence=new_seq,
981
+ ray_id=f"{self.ray_id}+{AXIOM_ABBR.get(axiom, '?')}",
982
+ ray_type=rtype,
983
+ depth=self.depth + 1,
984
+ parent_id=self.ray_id,
985
+ ce_prior=new_prior
986
+ )
987
  return None
988
 
989
  @dataclass
990
  class HypothesisTrace:
991
+ hid: str
992
+ round_idx: int
993
+ ray_name: str
994
+ ray_type: str
995
+ ce_before: float
996
+ ce_after: float
997
+ survived: bool
998
+ elapsed_ms: float
999
+ g1_pass: bool = False
1000
+ g2_pass: bool = False
1001
  binding: Dict[str, float] = field(default_factory=dict)
1002
  invariant_results: Dict[str, Tuple[float, bool]] = field(default_factory=dict)
1003
+ tension_class: str = "unknown"
1004
+ depth: int = 0
1005
 
1006
  @dataclass
1007
  class StructuralModel:
1008
+ best_binding: Dict[str, float]
1009
+ best_ce: float
1010
  best_ray: str = "β€”"
1011
  failure_patterns: Set[str] = field(default_factory=set)
1012
  resonant_pairs: List[Tuple[str, str]] = field(default_factory=list)
 
1018
  return Hypothesis(hid=hid, binding=binding, h_type=h_type, claim=claim,
1019
  derivation=derivation, pinned_vars=pinned, free_vars=free, confidence=conf)
1020
 
1021
+ def _hyp_continuous(p, bt, a, m):
1022
+ return [_make_hyp("cnt", bt.binding, "continuous", "Manifold", [], {}, p.variables, 0.45)]
1023
+
1024
  def _hyp_discrete(p, bt, a, m):
1025
+ b = dict(bt.binding)
1026
+ pinned = {}
1027
  for sn in p.scope_order:
1028
+ svars = p.scope_vars.get(sn, [])
1029
+ smcs = [p.compiled_constraints[i] for i in p.scope_groups.get(sn, [])]
1030
  if svars and smcs:
1031
  box = {v: IV(b.get(v, 0) - max(0.05 * (p.bounds[v][1] - p.bounds[v][0]), 1e-4),
1032
  b.get(v, 0) + max(0.05 * (p.bounds[v][1] - p.bounds[v][0]), 1e-4)) for v in svars if v in p.bounds}
 
1034
  if cont:
1035
  for v, iv in cont.items():
1036
  b[v] = iv.mid()
1037
+ if iv.width() < 1e-2:
1038
+ pinned[v] = b[v]
1039
  return [_make_hyp("dis", b, "discrete", "TopoScope", [], pinned, p.variables, 0.80)]
1040
 
1041
  def _hyp_quadratic(p, bt, a, m):
1042
+ hyps = []
1043
+ b = dict(bt.binding)
1044
  if bt.l9 and bt.l9.dominant_vars:
1045
+ for v in bt.l9.dominant_vars[:2]:
1046
+ hyps.append(_make_hyp(f"qua_{v}", b, "quadratic", f"Root({v})", [], {v: b[v]}, p.variables, 0.70))
1047
  return hyps
1048
 
1049
  def _hyp_bilinear(p, bt, a, m):
1050
+ hyps = []
1051
+ b = dict(bt.binding)
1052
  for vi, vj in p.bilinear_pairs:
1053
+ lo_i, hi_i = p.bounds.get(vi, (0, 10))
1054
+ lo_j, hi_j = p.bounds.get(vj, (0, 10))
1055
  product = abs(b.get(vi, 1) * b.get(vj, 1))
1056
+
1057
  if product <= 0: continue
1058
  gm = math.sqrt(product)
1059
+
1060
  if lo_i <= gm <= hi_i and lo_j <= gm <= hi_j:
1061
+ nb = dict(b)
1062
+ nb[vi] = nb[vj] = gm
1063
  hyps.append(_make_hyp(f"bil_eq_{vi}_{vj}", nb, "bilinear", f"GeoMean({vi}={vj}={gm:.3f})", ["bilinear"], {vi: gm, vj: gm}, [v for v in p.variables if v not in [vi, vj]], 0.70))
1064
+
1065
  for ratio in [0.4, 0.7071, 0.9]:
1066
+ vs = gm * ratio
1067
+ vl = product / (vs + 1e-9)
1068
  if lo_i <= vs <= hi_i and lo_j <= vl <= hi_j and vs < vl:
1069
+ nb2 = dict(b)
1070
+ nb2[vi] = vs
1071
+ nb2[vj] = vl
1072
  hyps.append(_make_hyp(f"bil_asc_{int(ratio*100)}_{vi}_{vj}", nb2, "bilinear", f"BilAsc({vi}={vs:.3f}<{vj}={vl:.3f})", ["bilinear"], {vi: vs, vj: vl}, [v for v in p.variables if v not in [vi, vj]], 0.75))
1073
  return hyps
1074
 
1075
  def _hyp_monotone_product(p, bt, a, m):
1076
+ hyps = []
1077
+ b = dict(bt.binding)
1078
  if not p.monotone_targets: return hyps
1079
  tb = _global_hc4_tighten_bounds(p)
1080
+
1081
  for v_small, v_large, k in p.monotone_targets:
1082
+ lo_s, hi_s = p.bounds.get(v_small, (-1e9, 1e9))
1083
+ lo_l, hi_l = p.bounds.get(v_large, (-1e9, 1e9))
1084
+
1085
  for ratio in [0.25, 0.5, 0.707, 0.9]:
1086
  vs_sq = k * ratio
1087
  if vs_sq <= 0: continue
1088
+ vs = math.sqrt(vs_sq)
1089
+ vl = k / vs
1090
  if not (lo_s <= vs <= hi_s and lo_l <= vl <= hi_l and vs <= vl): continue
1091
+
1092
+ nb = dict(b)
1093
+ nb[v_small] = vs
1094
+ nb[v_large] = vl
1095
  box = {u: IV(*tb.get(u, p.bounds.get(u, (-10, 10)))) for u in p.variables}
1096
+ box[v_small] = IV(vs - 1e-6, vs + 1e-6)
1097
+ box[v_large] = IV(vl - 1e-6, vl + 1e-6)
1098
  cont = _hc4(box, p.compiled_constraints)
1099
+
1100
  pinned = {v_small: vs, v_large: vl}
1101
  if cont:
1102
  for u, iv in cont.items():
1103
  if u in p.bounds: nb[u] = iv.mid()
1104
  pinned = {u: nb[u] for u in p.variables if cont[u].width() < 1e-2}
1105
+
1106
  hyps.append(_make_hyp(f"mpr_{v_small}_{v_large}_r{int(ratio*100)}", nb, "monotone_product", f"MonoProd({v_small}={vs:.4f}≀{v_large}={vl:.4f})", ["ordered", "hc4"], pinned, [u for u in p.variables if u not in pinned], 0.88))
1107
  return hyps
1108
 
1109
  def _hyp_metric(p, bt, a, m):
1110
+ hyps = []
1111
+ b = dict(bt.binding)
1112
  for mc in p.compiled_constraints:
1113
  if mc.kind != "equality" or not mc.parsed: continue
1114
  if not mc.parsed.is_Add: continue
1115
+
1116
  sq_terms = [t for t in mc.parsed.args if t.is_Pow and t.args[1] == 2]
1117
  if len(sq_terms) < 1: continue
1118
  vars_in = [str(s) for s in mc.parsed.free_symbols if str(s) in p.variables]
1119
  if not vars_in: continue
1120
+
1121
  const_terms = [float(t) for t in mc.parsed.args if t.is_Number]
1122
  if not const_terms: continue
1123
+
1124
  target = -const_terms[0]
1125
  if target <= 0: continue
1126
+
1127
  curr_val = sum(b.get(v, 0)**2 for v in vars_in)
1128
  if curr_val < 1e-8: continue
1129
+
1130
  scale = math.sqrt(target / curr_val)
1131
  nb = dict(b)
1132
  for v in vars_in:
1133
  lo, hi = p.bounds.get(v, (-10, 10))
1134
  nb[v] = max(lo, min(hi, b.get(v, 0) * scale))
1135
+
1136
  hyps.append(_make_hyp(f"met_{hash(mc.expr_str)%9999}", nb, "metric", f"RadialProject(scale={scale:.4f},dim={len(vars_in)})", ["metric", mc.expr_str], {}, list(p.variables), 0.75))
1137
  return hyps
1138
 
1139
  def _hyp_symmetric(p, bt, a, m):
1140
+ hyps = []
1141
+ b = dict(bt.binding)
1142
  groups_to_check = list(p.scope_vars.values()) if p.scope_vars else [p.variables]
1143
+ if not any(p.scope_vars.values()):
1144
+ groups_to_check = [p.variables]
1145
 
1146
  seen_pairs = set()
1147
  for grp in groups_to_check:
 
1152
  vi, vj = vl[i], vl[j]
1153
  if (vi, vj) in seen_pairs: continue
1154
  seen_pairs.add((vi, vj))
1155
+
1156
+ lo_i, hi_i = p.bounds.get(vi, (-1e9, 1e9))
1157
+ lo_j, hi_j = p.bounds.get(vj, (-1e9, 1e9))
1158
  bvi, bvj = b.get(vi, 0), b.get(vj, 0)
1159
+
1160
  if lo_i <= bvj <= hi_i and lo_j <= bvi <= hi_j:
1161
+ nb = dict(b)
1162
+ nb[vi], nb[vj] = bvj, bvi
1163
  hyps.append(_make_hyp(f"sym_{vi}_{vj}", nb, "symmetric", f"Swap({vi}↔{vj})", ["symmetric"], {vi: nb[vi], vj: nb[vj]}, [v for v in p.variables if v not in [vi, vj]], 0.60))
1164
+
1165
  avg = (bvi + bvj) / 2
1166
  if lo_i <= avg <= hi_i and lo_j <= avg <= hi_j:
1167
+ nb2 = dict(b)
1168
+ nb2[vi] = avg
1169
+ nb2[vj] = avg
1170
  hyps.append(_make_hyp(f"sym_avg_{vi}_{vj}", nb2, "symmetric", f"Average({vi}={vj}={avg:.4f})", ["symmetric"], {vi: avg, vj: avg}, [v for v in p.variables if v not in [vi, vj]], 0.55))
1171
  return hyps[:10]
1172
 
 
1177
  def _hyp_mutable(p, bt, a, m):
1178
  b = dict(bt.binding)
1179
  if bt.l9 and bt.l9.dominant_vars:
1180
+ v = bt.l9.dominant_vars[0]
1181
+ lo, hi = p.bounds.get(v, (-10, 10))
1182
  b[v] = max(lo, min(hi, b.get(v, 0) + random.gauss(0, (hi - lo) * 0.05)))
1183
  return [_make_hyp("mut", b, "mutable", "Perturb", [], {}, p.variables, 0.40)]
1184
  def _hyp_network(p, bt, a, m): return [_make_hyp("net", bt.binding, "network", "HubProp", [], {}, p.variables, 0.65)]
1185
  def _hyp_equilibrium(p, bt, a, m): return [_make_hyp("eql", bt.binding, "equilibrium", "GradBal", [], {}, p.variables, 0.72)]
1186
  def _hyp_superposition(p, bt, a, m):
1187
  if a and len(a) > 0:
1188
+ other = random.choice(a)
1189
+ lam = 0.5
1190
  nb = {v: lam * bt.binding.get(v, 0) + (1 - lam) * other.binding.get(v, 0) for v in p.variables}
1191
  return [_make_hyp("sup", nb, "superposition", "Superpose", [], {}, p.variables, 0.58)]
1192
  return []
1193
  def _hyp_locality(p, bt, a, m): return [_make_hyp("loc", bt.binding, "locality", "LocalFirst", [], {}, p.variables, 0.72)]
1194
  def _hyp_extremal(p, bt, a, m):
1195
+ hyps = []
1196
+ b = dict(bt.binding)
1197
  if bt.l9 and bt.l9.dominant_vars:
1198
+ v = bt.l9.dominant_vars[0]
1199
+ lo, hi = p.bounds.get(v, (0, 1))
1200
  for val in [lo, hi, (lo + hi) / 2]:
1201
+ nb = dict(b)
1202
+ nb[v] = val
1203
  hyps.append(_make_hyp(f"ext_{v}_{val:.3f}", nb, "extremal", f"PinBound({v}={val:.3f})", [], {v: val}, p.variables, 0.65))
1204
  return hyps
1205
  def _hyp_entropy(p, bt, a, m): return [_make_hyp("ent", {v: random.uniform(*p.bounds[v]) for v in p.variables}, "entropy", "MaxEnt", [], {}, p.variables, 0.48)]
 
1207
  def _hyp_surjective(p, bt, a, m): return [_make_hyp("sur", bt.binding, "surjective", "Sweep", [], {}, p.variables, 0.45)]
1208
  def _hyp_transitive(p, bt, a, m): return [_make_hyp("tra", bt.binding, "transitive", "TransSnap", [], {}, p.variables, 0.77)]
1209
  def _hyp_atomic(p, bt, a, m):
1210
+ hyps = []
1211
+ b = dict(bt.binding)
1212
  for mc in p.compiled_constraints:
1213
  if not mc.projections: continue
1214
  for v, projs in mc.projections.items():
 
1217
  val = float(proj["func"](*[b.get(s, 0.0) for s in proj["syms"]]))
1218
  lo, hi = p.bounds.get(v, (-1e9, 1e9))
1219
  if math.isfinite(val) and lo <= val <= hi:
1220
+ nb = dict(b)
1221
+ nb[v] = val
1222
  hyps.append(_make_hyp(f"ato_{v}", nb, "atomic", f"Solve({v})", [], {v: val}, p.variables, 0.70))
1223
  break
1224
  except: pass
 
1231
  def _hyp_composite(p, bt, a, m): return [_make_hyp("cmp", bt.binding, "composite", "Enz", [], {}, p.variables, 0.90)]
1232
  def _hyp_holism(p, bt, a, m): return [_make_hyp("hol", bt.binding, "holism", "Global", [], {}, p.variables, 0.73)]
1233
  def _hyp_parsimony(p, bt, a, m):
1234
+ b = dict(bt.binding)
1235
+ nb = {}
1236
  max_val = max((abs(v) for v in b.values()), default=1.0)
1237
  for v in p.variables:
1238
+ val = b[v]
1239
+ lo, hi = p.bounds[v]
1240
+ if abs(val) < 0.1 * max_val and lo <= 0.0 <= hi:
1241
+ nb[v] = 0.0
1242
  else:
1243
  candidates = [round(val * m) / m for m in [1, 2, 4] if lo <= round(val * m) / m <= hi]
1244
  nb[v] = min(candidates, key=lambda c: abs(c - val)) if candidates else val
 
1292
  scored = []
1293
  for ax in remaining_axioms:
1294
  w_allos = 1.0
1295
+ if n_dom == 1 and ax in isolated:
1296
+ w_allos += 5.0
1297
+ elif n_dom == 2 and ax in relational:
1298
+ w_allos += 5.0
1299
+ elif n_dom >= 3 and ax in systemic:
1300
+ w_allos += 5.0
1301
+
1302
  w_sketch = sketch.axiom_affinities.get(ax, 1.0) if sketch else 1.0
1303
  scored.append((w_allos * w_sketch, ax))
1304
 
 
1306
  children = []
1307
  for _, axiom in scored[:effective_width]:
1308
  child = ray.extend(axiom, "branch", new_prior=out_baton.ce)
1309
+ if child:
1310
+ child.baton = out_baton
1311
+ children.append(child)
1312
  return children
1313
 
1314
  def sketch_weighted_seeds(self, sketch: StructuralSketch, init_ce: float) -> List[AxiomRay]:
 
1327
  if b2 in (a, b1, mid, c): continue
1328
  if frozenset([mid, b2]) not in _CONTRA_SET and frozenset([b2, c]) not in _CONTRA_SET:
1329
  results.append(AxiomRay([a, b1, mid, b2, c], f"T5_{AXIOM_ABBR.get(a, '?')}_{AXIOM_ABBR.get(c, '?')}", "tension"))
1330
+ random.shuffle(results)
1331
+ return results[:max_n]
1332
 
1333
  def random_scouts(self, n: int = 600) -> List[AxiomRay]:
1334
+ scouts = []
1335
+ attempts = 0
1336
  while len(scouts) < n and attempts < n * 30:
1337
+ attempts += 1
1338
+ length = random.randint(3, 12)
1339
+ pool = list(ALL_AXIOMS)
1340
+ random.shuffle(pool)
1341
+ seq = [pool[0]]
1342
  for ax in pool[1:]:
1343
  if len(seq) >= length: break
1344
+ if ax != seq[-1] and frozenset([seq[-1], ax]) not in _CONTRA_SET:
1345
+ seq.append(ax)
1346
+ if len(seq) >= 3:
1347
+ scouts.append(AxiomRay(seq, f"SC_{''.join(AXIOM_ABBR.get(a, a[:2]) for a in seq)}", "scout"))
1348
  return scouts
1349
 
1350
  def recombine(self, ray_a, ray_b, ba, bb) -> List[AxiomRay]:
 
1356
  cut = min(len(ray_a.sequence), len(ray_b.sequence)) // 2
1357
  if cut > 0:
1358
  seq = ray_a.sequence[:cut] + [x for x in ray_b.sequence[cut:] if x not in ray_a.sequence[:cut]]
1359
+ if sequence_valid(seq):
1360
+ results.append(AxiomRay(seq, f"RC_l{int(lam*100)}", "recombine", baton=ib_baton, ce_prior=ib_ce))
1361
  return results
1362
 
1363
  def invert(self, ray, parent_ce) -> Optional[AxiomRay]:
1364
  inv = list(reversed(ray.sequence))
1365
+ if sequence_valid(inv) and inv != ray.sequence:
1366
+ return AxiomRay(inv, f"INV_{ray.ray_id}", "invert", parent_id=ray.ray_id, ce_prior=parent_ce)
1367
  return None
1368
 
1369
  def resonance_extensions(self, ray, parent_ce, resonant_pairs) -> List[AxiomRay]:
1370
  if not ray.sequence or not resonant_pairs: return []
1371
+ last = ray.sequence[-1]
1372
+ results = []
1373
  nexts = [b for (a, b) in resonant_pairs if a == last and b != last and frozenset([a, b]) not in _CONTRA_SET and b not in ray.sequence]
1374
  for b in nexts:
1375
  child = ray.extend(b, "branch", new_prior=parent_ce)
1376
+ if child:
1377
+ child.ray_id = f"RES_{child.ray_id}"
1378
+ results.append(child)
1379
  return results
1380
 
1381
  CREATIVE_SEEDER = CreativeSeeder()
 
1389
  g2 = {}
1390
  for inv in anchors:
1391
  try:
1392
+ if inv.compiled_func:
1393
+ val = float(inv.compiled_func(*[binding.get(v, 0.0) for v in inv.syms_used]))
1394
+ else:
1395
+ val = 999.0
1396
+
1397
  err = abs(val)
1398
+ if inv.mode == "eq":
1399
+ passed = err < inv.tolerance
1400
+ elif inv.mode == "geq":
1401
+ passed = val >= -inv.tolerance
1402
+ elif inv.mode == "leq":
1403
+ passed = val <= inv.tolerance
1404
+ else:
1405
+ passed = err < inv.tolerance
1406
+
1407
  g2[inv.name] = (round(val if inv.mode in ("geq", "leq") else err, 6), passed)
1408
+ except:
1409
+ g2[inv.name] = (999.0, False)
1410
+
1411
  g2_pass = all(v[1] for v in g2.values()) if g2 else True
1412
  return g1_pass, g2_pass, g2, round(g1_ce, 6)
1413
 
 
1418
 
1419
  def trace(self, axl_def: AXLProblemDef, base_problem: Problem):
1420
  hero_traces: List[HypothesisTrace] = []
1421
+ baton_registry: Dict[str, Baton] = {}
1422
+ baton_registry_keys: deque = deque()
1423
+ successful_rays: List[AxiomRay] = []
1424
+ resonant_pairs: List[Tuple[str, str]] = []
1425
 
1426
  for inv in axl_def.anchors:
1427
+ if not inv.compiled_func:
1428
+ inv.compile(base_problem.variables)
1429
 
1430
+ _update_state(phase="SKETCHING")
1431
+ _add_log("πŸ—Ί Computing structural sketch…")
1432
  sketch = compute_sketch(base_problem)
1433
  _update_state(sketch_summary="; ".join(sketch.sketch_notes[:4]), sympy_derivation=sketch.sympy_derivation)
1434
  _add_log(f"βœ“ Sketch: {sketch.dominant_type} system, DOF={sketch.n_free_dof}")
1435
 
1436
+ _update_state(phase="TEMPLATING")
1437
+ _add_log("πŸ”¬ Generating hypothesis templates…")
1438
  templates = generate_templates(base_problem, sketch)
1439
  _update_state(template_count=len(templates))
1440
 
1441
  init_b, init_ce = _mprt_sample(base_problem, {v: IV(*base_problem.bounds[v]) for v in base_problem.variables}, N_MPRT_EXPLORE)
1442
  seed_baton = Baton(binding=init_b, ce=init_ce, ray_id="SEED", l9=L9Certificate(init_ce, base_problem.variables[:3], [], "systemic"))
1443
 
1444
+ best_ce = init_ce
1445
+ best_binding = dict(init_b)
1446
+
1447
  if templates:
1448
  _add_log("βš— Evaluating templates (Phase 0 batch)…")
1449
  template_hyps = templates_to_hypotheses(templates, base_problem, init_b)
1450
  t_results = _batched_deduce_and_evaluate(base_problem, template_hyps)
1451
+
1452
  for (th, template), (final_b, final_ce, dom_vars, tc) in zip(zip(template_hyps, templates), t_results):
1453
  g1p, g2p, inv_res, g1ce = _verify(final_b, base_problem, axl_def.anchors)
1454
  overall = g1p and g2p
1455
+
1456
  if overall or final_ce < best_ce:
1457
  hero_traces.append(HypothesisTrace(
1458
  hid=template.template_id, round_idx=0, ray_name=f"template:{template.source}", ray_type="template",
1459
  ce_before=init_ce, ce_after=final_ce, survived=overall, elapsed_ms=0.0,
1460
  g1_pass=g1p, g2_pass=g2p, binding={k: round(v, 5) for k, v in final_b.items()},
1461
  invariant_results=inv_res, tension_class=tc, depth=0))
1462
+
1463
+ with STATE_LOCK:
1464
+ GLOBAL_SOLVE_STATE["recent_traces"].append(hero_traces[-1])
1465
+
1466
  if final_ce < best_ce:
1467
+ best_ce = final_ce
1468
+ best_binding = dict(final_b)
1469
  _update_state(best_ce=best_ce)
1470
+
1471
  if overall:
1472
  _add_log(f"βœ“ Template solved at Phase 0! Source: {template.source}")
1473
  _update_state(best_ce=best_ce, template_best_ce=best_ce, best_ray=f"template:{template.source}")
1474
  return best_binding, best_ce, hero_traces, 0, {"isolated": 0, "relational": 0, "systemic": 0}
1475
+
1476
  _update_state(template_best_ce=best_ce)
1477
 
1478
  _update_state(phase="SEARCHING")
1479
  seed_rays = CREATIVE_SEEDER.sketch_weighted_seeds(sketch, best_ce)
1480
 
1481
+ queues = {
1482
+ "core": seed_rays,
1483
+ "explore": CREATIVE_SEEDER.tension_seeds(3000) + CREATIVE_SEEDER.random_scouts(600),
1484
+ "genetic": CREATIVE_SEEDER.target_seeds(axl_def.anchors)
1485
+ }
1486
+ random.shuffle(queues["explore"])
1487
+ random.shuffle(queues["genetic"])
1488
+
1489
+ queue_order = ["core", "explore", "genetic"]
1490
+ q_idx = 0
1491
+ total_fired = 0
1492
  allosteric_counts = {"isolated": 0, "relational": 0, "systemic": 0}
1493
  model = StructuralModel(best_binding, best_ce)
1494
  seed_baton = Baton(binding=best_binding, ce=best_ce, ray_id="SEED", l9=L9Certificate(best_ce, base_problem.variables[:3], [], "systemic"))
 
1501
  q_idx = (q_idx + 1) % 3
1502
  if q_idx == start_idx: break
1503
  if not any(queues[k] for k in queue_order): break
1504
+ ray = queues[queue_order[q_idx]].pop(0)
1505
+ q_idx = (q_idx + 1) % 3
1506
+ batch_rays.append(ray)
1507
+ total_fired += 1
1508
+
1509
  if not batch_rays: break
1510
 
1511
  t0 = time.time()
1512
  historical_batons = list(baton_registry.values())
1513
  batch_hyps: List[Tuple[int, Hypothesis]] = []
1514
+
1515
  for i, ray in enumerate(batch_rays):
1516
  p_baton = ray.baton or seed_baton
1517
  constructor = AXIOM_CONSTRUCTORS.get(ray.sequence[-1])
1518
  hyps = constructor(base_problem, p_baton, historical_batons, model) if constructor else []
1519
+ if not hyps:
1520
+ hyps = [_make_hyp("fb", p_baton.binding, "fallback", "Pass", [], {}, base_problem.variables, 0.1)]
1521
  batch_hyps.append((i, hyps[0]))
1522
 
1523
  eval_results = _batched_deduce_and_evaluate(base_problem, [h for _, h in batch_hyps])
1524
  elapsed_ms = (time.time() - t0) * 1000 / max(1, len(batch_rays))
1525
 
1526
+ solved = False
1527
+ batch_heroes = []
1528
+
1529
  for (ray_idx, hyp), (final_b, final_ce, dom_vars, tension_class) in zip(batch_hyps, eval_results):
1530
  ray = batch_rays[ray_idx]
1531
  parent_ce = (ray.baton or seed_baton).ce
1532
  allosteric_counts[tension_class] = allosteric_counts.get(tension_class, 0) + 1
1533
 
1534
  g1_pass, g2_pass, inv_results, g1_ce = _verify(final_b, base_problem, axl_def.anchors)
1535
+ overall_pass = g1_pass and g2_pass
1536
+ improved = final_ce < best_ce
1537
 
1538
  if improved or overall_pass or random.random() < 0.002:
1539
  trace = HypothesisTrace(
 
1547
  out_baton = Baton(binding=final_b, ce=final_ce, ray_id=ray.ray_id, l9=L9Certificate(final_ce, dom_vars, [], tension_class))
1548
 
1549
  if final_ce < BATON_REGISTRY_THRESHOLD:
1550
+ if ray.ray_id in baton_registry:
1551
+ baton_registry[ray.ray_id] = out_baton
1552
  else:
1553
  if len(baton_registry) >= BATON_REGISTRY_MAX:
1554
+ old_key = baton_registry_keys.popleft()
1555
+ baton_registry.pop(old_key, None)
1556
+ baton_registry[ray.ray_id] = out_baton
1557
+ baton_registry_keys.append(ray.ray_id)
1558
 
1559
  if improved:
1560
+ best_ce = final_ce
1561
+ best_binding = dict(final_b)
1562
+ successful_rays.append(ray)
1563
+ model.best_binding = best_binding
1564
+ model.best_ce = best_ce
1565
+ model.best_ray = ray.name
1566
 
1567
+ if overall_pass:
1568
+ solved = True
1569
 
1570
  if improved and len(ray.sequence) >= 2:
1571
  pair = (ray.sequence[-2], ray.sequence[-1])
1572
+ if pair not in resonant_pairs:
1573
+ resonant_pairs.append(pair)
1574
  model.resonant_pairs = resonant_pairs
1575
 
1576
  earned = (final_ce < parent_ce * CE_EARN_RATIO or ray.depth < 1)
 
1580
  remaining = [a for a in ALL_AXIOMS if a != ray.sequence[-1] and frozenset([ray.sequence[-1], a]) not in _CONTRA_SET and a not in ray.sequence]
1581
  new_children = []
1582
  new_children.extend(CREATIVE_SEEDER.intelligent_branch(ray, out_baton, remaining, BRANCH_WIDTH, sketch=sketch))
1583
+
1584
  inv = CREATIVE_SEEDER.invert(ray, final_ce)
1585
+ if inv:
1586
+ new_children.append(inv)
1587
+
1588
  if len(successful_rays) >= 2:
1589
  candidates = [r for r in successful_rays if r.ray_id != ray.ray_id]
1590
  if candidates:
1591
+ partner = random.choice(candidates)
1592
+ ba = baton_registry.get(ray.ray_id, out_baton)
1593
+ bb = baton_registry.get(partner.ray_id)
1594
+ if bb is not None:
1595
+ new_children.extend(CREATIVE_SEEDER.recombine(ray, partner, ba, bb)[:3])
1596
+
1597
  new_children.extend(CREATIVE_SEEDER.resonance_extensions(ray, final_ce, resonant_pairs))
1598
+
1599
  for child in new_children:
1600
+ if child.ray_type in ("seed", "branch", "target"):
1601
+ queues["core"].append(child)
1602
+ elif child.ray_type in ("scout", "tension"):
1603
+ queues["explore"].append(child)
1604
+ elif child.ray_type in ("recombine", "invert"):
1605
+ queues["genetic"].append(child)
1606
 
1607
  queues["core"].sort(key=lambda r: r.ce_prior + (r.depth * 0.0001))
1608
  queues["genetic"].sort(key=lambda r: r.ce_prior + (r.depth * 0.0001))
1609
 
1610
  with STATE_LOCK:
1611
+ GLOBAL_SOLVE_STATE["best_ce"] = best_ce
1612
+ GLOBAL_SOLVE_STATE["total_fired"] = total_fired
1613
+ GLOBAL_SOLVE_STATE["best_ray"] = model.best_ray
1614
+ for t in batch_heroes:
1615
+ GLOBAL_SOLVE_STATE["recent_traces"].append(t)
1616
 
1617
  if solved: break
1618
 
 
1656
  resp = client.models.generate_content(model=GEMINI_MODEL, contents=[types.Content(role="user", parts=[types.Part.from_text(text=problem_text)])], config=config)
1657
 
1658
  text = resp.text.strip()
1659
+ if text.startswith("```"):
1660
+ text = text.split("```")[1]
1661
+ if text.startswith("json"):
1662
+ text = text[4:]
1663
+
1664
  text = text.strip().rstrip("`").strip()
1665
  d = json.loads(text)
1666
 
1667
  anchors = [AXLInvariant(name=a["name"], expr=a["expr"], tolerance=a.get("tolerance", VERIFY_G2_TOLERANCE), mode=a.get("mode", "eq")) for a in d.get("anchors", [])]
1668
  variables = [{"name": v["name"], "lo": float(v.get("lo", -1000.0)), "hi": float(v.get("hi", 1000.0))} for v in d["variables"]]
1669
+
1670
  return AXLProblemDef(name=d["name"], description=d.get("description", ""), axioms=set(), variables=variables, constraints=d.get("constraints", []), scopes=d.get("scopes", []), anchors=anchors, observations=d.get("observations", {}))
1671
 
1672
  def collapse_solution(problem_text, axl_def, psl_text, binding, g1_pass, g2_pass, inv_results, best_ray, total_fired, sketch_notes, sympy_derivation, api_key) -> str:
1673
  if not api_key: return "ERROR: API Key required."
1674
  client = genai.Client(api_key=api_key)
1675
+
1676
+ payload = {
1677
+ "original_problem": problem_text,
1678
+ "solved": g1_pass and g2_pass,
1679
+ "binding": {k: round(v, 6) for k, v in binding.items()},
1680
+ "psl_program_text": psl_text,
1681
+ "isomorphism_hypothesis": best_ray,
1682
+ "structural_sketch_notes": sketch_notes,
1683
+ "sympy_derivation_chain": sympy_derivation,
1684
+ "invariant_results": inv_results
1685
+ }
1686
+
1687
  config = types.GenerateContentConfig(thinking_config=types.ThinkingConfig(thinking_level="HIGH"), system_instruction=[types.Part.from_text(text=COLLAPSER_SYSTEM_PROMPT)], temperature=0.2)
1688
  resp = client.models.generate_content(model=GEMINI_MODEL, contents=[types.Content(role="user", parts=[types.Part.from_text(text=json.dumps(payload, indent=2))])], config=config)
1689
  return resp.text
1690
 
1691
  # ══════════════════════════════════════════════════════════════════════
1692
+ # SECTION 15: GLOBAL SOLVE TASK (With Thread Crash Safety)
1693
  # ══════════════════════════════════════════════════════════════════════
1694
  def global_solve_task(original_problem_text, api_key, prebuilt_axl=None):
1695
+ _update_state(
1696
+ is_running=True, phase="ENCODING", high_level_logs=[], answer="",
1697
+ best_ce=float('inf'), total_fired=0, best_ray="β€”", recent_traces=deque(maxlen=25),
1698
+ sketch_summary="", template_count=0, template_best_ce=float('inf'), sympy_derivation=[]
1699
+ )
1700
+
1701
+ try:
1702
+ MAX_ATTEMPTS = 3
1703
+ current_text = original_problem_text
1704
+ used_key = api_key or DEFAULT_GEMINI_API_KEY
1705
+ sketch_notes = []
1706
+
1707
+ for attempt in range(1, MAX_ATTEMPTS + 1):
1708
+ if prebuilt_axl is not None:
1709
+ _add_log("⚑ Bypassing Encoder: Using Pre-compiled Quantum AXL")
1710
+ axl_def = prebuilt_axl
1711
+ else:
1712
+ _add_log(f"πŸ” Encoding (attempt {attempt}/{MAX_ATTEMPTS})…")
1713
+ try:
1714
+ axl_def = encode_problem_to_axl(current_text, used_key)
1715
+ except Exception as e:
1716
+ _add_log(f"βœ— Encode failed: {e}")
1717
+ _update_state(phase="ERROR", answer=f"Encoder API Failed: {str(e)}")
1718
+ return
1719
+
1720
+ _add_log(f"βœ“ `{axl_def.name}` | vars: {', '.join(v['name'] for v in axl_def.variables)}")
1721
+ _update_state(phase="COMPILING")
1722
+
1723
+ try:
1724
+ psl_text = AXL_COMPILER.compile(axl_def)
1725
+ base_prob = build_base_problem(axl_def)
1726
+ except Exception as e:
1727
+ _add_log(f"βœ— Compile failed: {e}")
1728
+ _update_state(phase="ERROR", answer=f"Compiler Failed: {str(e)}")
1729
+ return
1730
+
1731
+ try:
1732
+ tracer = SequenceRayTracer()
1733
+ binding, ce, traces, total_fired, allosteric = tracer.trace(axl_def, base_prob)
1734
+ except Exception as e:
1735
+ _add_log(f"βœ— Solver error: {e}")
1736
+ _update_state(phase="ERROR", answer=f"Ray Tracer Crashed: {str(e)}")
1737
+ return
1738
+
1739
+ with STATE_LOCK:
1740
+ sketch_notes = GLOBAL_SOLVE_STATE.get("sketch_summary", "").split("; ")
1741
+ current_sympy_derivation = GLOBAL_SOLVE_STATE.get("sympy_derivation", [])
1742
+
1743
+ survived = [t for t in traces if t.survived]
1744
+ best_t = min(survived, key=lambda t: t.ce_after, default=None)
1745
+
1746
+ for inv in axl_def.anchors:
1747
+ if not inv.compiled_func:
1748
+ inv.compile(base_prob.variables)
1749
+
1750
+ g1_ce = base_prob.scalar_energy(binding)
1751
+ g1_pass = g1_ce < VERIFY_G1_THRESHOLD
1752
+ inv_results = {}
1753
+
1754
+ for inv in axl_def.anchors:
1755
+ try:
1756
+ val = float(inv.compiled_func(*[binding.get(v, 0.0) for v in inv.syms_used]))
1757
+ err = abs(val)
1758
+ if inv.mode == "eq":
1759
+ passed = err < inv.tolerance
1760
+ elif inv.mode == "geq":
1761
+ passed = val >= -inv.tolerance
1762
+ else:
1763
+ passed = val <= inv.tolerance
1764
+ inv_results[inv.name] = (round(val, 6), passed)
1765
+ except:
1766
+ inv_results[inv.name] = (999.0, False)
1767
+
1768
+ g2_pass = all(v[1] for v in inv_results.values())
1769
+
1770
+ solved_str = "βœ“ SOLVED" if (g1_pass and g2_pass) else "~ PARTIAL" if g1_pass else "βœ— UNSOLVED"
1771
+ best_ray = best_t.ray_name if best_t else "β€”"
1772
+ _add_log(f"🏁 {solved_str} (CE: {ce:.5f}) | Ray: {best_ray}")
1773
+
1774
+ if prebuilt_axl is None:
1775
+ if not g1_pass and attempt < MAX_ATTEMPTS:
1776
+ current_text = (original_problem_text + f"\n\nPREVIOUS ATTEMPT FAILED (Best CE: {ce}):\nGEOMETRIC SOLVER FAILED. Apply ALGEBRAIC REDUCTION: substitute simple equalities to eliminate variables, output simplified AXL.")
1777
+ _add_log("⚠ Geometric solver failed. Triggering algebraic reduction…")
1778
+ continue
1779
+ if not g2_pass and attempt < MAX_ATTEMPTS:
1780
+ failed = {k: v for k, (v, ok) in inv_results.items() if not ok}
1781
+ current_text = (original_problem_text + f"\n\nPREVIOUS ATTEMPT FAILED:\nGate 2 failed:\n{json.dumps(failed, indent=2)}\nRevise constraint encoding to capture these conditions.")
1782
+ _add_log("⚠ Gate 2 failed. Retrying with structural feedback…")
1783
+ continue
1784
+
1785
+ _add_log("πŸ”€ Collapsing isomorphism to domain language…")
1786
+ _update_state(phase="COLLAPSING")
1787
  try:
1788
+ answer = collapse_solution(original_problem_text, axl_def, psl_text, binding, g1_pass, g2_pass, inv_results, best_ray, total_fired, sketch_notes, current_sympy_derivation, used_key)
1789
+ _update_state(answer=answer, phase="DONE")
1790
+ _add_log("βœ“ Done.")
1791
+ except Exception as e:
1792
+ _update_state(answer=f"Collapsing error: {e}", phase="ERROR")
1793
+ _add_log("βœ— Collapse failed.")
1794
+ break
1795
+
1796
+ except Exception as e:
1797
+ _add_log(f"πŸ’₯ FATAL SYSTEM ERROR: {str(e)}")
1798
+ _update_state(phase="ERROR", answer=f"Fatal System Error: {str(e)}")
1799
+ finally:
1800
+ # ABSOLUTE GUARANTEE: Never lock the UI
1801
+ _update_state(is_running=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
1802
 
1803
  def trigger_solve(problem_text, api_key):
1804
  if GLOBAL_SOLVE_STATE["is_running"] or not problem_text.strip(): return
 
1806
 
1807
  def trigger_quantum_solve(example_name, api_key):
1808
  if not HAS_QUANTUM or GLOBAL_SOLVE_STATE["is_running"]: return
 
1809
 
1810
+ # We yield control to the thread immediately so the button click finishes safely
1811
+ def _run_q():
1812
+ if example_name == "Bell State":
1813
+ circ = QuantumCircuits.example_bell_state()
1814
+ elif example_name == "VQE H2":
1815
+ circ = QuantumCircuits.example_vqe_h2()
1816
+ elif example_name == "QAOA MaxCut":
1817
+ circ = QuantumCircuits.example_qaoa_maxcut_p1()
1818
+ else:
1819
+ return
1820
+
1821
+ problem_desc = f"Quantum Circuit: {circ.name}\nDescription: {circ.description}\nTarget Observables: {circ.expected_observables}"
1822
+
1823
+ try:
1824
+ axl_def = QuantumCircuits.build_quantum_axl(circ, AXLProblemDef, AXLInvariant)
1825
+ except Exception as e:
1826
+ _update_state(is_running=False, phase="ERROR", answer=f"Quantum compiler failed: {str(e)}")
1827
+ return
1828
+
1829
+ global_solve_task(problem_desc, api_key, axl_def)
1830
 
1831
+ threading.Thread(target=_run_q, daemon=True).start()
1832
 
1833
  # ══════════════════════════════════════════════════════════════════════
1834
  # SECTION 16: GRADIO INTERFACE
1835
  # ══════════════════════════════════════════════════════════════════════
1836
+ # Layout fixes for mobile sizing and wrapping
1837
+ CSS = """
1838
+ body { background: #090909; color: #e0e0e0; font-family: monospace; }
1839
+ .solver-log { font-size: 0.75em; background: #0d0d0d; border: 1px solid #181818; }
1840
+ .answer-box { font-size: 0.85em; background: #0d0d0d; border: 1px solid #222; padding: 10px; }
1841
+ .wrap-row { flex-wrap: wrap !important; }
1842
+ """
1843
+
1844
+ RAY_ICONS = {
1845
+ "seed": "🌱", "branch": "🌿", "tension": "⚑", "scout": "πŸ”­",
1846
+ "recombine": "🧬", "invert": "πŸ”„", "target": "🎯", "template": "πŸ—Ί", "fallback": "Β·"
1847
+ }
1848
 
 
1849
  PLACEHOLDER_HINT = textwrap.dedent("""
1850
  Try any natural language problem. Gemini encodes it, the system finds the structural solution.
1851
  Examples:
 
1855
 
1856
  def build_live_html():
1857
  with STATE_LOCK:
1858
+ phase = GLOBAL_SOLVE_STATE["phase"]
1859
+ ce = GLOBAL_SOLVE_STATE["best_ce"]
1860
+ fired = GLOBAL_SOLVE_STATE["total_fired"]
1861
+ best_ray = GLOBAL_SOLVE_STATE["best_ray"]
1862
+ traces = list(GLOBAL_SOLVE_STATE["recent_traces"])
1863
+ logs = GLOBAL_SOLVE_STATE["high_level_logs"]
1864
  sketch_summary = GLOBAL_SOLVE_STATE["sketch_summary"]
1865
+ template_count = GLOBAL_SOLVE_STATE["template_count"]
1866
+ template_best = GLOBAL_SOLVE_STATE["template_best_ce"]
1867
 
1868
  ce_color = "#4CAF50" if ce < SOLVE_THRESHOLD else "#FF9800"
1869
+
1870
+ if phase in ["SEARCHING", "COLLAPSING", "ENCODING", "SKETCHING", "TEMPLATING"]:
1871
+ phase_color = "#26C6DA"
1872
+ elif phase == "DONE":
1873
+ phase_color = "#4CAF50"
1874
+ elif phase == "ERROR":
1875
+ phase_color = "#F44336"
1876
+ else:
1877
+ phase_color = "#888"
1878
 
1879
  log_html = "<ul style='margin:0;padding-left:20px;color:#aaa;font-size:0.82em'>"
1880
+ for l in logs[-5:]:
1881
+ log_html += f"<li>{l}</li>"
1882
  log_html += "</ul>"
1883
 
1884
+ sketch_html = ""
1885
+ if sketch_summary:
1886
+ sketch_html = f"<div style='color:#555;font-size:0.72em;margin:6px 0;padding:4px 8px;border-left:2px solid #26C6DA;background:#0a0a0a'>πŸ—Ί <span style='color:#26C6DA'>Sketch</span>: {sketch_summary[:120]}</div>"
1887
+
1888
+ template_html = ""
1889
+ if template_count > 0:
1890
+ t_ce_str = f"{template_best:.5f}" if template_best < float('inf') else "β€”"
1891
+ template_html = f"<div style='color:#555;font-size:0.72em;margin:4px 0'>πŸ—Ί Templates: {template_count} generated | floor CE: {t_ce_str}</div>"
1892
 
1893
  ray_trail = ""
1894
  for t in reversed(traces):
1895
+ icon = RAY_ICONS.get(t.ray_type, "Β·")
1896
+ c = "#4CAF50" if t.survived else "#555"
1897
+ star = " β—€" if t.survived else ""
1898
  ray_trail += f"<div style='color:{c};font-size:0.78em;margin-bottom:2px'>{icon} [{t.ray_name}] CE={t.ce_after:.4f} <span style='color:#888'>({t.tension_class[:3]})</span><span style='color:#4CAF50;font-weight:700'>{star}</span></div>"
1899
 
1900
+ return f"""
1901
+ <div style='border:1px solid #222;border-radius:6px;padding:12px;background:#0d0d0d;min-height:440px;display:flex;flex-direction:column'>
1902
  <div style='color:{phase_color};font-weight:bold;margin-bottom:8px'>● Phase: {phase}</div>
1903
  <div style='margin-bottom:10px;border-bottom:1px solid #222;padding-bottom:8px'>{log_html}</div>
1904
  {sketch_html}{template_html}
 
1908
  </div>
1909
  <div style='color:#aaa;margin-bottom:8px;font-size:0.85em'>Best Iso: <span style='color:#FF9800'>{best_ray}</span></div>
1910
  <div style='flex:1;overflow-y:auto;border-top:1px solid #222;padding-top:8px'>{ray_trail}</div>
1911
+ </div>
1912
+ """
1913
 
1914
  with gr.Blocks(css=CSS, title="Practicality 24.1") as demo:
1915
  gr.Markdown("## βš— Practicality 24.1 β€” Structural Sketch, World Model Prior & Quantum Engine\n`[Gemini Encoder] β†’ [Structural Sketch / SymPy] β†’ [Morphing Ray Solver] β†’ [Gemini Collapser]`")
1916
+
1917
+ with gr.Row(elem_classes=["wrap-row"]):
1918
+ with gr.Column(scale=2, min_width=300):
1919
  api_key_input = gr.Textbox(label="Gemini API Key", type="password", placeholder="AIza...", value=DEFAULT_GEMINI_API_KEY, elem_classes=["solver-log"])
1920
  with gr.Tabs():
1921
  with gr.Tab("Natural Language"):
1922
  problem_input = gr.Textbox(label="Problem Description", placeholder=PLACEHOLDER_HINT, lines=5, elem_classes=["solver-log"])
1923
  with gr.Row():
1924
+ solve_btn = gr.Button("βš— Solve Natural Language", variant="primary")
1925
+ clear_btn = gr.Button("Clear")
1926
+
1927
  if HAS_QUANTUM:
1928
  with gr.Tab("Quantum Circuits (Heisenberg Abstraction)"):
1929
  q_dropdown = gr.Dropdown(choices=["Bell State", "VQE H2", "QAOA MaxCut"], label="Select Circuit Template", value="Bell State")
1930
  q_solve_btn = gr.Button("βš› Run Quantum Solver (Bypass Encoder)", variant="primary")
1931
+
1932
+ with gr.Column(scale=1, min_width=250):
1933
+ gr.Textbox(value=(f"Compute: {DEVICE.type.upper()}\n"
1934
+ f"Axioms: {len(ALL_AXIOMS)}\n"
1935
+ f"New: Thread Crash Safety & UI Layout Fix\n"
1936
+ f"New: Quantum BBGKY Cumulant Expansion\n"
1937
+ f"New: Homotopy Continuation (Morphing Ray)\n"
1938
+ f"New: Anchor Fix (Gate 2 Sync)"),
1939
+ lines=7, interactive=False, elem_classes=["solver-log"])
1940
+
1941
+ with gr.Row(elem_classes=["wrap-row"]):
1942
+ with gr.Column(scale=1, min_width=300):
1943
+ live_html = gr.HTML(value=build_live_html())
1944
+ with gr.Column(scale=1, min_width=300):
1945
+ answer_box = gr.Textbox(label="Isomorphic Collapse", lines=20, interactive=False, elem_classes=["answer-box"])
1946
 
1947
  def fetch_ui():
1948
  while True:
1949
+ time.sleep(1.0)
1950
+ yield build_live_html(), GLOBAL_SOLVE_STATE["answer"]
1951
 
1952
  solve_btn.click(fn=trigger_solve, inputs=[problem_input, api_key_input], outputs=None)
1953
  clear_btn.click(fn=lambda: ("", "", ""), inputs=[], outputs=[problem_input, live_html, answer_box])
1954
+
1955
+ if HAS_QUANTUM:
1956
+ q_solve_btn.click(fn=trigger_quantum_solve, inputs=[q_dropdown, api_key_input], outputs=None)
1957
+
1958
  demo.load(fetch_ui, inputs=None, outputs=[live_html, answer_box])
1959
 
1960
  if __name__ == "__main__":
1961
  print(f"[SYSTEM 24.1] Compute: {DEVICE.type.upper()} | Feature Flags: Quantum={HAS_QUANTUM}")
1962
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=False)