libqasm 0.6.7__cp39-cp39-macosx_11_0_arm64.whl → 0.6.8__cp39-cp39-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/ast.py CHANGED
@@ -1166,14 +1166,14 @@ class Annotated(Node):
1166
1166
  typ = cbor.get('@t', None)
1167
1167
  if typ is None:
1168
1168
  raise ValueError('type (@t) field is missing from node serialization')
1169
- if typ == 'Variable':
1170
- return Variable._deserialize(cbor, seq_to_ob, links)
1171
1169
  if typ == 'Gate':
1172
1170
  return Gate._deserialize(cbor, seq_to_ob, links)
1173
- if typ == 'MeasureInstruction':
1174
- return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
1175
- if typ == 'ResetInstruction':
1176
- return ResetInstruction._deserialize(cbor, seq_to_ob, links)
1171
+ if typ == 'Variable':
1172
+ return Variable._deserialize(cbor, seq_to_ob, links)
1173
+ if typ == 'GateInstruction':
1174
+ return GateInstruction._deserialize(cbor, seq_to_ob, links)
1175
+ if typ == 'NonGateInstruction':
1176
+ return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
1177
1177
  raise ValueError('unknown or unexpected type (@t) found in node serialization')
1178
1178
 
1179
1179
  def _serialize(self, id_map):
@@ -2524,12 +2524,10 @@ class Statement(Annotated):
2524
2524
  raise ValueError('type (@t) field is missing from node serialization')
2525
2525
  if typ == 'Variable':
2526
2526
  return Variable._deserialize(cbor, seq_to_ob, links)
2527
- if typ == 'Gate':
2528
- return Gate._deserialize(cbor, seq_to_ob, links)
2529
- if typ == 'MeasureInstruction':
2530
- return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
2531
- if typ == 'ResetInstruction':
2532
- return ResetInstruction._deserialize(cbor, seq_to_ob, links)
2527
+ if typ == 'GateInstruction':
2528
+ return GateInstruction._deserialize(cbor, seq_to_ob, links)
2529
+ if typ == 'NonGateInstruction':
2530
+ return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
2533
2531
  raise ValueError('unknown or unexpected type (@t) found in node serialization')
2534
2532
 
2535
2533
  def _serialize(self, id_map):
@@ -2588,12 +2586,10 @@ class BlockStatement(Statement):
2588
2586
  raise ValueError('type (@t) field is missing from node serialization')
2589
2587
  if typ == 'Variable':
2590
2588
  return Variable._deserialize(cbor, seq_to_ob, links)
2591
- if typ == 'Gate':
2592
- return Gate._deserialize(cbor, seq_to_ob, links)
2593
- if typ == 'MeasureInstruction':
2594
- return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
2595
- if typ == 'ResetInstruction':
2596
- return ResetInstruction._deserialize(cbor, seq_to_ob, links)
2589
+ if typ == 'GateInstruction':
2590
+ return GateInstruction._deserialize(cbor, seq_to_ob, links)
2591
+ if typ == 'NonGateInstruction':
2592
+ return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
2597
2593
  raise ValueError('unknown or unexpected type (@t) found in node serialization')
2598
2594
 
2599
2595
  def _serialize(self, id_map):
@@ -4983,83 +4979,27 @@ class MultiFunctionCall(_Multiple):
4983
4979
 
4984
4980
  _typemap['FunctionCall'] = FunctionCall
4985
4981
 
4986
- class Instruction(BlockStatement):
4987
- __slots__ = []
4988
-
4989
- def __init__(
4990
- self,
4991
- annotations=None,
4992
- ):
4993
- super().__init__(annotations=annotations)
4994
-
4995
- @staticmethod
4996
- def _deserialize(cbor, seq_to_ob, links):
4997
- """Attempts to deserialize the given cbor object (in Python primitive
4998
- representation) into a node of this type. All (sub)nodes are added to
4999
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
5000
- registered in the links list by means of a two-tuple of the setter
5001
- function for the link field and the sequence number of the target node.
5002
- """
5003
- if not isinstance(cbor, dict):
5004
- raise TypeError('node description object must be a dict')
5005
- typ = cbor.get('@t', None)
5006
- if typ is None:
5007
- raise ValueError('type (@t) field is missing from node serialization')
5008
- if typ == 'Gate':
5009
- return Gate._deserialize(cbor, seq_to_ob, links)
5010
- if typ == 'MeasureInstruction':
5011
- return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
5012
- if typ == 'ResetInstruction':
5013
- return ResetInstruction._deserialize(cbor, seq_to_ob, links)
5014
- raise ValueError('unknown or unexpected type (@t) found in node serialization')
5015
-
5016
- def _serialize(self, id_map):
5017
- """Serializes this node to the Python primitive representation of its
5018
- CBOR serialization. The tree that the node belongs to must be
5019
- well-formed. id_map must match Python id() calls for all nodes to unique
5020
- integers, to use for the sequence number representation of links."""
5021
- cbor = {'@i': id_map[id(self)], '@t': 'Instruction'}
5022
-
5023
- # Serialize the annotations field.
5024
- field = {'@T': '*'}
5025
- lst = []
5026
- for el in self._attr_annotations:
5027
- el = el._serialize(id_map)
5028
- el['@T'] = '1'
5029
- lst.append(el)
5030
- field['@d'] = lst
5031
- cbor['annotations'] = field
5032
-
5033
- # Serialize annotations.
5034
- for key, val in self._annot.items():
5035
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
5036
-
5037
- return cbor
5038
-
5039
-
5040
- class MultiInstruction(_Multiple):
5041
- """Wrapper for an edge with multiple Instruction objects."""
5042
-
5043
- _T = Instruction
5044
-
5045
-
5046
- _typemap['Instruction'] = Instruction
4982
+ class Gate(Annotated):
4983
+ """A gate can be a named gate or a composition of gate modifiers acting on a
4984
+ gate."""
5047
4985
 
5048
- class Gate(Instruction):
5049
4986
  __slots__ = [
5050
4987
  '_attr_name',
5051
- '_attr_operands',
4988
+ '_attr_gate',
4989
+ '_attr_parameter',
5052
4990
  ]
5053
4991
 
5054
4992
  def __init__(
5055
4993
  self,
5056
4994
  name=None,
5057
- operands=None,
4995
+ gate=None,
4996
+ parameter=None,
5058
4997
  annotations=None,
5059
4998
  ):
5060
4999
  super().__init__(annotations=annotations)
5061
5000
  self.name = name
5062
- self.operands = operands
5001
+ self.gate = gate
5002
+ self.parameter = parameter
5063
5003
 
5064
5004
  @property
5065
5005
  def name(self):
@@ -5082,24 +5022,44 @@ class Gate(Instruction):
5082
5022
  self._attr_name = None
5083
5023
 
5084
5024
  @property
5085
- def operands(self):
5086
- return self._attr_operands
5025
+ def gate(self):
5026
+ return self._attr_gate
5087
5027
 
5088
- @operands.setter
5089
- def operands(self, val):
5028
+ @gate.setter
5029
+ def gate(self, val):
5090
5030
  if val is None:
5091
- del self.operands
5031
+ del self.gate
5092
5032
  return
5093
- if not isinstance(val, ExpressionList):
5033
+ if not isinstance(val, Gate):
5094
5034
  # Try to "typecast" if this isn't an obvious mistake.
5095
5035
  if isinstance(val, Node):
5096
- raise TypeError('operands must be of type ExpressionList')
5097
- val = ExpressionList(val)
5098
- self._attr_operands = val
5036
+ raise TypeError('gate must be of type Gate')
5037
+ val = Gate(val)
5038
+ self._attr_gate = val
5099
5039
 
5100
- @operands.deleter
5101
- def operands(self):
5102
- self._attr_operands = None
5040
+ @gate.deleter
5041
+ def gate(self):
5042
+ self._attr_gate = None
5043
+
5044
+ @property
5045
+ def parameter(self):
5046
+ return self._attr_parameter
5047
+
5048
+ @parameter.setter
5049
+ def parameter(self, val):
5050
+ if val is None:
5051
+ del self.parameter
5052
+ return
5053
+ if not isinstance(val, Expression):
5054
+ # Try to "typecast" if this isn't an obvious mistake.
5055
+ if isinstance(val, Node):
5056
+ raise TypeError('parameter must be of type Expression')
5057
+ val = Expression(val)
5058
+ self._attr_parameter = val
5059
+
5060
+ @parameter.deleter
5061
+ def parameter(self):
5062
+ self._attr_parameter = None
5103
5063
 
5104
5064
  def __eq__(self, other):
5105
5065
  """Equality operator. Ignores annotations!"""
@@ -5107,7 +5067,9 @@ class Gate(Instruction):
5107
5067
  return False
5108
5068
  if self.name != other.name:
5109
5069
  return False
5110
- if self.operands != other.operands:
5070
+ if self.gate != other.gate:
5071
+ return False
5072
+ if self.parameter != other.parameter:
5111
5073
  return False
5112
5074
  if self.annotations != other.annotations:
5113
5075
  return False
@@ -5137,12 +5099,20 @@ class Gate(Instruction):
5137
5099
  s.append(self.name.dump(indent + 1, annotations, links) + '\n')
5138
5100
  s.append(' '*indent + '>\n')
5139
5101
  s.append(' '*indent)
5140
- s.append('operands: ')
5141
- if self.operands is None:
5142
- s.append('!MISSING\n')
5102
+ s.append('gate: ')
5103
+ if self.gate is None:
5104
+ s.append('-\n')
5143
5105
  else:
5144
5106
  s.append('<\n')
5145
- s.append(self.operands.dump(indent + 1, annotations, links) + '\n')
5107
+ s.append(self.gate.dump(indent + 1, annotations, links) + '\n')
5108
+ s.append(' '*indent + '>\n')
5109
+ s.append(' '*indent)
5110
+ s.append('parameter: ')
5111
+ if self.parameter is None:
5112
+ s.append('-\n')
5113
+ else:
5114
+ s.append('<\n')
5115
+ s.append(self.parameter.dump(indent + 1, annotations, links) + '\n')
5146
5116
  s.append(' '*indent + '>\n')
5147
5117
  s.append(' '*indent)
5148
5118
  s.append('annotations: ')
@@ -5172,8 +5142,10 @@ class Gate(Instruction):
5172
5142
  id_map[id(self)] = len(id_map)
5173
5143
  if self._attr_name is not None:
5174
5144
  self._attr_name.find_reachable(id_map)
5175
- if self._attr_operands is not None:
5176
- self._attr_operands.find_reachable(id_map)
5145
+ if self._attr_gate is not None:
5146
+ self._attr_gate.find_reachable(id_map)
5147
+ if self._attr_parameter is not None:
5148
+ self._attr_parameter.find_reachable(id_map)
5177
5149
  for el in self._attr_annotations:
5178
5150
  el.find_reachable(id_map)
5179
5151
  return id_map
@@ -5189,10 +5161,10 @@ class Gate(Instruction):
5189
5161
  raise NotWellFormed('name is required but not set')
5190
5162
  if self._attr_name is not None:
5191
5163
  self._attr_name.check_complete(id_map)
5192
- if self._attr_operands is None:
5193
- raise NotWellFormed('operands is required but not set')
5194
- if self._attr_operands is not None:
5195
- self._attr_operands.check_complete(id_map)
5164
+ if self._attr_gate is not None:
5165
+ self._attr_gate.check_complete(id_map)
5166
+ if self._attr_parameter is not None:
5167
+ self._attr_parameter.check_complete(id_map)
5196
5168
  for child in self._attr_annotations:
5197
5169
  child.check_complete(id_map)
5198
5170
 
@@ -5200,7 +5172,8 @@ class Gate(Instruction):
5200
5172
  """Returns a shallow copy of this node."""
5201
5173
  return Gate(
5202
5174
  name=self._attr_name,
5203
- operands=self._attr_operands,
5175
+ gate=self._attr_gate,
5176
+ parameter=self._attr_parameter,
5204
5177
  annotations=self._attr_annotations.copy()
5205
5178
  )
5206
5179
 
@@ -5212,7 +5185,8 @@ class Gate(Instruction):
5212
5185
  the stdlib instead, which should copy links correctly."""
5213
5186
  return Gate(
5214
5187
  name=_cloned(self._attr_name),
5215
- operands=_cloned(self._attr_operands),
5188
+ gate=_cloned(self._attr_gate),
5189
+ parameter=_cloned(self._attr_parameter),
5216
5190
  annotations=_cloned(self._attr_annotations)
5217
5191
  )
5218
5192
 
@@ -5243,16 +5217,27 @@ class Gate(Instruction):
5243
5217
  else:
5244
5218
  f_name = Identifier._deserialize(field, seq_to_ob, links)
5245
5219
 
5246
- # Deserialize the operands field.
5247
- field = cbor.get('operands', None)
5220
+ # Deserialize the gate field.
5221
+ field = cbor.get('gate', None)
5248
5222
  if not isinstance(field, dict):
5249
- raise ValueError('missing or invalid serialization of field operands')
5250
- if field.get('@T') != '1':
5251
- raise ValueError('unexpected edge type for field operands')
5223
+ raise ValueError('missing or invalid serialization of field gate')
5224
+ if field.get('@T') != '?':
5225
+ raise ValueError('unexpected edge type for field gate')
5252
5226
  if field.get('@t', None) is None:
5253
- f_operands = None
5227
+ f_gate = None
5254
5228
  else:
5255
- f_operands = ExpressionList._deserialize(field, seq_to_ob, links)
5229
+ f_gate = Gate._deserialize(field, seq_to_ob, links)
5230
+
5231
+ # Deserialize the parameter field.
5232
+ field = cbor.get('parameter', None)
5233
+ if not isinstance(field, dict):
5234
+ raise ValueError('missing or invalid serialization of field parameter')
5235
+ if field.get('@T') != '?':
5236
+ raise ValueError('unexpected edge type for field parameter')
5237
+ if field.get('@t', None) is None:
5238
+ f_parameter = None
5239
+ else:
5240
+ f_parameter = Expression._deserialize(field, seq_to_ob, links)
5256
5241
 
5257
5242
  # Deserialize the annotations field.
5258
5243
  field = cbor.get('annotations', None)
@@ -5270,7 +5255,7 @@ class Gate(Instruction):
5270
5255
  f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
5271
5256
 
5272
5257
  # Construct the Gate node.
5273
- node = Gate(f_name, f_operands, f_annotations)
5258
+ node = Gate(f_name, f_gate, f_parameter, f_annotations)
5274
5259
 
5275
5260
  # Deserialize annotations.
5276
5261
  for key, val in cbor.items():
@@ -5304,13 +5289,21 @@ class Gate(Instruction):
5304
5289
  field.update(self._attr_name._serialize(id_map))
5305
5290
  cbor['name'] = field
5306
5291
 
5307
- # Serialize the operands field.
5308
- field = {'@T': '1'}
5309
- if self._attr_operands is None:
5292
+ # Serialize the gate field.
5293
+ field = {'@T': '?'}
5294
+ if self._attr_gate is None:
5310
5295
  field['@t'] = None
5311
5296
  else:
5312
- field.update(self._attr_operands._serialize(id_map))
5313
- cbor['operands'] = field
5297
+ field.update(self._attr_gate._serialize(id_map))
5298
+ cbor['gate'] = field
5299
+
5300
+ # Serialize the parameter field.
5301
+ field = {'@T': '?'}
5302
+ if self._attr_parameter is None:
5303
+ field['@t'] = None
5304
+ else:
5305
+ field.update(self._attr_parameter._serialize(id_map))
5306
+ cbor['parameter'] = field
5314
5307
 
5315
5308
  # Serialize the annotations field.
5316
5309
  field = {'@T': '*'}
@@ -5337,43 +5330,131 @@ class MultiGate(_Multiple):
5337
5330
 
5338
5331
  _typemap['Gate'] = Gate
5339
5332
 
5340
- class GlobalBlock(Block):
5333
+ class Instruction(BlockStatement):
5334
+ __slots__ = []
5335
+
5336
+ def __init__(
5337
+ self,
5338
+ annotations=None,
5339
+ ):
5340
+ super().__init__(annotations=annotations)
5341
+
5342
+ @staticmethod
5343
+ def _deserialize(cbor, seq_to_ob, links):
5344
+ """Attempts to deserialize the given cbor object (in Python primitive
5345
+ representation) into a node of this type. All (sub)nodes are added to
5346
+ the seq_to_ob dict, indexed by their cbor sequence number. All links are
5347
+ registered in the links list by means of a two-tuple of the setter
5348
+ function for the link field and the sequence number of the target node.
5349
+ """
5350
+ if not isinstance(cbor, dict):
5351
+ raise TypeError('node description object must be a dict')
5352
+ typ = cbor.get('@t', None)
5353
+ if typ is None:
5354
+ raise ValueError('type (@t) field is missing from node serialization')
5355
+ if typ == 'GateInstruction':
5356
+ return GateInstruction._deserialize(cbor, seq_to_ob, links)
5357
+ if typ == 'NonGateInstruction':
5358
+ return NonGateInstruction._deserialize(cbor, seq_to_ob, links)
5359
+ raise ValueError('unknown or unexpected type (@t) found in node serialization')
5360
+
5361
+ def _serialize(self, id_map):
5362
+ """Serializes this node to the Python primitive representation of its
5363
+ CBOR serialization. The tree that the node belongs to must be
5364
+ well-formed. id_map must match Python id() calls for all nodes to unique
5365
+ integers, to use for the sequence number representation of links."""
5366
+ cbor = {'@i': id_map[id(self)], '@t': 'Instruction'}
5367
+
5368
+ # Serialize the annotations field.
5369
+ field = {'@T': '*'}
5370
+ lst = []
5371
+ for el in self._attr_annotations:
5372
+ el = el._serialize(id_map)
5373
+ el['@T'] = '1'
5374
+ lst.append(el)
5375
+ field['@d'] = lst
5376
+ cbor['annotations'] = field
5377
+
5378
+ # Serialize annotations.
5379
+ for key, val in self._annot.items():
5380
+ cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
5381
+
5382
+ return cbor
5383
+
5384
+
5385
+ class MultiInstruction(_Multiple):
5386
+ """Wrapper for an edge with multiple Instruction objects."""
5387
+
5388
+ _T = Instruction
5389
+
5390
+
5391
+ _typemap['Instruction'] = Instruction
5392
+
5393
+ class GateInstruction(Instruction):
5341
5394
  __slots__ = [
5342
- '_attr_statements',
5395
+ '_attr_gate',
5396
+ '_attr_operands',
5343
5397
  ]
5344
5398
 
5345
5399
  def __init__(
5346
5400
  self,
5347
- statements=None,
5401
+ gate=None,
5402
+ operands=None,
5403
+ annotations=None,
5348
5404
  ):
5349
- super().__init__()
5350
- self.statements = statements
5405
+ super().__init__(annotations=annotations)
5406
+ self.gate = gate
5407
+ self.operands = operands
5351
5408
 
5352
5409
  @property
5353
- def statements(self):
5354
- return self._attr_statements
5410
+ def gate(self):
5411
+ return self._attr_gate
5355
5412
 
5356
- @statements.setter
5357
- def statements(self, val):
5413
+ @gate.setter
5414
+ def gate(self, val):
5358
5415
  if val is None:
5359
- del self.statements
5416
+ del self.gate
5360
5417
  return
5361
- if not isinstance(val, MultiStatement):
5418
+ if not isinstance(val, Gate):
5362
5419
  # Try to "typecast" if this isn't an obvious mistake.
5363
5420
  if isinstance(val, Node):
5364
- raise TypeError('statements must be of type MultiStatement')
5365
- val = MultiStatement(val)
5366
- self._attr_statements = val
5421
+ raise TypeError('gate must be of type Gate')
5422
+ val = Gate(val)
5423
+ self._attr_gate = val
5367
5424
 
5368
- @statements.deleter
5369
- def statements(self):
5370
- self._attr_statements = MultiStatement()
5425
+ @gate.deleter
5426
+ def gate(self):
5427
+ self._attr_gate = None
5428
+
5429
+ @property
5430
+ def operands(self):
5431
+ return self._attr_operands
5432
+
5433
+ @operands.setter
5434
+ def operands(self, val):
5435
+ if val is None:
5436
+ del self.operands
5437
+ return
5438
+ if not isinstance(val, ExpressionList):
5439
+ # Try to "typecast" if this isn't an obvious mistake.
5440
+ if isinstance(val, Node):
5441
+ raise TypeError('operands must be of type ExpressionList')
5442
+ val = ExpressionList(val)
5443
+ self._attr_operands = val
5444
+
5445
+ @operands.deleter
5446
+ def operands(self):
5447
+ self._attr_operands = None
5371
5448
 
5372
5449
  def __eq__(self, other):
5373
5450
  """Equality operator. Ignores annotations!"""
5374
- if not isinstance(other, GlobalBlock):
5451
+ if not isinstance(other, GateInstruction):
5375
5452
  return False
5376
- if self.statements != other.statements:
5453
+ if self.gate != other.gate:
5454
+ return False
5455
+ if self.operands != other.operands:
5456
+ return False
5457
+ if self.annotations != other.annotations:
5377
5458
  return False
5378
5459
  return True
5379
5460
 
@@ -5384,7 +5465,7 @@ class GlobalBlock(Block):
5384
5465
  strings of the annotations that are to be printed. links specifies the
5385
5466
  maximum link recursion depth."""
5386
5467
  s = [' '*indent]
5387
- s.append('GlobalBlock(')
5468
+ s.append('GateInstruction(')
5388
5469
  if annotations is None:
5389
5470
  annotations = []
5390
5471
  for key in annotations:
@@ -5393,12 +5474,276 @@ class GlobalBlock(Block):
5393
5474
  s.append('\n')
5394
5475
  indent += 1
5395
5476
  s.append(' '*indent)
5396
- s.append('statements: ')
5397
- if not self.statements:
5477
+ s.append('gate: ')
5478
+ if self.gate is None:
5479
+ s.append('!MISSING\n')
5480
+ else:
5481
+ s.append('<\n')
5482
+ s.append(self.gate.dump(indent + 1, annotations, links) + '\n')
5483
+ s.append(' '*indent + '>\n')
5484
+ s.append(' '*indent)
5485
+ s.append('operands: ')
5486
+ if self.operands is None:
5487
+ s.append('!MISSING\n')
5488
+ else:
5489
+ s.append('<\n')
5490
+ s.append(self.operands.dump(indent + 1, annotations, links) + '\n')
5491
+ s.append(' '*indent + '>\n')
5492
+ s.append(' '*indent)
5493
+ s.append('annotations: ')
5494
+ if not self.annotations:
5398
5495
  s.append('-\n')
5399
5496
  else:
5400
5497
  s.append('[\n')
5401
- for child in self.statements:
5498
+ for child in self.annotations:
5499
+ s.append(child.dump(indent + 1, annotations, links) + '\n')
5500
+ s.append(' '*indent + ']\n')
5501
+ indent -= 1
5502
+ s.append(' '*indent)
5503
+ s.append(')')
5504
+ return ''.join(s)
5505
+
5506
+ __str__ = dump
5507
+ __repr__ = dump
5508
+
5509
+ def find_reachable(self, id_map=None):
5510
+ """Returns a dictionary mapping Python id() values to stable sequence
5511
+ numbers for all nodes in the tree rooted at this node. If id_map is
5512
+ specified, found nodes are appended to it."""
5513
+ if id_map is None:
5514
+ id_map = {}
5515
+ if id(self) in id_map:
5516
+ raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
5517
+ id_map[id(self)] = len(id_map)
5518
+ if self._attr_gate is not None:
5519
+ self._attr_gate.find_reachable(id_map)
5520
+ if self._attr_operands is not None:
5521
+ self._attr_operands.find_reachable(id_map)
5522
+ for el in self._attr_annotations:
5523
+ el.find_reachable(id_map)
5524
+ return id_map
5525
+
5526
+ def check_complete(self, id_map=None):
5527
+ """Raises NotWellFormed if the tree rooted at this node is not
5528
+ well-formed. If id_map is specified, this tree is only a subtree in the
5529
+ context of a larger tree, and id_map must be a dict mapping from Python
5530
+ id() codes to tree indices for all reachable nodes."""
5531
+ if id_map is None:
5532
+ id_map = self.find_reachable()
5533
+ if self._attr_gate is None:
5534
+ raise NotWellFormed('gate is required but not set')
5535
+ if self._attr_gate is not None:
5536
+ self._attr_gate.check_complete(id_map)
5537
+ if self._attr_operands is None:
5538
+ raise NotWellFormed('operands is required but not set')
5539
+ if self._attr_operands is not None:
5540
+ self._attr_operands.check_complete(id_map)
5541
+ for child in self._attr_annotations:
5542
+ child.check_complete(id_map)
5543
+
5544
+ def copy(self):
5545
+ """Returns a shallow copy of this node."""
5546
+ return GateInstruction(
5547
+ gate=self._attr_gate,
5548
+ operands=self._attr_operands,
5549
+ annotations=self._attr_annotations.copy()
5550
+ )
5551
+
5552
+ def clone(self):
5553
+ """Returns a deep copy of this node. This mimics the C++ interface,
5554
+ deficiencies with links included; that is, links always point to the
5555
+ original tree. If you're not cloning a subtree in a context where this
5556
+ is the desired behavior, you may want to use the copy.deepcopy() from
5557
+ the stdlib instead, which should copy links correctly."""
5558
+ return GateInstruction(
5559
+ gate=_cloned(self._attr_gate),
5560
+ operands=_cloned(self._attr_operands),
5561
+ annotations=_cloned(self._attr_annotations)
5562
+ )
5563
+
5564
+ @staticmethod
5565
+ def _deserialize(cbor, seq_to_ob, links):
5566
+ """Attempts to deserialize the given cbor object (in Python primitive
5567
+ representation) into a node of this type. All (sub)nodes are added to
5568
+ the seq_to_ob dict, indexed by their cbor sequence number. All links are
5569
+ registered in the links list by means of a two-tuple of the setter
5570
+ function for the link field and the sequence number of the target node.
5571
+ """
5572
+ if not isinstance(cbor, dict):
5573
+ raise TypeError('node description object must be a dict')
5574
+ typ = cbor.get('@t', None)
5575
+ if typ is None:
5576
+ raise ValueError('type (@t) field is missing from node serialization')
5577
+ if typ != 'GateInstruction':
5578
+ raise ValueError('found node serialization for ' + typ + ', but expected GateInstruction')
5579
+
5580
+ # Deserialize the gate field.
5581
+ field = cbor.get('gate', None)
5582
+ if not isinstance(field, dict):
5583
+ raise ValueError('missing or invalid serialization of field gate')
5584
+ if field.get('@T') != '1':
5585
+ raise ValueError('unexpected edge type for field gate')
5586
+ if field.get('@t', None) is None:
5587
+ f_gate = None
5588
+ else:
5589
+ f_gate = Gate._deserialize(field, seq_to_ob, links)
5590
+
5591
+ # Deserialize the operands field.
5592
+ field = cbor.get('operands', None)
5593
+ if not isinstance(field, dict):
5594
+ raise ValueError('missing or invalid serialization of field operands')
5595
+ if field.get('@T') != '1':
5596
+ raise ValueError('unexpected edge type for field operands')
5597
+ if field.get('@t', None) is None:
5598
+ f_operands = None
5599
+ else:
5600
+ f_operands = ExpressionList._deserialize(field, seq_to_ob, links)
5601
+
5602
+ # Deserialize the annotations field.
5603
+ field = cbor.get('annotations', None)
5604
+ if not isinstance(field, dict):
5605
+ raise ValueError('missing or invalid serialization of field annotations')
5606
+ if field.get('@T') != '*':
5607
+ raise ValueError('unexpected edge type for field annotations')
5608
+ data = field.get('@d', None)
5609
+ if not isinstance(data, list):
5610
+ raise ValueError('missing serialization of Any/Many contents')
5611
+ f_annotations = MultiAnnotationData()
5612
+ for element in data:
5613
+ if element.get('@T') != '1':
5614
+ raise ValueError('unexpected edge type for Any/Many element')
5615
+ f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
5616
+
5617
+ # Construct the GateInstruction node.
5618
+ node = GateInstruction(f_gate, f_operands, f_annotations)
5619
+
5620
+ # Deserialize annotations.
5621
+ for key, val in cbor.items():
5622
+ if not (key.startswith('{') and key.endswith('}')):
5623
+ continue
5624
+ key = key[1:-1]
5625
+ node[key] = cqasm.v3x.primitives.deserialize(key, val)
5626
+
5627
+ # Register node in sequence number lookup.
5628
+ seq = cbor.get('@i', None)
5629
+ if not isinstance(seq, int):
5630
+ raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
5631
+ if seq in seq_to_ob:
5632
+ raise ValueError('duplicate sequence number %d' % seq)
5633
+ seq_to_ob[seq] = node
5634
+
5635
+ return node
5636
+
5637
+ def _serialize(self, id_map):
5638
+ """Serializes this node to the Python primitive representation of its
5639
+ CBOR serialization. The tree that the node belongs to must be
5640
+ well-formed. id_map must match Python id() calls for all nodes to unique
5641
+ integers, to use for the sequence number representation of links."""
5642
+ cbor = {'@i': id_map[id(self)], '@t': 'GateInstruction'}
5643
+
5644
+ # Serialize the gate field.
5645
+ field = {'@T': '1'}
5646
+ if self._attr_gate is None:
5647
+ field['@t'] = None
5648
+ else:
5649
+ field.update(self._attr_gate._serialize(id_map))
5650
+ cbor['gate'] = field
5651
+
5652
+ # Serialize the operands field.
5653
+ field = {'@T': '1'}
5654
+ if self._attr_operands is None:
5655
+ field['@t'] = None
5656
+ else:
5657
+ field.update(self._attr_operands._serialize(id_map))
5658
+ cbor['operands'] = field
5659
+
5660
+ # Serialize the annotations field.
5661
+ field = {'@T': '*'}
5662
+ lst = []
5663
+ for el in self._attr_annotations:
5664
+ el = el._serialize(id_map)
5665
+ el['@T'] = '1'
5666
+ lst.append(el)
5667
+ field['@d'] = lst
5668
+ cbor['annotations'] = field
5669
+
5670
+ # Serialize annotations.
5671
+ for key, val in self._annot.items():
5672
+ cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
5673
+
5674
+ return cbor
5675
+
5676
+
5677
+ class MultiGateInstruction(_Multiple):
5678
+ """Wrapper for an edge with multiple GateInstruction objects."""
5679
+
5680
+ _T = GateInstruction
5681
+
5682
+
5683
+ _typemap['GateInstruction'] = GateInstruction
5684
+
5685
+ class GlobalBlock(Block):
5686
+ __slots__ = [
5687
+ '_attr_statements',
5688
+ ]
5689
+
5690
+ def __init__(
5691
+ self,
5692
+ statements=None,
5693
+ ):
5694
+ super().__init__()
5695
+ self.statements = statements
5696
+
5697
+ @property
5698
+ def statements(self):
5699
+ return self._attr_statements
5700
+
5701
+ @statements.setter
5702
+ def statements(self, val):
5703
+ if val is None:
5704
+ del self.statements
5705
+ return
5706
+ if not isinstance(val, MultiStatement):
5707
+ # Try to "typecast" if this isn't an obvious mistake.
5708
+ if isinstance(val, Node):
5709
+ raise TypeError('statements must be of type MultiStatement')
5710
+ val = MultiStatement(val)
5711
+ self._attr_statements = val
5712
+
5713
+ @statements.deleter
5714
+ def statements(self):
5715
+ self._attr_statements = MultiStatement()
5716
+
5717
+ def __eq__(self, other):
5718
+ """Equality operator. Ignores annotations!"""
5719
+ if not isinstance(other, GlobalBlock):
5720
+ return False
5721
+ if self.statements != other.statements:
5722
+ return False
5723
+ return True
5724
+
5725
+ def dump(self, indent=0, annotations=None, links=1):
5726
+ """Returns a debug representation of this tree as a multiline string.
5727
+ indent is the number of double spaces prefixed before every line.
5728
+ annotations, if specified, must be a set-like object containing the key
5729
+ strings of the annotations that are to be printed. links specifies the
5730
+ maximum link recursion depth."""
5731
+ s = [' '*indent]
5732
+ s.append('GlobalBlock(')
5733
+ if annotations is None:
5734
+ annotations = []
5735
+ for key in annotations:
5736
+ if key in self:
5737
+ s.append(' # {}: {}'.format(key, self[key]))
5738
+ s.append('\n')
5739
+ indent += 1
5740
+ s.append(' '*indent)
5741
+ s.append('statements: ')
5742
+ if not self.statements:
5743
+ s.append('-\n')
5744
+ else:
5745
+ s.append('[\n')
5746
+ for child in self.statements:
5402
5747
  s.append(child.dump(indent + 1, annotations, links) + '\n')
5403
5748
  s.append(' '*indent + ']\n')
5404
5749
  indent -= 1
@@ -7834,103 +8179,25 @@ class MultiLogicalXorExpression(_Multiple):
7834
8179
 
7835
8180
  _typemap['LogicalXorExpression'] = LogicalXorExpression
7836
8181
 
7837
- class MeasureInstruction(Instruction):
7838
- """For some instructions, like the measure instruction, we want to
7839
- differentiate between left hand side and right and side operands. For a
7840
- measure instruction, the right hand side operand should be a qubit, and the
7841
- left hand side operand a bit."""
7842
-
7843
- __slots__ = [
7844
- '_attr_name',
7845
- '_attr_lhs',
7846
- '_attr_rhs',
7847
- ]
8182
+ class ModuloExpression(ArithmeticExpression):
8183
+ __slots__ = []
7848
8184
 
7849
8185
  def __init__(
7850
8186
  self,
7851
- name=None,
7852
8187
  lhs=None,
7853
8188
  rhs=None,
7854
- annotations=None,
7855
8189
  ):
7856
- super().__init__(annotations=annotations)
7857
- self.name = name
7858
- self.lhs = lhs
7859
- self.rhs = rhs
8190
+ super().__init__(lhs=lhs, rhs=rhs)
7860
8191
 
7861
- @property
7862
- def name(self):
7863
- return self._attr_name
7864
-
7865
- @name.setter
7866
- def name(self, val):
7867
- if val is None:
7868
- del self.name
7869
- return
7870
- if not isinstance(val, Identifier):
7871
- # Try to "typecast" if this isn't an obvious mistake.
7872
- if isinstance(val, Node):
7873
- raise TypeError('name must be of type Identifier')
7874
- val = Identifier(val)
7875
- self._attr_name = val
7876
-
7877
- @name.deleter
7878
- def name(self):
7879
- self._attr_name = None
7880
-
7881
- @property
7882
- def lhs(self):
7883
- return self._attr_lhs
7884
-
7885
- @lhs.setter
7886
- def lhs(self, val):
7887
- if val is None:
7888
- del self.lhs
7889
- return
7890
- if not isinstance(val, Expression):
7891
- # Try to "typecast" if this isn't an obvious mistake.
7892
- if isinstance(val, Node):
7893
- raise TypeError('lhs must be of type Expression')
7894
- val = Expression(val)
7895
- self._attr_lhs = val
7896
-
7897
- @lhs.deleter
7898
- def lhs(self):
7899
- self._attr_lhs = None
7900
-
7901
- @property
7902
- def rhs(self):
7903
- return self._attr_rhs
7904
-
7905
- @rhs.setter
7906
- def rhs(self, val):
7907
- if val is None:
7908
- del self.rhs
7909
- return
7910
- if not isinstance(val, Expression):
7911
- # Try to "typecast" if this isn't an obvious mistake.
7912
- if isinstance(val, Node):
7913
- raise TypeError('rhs must be of type Expression')
7914
- val = Expression(val)
7915
- self._attr_rhs = val
7916
-
7917
- @rhs.deleter
7918
- def rhs(self):
7919
- self._attr_rhs = None
7920
-
7921
- def __eq__(self, other):
7922
- """Equality operator. Ignores annotations!"""
7923
- if not isinstance(other, MeasureInstruction):
7924
- return False
7925
- if self.name != other.name:
7926
- return False
7927
- if self.lhs != other.lhs:
7928
- return False
7929
- if self.rhs != other.rhs:
7930
- return False
7931
- if self.annotations != other.annotations:
7932
- return False
7933
- return True
8192
+ def __eq__(self, other):
8193
+ """Equality operator. Ignores annotations!"""
8194
+ if not isinstance(other, ModuloExpression):
8195
+ return False
8196
+ if self.lhs != other.lhs:
8197
+ return False
8198
+ if self.rhs != other.rhs:
8199
+ return False
8200
+ return True
7934
8201
 
7935
8202
  def dump(self, indent=0, annotations=None, links=1):
7936
8203
  """Returns a debug representation of this tree as a multiline string.
@@ -7939,7 +8206,7 @@ class MeasureInstruction(Instruction):
7939
8206
  strings of the annotations that are to be printed. links specifies the
7940
8207
  maximum link recursion depth."""
7941
8208
  s = [' '*indent]
7942
- s.append('MeasureInstruction(')
8209
+ s.append('ModuloExpression(')
7943
8210
  if annotations is None:
7944
8211
  annotations = []
7945
8212
  for key in annotations:
@@ -7948,14 +8215,6 @@ class MeasureInstruction(Instruction):
7948
8215
  s.append('\n')
7949
8216
  indent += 1
7950
8217
  s.append(' '*indent)
7951
- s.append('name: ')
7952
- if self.name is None:
7953
- s.append('!MISSING\n')
7954
- else:
7955
- s.append('<\n')
7956
- s.append(self.name.dump(indent + 1, annotations, links) + '\n')
7957
- s.append(' '*indent + '>\n')
7958
- s.append(' '*indent)
7959
8218
  s.append('lhs: ')
7960
8219
  if self.lhs is None:
7961
8220
  s.append('!MISSING\n')
@@ -7971,15 +8230,6 @@ class MeasureInstruction(Instruction):
7971
8230
  s.append('<\n')
7972
8231
  s.append(self.rhs.dump(indent + 1, annotations, links) + '\n')
7973
8232
  s.append(' '*indent + '>\n')
7974
- s.append(' '*indent)
7975
- s.append('annotations: ')
7976
- if not self.annotations:
7977
- s.append('-\n')
7978
- else:
7979
- s.append('[\n')
7980
- for child in self.annotations:
7981
- s.append(child.dump(indent + 1, annotations, links) + '\n')
7982
- s.append(' '*indent + ']\n')
7983
8233
  indent -= 1
7984
8234
  s.append(' '*indent)
7985
8235
  s.append(')')
@@ -7997,14 +8247,10 @@ class MeasureInstruction(Instruction):
7997
8247
  if id(self) in id_map:
7998
8248
  raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
7999
8249
  id_map[id(self)] = len(id_map)
8000
- if self._attr_name is not None:
8001
- self._attr_name.find_reachable(id_map)
8002
8250
  if self._attr_lhs is not None:
8003
8251
  self._attr_lhs.find_reachable(id_map)
8004
8252
  if self._attr_rhs is not None:
8005
8253
  self._attr_rhs.find_reachable(id_map)
8006
- for el in self._attr_annotations:
8007
- el.find_reachable(id_map)
8008
8254
  return id_map
8009
8255
 
8010
8256
  def check_complete(self, id_map=None):
@@ -8014,10 +8260,6 @@ class MeasureInstruction(Instruction):
8014
8260
  id() codes to tree indices for all reachable nodes."""
8015
8261
  if id_map is None:
8016
8262
  id_map = self.find_reachable()
8017
- if self._attr_name is None:
8018
- raise NotWellFormed('name is required but not set')
8019
- if self._attr_name is not None:
8020
- self._attr_name.check_complete(id_map)
8021
8263
  if self._attr_lhs is None:
8022
8264
  raise NotWellFormed('lhs is required but not set')
8023
8265
  if self._attr_lhs is not None:
@@ -8026,16 +8268,12 @@ class MeasureInstruction(Instruction):
8026
8268
  raise NotWellFormed('rhs is required but not set')
8027
8269
  if self._attr_rhs is not None:
8028
8270
  self._attr_rhs.check_complete(id_map)
8029
- for child in self._attr_annotations:
8030
- child.check_complete(id_map)
8031
8271
 
8032
8272
  def copy(self):
8033
8273
  """Returns a shallow copy of this node."""
8034
- return MeasureInstruction(
8035
- name=self._attr_name,
8274
+ return ModuloExpression(
8036
8275
  lhs=self._attr_lhs,
8037
- rhs=self._attr_rhs,
8038
- annotations=self._attr_annotations.copy()
8276
+ rhs=self._attr_rhs
8039
8277
  )
8040
8278
 
8041
8279
  def clone(self):
@@ -8044,11 +8282,9 @@ class MeasureInstruction(Instruction):
8044
8282
  original tree. If you're not cloning a subtree in a context where this
8045
8283
  is the desired behavior, you may want to use the copy.deepcopy() from
8046
8284
  the stdlib instead, which should copy links correctly."""
8047
- return MeasureInstruction(
8048
- name=_cloned(self._attr_name),
8285
+ return ModuloExpression(
8049
8286
  lhs=_cloned(self._attr_lhs),
8050
- rhs=_cloned(self._attr_rhs),
8051
- annotations=_cloned(self._attr_annotations)
8287
+ rhs=_cloned(self._attr_rhs)
8052
8288
  )
8053
8289
 
8054
8290
  @staticmethod
@@ -8064,19 +8300,8 @@ class MeasureInstruction(Instruction):
8064
8300
  typ = cbor.get('@t', None)
8065
8301
  if typ is None:
8066
8302
  raise ValueError('type (@t) field is missing from node serialization')
8067
- if typ != 'MeasureInstruction':
8068
- raise ValueError('found node serialization for ' + typ + ', but expected MeasureInstruction')
8069
-
8070
- # Deserialize the name field.
8071
- field = cbor.get('name', None)
8072
- if not isinstance(field, dict):
8073
- raise ValueError('missing or invalid serialization of field name')
8074
- if field.get('@T') != '1':
8075
- raise ValueError('unexpected edge type for field name')
8076
- if field.get('@t', None) is None:
8077
- f_name = None
8078
- else:
8079
- f_name = Identifier._deserialize(field, seq_to_ob, links)
8303
+ if typ != 'ModuloExpression':
8304
+ raise ValueError('found node serialization for ' + typ + ', but expected ModuloExpression')
8080
8305
 
8081
8306
  # Deserialize the lhs field.
8082
8307
  field = cbor.get('lhs', None)
@@ -8100,23 +8325,8 @@ class MeasureInstruction(Instruction):
8100
8325
  else:
8101
8326
  f_rhs = Expression._deserialize(field, seq_to_ob, links)
8102
8327
 
8103
- # Deserialize the annotations field.
8104
- field = cbor.get('annotations', None)
8105
- if not isinstance(field, dict):
8106
- raise ValueError('missing or invalid serialization of field annotations')
8107
- if field.get('@T') != '*':
8108
- raise ValueError('unexpected edge type for field annotations')
8109
- data = field.get('@d', None)
8110
- if not isinstance(data, list):
8111
- raise ValueError('missing serialization of Any/Many contents')
8112
- f_annotations = MultiAnnotationData()
8113
- for element in data:
8114
- if element.get('@T') != '1':
8115
- raise ValueError('unexpected edge type for Any/Many element')
8116
- f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
8117
-
8118
- # Construct the MeasureInstruction node.
8119
- node = MeasureInstruction(f_name, f_lhs, f_rhs, f_annotations)
8328
+ # Construct the ModuloExpression node.
8329
+ node = ModuloExpression(f_lhs, f_rhs)
8120
8330
 
8121
8331
  # Deserialize annotations.
8122
8332
  for key, val in cbor.items():
@@ -8140,15 +8350,7 @@ class MeasureInstruction(Instruction):
8140
8350
  CBOR serialization. The tree that the node belongs to must be
8141
8351
  well-formed. id_map must match Python id() calls for all nodes to unique
8142
8352
  integers, to use for the sequence number representation of links."""
8143
- cbor = {'@i': id_map[id(self)], '@t': 'MeasureInstruction'}
8144
-
8145
- # Serialize the name field.
8146
- field = {'@T': '1'}
8147
- if self._attr_name is None:
8148
- field['@t'] = None
8149
- else:
8150
- field.update(self._attr_name._serialize(id_map))
8151
- cbor['name'] = field
8353
+ cbor = {'@i': id_map[id(self)], '@t': 'ModuloExpression'}
8152
8354
 
8153
8355
  # Serialize the lhs field.
8154
8356
  field = {'@T': '1'}
@@ -8166,16 +8368,6 @@ class MeasureInstruction(Instruction):
8166
8368
  field.update(self._attr_rhs._serialize(id_map))
8167
8369
  cbor['rhs'] = field
8168
8370
 
8169
- # Serialize the annotations field.
8170
- field = {'@T': '*'}
8171
- lst = []
8172
- for el in self._attr_annotations:
8173
- el = el._serialize(id_map)
8174
- el['@T'] = '1'
8175
- lst.append(el)
8176
- field['@d'] = lst
8177
- cbor['annotations'] = field
8178
-
8179
8371
  # Serialize annotations.
8180
8372
  for key, val in self._annot.items():
8181
8373
  cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
@@ -8183,31 +8375,79 @@ class MeasureInstruction(Instruction):
8183
8375
  return cbor
8184
8376
 
8185
8377
 
8186
- class MultiMeasureInstruction(_Multiple):
8187
- """Wrapper for an edge with multiple MeasureInstruction objects."""
8378
+ class MultiModuloExpression(_Multiple):
8379
+ """Wrapper for an edge with multiple ModuloExpression objects."""
8188
8380
 
8189
- _T = MeasureInstruction
8381
+ _T = ModuloExpression
8190
8382
 
8191
8383
 
8192
- _typemap['MeasureInstruction'] = MeasureInstruction
8384
+ _typemap['ModuloExpression'] = ModuloExpression
8193
8385
 
8194
- class ModuloExpression(ArithmeticExpression):
8195
- __slots__ = []
8386
+ class NonGateInstruction(Instruction):
8387
+ __slots__ = [
8388
+ '_attr_name',
8389
+ '_attr_operands',
8390
+ ]
8196
8391
 
8197
8392
  def __init__(
8198
8393
  self,
8199
- lhs=None,
8200
- rhs=None,
8394
+ name=None,
8395
+ operands=None,
8396
+ annotations=None,
8201
8397
  ):
8202
- super().__init__(lhs=lhs, rhs=rhs)
8398
+ super().__init__(annotations=annotations)
8399
+ self.name = name
8400
+ self.operands = operands
8401
+
8402
+ @property
8403
+ def name(self):
8404
+ return self._attr_name
8405
+
8406
+ @name.setter
8407
+ def name(self, val):
8408
+ if val is None:
8409
+ del self.name
8410
+ return
8411
+ if not isinstance(val, Keyword):
8412
+ # Try to "typecast" if this isn't an obvious mistake.
8413
+ if isinstance(val, Node):
8414
+ raise TypeError('name must be of type Keyword')
8415
+ val = Keyword(val)
8416
+ self._attr_name = val
8417
+
8418
+ @name.deleter
8419
+ def name(self):
8420
+ self._attr_name = None
8421
+
8422
+ @property
8423
+ def operands(self):
8424
+ return self._attr_operands
8425
+
8426
+ @operands.setter
8427
+ def operands(self, val):
8428
+ if val is None:
8429
+ del self.operands
8430
+ return
8431
+ if not isinstance(val, ExpressionList):
8432
+ # Try to "typecast" if this isn't an obvious mistake.
8433
+ if isinstance(val, Node):
8434
+ raise TypeError('operands must be of type ExpressionList')
8435
+ val = ExpressionList(val)
8436
+ self._attr_operands = val
8437
+
8438
+ @operands.deleter
8439
+ def operands(self):
8440
+ self._attr_operands = None
8203
8441
 
8204
8442
  def __eq__(self, other):
8205
8443
  """Equality operator. Ignores annotations!"""
8206
- if not isinstance(other, ModuloExpression):
8444
+ if not isinstance(other, NonGateInstruction):
8207
8445
  return False
8208
- if self.lhs != other.lhs:
8446
+ if self.name != other.name:
8209
8447
  return False
8210
- if self.rhs != other.rhs:
8448
+ if self.operands != other.operands:
8449
+ return False
8450
+ if self.annotations != other.annotations:
8211
8451
  return False
8212
8452
  return True
8213
8453
 
@@ -8218,7 +8458,7 @@ class ModuloExpression(ArithmeticExpression):
8218
8458
  strings of the annotations that are to be printed. links specifies the
8219
8459
  maximum link recursion depth."""
8220
8460
  s = [' '*indent]
8221
- s.append('ModuloExpression(')
8461
+ s.append('NonGateInstruction(')
8222
8462
  if annotations is None:
8223
8463
  annotations = []
8224
8464
  for key in annotations:
@@ -8227,21 +8467,30 @@ class ModuloExpression(ArithmeticExpression):
8227
8467
  s.append('\n')
8228
8468
  indent += 1
8229
8469
  s.append(' '*indent)
8230
- s.append('lhs: ')
8231
- if self.lhs is None:
8470
+ s.append('name: ')
8471
+ if self.name is None:
8232
8472
  s.append('!MISSING\n')
8233
8473
  else:
8234
8474
  s.append('<\n')
8235
- s.append(self.lhs.dump(indent + 1, annotations, links) + '\n')
8475
+ s.append(self.name.dump(indent + 1, annotations, links) + '\n')
8236
8476
  s.append(' '*indent + '>\n')
8237
8477
  s.append(' '*indent)
8238
- s.append('rhs: ')
8239
- if self.rhs is None:
8478
+ s.append('operands: ')
8479
+ if self.operands is None:
8240
8480
  s.append('!MISSING\n')
8241
8481
  else:
8242
8482
  s.append('<\n')
8243
- s.append(self.rhs.dump(indent + 1, annotations, links) + '\n')
8483
+ s.append(self.operands.dump(indent + 1, annotations, links) + '\n')
8244
8484
  s.append(' '*indent + '>\n')
8485
+ s.append(' '*indent)
8486
+ s.append('annotations: ')
8487
+ if not self.annotations:
8488
+ s.append('-\n')
8489
+ else:
8490
+ s.append('[\n')
8491
+ for child in self.annotations:
8492
+ s.append(child.dump(indent + 1, annotations, links) + '\n')
8493
+ s.append(' '*indent + ']\n')
8245
8494
  indent -= 1
8246
8495
  s.append(' '*indent)
8247
8496
  s.append(')')
@@ -8259,10 +8508,12 @@ class ModuloExpression(ArithmeticExpression):
8259
8508
  if id(self) in id_map:
8260
8509
  raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
8261
8510
  id_map[id(self)] = len(id_map)
8262
- if self._attr_lhs is not None:
8263
- self._attr_lhs.find_reachable(id_map)
8264
- if self._attr_rhs is not None:
8265
- self._attr_rhs.find_reachable(id_map)
8511
+ if self._attr_name is not None:
8512
+ self._attr_name.find_reachable(id_map)
8513
+ if self._attr_operands is not None:
8514
+ self._attr_operands.find_reachable(id_map)
8515
+ for el in self._attr_annotations:
8516
+ el.find_reachable(id_map)
8266
8517
  return id_map
8267
8518
 
8268
8519
  def check_complete(self, id_map=None):
@@ -8272,20 +8523,23 @@ class ModuloExpression(ArithmeticExpression):
8272
8523
  id() codes to tree indices for all reachable nodes."""
8273
8524
  if id_map is None:
8274
8525
  id_map = self.find_reachable()
8275
- if self._attr_lhs is None:
8276
- raise NotWellFormed('lhs is required but not set')
8277
- if self._attr_lhs is not None:
8278
- self._attr_lhs.check_complete(id_map)
8279
- if self._attr_rhs is None:
8280
- raise NotWellFormed('rhs is required but not set')
8281
- if self._attr_rhs is not None:
8282
- self._attr_rhs.check_complete(id_map)
8526
+ if self._attr_name is None:
8527
+ raise NotWellFormed('name is required but not set')
8528
+ if self._attr_name is not None:
8529
+ self._attr_name.check_complete(id_map)
8530
+ if self._attr_operands is None:
8531
+ raise NotWellFormed('operands is required but not set')
8532
+ if self._attr_operands is not None:
8533
+ self._attr_operands.check_complete(id_map)
8534
+ for child in self._attr_annotations:
8535
+ child.check_complete(id_map)
8283
8536
 
8284
8537
  def copy(self):
8285
8538
  """Returns a shallow copy of this node."""
8286
- return ModuloExpression(
8287
- lhs=self._attr_lhs,
8288
- rhs=self._attr_rhs
8539
+ return NonGateInstruction(
8540
+ name=self._attr_name,
8541
+ operands=self._attr_operands,
8542
+ annotations=self._attr_annotations.copy()
8289
8543
  )
8290
8544
 
8291
8545
  def clone(self):
@@ -8294,9 +8548,10 @@ class ModuloExpression(ArithmeticExpression):
8294
8548
  original tree. If you're not cloning a subtree in a context where this
8295
8549
  is the desired behavior, you may want to use the copy.deepcopy() from
8296
8550
  the stdlib instead, which should copy links correctly."""
8297
- return ModuloExpression(
8298
- lhs=_cloned(self._attr_lhs),
8299
- rhs=_cloned(self._attr_rhs)
8551
+ return NonGateInstruction(
8552
+ name=_cloned(self._attr_name),
8553
+ operands=_cloned(self._attr_operands),
8554
+ annotations=_cloned(self._attr_annotations)
8300
8555
  )
8301
8556
 
8302
8557
  @staticmethod
@@ -8312,33 +8567,48 @@ class ModuloExpression(ArithmeticExpression):
8312
8567
  typ = cbor.get('@t', None)
8313
8568
  if typ is None:
8314
8569
  raise ValueError('type (@t) field is missing from node serialization')
8315
- if typ != 'ModuloExpression':
8316
- raise ValueError('found node serialization for ' + typ + ', but expected ModuloExpression')
8570
+ if typ != 'NonGateInstruction':
8571
+ raise ValueError('found node serialization for ' + typ + ', but expected NonGateInstruction')
8317
8572
 
8318
- # Deserialize the lhs field.
8319
- field = cbor.get('lhs', None)
8573
+ # Deserialize the name field.
8574
+ field = cbor.get('name', None)
8320
8575
  if not isinstance(field, dict):
8321
- raise ValueError('missing or invalid serialization of field lhs')
8576
+ raise ValueError('missing or invalid serialization of field name')
8322
8577
  if field.get('@T') != '1':
8323
- raise ValueError('unexpected edge type for field lhs')
8578
+ raise ValueError('unexpected edge type for field name')
8324
8579
  if field.get('@t', None) is None:
8325
- f_lhs = None
8580
+ f_name = None
8326
8581
  else:
8327
- f_lhs = Expression._deserialize(field, seq_to_ob, links)
8582
+ f_name = Keyword._deserialize(field, seq_to_ob, links)
8328
8583
 
8329
- # Deserialize the rhs field.
8330
- field = cbor.get('rhs', None)
8584
+ # Deserialize the operands field.
8585
+ field = cbor.get('operands', None)
8331
8586
  if not isinstance(field, dict):
8332
- raise ValueError('missing or invalid serialization of field rhs')
8587
+ raise ValueError('missing or invalid serialization of field operands')
8333
8588
  if field.get('@T') != '1':
8334
- raise ValueError('unexpected edge type for field rhs')
8589
+ raise ValueError('unexpected edge type for field operands')
8335
8590
  if field.get('@t', None) is None:
8336
- f_rhs = None
8591
+ f_operands = None
8337
8592
  else:
8338
- f_rhs = Expression._deserialize(field, seq_to_ob, links)
8593
+ f_operands = ExpressionList._deserialize(field, seq_to_ob, links)
8339
8594
 
8340
- # Construct the ModuloExpression node.
8341
- node = ModuloExpression(f_lhs, f_rhs)
8595
+ # Deserialize the annotations field.
8596
+ field = cbor.get('annotations', None)
8597
+ if not isinstance(field, dict):
8598
+ raise ValueError('missing or invalid serialization of field annotations')
8599
+ if field.get('@T') != '*':
8600
+ raise ValueError('unexpected edge type for field annotations')
8601
+ data = field.get('@d', None)
8602
+ if not isinstance(data, list):
8603
+ raise ValueError('missing serialization of Any/Many contents')
8604
+ f_annotations = MultiAnnotationData()
8605
+ for element in data:
8606
+ if element.get('@T') != '1':
8607
+ raise ValueError('unexpected edge type for Any/Many element')
8608
+ f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
8609
+
8610
+ # Construct the NonGateInstruction node.
8611
+ node = NonGateInstruction(f_name, f_operands, f_annotations)
8342
8612
 
8343
8613
  # Deserialize annotations.
8344
8614
  for key, val in cbor.items():
@@ -8362,23 +8632,33 @@ class ModuloExpression(ArithmeticExpression):
8362
8632
  CBOR serialization. The tree that the node belongs to must be
8363
8633
  well-formed. id_map must match Python id() calls for all nodes to unique
8364
8634
  integers, to use for the sequence number representation of links."""
8365
- cbor = {'@i': id_map[id(self)], '@t': 'ModuloExpression'}
8635
+ cbor = {'@i': id_map[id(self)], '@t': 'NonGateInstruction'}
8366
8636
 
8367
- # Serialize the lhs field.
8637
+ # Serialize the name field.
8368
8638
  field = {'@T': '1'}
8369
- if self._attr_lhs is None:
8639
+ if self._attr_name is None:
8370
8640
  field['@t'] = None
8371
8641
  else:
8372
- field.update(self._attr_lhs._serialize(id_map))
8373
- cbor['lhs'] = field
8642
+ field.update(self._attr_name._serialize(id_map))
8643
+ cbor['name'] = field
8374
8644
 
8375
- # Serialize the rhs field.
8645
+ # Serialize the operands field.
8376
8646
  field = {'@T': '1'}
8377
- if self._attr_rhs is None:
8647
+ if self._attr_operands is None:
8378
8648
  field['@t'] = None
8379
8649
  else:
8380
- field.update(self._attr_rhs._serialize(id_map))
8381
- cbor['rhs'] = field
8650
+ field.update(self._attr_operands._serialize(id_map))
8651
+ cbor['operands'] = field
8652
+
8653
+ # Serialize the annotations field.
8654
+ field = {'@T': '*'}
8655
+ lst = []
8656
+ for el in self._attr_annotations:
8657
+ el = el._serialize(id_map)
8658
+ el['@T'] = '1'
8659
+ lst.append(el)
8660
+ field['@d'] = lst
8661
+ cbor['annotations'] = field
8382
8662
 
8383
8663
  # Serialize annotations.
8384
8664
  for key, val in self._annot.items():
@@ -8387,13 +8667,13 @@ class ModuloExpression(ArithmeticExpression):
8387
8667
  return cbor
8388
8668
 
8389
8669
 
8390
- class MultiModuloExpression(_Multiple):
8391
- """Wrapper for an edge with multiple ModuloExpression objects."""
8670
+ class MultiNonGateInstruction(_Multiple):
8671
+ """Wrapper for an edge with multiple NonGateInstruction objects."""
8392
8672
 
8393
- _T = ModuloExpression
8673
+ _T = NonGateInstruction
8394
8674
 
8395
8675
 
8396
- _typemap['ModuloExpression'] = ModuloExpression
8676
+ _typemap['NonGateInstruction'] = NonGateInstruction
8397
8677
 
8398
8678
  class PowerExpression(ArithmeticExpression):
8399
8679
  __slots__ = []
@@ -9097,296 +9377,6 @@ class MultiProgram(_Multiple):
9097
9377
 
9098
9378
  _typemap['Program'] = Program
9099
9379
 
9100
- class ResetInstruction(Instruction):
9101
- __slots__ = [
9102
- '_attr_name',
9103
- '_attr_operand',
9104
- ]
9105
-
9106
- def __init__(
9107
- self,
9108
- name=None,
9109
- operand=None,
9110
- annotations=None,
9111
- ):
9112
- super().__init__(annotations=annotations)
9113
- self.name = name
9114
- self.operand = operand
9115
-
9116
- @property
9117
- def name(self):
9118
- return self._attr_name
9119
-
9120
- @name.setter
9121
- def name(self, val):
9122
- if val is None:
9123
- del self.name
9124
- return
9125
- if not isinstance(val, Identifier):
9126
- # Try to "typecast" if this isn't an obvious mistake.
9127
- if isinstance(val, Node):
9128
- raise TypeError('name must be of type Identifier')
9129
- val = Identifier(val)
9130
- self._attr_name = val
9131
-
9132
- @name.deleter
9133
- def name(self):
9134
- self._attr_name = None
9135
-
9136
- @property
9137
- def operand(self):
9138
- return self._attr_operand
9139
-
9140
- @operand.setter
9141
- def operand(self, val):
9142
- if val is None:
9143
- del self.operand
9144
- return
9145
- if not isinstance(val, Expression):
9146
- # Try to "typecast" if this isn't an obvious mistake.
9147
- if isinstance(val, Node):
9148
- raise TypeError('operand must be of type Expression')
9149
- val = Expression(val)
9150
- self._attr_operand = val
9151
-
9152
- @operand.deleter
9153
- def operand(self):
9154
- self._attr_operand = None
9155
-
9156
- def __eq__(self, other):
9157
- """Equality operator. Ignores annotations!"""
9158
- if not isinstance(other, ResetInstruction):
9159
- return False
9160
- if self.name != other.name:
9161
- return False
9162
- if self.operand != other.operand:
9163
- return False
9164
- if self.annotations != other.annotations:
9165
- return False
9166
- return True
9167
-
9168
- def dump(self, indent=0, annotations=None, links=1):
9169
- """Returns a debug representation of this tree as a multiline string.
9170
- indent is the number of double spaces prefixed before every line.
9171
- annotations, if specified, must be a set-like object containing the key
9172
- strings of the annotations that are to be printed. links specifies the
9173
- maximum link recursion depth."""
9174
- s = [' '*indent]
9175
- s.append('ResetInstruction(')
9176
- if annotations is None:
9177
- annotations = []
9178
- for key in annotations:
9179
- if key in self:
9180
- s.append(' # {}: {}'.format(key, self[key]))
9181
- s.append('\n')
9182
- indent += 1
9183
- s.append(' '*indent)
9184
- s.append('name: ')
9185
- if self.name is None:
9186
- s.append('!MISSING\n')
9187
- else:
9188
- s.append('<\n')
9189
- s.append(self.name.dump(indent + 1, annotations, links) + '\n')
9190
- s.append(' '*indent + '>\n')
9191
- s.append(' '*indent)
9192
- s.append('operand: ')
9193
- if self.operand is None:
9194
- s.append('-\n')
9195
- else:
9196
- s.append('<\n')
9197
- s.append(self.operand.dump(indent + 1, annotations, links) + '\n')
9198
- s.append(' '*indent + '>\n')
9199
- s.append(' '*indent)
9200
- s.append('annotations: ')
9201
- if not self.annotations:
9202
- s.append('-\n')
9203
- else:
9204
- s.append('[\n')
9205
- for child in self.annotations:
9206
- s.append(child.dump(indent + 1, annotations, links) + '\n')
9207
- s.append(' '*indent + ']\n')
9208
- indent -= 1
9209
- s.append(' '*indent)
9210
- s.append(')')
9211
- return ''.join(s)
9212
-
9213
- __str__ = dump
9214
- __repr__ = dump
9215
-
9216
- def find_reachable(self, id_map=None):
9217
- """Returns a dictionary mapping Python id() values to stable sequence
9218
- numbers for all nodes in the tree rooted at this node. If id_map is
9219
- specified, found nodes are appended to it."""
9220
- if id_map is None:
9221
- id_map = {}
9222
- if id(self) in id_map:
9223
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
9224
- id_map[id(self)] = len(id_map)
9225
- if self._attr_name is not None:
9226
- self._attr_name.find_reachable(id_map)
9227
- if self._attr_operand is not None:
9228
- self._attr_operand.find_reachable(id_map)
9229
- for el in self._attr_annotations:
9230
- el.find_reachable(id_map)
9231
- return id_map
9232
-
9233
- def check_complete(self, id_map=None):
9234
- """Raises NotWellFormed if the tree rooted at this node is not
9235
- well-formed. If id_map is specified, this tree is only a subtree in the
9236
- context of a larger tree, and id_map must be a dict mapping from Python
9237
- id() codes to tree indices for all reachable nodes."""
9238
- if id_map is None:
9239
- id_map = self.find_reachable()
9240
- if self._attr_name is None:
9241
- raise NotWellFormed('name is required but not set')
9242
- if self._attr_name is not None:
9243
- self._attr_name.check_complete(id_map)
9244
- if self._attr_operand is not None:
9245
- self._attr_operand.check_complete(id_map)
9246
- for child in self._attr_annotations:
9247
- child.check_complete(id_map)
9248
-
9249
- def copy(self):
9250
- """Returns a shallow copy of this node."""
9251
- return ResetInstruction(
9252
- name=self._attr_name,
9253
- operand=self._attr_operand,
9254
- annotations=self._attr_annotations.copy()
9255
- )
9256
-
9257
- def clone(self):
9258
- """Returns a deep copy of this node. This mimics the C++ interface,
9259
- deficiencies with links included; that is, links always point to the
9260
- original tree. If you're not cloning a subtree in a context where this
9261
- is the desired behavior, you may want to use the copy.deepcopy() from
9262
- the stdlib instead, which should copy links correctly."""
9263
- return ResetInstruction(
9264
- name=_cloned(self._attr_name),
9265
- operand=_cloned(self._attr_operand),
9266
- annotations=_cloned(self._attr_annotations)
9267
- )
9268
-
9269
- @staticmethod
9270
- def _deserialize(cbor, seq_to_ob, links):
9271
- """Attempts to deserialize the given cbor object (in Python primitive
9272
- representation) into a node of this type. All (sub)nodes are added to
9273
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
9274
- registered in the links list by means of a two-tuple of the setter
9275
- function for the link field and the sequence number of the target node.
9276
- """
9277
- if not isinstance(cbor, dict):
9278
- raise TypeError('node description object must be a dict')
9279
- typ = cbor.get('@t', None)
9280
- if typ is None:
9281
- raise ValueError('type (@t) field is missing from node serialization')
9282
- if typ != 'ResetInstruction':
9283
- raise ValueError('found node serialization for ' + typ + ', but expected ResetInstruction')
9284
-
9285
- # Deserialize the name field.
9286
- field = cbor.get('name', None)
9287
- if not isinstance(field, dict):
9288
- raise ValueError('missing or invalid serialization of field name')
9289
- if field.get('@T') != '1':
9290
- raise ValueError('unexpected edge type for field name')
9291
- if field.get('@t', None) is None:
9292
- f_name = None
9293
- else:
9294
- f_name = Identifier._deserialize(field, seq_to_ob, links)
9295
-
9296
- # Deserialize the operand field.
9297
- field = cbor.get('operand', None)
9298
- if not isinstance(field, dict):
9299
- raise ValueError('missing or invalid serialization of field operand')
9300
- if field.get('@T') != '?':
9301
- raise ValueError('unexpected edge type for field operand')
9302
- if field.get('@t', None) is None:
9303
- f_operand = None
9304
- else:
9305
- f_operand = Expression._deserialize(field, seq_to_ob, links)
9306
-
9307
- # Deserialize the annotations field.
9308
- field = cbor.get('annotations', None)
9309
- if not isinstance(field, dict):
9310
- raise ValueError('missing or invalid serialization of field annotations')
9311
- if field.get('@T') != '*':
9312
- raise ValueError('unexpected edge type for field annotations')
9313
- data = field.get('@d', None)
9314
- if not isinstance(data, list):
9315
- raise ValueError('missing serialization of Any/Many contents')
9316
- f_annotations = MultiAnnotationData()
9317
- for element in data:
9318
- if element.get('@T') != '1':
9319
- raise ValueError('unexpected edge type for Any/Many element')
9320
- f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
9321
-
9322
- # Construct the ResetInstruction node.
9323
- node = ResetInstruction(f_name, f_operand, f_annotations)
9324
-
9325
- # Deserialize annotations.
9326
- for key, val in cbor.items():
9327
- if not (key.startswith('{') and key.endswith('}')):
9328
- continue
9329
- key = key[1:-1]
9330
- node[key] = cqasm.v3x.primitives.deserialize(key, val)
9331
-
9332
- # Register node in sequence number lookup.
9333
- seq = cbor.get('@i', None)
9334
- if not isinstance(seq, int):
9335
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
9336
- if seq in seq_to_ob:
9337
- raise ValueError('duplicate sequence number %d' % seq)
9338
- seq_to_ob[seq] = node
9339
-
9340
- return node
9341
-
9342
- def _serialize(self, id_map):
9343
- """Serializes this node to the Python primitive representation of its
9344
- CBOR serialization. The tree that the node belongs to must be
9345
- well-formed. id_map must match Python id() calls for all nodes to unique
9346
- integers, to use for the sequence number representation of links."""
9347
- cbor = {'@i': id_map[id(self)], '@t': 'ResetInstruction'}
9348
-
9349
- # Serialize the name field.
9350
- field = {'@T': '1'}
9351
- if self._attr_name is None:
9352
- field['@t'] = None
9353
- else:
9354
- field.update(self._attr_name._serialize(id_map))
9355
- cbor['name'] = field
9356
-
9357
- # Serialize the operand field.
9358
- field = {'@T': '?'}
9359
- if self._attr_operand is None:
9360
- field['@t'] = None
9361
- else:
9362
- field.update(self._attr_operand._serialize(id_map))
9363
- cbor['operand'] = field
9364
-
9365
- # Serialize the annotations field.
9366
- field = {'@T': '*'}
9367
- lst = []
9368
- for el in self._attr_annotations:
9369
- el = el._serialize(id_map)
9370
- el['@T'] = '1'
9371
- lst.append(el)
9372
- field['@d'] = lst
9373
- cbor['annotations'] = field
9374
-
9375
- # Serialize annotations.
9376
- for key, val in self._annot.items():
9377
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
9378
-
9379
- return cbor
9380
-
9381
-
9382
- class MultiResetInstruction(_Multiple):
9383
- """Wrapper for an edge with multiple ResetInstruction objects."""
9384
-
9385
- _T = ResetInstruction
9386
-
9387
-
9388
- _typemap['ResetInstruction'] = ResetInstruction
9389
-
9390
9380
  class ShiftExpression(BinaryExpression):
9391
9381
  __slots__ = []
9392
9382