18
18
"""
19
19
import abc
20
20
import collections
21
- import json
22
21
23
22
from numbers import Complex
24
23
from typing import (
@@ -125,16 +124,26 @@ def __hash__(self) -> int:
125
124
def _convert_to_rs_instruction (instr : AbstractInstruction ) -> quil_rs .Instruction :
126
125
if isinstance (instr , quil_rs .Instruction ):
127
126
return instr
128
- if isinstance (instr , AbstractInstruction ):
129
- return quil_rs .Instruction (instr )
130
127
if isinstance (instr , quil_rs .Calibration ):
131
128
return quil_rs .Instruction .from_calibration_definition (instr )
129
+ if isinstance (instr , quil_rs .Declaration ):
130
+ return quil_rs .Instruction .from_declaration (instr )
131
+ if isinstance (instr , quil_rs .Delay ):
132
+ return quil_rs .Instruction .from_delay (instr )
133
+ if isinstance (instr , quil_rs .Fence ):
134
+ return quil_rs .Instruction .from_fence (instr )
132
135
if isinstance (instr , quil_rs .Gate ):
133
136
return quil_rs .Instruction .from_gate (instr )
134
137
if isinstance (instr , quil_rs .MeasureCalibrationDefinition ):
135
138
return quil_rs .Instruction .from_measure_calibration_definition (instr )
136
139
if isinstance (instr , quil_rs .Measurement ):
137
140
return quil_rs .Instruction .from_measurement (instr )
141
+ if isinstance (instr , quil_rs .Pragma ):
142
+ return quil_rs .Instruction .from_pragma (instr )
143
+ if isinstance (instr , quil_rs .Reset ):
144
+ return quil_rs .Instruction .from_reset (instr )
145
+ if isinstance (instr , AbstractInstruction ):
146
+ return quil_rs .Instruction (instr )
138
147
else :
139
148
raise ValueError (f"{ type (instr )} is not an Instruction" )
140
149
@@ -147,16 +156,24 @@ def _convert_to_py_instruction(instr: quil_rs.Instruction) -> AbstractInstructio
147
156
if isinstance (instr , quil_rs .Instruction ):
148
157
# TODOV4: Will have to handle unit variants since they don't have inner data
149
158
instr = instr .inner ()
150
- if isinstance (instr , quil_rs .Declaration ):
151
- return Declare ._from_rs_declaration (instr )
152
159
if isinstance (instr , quil_rs .Calibration ):
153
160
return DefCalibration ._from_rs_calibration (instr )
161
+ if isinstance (instr , quil_rs .Declaration ):
162
+ return Declare ._from_rs_declaration (instr )
163
+ if isinstance (instr , quil_rs .Delay ):
164
+ return Delay ._from_rs_delay (instr )
165
+ if isinstance (instr , quil_rs .Fence ):
166
+ return Fence ._from_rs_fence (instr )
154
167
if isinstance (instr , quil_rs .Gate ):
155
168
return Gate ._from_rs_gate (instr )
156
169
if isinstance (instr , quil_rs .MeasureCalibrationDefinition ):
157
170
return DefMeasureCalibration ._from_rs_measure_calibration_definition (instr )
158
171
if isinstance (instr , quil_rs .Measurement ):
159
172
return Measurement ._from_rs_measurement (instr )
173
+ if isinstance (instr , quil_rs .Pragma ):
174
+ return Pragma ._from_rs_pragma (instr )
175
+ if isinstance (instr , quil_rs .Reset ):
176
+ return Reset ._from_rs_reset (instr )
160
177
if isinstance (instr , quil_rs .CircuitDefinition ):
161
178
return DefCircuit ._from_rs_circuit_definition (instr )
162
179
if isinstance (instr , quil_rs .GateDefinition ):
@@ -424,24 +441,65 @@ def out(self) -> str:
424
441
return str (self )
425
442
426
443
427
- class ResetQubit ( AbstractInstruction ):
444
+ class Reset ( quil_rs . Reset , AbstractInstruction ):
428
445
"""
429
- This is the pyQuil object for a Quil targeted reset instruction.
446
+ The RESET instruction.
430
447
"""
431
448
432
- def __init__ (self , qubit : Union [Qubit , QubitPlaceholder , FormalArgument ]):
433
- if not isinstance (qubit , (Qubit , QubitPlaceholder , FormalArgument )):
434
- raise TypeError ("qubit should be a Qubit" )
435
- self .qubit = qubit
449
+ def __new__ (cls , qubit : Optional [Union [Qubit , QubitPlaceholder , FormalArgument ]] = None ):
450
+ rs_qubit : Optional [quil_rs .Qubit ] = None
451
+ if qubit is not None :
452
+ rs_qubit = _convert_to_rs_qubit (qubit )
453
+ return super ().__new__ (cls , rs_qubit )
454
+
455
+ @classmethod
456
+ def _from_rs_reset (cls , reset : quil_rs .Reset ) -> "Reset" :
457
+ return super ().__new__ (cls , reset .qubit )
436
458
437
459
def out (self ) -> str :
438
- return "RESET {}" . format (self . qubit . out () )
460
+ return str (self )
439
461
440
- def __str__ (self ) -> str :
441
- return "RESET {}" .format (_format_qubit_str (self .qubit ))
462
+ @deprecated (
463
+ deprecated_in = "4.0" ,
464
+ removed_in = "5.0" ,
465
+ current_version = pyquil_version ,
466
+ details = "The indices flag will be removed, use get_qubit_indices() instead." ,
467
+ )
468
+ def get_qubits (self , indices : bool = True ) -> Optional [Set [QubitDesignator ]]:
469
+ if super ().qubit is None :
470
+ return None
471
+ if indices :
472
+ return self .get_qubit_indices () # type: ignore
473
+ return {_convert_to_py_qubit (super ().qubit )} # type: ignore
474
+
475
+ def get_qubit_indices (self ) -> Optional [Set [int ]]:
476
+ if super ().qubit is None :
477
+ return None
478
+ return {super ().qubit .to_fixed ()} # type: ignore
479
+
480
+ @property
481
+ def qubit (self ) -> Optional [QubitDesignator ]:
482
+ if super ().qubit :
483
+ return _convert_to_py_qubit (super ().qubit ) # type: ignore
484
+ return super ().qubit
485
+
486
+ @qubit .setter
487
+ def qubit (self , qubit : Optional [QubitDesignator ]):
488
+ rs_qubit : Optional [quil_rs .Qubit ] = None
489
+ if qubit is not None :
490
+ rs_qubit = _convert_to_rs_qubit (qubit )
491
+ quil_rs .Reset .qubit .__set__ (self , rs_qubit )
442
492
443
- def get_qubits (self , indices : bool = True ) -> Set [QubitDesignator ]:
444
- return {_extract_qubit_index (self .qubit , indices )}
493
+
494
+ class ResetQubit (Reset ):
495
+ """
496
+ This is the pyQuil object for a Quil targeted reset instruction.
497
+ """
498
+
499
+ def __new__ (cls , qubit : Union [Qubit , QubitPlaceholder , FormalArgument ]):
500
+ if qubit is None :
501
+ raise TypeError ("qubit should not be None" )
502
+ return super ().__new__ (cls , qubit )
445
503
446
504
447
505
class DefGate (quil_rs .GateDefinition , AbstractInstruction ):
@@ -671,14 +729,6 @@ class Wait(SimpleInstruction):
671
729
op = "WAIT"
672
730
673
731
674
- class Reset (SimpleInstruction ):
675
- """
676
- The RESET instruction.
677
- """
678
-
679
- op = "RESET"
680
-
681
-
682
732
class Nop (SimpleInstruction ):
683
733
"""
684
734
The NOP instruction.
@@ -1006,7 +1056,7 @@ def out(self) -> str:
1006
1056
return "JUMP %s" % self .target
1007
1057
1008
1058
1009
- class Pragma (AbstractInstruction ):
1059
+ class Pragma (quil_rs . Pragma , AbstractInstruction ):
1010
1060
"""
1011
1061
A PRAGMA instruction.
1012
1062
@@ -1016,39 +1066,67 @@ class Pragma(AbstractInstruction):
1016
1066
1017
1067
"""
1018
1068
1019
- def __init__ (
1020
- self ,
1069
+ def __new__ (
1070
+ cls ,
1021
1071
command : str ,
1022
1072
args : Iterable [Union [QubitDesignator , str ]] = (),
1023
1073
freeform_string : str = "" ,
1024
- ):
1025
- if not isinstance (command , str ):
1026
- raise TypeError (f"Pragma's require an identifier: { command } " )
1027
-
1028
- if not isinstance (args , collections .abc .Iterable ):
1029
- raise TypeError (f"Pragma arguments must be an Iterable: { args } " )
1030
- for a in args :
1031
- if not (
1032
- isinstance (a , str ) or isinstance (a , int ) or isinstance (a , QubitPlaceholder ) or isinstance (a , Qubit )
1033
- ):
1034
- raise TypeError (f"Pragma arguments must be strings or integers: { a } " )
1035
- if not isinstance (freeform_string , str ):
1036
- raise TypeError (f"The freeform string argument must be a string: { freeform_string } " )
1037
-
1038
- self .command = command
1039
- self .args = tuple (args )
1040
- self .freeform_string = freeform_string
1074
+ ) -> Type ["Pragma" ]:
1075
+ data = freeform_string or None
1076
+ return super ().__new__ (cls , command , Pragma ._to_pragma_arguments (args ), data )
1077
+
1078
+ @classmethod
1079
+ def _from_rs_pragma (cls , pragma : quil_rs .Pragma ) -> "Pragma" :
1080
+ return super ().__new__ (cls , pragma .name , pragma .arguments , pragma .data )
1081
+
1082
+ @staticmethod
1083
+ def _to_pragma_arguments (args : Iterable [Union [QubitDesignator , str ]]) -> List [quil_rs .PragmaArgument ]:
1084
+ pragma_arguments = []
1085
+ for arg in args :
1086
+ if isinstance (arg , Qubit ):
1087
+ pragma_arguments .append (quil_rs .PragmaArgument .from_integer (arg .index ))
1088
+ elif isinstance (arg , (str , FormalArgument )):
1089
+ pragma_arguments .append (quil_rs .PragmaArgument .from_identifier (str (arg )))
1090
+ else :
1091
+ raise TypeError (f"{ type (arg )} isn't a valid QubitDesignator" )
1092
+ return pragma_arguments
1093
+
1094
+ @staticmethod
1095
+ def _to_py_arguments (args : List [quil_rs .PragmaArgument ]) -> List [QubitDesignator ]:
1096
+ arguments = []
1097
+ for arg in args :
1098
+ if arg .is_integer ():
1099
+ arguments .append (Qubit (arg .to_integer ()))
1100
+ else :
1101
+ arguments .append (FormalArgument (arg .to_identifier ()))
1102
+ return arguments
1041
1103
1042
1104
def out (self ) -> str :
1043
- ret = "PRAGMA {}" .format (self .command )
1044
- if self .args :
1045
- ret += " {}" .format (" " .join (str (a ) for a in self .args ))
1046
- if self .freeform_string :
1047
- ret += ' "{}"' .format (self .freeform_string )
1048
- return ret
1105
+ return str (self )
1049
1106
1050
- def __repr__ (self ) -> str :
1051
- return "<PRAGMA {}>" .format (self .command )
1107
+ @property
1108
+ def command (self ) -> str :
1109
+ return super ().name
1110
+
1111
+ @command .setter
1112
+ def command (self , command : str ):
1113
+ quil_rs .Pragma .name .__set__ (self , command )
1114
+
1115
+ @property
1116
+ def args (self ) -> Tuple [QubitDesignator ]:
1117
+ return tuple (Pragma ._to_py_arguments (super ().arguments ))
1118
+
1119
+ @args .setter
1120
+ def args (self , args : str ):
1121
+ quil_rs .Pragma .arguments .__set__ (self , Pragma ._to_pragma_arguments (args ))
1122
+
1123
+ @property
1124
+ def freeform_string (self ) -> str :
1125
+ return super ().data or ""
1126
+
1127
+ @freeform_string .setter
1128
+ def freeform_string (self , freeform_string : str ):
1129
+ quil_rs .Pragma .data .__set__ (self , freeform_string )
1052
1130
1053
1131
1054
1132
class Declare (quil_rs .Declaration , AbstractInstruction ):
@@ -1316,50 +1394,95 @@ def get_qubits(self, indices: bool = True) -> Set[QubitDesignator]:
1316
1394
return _get_frame_qubits (self .frame , indices )
1317
1395
1318
1396
1319
- class DelayFrames (AbstractInstruction ):
1320
- def __init__ (self , frames : List [Frame ], duration : float ):
1321
- # all frames should be on the same qubits
1322
- if len (frames ) == 0 :
1323
- raise ValueError ("DELAY expected nonempty list of frames." )
1324
- if len (set (tuple (f .qubits ) for f in frames )) != 1 :
1325
- raise ValueError ("DELAY with explicit frames requires all frames are on the same qubits." )
1397
+ class Delay (quil_rs .Delay , AbstractInstruction ):
1398
+ def __new__ (cls , frames : List [Frame ], qubits : List [Union [int , Qubit , FormalArgument ]], duration : float ) -> "Delay" :
1399
+ frame_names = [frame .name for frame in frames ]
1400
+ rs_qubits = _convert_to_rs_qubits (Delay ._join_frame_qubits (frames , qubits ))
1401
+ expression = quil_rs_expr .Expression .from_number (complex (duration ))
1402
+ return super ().__new__ (cls , expression , frame_names , rs_qubits )
1326
1403
1327
- self .frames = frames
1328
- self .duration = duration
1404
+ @classmethod
1405
+ def _from_rs_delay (cls , delay : quil_rs .Delay ) -> "Delay" :
1406
+ return super ().__new__ (cls , delay .duration , delay .frame_names , delay .qubits )
1407
+
1408
+ @staticmethod
1409
+ def _join_frame_qubits (
1410
+ frames : List [Frame ], qubits : List [Union [int , Qubit , FormalArgument ]]
1411
+ ) -> List [Union [int , Qubit , FormalArgument ]]:
1412
+ merged_qubits = set (qubits )
1413
+ for frame in frames :
1414
+ merged_qubits .update (frame .qubits ) # type: ignore
1415
+ return list (merged_qubits )
1329
1416
1330
1417
def out (self ) -> str :
1331
- qubits = self .frames [0 ].qubits
1332
- ret = "DELAY " + _format_qubits_str (qubits )
1333
- for f in self .frames :
1334
- ret += f' "{ f .name } "'
1335
- ret += f" { self .duration } "
1336
- return ret
1418
+ return str (self )
1337
1419
1420
+ @property
1421
+ def qubits (self ) -> List [QubitDesignator ]:
1422
+ return _convert_to_py_qubits (super ().qubits )
1338
1423
1339
- class DelayQubits (AbstractInstruction ):
1340
- def __init__ (self , qubits : List [Union [Qubit , FormalArgument ]], duration : float ):
1341
- self .qubits = qubits
1342
- self .duration = duration
1424
+ @qubits .setter
1425
+ def qubits (self , qubits : List [Union [int , Qubit , FormalArgument ]]):
1426
+ quil_rs .Delay .qubits .__set__ (self , _convert_to_rs_qubits (qubits ))
1343
1427
1344
- def out (self ) -> str :
1345
- return f"DELAY { _format_qubits_str (self .qubits )} { self .duration } "
1428
+ @property
1429
+ def frames (self ) -> List [Frame ]:
1430
+ return [Frame (self .qubits , name ) for name in super ().frame_names ]
1346
1431
1432
+ @frames .setter
1433
+ def frames (self , frames : List [Frame ]):
1434
+ new_qubits = Delay ._join_frame_qubits (frames , [])
1435
+ frame_names = [frame .name for frame in frames ]
1436
+ quil_rs .Delay .qubits .__set__ (self , _convert_to_rs_qubits (new_qubits ))
1437
+ quil_rs .Delay .frame_names .__set__ (self , frame_names )
1347
1438
1348
- class FenceAll (SimpleInstruction ):
1349
- """
1350
- The FENCE instruction.
1351
- """
1439
+ @property
1440
+ def duration (self ) -> float :
1441
+ return super ().duration .to_real ()
1442
+
1443
+ @duration .setter
1444
+ def duration (self , duration : float ):
1445
+ expression = quil_rs_expr .Expression .from_number (complex (duration ))
1446
+ quil_rs .Delay .duration .__set__ (self , expression )
1352
1447
1353
- op = "FENCE"
1354
1448
1449
+ class DelayFrames (Delay ):
1450
+ def __new__ (cls , frames : List [Frame ], duration : float ):
1451
+ return super ().__new__ (cls , frames , [], duration )
1355
1452
1356
- class Fence (AbstractInstruction ):
1357
- def __init__ (self , qubits : List [Union [Qubit , FormalArgument ]]):
1358
- self .qubits = qubits
1453
+
1454
+ class DelayQubits (Delay ):
1455
+ def __new__ (cls , qubits : List [Union [Qubit , FormalArgument ]], duration : float ):
1456
+ return super ().__new__ (cls , [], qubits , duration )
1457
+
1458
+
1459
+ class Fence (quil_rs .Fence , AbstractInstruction ):
1460
+ def __new__ (cls , qubits : List [Union [Qubit , FormalArgument ]]):
1461
+ return super ().__new__ (cls , _convert_to_rs_qubits (qubits ))
1462
+
1463
+ @classmethod
1464
+ def _from_rs_fence (cls , fence : quil_rs .Fence ) -> "Fence" :
1465
+ return super ().__new__ (cls , fence .qubits )
1359
1466
1360
1467
def out (self ) -> str :
1361
- ret = "FENCE " + _format_qubits_str (self .qubits )
1362
- return ret
1468
+ return str (self )
1469
+
1470
+ @property
1471
+ def qubits (self ) -> List [Union [Qubit , FormalArgument ]]:
1472
+ return _convert_to_py_qubits (super ().qubits )
1473
+
1474
+ @qubits .setter
1475
+ def qubits (self , qubits : List [Union [Qubit , FormalArgument ]]):
1476
+ quil_rs .Fence .qubits .__set__ (self , _convert_to_rs_qubits (qubits ))
1477
+
1478
+
1479
+ class FenceAll (Fence ):
1480
+ """
1481
+ The FENCE instruction.
1482
+ """
1483
+
1484
+ def __new__ (cls ):
1485
+ return super ().__new__ (cls , [])
1363
1486
1364
1487
1365
1488
class DefWaveform (quil_rs .WaveformDefinition , AbstractInstruction ):
0 commit comments