Spaces:
Sleeping
Sleeping
aishani-s20 commited on
Commit ·
b3dfb35
1
Parent(s): 3188877
improvement
Browse files- README.md +1 -1
- inference.py +1 -1
- models.py +1 -1
- server/quantum_openenv_env_environment.py +24 -8
README.md
CHANGED
|
@@ -74,7 +74,7 @@ Current LLM benchmarks rely on static toy puzzles. This environment bridges the
|
|
| 74 |
| `1` | **Cancel Identical Gates** | Removes self-inverse gate pairs (X·X=I, H·H=I, CNOT·CNOT=I) on the same qubits, not blocked by overlapping intermediate gates. | `+1.0` |
|
| 75 |
| `2` | **Swap Commuting Gates** | Swaps the target gate with the next adjacent gate **only if** their qubit sets do not intersect. Enables bringing distant cancellable pairs together. | `-0.05` |
|
| 76 |
| `3` | **H-X-H Identity Collapse** | Replaces a `H → X → H` sequence on the same qubit with a single `Z` gate (net: 2 gates removed). | `+2.0` |
|
| 77 |
-
| `4` | **Entanglement Compression** | Replaces
|
| 78 |
|
| 79 |
> **Invalid actions** (out-of-bounds index, illegal non-commuting swap, pattern not present) incur a `-0.10` penalty. Circuit state remains unchanged.
|
| 80 |
|
|
|
|
| 74 |
| `1` | **Cancel Identical Gates** | Removes self-inverse gate pairs (X·X=I, H·H=I, CNOT·CNOT=I) on the same qubits, not blocked by overlapping intermediate gates. | `+1.0` |
|
| 75 |
| `2` | **Swap Commuting Gates** | Swaps the target gate with the next adjacent gate **only if** their qubit sets do not intersect. Enables bringing distant cancellable pairs together. | `-0.05` |
|
| 76 |
| `3` | **H-X-H Identity Collapse** | Replaces a `H → X → H` sequence on the same qubit with a single `Z` gate (net: 2 gates removed). | `+2.0` |
|
| 77 |
+
| `4` | **Entanglement Compression** | Replaces a `CNOT(a,b) → CNOT(b,a) → CNOT(a,b)` sequence with a single `SWAP` gate — a standard compiler identity (net: 2 gates removed). | `+2.0` |
|
| 78 |
|
| 79 |
> **Invalid actions** (out-of-bounds index, illegal non-commuting swap, pattern not present) incur a `-0.10` penalty. Circuit state remains unchanged.
|
| 80 |
|
inference.py
CHANGED
|
@@ -79,7 +79,7 @@ SYSTEM_PROMPT = textwrap.dedent(
|
|
| 79 |
the same qubits, not blocked by intermediate gates sharing those qubits.
|
| 80 |
Action 2: Swap adjacent commuting gates (gates on entirely non-overlapping qubits).
|
| 81 |
Action 3: Replace an H-X-H sequence on the same qubit with a Z gate.
|
| 82 |
-
Action 4: Replace a CNOT
|
| 83 |
|
| 84 |
You MUST output ONLY a valid JSON object with exactly two keys:
|
| 85 |
"target_index" (integer) and "action_type" (integer 1-4).
|
|
|
|
| 79 |
the same qubits, not blocked by intermediate gates sharing those qubits.
|
| 80 |
Action 2: Swap adjacent commuting gates (gates on entirely non-overlapping qubits).
|
| 81 |
Action 3: Replace an H-X-H sequence on the same qubit with a Z gate.
|
| 82 |
+
Action 4: Replace a CNOT(a,b)→CNOT(b,a)→CNOT(a,b) sequence with a single SWAP gate (3 alternating CNOTs collapse to 1 SWAP).
|
| 83 |
|
| 84 |
You MUST output ONLY a valid JSON object with exactly two keys:
|
| 85 |
"target_index" (integer) and "action_type" (integer 1-4).
|
models.py
CHANGED
|
@@ -41,7 +41,7 @@ class QuantumAction(Action):
|
|
| 41 |
default=1,
|
| 42 |
ge=1, # Minimum action type is 1
|
| 43 |
le=4, # Maximum action type is 4
|
| 44 |
-
description="1: Cancel identical gates, 2: Swap commuting gates, 3: Replace H-X-H with Z, 4: Replace
|
| 45 |
)
|
| 46 |
|
| 47 |
|
|
|
|
| 41 |
default=1,
|
| 42 |
ge=1, # Minimum action type is 1
|
| 43 |
le=4, # Maximum action type is 4
|
| 44 |
+
description="1: Cancel identical gates, 2: Swap commuting gates, 3: Replace H-X-H with Z, 4: Replace 3-CNOT sequence with SWAP"
|
| 45 |
)
|
| 46 |
|
| 47 |
|
server/quantum_openenv_env_environment.py
CHANGED
|
@@ -71,6 +71,16 @@ class TaskConfig:
|
|
| 71 |
insert_idx_2 = rng.randint(insert_idx_1, len(circuit))
|
| 72 |
circuit.insert(insert_idx_2, gate2)
|
| 73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
return circuit
|
| 75 |
|
| 76 |
|
|
@@ -247,20 +257,26 @@ class QuantumCircuitOptimizationEnvironment(Environment):
|
|
| 247 |
action_result = "identity_hxh_to_z"
|
| 248 |
self._used_advanced_actions = True
|
| 249 |
|
| 250 |
-
# ACTION 4: Replace CNOT
|
| 251 |
elif action_type == 4:
|
| 252 |
-
if target_index +
|
| 253 |
g1 = self._circuit[target_index]
|
| 254 |
g2 = self._circuit[target_index + 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
|
| 256 |
-
if (g1.name == "CNOT" and g2.name == "
|
| 257 |
-
|
|
|
|
|
|
|
| 258 |
self._circuit.pop(target_index + 1)
|
| 259 |
self._circuit[target_index] = QuantumGate(
|
| 260 |
-
name="
|
| 261 |
)
|
| 262 |
-
reward =
|
| 263 |
-
action_result = "
|
| 264 |
self._used_advanced_actions = True
|
| 265 |
|
| 266 |
return self._build_observation(reward, action_result)
|
|
@@ -377,7 +393,7 @@ class QuantumCircuitOptimizationEnvironment(Environment):
|
|
| 377 |
"1: Cancel identical self-inverse gates (H, X, Y, Z, CNOT, SWAP).\n\n"
|
| 378 |
"2: Swap adjacent commuting gates (gates not sharing qubits).\n\n"
|
| 379 |
"3: Replace an H-X-H sequence with a Z gate.\n\n"
|
| 380 |
-
"4: Replace a
|
| 381 |
"CURRENT CIRCUIT STATE:\n\n"
|
| 382 |
)
|
| 383 |
|
|
|
|
| 71 |
insert_idx_2 = rng.randint(insert_idx_1, len(circuit))
|
| 72 |
circuit.insert(insert_idx_2, gate2)
|
| 73 |
|
| 74 |
+
if self.use_entangling and self.num_qubits > 1:
|
| 75 |
+
num_patterns = 1 if self.name == "medium" else 2 # hard gets 2
|
| 76 |
+
for _ in range(num_patterns):
|
| 77 |
+
if rng.random() > 0.3: # 70% chance per pattern, keeps it non-deterministic
|
| 78 |
+
q1, q2 = rng.sample(range(self.num_qubits), 2)
|
| 79 |
+
insert_at = rng.randint(0, len(circuit))
|
| 80 |
+
circuit.insert(insert_at, QuantumGate(name="CNOT", target_qubits=[q1, q2]))
|
| 81 |
+
circuit.insert(insert_at + 1, QuantumGate(name="CNOT", target_qubits=[q2, q1]))
|
| 82 |
+
circuit.insert(insert_at + 2, QuantumGate(name="CNOT", target_qubits=[q1, q2]))
|
| 83 |
+
|
| 84 |
return circuit
|
| 85 |
|
| 86 |
|
|
|
|
| 257 |
action_result = "identity_hxh_to_z"
|
| 258 |
self._used_advanced_actions = True
|
| 259 |
|
| 260 |
+
# ACTION 4: Replace CNOT(a,b)→CNOT(b,a)→CNOT(a,b) with SWAP (advanced identity)
|
| 261 |
elif action_type == 4:
|
| 262 |
+
if target_index + 2 < len(self._circuit):
|
| 263 |
g1 = self._circuit[target_index]
|
| 264 |
g2 = self._circuit[target_index + 1]
|
| 265 |
+
g3 = self._circuit[target_index + 2]
|
| 266 |
+
|
| 267 |
+
qubits_ab = g1.target_qubits # e.g. [0, 1]
|
| 268 |
+
qubits_ba = list(reversed(g1.target_qubits)) # e.g. [1, 0]
|
| 269 |
|
| 270 |
+
if (g1.name == "CNOT" and g2.name == "CNOT" and g3.name == "CNOT" and
|
| 271 |
+
g1.target_qubits == g3.target_qubits and
|
| 272 |
+
g2.target_qubits == qubits_ba):
|
| 273 |
+
self._circuit.pop(target_index + 2)
|
| 274 |
self._circuit.pop(target_index + 1)
|
| 275 |
self._circuit[target_index] = QuantumGate(
|
| 276 |
+
name="SWAP", target_qubits=g1.target_qubits
|
| 277 |
)
|
| 278 |
+
reward = 2.0 # saves 2 gates, same as H-X-H identity
|
| 279 |
+
action_result = "identity_3cnot_to_swap"
|
| 280 |
self._used_advanced_actions = True
|
| 281 |
|
| 282 |
return self._build_observation(reward, action_result)
|
|
|
|
| 393 |
"1: Cancel identical self-inverse gates (H, X, Y, Z, CNOT, SWAP).\n\n"
|
| 394 |
"2: Swap adjacent commuting gates (gates not sharing qubits).\n\n"
|
| 395 |
"3: Replace an H-X-H sequence with a Z gate.\n\n"
|
| 396 |
+
"4: Replace CNOT(a,b)→CNOT(b,a)→CNOT(a,b) with a single SWAP gate.\n\n"
|
| 397 |
"CURRENT CIRCUIT STATE:\n\n"
|
| 398 |
)
|
| 399 |
|