libqasm 0.5.2__cp38-cp38-win_amd64.whl → 0.6.1__cp38-cp38-win_amd64.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/v1x/types.py DELETED
@@ -1,2414 +0,0 @@
1
- import functools
2
- import struct
3
- import cqasm.v1x.primitives
4
-
5
-
6
- _typemap = {}
7
-
8
-
9
- def _cbor_read_intlike(cbor, offset, info):
10
- """Parses the additional information and reads any additional bytes it
11
- specifies the existence of, and returns the encoded integer. offset
12
- should point to the byte immediately following the initial byte. Returns
13
- the encoded integer and the offset immediately following the object."""
14
-
15
- # Info less than 24 is a shorthand for the integer itself.
16
- if info < 24:
17
- return info, offset
18
-
19
- # 24 is 8-bit following the info byte.
20
- if info == 24:
21
- return cbor[offset], offset + 1
22
-
23
- # 25 is 16-bit following the info byte.
24
- if info == 25:
25
- val, = struct.unpack('>H', cbor[offset:offset+2])
26
- return val, offset + 2
27
-
28
- # 26 is 32-bit following the info byte.
29
- if info == 26:
30
- val, = struct.unpack('>I', cbor[offset:offset+4])
31
- return val, offset + 4
32
-
33
- # 27 is 64-bit following the info byte.
34
- if info == 27:
35
- val, = struct.unpack('>Q', cbor[offset:offset+8])
36
- return val, offset + 8
37
-
38
- # Info greater than or equal to 28 is illegal. Note that 31 is used for
39
- # indefinite lengths, so this must be checked prior to calling this
40
- # method.
41
- raise ValueError("invalid CBOR: illegal additional info for integer or object length")
42
-
43
-
44
- def _sub_cbor_to_py(cbor, offset):
45
- """Converts the CBOR object starting at cbor[offset] to its Python
46
- representation for as far as tree-gen supports CBOR. Returns this Python
47
- representation and the offset immediately following the CBOR representation
48
- thereof. Supported types:
49
-
50
- - 0: unsigned integer (int)
51
- - 1: negative integer (int)
52
- - 2: byte string (bytes)
53
- - 3: UTF-8 string (str)
54
- - 4: array (list)
55
- - 5: map (dict)
56
- - 6: semantic tag (ignored)
57
- - 7.20: false (bool)
58
- - 7.21: true (bool)
59
- - 7.22: null (NoneType)
60
- - 7.27: double-precision float (float)
61
-
62
- Both definite-length and indefinite-length notation is supported for sized
63
- objects (strings, arrays, maps). A ValueError is thrown if the CBOR is
64
- invalid or contains unsupported structures."""
65
-
66
- # Read the initial byte.
67
- initial = cbor[offset]
68
- typ = initial >> 5
69
- info = initial & 0x1F
70
- offset += 1
71
-
72
- # Handle unsigned integer (0) and negative integer (1).
73
- if typ <= 1:
74
- value, offset = _cbor_read_intlike(cbor, offset, info)
75
- if typ == 1:
76
- value = -1 - value
77
- return value, offset
78
-
79
- # Handle byte string (2) and UTF-8 string (3).
80
- if typ <= 3:
81
-
82
- # Gather components of the string in here.
83
- if info == 31:
84
-
85
- # Handle indefinite length strings. These consist of a
86
- # break-terminated (0xFF) list of definite-length strings of the
87
- # same type.
88
- value = []
89
- while True:
90
- sub_initial = cbor[offset]; offset += 1
91
- if sub_initial == 0xFF:
92
- break
93
- sub_typ = sub_initial >> 5
94
- sub_info = sub_initial & 0x1F
95
- if sub_typ != typ:
96
- raise ValueError('invalid CBOR: illegal indefinite-length string component')
97
-
98
- # Seek past definite-length string component. The size in
99
- # bytes is encoded as an integer.
100
- size, offset = _cbor_read_intlike(cbor, offset, sub_info)
101
- value.append(cbor[offset:offset + size])
102
- offset += size
103
- value = b''.join(value)
104
-
105
- else:
106
-
107
- # Handle definite-length strings. The size in bytes is encoded as
108
- # an integer.
109
- size, offset = _cbor_read_intlike(cbor, offset, info)
110
- value = cbor[offset:offset + size]
111
- offset += size
112
-
113
- if typ == 3:
114
- value = value.decode('UTF-8')
115
- return value, offset
116
-
117
- # Handle array (4) and map (5).
118
- if typ <= 5:
119
-
120
- # Create result container.
121
- container = [] if typ == 4 else {}
122
-
123
- # Handle indefinite length arrays and maps.
124
- if info == 31:
125
-
126
- # Read objects/object pairs until we encounter a break.
127
- while cbor[offset] != 0xFF:
128
- if typ == 4:
129
- value, offset = _sub_cbor_to_py(cbor, offset)
130
- container.append(value)
131
- else:
132
- key, offset = _sub_cbor_to_py(cbor, offset)
133
- if not isinstance(key, str):
134
- raise ValueError('invalid CBOR: map key is not a UTF-8 string')
135
- value, offset = _sub_cbor_to_py(cbor, offset)
136
- container[key] = value
137
-
138
- # Seek past the break.
139
- offset += 1
140
-
141
- else:
142
-
143
- # Handle definite-length arrays and maps. The amount of
144
- # objects/object pairs is encoded as an integer.
145
- size, offset = _cbor_read_intlike(cbor, offset, info)
146
- for _ in range(size):
147
- if typ == 4:
148
- value, offset = _sub_cbor_to_py(cbor, offset)
149
- container.append(value)
150
- else:
151
- key, offset = _sub_cbor_to_py(cbor, offset)
152
- if not isinstance(key, str):
153
- raise ValueError('invalid CBOR: map key is not a UTF-8 string')
154
- value, offset = _sub_cbor_to_py(cbor, offset)
155
- container[key] = value
156
-
157
- return container, offset
158
-
159
- # Handle semantic tags.
160
- if typ == 6:
161
-
162
- # We don't use semantic tags for anything, but ignoring them is
163
- # legal and reading past them is easy enough.
164
- _, offset = _cbor_read_intlike(cbor, offset, info)
165
- return _sub_cbor_to_py(cbor, offset)
166
-
167
- # Handle major type 7. Here, the type is defined by the additional info.
168
- # Additional info 24 is reserved for having the type specified by the
169
- # next byte, but all such values are unassigned.
170
- if info == 20:
171
- # false
172
- return False, offset
173
-
174
- if info == 21:
175
- # true
176
- return True, offset
177
-
178
- if info == 22:
179
- # null
180
- return None, offset
181
-
182
- if info == 23:
183
- # Undefined value.
184
- raise ValueError('invalid CBOR: undefined value is not supported')
185
-
186
- if info == 25:
187
- # Half-precision float.
188
- raise ValueError('invalid CBOR: half-precision float is not supported')
189
-
190
- if info == 26:
191
- # Single-precision float.
192
- raise ValueError('invalid CBOR: single-precision float is not supported')
193
-
194
- if info == 27:
195
- # Double-precision float.
196
- value, = struct.unpack('>d', cbor[offset:offset+8])
197
- return value, offset + 8
198
-
199
- if info == 31:
200
- # Break value used for indefinite-length objects.
201
- raise ValueError('invalid CBOR: unexpected break')
202
-
203
- raise ValueError('invalid CBOR: unknown type code')
204
-
205
-
206
- def _cbor_to_py(cbor):
207
- """Converts the given CBOR object (bytes) to its Python representation for
208
- as far as tree-gen supports CBOR. Supported types:
209
-
210
- - 0: unsigned integer (int)
211
- - 1: negative integer (int)
212
- - 2: byte string (bytes)
213
- - 3: UTF-8 string (str)
214
- - 4: array (list)
215
- - 5: map (dict)
216
- - 6: semantic tag (ignored)
217
- - 7.20: false (bool)
218
- - 7.21: true (bool)
219
- - 7.22: null (NoneType)
220
- - 7.27: double-precision float (float)
221
-
222
- Both definite-length and indefinite-length notation is supported for sized
223
- objects (strings, arrays, maps). A ValueError is thrown if the CBOR is
224
- invalid or contains unsupported structures."""
225
-
226
- value, length = _sub_cbor_to_py(cbor, 0)
227
- if length < len(cbor):
228
- raise ValueError('invalid CBOR: garbage at the end')
229
- return value
230
-
231
-
232
- class _Cbor(bytes):
233
- """Marker class indicating that this bytes object represents CBOR."""
234
- pass
235
-
236
-
237
- def _cbor_write_intlike(value, major=0):
238
- """Converts the given integer to its minimal representation in CBOR. The
239
- major code can be overridden to write lengths for strings, arrays, and
240
- maps."""
241
-
242
- # Negative integers use major code 1.
243
- if value < 0:
244
- major = 1
245
- value = -1 - value
246
- initial = major << 5
247
-
248
- # Use the minimal representation.
249
- if value < 24:
250
- return struct.pack('>B', initial | value)
251
- if value < 0x100:
252
- return struct.pack('>BB', initial | 24, value)
253
- if value < 0x10000:
254
- return struct.pack('>BH', initial | 25, value)
255
- if value < 0x100000000:
256
- return struct.pack('>BI', initial | 26, value)
257
- if value < 0x10000000000000000:
258
- return struct.pack('>BQ', initial | 27, value)
259
-
260
- raise ValueError('integer too large for CBOR (bigint not supported)')
261
-
262
-
263
- def _py_to_cbor(value, type_converter=None):
264
- """Inverse of _cbor_to_py(). type_converter optionally specifies a function
265
- that takes a value and either converts it to a primitive for serialization,
266
- converts it to a _Cbor object manually, or raises a TypeError if no
267
- conversion is known. If no type_converter is specified, a TypeError is
268
- raised in all cases the type_converter would otherwise be called. The cbor
269
- serialization is returned using a _Cbor object, which is just a marker class
270
- behaving just like bytes."""
271
- if isinstance(value, _Cbor):
272
- return value
273
-
274
- if isinstance(value, int):
275
- return _Cbor(_cbor_write_intlike(value))
276
-
277
- if isinstance(value, float):
278
- return _Cbor(struct.pack('>Bd', 0xFB, value))
279
-
280
- if isinstance(value, str):
281
- value = value.encode('UTF-8')
282
- return _Cbor(_cbor_write_intlike(len(value), 3) + value)
283
-
284
- if isinstance(value, bytes):
285
- return _Cbor(_cbor_write_intlike(len(value), 2) + value)
286
-
287
- if value is False:
288
- return _Cbor(b'\xF4')
289
-
290
- if value is True:
291
- return _Cbor(b'\xF5')
292
-
293
- if value is None:
294
- return _Cbor(b'\xF6')
295
-
296
- if isinstance(value, (list, tuple)):
297
- cbor = [_cbor_write_intlike(len(value), 4)]
298
- for val in value:
299
- cbor.append(_py_to_cbor(val, type_converter))
300
- return _Cbor(b''.join(cbor))
301
-
302
- if isinstance(value, dict):
303
- cbor = [_cbor_write_intlike(len(value), 5)]
304
- for key, val in sorted(value.items()):
305
- if not isinstance(key, str):
306
- raise TypeError('dict keys must be strings')
307
- cbor.append(_py_to_cbor(key, type_converter))
308
- cbor.append(_py_to_cbor(val, type_converter))
309
- return _Cbor(b''.join(cbor))
310
-
311
- if type_converter is not None:
312
- return _py_to_cbor(type_converter(value))
313
-
314
- raise TypeError('unsupported type for conversion to cbor: %r' % (value,))
315
-
316
-
317
- class NotWellFormed(ValueError):
318
- """Exception class for well-formedness checks."""
319
-
320
- def __init__(self, msg):
321
- super().__init__('not well-formed: ' + str(msg))
322
-
323
-
324
- class Node(object):
325
- """Base class for nodes."""
326
-
327
- __slots__ = ['_annot']
328
-
329
- def __init__(self):
330
- super().__init__()
331
- self._annot = {}
332
-
333
- def __getitem__(self, key):
334
- """Returns the annotation object with the specified key, or raises
335
- KeyError if not found."""
336
- if not isinstance(key, str):
337
- raise TypeError('indexing a node with something other than an '
338
- 'annotation key string')
339
- return self._annot[key]
340
-
341
- def __setitem__(self, key, val):
342
- """Assigns the annotation object with the specified key."""
343
- if not isinstance(key, str):
344
- raise TypeError('indexing a node with something other than an '
345
- 'annotation key string')
346
- self._annot[key] = val
347
-
348
- def __delitem__(self, key):
349
- """Deletes the annotation object with the specified key."""
350
- if not isinstance(key, str):
351
- raise TypeError('indexing a node with something other than an '
352
- 'annotation key string')
353
- del self._annot[key]
354
-
355
- def __contains__(self, key):
356
- """Returns whether an annotation exists for the specified key."""
357
- return key in self._annot
358
-
359
- @staticmethod
360
- def find_reachable(self, id_map=None):
361
- """Returns a dictionary mapping Python id() values to stable sequence
362
- numbers for all nodes in the tree rooted at this node. If id_map is
363
- specified, found nodes are appended to it. Note that this is overridden
364
- by the actual node class implementations; this base function does very
365
- little."""
366
- if id_map is None:
367
- id_map = {}
368
- return id_map
369
-
370
- def check_complete(self, id_map=None):
371
- """Raises NotWellFormed if the tree rooted at this node is not
372
- well-formed. If id_map is specified, this tree is only a subtree in the
373
- context of a larger tree, and id_map must be a dict mapping from Python
374
- id() codes to tree indices for all reachable nodes. Note that this is
375
- overridden by the actual node class implementations; this base function
376
- always raises an exception."""
377
- raise NotWellFormed('found node of abstract type ' + type(self).__name__)
378
-
379
- def check_well_formed(self):
380
- """Checks whether the tree starting at this node is well-formed. That
381
- is:
382
-
383
- - all One, Link, and Many edges have (at least) one entry;
384
- - all the One entries internally stored by Any/Many have an entry;
385
- - all Link and filled OptLink nodes link to a node that's reachable
386
- from this node;
387
- - the nodes referred to be One/Maybe only appear once in the tree
388
- (except through links).
389
-
390
- If it isn't well-formed, a NotWellFormed is thrown."""
391
- self.check_complete()
392
-
393
- def is_well_formed(self):
394
- """Returns whether the tree starting at this node is well-formed. That
395
- is:
396
-
397
- - all One, Link, and Many edges have (at least) one entry;
398
- - all the One entries internally stored by Any/Many have an entry;
399
- - all Link and filled OptLink nodes link to a node that's reachable
400
- from this node;
401
- - the nodes referred to be One/Maybe only appear once in the tree
402
- (except through links)."""
403
- try:
404
- self.check_well_formed()
405
- return True
406
- except NotWellFormed:
407
- return False
408
-
409
- def copy(self):
410
- """Returns a shallow copy of this node. Note that this is overridden by
411
- the actual node class implementations; this base function always raises
412
- an exception."""
413
- raise TypeError('can\'t copy node of abstract type ' + type(self).__name__)
414
-
415
- def clone(self):
416
- """Returns a deep copy of this node. Note that this is overridden by
417
- the actual node class implementations; this base function always raises
418
- an exception."""
419
- raise TypeError('can\'t clone node of abstract type ' + type(self).__name__)
420
-
421
- @classmethod
422
- def deserialize(cls, cbor):
423
- """Attempts to deserialize the given cbor object (either as bytes or as
424
- its Python primitive representation) into a node of this type."""
425
- if isinstance(cbor, bytes):
426
- cbor = _cbor_to_py(cbor)
427
- seq_to_ob = {}
428
- links = []
429
- root = cls._deserialize(cbor, seq_to_ob, links)
430
- for link_setter, seq in links:
431
- ob = seq_to_ob.get(seq, None)
432
- if ob is None:
433
- raise ValueError('found link to nonexistent object')
434
- link_setter(ob)
435
- return root
436
-
437
- def serialize(self):
438
- """Serializes this node into its cbor representation in the form of a
439
- bytes object."""
440
- id_map = self.find_reachable()
441
- self.check_complete(id_map)
442
- return _py_to_cbor(self._serialize(id_map))
443
-
444
- @staticmethod
445
- def _deserialize(cbor, seq_to_ob, links):
446
- if not isinstance(cbor, dict):
447
- raise TypeError('node description object must be a dict')
448
- typ = cbor.get('@t', None)
449
- if typ is None:
450
- raise ValueError('type (@t) field is missing from node serialization')
451
- node_type = _typemap.get(cbor.get('@t'), None)
452
- if node_type is None:
453
- raise ValueError('unknown node type (@t): ' + str(cbor.get('@t')))
454
- return node_type._deserialize(cbor, seq_to_ob, links)
455
-
456
-
457
- @functools.total_ordering
458
- class _Multiple(object):
459
- """Base class for the Any* and Many* edge helper classes. Inheriting
460
- classes must set the class constant _T to the node type they are made
461
- for."""
462
-
463
- __slots__ = ['_l']
464
-
465
- def __init__(self, *args, **kwargs):
466
- super().__init__()
467
- self._l = list(*args, **kwargs)
468
- for idx, val in enumerate(self._l):
469
- if not isinstance(val, self._T):
470
- raise TypeError(
471
- 'object {!r} at index {:d} is not an instance of {!r}'
472
- .format(val, idx, self._T))
473
-
474
- def __repr__(self):
475
- return '{}({!r})'.format(type(self).__name__, self._l)
476
-
477
- def clone(self):
478
- return self.__class__(map(lambda node: node.clone(), self._l))
479
-
480
- def __len__(self):
481
- return len(self._l)
482
-
483
- def __getitem__(self, idx):
484
- return self._l[idx]
485
-
486
- def __setitem__(self, idx, val):
487
- if not isinstance(val, self._T):
488
- raise TypeError(
489
- 'object {!r} is not an instance of {!r}'
490
- .format(val, idx, self._T))
491
- self._l[idx] = val
492
-
493
- def __delitem__(self, idx):
494
- del self._l[idx]
495
-
496
- def __iter__(self):
497
- return iter(self._l)
498
-
499
- def __reversed__(self):
500
- return reversed(self._l)
501
-
502
- def __contains__(self, val):
503
- return val in self._l
504
-
505
- def append(self, val):
506
- if not isinstance(val, self._T):
507
- raise TypeError(
508
- 'object {!r} is not an instance of {!r}'
509
- .format(val, self._T))
510
- self._l.append(val)
511
-
512
- def extend(self, iterable):
513
- for val in iterable:
514
- self.append(val)
515
-
516
- def insert(self, idx, val):
517
- if not isinstance(val, self._T):
518
- raise TypeError(
519
- 'object {!r} is not an instance of {!r}'
520
- .format(val, self._T))
521
- self._l.insert(idx, val)
522
-
523
- def remote(self, val):
524
- self._l.remove(val)
525
-
526
- def pop(self, idx=-1):
527
- return self._l.pop(idx)
528
-
529
- def clear(self):
530
- self._l.clear()
531
-
532
- def idx(self, val, start=0, end=-1):
533
- return self._l.idx(val, start, end)
534
-
535
- def count(self, val):
536
- return self._l.count(val)
537
-
538
- def sort(self, key=None, reverse=False):
539
- self._l.sort(key=key, reverse=reverse)
540
-
541
- def reverse(self):
542
- self._l.reverse()
543
-
544
- def copy(self):
545
- return self.__class__(self)
546
-
547
- def __eq__(self, other):
548
- if not isinstance(other, _Multiple):
549
- return False
550
- return self._l == other._l
551
-
552
- def __lt__(self, other):
553
- return self._l < other._l
554
-
555
- def __iadd__(self, other):
556
- self.extend(other)
557
-
558
- def __add__(self, other):
559
- copy = self.copy()
560
- copy += other
561
- return copy
562
-
563
- def __imul__(self, other):
564
- self._l *= other
565
-
566
- def __mul__(self, other):
567
- copy = self.copy()
568
- copy *= other
569
- return copy
570
-
571
- def __rmul__(self, other):
572
- copy = self.copy()
573
- copy *= other
574
- return copy
575
-
576
-
577
- class MultiNode(_Multiple):
578
- """Wrapper for an edge with multiple Node objects."""
579
-
580
- _T = Node
581
-
582
-
583
- def _cloned(obj):
584
- """Attempts to clone the given object by calling its clone() method, if it
585
- has one."""
586
- if hasattr(obj, 'clone'):
587
- return obj.clone()
588
- return obj
589
-
590
-
591
- class TypeBase(Node):
592
- """Base for all types, with a member indicating whether values of this type
593
- are assignable (references) or not (constants, expression results)."""
594
-
595
- __slots__ = [
596
- '_attr_assignable',
597
- ]
598
-
599
- def __init__(
600
- self,
601
- assignable=None,
602
- ):
603
- super().__init__()
604
- self.assignable = assignable
605
-
606
- @property
607
- def assignable(self):
608
- """Whether a value of this type can be assigned (true), or can only be
609
- read (false). For constraints, whether the value must be assignable
610
- (true), or only has to be read. In C++ terminology, true = lvalue, false
611
- = rvalue (more or less)."""
612
- return self._attr_assignable
613
-
614
- @assignable.setter
615
- def assignable(self, val):
616
- if val is None:
617
- del self.assignable
618
- return
619
- if not isinstance(val, cqasm.v1x.primitives.Bool):
620
- # Try to "typecast" if this isn't an obvious mistake.
621
- if isinstance(val, Node):
622
- raise TypeError('assignable must be of type cqasm.v1x.primitives.Bool')
623
- val = cqasm.v1x.primitives.Bool(val)
624
- self._attr_assignable = val
625
-
626
- @assignable.deleter
627
- def assignable(self):
628
- self._attr_assignable = cqasm.v1x.primitives.Bool()
629
-
630
- @staticmethod
631
- def _deserialize(cbor, seq_to_ob, links):
632
- """Attempts to deserialize the given cbor object (in Python primitive
633
- representation) into a node of this type. All (sub)nodes are added to
634
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
635
- registered in the links list by means of a two-tuple of the setter
636
- function for the link field and the sequence number of the target node.
637
- """
638
- if not isinstance(cbor, dict):
639
- raise TypeError('node description object must be a dict')
640
- typ = cbor.get('@t', None)
641
- if typ is None:
642
- raise ValueError('type (@t) field is missing from node serialization')
643
- if typ == 'Qubit':
644
- return Qubit._deserialize(cbor, seq_to_ob, links)
645
- if typ == 'Bool':
646
- return Bool._deserialize(cbor, seq_to_ob, links)
647
- if typ == 'Axis':
648
- return Axis._deserialize(cbor, seq_to_ob, links)
649
- if typ == 'Int':
650
- return Int._deserialize(cbor, seq_to_ob, links)
651
- if typ == 'Real':
652
- return Real._deserialize(cbor, seq_to_ob, links)
653
- if typ == 'Complex':
654
- return Complex._deserialize(cbor, seq_to_ob, links)
655
- if typ == 'RealMatrix':
656
- return RealMatrix._deserialize(cbor, seq_to_ob, links)
657
- if typ == 'ComplexMatrix':
658
- return ComplexMatrix._deserialize(cbor, seq_to_ob, links)
659
- if typ == 'String':
660
- return String._deserialize(cbor, seq_to_ob, links)
661
- if typ == 'Json':
662
- return Json._deserialize(cbor, seq_to_ob, links)
663
- raise ValueError('unknown or unexpected type (@t) found in node serialization')
664
-
665
- def _serialize(self, id_map):
666
- """Serializes this node to the Python primitive representation of its
667
- CBOR serialization. The tree that the node belongs to must be
668
- well-formed. id_map must match Python id() calls for all nodes to unique
669
- integers, to use for the sequence number representation of links."""
670
- cbor = {'@i': id_map[id(self)], '@t': 'TypeBase'}
671
-
672
- # Serialize the assignable field.
673
- if hasattr(self._attr_assignable, 'serialize_cbor'):
674
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
675
- else:
676
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
677
-
678
- # Serialize annotations.
679
- for key, val in self._annot.items():
680
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
681
-
682
- return cbor
683
-
684
-
685
- class MultiTypeBase(_Multiple):
686
- """Wrapper for an edge with multiple TypeBase objects."""
687
-
688
- _T = TypeBase
689
-
690
-
691
- _typemap['TypeBase'] = TypeBase
692
-
693
- class Axis(TypeBase):
694
- """Type of an axis (x, y, or z)."""
695
-
696
- __slots__ = []
697
-
698
- def __init__(
699
- self,
700
- assignable=None,
701
- ):
702
- super().__init__(assignable=assignable)
703
-
704
- def __eq__(self, other):
705
- """Equality operator. Ignores annotations!"""
706
- if not isinstance(other, Axis):
707
- return False
708
- if self.assignable != other.assignable:
709
- return False
710
- return True
711
-
712
- def dump(self, indent=0, annotations=None, links=1):
713
- """Returns a debug representation of this tree as a multiline string.
714
- indent is the number of double spaces prefixed before every line.
715
- annotations, if specified, must be a set-like object containing the key
716
- strings of the annotations that are to be printed. links specifies the
717
- maximum link recursion depth."""
718
- s = [' '*indent]
719
- s.append('Axis(')
720
- if annotations is None:
721
- annotations = []
722
- for key in annotations:
723
- if key in self:
724
- s.append(' # {}: {}'.format(key, self[key]))
725
- s.append('\n')
726
- indent += 1
727
- s.append(' '*indent)
728
- s.append('assignable: ')
729
- s.append(str(self.assignable) + '\n')
730
- indent -= 1
731
- s.append(' '*indent)
732
- s.append(')')
733
- return ''.join(s)
734
-
735
- __str__ = dump
736
- __repr__ = dump
737
-
738
- def find_reachable(self, id_map=None):
739
- """Returns a dictionary mapping Python id() values to stable sequence
740
- numbers for all nodes in the tree rooted at this node. If id_map is
741
- specified, found nodes are appended to it."""
742
- if id_map is None:
743
- id_map = {}
744
- if id(self) in id_map:
745
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
746
- id_map[id(self)] = len(id_map)
747
- return id_map
748
-
749
- def check_complete(self, id_map=None):
750
- """Raises NotWellFormed if the tree rooted at this node is not
751
- well-formed. If id_map is specified, this tree is only a subtree in the
752
- context of a larger tree, and id_map must be a dict mapping from Python
753
- id() codes to tree indices for all reachable nodes."""
754
- if id_map is None:
755
- id_map = self.find_reachable()
756
-
757
- def copy(self):
758
- """Returns a shallow copy of this node."""
759
- return Axis(
760
- assignable=self._attr_assignable
761
- )
762
-
763
- def clone(self):
764
- """Returns a deep copy of this node. This mimics the C++ interface,
765
- deficiencies with links included; that is, links always point to the
766
- original tree. If you're not cloning a subtree in a context where this
767
- is the desired behavior, you may want to use the copy.deepcopy() from
768
- the stdlib instead, which should copy links correctly."""
769
- return Axis(
770
- assignable=_cloned(self._attr_assignable)
771
- )
772
-
773
- @staticmethod
774
- def _deserialize(cbor, seq_to_ob, links):
775
- """Attempts to deserialize the given cbor object (in Python primitive
776
- representation) into a node of this type. All (sub)nodes are added to
777
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
778
- registered in the links list by means of a two-tuple of the setter
779
- function for the link field and the sequence number of the target node.
780
- """
781
- if not isinstance(cbor, dict):
782
- raise TypeError('node description object must be a dict')
783
- typ = cbor.get('@t', None)
784
- if typ is None:
785
- raise ValueError('type (@t) field is missing from node serialization')
786
- if typ != 'Axis':
787
- raise ValueError('found node serialization for ' + typ + ', but expected Axis')
788
-
789
- # Deserialize the assignable field.
790
- field = cbor.get('assignable', None)
791
- if not isinstance(field, dict):
792
- raise ValueError('missing or invalid serialization of field assignable')
793
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
794
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
795
- else:
796
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
797
-
798
- # Construct the Axis node.
799
- node = Axis(f_assignable)
800
-
801
- # Deserialize annotations.
802
- for key, val in cbor.items():
803
- if not (key.startswith('{') and key.endswith('}')):
804
- continue
805
- key = key[1:-1]
806
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
807
-
808
- # Register node in sequence number lookup.
809
- seq = cbor.get('@i', None)
810
- if not isinstance(seq, int):
811
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
812
- if seq in seq_to_ob:
813
- raise ValueError('duplicate sequence number %d' % seq)
814
- seq_to_ob[seq] = node
815
-
816
- return node
817
-
818
- def _serialize(self, id_map):
819
- """Serializes this node to the Python primitive representation of its
820
- CBOR serialization. The tree that the node belongs to must be
821
- well-formed. id_map must match Python id() calls for all nodes to unique
822
- integers, to use for the sequence number representation of links."""
823
- cbor = {'@i': id_map[id(self)], '@t': 'Axis'}
824
-
825
- # Serialize the assignable field.
826
- if hasattr(self._attr_assignable, 'serialize_cbor'):
827
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
828
- else:
829
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
830
-
831
- # Serialize annotations.
832
- for key, val in self._annot.items():
833
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
834
-
835
- return cbor
836
-
837
-
838
- class MultiAxis(_Multiple):
839
- """Wrapper for an edge with multiple Axis objects."""
840
-
841
- _T = Axis
842
-
843
-
844
- _typemap['Axis'] = Axis
845
-
846
- class Bool(TypeBase):
847
- """Type of a boolean/bit."""
848
-
849
- __slots__ = []
850
-
851
- def __init__(
852
- self,
853
- assignable=None,
854
- ):
855
- super().__init__(assignable=assignable)
856
-
857
- def __eq__(self, other):
858
- """Equality operator. Ignores annotations!"""
859
- if not isinstance(other, Bool):
860
- return False
861
- if self.assignable != other.assignable:
862
- return False
863
- return True
864
-
865
- def dump(self, indent=0, annotations=None, links=1):
866
- """Returns a debug representation of this tree as a multiline string.
867
- indent is the number of double spaces prefixed before every line.
868
- annotations, if specified, must be a set-like object containing the key
869
- strings of the annotations that are to be printed. links specifies the
870
- maximum link recursion depth."""
871
- s = [' '*indent]
872
- s.append('Bool(')
873
- if annotations is None:
874
- annotations = []
875
- for key in annotations:
876
- if key in self:
877
- s.append(' # {}: {}'.format(key, self[key]))
878
- s.append('\n')
879
- indent += 1
880
- s.append(' '*indent)
881
- s.append('assignable: ')
882
- s.append(str(self.assignable) + '\n')
883
- indent -= 1
884
- s.append(' '*indent)
885
- s.append(')')
886
- return ''.join(s)
887
-
888
- __str__ = dump
889
- __repr__ = dump
890
-
891
- def find_reachable(self, id_map=None):
892
- """Returns a dictionary mapping Python id() values to stable sequence
893
- numbers for all nodes in the tree rooted at this node. If id_map is
894
- specified, found nodes are appended to it."""
895
- if id_map is None:
896
- id_map = {}
897
- if id(self) in id_map:
898
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
899
- id_map[id(self)] = len(id_map)
900
- return id_map
901
-
902
- def check_complete(self, id_map=None):
903
- """Raises NotWellFormed if the tree rooted at this node is not
904
- well-formed. If id_map is specified, this tree is only a subtree in the
905
- context of a larger tree, and id_map must be a dict mapping from Python
906
- id() codes to tree indices for all reachable nodes."""
907
- if id_map is None:
908
- id_map = self.find_reachable()
909
-
910
- def copy(self):
911
- """Returns a shallow copy of this node."""
912
- return Bool(
913
- assignable=self._attr_assignable
914
- )
915
-
916
- def clone(self):
917
- """Returns a deep copy of this node. This mimics the C++ interface,
918
- deficiencies with links included; that is, links always point to the
919
- original tree. If you're not cloning a subtree in a context where this
920
- is the desired behavior, you may want to use the copy.deepcopy() from
921
- the stdlib instead, which should copy links correctly."""
922
- return Bool(
923
- assignable=_cloned(self._attr_assignable)
924
- )
925
-
926
- @staticmethod
927
- def _deserialize(cbor, seq_to_ob, links):
928
- """Attempts to deserialize the given cbor object (in Python primitive
929
- representation) into a node of this type. All (sub)nodes are added to
930
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
931
- registered in the links list by means of a two-tuple of the setter
932
- function for the link field and the sequence number of the target node.
933
- """
934
- if not isinstance(cbor, dict):
935
- raise TypeError('node description object must be a dict')
936
- typ = cbor.get('@t', None)
937
- if typ is None:
938
- raise ValueError('type (@t) field is missing from node serialization')
939
- if typ != 'Bool':
940
- raise ValueError('found node serialization for ' + typ + ', but expected Bool')
941
-
942
- # Deserialize the assignable field.
943
- field = cbor.get('assignable', None)
944
- if not isinstance(field, dict):
945
- raise ValueError('missing or invalid serialization of field assignable')
946
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
947
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
948
- else:
949
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
950
-
951
- # Construct the Bool node.
952
- node = Bool(f_assignable)
953
-
954
- # Deserialize annotations.
955
- for key, val in cbor.items():
956
- if not (key.startswith('{') and key.endswith('}')):
957
- continue
958
- key = key[1:-1]
959
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
960
-
961
- # Register node in sequence number lookup.
962
- seq = cbor.get('@i', None)
963
- if not isinstance(seq, int):
964
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
965
- if seq in seq_to_ob:
966
- raise ValueError('duplicate sequence number %d' % seq)
967
- seq_to_ob[seq] = node
968
-
969
- return node
970
-
971
- def _serialize(self, id_map):
972
- """Serializes this node to the Python primitive representation of its
973
- CBOR serialization. The tree that the node belongs to must be
974
- well-formed. id_map must match Python id() calls for all nodes to unique
975
- integers, to use for the sequence number representation of links."""
976
- cbor = {'@i': id_map[id(self)], '@t': 'Bool'}
977
-
978
- # Serialize the assignable field.
979
- if hasattr(self._attr_assignable, 'serialize_cbor'):
980
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
981
- else:
982
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
983
-
984
- # Serialize annotations.
985
- for key, val in self._annot.items():
986
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
987
-
988
- return cbor
989
-
990
-
991
- class MultiBool(_Multiple):
992
- """Wrapper for an edge with multiple Bool objects."""
993
-
994
- _T = Bool
995
-
996
-
997
- _typemap['Bool'] = Bool
998
-
999
- class Complex(TypeBase):
1000
- """Type of a complex number (2x IEEE double)."""
1001
-
1002
- __slots__ = []
1003
-
1004
- def __init__(
1005
- self,
1006
- assignable=None,
1007
- ):
1008
- super().__init__(assignable=assignable)
1009
-
1010
- def __eq__(self, other):
1011
- """Equality operator. Ignores annotations!"""
1012
- if not isinstance(other, Complex):
1013
- return False
1014
- if self.assignable != other.assignable:
1015
- return False
1016
- return True
1017
-
1018
- def dump(self, indent=0, annotations=None, links=1):
1019
- """Returns a debug representation of this tree as a multiline string.
1020
- indent is the number of double spaces prefixed before every line.
1021
- annotations, if specified, must be a set-like object containing the key
1022
- strings of the annotations that are to be printed. links specifies the
1023
- maximum link recursion depth."""
1024
- s = [' '*indent]
1025
- s.append('Complex(')
1026
- if annotations is None:
1027
- annotations = []
1028
- for key in annotations:
1029
- if key in self:
1030
- s.append(' # {}: {}'.format(key, self[key]))
1031
- s.append('\n')
1032
- indent += 1
1033
- s.append(' '*indent)
1034
- s.append('assignable: ')
1035
- s.append(str(self.assignable) + '\n')
1036
- indent -= 1
1037
- s.append(' '*indent)
1038
- s.append(')')
1039
- return ''.join(s)
1040
-
1041
- __str__ = dump
1042
- __repr__ = dump
1043
-
1044
- def find_reachable(self, id_map=None):
1045
- """Returns a dictionary mapping Python id() values to stable sequence
1046
- numbers for all nodes in the tree rooted at this node. If id_map is
1047
- specified, found nodes are appended to it."""
1048
- if id_map is None:
1049
- id_map = {}
1050
- if id(self) in id_map:
1051
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
1052
- id_map[id(self)] = len(id_map)
1053
- return id_map
1054
-
1055
- def check_complete(self, id_map=None):
1056
- """Raises NotWellFormed if the tree rooted at this node is not
1057
- well-formed. If id_map is specified, this tree is only a subtree in the
1058
- context of a larger tree, and id_map must be a dict mapping from Python
1059
- id() codes to tree indices for all reachable nodes."""
1060
- if id_map is None:
1061
- id_map = self.find_reachable()
1062
-
1063
- def copy(self):
1064
- """Returns a shallow copy of this node."""
1065
- return Complex(
1066
- assignable=self._attr_assignable
1067
- )
1068
-
1069
- def clone(self):
1070
- """Returns a deep copy of this node. This mimics the C++ interface,
1071
- deficiencies with links included; that is, links always point to the
1072
- original tree. If you're not cloning a subtree in a context where this
1073
- is the desired behavior, you may want to use the copy.deepcopy() from
1074
- the stdlib instead, which should copy links correctly."""
1075
- return Complex(
1076
- assignable=_cloned(self._attr_assignable)
1077
- )
1078
-
1079
- @staticmethod
1080
- def _deserialize(cbor, seq_to_ob, links):
1081
- """Attempts to deserialize the given cbor object (in Python primitive
1082
- representation) into a node of this type. All (sub)nodes are added to
1083
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
1084
- registered in the links list by means of a two-tuple of the setter
1085
- function for the link field and the sequence number of the target node.
1086
- """
1087
- if not isinstance(cbor, dict):
1088
- raise TypeError('node description object must be a dict')
1089
- typ = cbor.get('@t', None)
1090
- if typ is None:
1091
- raise ValueError('type (@t) field is missing from node serialization')
1092
- if typ != 'Complex':
1093
- raise ValueError('found node serialization for ' + typ + ', but expected Complex')
1094
-
1095
- # Deserialize the assignable field.
1096
- field = cbor.get('assignable', None)
1097
- if not isinstance(field, dict):
1098
- raise ValueError('missing or invalid serialization of field assignable')
1099
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
1100
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
1101
- else:
1102
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
1103
-
1104
- # Construct the Complex node.
1105
- node = Complex(f_assignable)
1106
-
1107
- # Deserialize annotations.
1108
- for key, val in cbor.items():
1109
- if not (key.startswith('{') and key.endswith('}')):
1110
- continue
1111
- key = key[1:-1]
1112
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
1113
-
1114
- # Register node in sequence number lookup.
1115
- seq = cbor.get('@i', None)
1116
- if not isinstance(seq, int):
1117
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
1118
- if seq in seq_to_ob:
1119
- raise ValueError('duplicate sequence number %d' % seq)
1120
- seq_to_ob[seq] = node
1121
-
1122
- return node
1123
-
1124
- def _serialize(self, id_map):
1125
- """Serializes this node to the Python primitive representation of its
1126
- CBOR serialization. The tree that the node belongs to must be
1127
- well-formed. id_map must match Python id() calls for all nodes to unique
1128
- integers, to use for the sequence number representation of links."""
1129
- cbor = {'@i': id_map[id(self)], '@t': 'Complex'}
1130
-
1131
- # Serialize the assignable field.
1132
- if hasattr(self._attr_assignable, 'serialize_cbor'):
1133
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
1134
- else:
1135
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
1136
-
1137
- # Serialize annotations.
1138
- for key, val in self._annot.items():
1139
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
1140
-
1141
- return cbor
1142
-
1143
-
1144
- class MultiComplex(_Multiple):
1145
- """Wrapper for an edge with multiple Complex objects."""
1146
-
1147
- _T = Complex
1148
-
1149
-
1150
- _typemap['Complex'] = Complex
1151
-
1152
- class ComplexMatrix(TypeBase):
1153
- """Type of a complex matrix. Also used for one-dimensional arrays and
1154
- vectors."""
1155
-
1156
- __slots__ = [
1157
- '_attr_num_rows',
1158
- '_attr_num_cols',
1159
- ]
1160
-
1161
- def __init__(
1162
- self,
1163
- num_rows=None,
1164
- num_cols=None,
1165
- assignable=None,
1166
- ):
1167
- super().__init__(assignable=assignable)
1168
- self.num_rows = num_rows
1169
- self.num_cols = num_cols
1170
-
1171
- @property
1172
- def num_rows(self):
1173
- """Number of rows. Negative indicates that the value is unconstrained.
1174
- Must be one or more otherwise."""
1175
- return self._attr_num_rows
1176
-
1177
- @num_rows.setter
1178
- def num_rows(self, val):
1179
- if val is None:
1180
- del self.num_rows
1181
- return
1182
- if not isinstance(val, cqasm.v1x.primitives.Int):
1183
- # Try to "typecast" if this isn't an obvious mistake.
1184
- if isinstance(val, Node):
1185
- raise TypeError('num_rows must be of type cqasm.v1x.primitives.Int')
1186
- val = cqasm.v1x.primitives.Int(val)
1187
- self._attr_num_rows = val
1188
-
1189
- @num_rows.deleter
1190
- def num_rows(self):
1191
- self._attr_num_rows = cqasm.v1x.primitives.Int()
1192
-
1193
- @property
1194
- def num_cols(self):
1195
- """Number of columns. Negative indicates that the value is
1196
- unconstrained. Can be zero, unlike num_rows."""
1197
- return self._attr_num_cols
1198
-
1199
- @num_cols.setter
1200
- def num_cols(self, val):
1201
- if val is None:
1202
- del self.num_cols
1203
- return
1204
- if not isinstance(val, cqasm.v1x.primitives.Int):
1205
- # Try to "typecast" if this isn't an obvious mistake.
1206
- if isinstance(val, Node):
1207
- raise TypeError('num_cols must be of type cqasm.v1x.primitives.Int')
1208
- val = cqasm.v1x.primitives.Int(val)
1209
- self._attr_num_cols = val
1210
-
1211
- @num_cols.deleter
1212
- def num_cols(self):
1213
- self._attr_num_cols = cqasm.v1x.primitives.Int()
1214
-
1215
- def __eq__(self, other):
1216
- """Equality operator. Ignores annotations!"""
1217
- if not isinstance(other, ComplexMatrix):
1218
- return False
1219
- if self.num_rows != other.num_rows:
1220
- return False
1221
- if self.num_cols != other.num_cols:
1222
- return False
1223
- if self.assignable != other.assignable:
1224
- return False
1225
- return True
1226
-
1227
- def dump(self, indent=0, annotations=None, links=1):
1228
- """Returns a debug representation of this tree as a multiline string.
1229
- indent is the number of double spaces prefixed before every line.
1230
- annotations, if specified, must be a set-like object containing the key
1231
- strings of the annotations that are to be printed. links specifies the
1232
- maximum link recursion depth."""
1233
- s = [' '*indent]
1234
- s.append('ComplexMatrix(')
1235
- if annotations is None:
1236
- annotations = []
1237
- for key in annotations:
1238
- if key in self:
1239
- s.append(' # {}: {}'.format(key, self[key]))
1240
- s.append('\n')
1241
- indent += 1
1242
- s.append(' '*indent)
1243
- s.append('num_rows: ')
1244
- s.append(str(self.num_rows) + '\n')
1245
- s.append(' '*indent)
1246
- s.append('num_cols: ')
1247
- s.append(str(self.num_cols) + '\n')
1248
- s.append(' '*indent)
1249
- s.append('assignable: ')
1250
- s.append(str(self.assignable) + '\n')
1251
- indent -= 1
1252
- s.append(' '*indent)
1253
- s.append(')')
1254
- return ''.join(s)
1255
-
1256
- __str__ = dump
1257
- __repr__ = dump
1258
-
1259
- def find_reachable(self, id_map=None):
1260
- """Returns a dictionary mapping Python id() values to stable sequence
1261
- numbers for all nodes in the tree rooted at this node. If id_map is
1262
- specified, found nodes are appended to it."""
1263
- if id_map is None:
1264
- id_map = {}
1265
- if id(self) in id_map:
1266
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
1267
- id_map[id(self)] = len(id_map)
1268
- return id_map
1269
-
1270
- def check_complete(self, id_map=None):
1271
- """Raises NotWellFormed if the tree rooted at this node is not
1272
- well-formed. If id_map is specified, this tree is only a subtree in the
1273
- context of a larger tree, and id_map must be a dict mapping from Python
1274
- id() codes to tree indices for all reachable nodes."""
1275
- if id_map is None:
1276
- id_map = self.find_reachable()
1277
-
1278
- def copy(self):
1279
- """Returns a shallow copy of this node."""
1280
- return ComplexMatrix(
1281
- num_rows=self._attr_num_rows,
1282
- num_cols=self._attr_num_cols,
1283
- assignable=self._attr_assignable
1284
- )
1285
-
1286
- def clone(self):
1287
- """Returns a deep copy of this node. This mimics the C++ interface,
1288
- deficiencies with links included; that is, links always point to the
1289
- original tree. If you're not cloning a subtree in a context where this
1290
- is the desired behavior, you may want to use the copy.deepcopy() from
1291
- the stdlib instead, which should copy links correctly."""
1292
- return ComplexMatrix(
1293
- num_rows=_cloned(self._attr_num_rows),
1294
- num_cols=_cloned(self._attr_num_cols),
1295
- assignable=_cloned(self._attr_assignable)
1296
- )
1297
-
1298
- @staticmethod
1299
- def _deserialize(cbor, seq_to_ob, links):
1300
- """Attempts to deserialize the given cbor object (in Python primitive
1301
- representation) into a node of this type. All (sub)nodes are added to
1302
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
1303
- registered in the links list by means of a two-tuple of the setter
1304
- function for the link field and the sequence number of the target node.
1305
- """
1306
- if not isinstance(cbor, dict):
1307
- raise TypeError('node description object must be a dict')
1308
- typ = cbor.get('@t', None)
1309
- if typ is None:
1310
- raise ValueError('type (@t) field is missing from node serialization')
1311
- if typ != 'ComplexMatrix':
1312
- raise ValueError('found node serialization for ' + typ + ', but expected ComplexMatrix')
1313
-
1314
- # Deserialize the num_rows field.
1315
- field = cbor.get('num_rows', None)
1316
- if not isinstance(field, dict):
1317
- raise ValueError('missing or invalid serialization of field num_rows')
1318
- if hasattr(cqasm.v1x.primitives.Int, 'deserialize_cbor'):
1319
- f_num_rows = cqasm.v1x.primitives.Int.deserialize_cbor(field)
1320
- else:
1321
- f_num_rows = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Int, field)
1322
-
1323
- # Deserialize the num_cols field.
1324
- field = cbor.get('num_cols', None)
1325
- if not isinstance(field, dict):
1326
- raise ValueError('missing or invalid serialization of field num_cols')
1327
- if hasattr(cqasm.v1x.primitives.Int, 'deserialize_cbor'):
1328
- f_num_cols = cqasm.v1x.primitives.Int.deserialize_cbor(field)
1329
- else:
1330
- f_num_cols = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Int, field)
1331
-
1332
- # Deserialize the assignable field.
1333
- field = cbor.get('assignable', None)
1334
- if not isinstance(field, dict):
1335
- raise ValueError('missing or invalid serialization of field assignable')
1336
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
1337
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
1338
- else:
1339
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
1340
-
1341
- # Construct the ComplexMatrix node.
1342
- node = ComplexMatrix(f_num_rows, f_num_cols, f_assignable)
1343
-
1344
- # Deserialize annotations.
1345
- for key, val in cbor.items():
1346
- if not (key.startswith('{') and key.endswith('}')):
1347
- continue
1348
- key = key[1:-1]
1349
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
1350
-
1351
- # Register node in sequence number lookup.
1352
- seq = cbor.get('@i', None)
1353
- if not isinstance(seq, int):
1354
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
1355
- if seq in seq_to_ob:
1356
- raise ValueError('duplicate sequence number %d' % seq)
1357
- seq_to_ob[seq] = node
1358
-
1359
- return node
1360
-
1361
- def _serialize(self, id_map):
1362
- """Serializes this node to the Python primitive representation of its
1363
- CBOR serialization. The tree that the node belongs to must be
1364
- well-formed. id_map must match Python id() calls for all nodes to unique
1365
- integers, to use for the sequence number representation of links."""
1366
- cbor = {'@i': id_map[id(self)], '@t': 'ComplexMatrix'}
1367
-
1368
- # Serialize the num_rows field.
1369
- if hasattr(self._attr_num_rows, 'serialize_cbor'):
1370
- cbor['num_rows'] = self._attr_num_rows.serialize_cbor()
1371
- else:
1372
- cbor['num_rows'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Int, self._attr_num_rows)
1373
-
1374
- # Serialize the num_cols field.
1375
- if hasattr(self._attr_num_cols, 'serialize_cbor'):
1376
- cbor['num_cols'] = self._attr_num_cols.serialize_cbor()
1377
- else:
1378
- cbor['num_cols'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Int, self._attr_num_cols)
1379
-
1380
- # Serialize the assignable field.
1381
- if hasattr(self._attr_assignable, 'serialize_cbor'):
1382
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
1383
- else:
1384
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
1385
-
1386
- # Serialize annotations.
1387
- for key, val in self._annot.items():
1388
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
1389
-
1390
- return cbor
1391
-
1392
-
1393
- class MultiComplexMatrix(_Multiple):
1394
- """Wrapper for an edge with multiple ComplexMatrix objects."""
1395
-
1396
- _T = ComplexMatrix
1397
-
1398
-
1399
- _typemap['ComplexMatrix'] = ComplexMatrix
1400
-
1401
- class Int(TypeBase):
1402
- """Type of an integer (signed 64-bit)."""
1403
-
1404
- __slots__ = []
1405
-
1406
- def __init__(
1407
- self,
1408
- assignable=None,
1409
- ):
1410
- super().__init__(assignable=assignable)
1411
-
1412
- def __eq__(self, other):
1413
- """Equality operator. Ignores annotations!"""
1414
- if not isinstance(other, Int):
1415
- return False
1416
- if self.assignable != other.assignable:
1417
- return False
1418
- return True
1419
-
1420
- def dump(self, indent=0, annotations=None, links=1):
1421
- """Returns a debug representation of this tree as a multiline string.
1422
- indent is the number of double spaces prefixed before every line.
1423
- annotations, if specified, must be a set-like object containing the key
1424
- strings of the annotations that are to be printed. links specifies the
1425
- maximum link recursion depth."""
1426
- s = [' '*indent]
1427
- s.append('Int(')
1428
- if annotations is None:
1429
- annotations = []
1430
- for key in annotations:
1431
- if key in self:
1432
- s.append(' # {}: {}'.format(key, self[key]))
1433
- s.append('\n')
1434
- indent += 1
1435
- s.append(' '*indent)
1436
- s.append('assignable: ')
1437
- s.append(str(self.assignable) + '\n')
1438
- indent -= 1
1439
- s.append(' '*indent)
1440
- s.append(')')
1441
- return ''.join(s)
1442
-
1443
- __str__ = dump
1444
- __repr__ = dump
1445
-
1446
- def find_reachable(self, id_map=None):
1447
- """Returns a dictionary mapping Python id() values to stable sequence
1448
- numbers for all nodes in the tree rooted at this node. If id_map is
1449
- specified, found nodes are appended to it."""
1450
- if id_map is None:
1451
- id_map = {}
1452
- if id(self) in id_map:
1453
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
1454
- id_map[id(self)] = len(id_map)
1455
- return id_map
1456
-
1457
- def check_complete(self, id_map=None):
1458
- """Raises NotWellFormed if the tree rooted at this node is not
1459
- well-formed. If id_map is specified, this tree is only a subtree in the
1460
- context of a larger tree, and id_map must be a dict mapping from Python
1461
- id() codes to tree indices for all reachable nodes."""
1462
- if id_map is None:
1463
- id_map = self.find_reachable()
1464
-
1465
- def copy(self):
1466
- """Returns a shallow copy of this node."""
1467
- return Int(
1468
- assignable=self._attr_assignable
1469
- )
1470
-
1471
- def clone(self):
1472
- """Returns a deep copy of this node. This mimics the C++ interface,
1473
- deficiencies with links included; that is, links always point to the
1474
- original tree. If you're not cloning a subtree in a context where this
1475
- is the desired behavior, you may want to use the copy.deepcopy() from
1476
- the stdlib instead, which should copy links correctly."""
1477
- return Int(
1478
- assignable=_cloned(self._attr_assignable)
1479
- )
1480
-
1481
- @staticmethod
1482
- def _deserialize(cbor, seq_to_ob, links):
1483
- """Attempts to deserialize the given cbor object (in Python primitive
1484
- representation) into a node of this type. All (sub)nodes are added to
1485
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
1486
- registered in the links list by means of a two-tuple of the setter
1487
- function for the link field and the sequence number of the target node.
1488
- """
1489
- if not isinstance(cbor, dict):
1490
- raise TypeError('node description object must be a dict')
1491
- typ = cbor.get('@t', None)
1492
- if typ is None:
1493
- raise ValueError('type (@t) field is missing from node serialization')
1494
- if typ != 'Int':
1495
- raise ValueError('found node serialization for ' + typ + ', but expected Int')
1496
-
1497
- # Deserialize the assignable field.
1498
- field = cbor.get('assignable', None)
1499
- if not isinstance(field, dict):
1500
- raise ValueError('missing or invalid serialization of field assignable')
1501
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
1502
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
1503
- else:
1504
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
1505
-
1506
- # Construct the Int node.
1507
- node = Int(f_assignable)
1508
-
1509
- # Deserialize annotations.
1510
- for key, val in cbor.items():
1511
- if not (key.startswith('{') and key.endswith('}')):
1512
- continue
1513
- key = key[1:-1]
1514
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
1515
-
1516
- # Register node in sequence number lookup.
1517
- seq = cbor.get('@i', None)
1518
- if not isinstance(seq, int):
1519
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
1520
- if seq in seq_to_ob:
1521
- raise ValueError('duplicate sequence number %d' % seq)
1522
- seq_to_ob[seq] = node
1523
-
1524
- return node
1525
-
1526
- def _serialize(self, id_map):
1527
- """Serializes this node to the Python primitive representation of its
1528
- CBOR serialization. The tree that the node belongs to must be
1529
- well-formed. id_map must match Python id() calls for all nodes to unique
1530
- integers, to use for the sequence number representation of links."""
1531
- cbor = {'@i': id_map[id(self)], '@t': 'Int'}
1532
-
1533
- # Serialize the assignable field.
1534
- if hasattr(self._attr_assignable, 'serialize_cbor'):
1535
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
1536
- else:
1537
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
1538
-
1539
- # Serialize annotations.
1540
- for key, val in self._annot.items():
1541
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
1542
-
1543
- return cbor
1544
-
1545
-
1546
- class MultiInt(_Multiple):
1547
- """Wrapper for an edge with multiple Int objects."""
1548
-
1549
- _T = Int
1550
-
1551
-
1552
- _typemap['Int'] = Int
1553
-
1554
- class Json(TypeBase):
1555
- """Type of a JSON string."""
1556
-
1557
- __slots__ = []
1558
-
1559
- def __init__(
1560
- self,
1561
- assignable=None,
1562
- ):
1563
- super().__init__(assignable=assignable)
1564
-
1565
- def __eq__(self, other):
1566
- """Equality operator. Ignores annotations!"""
1567
- if not isinstance(other, Json):
1568
- return False
1569
- if self.assignable != other.assignable:
1570
- return False
1571
- return True
1572
-
1573
- def dump(self, indent=0, annotations=None, links=1):
1574
- """Returns a debug representation of this tree as a multiline string.
1575
- indent is the number of double spaces prefixed before every line.
1576
- annotations, if specified, must be a set-like object containing the key
1577
- strings of the annotations that are to be printed. links specifies the
1578
- maximum link recursion depth."""
1579
- s = [' '*indent]
1580
- s.append('Json(')
1581
- if annotations is None:
1582
- annotations = []
1583
- for key in annotations:
1584
- if key in self:
1585
- s.append(' # {}: {}'.format(key, self[key]))
1586
- s.append('\n')
1587
- indent += 1
1588
- s.append(' '*indent)
1589
- s.append('assignable: ')
1590
- s.append(str(self.assignable) + '\n')
1591
- indent -= 1
1592
- s.append(' '*indent)
1593
- s.append(')')
1594
- return ''.join(s)
1595
-
1596
- __str__ = dump
1597
- __repr__ = dump
1598
-
1599
- def find_reachable(self, id_map=None):
1600
- """Returns a dictionary mapping Python id() values to stable sequence
1601
- numbers for all nodes in the tree rooted at this node. If id_map is
1602
- specified, found nodes are appended to it."""
1603
- if id_map is None:
1604
- id_map = {}
1605
- if id(self) in id_map:
1606
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
1607
- id_map[id(self)] = len(id_map)
1608
- return id_map
1609
-
1610
- def check_complete(self, id_map=None):
1611
- """Raises NotWellFormed if the tree rooted at this node is not
1612
- well-formed. If id_map is specified, this tree is only a subtree in the
1613
- context of a larger tree, and id_map must be a dict mapping from Python
1614
- id() codes to tree indices for all reachable nodes."""
1615
- if id_map is None:
1616
- id_map = self.find_reachable()
1617
-
1618
- def copy(self):
1619
- """Returns a shallow copy of this node."""
1620
- return Json(
1621
- assignable=self._attr_assignable
1622
- )
1623
-
1624
- def clone(self):
1625
- """Returns a deep copy of this node. This mimics the C++ interface,
1626
- deficiencies with links included; that is, links always point to the
1627
- original tree. If you're not cloning a subtree in a context where this
1628
- is the desired behavior, you may want to use the copy.deepcopy() from
1629
- the stdlib instead, which should copy links correctly."""
1630
- return Json(
1631
- assignable=_cloned(self._attr_assignable)
1632
- )
1633
-
1634
- @staticmethod
1635
- def _deserialize(cbor, seq_to_ob, links):
1636
- """Attempts to deserialize the given cbor object (in Python primitive
1637
- representation) into a node of this type. All (sub)nodes are added to
1638
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
1639
- registered in the links list by means of a two-tuple of the setter
1640
- function for the link field and the sequence number of the target node.
1641
- """
1642
- if not isinstance(cbor, dict):
1643
- raise TypeError('node description object must be a dict')
1644
- typ = cbor.get('@t', None)
1645
- if typ is None:
1646
- raise ValueError('type (@t) field is missing from node serialization')
1647
- if typ != 'Json':
1648
- raise ValueError('found node serialization for ' + typ + ', but expected Json')
1649
-
1650
- # Deserialize the assignable field.
1651
- field = cbor.get('assignable', None)
1652
- if not isinstance(field, dict):
1653
- raise ValueError('missing or invalid serialization of field assignable')
1654
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
1655
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
1656
- else:
1657
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
1658
-
1659
- # Construct the Json node.
1660
- node = Json(f_assignable)
1661
-
1662
- # Deserialize annotations.
1663
- for key, val in cbor.items():
1664
- if not (key.startswith('{') and key.endswith('}')):
1665
- continue
1666
- key = key[1:-1]
1667
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
1668
-
1669
- # Register node in sequence number lookup.
1670
- seq = cbor.get('@i', None)
1671
- if not isinstance(seq, int):
1672
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
1673
- if seq in seq_to_ob:
1674
- raise ValueError('duplicate sequence number %d' % seq)
1675
- seq_to_ob[seq] = node
1676
-
1677
- return node
1678
-
1679
- def _serialize(self, id_map):
1680
- """Serializes this node to the Python primitive representation of its
1681
- CBOR serialization. The tree that the node belongs to must be
1682
- well-formed. id_map must match Python id() calls for all nodes to unique
1683
- integers, to use for the sequence number representation of links."""
1684
- cbor = {'@i': id_map[id(self)], '@t': 'Json'}
1685
-
1686
- # Serialize the assignable field.
1687
- if hasattr(self._attr_assignable, 'serialize_cbor'):
1688
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
1689
- else:
1690
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
1691
-
1692
- # Serialize annotations.
1693
- for key, val in self._annot.items():
1694
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
1695
-
1696
- return cbor
1697
-
1698
-
1699
- class MultiJson(_Multiple):
1700
- """Wrapper for an edge with multiple Json objects."""
1701
-
1702
- _T = Json
1703
-
1704
-
1705
- _typemap['Json'] = Json
1706
-
1707
- class Qubit(TypeBase):
1708
- """Type of one or more qubit references."""
1709
-
1710
- __slots__ = []
1711
-
1712
- def __init__(
1713
- self,
1714
- assignable=None,
1715
- ):
1716
- super().__init__(assignable=assignable)
1717
-
1718
- def __eq__(self, other):
1719
- """Equality operator. Ignores annotations!"""
1720
- if not isinstance(other, Qubit):
1721
- return False
1722
- if self.assignable != other.assignable:
1723
- return False
1724
- return True
1725
-
1726
- def dump(self, indent=0, annotations=None, links=1):
1727
- """Returns a debug representation of this tree as a multiline string.
1728
- indent is the number of double spaces prefixed before every line.
1729
- annotations, if specified, must be a set-like object containing the key
1730
- strings of the annotations that are to be printed. links specifies the
1731
- maximum link recursion depth."""
1732
- s = [' '*indent]
1733
- s.append('Qubit(')
1734
- if annotations is None:
1735
- annotations = []
1736
- for key in annotations:
1737
- if key in self:
1738
- s.append(' # {}: {}'.format(key, self[key]))
1739
- s.append('\n')
1740
- indent += 1
1741
- s.append(' '*indent)
1742
- s.append('assignable: ')
1743
- s.append(str(self.assignable) + '\n')
1744
- indent -= 1
1745
- s.append(' '*indent)
1746
- s.append(')')
1747
- return ''.join(s)
1748
-
1749
- __str__ = dump
1750
- __repr__ = dump
1751
-
1752
- def find_reachable(self, id_map=None):
1753
- """Returns a dictionary mapping Python id() values to stable sequence
1754
- numbers for all nodes in the tree rooted at this node. If id_map is
1755
- specified, found nodes are appended to it."""
1756
- if id_map is None:
1757
- id_map = {}
1758
- if id(self) in id_map:
1759
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
1760
- id_map[id(self)] = len(id_map)
1761
- return id_map
1762
-
1763
- def check_complete(self, id_map=None):
1764
- """Raises NotWellFormed if the tree rooted at this node is not
1765
- well-formed. If id_map is specified, this tree is only a subtree in the
1766
- context of a larger tree, and id_map must be a dict mapping from Python
1767
- id() codes to tree indices for all reachable nodes."""
1768
- if id_map is None:
1769
- id_map = self.find_reachable()
1770
-
1771
- def copy(self):
1772
- """Returns a shallow copy of this node."""
1773
- return Qubit(
1774
- assignable=self._attr_assignable
1775
- )
1776
-
1777
- def clone(self):
1778
- """Returns a deep copy of this node. This mimics the C++ interface,
1779
- deficiencies with links included; that is, links always point to the
1780
- original tree. If you're not cloning a subtree in a context where this
1781
- is the desired behavior, you may want to use the copy.deepcopy() from
1782
- the stdlib instead, which should copy links correctly."""
1783
- return Qubit(
1784
- assignable=_cloned(self._attr_assignable)
1785
- )
1786
-
1787
- @staticmethod
1788
- def _deserialize(cbor, seq_to_ob, links):
1789
- """Attempts to deserialize the given cbor object (in Python primitive
1790
- representation) into a node of this type. All (sub)nodes are added to
1791
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
1792
- registered in the links list by means of a two-tuple of the setter
1793
- function for the link field and the sequence number of the target node.
1794
- """
1795
- if not isinstance(cbor, dict):
1796
- raise TypeError('node description object must be a dict')
1797
- typ = cbor.get('@t', None)
1798
- if typ is None:
1799
- raise ValueError('type (@t) field is missing from node serialization')
1800
- if typ != 'Qubit':
1801
- raise ValueError('found node serialization for ' + typ + ', but expected Qubit')
1802
-
1803
- # Deserialize the assignable field.
1804
- field = cbor.get('assignable', None)
1805
- if not isinstance(field, dict):
1806
- raise ValueError('missing or invalid serialization of field assignable')
1807
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
1808
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
1809
- else:
1810
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
1811
-
1812
- # Construct the Qubit node.
1813
- node = Qubit(f_assignable)
1814
-
1815
- # Deserialize annotations.
1816
- for key, val in cbor.items():
1817
- if not (key.startswith('{') and key.endswith('}')):
1818
- continue
1819
- key = key[1:-1]
1820
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
1821
-
1822
- # Register node in sequence number lookup.
1823
- seq = cbor.get('@i', None)
1824
- if not isinstance(seq, int):
1825
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
1826
- if seq in seq_to_ob:
1827
- raise ValueError('duplicate sequence number %d' % seq)
1828
- seq_to_ob[seq] = node
1829
-
1830
- return node
1831
-
1832
- def _serialize(self, id_map):
1833
- """Serializes this node to the Python primitive representation of its
1834
- CBOR serialization. The tree that the node belongs to must be
1835
- well-formed. id_map must match Python id() calls for all nodes to unique
1836
- integers, to use for the sequence number representation of links."""
1837
- cbor = {'@i': id_map[id(self)], '@t': 'Qubit'}
1838
-
1839
- # Serialize the assignable field.
1840
- if hasattr(self._attr_assignable, 'serialize_cbor'):
1841
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
1842
- else:
1843
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
1844
-
1845
- # Serialize annotations.
1846
- for key, val in self._annot.items():
1847
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
1848
-
1849
- return cbor
1850
-
1851
-
1852
- class MultiQubit(_Multiple):
1853
- """Wrapper for an edge with multiple Qubit objects."""
1854
-
1855
- _T = Qubit
1856
-
1857
-
1858
- _typemap['Qubit'] = Qubit
1859
-
1860
- class Real(TypeBase):
1861
- """Type of a real number (IEEE double)."""
1862
-
1863
- __slots__ = []
1864
-
1865
- def __init__(
1866
- self,
1867
- assignable=None,
1868
- ):
1869
- super().__init__(assignable=assignable)
1870
-
1871
- def __eq__(self, other):
1872
- """Equality operator. Ignores annotations!"""
1873
- if not isinstance(other, Real):
1874
- return False
1875
- if self.assignable != other.assignable:
1876
- return False
1877
- return True
1878
-
1879
- def dump(self, indent=0, annotations=None, links=1):
1880
- """Returns a debug representation of this tree as a multiline string.
1881
- indent is the number of double spaces prefixed before every line.
1882
- annotations, if specified, must be a set-like object containing the key
1883
- strings of the annotations that are to be printed. links specifies the
1884
- maximum link recursion depth."""
1885
- s = [' '*indent]
1886
- s.append('Real(')
1887
- if annotations is None:
1888
- annotations = []
1889
- for key in annotations:
1890
- if key in self:
1891
- s.append(' # {}: {}'.format(key, self[key]))
1892
- s.append('\n')
1893
- indent += 1
1894
- s.append(' '*indent)
1895
- s.append('assignable: ')
1896
- s.append(str(self.assignable) + '\n')
1897
- indent -= 1
1898
- s.append(' '*indent)
1899
- s.append(')')
1900
- return ''.join(s)
1901
-
1902
- __str__ = dump
1903
- __repr__ = dump
1904
-
1905
- def find_reachable(self, id_map=None):
1906
- """Returns a dictionary mapping Python id() values to stable sequence
1907
- numbers for all nodes in the tree rooted at this node. If id_map is
1908
- specified, found nodes are appended to it."""
1909
- if id_map is None:
1910
- id_map = {}
1911
- if id(self) in id_map:
1912
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
1913
- id_map[id(self)] = len(id_map)
1914
- return id_map
1915
-
1916
- def check_complete(self, id_map=None):
1917
- """Raises NotWellFormed if the tree rooted at this node is not
1918
- well-formed. If id_map is specified, this tree is only a subtree in the
1919
- context of a larger tree, and id_map must be a dict mapping from Python
1920
- id() codes to tree indices for all reachable nodes."""
1921
- if id_map is None:
1922
- id_map = self.find_reachable()
1923
-
1924
- def copy(self):
1925
- """Returns a shallow copy of this node."""
1926
- return Real(
1927
- assignable=self._attr_assignable
1928
- )
1929
-
1930
- def clone(self):
1931
- """Returns a deep copy of this node. This mimics the C++ interface,
1932
- deficiencies with links included; that is, links always point to the
1933
- original tree. If you're not cloning a subtree in a context where this
1934
- is the desired behavior, you may want to use the copy.deepcopy() from
1935
- the stdlib instead, which should copy links correctly."""
1936
- return Real(
1937
- assignable=_cloned(self._attr_assignable)
1938
- )
1939
-
1940
- @staticmethod
1941
- def _deserialize(cbor, seq_to_ob, links):
1942
- """Attempts to deserialize the given cbor object (in Python primitive
1943
- representation) into a node of this type. All (sub)nodes are added to
1944
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
1945
- registered in the links list by means of a two-tuple of the setter
1946
- function for the link field and the sequence number of the target node.
1947
- """
1948
- if not isinstance(cbor, dict):
1949
- raise TypeError('node description object must be a dict')
1950
- typ = cbor.get('@t', None)
1951
- if typ is None:
1952
- raise ValueError('type (@t) field is missing from node serialization')
1953
- if typ != 'Real':
1954
- raise ValueError('found node serialization for ' + typ + ', but expected Real')
1955
-
1956
- # Deserialize the assignable field.
1957
- field = cbor.get('assignable', None)
1958
- if not isinstance(field, dict):
1959
- raise ValueError('missing or invalid serialization of field assignable')
1960
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
1961
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
1962
- else:
1963
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
1964
-
1965
- # Construct the Real node.
1966
- node = Real(f_assignable)
1967
-
1968
- # Deserialize annotations.
1969
- for key, val in cbor.items():
1970
- if not (key.startswith('{') and key.endswith('}')):
1971
- continue
1972
- key = key[1:-1]
1973
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
1974
-
1975
- # Register node in sequence number lookup.
1976
- seq = cbor.get('@i', None)
1977
- if not isinstance(seq, int):
1978
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
1979
- if seq in seq_to_ob:
1980
- raise ValueError('duplicate sequence number %d' % seq)
1981
- seq_to_ob[seq] = node
1982
-
1983
- return node
1984
-
1985
- def _serialize(self, id_map):
1986
- """Serializes this node to the Python primitive representation of its
1987
- CBOR serialization. The tree that the node belongs to must be
1988
- well-formed. id_map must match Python id() calls for all nodes to unique
1989
- integers, to use for the sequence number representation of links."""
1990
- cbor = {'@i': id_map[id(self)], '@t': 'Real'}
1991
-
1992
- # Serialize the assignable field.
1993
- if hasattr(self._attr_assignable, 'serialize_cbor'):
1994
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
1995
- else:
1996
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
1997
-
1998
- # Serialize annotations.
1999
- for key, val in self._annot.items():
2000
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
2001
-
2002
- return cbor
2003
-
2004
-
2005
- class MultiReal(_Multiple):
2006
- """Wrapper for an edge with multiple Real objects."""
2007
-
2008
- _T = Real
2009
-
2010
-
2011
- _typemap['Real'] = Real
2012
-
2013
- class RealMatrix(TypeBase):
2014
- """Type of a real matrix. Also used for one-dimensional arrays and vectors.
2015
- """
2016
-
2017
- __slots__ = [
2018
- '_attr_num_rows',
2019
- '_attr_num_cols',
2020
- ]
2021
-
2022
- def __init__(
2023
- self,
2024
- num_rows=None,
2025
- num_cols=None,
2026
- assignable=None,
2027
- ):
2028
- super().__init__(assignable=assignable)
2029
- self.num_rows = num_rows
2030
- self.num_cols = num_cols
2031
-
2032
- @property
2033
- def num_rows(self):
2034
- """Number of rows. Negative indicates that the value is unconstrained.
2035
- Must be one or more otherwise."""
2036
- return self._attr_num_rows
2037
-
2038
- @num_rows.setter
2039
- def num_rows(self, val):
2040
- if val is None:
2041
- del self.num_rows
2042
- return
2043
- if not isinstance(val, cqasm.v1x.primitives.Int):
2044
- # Try to "typecast" if this isn't an obvious mistake.
2045
- if isinstance(val, Node):
2046
- raise TypeError('num_rows must be of type cqasm.v1x.primitives.Int')
2047
- val = cqasm.v1x.primitives.Int(val)
2048
- self._attr_num_rows = val
2049
-
2050
- @num_rows.deleter
2051
- def num_rows(self):
2052
- self._attr_num_rows = cqasm.v1x.primitives.Int()
2053
-
2054
- @property
2055
- def num_cols(self):
2056
- """Number of columns. Negative indicates that the value is
2057
- unconstrained. Can be zero, unlike num_rows."""
2058
- return self._attr_num_cols
2059
-
2060
- @num_cols.setter
2061
- def num_cols(self, val):
2062
- if val is None:
2063
- del self.num_cols
2064
- return
2065
- if not isinstance(val, cqasm.v1x.primitives.Int):
2066
- # Try to "typecast" if this isn't an obvious mistake.
2067
- if isinstance(val, Node):
2068
- raise TypeError('num_cols must be of type cqasm.v1x.primitives.Int')
2069
- val = cqasm.v1x.primitives.Int(val)
2070
- self._attr_num_cols = val
2071
-
2072
- @num_cols.deleter
2073
- def num_cols(self):
2074
- self._attr_num_cols = cqasm.v1x.primitives.Int()
2075
-
2076
- def __eq__(self, other):
2077
- """Equality operator. Ignores annotations!"""
2078
- if not isinstance(other, RealMatrix):
2079
- return False
2080
- if self.num_rows != other.num_rows:
2081
- return False
2082
- if self.num_cols != other.num_cols:
2083
- return False
2084
- if self.assignable != other.assignable:
2085
- return False
2086
- return True
2087
-
2088
- def dump(self, indent=0, annotations=None, links=1):
2089
- """Returns a debug representation of this tree as a multiline string.
2090
- indent is the number of double spaces prefixed before every line.
2091
- annotations, if specified, must be a set-like object containing the key
2092
- strings of the annotations that are to be printed. links specifies the
2093
- maximum link recursion depth."""
2094
- s = [' '*indent]
2095
- s.append('RealMatrix(')
2096
- if annotations is None:
2097
- annotations = []
2098
- for key in annotations:
2099
- if key in self:
2100
- s.append(' # {}: {}'.format(key, self[key]))
2101
- s.append('\n')
2102
- indent += 1
2103
- s.append(' '*indent)
2104
- s.append('num_rows: ')
2105
- s.append(str(self.num_rows) + '\n')
2106
- s.append(' '*indent)
2107
- s.append('num_cols: ')
2108
- s.append(str(self.num_cols) + '\n')
2109
- s.append(' '*indent)
2110
- s.append('assignable: ')
2111
- s.append(str(self.assignable) + '\n')
2112
- indent -= 1
2113
- s.append(' '*indent)
2114
- s.append(')')
2115
- return ''.join(s)
2116
-
2117
- __str__ = dump
2118
- __repr__ = dump
2119
-
2120
- def find_reachable(self, id_map=None):
2121
- """Returns a dictionary mapping Python id() values to stable sequence
2122
- numbers for all nodes in the tree rooted at this node. If id_map is
2123
- specified, found nodes are appended to it."""
2124
- if id_map is None:
2125
- id_map = {}
2126
- if id(self) in id_map:
2127
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
2128
- id_map[id(self)] = len(id_map)
2129
- return id_map
2130
-
2131
- def check_complete(self, id_map=None):
2132
- """Raises NotWellFormed if the tree rooted at this node is not
2133
- well-formed. If id_map is specified, this tree is only a subtree in the
2134
- context of a larger tree, and id_map must be a dict mapping from Python
2135
- id() codes to tree indices for all reachable nodes."""
2136
- if id_map is None:
2137
- id_map = self.find_reachable()
2138
-
2139
- def copy(self):
2140
- """Returns a shallow copy of this node."""
2141
- return RealMatrix(
2142
- num_rows=self._attr_num_rows,
2143
- num_cols=self._attr_num_cols,
2144
- assignable=self._attr_assignable
2145
- )
2146
-
2147
- def clone(self):
2148
- """Returns a deep copy of this node. This mimics the C++ interface,
2149
- deficiencies with links included; that is, links always point to the
2150
- original tree. If you're not cloning a subtree in a context where this
2151
- is the desired behavior, you may want to use the copy.deepcopy() from
2152
- the stdlib instead, which should copy links correctly."""
2153
- return RealMatrix(
2154
- num_rows=_cloned(self._attr_num_rows),
2155
- num_cols=_cloned(self._attr_num_cols),
2156
- assignable=_cloned(self._attr_assignable)
2157
- )
2158
-
2159
- @staticmethod
2160
- def _deserialize(cbor, seq_to_ob, links):
2161
- """Attempts to deserialize the given cbor object (in Python primitive
2162
- representation) into a node of this type. All (sub)nodes are added to
2163
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
2164
- registered in the links list by means of a two-tuple of the setter
2165
- function for the link field and the sequence number of the target node.
2166
- """
2167
- if not isinstance(cbor, dict):
2168
- raise TypeError('node description object must be a dict')
2169
- typ = cbor.get('@t', None)
2170
- if typ is None:
2171
- raise ValueError('type (@t) field is missing from node serialization')
2172
- if typ != 'RealMatrix':
2173
- raise ValueError('found node serialization for ' + typ + ', but expected RealMatrix')
2174
-
2175
- # Deserialize the num_rows field.
2176
- field = cbor.get('num_rows', None)
2177
- if not isinstance(field, dict):
2178
- raise ValueError('missing or invalid serialization of field num_rows')
2179
- if hasattr(cqasm.v1x.primitives.Int, 'deserialize_cbor'):
2180
- f_num_rows = cqasm.v1x.primitives.Int.deserialize_cbor(field)
2181
- else:
2182
- f_num_rows = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Int, field)
2183
-
2184
- # Deserialize the num_cols field.
2185
- field = cbor.get('num_cols', None)
2186
- if not isinstance(field, dict):
2187
- raise ValueError('missing or invalid serialization of field num_cols')
2188
- if hasattr(cqasm.v1x.primitives.Int, 'deserialize_cbor'):
2189
- f_num_cols = cqasm.v1x.primitives.Int.deserialize_cbor(field)
2190
- else:
2191
- f_num_cols = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Int, field)
2192
-
2193
- # Deserialize the assignable field.
2194
- field = cbor.get('assignable', None)
2195
- if not isinstance(field, dict):
2196
- raise ValueError('missing or invalid serialization of field assignable')
2197
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
2198
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
2199
- else:
2200
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
2201
-
2202
- # Construct the RealMatrix node.
2203
- node = RealMatrix(f_num_rows, f_num_cols, f_assignable)
2204
-
2205
- # Deserialize annotations.
2206
- for key, val in cbor.items():
2207
- if not (key.startswith('{') and key.endswith('}')):
2208
- continue
2209
- key = key[1:-1]
2210
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
2211
-
2212
- # Register node in sequence number lookup.
2213
- seq = cbor.get('@i', None)
2214
- if not isinstance(seq, int):
2215
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
2216
- if seq in seq_to_ob:
2217
- raise ValueError('duplicate sequence number %d' % seq)
2218
- seq_to_ob[seq] = node
2219
-
2220
- return node
2221
-
2222
- def _serialize(self, id_map):
2223
- """Serializes this node to the Python primitive representation of its
2224
- CBOR serialization. The tree that the node belongs to must be
2225
- well-formed. id_map must match Python id() calls for all nodes to unique
2226
- integers, to use for the sequence number representation of links."""
2227
- cbor = {'@i': id_map[id(self)], '@t': 'RealMatrix'}
2228
-
2229
- # Serialize the num_rows field.
2230
- if hasattr(self._attr_num_rows, 'serialize_cbor'):
2231
- cbor['num_rows'] = self._attr_num_rows.serialize_cbor()
2232
- else:
2233
- cbor['num_rows'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Int, self._attr_num_rows)
2234
-
2235
- # Serialize the num_cols field.
2236
- if hasattr(self._attr_num_cols, 'serialize_cbor'):
2237
- cbor['num_cols'] = self._attr_num_cols.serialize_cbor()
2238
- else:
2239
- cbor['num_cols'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Int, self._attr_num_cols)
2240
-
2241
- # Serialize the assignable field.
2242
- if hasattr(self._attr_assignable, 'serialize_cbor'):
2243
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
2244
- else:
2245
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
2246
-
2247
- # Serialize annotations.
2248
- for key, val in self._annot.items():
2249
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
2250
-
2251
- return cbor
2252
-
2253
-
2254
- class MultiRealMatrix(_Multiple):
2255
- """Wrapper for an edge with multiple RealMatrix objects."""
2256
-
2257
- _T = RealMatrix
2258
-
2259
-
2260
- _typemap['RealMatrix'] = RealMatrix
2261
-
2262
- class String(TypeBase):
2263
- """Type of an arbitrary string."""
2264
-
2265
- __slots__ = []
2266
-
2267
- def __init__(
2268
- self,
2269
- assignable=None,
2270
- ):
2271
- super().__init__(assignable=assignable)
2272
-
2273
- def __eq__(self, other):
2274
- """Equality operator. Ignores annotations!"""
2275
- if not isinstance(other, String):
2276
- return False
2277
- if self.assignable != other.assignable:
2278
- return False
2279
- return True
2280
-
2281
- def dump(self, indent=0, annotations=None, links=1):
2282
- """Returns a debug representation of this tree as a multiline string.
2283
- indent is the number of double spaces prefixed before every line.
2284
- annotations, if specified, must be a set-like object containing the key
2285
- strings of the annotations that are to be printed. links specifies the
2286
- maximum link recursion depth."""
2287
- s = [' '*indent]
2288
- s.append('String(')
2289
- if annotations is None:
2290
- annotations = []
2291
- for key in annotations:
2292
- if key in self:
2293
- s.append(' # {}: {}'.format(key, self[key]))
2294
- s.append('\n')
2295
- indent += 1
2296
- s.append(' '*indent)
2297
- s.append('assignable: ')
2298
- s.append(str(self.assignable) + '\n')
2299
- indent -= 1
2300
- s.append(' '*indent)
2301
- s.append(')')
2302
- return ''.join(s)
2303
-
2304
- __str__ = dump
2305
- __repr__ = dump
2306
-
2307
- def find_reachable(self, id_map=None):
2308
- """Returns a dictionary mapping Python id() values to stable sequence
2309
- numbers for all nodes in the tree rooted at this node. If id_map is
2310
- specified, found nodes are appended to it."""
2311
- if id_map is None:
2312
- id_map = {}
2313
- if id(self) in id_map:
2314
- raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
2315
- id_map[id(self)] = len(id_map)
2316
- return id_map
2317
-
2318
- def check_complete(self, id_map=None):
2319
- """Raises NotWellFormed if the tree rooted at this node is not
2320
- well-formed. If id_map is specified, this tree is only a subtree in the
2321
- context of a larger tree, and id_map must be a dict mapping from Python
2322
- id() codes to tree indices for all reachable nodes."""
2323
- if id_map is None:
2324
- id_map = self.find_reachable()
2325
-
2326
- def copy(self):
2327
- """Returns a shallow copy of this node."""
2328
- return String(
2329
- assignable=self._attr_assignable
2330
- )
2331
-
2332
- def clone(self):
2333
- """Returns a deep copy of this node. This mimics the C++ interface,
2334
- deficiencies with links included; that is, links always point to the
2335
- original tree. If you're not cloning a subtree in a context where this
2336
- is the desired behavior, you may want to use the copy.deepcopy() from
2337
- the stdlib instead, which should copy links correctly."""
2338
- return String(
2339
- assignable=_cloned(self._attr_assignable)
2340
- )
2341
-
2342
- @staticmethod
2343
- def _deserialize(cbor, seq_to_ob, links):
2344
- """Attempts to deserialize the given cbor object (in Python primitive
2345
- representation) into a node of this type. All (sub)nodes are added to
2346
- the seq_to_ob dict, indexed by their cbor sequence number. All links are
2347
- registered in the links list by means of a two-tuple of the setter
2348
- function for the link field and the sequence number of the target node.
2349
- """
2350
- if not isinstance(cbor, dict):
2351
- raise TypeError('node description object must be a dict')
2352
- typ = cbor.get('@t', None)
2353
- if typ is None:
2354
- raise ValueError('type (@t) field is missing from node serialization')
2355
- if typ != 'String':
2356
- raise ValueError('found node serialization for ' + typ + ', but expected String')
2357
-
2358
- # Deserialize the assignable field.
2359
- field = cbor.get('assignable', None)
2360
- if not isinstance(field, dict):
2361
- raise ValueError('missing or invalid serialization of field assignable')
2362
- if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
2363
- f_assignable = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
2364
- else:
2365
- f_assignable = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
2366
-
2367
- # Construct the String node.
2368
- node = String(f_assignable)
2369
-
2370
- # Deserialize annotations.
2371
- for key, val in cbor.items():
2372
- if not (key.startswith('{') and key.endswith('}')):
2373
- continue
2374
- key = key[1:-1]
2375
- node[key] = cqasm.v1x.primitives.deserialize(key, val)
2376
-
2377
- # Register node in sequence number lookup.
2378
- seq = cbor.get('@i', None)
2379
- if not isinstance(seq, int):
2380
- raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
2381
- if seq in seq_to_ob:
2382
- raise ValueError('duplicate sequence number %d' % seq)
2383
- seq_to_ob[seq] = node
2384
-
2385
- return node
2386
-
2387
- def _serialize(self, id_map):
2388
- """Serializes this node to the Python primitive representation of its
2389
- CBOR serialization. The tree that the node belongs to must be
2390
- well-formed. id_map must match Python id() calls for all nodes to unique
2391
- integers, to use for the sequence number representation of links."""
2392
- cbor = {'@i': id_map[id(self)], '@t': 'String'}
2393
-
2394
- # Serialize the assignable field.
2395
- if hasattr(self._attr_assignable, 'serialize_cbor'):
2396
- cbor['assignable'] = self._attr_assignable.serialize_cbor()
2397
- else:
2398
- cbor['assignable'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_assignable)
2399
-
2400
- # Serialize annotations.
2401
- for key, val in self._annot.items():
2402
- cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
2403
-
2404
- return cbor
2405
-
2406
-
2407
- class MultiString(_Multiple):
2408
- """Wrapper for an edge with multiple String objects."""
2409
-
2410
- _T = String
2411
-
2412
-
2413
- _typemap['String'] = String
2414
-