1# Copyright 2018 The Cirq Developers 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import pytest 16 17import cirq 18import cirq.testing 19 20 21def test_validation(): 22 a = cirq.NamedQubit('a') 23 b = cirq.NamedQubit('b') 24 c = cirq.NamedQubit('c') 25 d = cirq.NamedQubit('d') 26 27 _ = cirq.Moment([]) 28 _ = cirq.Moment([cirq.X(a)]) 29 _ = cirq.Moment([cirq.CZ(a, b)]) 30 _ = cirq.Moment([cirq.CZ(b, d)]) 31 _ = cirq.Moment([cirq.CZ(a, b), cirq.CZ(c, d)]) 32 _ = cirq.Moment([cirq.CZ(a, c), cirq.CZ(b, d)]) 33 _ = cirq.Moment([cirq.CZ(a, c), cirq.X(b)]) 34 35 with pytest.raises(ValueError): 36 _ = cirq.Moment([cirq.X(a), cirq.X(a)]) 37 with pytest.raises(ValueError): 38 _ = cirq.Moment([cirq.CZ(a, c), cirq.X(c)]) 39 with pytest.raises(ValueError): 40 _ = cirq.Moment([cirq.CZ(a, c), cirq.CZ(c, d)]) 41 42 43def test_equality(): 44 a = cirq.NamedQubit('a') 45 b = cirq.NamedQubit('b') 46 c = cirq.NamedQubit('c') 47 d = cirq.NamedQubit('d') 48 49 eq = cirq.testing.EqualsTester() 50 51 # Default is empty. Iterables get frozen into tuples. 52 eq.add_equality_group(cirq.Moment(), cirq.Moment([]), cirq.Moment(())) 53 eq.add_equality_group(cirq.Moment([cirq.X(d)]), cirq.Moment((cirq.X(d),))) 54 55 # Equality depends on gate and qubits. 56 eq.add_equality_group(cirq.Moment([cirq.X(a)])) 57 eq.add_equality_group(cirq.Moment([cirq.X(b)])) 58 eq.add_equality_group(cirq.Moment([cirq.Y(a)])) 59 60 # Equality doesn't depend on order. 61 eq.add_equality_group(cirq.Moment([cirq.X(a), cirq.X(b)]), cirq.Moment([cirq.X(a), cirq.X(b)])) 62 63 # Two qubit gates. 64 eq.make_equality_group(lambda: cirq.Moment([cirq.CZ(c, d)])) 65 eq.make_equality_group(lambda: cirq.Moment([cirq.CZ(a, c)])) 66 eq.make_equality_group(lambda: cirq.Moment([cirq.CZ(a, b), cirq.CZ(c, d)])) 67 eq.make_equality_group(lambda: cirq.Moment([cirq.CZ(a, c), cirq.CZ(b, d)])) 68 69 70def test_approx_eq(): 71 a = cirq.NamedQubit('a') 72 b = cirq.NamedQubit('b') 73 74 assert not cirq.approx_eq(cirq.Moment([cirq.X(a)]), cirq.X(a)) 75 76 # Default is empty. Iterables get frozen into tuples. 77 assert cirq.approx_eq(cirq.Moment(), cirq.Moment([])) 78 assert cirq.approx_eq(cirq.Moment([]), cirq.Moment(())) 79 80 assert cirq.approx_eq(cirq.Moment([cirq.X(a)]), cirq.Moment([cirq.X(a)])) 81 assert not cirq.approx_eq(cirq.Moment([cirq.X(a)]), cirq.Moment([cirq.X(b)])) 82 83 assert cirq.approx_eq( 84 cirq.Moment([cirq.XPowGate(exponent=0)(a)]), cirq.Moment([cirq.XPowGate(exponent=1e-9)(a)]) 85 ) 86 assert not cirq.approx_eq( 87 cirq.Moment([cirq.XPowGate(exponent=0)(a)]), cirq.Moment([cirq.XPowGate(exponent=1e-7)(a)]) 88 ) 89 assert cirq.approx_eq( 90 cirq.Moment([cirq.XPowGate(exponent=0)(a)]), 91 cirq.Moment([cirq.XPowGate(exponent=1e-7)(a)]), 92 atol=1e-6, 93 ) 94 95 96def test_operates_on_single_qubit(): 97 a = cirq.NamedQubit('a') 98 b = cirq.NamedQubit('b') 99 c = cirq.NamedQubit('c') 100 101 # Empty case. 102 assert not cirq.Moment().operates_on_single_qubit(a) 103 assert not cirq.Moment().operates_on_single_qubit(b) 104 105 # One-qubit operation case. 106 assert cirq.Moment([cirq.X(a)]).operates_on_single_qubit(a) 107 assert not cirq.Moment([cirq.X(a)]).operates_on_single_qubit(b) 108 109 # Two-qubit operation case. 110 assert cirq.Moment([cirq.CZ(a, b)]).operates_on_single_qubit(a) 111 assert cirq.Moment([cirq.CZ(a, b)]).operates_on_single_qubit(b) 112 assert not cirq.Moment([cirq.CZ(a, b)]).operates_on_single_qubit(c) 113 114 # Multiple operations case. 115 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on_single_qubit(a) 116 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on_single_qubit(b) 117 assert not cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on_single_qubit(c) 118 119 120def test_operates_on(): 121 a = cirq.NamedQubit('a') 122 b = cirq.NamedQubit('b') 123 c = cirq.NamedQubit('c') 124 125 # Empty case. 126 assert not cirq.Moment().operates_on([]) 127 assert not cirq.Moment().operates_on([a]) 128 assert not cirq.Moment().operates_on([b]) 129 assert not cirq.Moment().operates_on([a, b]) 130 131 # One-qubit operation case. 132 assert not cirq.Moment([cirq.X(a)]).operates_on([]) 133 assert cirq.Moment([cirq.X(a)]).operates_on([a]) 134 assert not cirq.Moment([cirq.X(a)]).operates_on([b]) 135 assert cirq.Moment([cirq.X(a)]).operates_on([a, b]) 136 137 # Two-qubit operation case. 138 assert not cirq.Moment([cirq.CZ(a, b)]).operates_on([]) 139 assert cirq.Moment([cirq.CZ(a, b)]).operates_on([a]) 140 assert cirq.Moment([cirq.CZ(a, b)]).operates_on([b]) 141 assert cirq.Moment([cirq.CZ(a, b)]).operates_on([a, b]) 142 assert not cirq.Moment([cirq.CZ(a, b)]).operates_on([c]) 143 assert cirq.Moment([cirq.CZ(a, b)]).operates_on([a, c]) 144 assert cirq.Moment([cirq.CZ(a, b)]).operates_on([a, b, c]) 145 146 # Multiple operations case. 147 assert not cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([]) 148 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([a]) 149 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([b]) 150 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([a, b]) 151 assert not cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([c]) 152 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([a, c]) 153 assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([a, b, c]) 154 155 156def test_operation_at(): 157 a = cirq.NamedQubit('a') 158 b = cirq.NamedQubit('b') 159 c = cirq.NamedQubit('c') 160 161 # No operation on that qubit 162 assert cirq.Moment().operation_at(a) is None 163 164 # One Operation on the quibt 165 assert cirq.Moment([cirq.X(a)]).operation_at(a) == cirq.X(a) 166 167 # Multiple Operations on the qubits 168 assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).operation_at(a) == cirq.CZ(a, b) 169 170 171def test_with_operation(): 172 a = cirq.NamedQubit('a') 173 b = cirq.NamedQubit('b') 174 175 assert cirq.Moment().with_operation(cirq.X(a)) == cirq.Moment([cirq.X(a)]) 176 177 assert cirq.Moment([cirq.X(a)]).with_operation(cirq.X(b)) == cirq.Moment([cirq.X(a), cirq.X(b)]) 178 179 # One-qubit operation case. 180 with pytest.raises(ValueError): 181 _ = cirq.Moment([cirq.X(a)]).with_operation(cirq.X(a)) 182 183 # Two-qubit operation case. 184 with pytest.raises(ValueError): 185 _ = cirq.Moment([cirq.CZ(a, b)]).with_operation(cirq.X(a)) 186 with pytest.raises(ValueError): 187 _ = cirq.Moment([cirq.CZ(a, b)]).with_operation(cirq.X(b)) 188 189 # Multiple operations case. 190 with pytest.raises(ValueError): 191 _ = cirq.Moment([cirq.X(a), cirq.X(b)]).with_operation(cirq.X(a)) 192 with pytest.raises(ValueError): 193 _ = cirq.Moment([cirq.X(a), cirq.X(b)]).with_operation(cirq.X(b)) 194 195 196def test_with_operations(): 197 a = cirq.NamedQubit('a') 198 b = cirq.NamedQubit('b') 199 c = cirq.NamedQubit('c') 200 201 assert cirq.Moment().with_operations(cirq.X(a)) == cirq.Moment([cirq.X(a)]) 202 assert cirq.Moment().with_operations(cirq.X(a), cirq.X(b)) == cirq.Moment( 203 [cirq.X(a), cirq.X(b)] 204 ) 205 206 assert cirq.Moment([cirq.X(a)]).with_operations(cirq.X(b)) == cirq.Moment( 207 [cirq.X(a), cirq.X(b)] 208 ) 209 assert cirq.Moment([cirq.X(a)]).with_operations(cirq.X(b), cirq.X(c)) == cirq.Moment( 210 [cirq.X(a), cirq.X(b), cirq.X(c)] 211 ) 212 213 # One-qubit operation case. 214 with pytest.raises(ValueError): 215 _ = cirq.Moment([cirq.X(a)]).with_operations(cirq.X(a)) 216 217 # Two-qubit operation case. 218 with pytest.raises(ValueError): 219 _ = cirq.Moment([cirq.CZ(a, b)]).with_operations(cirq.X(a)) 220 with pytest.raises(ValueError): 221 _ = cirq.Moment([cirq.CZ(a, b)]).with_operations(cirq.X(b)) 222 223 # Multiple operations case. 224 with pytest.raises(ValueError): 225 _ = cirq.Moment([cirq.X(a), cirq.X(b)]).with_operations(cirq.X(a)) 226 with pytest.raises(ValueError): 227 _ = cirq.Moment([cirq.X(a), cirq.X(b)]).with_operations(cirq.X(b)) 228 229 230def test_without_operations_touching(): 231 a = cirq.NamedQubit('a') 232 b = cirq.NamedQubit('b') 233 c = cirq.NamedQubit('c') 234 235 # Empty case. 236 assert cirq.Moment().without_operations_touching([]) == cirq.Moment() 237 assert cirq.Moment().without_operations_touching([a]) == cirq.Moment() 238 assert cirq.Moment().without_operations_touching([a, b]) == cirq.Moment() 239 240 # One-qubit operation case. 241 assert cirq.Moment([cirq.X(a)]).without_operations_touching([]) == cirq.Moment([cirq.X(a)]) 242 assert cirq.Moment([cirq.X(a)]).without_operations_touching([a]) == cirq.Moment() 243 assert cirq.Moment([cirq.X(a)]).without_operations_touching([b]) == cirq.Moment([cirq.X(a)]) 244 245 # Two-qubit operation case. 246 assert cirq.Moment([cirq.CZ(a, b)]).without_operations_touching([]) == cirq.Moment( 247 [cirq.CZ(a, b)] 248 ) 249 assert cirq.Moment([cirq.CZ(a, b)]).without_operations_touching([a]) == cirq.Moment() 250 assert cirq.Moment([cirq.CZ(a, b)]).without_operations_touching([b]) == cirq.Moment() 251 assert cirq.Moment([cirq.CZ(a, b)]).without_operations_touching([c]) == cirq.Moment( 252 [cirq.CZ(a, b)] 253 ) 254 255 # Multiple operation case. 256 assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).without_operations_touching([]) == cirq.Moment( 257 [cirq.CZ(a, b), cirq.X(c)] 258 ) 259 assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).without_operations_touching([a]) == cirq.Moment( 260 [cirq.X(c)] 261 ) 262 assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).without_operations_touching([b]) == cirq.Moment( 263 [cirq.X(c)] 264 ) 265 assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).without_operations_touching([c]) == cirq.Moment( 266 [cirq.CZ(a, b)] 267 ) 268 assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).without_operations_touching( 269 [a, b] 270 ) == cirq.Moment([cirq.X(c)]) 271 assert ( 272 cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).without_operations_touching([a, c]) == cirq.Moment() 273 ) 274 275 276def test_with_measurement_keys(): 277 a, b = cirq.LineQubit.range(2) 278 m = cirq.Moment(cirq.measure(a, key='m1'), cirq.measure(b, key='m2')) 279 280 new_moment = cirq.with_measurement_key_mapping( 281 m, 282 { 283 'm1': 'p1', 284 'm2': 'p2', 285 'x': 'z', 286 }, 287 ) 288 289 assert new_moment.operations[0] == cirq.measure(a, key='p1') 290 assert new_moment.operations[1] == cirq.measure(b, key='p2') 291 292 293def test_with_key_path(): 294 a, b = cirq.LineQubit.range(2) 295 m = cirq.Moment(cirq.measure(a, key='m1'), cirq.measure(b, key='m2')) 296 297 new_moment = cirq.with_key_path(m, ('a', 'b')) 298 299 assert new_moment.operations[0] == cirq.measure( 300 a, key=cirq.MeasurementKey.parse_serialized('a:b:m1') 301 ) 302 assert new_moment.operations[1] == cirq.measure( 303 b, key=cirq.MeasurementKey.parse_serialized('a:b:m2') 304 ) 305 306 307def test_copy(): 308 a = cirq.NamedQubit('a') 309 b = cirq.NamedQubit('b') 310 original = cirq.Moment([cirq.CZ(a, b)]) 311 copy = original.__copy__() 312 assert original == copy 313 assert id(original) != id(copy) 314 315 316def test_qubits(): 317 a = cirq.NamedQubit('a') 318 b = cirq.NamedQubit('b') 319 320 assert cirq.Moment([cirq.X(a), cirq.X(b)]).qubits == {a, b} 321 assert cirq.Moment([cirq.X(a)]).qubits == {a} 322 assert cirq.Moment([cirq.CZ(a, b)]).qubits == {a, b} 323 324 325def test_container_methods(): 326 a = cirq.NamedQubit('a') 327 b = cirq.NamedQubit('b') 328 m = cirq.Moment([cirq.H(a), cirq.H(b)]) 329 assert list(m) == list(m.operations) 330 # __iter__ 331 assert list(iter(m)) == list(m.operations) 332 # __contains__ for free. 333 assert cirq.H(b) in m 334 335 assert len(m) == 2 336 337 338def test_decompose(): 339 a = cirq.NamedQubit('a') 340 b = cirq.NamedQubit('b') 341 m = cirq.Moment(cirq.X(a), cirq.X(b)) 342 assert list(cirq.decompose(m)) == list(m.operations) 343 344 345def test_measurement_keys(): 346 a = cirq.NamedQubit('a') 347 b = cirq.NamedQubit('b') 348 m = cirq.Moment(cirq.X(a), cirq.X(b)) 349 assert cirq.measurement_key_names(m) == set() 350 assert not cirq.is_measurement(m) 351 352 m2 = cirq.Moment(cirq.measure(a, b, key='foo')) 353 assert cirq.measurement_key_objs(m2) == {cirq.MeasurementKey('foo')} 354 assert cirq.measurement_key_names(m2) == {'foo'} 355 assert cirq.is_measurement(m2) 356 357 358def test_bool(): 359 assert not cirq.Moment() 360 a = cirq.NamedQubit('a') 361 assert cirq.Moment([cirq.X(a)]) 362 363 364def test_repr(): 365 a = cirq.NamedQubit('a') 366 b = cirq.NamedQubit('b') 367 368 cirq.testing.assert_equivalent_repr(cirq.Moment()) 369 cirq.testing.assert_equivalent_repr(cirq.Moment(cirq.CZ(a, b))) 370 cirq.testing.assert_equivalent_repr(cirq.Moment(cirq.X(a), cirq.Y(b))) 371 372 373def test_json_dict(): 374 a = cirq.NamedQubit('a') 375 b = cirq.NamedQubit('b') 376 mom = cirq.Moment([cirq.CZ(a, b)]) 377 assert mom._json_dict_() == {'cirq_type': 'Moment', 'operations': (cirq.CZ(a, b),)} 378 379 380def test_inverse(): 381 a, b, c = cirq.LineQubit.range(3) 382 m = cirq.Moment([cirq.S(a), cirq.CNOT(b, c)]) 383 assert m ** 1 is m 384 assert m ** -1 == cirq.Moment([cirq.S(a) ** -1, cirq.CNOT(b, c)]) 385 assert m ** 0.5 == cirq.Moment([cirq.T(a), cirq.CNOT(b, c) ** 0.5]) 386 assert cirq.inverse(m) == m ** -1 387 assert cirq.inverse(cirq.inverse(m)) == m 388 assert cirq.inverse(cirq.Moment([cirq.measure(a)]), default=None) is None 389 390 391def test_immutable_moment(): 392 with pytest.raises(AttributeError): 393 q1, q2 = cirq.LineQubit.range(2) 394 circuit = cirq.Circuit(cirq.X(q1)) 395 moment = circuit.moments[0] 396 moment.operations += (cirq.Y(q2),) 397 398 399def test_add(): 400 a, b, c = cirq.LineQubit.range(3) 401 expected_circuit = cirq.Circuit([cirq.CNOT(a, b), cirq.X(a), cirq.Y(b)]) 402 403 circuit1 = cirq.Circuit([cirq.CNOT(a, b), cirq.X(a)]) 404 circuit1[1] += cirq.Y(b) 405 assert circuit1 == expected_circuit 406 407 circuit2 = cirq.Circuit(cirq.CNOT(a, b), cirq.Y(b)) 408 circuit2[1] += cirq.X(a) 409 assert circuit2 == expected_circuit 410 411 m1 = cirq.Moment([cirq.X(a)]) 412 m2 = cirq.Moment([cirq.CNOT(a, b)]) 413 m3 = cirq.Moment([cirq.X(c)]) 414 assert m1 + m3 == cirq.Moment([cirq.X(a), cirq.X(c)]) 415 assert m2 + m3 == cirq.Moment([cirq.CNOT(a, b), cirq.X(c)]) 416 with pytest.raises(ValueError, match='Overlap'): 417 _ = m1 + m2 418 419 assert m1 + [[[[cirq.Y(b)]]]] == cirq.Moment(cirq.X(a), cirq.Y(b)) 420 assert m1 + [] == m1 421 422 423def test_sub(): 424 a, b, c = cirq.LineQubit.range(3) 425 m = cirq.Moment(cirq.X(a), cirq.Y(b)) 426 assert m - [] == m 427 assert m - cirq.X(a) == cirq.Moment(cirq.Y(b)) 428 assert m - [[[[cirq.X(a)]], []]] == cirq.Moment(cirq.Y(b)) 429 assert m - [cirq.X(a), cirq.Y(b)] == cirq.Moment() 430 assert m - [cirq.Y(b)] == cirq.Moment(cirq.X(a)) 431 432 with pytest.raises(ValueError, match="missing operations"): 433 _ = m - cirq.X(b) 434 with pytest.raises(ValueError, match="missing operations"): 435 _ = m - [cirq.X(a), cirq.Z(c)] 436 437 # Preserves relative order. 438 m2 = cirq.Moment(cirq.X(a), cirq.Y(b), cirq.Z(c)) 439 assert m2 - cirq.Y(b) == cirq.Moment(cirq.X(a), cirq.Z(c)) 440 441 442def test_op_tree(): 443 eq = cirq.testing.EqualsTester() 444 a, b = cirq.LineQubit.range(2) 445 446 eq.add_equality_group( 447 cirq.Moment(), 448 cirq.Moment([]), 449 cirq.Moment([[], [[[]]]]), 450 ) 451 452 eq.add_equality_group( 453 cirq.Moment(cirq.X(a)), 454 cirq.Moment([cirq.X(a)]), 455 cirq.Moment({cirq.X(a)}), 456 ) 457 458 eq.add_equality_group( 459 cirq.Moment(cirq.X(a), cirq.Y(b)), 460 cirq.Moment([cirq.X(a), cirq.Y(b)]), 461 ) 462 463 464def test_indexes_by_qubit(): 465 a, b, c = cirq.LineQubit.range(3) 466 moment = cirq.Moment([cirq.H(a), cirq.CNOT(b, c)]) 467 468 assert moment[a] == cirq.H(a) 469 assert moment[b] == cirq.CNOT(b, c) 470 assert moment[c] == cirq.CNOT(b, c) 471 472 473def test_throws_when_indexed_by_unused_qubit(): 474 a, b = cirq.LineQubit.range(2) 475 moment = cirq.Moment([cirq.H(a)]) 476 477 with pytest.raises(KeyError, match="Moment doesn't act on given qubit"): 478 _ = moment[b] 479 480 481def test_indexes_by_list_of_qubits(): 482 q = cirq.LineQubit.range(4) 483 moment = cirq.Moment([cirq.Z(q[0]), cirq.CNOT(q[1], q[2])]) 484 485 assert moment[[q[0]]] == cirq.Moment([cirq.Z(q[0])]) 486 assert moment[[q[1]]] == cirq.Moment([cirq.CNOT(q[1], q[2])]) 487 assert moment[[q[2]]] == cirq.Moment([cirq.CNOT(q[1], q[2])]) 488 assert moment[[q[3]]] == cirq.Moment([]) 489 assert moment[q[0:2]] == moment 490 assert moment[q[1:3]] == cirq.Moment([cirq.CNOT(q[1], q[2])]) 491 assert moment[q[2:4]] == cirq.Moment([cirq.CNOT(q[1], q[2])]) 492 assert moment[[q[0], q[3]]] == cirq.Moment([cirq.Z(q[0])]) 493 assert moment[q] == moment 494 495 496def test_moment_text_diagram(): 497 a, b, c, d = cirq.GridQubit.rect(2, 2) 498 m = cirq.Moment(cirq.CZ(a, b), cirq.CNOT(c, d)) 499 assert ( 500 str(m).strip() 501 == """ 502 ╷ 0 1 503╶─┼───── 5040 │ @─@ 505 │ 5061 │ @─X 507 │ 508 """.strip() 509 ) 510 511 m = cirq.Moment(cirq.CZ(a, b), cirq.CNOT(c, d)) 512 cirq.testing.assert_has_diagram( 513 m, 514 """ 515 ╷ None 0 1 516╶──┼────────── 517aa │ 518 │ 5190 │ @─@ 520 │ 5211 │ @─X 522 │ 523 """, 524 extra_qubits=[cirq.NamedQubit("aa")], 525 ) 526 527 m = cirq.Moment(cirq.S(c), cirq.ISWAP(a, d)) 528 cirq.testing.assert_has_diagram( 529 m, 530 """ 531 ╷ 0 1 532╶─┼───────────── 5330 │ iSwap─┐ 534 │ │ 5351 │ S iSwap 536 │ 537 """, 538 ) 539 540 m = cirq.Moment(cirq.S(c) ** 0.1, cirq.ISWAP(a, d) ** 0.5) 541 cirq.testing.assert_has_diagram( 542 m, 543 """ 544 ╷ 0 1 545╶─┼───────────────── 5460 │ iSwap^0.5─┐ 547 │ │ 5481 │ Z^0.05 iSwap 549 │ 550 """, 551 ) 552 553 a, b, c = cirq.LineQubit.range(3) 554 m = cirq.Moment(cirq.X(a), cirq.SWAP(b, c)) 555 cirq.testing.assert_has_diagram( 556 m, 557 """ 558 ╷ a b c 559╶─┼─────── 5600 │ X 561 │ 5621 │ ×─┐ 563 │ │ 5642 │ × 565 │ 566 """, 567 xy_breakdown_func=lambda q: ('abc'[q.x], q.x), 568 ) 569 570 class EmptyGate(cirq.Gate): 571 def _num_qubits_(self) -> int: 572 return 1 573 574 def __str__(self): 575 return 'Empty' 576 577 m = cirq.Moment(EmptyGate().on(a)) 578 cirq.testing.assert_has_diagram( 579 m, 580 """ 581 ╷ 0 582╶─┼─────── 5830 │ Empty 584 │ 585 """, 586 ) 587 588 589def test_commutes(): 590 a = cirq.NamedQubit('a') 591 b = cirq.NamedQubit('b') 592 c = cirq.NamedQubit('c') 593 d = cirq.NamedQubit('d') 594 595 moment = cirq.Moment([cirq.X(a), cirq.Y(b), cirq.H(c)]) 596 597 assert NotImplemented == cirq.commutes(moment, a, default=NotImplemented) 598 599 assert cirq.commutes(moment, cirq.X(a)) 600 assert cirq.commutes(moment, cirq.Y(b)) 601 assert cirq.commutes(moment, cirq.H(c)) 602 assert cirq.commutes(moment, cirq.H(d)) 603 604 # X and H do not commute 605 assert not cirq.commutes(moment, cirq.H(a)) 606 assert not cirq.commutes(moment, cirq.H(b)) 607 assert not cirq.commutes(moment, cirq.X(c)) 608 609 610def test_transform_qubits(): 611 a, b = cirq.LineQubit.range(2) 612 x, y = cirq.GridQubit.rect(2, 1, 10, 20) 613 614 original = cirq.Moment([cirq.X(a), cirq.Y(b)]) 615 modified = cirq.Moment([cirq.X(x), cirq.Y(y)]) 616 617 assert original.transform_qubits({a: x, b: y}) == modified 618 assert original.transform_qubits(lambda q: cirq.GridQubit(10 + q.x, 20)) == modified 619 with pytest.raises(TypeError, match='must be a function or dict'): 620 _ = original.transform_qubits('bad arg') 621