everydaytok commited on
Commit
6d3b1d9
Β·
verified Β·
1 Parent(s): d9d9304

Create practicality_oracle.py

Browse files
Files changed (1) hide show
  1. practicality_oracle.py +217 -0
practicality_oracle.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import copy
3
+ import json
4
+ import numpy as np
5
+ from fractions import Fraction
6
+ from typing import Dict, Tuple, Optional, Any, Callable
7
+ from dataclasses import dataclass, field
8
+ from google import genai
9
+ from google.genai import types
10
+
11
+ # ══════════════════════════════════════════════════════════════════════
12
+ # SECTION A: HEISENBERG QUANTUM SIMULATOR (Physics Rules)
13
+ # ══════════════════════════════════════════════════════════════════════
14
+ @dataclass
15
+ class StabilizerTableau:
16
+ n: int
17
+ tableau: np.ndarray = field(default=None)
18
+ def __post_init__(self):
19
+ if self.tableau is None:
20
+ self.tableau = np.zeros((2*self.n, 2*self.n+1), dtype=np.uint8)
21
+ for i in range(self.n):
22
+ self.tableau[i, i] = 1; self.tableau[self.n+i, self.n+i] = 1
23
+
24
+ class HeisenbergSimulator:
25
+ def __init__(self, n_qubits: int):
26
+ self.n = n_qubits
27
+ self.state = StabilizerTableau(n_qubits)
28
+
29
+ def h(self, q: int):
30
+ t = self.state.tableau
31
+ for i in range(2*self.n):
32
+ t[i, 2*self.n] ^= t[i, q] & t[i, self.n+q]
33
+ t[i, q], t[i, self.n+q] = t[i, self.n+q], t[i, q]
34
+
35
+ def cnot(self, c: int, target: int):
36
+ n = self.n; t = self.state.tableau
37
+ for i in range(2*n):
38
+ t[i, 2*n] ^= t[i,c] & t[i,n+target] & (t[i,target] ^ t[i,n+c] ^ 1)
39
+ t[i, target] ^= t[i, c]; t[i, n+c] ^= t[i, n+target]
40
+
41
+ def get_operator_expectation(self, pauli_string: str) -> float:
42
+ n = self.n
43
+ x_part, z_part = np.zeros(n, dtype=np.uint8), np.zeros(n, dtype=np.uint8)
44
+ phase = 0
45
+ for i, p in enumerate(pauli_string):
46
+ if p == 'X': x_part[i] = 1
47
+ elif p == 'Z': z_part[i] = 1
48
+ elif p == 'Y': x_part[i] = 1; z_part[i] = 1; phase += 1
49
+
50
+ t = self.state.tableau
51
+ for i in range(n, 2*n):
52
+ if (np.sum(t[i, :n] * z_part + t[i, n:2*n] * x_part) % 2) == 1: return 0.0
53
+
54
+ test_row = np.concatenate([x_part, z_part, [phase % 2]])
55
+ for i in range(n, 2*n):
56
+ if np.array_equal(t[i, :2*n], test_row[:2*n]): return 1.0 if t[i, 2*n] == 0 else -1.0
57
+ neg_row = test_row.copy(); neg_row[2*n] = 1 - neg_row[2*n]
58
+ if np.array_equal(t[i, :2*n], neg_row[:2*n]): return -1.0 if t[i, 2*n] == 0 else 1.0
59
+ return 1.0
60
+
61
+ # ══════════════════════════════════════════════════════════════════════
62
+ # SECTION B: THE TRUTH ORACLE (Ground Truth Checking)
63
+ # ══════════════════════════════════════════════════════════════════════
64
+ FACTORIZATION_TEST_CASES = [(15, 3, 5), (35, 5, 7), (85, 5, 17), (143, 11, 13)]
65
+
66
+ def extract_factors_from_binding(binding: Dict[str, float], N: int) -> Optional[Tuple[int, int]]:
67
+ for pname, qname in [('p', 'q'), ('factor_p', 'factor_q'), ('x', 'y')]:
68
+ if pname in binding and qname in binding:
69
+ p, q = round(binding[pname]), round(binding[qname])
70
+ if p * q == N and p >= 2 and q >= 2: return (min(p, q), max(p, q))
71
+ if 's' in binding and 'd' in binding:
72
+ s, d = binding['s'], binding['d']
73
+ p, q = round((s + d) / 2), round((s - d) / 2)
74
+ if p * q == N and p >= 2 and q >= 2: return (min(p, q), max(p, q))
75
+ if 't' in binding:
76
+ t = round(binding['t'])
77
+ if t >= 2 and N % t == 0: return (min(t, N//t), max(t, N//t))
78
+ for v, val in binding.items():
79
+ if not math.isfinite(val): continue
80
+ p = round(val)
81
+ if p >= 2 and p * p <= N and N % p == 0: return (p, N // p)
82
+ return None
83
+
84
+ def ground_truth_verify(binding: Dict[str, float], N: int) -> Tuple[bool, str]:
85
+ """The Oracle: Prevents Hallucinations."""
86
+ result = extract_factors_from_binding(binding, N)
87
+ if result is None: return False, "No valid integer factor pair extractable from binding"
88
+ p, q = result
89
+ if p * q == N: return True, f"{p} Γ— {q} = {N} βœ“"
90
+ return False, f"Round-trip failed: extracted ({p}, {q}), {p}Γ—{q}={p*q} β‰  {N}"
91
+
92
+ class AdversaryPreFlight:
93
+ def __init__(self, solver_callback: Callable, log_callback: Callable):
94
+ self.solver_callback = solver_callback
95
+ self.log = log_callback
96
+ self.test_cases = FACTORIZATION_TEST_CASES
97
+ self.rejection_log = []
98
+
99
+ def check_isomorphism(self, axl_def: Any) -> Tuple[bool, str]:
100
+ self.log("ADVERSARY PRE-FLIGHT: testing isomorphism on known toy cases...")
101
+ passed_count = 0
102
+ for N, true_p, true_q in self.test_cases:
103
+ new_axl = copy.deepcopy(axl_def)
104
+ if new_axl.observations:
105
+ old_N = list(axl_def.observations.values())[0]
106
+ for key in list(new_axl.observations.keys()):
107
+ if abs(new_axl.observations[key] - old_N) < 1e-6: new_axl.observations[key] = float(N)
108
+ for v in new_axl.variables:
109
+ if abs(v['lo'] - v['hi']) < 1e-6 and abs(v['lo'] - old_N) < 1e-6: v['lo'] = v['hi'] = float(N)
110
+
111
+ binding = self.solver_callback(new_axl, N)
112
+ if not binding:
113
+ self.log(f" N={N}: SKIP (quick-solve failed)")
114
+ continue
115
+
116
+ ok, msg = ground_truth_verify(binding, N)
117
+ self.log(f" N={N}: {'βœ“ PASS' if ok else 'βœ— FAIL'} | {msg}")
118
+ if ok: passed_count += 1
119
+ else: self.rejection_log.append({'N': N, 'reason': msg})
120
+
121
+ if passed_count == len(self.test_cases): return True, f"Passed all {passed_count} pre-flight cases"
122
+ elif passed_count == 0: return False, "REJECTED: failed all pre-flight cases β€” isomorphism invalid"
123
+ else: return False, f"REJECTED: passed {passed_count}/{len(self.test_cases)} β€” not reliable enough"
124
+
125
+ def failure_taxonomy(self, binding: Dict[str, float], N: int, ce: float) -> str:
126
+ ok, _ = ground_truth_verify(binding, N)
127
+ if ok: return "NONE β€” solved correctly"
128
+ if ce > 100: return "TYPE_A: Structural infeasibility β€” constraints contradict, redesign isomorphism"
129
+ result = extract_factors_from_binding(binding, N)
130
+ if result is None:
131
+ if any(abs(v - round(v)) > 0.3 for v in binding.values() if math.isfinite(v)):
132
+ return "TYPE_D: Integrality failure β€” optimizer stuck between integers"
133
+ return "TYPE_C: Wrong abstraction β€” inverse map broken, can't extract factors"
134
+ p, q = result
135
+ if p * q != N:
136
+ if abs(p * q - N) / N < 0.1: return "TYPE_D: Precision issue β€” close but not exact"
137
+ return "TYPE_C: Wrong abstraction β€” extracted integers don't multiply to N"
138
+ return "TYPE_B: Optimization landscape β€” increase rays or change initialization"
139
+
140
+ # ══════════════════════════════════════════════════════════════════════
141
+ # SECTION C: LLM PROMPTS & STRUCTURAL TEMPLATES
142
+ # ══════════════════════════════════════════════════════════════════════
143
+
144
+ NOVEL_ISOMORPHISM_DISCOVERY_PROMPT = """\
145
+ You are an isomorphism designer. Your task is to invent a continuous optimization encoding for integer factorization of N.
146
+ HARD REQUIREMENTS:
147
+ 1. INVERSE MAP: Write f() and g() explicitly. g() must output exact integers.
148
+ 2. MANUAL VERIFICATION: Show your objective evaluates to 0 for N=15, 35, 85 at the exact factor values.
149
+ 3. LANDSCAPE: Explain local minima and why descent won't get trapped.
150
+ 4. UNIQUENESS: Are the factors the ONLY zeros in [2, sqrt(N)]?
151
+ 5. PSL TEMPLATE: Write the full ready-to-run block with tight bounds and GEQ guards.
152
+ Do NOT propose an isomorphism if you cannot answer these 5 constraints.
153
+ """
154
+
155
+ ENCODER_PROMPT = """You are the Encoder. CRITICAL RULE: Every problem MUST include an explicit INVERSE MAP in the description.
156
+ If variables are x,y: inverse map is p=round(x), q=round(y).
157
+ If variable is t: inverse map is p=round(t), q=N//p.
158
+ OUTPUT SCHEMA (JSON only):
159
+ {"name": string, "description": string, "variables": [{"name": string, "lo": number, "hi": number, "is_int": boolean}], "constraints": [{"kind": "EQ"|"GEQ"|"LEQ", "expr": string, "weight": number}], "anchors": [], "observations": {"variable_name": number}}
160
+ RULES: Use ** for exponents. Variables > 10000 encode in log2 space."""
161
+
162
+ COLLAPSER_PROMPT = """You are the Grounded Hypothesis Collapser.
163
+ HARD RULE: For factorization problems, ALWAYS compute the integers (p, q) and verify p*q=N.
164
+ If product != N: this is UNSOLVED even if CE is low. State this explicitly.
165
+ OUTPUT SCHEMA (JSON only):
166
+ {"scaled_formulas": {"metric": "expr"}, "hypothesis_markdown": "## Markdown output"}"""
167
+
168
+ STRUCTURAL_HYPOTHESIS_TEMPLATES = {
169
+ "Fermat Algebraic (Exact Bijection)": """\
170
+ CONCRETE HYPOTHESIS: Fermat Algebraic Factorization
171
+ ====================================================
172
+ N = p*q is equivalent to 4N = s^2 - d^2
173
+ where s = p+q and d = p-q.
174
+ Factors: p = (s+d)/2, q = (s-d)/2.
175
+
176
+ MINIMIZE: d
177
+
178
+ Variables:
179
+ s in [2.0, 172.0]
180
+ d in [0.0, 84.0]
181
+ sum_sq in [340.0, 340.0]
182
+ p in [1.0, 85.0]
183
+ q in [1.0, 85.0]
184
+
185
+ Constraints:
186
+ EQ weight=100: sum_sq - (s**2 - d**2)
187
+ EQ weight=100: sum_sq - 340.0
188
+ EQ weight=10: p - (s + d) / 2.0
189
+ EQ weight=10: q - (s - d) / 2.0
190
+ GEQ: s - d - 2.0
191
+ GEQ: d - 0.0
192
+ GEQ: s - 2.0
193
+
194
+ Anchor: sum_sq - 340.0 = 0 (tolerance 0.001).
195
+ Observation: sum_sq = 340.0.
196
+ """,
197
+ "1D Sine Snap (Fixed Parameterization)": """\
198
+ CONCRETE HYPOTHESIS: 1D Sine-Snap Factorization (Fixed)
199
+ =========================================================
200
+ Key fix: only ONE free variable t. y is derived as N/t.
201
+ Eliminates y=0 collapse entirely.
202
+
203
+ MINIMIZE: snap
204
+
205
+ Variables:
206
+ t in [2.0, 9.0]
207
+ snap in [0.0, 2.0]
208
+
209
+ Constraints:
210
+ EQ weight=10: snap - (sin(t * 3.14159265)**2 + sin(85.0 / t * 3.14159265)**2)
211
+ GEQ: t - 2.0
212
+ LEQ: t - 9.0
213
+
214
+ Anchor: snap = 0 (tolerance 0.01).
215
+ Observation: snap = 0.0.
216
+ """
217
+ }