libqasm 0.6.7__cp312-cp312-macosx_11_0_arm64.whl → 0.6.9__cp312-cp312-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cqasm/v3x/__init__.py +2 -2
- cqasm/v3x/ast.py +723 -675
- cqasm/v3x/semantic.py +834 -30
- libqasm/_libqasm.cpython-312-darwin.so +0 -0
- libqasm/libqasm.py +2 -2
- {libqasm-0.6.7.dist-info → libqasm-0.6.9.dist-info}/METADATA +6 -5
- libqasm-0.6.9.dist-info/RECORD +16 -0
- {libqasm-0.6.7.dist-info → libqasm-0.6.9.dist-info}/WHEEL +1 -1
- libqasm-0.6.7.dist-info/RECORD +0 -16
- {libqasm-0.6.7.dist-info → libqasm-0.6.9.dist-info}/LICENSE.md +0 -0
- {libqasm-0.6.7.dist-info → libqasm-0.6.9.dist-info}/top_level.txt +0 -0
cqasm/v3x/semantic.py
CHANGED
@@ -638,10 +638,14 @@ class Annotated(Node):
|
|
638
638
|
typ = cbor.get('@t', None)
|
639
639
|
if typ is None:
|
640
640
|
raise ValueError('type (@t) field is missing from node serialization')
|
641
|
+
if typ == 'Gate':
|
642
|
+
return Gate._deserialize(cbor, seq_to_ob, links)
|
641
643
|
if typ == 'Variable':
|
642
644
|
return Variable._deserialize(cbor, seq_to_ob, links)
|
643
|
-
if typ == '
|
644
|
-
return
|
645
|
+
if typ == 'GateInstruction':
|
646
|
+
return GateInstruction._deserialize(cbor, seq_to_ob, links)
|
647
|
+
if typ == 'NonGateInstruction':
|
648
|
+
return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
|
645
649
|
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
646
650
|
|
647
651
|
def _serialize(self, id_map):
|
@@ -1162,14 +1166,663 @@ class MultiBlock(_Multiple):
|
|
1162
1166
|
|
1163
1167
|
_typemap['Block'] = Block
|
1164
1168
|
|
1169
|
+
class Gate(Annotated):
|
1170
|
+
"""A gate can be a named gate or a composition of gate modifiers acting on a
|
1171
|
+
gate. pow is the only gate modifier that has an operand."""
|
1172
|
+
|
1173
|
+
__slots__ = [
|
1174
|
+
'_attr_name',
|
1175
|
+
'_attr_gate',
|
1176
|
+
'_attr_parameter',
|
1177
|
+
]
|
1178
|
+
|
1179
|
+
def __init__(
|
1180
|
+
self,
|
1181
|
+
name=None,
|
1182
|
+
gate=None,
|
1183
|
+
parameter=None,
|
1184
|
+
annotations=None,
|
1185
|
+
):
|
1186
|
+
super().__init__(annotations=annotations)
|
1187
|
+
self.name = name
|
1188
|
+
self.gate = gate
|
1189
|
+
self.parameter = parameter
|
1190
|
+
|
1191
|
+
@property
|
1192
|
+
def name(self):
|
1193
|
+
return self._attr_name
|
1194
|
+
|
1195
|
+
@name.setter
|
1196
|
+
def name(self, val):
|
1197
|
+
if val is None:
|
1198
|
+
del self.name
|
1199
|
+
return
|
1200
|
+
if not isinstance(val, cqasm.v3x.primitives.Str):
|
1201
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1202
|
+
if isinstance(val, Node):
|
1203
|
+
raise TypeError('name must be of type cqasm.v3x.primitives.Str')
|
1204
|
+
val = cqasm.v3x.primitives.Str(val)
|
1205
|
+
self._attr_name = val
|
1206
|
+
|
1207
|
+
@name.deleter
|
1208
|
+
def name(self):
|
1209
|
+
self._attr_name = cqasm.v3x.primitives.Str()
|
1210
|
+
|
1211
|
+
@property
|
1212
|
+
def gate(self):
|
1213
|
+
return self._attr_gate
|
1214
|
+
|
1215
|
+
@gate.setter
|
1216
|
+
def gate(self, val):
|
1217
|
+
if val is None:
|
1218
|
+
del self.gate
|
1219
|
+
return
|
1220
|
+
if not isinstance(val, Gate):
|
1221
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1222
|
+
if isinstance(val, Node):
|
1223
|
+
raise TypeError('gate must be of type Gate')
|
1224
|
+
val = Gate(val)
|
1225
|
+
self._attr_gate = val
|
1226
|
+
|
1227
|
+
@gate.deleter
|
1228
|
+
def gate(self):
|
1229
|
+
self._attr_gate = None
|
1230
|
+
|
1231
|
+
@property
|
1232
|
+
def parameter(self):
|
1233
|
+
return self._attr_parameter
|
1234
|
+
|
1235
|
+
@parameter.setter
|
1236
|
+
def parameter(self, val):
|
1237
|
+
if val is None:
|
1238
|
+
del self.parameter
|
1239
|
+
return
|
1240
|
+
if not isinstance(val, cqasm.v3x.values.ValueBase):
|
1241
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1242
|
+
if isinstance(val, Node):
|
1243
|
+
raise TypeError('parameter must be of type cqasm.v3x.values.ValueBase')
|
1244
|
+
val = cqasm.v3x.values.ValueBase(val)
|
1245
|
+
self._attr_parameter = val
|
1246
|
+
|
1247
|
+
@parameter.deleter
|
1248
|
+
def parameter(self):
|
1249
|
+
self._attr_parameter = None
|
1250
|
+
|
1251
|
+
def __eq__(self, other):
|
1252
|
+
"""Equality operator. Ignores annotations!"""
|
1253
|
+
if not isinstance(other, Gate):
|
1254
|
+
return False
|
1255
|
+
if self.name != other.name:
|
1256
|
+
return False
|
1257
|
+
if self.gate != other.gate:
|
1258
|
+
return False
|
1259
|
+
if self.parameter != other.parameter:
|
1260
|
+
return False
|
1261
|
+
if self.annotations != other.annotations:
|
1262
|
+
return False
|
1263
|
+
return True
|
1264
|
+
|
1265
|
+
def dump(self, indent=0, annotations=None, links=1):
|
1266
|
+
"""Returns a debug representation of this tree as a multiline string.
|
1267
|
+
indent is the number of double spaces prefixed before every line.
|
1268
|
+
annotations, if specified, must be a set-like object containing the key
|
1269
|
+
strings of the annotations that are to be printed. links specifies the
|
1270
|
+
maximum link recursion depth."""
|
1271
|
+
s = [' '*indent]
|
1272
|
+
s.append('Gate(')
|
1273
|
+
if annotations is None:
|
1274
|
+
annotations = []
|
1275
|
+
for key in annotations:
|
1276
|
+
if key in self:
|
1277
|
+
s.append(' # {}: {}'.format(key, self[key]))
|
1278
|
+
s.append('\n')
|
1279
|
+
indent += 1
|
1280
|
+
s.append(' '*indent)
|
1281
|
+
s.append('name: ')
|
1282
|
+
s.append(str(self.name) + '\n')
|
1283
|
+
s.append(' '*indent)
|
1284
|
+
s.append('gate: ')
|
1285
|
+
if self.gate is None:
|
1286
|
+
s.append('-\n')
|
1287
|
+
else:
|
1288
|
+
s.append('<\n')
|
1289
|
+
s.append(self.gate.dump(indent + 1, annotations, links) + '\n')
|
1290
|
+
s.append(' '*indent + '>\n')
|
1291
|
+
s.append(' '*indent)
|
1292
|
+
s.append('parameter: ')
|
1293
|
+
if self.parameter is None:
|
1294
|
+
s.append('-\n')
|
1295
|
+
else:
|
1296
|
+
s.append('<\n')
|
1297
|
+
s.append(self.parameter.dump(indent + 1, annotations, links) + '\n')
|
1298
|
+
s.append(' '*indent + '>\n')
|
1299
|
+
s.append(' '*indent)
|
1300
|
+
s.append('annotations: ')
|
1301
|
+
if not self.annotations:
|
1302
|
+
s.append('-\n')
|
1303
|
+
else:
|
1304
|
+
s.append('[\n')
|
1305
|
+
for child in self.annotations:
|
1306
|
+
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
1307
|
+
s.append(' '*indent + ']\n')
|
1308
|
+
indent -= 1
|
1309
|
+
s.append(' '*indent)
|
1310
|
+
s.append(')')
|
1311
|
+
return ''.join(s)
|
1312
|
+
|
1313
|
+
__str__ = dump
|
1314
|
+
__repr__ = dump
|
1315
|
+
|
1316
|
+
def find_reachable(self, id_map=None):
|
1317
|
+
"""Returns a dictionary mapping Python id() values to stable sequence
|
1318
|
+
numbers for all nodes in the tree rooted at this node. If id_map is
|
1319
|
+
specified, found nodes are appended to it."""
|
1320
|
+
if id_map is None:
|
1321
|
+
id_map = {}
|
1322
|
+
if id(self) in id_map:
|
1323
|
+
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1324
|
+
id_map[id(self)] = len(id_map)
|
1325
|
+
if self._attr_gate is not None:
|
1326
|
+
self._attr_gate.find_reachable(id_map)
|
1327
|
+
if self._attr_parameter is not None:
|
1328
|
+
self._attr_parameter.find_reachable(id_map)
|
1329
|
+
for el in self._attr_annotations:
|
1330
|
+
el.find_reachable(id_map)
|
1331
|
+
return id_map
|
1332
|
+
|
1333
|
+
def check_complete(self, id_map=None):
|
1334
|
+
"""Raises NotWellFormed if the tree rooted at this node is not
|
1335
|
+
well-formed. If id_map is specified, this tree is only a subtree in the
|
1336
|
+
context of a larger tree, and id_map must be a dict mapping from Python
|
1337
|
+
id() codes to tree indices for all reachable nodes."""
|
1338
|
+
if id_map is None:
|
1339
|
+
id_map = self.find_reachable()
|
1340
|
+
if self._attr_gate is not None:
|
1341
|
+
self._attr_gate.check_complete(id_map)
|
1342
|
+
if self._attr_parameter is not None:
|
1343
|
+
self._attr_parameter.check_complete(id_map)
|
1344
|
+
for child in self._attr_annotations:
|
1345
|
+
child.check_complete(id_map)
|
1346
|
+
|
1347
|
+
def copy(self):
|
1348
|
+
"""Returns a shallow copy of this node."""
|
1349
|
+
return Gate(
|
1350
|
+
name=self._attr_name,
|
1351
|
+
gate=self._attr_gate,
|
1352
|
+
parameter=self._attr_parameter,
|
1353
|
+
annotations=self._attr_annotations.copy()
|
1354
|
+
)
|
1355
|
+
|
1356
|
+
def clone(self):
|
1357
|
+
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1358
|
+
deficiencies with links included; that is, links always point to the
|
1359
|
+
original tree. If you're not cloning a subtree in a context where this
|
1360
|
+
is the desired behavior, you may want to use the copy.deepcopy() from
|
1361
|
+
the stdlib instead, which should copy links correctly."""
|
1362
|
+
return Gate(
|
1363
|
+
name=_cloned(self._attr_name),
|
1364
|
+
gate=_cloned(self._attr_gate),
|
1365
|
+
parameter=_cloned(self._attr_parameter),
|
1366
|
+
annotations=_cloned(self._attr_annotations)
|
1367
|
+
)
|
1368
|
+
|
1369
|
+
@staticmethod
|
1370
|
+
def _deserialize(cbor, seq_to_ob, links):
|
1371
|
+
"""Attempts to deserialize the given cbor object (in Python primitive
|
1372
|
+
representation) into a node of this type. All (sub)nodes are added to
|
1373
|
+
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1374
|
+
registered in the links list by means of a two-tuple of the setter
|
1375
|
+
function for the link field and the sequence number of the target node.
|
1376
|
+
"""
|
1377
|
+
if not isinstance(cbor, dict):
|
1378
|
+
raise TypeError('node description object must be a dict')
|
1379
|
+
typ = cbor.get('@t', None)
|
1380
|
+
if typ is None:
|
1381
|
+
raise ValueError('type (@t) field is missing from node serialization')
|
1382
|
+
if typ != 'Gate':
|
1383
|
+
raise ValueError('found node serialization for ' + typ + ', but expected Gate')
|
1384
|
+
|
1385
|
+
# Deserialize the name field.
|
1386
|
+
field = cbor.get('name', None)
|
1387
|
+
if not isinstance(field, dict):
|
1388
|
+
raise ValueError('missing or invalid serialization of field name')
|
1389
|
+
if hasattr(cqasm.v3x.primitives.Str, 'deserialize_cbor'):
|
1390
|
+
f_name = cqasm.v3x.primitives.Str.deserialize_cbor(field)
|
1391
|
+
else:
|
1392
|
+
f_name = cqasm.v3x.primitives.deserialize(cqasm.v3x.primitives.Str, field)
|
1393
|
+
|
1394
|
+
# Deserialize the gate field.
|
1395
|
+
field = cbor.get('gate', None)
|
1396
|
+
if not isinstance(field, dict):
|
1397
|
+
raise ValueError('missing or invalid serialization of field gate')
|
1398
|
+
if field.get('@T') != '?':
|
1399
|
+
raise ValueError('unexpected edge type for field gate')
|
1400
|
+
if field.get('@t', None) is None:
|
1401
|
+
f_gate = None
|
1402
|
+
else:
|
1403
|
+
f_gate = Gate._deserialize(field, seq_to_ob, links)
|
1404
|
+
|
1405
|
+
# Deserialize the parameter field.
|
1406
|
+
field = cbor.get('parameter', None)
|
1407
|
+
if not isinstance(field, dict):
|
1408
|
+
raise ValueError('missing or invalid serialization of field parameter')
|
1409
|
+
if field.get('@T') != '?':
|
1410
|
+
raise ValueError('unexpected edge type for field parameter')
|
1411
|
+
if field.get('@t', None) is None:
|
1412
|
+
f_parameter = None
|
1413
|
+
else:
|
1414
|
+
f_parameter = cqasm.v3x.values.ValueBase._deserialize(field, seq_to_ob, links)
|
1415
|
+
|
1416
|
+
# Deserialize the annotations field.
|
1417
|
+
field = cbor.get('annotations', None)
|
1418
|
+
if not isinstance(field, dict):
|
1419
|
+
raise ValueError('missing or invalid serialization of field annotations')
|
1420
|
+
if field.get('@T') != '*':
|
1421
|
+
raise ValueError('unexpected edge type for field annotations')
|
1422
|
+
data = field.get('@d', None)
|
1423
|
+
if not isinstance(data, list):
|
1424
|
+
raise ValueError('missing serialization of Any/Many contents')
|
1425
|
+
f_annotations = MultiAnnotationData()
|
1426
|
+
for element in data:
|
1427
|
+
if element.get('@T') != '1':
|
1428
|
+
raise ValueError('unexpected edge type for Any/Many element')
|
1429
|
+
f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
|
1430
|
+
|
1431
|
+
# Construct the Gate node.
|
1432
|
+
node = Gate(f_name, f_gate, f_parameter, f_annotations)
|
1433
|
+
|
1434
|
+
# Deserialize annotations.
|
1435
|
+
for key, val in cbor.items():
|
1436
|
+
if not (key.startswith('{') and key.endswith('}')):
|
1437
|
+
continue
|
1438
|
+
key = key[1:-1]
|
1439
|
+
node[key] = cqasm.v3x.primitives.deserialize(key, val)
|
1440
|
+
|
1441
|
+
# Register node in sequence number lookup.
|
1442
|
+
seq = cbor.get('@i', None)
|
1443
|
+
if not isinstance(seq, int):
|
1444
|
+
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1445
|
+
if seq in seq_to_ob:
|
1446
|
+
raise ValueError('duplicate sequence number %d' % seq)
|
1447
|
+
seq_to_ob[seq] = node
|
1448
|
+
|
1449
|
+
return node
|
1450
|
+
|
1451
|
+
def _serialize(self, id_map):
|
1452
|
+
"""Serializes this node to the Python primitive representation of its
|
1453
|
+
CBOR serialization. The tree that the node belongs to must be
|
1454
|
+
well-formed. id_map must match Python id() calls for all nodes to unique
|
1455
|
+
integers, to use for the sequence number representation of links."""
|
1456
|
+
cbor = {'@i': id_map[id(self)], '@t': 'Gate'}
|
1457
|
+
|
1458
|
+
# Serialize the name field.
|
1459
|
+
if hasattr(self._attr_name, 'serialize_cbor'):
|
1460
|
+
cbor['name'] = self._attr_name.serialize_cbor()
|
1461
|
+
else:
|
1462
|
+
cbor['name'] = cqasm.v3x.primitives.serialize(cqasm.v3x.primitives.Str, self._attr_name)
|
1463
|
+
|
1464
|
+
# Serialize the gate field.
|
1465
|
+
field = {'@T': '?'}
|
1466
|
+
if self._attr_gate is None:
|
1467
|
+
field['@t'] = None
|
1468
|
+
else:
|
1469
|
+
field.update(self._attr_gate._serialize(id_map))
|
1470
|
+
cbor['gate'] = field
|
1471
|
+
|
1472
|
+
# Serialize the parameter field.
|
1473
|
+
field = {'@T': '?'}
|
1474
|
+
if self._attr_parameter is None:
|
1475
|
+
field['@t'] = None
|
1476
|
+
else:
|
1477
|
+
field.update(self._attr_parameter._serialize(id_map))
|
1478
|
+
cbor['parameter'] = field
|
1479
|
+
|
1480
|
+
# Serialize the annotations field.
|
1481
|
+
field = {'@T': '*'}
|
1482
|
+
lst = []
|
1483
|
+
for el in self._attr_annotations:
|
1484
|
+
el = el._serialize(id_map)
|
1485
|
+
el['@T'] = '1'
|
1486
|
+
lst.append(el)
|
1487
|
+
field['@d'] = lst
|
1488
|
+
cbor['annotations'] = field
|
1489
|
+
|
1490
|
+
# Serialize annotations.
|
1491
|
+
for key, val in self._annot.items():
|
1492
|
+
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
1493
|
+
|
1494
|
+
return cbor
|
1495
|
+
|
1496
|
+
|
1497
|
+
class MultiGate(_Multiple):
|
1498
|
+
"""Wrapper for an edge with multiple Gate objects."""
|
1499
|
+
|
1500
|
+
_T = Gate
|
1501
|
+
|
1502
|
+
|
1503
|
+
_typemap['Gate'] = Gate
|
1504
|
+
|
1165
1505
|
class Statement(Annotated):
|
1166
1506
|
__slots__ = []
|
1167
1507
|
|
1168
|
-
def __init__(
|
1169
|
-
self,
|
1170
|
-
annotations=None,
|
1171
|
-
):
|
1172
|
-
super().__init__(annotations=annotations)
|
1508
|
+
def __init__(
|
1509
|
+
self,
|
1510
|
+
annotations=None,
|
1511
|
+
):
|
1512
|
+
super().__init__(annotations=annotations)
|
1513
|
+
|
1514
|
+
@staticmethod
|
1515
|
+
def _deserialize(cbor, seq_to_ob, links):
|
1516
|
+
"""Attempts to deserialize the given cbor object (in Python primitive
|
1517
|
+
representation) into a node of this type. All (sub)nodes are added to
|
1518
|
+
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1519
|
+
registered in the links list by means of a two-tuple of the setter
|
1520
|
+
function for the link field and the sequence number of the target node.
|
1521
|
+
"""
|
1522
|
+
if not isinstance(cbor, dict):
|
1523
|
+
raise TypeError('node description object must be a dict')
|
1524
|
+
typ = cbor.get('@t', None)
|
1525
|
+
if typ is None:
|
1526
|
+
raise ValueError('type (@t) field is missing from node serialization')
|
1527
|
+
if typ == 'GateInstruction':
|
1528
|
+
return GateInstruction._deserialize(cbor, seq_to_ob, links)
|
1529
|
+
if typ == 'NonGateInstruction':
|
1530
|
+
return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
|
1531
|
+
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
1532
|
+
|
1533
|
+
def _serialize(self, id_map):
|
1534
|
+
"""Serializes this node to the Python primitive representation of its
|
1535
|
+
CBOR serialization. The tree that the node belongs to must be
|
1536
|
+
well-formed. id_map must match Python id() calls for all nodes to unique
|
1537
|
+
integers, to use for the sequence number representation of links."""
|
1538
|
+
cbor = {'@i': id_map[id(self)], '@t': 'Statement'}
|
1539
|
+
|
1540
|
+
# Serialize the annotations field.
|
1541
|
+
field = {'@T': '*'}
|
1542
|
+
lst = []
|
1543
|
+
for el in self._attr_annotations:
|
1544
|
+
el = el._serialize(id_map)
|
1545
|
+
el['@T'] = '1'
|
1546
|
+
lst.append(el)
|
1547
|
+
field['@d'] = lst
|
1548
|
+
cbor['annotations'] = field
|
1549
|
+
|
1550
|
+
# Serialize annotations.
|
1551
|
+
for key, val in self._annot.items():
|
1552
|
+
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
1553
|
+
|
1554
|
+
return cbor
|
1555
|
+
|
1556
|
+
|
1557
|
+
class MultiStatement(_Multiple):
|
1558
|
+
"""Wrapper for an edge with multiple Statement objects."""
|
1559
|
+
|
1560
|
+
_T = Statement
|
1561
|
+
|
1562
|
+
|
1563
|
+
_typemap['Statement'] = Statement
|
1564
|
+
|
1565
|
+
class Instruction(Statement):
|
1566
|
+
__slots__ = []
|
1567
|
+
|
1568
|
+
def __init__(
|
1569
|
+
self,
|
1570
|
+
annotations=None,
|
1571
|
+
):
|
1572
|
+
super().__init__(annotations=annotations)
|
1573
|
+
|
1574
|
+
@staticmethod
|
1575
|
+
def _deserialize(cbor, seq_to_ob, links):
|
1576
|
+
"""Attempts to deserialize the given cbor object (in Python primitive
|
1577
|
+
representation) into a node of this type. All (sub)nodes are added to
|
1578
|
+
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1579
|
+
registered in the links list by means of a two-tuple of the setter
|
1580
|
+
function for the link field and the sequence number of the target node.
|
1581
|
+
"""
|
1582
|
+
if not isinstance(cbor, dict):
|
1583
|
+
raise TypeError('node description object must be a dict')
|
1584
|
+
typ = cbor.get('@t', None)
|
1585
|
+
if typ is None:
|
1586
|
+
raise ValueError('type (@t) field is missing from node serialization')
|
1587
|
+
if typ == 'GateInstruction':
|
1588
|
+
return GateInstruction._deserialize(cbor, seq_to_ob, links)
|
1589
|
+
if typ == 'NonGateInstruction':
|
1590
|
+
return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
|
1591
|
+
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
1592
|
+
|
1593
|
+
def _serialize(self, id_map):
|
1594
|
+
"""Serializes this node to the Python primitive representation of its
|
1595
|
+
CBOR serialization. The tree that the node belongs to must be
|
1596
|
+
well-formed. id_map must match Python id() calls for all nodes to unique
|
1597
|
+
integers, to use for the sequence number representation of links."""
|
1598
|
+
cbor = {'@i': id_map[id(self)], '@t': 'Instruction'}
|
1599
|
+
|
1600
|
+
# Serialize the annotations field.
|
1601
|
+
field = {'@T': '*'}
|
1602
|
+
lst = []
|
1603
|
+
for el in self._attr_annotations:
|
1604
|
+
el = el._serialize(id_map)
|
1605
|
+
el['@T'] = '1'
|
1606
|
+
lst.append(el)
|
1607
|
+
field['@d'] = lst
|
1608
|
+
cbor['annotations'] = field
|
1609
|
+
|
1610
|
+
# Serialize annotations.
|
1611
|
+
for key, val in self._annot.items():
|
1612
|
+
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
1613
|
+
|
1614
|
+
return cbor
|
1615
|
+
|
1616
|
+
|
1617
|
+
class MultiInstruction(_Multiple):
|
1618
|
+
"""Wrapper for an edge with multiple Instruction objects."""
|
1619
|
+
|
1620
|
+
_T = Instruction
|
1621
|
+
|
1622
|
+
|
1623
|
+
_typemap['Instruction'] = Instruction
|
1624
|
+
|
1625
|
+
class GateInstruction(Instruction):
|
1626
|
+
"""A gate, or a composition of gate modifiers and a gate"""
|
1627
|
+
|
1628
|
+
__slots__ = [
|
1629
|
+
'_attr_instruction_ref',
|
1630
|
+
'_attr_gate',
|
1631
|
+
'_attr_operands',
|
1632
|
+
]
|
1633
|
+
|
1634
|
+
def __init__(
|
1635
|
+
self,
|
1636
|
+
instruction_ref=None,
|
1637
|
+
gate=None,
|
1638
|
+
operands=None,
|
1639
|
+
annotations=None,
|
1640
|
+
):
|
1641
|
+
super().__init__(annotations=annotations)
|
1642
|
+
self.instruction_ref = instruction_ref
|
1643
|
+
self.gate = gate
|
1644
|
+
self.operands = operands
|
1645
|
+
|
1646
|
+
@property
|
1647
|
+
def instruction_ref(self):
|
1648
|
+
return self._attr_instruction_ref
|
1649
|
+
|
1650
|
+
@instruction_ref.setter
|
1651
|
+
def instruction_ref(self, val):
|
1652
|
+
if val is None:
|
1653
|
+
del self.instruction_ref
|
1654
|
+
return
|
1655
|
+
if not isinstance(val, cqasm.v3x.instruction.InstructionRef):
|
1656
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1657
|
+
if isinstance(val, Node):
|
1658
|
+
raise TypeError('instruction_ref must be of type cqasm.v3x.instruction.InstructionRef')
|
1659
|
+
val = cqasm.v3x.instruction.InstructionRef(val)
|
1660
|
+
self._attr_instruction_ref = val
|
1661
|
+
|
1662
|
+
@instruction_ref.deleter
|
1663
|
+
def instruction_ref(self):
|
1664
|
+
self._attr_instruction_ref = cqasm.v3x.instruction.InstructionRef()
|
1665
|
+
|
1666
|
+
@property
|
1667
|
+
def gate(self):
|
1668
|
+
return self._attr_gate
|
1669
|
+
|
1670
|
+
@gate.setter
|
1671
|
+
def gate(self, val):
|
1672
|
+
if val is None:
|
1673
|
+
del self.gate
|
1674
|
+
return
|
1675
|
+
if not isinstance(val, Gate):
|
1676
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1677
|
+
if isinstance(val, Node):
|
1678
|
+
raise TypeError('gate must be of type Gate')
|
1679
|
+
val = Gate(val)
|
1680
|
+
self._attr_gate = val
|
1681
|
+
|
1682
|
+
@gate.deleter
|
1683
|
+
def gate(self):
|
1684
|
+
self._attr_gate = None
|
1685
|
+
|
1686
|
+
@property
|
1687
|
+
def operands(self):
|
1688
|
+
return self._attr_operands
|
1689
|
+
|
1690
|
+
@operands.setter
|
1691
|
+
def operands(self, val):
|
1692
|
+
if val is None:
|
1693
|
+
del self.operands
|
1694
|
+
return
|
1695
|
+
if not isinstance(val, cqasm.v3x.values.MultiValueBase):
|
1696
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1697
|
+
if isinstance(val, Node):
|
1698
|
+
raise TypeError('operands must be of type cqasm.v3x.values.MultiValueBase')
|
1699
|
+
val = cqasm.v3x.values.MultiValueBase(val)
|
1700
|
+
self._attr_operands = val
|
1701
|
+
|
1702
|
+
@operands.deleter
|
1703
|
+
def operands(self):
|
1704
|
+
self._attr_operands = cqasm.v3x.values.MultiValueBase()
|
1705
|
+
|
1706
|
+
def __eq__(self, other):
|
1707
|
+
"""Equality operator. Ignores annotations!"""
|
1708
|
+
if not isinstance(other, GateInstruction):
|
1709
|
+
return False
|
1710
|
+
if self.instruction_ref != other.instruction_ref:
|
1711
|
+
return False
|
1712
|
+
if self.gate != other.gate:
|
1713
|
+
return False
|
1714
|
+
if self.operands != other.operands:
|
1715
|
+
return False
|
1716
|
+
if self.annotations != other.annotations:
|
1717
|
+
return False
|
1718
|
+
return True
|
1719
|
+
|
1720
|
+
def dump(self, indent=0, annotations=None, links=1):
|
1721
|
+
"""Returns a debug representation of this tree as a multiline string.
|
1722
|
+
indent is the number of double spaces prefixed before every line.
|
1723
|
+
annotations, if specified, must be a set-like object containing the key
|
1724
|
+
strings of the annotations that are to be printed. links specifies the
|
1725
|
+
maximum link recursion depth."""
|
1726
|
+
s = [' '*indent]
|
1727
|
+
s.append('GateInstruction(')
|
1728
|
+
if annotations is None:
|
1729
|
+
annotations = []
|
1730
|
+
for key in annotations:
|
1731
|
+
if key in self:
|
1732
|
+
s.append(' # {}: {}'.format(key, self[key]))
|
1733
|
+
s.append('\n')
|
1734
|
+
indent += 1
|
1735
|
+
s.append(' '*indent)
|
1736
|
+
s.append('instruction_ref: ')
|
1737
|
+
s.append(str(self.instruction_ref) + '\n')
|
1738
|
+
s.append(' '*indent)
|
1739
|
+
s.append('gate: ')
|
1740
|
+
if self.gate is None:
|
1741
|
+
s.append('!MISSING\n')
|
1742
|
+
else:
|
1743
|
+
s.append('<\n')
|
1744
|
+
s.append(self.gate.dump(indent + 1, annotations, links) + '\n')
|
1745
|
+
s.append(' '*indent + '>\n')
|
1746
|
+
s.append(' '*indent)
|
1747
|
+
s.append('operands: ')
|
1748
|
+
if not self.operands:
|
1749
|
+
s.append('-\n')
|
1750
|
+
else:
|
1751
|
+
s.append('[\n')
|
1752
|
+
for child in self.operands:
|
1753
|
+
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
1754
|
+
s.append(' '*indent + ']\n')
|
1755
|
+
s.append(' '*indent)
|
1756
|
+
s.append('annotations: ')
|
1757
|
+
if not self.annotations:
|
1758
|
+
s.append('-\n')
|
1759
|
+
else:
|
1760
|
+
s.append('[\n')
|
1761
|
+
for child in self.annotations:
|
1762
|
+
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
1763
|
+
s.append(' '*indent + ']\n')
|
1764
|
+
indent -= 1
|
1765
|
+
s.append(' '*indent)
|
1766
|
+
s.append(')')
|
1767
|
+
return ''.join(s)
|
1768
|
+
|
1769
|
+
__str__ = dump
|
1770
|
+
__repr__ = dump
|
1771
|
+
|
1772
|
+
def find_reachable(self, id_map=None):
|
1773
|
+
"""Returns a dictionary mapping Python id() values to stable sequence
|
1774
|
+
numbers for all nodes in the tree rooted at this node. If id_map is
|
1775
|
+
specified, found nodes are appended to it."""
|
1776
|
+
if id_map is None:
|
1777
|
+
id_map = {}
|
1778
|
+
if id(self) in id_map:
|
1779
|
+
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1780
|
+
id_map[id(self)] = len(id_map)
|
1781
|
+
if self._attr_gate is not None:
|
1782
|
+
self._attr_gate.find_reachable(id_map)
|
1783
|
+
for el in self._attr_operands:
|
1784
|
+
el.find_reachable(id_map)
|
1785
|
+
for el in self._attr_annotations:
|
1786
|
+
el.find_reachable(id_map)
|
1787
|
+
return id_map
|
1788
|
+
|
1789
|
+
def check_complete(self, id_map=None):
|
1790
|
+
"""Raises NotWellFormed if the tree rooted at this node is not
|
1791
|
+
well-formed. If id_map is specified, this tree is only a subtree in the
|
1792
|
+
context of a larger tree, and id_map must be a dict mapping from Python
|
1793
|
+
id() codes to tree indices for all reachable nodes."""
|
1794
|
+
if id_map is None:
|
1795
|
+
id_map = self.find_reachable()
|
1796
|
+
if self._attr_gate is None:
|
1797
|
+
raise NotWellFormed('gate is required but not set')
|
1798
|
+
if self._attr_gate is not None:
|
1799
|
+
self._attr_gate.check_complete(id_map)
|
1800
|
+
for child in self._attr_operands:
|
1801
|
+
child.check_complete(id_map)
|
1802
|
+
for child in self._attr_annotations:
|
1803
|
+
child.check_complete(id_map)
|
1804
|
+
|
1805
|
+
def copy(self):
|
1806
|
+
"""Returns a shallow copy of this node."""
|
1807
|
+
return GateInstruction(
|
1808
|
+
instruction_ref=self._attr_instruction_ref,
|
1809
|
+
gate=self._attr_gate,
|
1810
|
+
operands=self._attr_operands.copy(),
|
1811
|
+
annotations=self._attr_annotations.copy()
|
1812
|
+
)
|
1813
|
+
|
1814
|
+
def clone(self):
|
1815
|
+
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1816
|
+
deficiencies with links included; that is, links always point to the
|
1817
|
+
original tree. If you're not cloning a subtree in a context where this
|
1818
|
+
is the desired behavior, you may want to use the copy.deepcopy() from
|
1819
|
+
the stdlib instead, which should copy links correctly."""
|
1820
|
+
return GateInstruction(
|
1821
|
+
instruction_ref=_cloned(self._attr_instruction_ref),
|
1822
|
+
gate=_cloned(self._attr_gate),
|
1823
|
+
operands=_cloned(self._attr_operands),
|
1824
|
+
annotations=_cloned(self._attr_annotations)
|
1825
|
+
)
|
1173
1826
|
|
1174
1827
|
@staticmethod
|
1175
1828
|
def _deserialize(cbor, seq_to_ob, links):
|
@@ -1184,16 +1837,109 @@ class Statement(Annotated):
|
|
1184
1837
|
typ = cbor.get('@t', None)
|
1185
1838
|
if typ is None:
|
1186
1839
|
raise ValueError('type (@t) field is missing from node serialization')
|
1187
|
-
if typ
|
1188
|
-
|
1189
|
-
|
1840
|
+
if typ != 'GateInstruction':
|
1841
|
+
raise ValueError('found node serialization for ' + typ + ', but expected GateInstruction')
|
1842
|
+
|
1843
|
+
# Deserialize the instruction_ref field.
|
1844
|
+
field = cbor.get('instruction_ref', None)
|
1845
|
+
if not isinstance(field, dict):
|
1846
|
+
raise ValueError('missing or invalid serialization of field instruction_ref')
|
1847
|
+
if hasattr(cqasm.v3x.instruction.InstructionRef, 'deserialize_cbor'):
|
1848
|
+
f_instruction_ref = cqasm.v3x.instruction.InstructionRef.deserialize_cbor(field)
|
1849
|
+
else:
|
1850
|
+
f_instruction_ref = cqasm.v3x.primitives.deserialize(cqasm.v3x.instruction.InstructionRef, field)
|
1851
|
+
|
1852
|
+
# Deserialize the gate field.
|
1853
|
+
field = cbor.get('gate', None)
|
1854
|
+
if not isinstance(field, dict):
|
1855
|
+
raise ValueError('missing or invalid serialization of field gate')
|
1856
|
+
if field.get('@T') != '1':
|
1857
|
+
raise ValueError('unexpected edge type for field gate')
|
1858
|
+
if field.get('@t', None) is None:
|
1859
|
+
f_gate = None
|
1860
|
+
else:
|
1861
|
+
f_gate = Gate._deserialize(field, seq_to_ob, links)
|
1862
|
+
|
1863
|
+
# Deserialize the operands field.
|
1864
|
+
field = cbor.get('operands', None)
|
1865
|
+
if not isinstance(field, dict):
|
1866
|
+
raise ValueError('missing or invalid serialization of field operands')
|
1867
|
+
if field.get('@T') != '*':
|
1868
|
+
raise ValueError('unexpected edge type for field operands')
|
1869
|
+
data = field.get('@d', None)
|
1870
|
+
if not isinstance(data, list):
|
1871
|
+
raise ValueError('missing serialization of Any/Many contents')
|
1872
|
+
f_operands = cqasm.v3x.values.MultiValueBase()
|
1873
|
+
for element in data:
|
1874
|
+
if element.get('@T') != '1':
|
1875
|
+
raise ValueError('unexpected edge type for Any/Many element')
|
1876
|
+
f_operands.append(cqasm.v3x.values.ValueBase._deserialize(element, seq_to_ob, links))
|
1877
|
+
|
1878
|
+
# Deserialize the annotations field.
|
1879
|
+
field = cbor.get('annotations', None)
|
1880
|
+
if not isinstance(field, dict):
|
1881
|
+
raise ValueError('missing or invalid serialization of field annotations')
|
1882
|
+
if field.get('@T') != '*':
|
1883
|
+
raise ValueError('unexpected edge type for field annotations')
|
1884
|
+
data = field.get('@d', None)
|
1885
|
+
if not isinstance(data, list):
|
1886
|
+
raise ValueError('missing serialization of Any/Many contents')
|
1887
|
+
f_annotations = MultiAnnotationData()
|
1888
|
+
for element in data:
|
1889
|
+
if element.get('@T') != '1':
|
1890
|
+
raise ValueError('unexpected edge type for Any/Many element')
|
1891
|
+
f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
|
1892
|
+
|
1893
|
+
# Construct the GateInstruction node.
|
1894
|
+
node = GateInstruction(f_instruction_ref, f_gate, f_operands, f_annotations)
|
1895
|
+
|
1896
|
+
# Deserialize annotations.
|
1897
|
+
for key, val in cbor.items():
|
1898
|
+
if not (key.startswith('{') and key.endswith('}')):
|
1899
|
+
continue
|
1900
|
+
key = key[1:-1]
|
1901
|
+
node[key] = cqasm.v3x.primitives.deserialize(key, val)
|
1902
|
+
|
1903
|
+
# Register node in sequence number lookup.
|
1904
|
+
seq = cbor.get('@i', None)
|
1905
|
+
if not isinstance(seq, int):
|
1906
|
+
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1907
|
+
if seq in seq_to_ob:
|
1908
|
+
raise ValueError('duplicate sequence number %d' % seq)
|
1909
|
+
seq_to_ob[seq] = node
|
1910
|
+
|
1911
|
+
return node
|
1190
1912
|
|
1191
1913
|
def _serialize(self, id_map):
|
1192
1914
|
"""Serializes this node to the Python primitive representation of its
|
1193
1915
|
CBOR serialization. The tree that the node belongs to must be
|
1194
1916
|
well-formed. id_map must match Python id() calls for all nodes to unique
|
1195
1917
|
integers, to use for the sequence number representation of links."""
|
1196
|
-
cbor = {'@i': id_map[id(self)], '@t': '
|
1918
|
+
cbor = {'@i': id_map[id(self)], '@t': 'GateInstruction'}
|
1919
|
+
|
1920
|
+
# Serialize the instruction_ref field.
|
1921
|
+
if hasattr(self._attr_instruction_ref, 'serialize_cbor'):
|
1922
|
+
cbor['instruction_ref'] = self._attr_instruction_ref.serialize_cbor()
|
1923
|
+
else:
|
1924
|
+
cbor['instruction_ref'] = cqasm.v3x.primitives.serialize(cqasm.v3x.instruction.InstructionRef, self._attr_instruction_ref)
|
1925
|
+
|
1926
|
+
# Serialize the gate field.
|
1927
|
+
field = {'@T': '1'}
|
1928
|
+
if self._attr_gate is None:
|
1929
|
+
field['@t'] = None
|
1930
|
+
else:
|
1931
|
+
field.update(self._attr_gate._serialize(id_map))
|
1932
|
+
cbor['gate'] = field
|
1933
|
+
|
1934
|
+
# Serialize the operands field.
|
1935
|
+
field = {'@T': '*'}
|
1936
|
+
lst = []
|
1937
|
+
for el in self._attr_operands:
|
1938
|
+
el = el._serialize(id_map)
|
1939
|
+
el['@T'] = '1'
|
1940
|
+
lst.append(el)
|
1941
|
+
field['@d'] = lst
|
1942
|
+
cbor['operands'] = field
|
1197
1943
|
|
1198
1944
|
# Serialize the annotations field.
|
1199
1945
|
field = {'@T': '*'}
|
@@ -1212,21 +1958,22 @@ class Statement(Annotated):
|
|
1212
1958
|
return cbor
|
1213
1959
|
|
1214
1960
|
|
1215
|
-
class
|
1216
|
-
"""Wrapper for an edge with multiple
|
1961
|
+
class MultiGateInstruction(_Multiple):
|
1962
|
+
"""Wrapper for an edge with multiple GateInstruction objects."""
|
1217
1963
|
|
1218
|
-
_T =
|
1964
|
+
_T = GateInstruction
|
1219
1965
|
|
1220
1966
|
|
1221
|
-
_typemap['
|
1967
|
+
_typemap['GateInstruction'] = GateInstruction
|
1222
1968
|
|
1223
|
-
class Instruction
|
1224
|
-
"""
|
1969
|
+
class NonGateInstruction(Instruction):
|
1970
|
+
"""A measure instruction or a reset instruction"""
|
1225
1971
|
|
1226
1972
|
__slots__ = [
|
1227
1973
|
'_attr_instruction_ref',
|
1228
1974
|
'_attr_name',
|
1229
1975
|
'_attr_operands',
|
1976
|
+
'_attr_parameter',
|
1230
1977
|
]
|
1231
1978
|
|
1232
1979
|
def __init__(
|
@@ -1234,12 +1981,14 @@ class Instruction(Statement):
|
|
1234
1981
|
instruction_ref=None,
|
1235
1982
|
name=None,
|
1236
1983
|
operands=None,
|
1984
|
+
parameter=None,
|
1237
1985
|
annotations=None,
|
1238
1986
|
):
|
1239
1987
|
super().__init__(annotations=annotations)
|
1240
1988
|
self.instruction_ref = instruction_ref
|
1241
1989
|
self.name = name
|
1242
1990
|
self.operands = operands
|
1991
|
+
self.parameter = parameter
|
1243
1992
|
|
1244
1993
|
@property
|
1245
1994
|
def instruction_ref(self):
|
@@ -1301,9 +2050,29 @@ class Instruction(Statement):
|
|
1301
2050
|
def operands(self):
|
1302
2051
|
self._attr_operands = cqasm.v3x.values.MultiValueBase()
|
1303
2052
|
|
2053
|
+
@property
|
2054
|
+
def parameter(self):
|
2055
|
+
return self._attr_parameter
|
2056
|
+
|
2057
|
+
@parameter.setter
|
2058
|
+
def parameter(self, val):
|
2059
|
+
if val is None:
|
2060
|
+
del self.parameter
|
2061
|
+
return
|
2062
|
+
if not isinstance(val, cqasm.v3x.values.ValueBase):
|
2063
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
2064
|
+
if isinstance(val, Node):
|
2065
|
+
raise TypeError('parameter must be of type cqasm.v3x.values.ValueBase')
|
2066
|
+
val = cqasm.v3x.values.ValueBase(val)
|
2067
|
+
self._attr_parameter = val
|
2068
|
+
|
2069
|
+
@parameter.deleter
|
2070
|
+
def parameter(self):
|
2071
|
+
self._attr_parameter = None
|
2072
|
+
|
1304
2073
|
def __eq__(self, other):
|
1305
2074
|
"""Equality operator. Ignores annotations!"""
|
1306
|
-
if not isinstance(other,
|
2075
|
+
if not isinstance(other, NonGateInstruction):
|
1307
2076
|
return False
|
1308
2077
|
if self.instruction_ref != other.instruction_ref:
|
1309
2078
|
return False
|
@@ -1311,6 +2080,8 @@ class Instruction(Statement):
|
|
1311
2080
|
return False
|
1312
2081
|
if self.operands != other.operands:
|
1313
2082
|
return False
|
2083
|
+
if self.parameter != other.parameter:
|
2084
|
+
return False
|
1314
2085
|
if self.annotations != other.annotations:
|
1315
2086
|
return False
|
1316
2087
|
return True
|
@@ -1322,7 +2093,7 @@ class Instruction(Statement):
|
|
1322
2093
|
strings of the annotations that are to be printed. links specifies the
|
1323
2094
|
maximum link recursion depth."""
|
1324
2095
|
s = [' '*indent]
|
1325
|
-
s.append('
|
2096
|
+
s.append('NonGateInstruction(')
|
1326
2097
|
if annotations is None:
|
1327
2098
|
annotations = []
|
1328
2099
|
for key in annotations:
|
@@ -1346,6 +2117,14 @@ class Instruction(Statement):
|
|
1346
2117
|
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
1347
2118
|
s.append(' '*indent + ']\n')
|
1348
2119
|
s.append(' '*indent)
|
2120
|
+
s.append('parameter: ')
|
2121
|
+
if self.parameter is None:
|
2122
|
+
s.append('-\n')
|
2123
|
+
else:
|
2124
|
+
s.append('<\n')
|
2125
|
+
s.append(self.parameter.dump(indent + 1, annotations, links) + '\n')
|
2126
|
+
s.append(' '*indent + '>\n')
|
2127
|
+
s.append(' '*indent)
|
1349
2128
|
s.append('annotations: ')
|
1350
2129
|
if not self.annotations:
|
1351
2130
|
s.append('-\n')
|
@@ -1373,6 +2152,8 @@ class Instruction(Statement):
|
|
1373
2152
|
id_map[id(self)] = len(id_map)
|
1374
2153
|
for el in self._attr_operands:
|
1375
2154
|
el.find_reachable(id_map)
|
2155
|
+
if self._attr_parameter is not None:
|
2156
|
+
self._attr_parameter.find_reachable(id_map)
|
1376
2157
|
for el in self._attr_annotations:
|
1377
2158
|
el.find_reachable(id_map)
|
1378
2159
|
return id_map
|
@@ -1386,15 +2167,18 @@ class Instruction(Statement):
|
|
1386
2167
|
id_map = self.find_reachable()
|
1387
2168
|
for child in self._attr_operands:
|
1388
2169
|
child.check_complete(id_map)
|
2170
|
+
if self._attr_parameter is not None:
|
2171
|
+
self._attr_parameter.check_complete(id_map)
|
1389
2172
|
for child in self._attr_annotations:
|
1390
2173
|
child.check_complete(id_map)
|
1391
2174
|
|
1392
2175
|
def copy(self):
|
1393
2176
|
"""Returns a shallow copy of this node."""
|
1394
|
-
return
|
2177
|
+
return NonGateInstruction(
|
1395
2178
|
instruction_ref=self._attr_instruction_ref,
|
1396
2179
|
name=self._attr_name,
|
1397
2180
|
operands=self._attr_operands.copy(),
|
2181
|
+
parameter=self._attr_parameter,
|
1398
2182
|
annotations=self._attr_annotations.copy()
|
1399
2183
|
)
|
1400
2184
|
|
@@ -1404,10 +2188,11 @@ class Instruction(Statement):
|
|
1404
2188
|
original tree. If you're not cloning a subtree in a context where this
|
1405
2189
|
is the desired behavior, you may want to use the copy.deepcopy() from
|
1406
2190
|
the stdlib instead, which should copy links correctly."""
|
1407
|
-
return
|
2191
|
+
return NonGateInstruction(
|
1408
2192
|
instruction_ref=_cloned(self._attr_instruction_ref),
|
1409
2193
|
name=_cloned(self._attr_name),
|
1410
2194
|
operands=_cloned(self._attr_operands),
|
2195
|
+
parameter=_cloned(self._attr_parameter),
|
1411
2196
|
annotations=_cloned(self._attr_annotations)
|
1412
2197
|
)
|
1413
2198
|
|
@@ -1424,8 +2209,8 @@ class Instruction(Statement):
|
|
1424
2209
|
typ = cbor.get('@t', None)
|
1425
2210
|
if typ is None:
|
1426
2211
|
raise ValueError('type (@t) field is missing from node serialization')
|
1427
|
-
if typ != '
|
1428
|
-
raise ValueError('found node serialization for ' + typ + ', but expected
|
2212
|
+
if typ != 'NonGateInstruction':
|
2213
|
+
raise ValueError('found node serialization for ' + typ + ', but expected NonGateInstruction')
|
1429
2214
|
|
1430
2215
|
# Deserialize the instruction_ref field.
|
1431
2216
|
field = cbor.get('instruction_ref', None)
|
@@ -1460,6 +2245,17 @@ class Instruction(Statement):
|
|
1460
2245
|
raise ValueError('unexpected edge type for Any/Many element')
|
1461
2246
|
f_operands.append(cqasm.v3x.values.ValueBase._deserialize(element, seq_to_ob, links))
|
1462
2247
|
|
2248
|
+
# Deserialize the parameter field.
|
2249
|
+
field = cbor.get('parameter', None)
|
2250
|
+
if not isinstance(field, dict):
|
2251
|
+
raise ValueError('missing or invalid serialization of field parameter')
|
2252
|
+
if field.get('@T') != '?':
|
2253
|
+
raise ValueError('unexpected edge type for field parameter')
|
2254
|
+
if field.get('@t', None) is None:
|
2255
|
+
f_parameter = None
|
2256
|
+
else:
|
2257
|
+
f_parameter = cqasm.v3x.values.ValueBase._deserialize(field, seq_to_ob, links)
|
2258
|
+
|
1463
2259
|
# Deserialize the annotations field.
|
1464
2260
|
field = cbor.get('annotations', None)
|
1465
2261
|
if not isinstance(field, dict):
|
@@ -1475,8 +2271,8 @@ class Instruction(Statement):
|
|
1475
2271
|
raise ValueError('unexpected edge type for Any/Many element')
|
1476
2272
|
f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
|
1477
2273
|
|
1478
|
-
# Construct the
|
1479
|
-
node =
|
2274
|
+
# Construct the NonGateInstruction node.
|
2275
|
+
node = NonGateInstruction(f_instruction_ref, f_name, f_operands, f_parameter, f_annotations)
|
1480
2276
|
|
1481
2277
|
# Deserialize annotations.
|
1482
2278
|
for key, val in cbor.items():
|
@@ -1500,7 +2296,7 @@ class Instruction(Statement):
|
|
1500
2296
|
CBOR serialization. The tree that the node belongs to must be
|
1501
2297
|
well-formed. id_map must match Python id() calls for all nodes to unique
|
1502
2298
|
integers, to use for the sequence number representation of links."""
|
1503
|
-
cbor = {'@i': id_map[id(self)], '@t': '
|
2299
|
+
cbor = {'@i': id_map[id(self)], '@t': 'NonGateInstruction'}
|
1504
2300
|
|
1505
2301
|
# Serialize the instruction_ref field.
|
1506
2302
|
if hasattr(self._attr_instruction_ref, 'serialize_cbor'):
|
@@ -1524,6 +2320,14 @@ class Instruction(Statement):
|
|
1524
2320
|
field['@d'] = lst
|
1525
2321
|
cbor['operands'] = field
|
1526
2322
|
|
2323
|
+
# Serialize the parameter field.
|
2324
|
+
field = {'@T': '?'}
|
2325
|
+
if self._attr_parameter is None:
|
2326
|
+
field['@t'] = None
|
2327
|
+
else:
|
2328
|
+
field.update(self._attr_parameter._serialize(id_map))
|
2329
|
+
cbor['parameter'] = field
|
2330
|
+
|
1527
2331
|
# Serialize the annotations field.
|
1528
2332
|
field = {'@T': '*'}
|
1529
2333
|
lst = []
|
@@ -1541,13 +2345,13 @@ class Instruction(Statement):
|
|
1541
2345
|
return cbor
|
1542
2346
|
|
1543
2347
|
|
1544
|
-
class
|
1545
|
-
"""Wrapper for an edge with multiple
|
2348
|
+
class MultiNonGateInstruction(_Multiple):
|
2349
|
+
"""Wrapper for an edge with multiple NonGateInstruction objects."""
|
1546
2350
|
|
1547
|
-
_T =
|
2351
|
+
_T = NonGateInstruction
|
1548
2352
|
|
1549
2353
|
|
1550
|
-
_typemap['
|
2354
|
+
_typemap['NonGateInstruction'] = NonGateInstruction
|
1551
2355
|
|
1552
2356
|
class Program(Node):
|
1553
2357
|
__slots__ = [
|