Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,19 +1,21 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
-
PRACTICALITY UNIFIED SERVER 22.
|
| 4 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 5 |
ARCHITECTURE:
|
| 6 |
User Text β [GEMINI 3.1 ENCODER] β AXLProblemDef (Strict Math Representation)
|
| 7 |
-
β
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
LATEST UPDATES (22.
|
| 14 |
-
-
|
| 15 |
-
|
| 16 |
-
-
|
|
|
|
|
|
|
| 17 |
"""
|
| 18 |
|
| 19 |
import os, time, random, math, threading, warnings, queue, json, textwrap
|
|
@@ -28,20 +30,20 @@ from sympy.parsing.sympy_parser import parse_expr
|
|
| 28 |
import torch
|
| 29 |
import gradio as gr
|
| 30 |
|
| 31 |
-
#
|
| 32 |
from google import genai
|
| 33 |
from google.genai import types
|
| 34 |
|
| 35 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 36 |
# AI CONFIGURATION (Set your key here!)
|
| 37 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 38 |
-
DEFAULT_GEMINI_API_KEY = os.environ.get("
|
| 39 |
-
GEMINI_MODEL = "
|
| 40 |
|
| 41 |
warnings.filterwarnings("ignore")
|
| 42 |
USE_GPU = torch.cuda.is_available()
|
| 43 |
DEVICE = torch.device("cuda" if USE_GPU else "cpu")
|
| 44 |
-
print(f"[UNIFIED SERVER] Compute: {DEVICE.type.upper()} | System 22.
|
| 45 |
|
| 46 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 47 |
# SECTION 1: CONSTANTS
|
|
@@ -54,7 +56,7 @@ N_MPRT_EXPLORE = 1000
|
|
| 54 |
PROJECTION_CACHE: Dict = {}
|
| 55 |
|
| 56 |
MAX_TOTAL_RAYS = 1_500_000
|
| 57 |
-
RAY_BATCH_SIZE =
|
| 58 |
CE_EARN_RATIO = 0.90
|
| 59 |
SCOUT_CE_THRESHOLD = 0.5
|
| 60 |
BRANCH_WIDTH = 12
|
|
@@ -63,7 +65,29 @@ BATON_REGISTRY_THRESHOLD = 2.0
|
|
| 63 |
BATON_REGISTRY_MAX = 5000
|
| 64 |
|
| 65 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 66 |
-
# SECTION 2:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 68 |
class IV:
|
| 69 |
__slots__ = ("lo","hi")
|
|
@@ -144,7 +168,7 @@ def _global_hc4_tighten_bounds(problem):
|
|
| 144 |
for v in problem.bounds if v in c}
|
| 145 |
|
| 146 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 147 |
-
# SECTION
|
| 148 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 149 |
@dataclass
|
| 150 |
class PSLVar: name:str; lo:float; hi:float
|
|
@@ -273,7 +297,7 @@ class AXLtoPSLCompiler:
|
|
| 273 |
AXL_COMPILER=AXLtoPSLCompiler()
|
| 274 |
|
| 275 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 276 |
-
# SECTION
|
| 277 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 278 |
@dataclass
|
| 279 |
class Constraint:
|
|
@@ -460,7 +484,7 @@ def build_base_problem(axl_def:AXLProblemDef) -> Problem:
|
|
| 460 |
scope_order=ep.scope_order)
|
| 461 |
|
| 462 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 463 |
-
# SECTION
|
| 464 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 465 |
@dataclass
|
| 466 |
class L9Certificate:
|
|
@@ -545,7 +569,7 @@ def _mprt_sample(problem,work_box,N):
|
|
| 545 |
return {v:float(X[best_idx,i].item()) for i,v in enumerate(var_list)},ce_batch[best_idx].item()
|
| 546 |
|
| 547 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 548 |
-
# SECTION
|
| 549 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 550 |
class Axiom:
|
| 551 |
CONTINUOUS="CONTINUOUS"; DISCRETE="DISCRETE"; QUADRATIC="QUADRATIC"
|
|
@@ -578,7 +602,7 @@ def sequence_valid(seq:List[str]) -> bool:
|
|
| 578 |
return True
|
| 579 |
|
| 580 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 581 |
-
# SECTION
|
| 582 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 583 |
RAY_TYPES=["seed","branch","tension","scout","recombine","invert","target"]
|
| 584 |
|
|
@@ -630,7 +654,7 @@ class StructuralModel:
|
|
| 630 |
resonant_pairs:List[Tuple[str,str]]=field(default_factory=list)
|
| 631 |
|
| 632 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 633 |
-
# SECTION
|
| 634 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 635 |
def _make_hyp(hid,binding,h_type,claim,derivation,pinned,free,conf):
|
| 636 |
return Hypothesis(hid=hid,binding=binding,h_type=h_type,claim=claim,
|
|
@@ -783,7 +807,7 @@ AXIOM_CONSTRUCTORS={
|
|
| 783 |
}
|
| 784 |
|
| 785 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 786 |
-
# SECTION
|
| 787 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 788 |
class CreativeSeeder:
|
| 789 |
def target_seeds(self,anchors:List[AXLInvariant]) -> List[AxiomRay]:
|
|
@@ -888,7 +912,7 @@ class CreativeSeeder:
|
|
| 888 |
CREATIVE_SEEDER=CreativeSeeder()
|
| 889 |
|
| 890 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 891 |
-
# SECTION
|
| 892 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 893 |
def _verify(binding:Dict[str,float],base_problem:Problem,
|
| 894 |
anchors:List[AXLInvariant]) -> Tuple[bool,bool,Dict[str,Tuple[float,bool]],float]:
|
|
@@ -910,7 +934,7 @@ def _verify(binding:Dict[str,float],base_problem:Problem,
|
|
| 910 |
return g1_pass,g2_pass,g2,round(g1_ce,6)
|
| 911 |
|
| 912 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 913 |
-
# SECTION
|
| 914 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 915 |
class SequenceRayTracer:
|
| 916 |
def trace(self,axl_def:AXLProblemDef,base_problem:Problem):
|
|
@@ -941,7 +965,7 @@ class SequenceRayTracer:
|
|
| 941 |
model=StructuralModel(best_binding,best_ce)
|
| 942 |
allosteric_counts={"isolated":0,"relational":0,"systemic":0}
|
| 943 |
|
| 944 |
-
while total_fired<MAX_TOTAL_RAYS:
|
| 945 |
batch_rays:List[AxiomRay]=[]
|
| 946 |
for _ in range(RAY_BATCH_SIZE):
|
| 947 |
start_idx=q_idx
|
|
@@ -1047,13 +1071,18 @@ class SequenceRayTracer:
|
|
| 1047 |
|
| 1048 |
queues["core"].sort(key=lambda r:r.ce_prior+(r.depth*0.0001))
|
| 1049 |
queues["genetic"].sort(key=lambda r:r.ce_prior+(r.depth*0.0001))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1050 |
if solved: break
|
| 1051 |
|
| 1052 |
return best_binding,best_ce,hero_traces,total_fired,allosteric_counts
|
| 1053 |
|
| 1054 |
|
| 1055 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1056 |
-
# SECTION
|
| 1057 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1058 |
|
| 1059 |
ENCODER_SYSTEM_PROMPT = """You are the Encoder for the Practicality Wisdom Layer β a neuro-symbolic
|
|
@@ -1122,7 +1151,37 @@ CONSTRAINTS & ANCHORS:
|
|
| 1122 |
β’ Anchors are the verification conditions. What MUST be true to accept the solution?
|
| 1123 |
|
| 1124 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1125 |
-
PART 3:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1126 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1127 |
|
| 1128 |
If a previous solve attempt is included in the user message showing
|
|
@@ -1135,44 +1194,37 @@ Common fixes:
|
|
| 1135 |
Output ONLY the JSON. No preamble.
|
| 1136 |
"""
|
| 1137 |
|
| 1138 |
-
COLLAPSER_SYSTEM_PROMPT = """You are the Collapser for the Practicality Wisdom Layer.
|
| 1139 |
-
a
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1140 |
β’ The original natural language problem
|
| 1141 |
-
β’ The problem name and description
|
| 1142 |
β’ Whether the solver succeeded (solved/partial/unsolved)
|
| 1143 |
β’ The verified variable binding (the numerical solution)
|
| 1144 |
-
β’
|
| 1145 |
-
β’
|
| 1146 |
-
β’ The best axiom ray sequence that found the solution
|
| 1147 |
-
β’ Total rays fired
|
| 1148 |
-
|
| 1149 |
-
Your job is to translate this back into clear, domain-appropriate
|
| 1150 |
-
natural language that a human expert in the problem domain would
|
| 1151 |
-
recognize as correct and useful.
|
| 1152 |
|
| 1153 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1154 |
TONE AND FORMAT RULES
|
| 1155 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1156 |
-
β’ Write for a domain expert, not a general audience
|
| 1157 |
-
β’ Use domain-appropriate variable names and units if discernible
|
| 1158 |
β’ Lead with the status: SOLVED / PARTIAL / UNSOLVED
|
| 1159 |
-
β’
|
| 1160 |
-
β’
|
| 1161 |
-
|
| 1162 |
-
|
| 1163 |
-
|
| 1164 |
-
β’ Keep
|
| 1165 |
-
β’ End with the axiom sequence that found the solution, formatted
|
| 1166 |
-
as a one-line note
|
| 1167 |
"""
|
| 1168 |
|
| 1169 |
def encode_problem_to_axl(problem_text: str, api_key: str) -> AXLProblemDef:
|
| 1170 |
-
"""Uses Google GenAI to slot-fill the text into the AXL structural JSON."""
|
| 1171 |
if not api_key:
|
| 1172 |
-
raise ValueError("Gemini API Key is missing.
|
| 1173 |
|
| 1174 |
client = genai.Client(api_key=api_key)
|
| 1175 |
-
|
| 1176 |
config = types.GenerateContentConfig(
|
| 1177 |
system_instruction=[types.Part.from_text(text=ENCODER_SYSTEM_PROMPT)],
|
| 1178 |
response_mime_type="application/json",
|
|
@@ -1181,19 +1233,16 @@ def encode_problem_to_axl(problem_text: str, api_key: str) -> AXLProblemDef:
|
|
| 1181 |
|
| 1182 |
response = client.models.generate_content(
|
| 1183 |
model=GEMINI_MODEL,
|
| 1184 |
-
contents=problem_text,
|
| 1185 |
config=config,
|
| 1186 |
)
|
| 1187 |
-
|
| 1188 |
return _parse_axl_json(response.text)
|
| 1189 |
|
| 1190 |
def _parse_axl_json(raw_json: str) -> AXLProblemDef:
|
| 1191 |
-
"""Parses Gemini JSON output into the strict AXL structural definition."""
|
| 1192 |
text = raw_json.strip()
|
| 1193 |
if text.startswith("```"):
|
| 1194 |
text = text.split("```")[1]
|
| 1195 |
-
if text.startswith("json"):
|
| 1196 |
-
text = text[4:]
|
| 1197 |
text = text.strip().rstrip("`").strip()
|
| 1198 |
|
| 1199 |
d = json.loads(text)
|
|
@@ -1217,7 +1266,7 @@ def _parse_axl_json(raw_json: str) -> AXLProblemDef:
|
|
| 1217 |
return AXLProblemDef(
|
| 1218 |
name=d["name"],
|
| 1219 |
description=d.get("description", ""),
|
| 1220 |
-
axioms=set(), # Engine owns Axioms
|
| 1221 |
variables=variables,
|
| 1222 |
constraints=d.get("constraints", []),
|
| 1223 |
scopes=d.get("scopes", []),
|
|
@@ -1228,6 +1277,7 @@ def _parse_axl_json(raw_json: str) -> AXLProblemDef:
|
|
| 1228 |
def collapse_solution(
|
| 1229 |
problem_text: str,
|
| 1230 |
axl_def: AXLProblemDef,
|
|
|
|
| 1231 |
binding: Dict[str, float],
|
| 1232 |
g1_pass: bool,
|
| 1233 |
g2_pass: bool,
|
|
@@ -1236,22 +1286,17 @@ def collapse_solution(
|
|
| 1236 |
total_fired: int,
|
| 1237 |
api_key: str
|
| 1238 |
) -> str:
|
| 1239 |
-
|
| 1240 |
-
if not api_key:
|
| 1241 |
-
return "ERROR: Gemini API Key required for semantic collapsing."
|
| 1242 |
|
| 1243 |
client = genai.Client(api_key=api_key)
|
| 1244 |
|
| 1245 |
payload = {
|
| 1246 |
"original_problem": problem_text,
|
| 1247 |
-
"problem_name": axl_def.name,
|
| 1248 |
"solved": g1_pass and g2_pass,
|
| 1249 |
-
"gate1_pass": g1_pass,
|
| 1250 |
-
"gate2_pass": g2_pass,
|
| 1251 |
"binding": {k: round(v, 6) for k, v in binding.items()},
|
|
|
|
|
|
|
| 1252 |
"invariant_results":invariant_results,
|
| 1253 |
-
"best_ray_sequence":best_ray,
|
| 1254 |
-
"rays_fired": total_fired,
|
| 1255 |
}
|
| 1256 |
|
| 1257 |
config = types.GenerateContentConfig(
|
|
@@ -1262,44 +1307,41 @@ def collapse_solution(
|
|
| 1262 |
|
| 1263 |
response = client.models.generate_content(
|
| 1264 |
model=GEMINI_MODEL,
|
| 1265 |
-
contents=json.dumps(payload, indent=2),
|
| 1266 |
config=config,
|
| 1267 |
)
|
| 1268 |
-
|
| 1269 |
return response.text
|
| 1270 |
|
| 1271 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1272 |
-
# SECTION
|
| 1273 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1274 |
|
| 1275 |
-
def
|
| 1276 |
"""
|
| 1277 |
-
|
| 1278 |
-
|
| 1279 |
"""
|
| 1280 |
-
|
| 1281 |
-
|
| 1282 |
-
|
| 1283 |
-
|
| 1284 |
-
def emit(line: str):
|
| 1285 |
-
log_lines.append(line)
|
| 1286 |
-
return "\n".join(log_lines), answer_text
|
| 1287 |
|
|
|
|
| 1288 |
current_text = original_problem_text
|
| 1289 |
used_key = api_key or DEFAULT_GEMINI_API_KEY
|
| 1290 |
|
| 1291 |
for attempt in range(1, MAX_ATTEMPTS + 1):
|
| 1292 |
-
|
| 1293 |
t0 = time.time()
|
| 1294 |
|
| 1295 |
try:
|
| 1296 |
axl_def = encode_problem_to_axl(current_text, used_key)
|
| 1297 |
except Exception as e:
|
| 1298 |
-
|
|
|
|
| 1299 |
return
|
| 1300 |
|
| 1301 |
enc_ms = round((time.time() - t0) * 1000)
|
| 1302 |
-
|
| 1303 |
f"β **Encoded** as `{axl_def.name}` ({enc_ms} ms)\n"
|
| 1304 |
f" Variables: `{', '.join(v['name'] for v in axl_def.variables)}`\n"
|
| 1305 |
f" Anchors: {len(axl_def.anchors)}\n\n"
|
|
@@ -1307,49 +1349,32 @@ def run_solve_streaming(original_problem_text: str, api_key: str):
|
|
| 1307 |
)
|
| 1308 |
|
| 1309 |
try:
|
|
|
|
| 1310 |
base_prob = build_base_problem(axl_def)
|
| 1311 |
except Exception as e:
|
| 1312 |
-
|
|
|
|
| 1313 |
return
|
| 1314 |
|
| 1315 |
-
|
| 1316 |
f"β **Compiled**: {len(base_prob.variables)} vars, "
|
| 1317 |
f"{len(base_prob.compiled_constraints)} constraints\n"
|
| 1318 |
-
f" Bilinear pairs: {len(base_prob.bilinear_pairs)}\n"
|
| 1319 |
-
f" Monotone targets: {len(base_prob.monotone_targets)}\n\n"
|
| 1320 |
f"π **Running wisdom layer (PyTorch Search)β¦**\n"
|
| 1321 |
)
|
| 1322 |
|
| 1323 |
-
|
| 1324 |
-
|
| 1325 |
-
|
| 1326 |
-
|
| 1327 |
-
|
| 1328 |
-
|
| 1329 |
-
result_q.put(("ok", binding, ce, traces, total_fired, allosteric))
|
| 1330 |
-
except Exception as e:
|
| 1331 |
-
result_q.put(("err", str(e)))
|
| 1332 |
-
|
| 1333 |
-
worker_thread = threading.Thread(target=_worker, daemon=True)
|
| 1334 |
-
worker_thread.start()
|
| 1335 |
-
|
| 1336 |
-
dots = 0
|
| 1337 |
-
while worker_thread.is_alive():
|
| 1338 |
-
worker_thread.join(timeout=3.0)
|
| 1339 |
-
if worker_thread.is_alive():
|
| 1340 |
-
dots += 1
|
| 1341 |
-
yield emit(f" Β·{'Β·' * dots} still searching ({dots * 3}s)β¦\n")
|
| 1342 |
-
|
| 1343 |
-
if result_q.empty():
|
| 1344 |
-
yield emit("β Solver returned no result.\n")
|
| 1345 |
return
|
| 1346 |
|
| 1347 |
-
|
| 1348 |
-
|
| 1349 |
-
|
| 1350 |
return
|
| 1351 |
|
| 1352 |
-
_, binding, ce, traces, total_fired, allosteric = result
|
| 1353 |
survived = [t for t in traces if t.survived]
|
| 1354 |
best_t = min(survived, key=lambda t: t.ce_after, default=None)
|
| 1355 |
|
|
@@ -1376,38 +1401,48 @@ def run_solve_streaming(original_problem_text: str, api_key: str):
|
|
| 1376 |
g2_detail = " | ".join(f"{'β' if ok else 'β'} {k}" for k, (_, ok) in inv_results.items())
|
| 1377 |
best_ray = best_t.ray_name if best_t else "β"
|
| 1378 |
|
| 1379 |
-
|
| 1380 |
f"\n{solved_str}\n"
|
| 1381 |
f" CE = {ce:.6f} | Gate 1: {'β' if g1_pass else 'β'} | Gate 2: {'β' if g2_pass else 'β'}\n"
|
| 1382 |
f" {g2_detail}\n"
|
| 1383 |
-
f"
|
| 1384 |
f" Rays fired: {total_fired:,} | Survived: {len(survived)}\n"
|
| 1385 |
f" Allosteric: isolated {allosteric.get('isolated',0):,} | relational {allosteric.get('relational',0):,} | systemic {allosteric.get('systemic',0):,}\n\n"
|
| 1386 |
)
|
| 1387 |
|
| 1388 |
-
# ββ Self-Correcting Feedback Loop (Gate 2 Failure) βββββββββββββββ
|
| 1389 |
if not g2_pass and attempt < MAX_ATTEMPTS:
|
| 1390 |
failed_invs = {k: v for k, (v, ok) in inv_results.items() if not ok}
|
| 1391 |
current_text = original_problem_text + f"\n\nPREVIOUS ATTEMPT FAILED:\nGate 2 invariants that did not pass:\n{json.dumps(failed_invs, indent=2)}\n\nPlease revise the constraint encoding to better capture these conditions."
|
| 1392 |
-
|
| 1393 |
continue
|
| 1394 |
|
| 1395 |
-
|
| 1396 |
try:
|
| 1397 |
answer_text = collapse_solution(
|
| 1398 |
-
original_problem_text, axl_def, binding,
|
| 1399 |
g1_pass, g2_pass, inv_results,
|
| 1400 |
best_ray, total_fired, used_key
|
| 1401 |
)
|
| 1402 |
-
|
|
|
|
| 1403 |
except Exception as e:
|
| 1404 |
-
|
| 1405 |
-
|
| 1406 |
|
| 1407 |
break
|
| 1408 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1409 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1410 |
-
# SECTION
|
| 1411 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1412 |
|
| 1413 |
CSS = """
|
|
@@ -1466,30 +1501,31 @@ with gr.Blocks(css=CSS, title="Practicality Unified Server") as demo:
|
|
| 1466 |
|
| 1467 |
with gr.Row():
|
| 1468 |
solver_log = gr.Textbox(
|
| 1469 |
-
label="Solver Log",
|
| 1470 |
lines=18,
|
| 1471 |
interactive=False,
|
| 1472 |
elem_classes=["solver-log"],
|
| 1473 |
)
|
| 1474 |
answer_box = gr.Textbox(
|
| 1475 |
-
label="
|
| 1476 |
lines=18,
|
| 1477 |
interactive=False,
|
| 1478 |
elem_classes=["answer-box"],
|
| 1479 |
)
|
| 1480 |
|
| 1481 |
-
|
| 1482 |
-
|
| 1483 |
-
|
| 1484 |
-
|
| 1485 |
-
|
| 1486 |
-
|
|
|
|
|
|
|
| 1487 |
|
| 1488 |
solve_btn.click(
|
| 1489 |
-
fn=
|
| 1490 |
inputs=[problem_input, api_key_input],
|
| 1491 |
-
outputs=
|
| 1492 |
-
show_progress=False,
|
| 1493 |
)
|
| 1494 |
|
| 1495 |
clear_btn.click(
|
|
@@ -1498,14 +1534,14 @@ with gr.Blocks(css=CSS, title="Practicality Unified Server") as demo:
|
|
| 1498 |
outputs=[problem_input, solver_log, answer_box],
|
| 1499 |
)
|
| 1500 |
|
|
|
|
|
|
|
| 1501 |
gr.Markdown(
|
| 1502 |
-
"Built with Gradio Β· Practicality 22.
|
| 1503 |
elem_classes=["status-bar"]
|
| 1504 |
)
|
| 1505 |
|
| 1506 |
-
demo.queue()
|
| 1507 |
-
|
| 1508 |
if __name__ == "__main__":
|
| 1509 |
print(f"[UNIFIED SERVER] Compute: {DEVICE.type.upper()}")
|
| 1510 |
-
print(f"[UNIFIED SERVER] System 22.
|
| 1511 |
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
+
PRACTICALITY UNIFIED SERVER 22.2 β GLOBAL STATE + ISOMORPHISM COLLAPSE
|
| 4 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 5 |
ARCHITECTURE:
|
| 6 |
User Text β [GEMINI 3.1 ENCODER] β AXLProblemDef (Strict Math Representation)
|
| 7 |
+
β Python Compiler β PSL Mathematical Program
|
| 8 |
+
β [WISDOM LAYER] β Hypothesis Engine tests Isomorphic Axiom sequences
|
| 9 |
+
β PyTorch validates via Masked Deduction
|
| 10 |
+
β [GEMINI 3.1 COLLAPSER] β Receives: Binding, PSL Program, Winning Axiom Sequence
|
| 11 |
+
β Outputs: Domain-language explanation based on theory
|
| 12 |
+
|
| 13 |
+
LATEST UPDATES (22.2):
|
| 14 |
+
- GLOBAL STATE: The solver runs decoupled from the UI. You can close your browser,
|
| 15 |
+
return later, refresh the page, and instantly see the live search progress.
|
| 16 |
+
- BATCH SCALING: CPU/GPU batch size doubled to 24,576.
|
| 17 |
+
- ISOMORPHISM COLLAPSING: The LLM is explicitly fed the compiled PSL and the
|
| 18 |
+
winning structural theory (Axiom ray) to explain *how* the problem was solved.
|
| 19 |
"""
|
| 20 |
|
| 21 |
import os, time, random, math, threading, warnings, queue, json, textwrap
|
|
|
|
| 30 |
import torch
|
| 31 |
import gradio as gr
|
| 32 |
|
| 33 |
+
# Google GenAI SDK
|
| 34 |
from google import genai
|
| 35 |
from google.genai import types
|
| 36 |
|
| 37 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 38 |
# AI CONFIGURATION (Set your key here!)
|
| 39 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 40 |
+
DEFAULT_GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
|
| 41 |
+
GEMINI_MODEL = "gemini-3.1-pro-preview"
|
| 42 |
|
| 43 |
warnings.filterwarnings("ignore")
|
| 44 |
USE_GPU = torch.cuda.is_available()
|
| 45 |
DEVICE = torch.device("cuda" if USE_GPU else "cpu")
|
| 46 |
+
print(f"[UNIFIED SERVER] Compute: {DEVICE.type.upper()} | System 22.2 (Persistent Global State)")
|
| 47 |
|
| 48 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 49 |
# SECTION 1: CONSTANTS
|
|
|
|
| 56 |
PROJECTION_CACHE: Dict = {}
|
| 57 |
|
| 58 |
MAX_TOTAL_RAYS = 1_500_000
|
| 59 |
+
RAY_BATCH_SIZE = 24576 # DOUBLED: Maximum CPU throughput to feed GPU
|
| 60 |
CE_EARN_RATIO = 0.90
|
| 61 |
SCOUT_CE_THRESHOLD = 0.5
|
| 62 |
BRANCH_WIDTH = 12
|
|
|
|
| 65 |
BATON_REGISTRY_MAX = 5000
|
| 66 |
|
| 67 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 68 |
+
# SECTION 2: GLOBAL STATE (Persistence Fix)
|
| 69 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 70 |
+
STATE_LOCK = threading.Lock()
|
| 71 |
+
|
| 72 |
+
# This state persists across browser reloads
|
| 73 |
+
GLOBAL_SOLVE_STATE = {
|
| 74 |
+
"is_running": False,
|
| 75 |
+
"logs": [],
|
| 76 |
+
"answer": "",
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
def _emit_log(line: str):
|
| 80 |
+
"""Thread-safe log appending."""
|
| 81 |
+
with STATE_LOCK:
|
| 82 |
+
GLOBAL_SOLVE_STATE["logs"].append(line)
|
| 83 |
+
|
| 84 |
+
def _set_answer(text: str):
|
| 85 |
+
"""Thread-safe answer updating."""
|
| 86 |
+
with STATE_LOCK:
|
| 87 |
+
GLOBAL_SOLVE_STATE["answer"] = text
|
| 88 |
+
|
| 89 |
+
# βββββββββββββββββββββββοΏ½οΏ½ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 90 |
+
# SECTION 3: INTERVAL ARITHMETIC (HC4)
|
| 91 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 92 |
class IV:
|
| 93 |
__slots__ = ("lo","hi")
|
|
|
|
| 168 |
for v in problem.bounds if v in c}
|
| 169 |
|
| 170 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 171 |
+
# SECTION 4: PSL PARSER & PRE-COMPILATION
|
| 172 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 173 |
@dataclass
|
| 174 |
class PSLVar: name:str; lo:float; hi:float
|
|
|
|
| 297 |
AXL_COMPILER=AXLtoPSLCompiler()
|
| 298 |
|
| 299 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 300 |
+
# SECTION 5: PROBLEM COMPILATION
|
| 301 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 302 |
@dataclass
|
| 303 |
class Constraint:
|
|
|
|
| 484 |
scope_order=ep.scope_order)
|
| 485 |
|
| 486 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 487 |
+
# SECTION 6: BATCHED MASKED DEDUCTION
|
| 488 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 489 |
@dataclass
|
| 490 |
class L9Certificate:
|
|
|
|
| 569 |
return {v:float(X[best_idx,i].item()) for i,v in enumerate(var_list)},ce_batch[best_idx].item()
|
| 570 |
|
| 571 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 572 |
+
# SECTION 7: AXIOMS
|
| 573 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 574 |
class Axiom:
|
| 575 |
CONTINUOUS="CONTINUOUS"; DISCRETE="DISCRETE"; QUADRATIC="QUADRATIC"
|
|
|
|
| 602 |
return True
|
| 603 |
|
| 604 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 605 |
+
# SECTION 8: SHARED DATACLASSES
|
| 606 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 607 |
RAY_TYPES=["seed","branch","tension","scout","recombine","invert","target"]
|
| 608 |
|
|
|
|
| 654 |
resonant_pairs:List[Tuple[str,str]]=field(default_factory=list)
|
| 655 |
|
| 656 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 657 |
+
# SECTION 9: HYPOTHESIS CONSTRUCTORS
|
| 658 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 659 |
def _make_hyp(hid,binding,h_type,claim,derivation,pinned,free,conf):
|
| 660 |
return Hypothesis(hid=hid,binding=binding,h_type=h_type,claim=claim,
|
|
|
|
| 807 |
}
|
| 808 |
|
| 809 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 810 |
+
# SECTION 10: CREATIVE SEEDER
|
| 811 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 812 |
class CreativeSeeder:
|
| 813 |
def target_seeds(self,anchors:List[AXLInvariant]) -> List[AxiomRay]:
|
|
|
|
| 912 |
CREATIVE_SEEDER=CreativeSeeder()
|
| 913 |
|
| 914 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 915 |
+
# SECTION 11: VERIFY LAYER
|
| 916 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 917 |
def _verify(binding:Dict[str,float],base_problem:Problem,
|
| 918 |
anchors:List[AXLInvariant]) -> Tuple[bool,bool,Dict[str,Tuple[float,bool]],float]:
|
|
|
|
| 934 |
return g1_pass,g2_pass,g2,round(g1_ce,6)
|
| 935 |
|
| 936 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 937 |
+
# SECTION 12: SEQUENCE RAY TRACER
|
| 938 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 939 |
class SequenceRayTracer:
|
| 940 |
def trace(self,axl_def:AXLProblemDef,base_problem:Problem):
|
|
|
|
| 965 |
model=StructuralModel(best_binding,best_ce)
|
| 966 |
allosteric_counts={"isolated":0,"relational":0,"systemic":0}
|
| 967 |
|
| 968 |
+
while total_fired<MAX_TOTAL_RAYS and GLOBAL_SOLVE_STATE["is_running"]:
|
| 969 |
batch_rays:List[AxiomRay]=[]
|
| 970 |
for _ in range(RAY_BATCH_SIZE):
|
| 971 |
start_idx=q_idx
|
|
|
|
| 1071 |
|
| 1072 |
queues["core"].sort(key=lambda r:r.ce_prior+(r.depth*0.0001))
|
| 1073 |
queues["genetic"].sort(key=lambda r:r.ce_prior+(r.depth*0.0001))
|
| 1074 |
+
|
| 1075 |
+
# Periodically heartbeat logs
|
| 1076 |
+
if total_fired % (RAY_BATCH_SIZE * 5) == 0:
|
| 1077 |
+
_emit_log(f" Β· searching ({total_fired:,} rays fired, best CE={best_ce:.4f})β¦")
|
| 1078 |
+
|
| 1079 |
if solved: break
|
| 1080 |
|
| 1081 |
return best_binding,best_ce,hero_traces,total_fired,allosteric_counts
|
| 1082 |
|
| 1083 |
|
| 1084 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1085 |
+
# SECTION 13: LLM BRIDGE (GOOGLE GENAI 3.1)
|
| 1086 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1087 |
|
| 1088 |
ENCODER_SYSTEM_PROMPT = """You are the Encoder for the Practicality Wisdom Layer β a neuro-symbolic
|
|
|
|
| 1151 |
β’ Anchors are the verification conditions. What MUST be true to accept the solution?
|
| 1152 |
|
| 1153 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1154 |
+
PART 3: EXAMPLES
|
| 1155 |
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1156 |
+
|
| 1157 |
+
EXAMPLE 1: Chemical Equilibrium (A + B β C, Kc = 4)
|
| 1158 |
+
User: "Find equilibrium concentrations for A+BβC with Kc=4,
|
| 1159 |
+
starting with [A]=[B]=1 mol/L and [C]=0"
|
| 1160 |
+
|
| 1161 |
+
Output:
|
| 1162 |
+
{
|
| 1163 |
+
"name": "ChemEquilibrium",
|
| 1164 |
+
"description": "A+BβC equilibrium with Kc=4, initial [A]=[B]=1, [C]=0",
|
| 1165 |
+
"variables": [
|
| 1166 |
+
{"name": "ca", "lo": 0.0},
|
| 1167 |
+
{"name": "cb", "lo": 0.0},
|
| 1168 |
+
{"name": "cc", "lo": 0.0}
|
| 1169 |
+
],
|
| 1170 |
+
"constraints": [
|
| 1171 |
+
{"kind": "CONSERVE", "expr": "ca + cc - 1.0"},
|
| 1172 |
+
{"kind": "CONSERVE", "expr": "cb + cc - 1.0"},
|
| 1173 |
+
{"kind": "EQ", "expr": "4*ca*cb - cc", "weight": 5.0}
|
| 1174 |
+
],
|
| 1175 |
+
"anchors": [
|
| 1176 |
+
{"name": "atom_balance_A", "expr": "ca + cc - 1.0", "tolerance": 0.001, "mode": "eq"},
|
| 1177 |
+
{"name": "atom_balance_B", "expr": "cb + cc - 1.0", "tolerance": 0.001, "mode": "eq"},
|
| 1178 |
+
{"name": "kc_equilibrium", "expr": "4*ca*cb - cc", "tolerance": 0.001, "mode": "eq"}
|
| 1179 |
+
],
|
| 1180 |
+
"observations": {}
|
| 1181 |
+
}
|
| 1182 |
+
|
| 1183 |
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1184 |
+
PART 4: FAILURE HANDLING
|
| 1185 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1186 |
|
| 1187 |
If a previous solve attempt is included in the user message showing
|
|
|
|
| 1194 |
Output ONLY the JSON. No preamble.
|
| 1195 |
"""
|
| 1196 |
|
| 1197 |
+
COLLAPSER_SYSTEM_PROMPT = """You are the Collapser for the Practicality Wisdom Layer.
|
| 1198 |
+
The system has derived a structural isomorphism (an Axiom Sequence) to collapse
|
| 1199 |
+
the problem constraints you encoded into a verified numerical solution.
|
| 1200 |
+
|
| 1201 |
+
Your job is to explain the solution using this structural thinking.
|
| 1202 |
+
|
| 1203 |
+
You receive a JSON object containing:
|
| 1204 |
β’ The original natural language problem
|
|
|
|
| 1205 |
β’ Whether the solver succeeded (solved/partial/unsolved)
|
| 1206 |
β’ The verified variable binding (the numerical solution)
|
| 1207 |
+
β’ The compiled PSL Program Text (The exact mathematical constraints the engine proved)
|
| 1208 |
+
β’ The ISOMORPHISM HYPOTHESIS (best_ray_sequence): The geometric theory that unlocked it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1209 |
|
| 1210 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1211 |
TONE AND FORMAT RULES
|
| 1212 |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1213 |
+
β’ Write for a domain expert, not a general audience.
|
|
|
|
| 1214 |
β’ Lead with the status: SOLVED / PARTIAL / UNSOLVED
|
| 1215 |
+
β’ Provide the final binding values with domain-appropriate context.
|
| 1216 |
+
β’ EXPLAIN THE ISOMORPHISM: Explicitly explain *how* the `isomorphism_hypothesis`
|
| 1217 |
+
(the Axiom sequence like SYMMETRICβMONOTONE) structurally describes the
|
| 1218 |
+
`psl_program_text`. Do not just list the axioms; explain why the problem's
|
| 1219 |
+
topology fits that geometry.
|
| 1220 |
+
β’ Keep the entire output under 300 words.
|
|
|
|
|
|
|
| 1221 |
"""
|
| 1222 |
|
| 1223 |
def encode_problem_to_axl(problem_text: str, api_key: str) -> AXLProblemDef:
|
|
|
|
| 1224 |
if not api_key:
|
| 1225 |
+
raise ValueError("Gemini API Key is missing.")
|
| 1226 |
|
| 1227 |
client = genai.Client(api_key=api_key)
|
|
|
|
| 1228 |
config = types.GenerateContentConfig(
|
| 1229 |
system_instruction=[types.Part.from_text(text=ENCODER_SYSTEM_PROMPT)],
|
| 1230 |
response_mime_type="application/json",
|
|
|
|
| 1233 |
|
| 1234 |
response = client.models.generate_content(
|
| 1235 |
model=GEMINI_MODEL,
|
| 1236 |
+
contents=[types.Content(role="user", parts=[types.Part.from_text(text=problem_text)])],
|
| 1237 |
config=config,
|
| 1238 |
)
|
|
|
|
| 1239 |
return _parse_axl_json(response.text)
|
| 1240 |
|
| 1241 |
def _parse_axl_json(raw_json: str) -> AXLProblemDef:
|
|
|
|
| 1242 |
text = raw_json.strip()
|
| 1243 |
if text.startswith("```"):
|
| 1244 |
text = text.split("```")[1]
|
| 1245 |
+
if text.startswith("json"): text = text[4:]
|
|
|
|
| 1246 |
text = text.strip().rstrip("`").strip()
|
| 1247 |
|
| 1248 |
d = json.loads(text)
|
|
|
|
| 1266 |
return AXLProblemDef(
|
| 1267 |
name=d["name"],
|
| 1268 |
description=d.get("description", ""),
|
| 1269 |
+
axioms=set(), # Engine owns Axioms
|
| 1270 |
variables=variables,
|
| 1271 |
constraints=d.get("constraints", []),
|
| 1272 |
scopes=d.get("scopes", []),
|
|
|
|
| 1277 |
def collapse_solution(
|
| 1278 |
problem_text: str,
|
| 1279 |
axl_def: AXLProblemDef,
|
| 1280 |
+
psl_text: str,
|
| 1281 |
binding: Dict[str, float],
|
| 1282 |
g1_pass: bool,
|
| 1283 |
g2_pass: bool,
|
|
|
|
| 1286 |
total_fired: int,
|
| 1287 |
api_key: str
|
| 1288 |
) -> str:
|
| 1289 |
+
if not api_key: return "ERROR: Gemini API Key required."
|
|
|
|
|
|
|
| 1290 |
|
| 1291 |
client = genai.Client(api_key=api_key)
|
| 1292 |
|
| 1293 |
payload = {
|
| 1294 |
"original_problem": problem_text,
|
|
|
|
| 1295 |
"solved": g1_pass and g2_pass,
|
|
|
|
|
|
|
| 1296 |
"binding": {k: round(v, 6) for k, v in binding.items()},
|
| 1297 |
+
"psl_program_text": psl_text,
|
| 1298 |
+
"isomorphism_hypothesis": best_ray,
|
| 1299 |
"invariant_results":invariant_results,
|
|
|
|
|
|
|
| 1300 |
}
|
| 1301 |
|
| 1302 |
config = types.GenerateContentConfig(
|
|
|
|
| 1307 |
|
| 1308 |
response = client.models.generate_content(
|
| 1309 |
model=GEMINI_MODEL,
|
| 1310 |
+
contents=[types.Content(role="user", parts=[types.Part.from_text(text=json.dumps(payload, indent=2))])],
|
| 1311 |
config=config,
|
| 1312 |
)
|
|
|
|
| 1313 |
return response.text
|
| 1314 |
|
| 1315 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1316 |
+
# SECTION 14: GLOBAL SOLVE TASK (Background Thread)
|
| 1317 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1318 |
|
| 1319 |
+
def global_solve_task(original_problem_text: str, api_key: str):
|
| 1320 |
"""
|
| 1321 |
+
Runs the full neuro-symbolic pipeline in a background thread,
|
| 1322 |
+
updating the GLOBAL_SOLVE_STATE dictionary for the UI to poll.
|
| 1323 |
"""
|
| 1324 |
+
GLOBAL_SOLVE_STATE["is_running"] = True
|
| 1325 |
+
GLOBAL_SOLVE_STATE["logs"] = []
|
| 1326 |
+
GLOBAL_SOLVE_STATE["answer"] = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1327 |
|
| 1328 |
+
MAX_ATTEMPTS = 3
|
| 1329 |
current_text = original_problem_text
|
| 1330 |
used_key = api_key or DEFAULT_GEMINI_API_KEY
|
| 1331 |
|
| 1332 |
for attempt in range(1, MAX_ATTEMPTS + 1):
|
| 1333 |
+
_emit_log(f"π **Encoding problem (Attempt {attempt}/{MAX_ATTEMPTS})β¦**\n")
|
| 1334 |
t0 = time.time()
|
| 1335 |
|
| 1336 |
try:
|
| 1337 |
axl_def = encode_problem_to_axl(current_text, used_key)
|
| 1338 |
except Exception as e:
|
| 1339 |
+
_emit_log(f"β Encoding failed: {e}\n")
|
| 1340 |
+
GLOBAL_SOLVE_STATE["is_running"] = False
|
| 1341 |
return
|
| 1342 |
|
| 1343 |
enc_ms = round((time.time() - t0) * 1000)
|
| 1344 |
+
_emit_log(
|
| 1345 |
f"β **Encoded** as `{axl_def.name}` ({enc_ms} ms)\n"
|
| 1346 |
f" Variables: `{', '.join(v['name'] for v in axl_def.variables)}`\n"
|
| 1347 |
f" Anchors: {len(axl_def.anchors)}\n\n"
|
|
|
|
| 1349 |
)
|
| 1350 |
|
| 1351 |
try:
|
| 1352 |
+
psl_text = AXL_COMPILER.compile(axl_def)
|
| 1353 |
base_prob = build_base_problem(axl_def)
|
| 1354 |
except Exception as e:
|
| 1355 |
+
_emit_log(f"β Compilation failed: {e}\n")
|
| 1356 |
+
GLOBAL_SOLVE_STATE["is_running"] = False
|
| 1357 |
return
|
| 1358 |
|
| 1359 |
+
_emit_log(
|
| 1360 |
f"β **Compiled**: {len(base_prob.variables)} vars, "
|
| 1361 |
f"{len(base_prob.compiled_constraints)} constraints\n"
|
|
|
|
|
|
|
| 1362 |
f"π **Running wisdom layer (PyTorch Search)β¦**\n"
|
| 1363 |
)
|
| 1364 |
|
| 1365 |
+
try:
|
| 1366 |
+
tracer = SequenceRayTracer()
|
| 1367 |
+
binding, ce, traces, total_fired, allosteric = tracer.trace(axl_def, base_prob)
|
| 1368 |
+
except Exception as e:
|
| 1369 |
+
_emit_log(f"β Solver error: {e}\n")
|
| 1370 |
+
GLOBAL_SOLVE_STATE["is_running"] = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1371 |
return
|
| 1372 |
|
| 1373 |
+
if total_fired == 0:
|
| 1374 |
+
_emit_log("β Solver returned no result.\n")
|
| 1375 |
+
GLOBAL_SOLVE_STATE["is_running"] = False
|
| 1376 |
return
|
| 1377 |
|
|
|
|
| 1378 |
survived = [t for t in traces if t.survived]
|
| 1379 |
best_t = min(survived, key=lambda t: t.ce_after, default=None)
|
| 1380 |
|
|
|
|
| 1401 |
g2_detail = " | ".join(f"{'β' if ok else 'β'} {k}" for k, (_, ok) in inv_results.items())
|
| 1402 |
best_ray = best_t.ray_name if best_t else "β"
|
| 1403 |
|
| 1404 |
+
_emit_log(
|
| 1405 |
f"\n{solved_str}\n"
|
| 1406 |
f" CE = {ce:.6f} | Gate 1: {'β' if g1_pass else 'β'} | Gate 2: {'β' if g2_pass else 'β'}\n"
|
| 1407 |
f" {g2_detail}\n"
|
| 1408 |
+
f" Isomorphism: `{best_ray}`\n"
|
| 1409 |
f" Rays fired: {total_fired:,} | Survived: {len(survived)}\n"
|
| 1410 |
f" Allosteric: isolated {allosteric.get('isolated',0):,} | relational {allosteric.get('relational',0):,} | systemic {allosteric.get('systemic',0):,}\n\n"
|
| 1411 |
)
|
| 1412 |
|
|
|
|
| 1413 |
if not g2_pass and attempt < MAX_ATTEMPTS:
|
| 1414 |
failed_invs = {k: v for k, (v, ok) in inv_results.items() if not ok}
|
| 1415 |
current_text = original_problem_text + f"\n\nPREVIOUS ATTEMPT FAILED:\nGate 2 invariants that did not pass:\n{json.dumps(failed_invs, indent=2)}\n\nPlease revise the constraint encoding to better capture these conditions."
|
| 1416 |
+
_emit_log(f"β **Gate 2 Failed.** Retrying ({len(failed_invs)} invariants failed) with structural feedback...\n\n---\n")
|
| 1417 |
continue
|
| 1418 |
|
| 1419 |
+
_emit_log(f"π€ **Collapsing Isomorphism to Domain Languageβ¦**\n")
|
| 1420 |
try:
|
| 1421 |
answer_text = collapse_solution(
|
| 1422 |
+
original_problem_text, axl_def, psl_text, binding,
|
| 1423 |
g1_pass, g2_pass, inv_results,
|
| 1424 |
best_ray, total_fired, used_key
|
| 1425 |
)
|
| 1426 |
+
_set_answer(answer_text)
|
| 1427 |
+
_emit_log("β Done.\n")
|
| 1428 |
except Exception as e:
|
| 1429 |
+
_set_answer(f"Error during collapsing: {e}")
|
| 1430 |
+
_emit_log("β Collapsing failed.\n")
|
| 1431 |
|
| 1432 |
break
|
| 1433 |
|
| 1434 |
+
GLOBAL_SOLVE_STATE["is_running"] = False
|
| 1435 |
+
|
| 1436 |
+
|
| 1437 |
+
def trigger_solve(problem_text: str, api_key: str):
|
| 1438 |
+
if GLOBAL_SOLVE_STATE["is_running"]:
|
| 1439 |
+
return
|
| 1440 |
+
if not problem_text.strip():
|
| 1441 |
+
return
|
| 1442 |
+
threading.Thread(target=global_solve_task, args=(problem_text, api_key), daemon=True).start()
|
| 1443 |
+
|
| 1444 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1445 |
+
# SECTION 15: GRADIO INTERFACE (Polling Global State)
|
| 1446 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1447 |
|
| 1448 |
CSS = """
|
|
|
|
| 1501 |
|
| 1502 |
with gr.Row():
|
| 1503 |
solver_log = gr.Textbox(
|
| 1504 |
+
label="Solver Log (Live State)",
|
| 1505 |
lines=18,
|
| 1506 |
interactive=False,
|
| 1507 |
elem_classes=["solver-log"],
|
| 1508 |
)
|
| 1509 |
answer_box = gr.Textbox(
|
| 1510 |
+
label="Isomorphic Collapse",
|
| 1511 |
lines=18,
|
| 1512 |
interactive=False,
|
| 1513 |
elem_classes=["answer-box"],
|
| 1514 |
)
|
| 1515 |
|
| 1516 |
+
# UI Polling Loop
|
| 1517 |
+
def fetch_ui_state():
|
| 1518 |
+
while True:
|
| 1519 |
+
time.sleep(1.0)
|
| 1520 |
+
with STATE_LOCK:
|
| 1521 |
+
logs = "".join(GLOBAL_SOLVE_STATE["logs"])
|
| 1522 |
+
ans = GLOBAL_SOLVE_STATE["answer"]
|
| 1523 |
+
yield logs, ans
|
| 1524 |
|
| 1525 |
solve_btn.click(
|
| 1526 |
+
fn=trigger_solve,
|
| 1527 |
inputs=[problem_input, api_key_input],
|
| 1528 |
+
outputs=None, # Fire and forget, UI loop handles updates
|
|
|
|
| 1529 |
)
|
| 1530 |
|
| 1531 |
clear_btn.click(
|
|
|
|
| 1534 |
outputs=[problem_input, solver_log, answer_box],
|
| 1535 |
)
|
| 1536 |
|
| 1537 |
+
demo.load(fetch_ui_state, inputs=None, outputs=[solver_log, answer_box])
|
| 1538 |
+
|
| 1539 |
gr.Markdown(
|
| 1540 |
+
"Built with Gradio Β· Practicality 22.2 Β· Global State Persistence + Structural Collapsing",
|
| 1541 |
elem_classes=["status-bar"]
|
| 1542 |
)
|
| 1543 |
|
|
|
|
|
|
|
| 1544 |
if __name__ == "__main__":
|
| 1545 |
print(f"[UNIFIED SERVER] Compute: {DEVICE.type.upper()}")
|
| 1546 |
+
print(f"[UNIFIED SERVER] System 22.2: GenAI SDK wired. Model: {GEMINI_MODEL}")
|
| 1547 |
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|