libqasm 0.5.2__cp310-cp310-win_amd64.whl → 0.6.1__cp310-cp310-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/v3x/ast.py +7407 -2186
- cqasm/v3x/primitives.py +4 -25
- cqasm/v3x/semantic.py +231 -522
- cqasm/v3x/types.py +75 -1150
- cqasm/v3x/values.py +78 -973
- libQasm/_libQasm.cp310-win_amd64.pyd +0 -0
- libQasm/libQasm.py +8 -699
- {libqasm-0.5.2.dist-info → libqasm-0.6.1.dist-info}/METADATA +37 -48
- libqasm-0.6.1.dist-info/RECORD +16 -0
- {libqasm-0.5.2.dist-info → libqasm-0.6.1.dist-info}/WHEEL +1 -1
- cqasm/v1x/__init__.py +0 -65
- cqasm/v1x/ast.py +0 -14966
- cqasm/v1x/error_model.py +0 -41
- cqasm/v1x/instruction.py +0 -70
- cqasm/v1x/primitives.py +0 -177
- cqasm/v1x/semantic.py +0 -7214
- cqasm/v1x/types.py +0 -2414
- cqasm/v1x/values.py +0 -3200
- libqasm-0.5.2.dist-info/RECORD +0 -24
- {libqasm-0.5.2.dist-info → libqasm-0.6.1.dist-info}/LICENSE.md +0 -0
- {libqasm-0.5.2.dist-info → libqasm-0.6.1.dist-info}/top_level.txt +0 -0
cqasm/v1x/values.py
DELETED
@@ -1,3200 +0,0 @@
|
|
1
|
-
import functools
|
2
|
-
import struct
|
3
|
-
import cqasm.v1x.primitives
|
4
|
-
import cqasm.v1x.types
|
5
|
-
import cqasm.v1x.semantic
|
6
|
-
|
7
|
-
|
8
|
-
_typemap = {}
|
9
|
-
|
10
|
-
|
11
|
-
def _cbor_read_intlike(cbor, offset, info):
|
12
|
-
"""Parses the additional information and reads any additional bytes it
|
13
|
-
specifies the existence of, and returns the encoded integer. offset
|
14
|
-
should point to the byte immediately following the initial byte. Returns
|
15
|
-
the encoded integer and the offset immediately following the object."""
|
16
|
-
|
17
|
-
# Info less than 24 is a shorthand for the integer itself.
|
18
|
-
if info < 24:
|
19
|
-
return info, offset
|
20
|
-
|
21
|
-
# 24 is 8-bit following the info byte.
|
22
|
-
if info == 24:
|
23
|
-
return cbor[offset], offset + 1
|
24
|
-
|
25
|
-
# 25 is 16-bit following the info byte.
|
26
|
-
if info == 25:
|
27
|
-
val, = struct.unpack('>H', cbor[offset:offset+2])
|
28
|
-
return val, offset + 2
|
29
|
-
|
30
|
-
# 26 is 32-bit following the info byte.
|
31
|
-
if info == 26:
|
32
|
-
val, = struct.unpack('>I', cbor[offset:offset+4])
|
33
|
-
return val, offset + 4
|
34
|
-
|
35
|
-
# 27 is 64-bit following the info byte.
|
36
|
-
if info == 27:
|
37
|
-
val, = struct.unpack('>Q', cbor[offset:offset+8])
|
38
|
-
return val, offset + 8
|
39
|
-
|
40
|
-
# Info greater than or equal to 28 is illegal. Note that 31 is used for
|
41
|
-
# indefinite lengths, so this must be checked prior to calling this
|
42
|
-
# method.
|
43
|
-
raise ValueError("invalid CBOR: illegal additional info for integer or object length")
|
44
|
-
|
45
|
-
|
46
|
-
def _sub_cbor_to_py(cbor, offset):
|
47
|
-
"""Converts the CBOR object starting at cbor[offset] to its Python
|
48
|
-
representation for as far as tree-gen supports CBOR. Returns this Python
|
49
|
-
representation and the offset immediately following the CBOR representation
|
50
|
-
thereof. Supported types:
|
51
|
-
|
52
|
-
- 0: unsigned integer (int)
|
53
|
-
- 1: negative integer (int)
|
54
|
-
- 2: byte string (bytes)
|
55
|
-
- 3: UTF-8 string (str)
|
56
|
-
- 4: array (list)
|
57
|
-
- 5: map (dict)
|
58
|
-
- 6: semantic tag (ignored)
|
59
|
-
- 7.20: false (bool)
|
60
|
-
- 7.21: true (bool)
|
61
|
-
- 7.22: null (NoneType)
|
62
|
-
- 7.27: double-precision float (float)
|
63
|
-
|
64
|
-
Both definite-length and indefinite-length notation is supported for sized
|
65
|
-
objects (strings, arrays, maps). A ValueError is thrown if the CBOR is
|
66
|
-
invalid or contains unsupported structures."""
|
67
|
-
|
68
|
-
# Read the initial byte.
|
69
|
-
initial = cbor[offset]
|
70
|
-
typ = initial >> 5
|
71
|
-
info = initial & 0x1F
|
72
|
-
offset += 1
|
73
|
-
|
74
|
-
# Handle unsigned integer (0) and negative integer (1).
|
75
|
-
if typ <= 1:
|
76
|
-
value, offset = _cbor_read_intlike(cbor, offset, info)
|
77
|
-
if typ == 1:
|
78
|
-
value = -1 - value
|
79
|
-
return value, offset
|
80
|
-
|
81
|
-
# Handle byte string (2) and UTF-8 string (3).
|
82
|
-
if typ <= 3:
|
83
|
-
|
84
|
-
# Gather components of the string in here.
|
85
|
-
if info == 31:
|
86
|
-
|
87
|
-
# Handle indefinite length strings. These consist of a
|
88
|
-
# break-terminated (0xFF) list of definite-length strings of the
|
89
|
-
# same type.
|
90
|
-
value = []
|
91
|
-
while True:
|
92
|
-
sub_initial = cbor[offset]; offset += 1
|
93
|
-
if sub_initial == 0xFF:
|
94
|
-
break
|
95
|
-
sub_typ = sub_initial >> 5
|
96
|
-
sub_info = sub_initial & 0x1F
|
97
|
-
if sub_typ != typ:
|
98
|
-
raise ValueError('invalid CBOR: illegal indefinite-length string component')
|
99
|
-
|
100
|
-
# Seek past definite-length string component. The size in
|
101
|
-
# bytes is encoded as an integer.
|
102
|
-
size, offset = _cbor_read_intlike(cbor, offset, sub_info)
|
103
|
-
value.append(cbor[offset:offset + size])
|
104
|
-
offset += size
|
105
|
-
value = b''.join(value)
|
106
|
-
|
107
|
-
else:
|
108
|
-
|
109
|
-
# Handle definite-length strings. The size in bytes is encoded as
|
110
|
-
# an integer.
|
111
|
-
size, offset = _cbor_read_intlike(cbor, offset, info)
|
112
|
-
value = cbor[offset:offset + size]
|
113
|
-
offset += size
|
114
|
-
|
115
|
-
if typ == 3:
|
116
|
-
value = value.decode('UTF-8')
|
117
|
-
return value, offset
|
118
|
-
|
119
|
-
# Handle array (4) and map (5).
|
120
|
-
if typ <= 5:
|
121
|
-
|
122
|
-
# Create result container.
|
123
|
-
container = [] if typ == 4 else {}
|
124
|
-
|
125
|
-
# Handle indefinite length arrays and maps.
|
126
|
-
if info == 31:
|
127
|
-
|
128
|
-
# Read objects/object pairs until we encounter a break.
|
129
|
-
while cbor[offset] != 0xFF:
|
130
|
-
if typ == 4:
|
131
|
-
value, offset = _sub_cbor_to_py(cbor, offset)
|
132
|
-
container.append(value)
|
133
|
-
else:
|
134
|
-
key, offset = _sub_cbor_to_py(cbor, offset)
|
135
|
-
if not isinstance(key, str):
|
136
|
-
raise ValueError('invalid CBOR: map key is not a UTF-8 string')
|
137
|
-
value, offset = _sub_cbor_to_py(cbor, offset)
|
138
|
-
container[key] = value
|
139
|
-
|
140
|
-
# Seek past the break.
|
141
|
-
offset += 1
|
142
|
-
|
143
|
-
else:
|
144
|
-
|
145
|
-
# Handle definite-length arrays and maps. The amount of
|
146
|
-
# objects/object pairs is encoded as an integer.
|
147
|
-
size, offset = _cbor_read_intlike(cbor, offset, info)
|
148
|
-
for _ in range(size):
|
149
|
-
if typ == 4:
|
150
|
-
value, offset = _sub_cbor_to_py(cbor, offset)
|
151
|
-
container.append(value)
|
152
|
-
else:
|
153
|
-
key, offset = _sub_cbor_to_py(cbor, offset)
|
154
|
-
if not isinstance(key, str):
|
155
|
-
raise ValueError('invalid CBOR: map key is not a UTF-8 string')
|
156
|
-
value, offset = _sub_cbor_to_py(cbor, offset)
|
157
|
-
container[key] = value
|
158
|
-
|
159
|
-
return container, offset
|
160
|
-
|
161
|
-
# Handle semantic tags.
|
162
|
-
if typ == 6:
|
163
|
-
|
164
|
-
# We don't use semantic tags for anything, but ignoring them is
|
165
|
-
# legal and reading past them is easy enough.
|
166
|
-
_, offset = _cbor_read_intlike(cbor, offset, info)
|
167
|
-
return _sub_cbor_to_py(cbor, offset)
|
168
|
-
|
169
|
-
# Handle major type 7. Here, the type is defined by the additional info.
|
170
|
-
# Additional info 24 is reserved for having the type specified by the
|
171
|
-
# next byte, but all such values are unassigned.
|
172
|
-
if info == 20:
|
173
|
-
# false
|
174
|
-
return False, offset
|
175
|
-
|
176
|
-
if info == 21:
|
177
|
-
# true
|
178
|
-
return True, offset
|
179
|
-
|
180
|
-
if info == 22:
|
181
|
-
# null
|
182
|
-
return None, offset
|
183
|
-
|
184
|
-
if info == 23:
|
185
|
-
# Undefined value.
|
186
|
-
raise ValueError('invalid CBOR: undefined value is not supported')
|
187
|
-
|
188
|
-
if info == 25:
|
189
|
-
# Half-precision float.
|
190
|
-
raise ValueError('invalid CBOR: half-precision float is not supported')
|
191
|
-
|
192
|
-
if info == 26:
|
193
|
-
# Single-precision float.
|
194
|
-
raise ValueError('invalid CBOR: single-precision float is not supported')
|
195
|
-
|
196
|
-
if info == 27:
|
197
|
-
# Double-precision float.
|
198
|
-
value, = struct.unpack('>d', cbor[offset:offset+8])
|
199
|
-
return value, offset + 8
|
200
|
-
|
201
|
-
if info == 31:
|
202
|
-
# Break value used for indefinite-length objects.
|
203
|
-
raise ValueError('invalid CBOR: unexpected break')
|
204
|
-
|
205
|
-
raise ValueError('invalid CBOR: unknown type code')
|
206
|
-
|
207
|
-
|
208
|
-
def _cbor_to_py(cbor):
|
209
|
-
"""Converts the given CBOR object (bytes) to its Python representation for
|
210
|
-
as far as tree-gen supports CBOR. Supported types:
|
211
|
-
|
212
|
-
- 0: unsigned integer (int)
|
213
|
-
- 1: negative integer (int)
|
214
|
-
- 2: byte string (bytes)
|
215
|
-
- 3: UTF-8 string (str)
|
216
|
-
- 4: array (list)
|
217
|
-
- 5: map (dict)
|
218
|
-
- 6: semantic tag (ignored)
|
219
|
-
- 7.20: false (bool)
|
220
|
-
- 7.21: true (bool)
|
221
|
-
- 7.22: null (NoneType)
|
222
|
-
- 7.27: double-precision float (float)
|
223
|
-
|
224
|
-
Both definite-length and indefinite-length notation is supported for sized
|
225
|
-
objects (strings, arrays, maps). A ValueError is thrown if the CBOR is
|
226
|
-
invalid or contains unsupported structures."""
|
227
|
-
|
228
|
-
value, length = _sub_cbor_to_py(cbor, 0)
|
229
|
-
if length < len(cbor):
|
230
|
-
raise ValueError('invalid CBOR: garbage at the end')
|
231
|
-
return value
|
232
|
-
|
233
|
-
|
234
|
-
class _Cbor(bytes):
|
235
|
-
"""Marker class indicating that this bytes object represents CBOR."""
|
236
|
-
pass
|
237
|
-
|
238
|
-
|
239
|
-
def _cbor_write_intlike(value, major=0):
|
240
|
-
"""Converts the given integer to its minimal representation in CBOR. The
|
241
|
-
major code can be overridden to write lengths for strings, arrays, and
|
242
|
-
maps."""
|
243
|
-
|
244
|
-
# Negative integers use major code 1.
|
245
|
-
if value < 0:
|
246
|
-
major = 1
|
247
|
-
value = -1 - value
|
248
|
-
initial = major << 5
|
249
|
-
|
250
|
-
# Use the minimal representation.
|
251
|
-
if value < 24:
|
252
|
-
return struct.pack('>B', initial | value)
|
253
|
-
if value < 0x100:
|
254
|
-
return struct.pack('>BB', initial | 24, value)
|
255
|
-
if value < 0x10000:
|
256
|
-
return struct.pack('>BH', initial | 25, value)
|
257
|
-
if value < 0x100000000:
|
258
|
-
return struct.pack('>BI', initial | 26, value)
|
259
|
-
if value < 0x10000000000000000:
|
260
|
-
return struct.pack('>BQ', initial | 27, value)
|
261
|
-
|
262
|
-
raise ValueError('integer too large for CBOR (bigint not supported)')
|
263
|
-
|
264
|
-
|
265
|
-
def _py_to_cbor(value, type_converter=None):
|
266
|
-
"""Inverse of _cbor_to_py(). type_converter optionally specifies a function
|
267
|
-
that takes a value and either converts it to a primitive for serialization,
|
268
|
-
converts it to a _Cbor object manually, or raises a TypeError if no
|
269
|
-
conversion is known. If no type_converter is specified, a TypeError is
|
270
|
-
raised in all cases the type_converter would otherwise be called. The cbor
|
271
|
-
serialization is returned using a _Cbor object, which is just a marker class
|
272
|
-
behaving just like bytes."""
|
273
|
-
if isinstance(value, _Cbor):
|
274
|
-
return value
|
275
|
-
|
276
|
-
if isinstance(value, int):
|
277
|
-
return _Cbor(_cbor_write_intlike(value))
|
278
|
-
|
279
|
-
if isinstance(value, float):
|
280
|
-
return _Cbor(struct.pack('>Bd', 0xFB, value))
|
281
|
-
|
282
|
-
if isinstance(value, str):
|
283
|
-
value = value.encode('UTF-8')
|
284
|
-
return _Cbor(_cbor_write_intlike(len(value), 3) + value)
|
285
|
-
|
286
|
-
if isinstance(value, bytes):
|
287
|
-
return _Cbor(_cbor_write_intlike(len(value), 2) + value)
|
288
|
-
|
289
|
-
if value is False:
|
290
|
-
return _Cbor(b'\xF4')
|
291
|
-
|
292
|
-
if value is True:
|
293
|
-
return _Cbor(b'\xF5')
|
294
|
-
|
295
|
-
if value is None:
|
296
|
-
return _Cbor(b'\xF6')
|
297
|
-
|
298
|
-
if isinstance(value, (list, tuple)):
|
299
|
-
cbor = [_cbor_write_intlike(len(value), 4)]
|
300
|
-
for val in value:
|
301
|
-
cbor.append(_py_to_cbor(val, type_converter))
|
302
|
-
return _Cbor(b''.join(cbor))
|
303
|
-
|
304
|
-
if isinstance(value, dict):
|
305
|
-
cbor = [_cbor_write_intlike(len(value), 5)]
|
306
|
-
for key, val in sorted(value.items()):
|
307
|
-
if not isinstance(key, str):
|
308
|
-
raise TypeError('dict keys must be strings')
|
309
|
-
cbor.append(_py_to_cbor(key, type_converter))
|
310
|
-
cbor.append(_py_to_cbor(val, type_converter))
|
311
|
-
return _Cbor(b''.join(cbor))
|
312
|
-
|
313
|
-
if type_converter is not None:
|
314
|
-
return _py_to_cbor(type_converter(value))
|
315
|
-
|
316
|
-
raise TypeError('unsupported type for conversion to cbor: %r' % (value,))
|
317
|
-
|
318
|
-
|
319
|
-
class NotWellFormed(ValueError):
|
320
|
-
"""Exception class for well-formedness checks."""
|
321
|
-
|
322
|
-
def __init__(self, msg):
|
323
|
-
super().__init__('not well-formed: ' + str(msg))
|
324
|
-
|
325
|
-
|
326
|
-
class Node(object):
|
327
|
-
"""Base class for nodes."""
|
328
|
-
|
329
|
-
__slots__ = ['_annot']
|
330
|
-
|
331
|
-
def __init__(self):
|
332
|
-
super().__init__()
|
333
|
-
self._annot = {}
|
334
|
-
|
335
|
-
def __getitem__(self, key):
|
336
|
-
"""Returns the annotation object with the specified key, or raises
|
337
|
-
KeyError if not found."""
|
338
|
-
if not isinstance(key, str):
|
339
|
-
raise TypeError('indexing a node with something other than an '
|
340
|
-
'annotation key string')
|
341
|
-
return self._annot[key]
|
342
|
-
|
343
|
-
def __setitem__(self, key, val):
|
344
|
-
"""Assigns the annotation object with the specified key."""
|
345
|
-
if not isinstance(key, str):
|
346
|
-
raise TypeError('indexing a node with something other than an '
|
347
|
-
'annotation key string')
|
348
|
-
self._annot[key] = val
|
349
|
-
|
350
|
-
def __delitem__(self, key):
|
351
|
-
"""Deletes the annotation object with the specified key."""
|
352
|
-
if not isinstance(key, str):
|
353
|
-
raise TypeError('indexing a node with something other than an '
|
354
|
-
'annotation key string')
|
355
|
-
del self._annot[key]
|
356
|
-
|
357
|
-
def __contains__(self, key):
|
358
|
-
"""Returns whether an annotation exists for the specified key."""
|
359
|
-
return key in self._annot
|
360
|
-
|
361
|
-
@staticmethod
|
362
|
-
def find_reachable(self, id_map=None):
|
363
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
364
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
365
|
-
specified, found nodes are appended to it. Note that this is overridden
|
366
|
-
by the actual node class implementations; this base function does very
|
367
|
-
little."""
|
368
|
-
if id_map is None:
|
369
|
-
id_map = {}
|
370
|
-
return id_map
|
371
|
-
|
372
|
-
def check_complete(self, id_map=None):
|
373
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
374
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
375
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
376
|
-
id() codes to tree indices for all reachable nodes. Note that this is
|
377
|
-
overridden by the actual node class implementations; this base function
|
378
|
-
always raises an exception."""
|
379
|
-
raise NotWellFormed('found node of abstract type ' + type(self).__name__)
|
380
|
-
|
381
|
-
def check_well_formed(self):
|
382
|
-
"""Checks whether the tree starting at this node is well-formed. That
|
383
|
-
is:
|
384
|
-
|
385
|
-
- all One, Link, and Many edges have (at least) one entry;
|
386
|
-
- all the One entries internally stored by Any/Many have an entry;
|
387
|
-
- all Link and filled OptLink nodes link to a node that's reachable
|
388
|
-
from this node;
|
389
|
-
- the nodes referred to be One/Maybe only appear once in the tree
|
390
|
-
(except through links).
|
391
|
-
|
392
|
-
If it isn't well-formed, a NotWellFormed is thrown."""
|
393
|
-
self.check_complete()
|
394
|
-
|
395
|
-
def is_well_formed(self):
|
396
|
-
"""Returns whether the tree starting at this node is well-formed. That
|
397
|
-
is:
|
398
|
-
|
399
|
-
- all One, Link, and Many edges have (at least) one entry;
|
400
|
-
- all the One entries internally stored by Any/Many have an entry;
|
401
|
-
- all Link and filled OptLink nodes link to a node that's reachable
|
402
|
-
from this node;
|
403
|
-
- the nodes referred to be One/Maybe only appear once in the tree
|
404
|
-
(except through links)."""
|
405
|
-
try:
|
406
|
-
self.check_well_formed()
|
407
|
-
return True
|
408
|
-
except NotWellFormed:
|
409
|
-
return False
|
410
|
-
|
411
|
-
def copy(self):
|
412
|
-
"""Returns a shallow copy of this node. Note that this is overridden by
|
413
|
-
the actual node class implementations; this base function always raises
|
414
|
-
an exception."""
|
415
|
-
raise TypeError('can\'t copy node of abstract type ' + type(self).__name__)
|
416
|
-
|
417
|
-
def clone(self):
|
418
|
-
"""Returns a deep copy of this node. Note that this is overridden by
|
419
|
-
the actual node class implementations; this base function always raises
|
420
|
-
an exception."""
|
421
|
-
raise TypeError('can\'t clone node of abstract type ' + type(self).__name__)
|
422
|
-
|
423
|
-
@classmethod
|
424
|
-
def deserialize(cls, cbor):
|
425
|
-
"""Attempts to deserialize the given cbor object (either as bytes or as
|
426
|
-
its Python primitive representation) into a node of this type."""
|
427
|
-
if isinstance(cbor, bytes):
|
428
|
-
cbor = _cbor_to_py(cbor)
|
429
|
-
seq_to_ob = {}
|
430
|
-
links = []
|
431
|
-
root = cls._deserialize(cbor, seq_to_ob, links)
|
432
|
-
for link_setter, seq in links:
|
433
|
-
ob = seq_to_ob.get(seq, None)
|
434
|
-
if ob is None:
|
435
|
-
raise ValueError('found link to nonexistent object')
|
436
|
-
link_setter(ob)
|
437
|
-
return root
|
438
|
-
|
439
|
-
def serialize(self):
|
440
|
-
"""Serializes this node into its cbor representation in the form of a
|
441
|
-
bytes object."""
|
442
|
-
id_map = self.find_reachable()
|
443
|
-
self.check_complete(id_map)
|
444
|
-
return _py_to_cbor(self._serialize(id_map))
|
445
|
-
|
446
|
-
@staticmethod
|
447
|
-
def _deserialize(cbor, seq_to_ob, links):
|
448
|
-
if not isinstance(cbor, dict):
|
449
|
-
raise TypeError('node description object must be a dict')
|
450
|
-
typ = cbor.get('@t', None)
|
451
|
-
if typ is None:
|
452
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
453
|
-
node_type = _typemap.get(cbor.get('@t'), None)
|
454
|
-
if node_type is None:
|
455
|
-
raise ValueError('unknown node type (@t): ' + str(cbor.get('@t')))
|
456
|
-
return node_type._deserialize(cbor, seq_to_ob, links)
|
457
|
-
|
458
|
-
|
459
|
-
@functools.total_ordering
|
460
|
-
class _Multiple(object):
|
461
|
-
"""Base class for the Any* and Many* edge helper classes. Inheriting
|
462
|
-
classes must set the class constant _T to the node type they are made
|
463
|
-
for."""
|
464
|
-
|
465
|
-
__slots__ = ['_l']
|
466
|
-
|
467
|
-
def __init__(self, *args, **kwargs):
|
468
|
-
super().__init__()
|
469
|
-
self._l = list(*args, **kwargs)
|
470
|
-
for idx, val in enumerate(self._l):
|
471
|
-
if not isinstance(val, self._T):
|
472
|
-
raise TypeError(
|
473
|
-
'object {!r} at index {:d} is not an instance of {!r}'
|
474
|
-
.format(val, idx, self._T))
|
475
|
-
|
476
|
-
def __repr__(self):
|
477
|
-
return '{}({!r})'.format(type(self).__name__, self._l)
|
478
|
-
|
479
|
-
def clone(self):
|
480
|
-
return self.__class__(map(lambda node: node.clone(), self._l))
|
481
|
-
|
482
|
-
def __len__(self):
|
483
|
-
return len(self._l)
|
484
|
-
|
485
|
-
def __getitem__(self, idx):
|
486
|
-
return self._l[idx]
|
487
|
-
|
488
|
-
def __setitem__(self, idx, val):
|
489
|
-
if not isinstance(val, self._T):
|
490
|
-
raise TypeError(
|
491
|
-
'object {!r} is not an instance of {!r}'
|
492
|
-
.format(val, idx, self._T))
|
493
|
-
self._l[idx] = val
|
494
|
-
|
495
|
-
def __delitem__(self, idx):
|
496
|
-
del self._l[idx]
|
497
|
-
|
498
|
-
def __iter__(self):
|
499
|
-
return iter(self._l)
|
500
|
-
|
501
|
-
def __reversed__(self):
|
502
|
-
return reversed(self._l)
|
503
|
-
|
504
|
-
def __contains__(self, val):
|
505
|
-
return val in self._l
|
506
|
-
|
507
|
-
def append(self, val):
|
508
|
-
if not isinstance(val, self._T):
|
509
|
-
raise TypeError(
|
510
|
-
'object {!r} is not an instance of {!r}'
|
511
|
-
.format(val, self._T))
|
512
|
-
self._l.append(val)
|
513
|
-
|
514
|
-
def extend(self, iterable):
|
515
|
-
for val in iterable:
|
516
|
-
self.append(val)
|
517
|
-
|
518
|
-
def insert(self, idx, val):
|
519
|
-
if not isinstance(val, self._T):
|
520
|
-
raise TypeError(
|
521
|
-
'object {!r} is not an instance of {!r}'
|
522
|
-
.format(val, self._T))
|
523
|
-
self._l.insert(idx, val)
|
524
|
-
|
525
|
-
def remote(self, val):
|
526
|
-
self._l.remove(val)
|
527
|
-
|
528
|
-
def pop(self, idx=-1):
|
529
|
-
return self._l.pop(idx)
|
530
|
-
|
531
|
-
def clear(self):
|
532
|
-
self._l.clear()
|
533
|
-
|
534
|
-
def idx(self, val, start=0, end=-1):
|
535
|
-
return self._l.idx(val, start, end)
|
536
|
-
|
537
|
-
def count(self, val):
|
538
|
-
return self._l.count(val)
|
539
|
-
|
540
|
-
def sort(self, key=None, reverse=False):
|
541
|
-
self._l.sort(key=key, reverse=reverse)
|
542
|
-
|
543
|
-
def reverse(self):
|
544
|
-
self._l.reverse()
|
545
|
-
|
546
|
-
def copy(self):
|
547
|
-
return self.__class__(self)
|
548
|
-
|
549
|
-
def __eq__(self, other):
|
550
|
-
if not isinstance(other, _Multiple):
|
551
|
-
return False
|
552
|
-
return self._l == other._l
|
553
|
-
|
554
|
-
def __lt__(self, other):
|
555
|
-
return self._l < other._l
|
556
|
-
|
557
|
-
def __iadd__(self, other):
|
558
|
-
self.extend(other)
|
559
|
-
|
560
|
-
def __add__(self, other):
|
561
|
-
copy = self.copy()
|
562
|
-
copy += other
|
563
|
-
return copy
|
564
|
-
|
565
|
-
def __imul__(self, other):
|
566
|
-
self._l *= other
|
567
|
-
|
568
|
-
def __mul__(self, other):
|
569
|
-
copy = self.copy()
|
570
|
-
copy *= other
|
571
|
-
return copy
|
572
|
-
|
573
|
-
def __rmul__(self, other):
|
574
|
-
copy = self.copy()
|
575
|
-
copy *= other
|
576
|
-
return copy
|
577
|
-
|
578
|
-
|
579
|
-
class MultiNode(_Multiple):
|
580
|
-
"""Wrapper for an edge with multiple Node objects."""
|
581
|
-
|
582
|
-
_T = Node
|
583
|
-
|
584
|
-
|
585
|
-
def _cloned(obj):
|
586
|
-
"""Attempts to clone the given object by calling its clone() method, if it
|
587
|
-
has one."""
|
588
|
-
if hasattr(obj, 'clone'):
|
589
|
-
return obj.clone()
|
590
|
-
return obj
|
591
|
-
|
592
|
-
|
593
|
-
class Reference(Node):
|
594
|
-
"""Represents a reference to some storage location."""
|
595
|
-
|
596
|
-
__slots__ = []
|
597
|
-
|
598
|
-
def __init__(self):
|
599
|
-
super().__init__()
|
600
|
-
|
601
|
-
@staticmethod
|
602
|
-
def _deserialize(cbor, seq_to_ob, links):
|
603
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
604
|
-
representation) into a node of this type. All (sub)nodes are added to
|
605
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
606
|
-
registered in the links list by means of a two-tuple of the setter
|
607
|
-
function for the link field and the sequence number of the target node.
|
608
|
-
"""
|
609
|
-
if not isinstance(cbor, dict):
|
610
|
-
raise TypeError('node description object must be a dict')
|
611
|
-
typ = cbor.get('@t', None)
|
612
|
-
if typ is None:
|
613
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
614
|
-
if typ == 'QubitRefs':
|
615
|
-
return QubitRefs._deserialize(cbor, seq_to_ob, links)
|
616
|
-
if typ == 'BitRefs':
|
617
|
-
return BitRefs._deserialize(cbor, seq_to_ob, links)
|
618
|
-
if typ == 'VariableRef':
|
619
|
-
return VariableRef._deserialize(cbor, seq_to_ob, links)
|
620
|
-
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
621
|
-
|
622
|
-
def _serialize(self, id_map):
|
623
|
-
"""Serializes this node to the Python primitive representation of its
|
624
|
-
CBOR serialization. The tree that the node belongs to must be
|
625
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
626
|
-
integers, to use for the sequence number representation of links."""
|
627
|
-
cbor = {'@i': id_map[id(self)], '@t': 'Reference'}
|
628
|
-
|
629
|
-
# Serialize annotations.
|
630
|
-
for key, val in self._annot.items():
|
631
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
632
|
-
|
633
|
-
return cbor
|
634
|
-
|
635
|
-
|
636
|
-
class MultiReference(_Multiple):
|
637
|
-
"""Wrapper for an edge with multiple Reference objects."""
|
638
|
-
|
639
|
-
_T = Reference
|
640
|
-
|
641
|
-
|
642
|
-
_typemap['Reference'] = Reference
|
643
|
-
|
644
|
-
class BitRefs(Reference):
|
645
|
-
"""Represents a measurement bit, or a number of measurement bits for
|
646
|
-
conditional gates with multiple conditions. When there are multiple, the
|
647
|
-
conditions are all and'ed together."""
|
648
|
-
|
649
|
-
__slots__ = [
|
650
|
-
'_attr_index',
|
651
|
-
]
|
652
|
-
|
653
|
-
def __init__(
|
654
|
-
self,
|
655
|
-
index=None,
|
656
|
-
):
|
657
|
-
super().__init__()
|
658
|
-
self.index = index
|
659
|
-
|
660
|
-
@property
|
661
|
-
def index(self):
|
662
|
-
"""Set of qubit indices for which these are measurement bits, starting
|
663
|
-
at 0."""
|
664
|
-
return self._attr_index
|
665
|
-
|
666
|
-
@index.setter
|
667
|
-
def index(self, val):
|
668
|
-
if val is None:
|
669
|
-
del self.index
|
670
|
-
return
|
671
|
-
if not isinstance(val, MultiConstInt):
|
672
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
673
|
-
if isinstance(val, Node):
|
674
|
-
raise TypeError('index must be of type MultiConstInt')
|
675
|
-
val = MultiConstInt(val)
|
676
|
-
self._attr_index = val
|
677
|
-
|
678
|
-
@index.deleter
|
679
|
-
def index(self):
|
680
|
-
self._attr_index = MultiConstInt()
|
681
|
-
|
682
|
-
def __eq__(self, other):
|
683
|
-
"""Equality operator. Ignores annotations!"""
|
684
|
-
if not isinstance(other, BitRefs):
|
685
|
-
return False
|
686
|
-
if self.index != other.index:
|
687
|
-
return False
|
688
|
-
return True
|
689
|
-
|
690
|
-
def dump(self, indent=0, annotations=None, links=1):
|
691
|
-
"""Returns a debug representation of this tree as a multiline string.
|
692
|
-
indent is the number of double spaces prefixed before every line.
|
693
|
-
annotations, if specified, must be a set-like object containing the key
|
694
|
-
strings of the annotations that are to be printed. links specifies the
|
695
|
-
maximum link recursion depth."""
|
696
|
-
s = [' '*indent]
|
697
|
-
s.append('BitRefs(')
|
698
|
-
if annotations is None:
|
699
|
-
annotations = []
|
700
|
-
for key in annotations:
|
701
|
-
if key in self:
|
702
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
703
|
-
s.append('\n')
|
704
|
-
indent += 1
|
705
|
-
s.append(' '*indent)
|
706
|
-
s.append('index: ')
|
707
|
-
if not self.index:
|
708
|
-
s.append('!MISSING\n')
|
709
|
-
else:
|
710
|
-
s.append('[\n')
|
711
|
-
for child in self.index:
|
712
|
-
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
713
|
-
s.append(' '*indent + ']\n')
|
714
|
-
indent -= 1
|
715
|
-
s.append(' '*indent)
|
716
|
-
s.append(')')
|
717
|
-
return ''.join(s)
|
718
|
-
|
719
|
-
__str__ = dump
|
720
|
-
__repr__ = dump
|
721
|
-
|
722
|
-
def find_reachable(self, id_map=None):
|
723
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
724
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
725
|
-
specified, found nodes are appended to it."""
|
726
|
-
if id_map is None:
|
727
|
-
id_map = {}
|
728
|
-
if id(self) in id_map:
|
729
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
730
|
-
id_map[id(self)] = len(id_map)
|
731
|
-
for el in self._attr_index:
|
732
|
-
el.find_reachable(id_map)
|
733
|
-
return id_map
|
734
|
-
|
735
|
-
def check_complete(self, id_map=None):
|
736
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
737
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
738
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
739
|
-
id() codes to tree indices for all reachable nodes."""
|
740
|
-
if id_map is None:
|
741
|
-
id_map = self.find_reachable()
|
742
|
-
if not self._attr_index:
|
743
|
-
raise NotWellFormed('index needs at least one node but has zero')
|
744
|
-
for child in self._attr_index:
|
745
|
-
child.check_complete(id_map)
|
746
|
-
|
747
|
-
def copy(self):
|
748
|
-
"""Returns a shallow copy of this node."""
|
749
|
-
return BitRefs(
|
750
|
-
index=self._attr_index.copy()
|
751
|
-
)
|
752
|
-
|
753
|
-
def clone(self):
|
754
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
755
|
-
deficiencies with links included; that is, links always point to the
|
756
|
-
original tree. If you're not cloning a subtree in a context where this
|
757
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
758
|
-
the stdlib instead, which should copy links correctly."""
|
759
|
-
return BitRefs(
|
760
|
-
index=_cloned(self._attr_index)
|
761
|
-
)
|
762
|
-
|
763
|
-
@staticmethod
|
764
|
-
def _deserialize(cbor, seq_to_ob, links):
|
765
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
766
|
-
representation) into a node of this type. All (sub)nodes are added to
|
767
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
768
|
-
registered in the links list by means of a two-tuple of the setter
|
769
|
-
function for the link field and the sequence number of the target node.
|
770
|
-
"""
|
771
|
-
if not isinstance(cbor, dict):
|
772
|
-
raise TypeError('node description object must be a dict')
|
773
|
-
typ = cbor.get('@t', None)
|
774
|
-
if typ is None:
|
775
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
776
|
-
if typ != 'BitRefs':
|
777
|
-
raise ValueError('found node serialization for ' + typ + ', but expected BitRefs')
|
778
|
-
|
779
|
-
# Deserialize the index field.
|
780
|
-
field = cbor.get('index', None)
|
781
|
-
if not isinstance(field, dict):
|
782
|
-
raise ValueError('missing or invalid serialization of field index')
|
783
|
-
if field.get('@T') != '+':
|
784
|
-
raise ValueError('unexpected edge type for field index')
|
785
|
-
data = field.get('@d', None)
|
786
|
-
if not isinstance(data, list):
|
787
|
-
raise ValueError('missing serialization of Any/Many contents')
|
788
|
-
f_index = MultiConstInt()
|
789
|
-
for element in data:
|
790
|
-
if element.get('@T') != '1':
|
791
|
-
raise ValueError('unexpected edge type for Any/Many element')
|
792
|
-
f_index.append(ConstInt._deserialize(element, seq_to_ob, links))
|
793
|
-
|
794
|
-
# Construct the BitRefs node.
|
795
|
-
node = BitRefs(f_index)
|
796
|
-
|
797
|
-
# Deserialize annotations.
|
798
|
-
for key, val in cbor.items():
|
799
|
-
if not (key.startswith('{') and key.endswith('}')):
|
800
|
-
continue
|
801
|
-
key = key[1:-1]
|
802
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
803
|
-
|
804
|
-
# Register node in sequence number lookup.
|
805
|
-
seq = cbor.get('@i', None)
|
806
|
-
if not isinstance(seq, int):
|
807
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
808
|
-
if seq in seq_to_ob:
|
809
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
810
|
-
seq_to_ob[seq] = node
|
811
|
-
|
812
|
-
return node
|
813
|
-
|
814
|
-
def _serialize(self, id_map):
|
815
|
-
"""Serializes this node to the Python primitive representation of its
|
816
|
-
CBOR serialization. The tree that the node belongs to must be
|
817
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
818
|
-
integers, to use for the sequence number representation of links."""
|
819
|
-
cbor = {'@i': id_map[id(self)], '@t': 'BitRefs'}
|
820
|
-
|
821
|
-
# Serialize the index field.
|
822
|
-
field = {'@T': '+'}
|
823
|
-
lst = []
|
824
|
-
for el in self._attr_index:
|
825
|
-
el = el._serialize(id_map)
|
826
|
-
el['@T'] = '1'
|
827
|
-
lst.append(el)
|
828
|
-
field['@d'] = lst
|
829
|
-
cbor['index'] = field
|
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 MultiBitRefs(_Multiple):
|
839
|
-
"""Wrapper for an edge with multiple BitRefs objects."""
|
840
|
-
|
841
|
-
_T = BitRefs
|
842
|
-
|
843
|
-
|
844
|
-
_typemap['BitRefs'] = BitRefs
|
845
|
-
|
846
|
-
class Constant(Node):
|
847
|
-
"""Represents a constant value."""
|
848
|
-
|
849
|
-
__slots__ = []
|
850
|
-
|
851
|
-
def __init__(self):
|
852
|
-
super().__init__()
|
853
|
-
|
854
|
-
@staticmethod
|
855
|
-
def _deserialize(cbor, seq_to_ob, links):
|
856
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
857
|
-
representation) into a node of this type. All (sub)nodes are added to
|
858
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
859
|
-
registered in the links list by means of a two-tuple of the setter
|
860
|
-
function for the link field and the sequence number of the target node.
|
861
|
-
"""
|
862
|
-
if not isinstance(cbor, dict):
|
863
|
-
raise TypeError('node description object must be a dict')
|
864
|
-
typ = cbor.get('@t', None)
|
865
|
-
if typ is None:
|
866
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
867
|
-
if typ == 'ConstBool':
|
868
|
-
return ConstBool._deserialize(cbor, seq_to_ob, links)
|
869
|
-
if typ == 'ConstAxis':
|
870
|
-
return ConstAxis._deserialize(cbor, seq_to_ob, links)
|
871
|
-
if typ == 'ConstInt':
|
872
|
-
return ConstInt._deserialize(cbor, seq_to_ob, links)
|
873
|
-
if typ == 'ConstReal':
|
874
|
-
return ConstReal._deserialize(cbor, seq_to_ob, links)
|
875
|
-
if typ == 'ConstComplex':
|
876
|
-
return ConstComplex._deserialize(cbor, seq_to_ob, links)
|
877
|
-
if typ == 'ConstRealMatrix':
|
878
|
-
return ConstRealMatrix._deserialize(cbor, seq_to_ob, links)
|
879
|
-
if typ == 'ConstComplexMatrix':
|
880
|
-
return ConstComplexMatrix._deserialize(cbor, seq_to_ob, links)
|
881
|
-
if typ == 'ConstString':
|
882
|
-
return ConstString._deserialize(cbor, seq_to_ob, links)
|
883
|
-
if typ == 'ConstJson':
|
884
|
-
return ConstJson._deserialize(cbor, seq_to_ob, links)
|
885
|
-
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
886
|
-
|
887
|
-
def _serialize(self, id_map):
|
888
|
-
"""Serializes this node to the Python primitive representation of its
|
889
|
-
CBOR serialization. The tree that the node belongs to must be
|
890
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
891
|
-
integers, to use for the sequence number representation of links."""
|
892
|
-
cbor = {'@i': id_map[id(self)], '@t': 'Constant'}
|
893
|
-
|
894
|
-
# Serialize annotations.
|
895
|
-
for key, val in self._annot.items():
|
896
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
897
|
-
|
898
|
-
return cbor
|
899
|
-
|
900
|
-
|
901
|
-
class MultiConstant(_Multiple):
|
902
|
-
"""Wrapper for an edge with multiple Constant objects."""
|
903
|
-
|
904
|
-
_T = Constant
|
905
|
-
|
906
|
-
|
907
|
-
_typemap['Constant'] = Constant
|
908
|
-
|
909
|
-
class ConstAxis(Constant):
|
910
|
-
"""Represents an axis value (x, y, or z)."""
|
911
|
-
|
912
|
-
__slots__ = [
|
913
|
-
'_attr_value',
|
914
|
-
]
|
915
|
-
|
916
|
-
def __init__(
|
917
|
-
self,
|
918
|
-
value=None,
|
919
|
-
):
|
920
|
-
super().__init__()
|
921
|
-
self.value = value
|
922
|
-
|
923
|
-
@property
|
924
|
-
def value(self):
|
925
|
-
"""The contained value."""
|
926
|
-
return self._attr_value
|
927
|
-
|
928
|
-
@value.setter
|
929
|
-
def value(self, val):
|
930
|
-
if val is None:
|
931
|
-
del self.value
|
932
|
-
return
|
933
|
-
if not isinstance(val, cqasm.v1x.primitives.Axis):
|
934
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
935
|
-
if isinstance(val, Node):
|
936
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Axis')
|
937
|
-
val = cqasm.v1x.primitives.Axis(val)
|
938
|
-
self._attr_value = val
|
939
|
-
|
940
|
-
@value.deleter
|
941
|
-
def value(self):
|
942
|
-
self._attr_value = cqasm.v1x.primitives.Axis()
|
943
|
-
|
944
|
-
def __eq__(self, other):
|
945
|
-
"""Equality operator. Ignores annotations!"""
|
946
|
-
if not isinstance(other, ConstAxis):
|
947
|
-
return False
|
948
|
-
if self.value != other.value:
|
949
|
-
return False
|
950
|
-
return True
|
951
|
-
|
952
|
-
def dump(self, indent=0, annotations=None, links=1):
|
953
|
-
"""Returns a debug representation of this tree as a multiline string.
|
954
|
-
indent is the number of double spaces prefixed before every line.
|
955
|
-
annotations, if specified, must be a set-like object containing the key
|
956
|
-
strings of the annotations that are to be printed. links specifies the
|
957
|
-
maximum link recursion depth."""
|
958
|
-
s = [' '*indent]
|
959
|
-
s.append('ConstAxis(')
|
960
|
-
if annotations is None:
|
961
|
-
annotations = []
|
962
|
-
for key in annotations:
|
963
|
-
if key in self:
|
964
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
965
|
-
s.append('\n')
|
966
|
-
indent += 1
|
967
|
-
s.append(' '*indent)
|
968
|
-
s.append('value: ')
|
969
|
-
s.append(str(self.value) + '\n')
|
970
|
-
indent -= 1
|
971
|
-
s.append(' '*indent)
|
972
|
-
s.append(')')
|
973
|
-
return ''.join(s)
|
974
|
-
|
975
|
-
__str__ = dump
|
976
|
-
__repr__ = dump
|
977
|
-
|
978
|
-
def find_reachable(self, id_map=None):
|
979
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
980
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
981
|
-
specified, found nodes are appended to it."""
|
982
|
-
if id_map is None:
|
983
|
-
id_map = {}
|
984
|
-
if id(self) in id_map:
|
985
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
986
|
-
id_map[id(self)] = len(id_map)
|
987
|
-
return id_map
|
988
|
-
|
989
|
-
def check_complete(self, id_map=None):
|
990
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
991
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
992
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
993
|
-
id() codes to tree indices for all reachable nodes."""
|
994
|
-
if id_map is None:
|
995
|
-
id_map = self.find_reachable()
|
996
|
-
|
997
|
-
def copy(self):
|
998
|
-
"""Returns a shallow copy of this node."""
|
999
|
-
return ConstAxis(
|
1000
|
-
value=self._attr_value
|
1001
|
-
)
|
1002
|
-
|
1003
|
-
def clone(self):
|
1004
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1005
|
-
deficiencies with links included; that is, links always point to the
|
1006
|
-
original tree. If you're not cloning a subtree in a context where this
|
1007
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
1008
|
-
the stdlib instead, which should copy links correctly."""
|
1009
|
-
return ConstAxis(
|
1010
|
-
value=_cloned(self._attr_value)
|
1011
|
-
)
|
1012
|
-
|
1013
|
-
@staticmethod
|
1014
|
-
def _deserialize(cbor, seq_to_ob, links):
|
1015
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
1016
|
-
representation) into a node of this type. All (sub)nodes are added to
|
1017
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1018
|
-
registered in the links list by means of a two-tuple of the setter
|
1019
|
-
function for the link field and the sequence number of the target node.
|
1020
|
-
"""
|
1021
|
-
if not isinstance(cbor, dict):
|
1022
|
-
raise TypeError('node description object must be a dict')
|
1023
|
-
typ = cbor.get('@t', None)
|
1024
|
-
if typ is None:
|
1025
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
1026
|
-
if typ != 'ConstAxis':
|
1027
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstAxis')
|
1028
|
-
|
1029
|
-
# Deserialize the value field.
|
1030
|
-
field = cbor.get('value', None)
|
1031
|
-
if not isinstance(field, dict):
|
1032
|
-
raise ValueError('missing or invalid serialization of field value')
|
1033
|
-
if hasattr(cqasm.v1x.primitives.Axis, 'deserialize_cbor'):
|
1034
|
-
f_value = cqasm.v1x.primitives.Axis.deserialize_cbor(field)
|
1035
|
-
else:
|
1036
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Axis, field)
|
1037
|
-
|
1038
|
-
# Construct the ConstAxis node.
|
1039
|
-
node = ConstAxis(f_value)
|
1040
|
-
|
1041
|
-
# Deserialize annotations.
|
1042
|
-
for key, val in cbor.items():
|
1043
|
-
if not (key.startswith('{') and key.endswith('}')):
|
1044
|
-
continue
|
1045
|
-
key = key[1:-1]
|
1046
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
1047
|
-
|
1048
|
-
# Register node in sequence number lookup.
|
1049
|
-
seq = cbor.get('@i', None)
|
1050
|
-
if not isinstance(seq, int):
|
1051
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1052
|
-
if seq in seq_to_ob:
|
1053
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
1054
|
-
seq_to_ob[seq] = node
|
1055
|
-
|
1056
|
-
return node
|
1057
|
-
|
1058
|
-
def _serialize(self, id_map):
|
1059
|
-
"""Serializes this node to the Python primitive representation of its
|
1060
|
-
CBOR serialization. The tree that the node belongs to must be
|
1061
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
1062
|
-
integers, to use for the sequence number representation of links."""
|
1063
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstAxis'}
|
1064
|
-
|
1065
|
-
# Serialize the value field.
|
1066
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
1067
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
1068
|
-
else:
|
1069
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Axis, self._attr_value)
|
1070
|
-
|
1071
|
-
# Serialize annotations.
|
1072
|
-
for key, val in self._annot.items():
|
1073
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
1074
|
-
|
1075
|
-
return cbor
|
1076
|
-
|
1077
|
-
|
1078
|
-
class MultiConstAxis(_Multiple):
|
1079
|
-
"""Wrapper for an edge with multiple ConstAxis objects."""
|
1080
|
-
|
1081
|
-
_T = ConstAxis
|
1082
|
-
|
1083
|
-
|
1084
|
-
_typemap['ConstAxis'] = ConstAxis
|
1085
|
-
|
1086
|
-
class ConstBool(Constant):
|
1087
|
-
"""Represents a value of type bool."""
|
1088
|
-
|
1089
|
-
__slots__ = [
|
1090
|
-
'_attr_value',
|
1091
|
-
]
|
1092
|
-
|
1093
|
-
def __init__(
|
1094
|
-
self,
|
1095
|
-
value=None,
|
1096
|
-
):
|
1097
|
-
super().__init__()
|
1098
|
-
self.value = value
|
1099
|
-
|
1100
|
-
@property
|
1101
|
-
def value(self):
|
1102
|
-
"""The contained value."""
|
1103
|
-
return self._attr_value
|
1104
|
-
|
1105
|
-
@value.setter
|
1106
|
-
def value(self, val):
|
1107
|
-
if val is None:
|
1108
|
-
del self.value
|
1109
|
-
return
|
1110
|
-
if not isinstance(val, cqasm.v1x.primitives.Bool):
|
1111
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1112
|
-
if isinstance(val, Node):
|
1113
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Bool')
|
1114
|
-
val = cqasm.v1x.primitives.Bool(val)
|
1115
|
-
self._attr_value = val
|
1116
|
-
|
1117
|
-
@value.deleter
|
1118
|
-
def value(self):
|
1119
|
-
self._attr_value = cqasm.v1x.primitives.Bool()
|
1120
|
-
|
1121
|
-
def __eq__(self, other):
|
1122
|
-
"""Equality operator. Ignores annotations!"""
|
1123
|
-
if not isinstance(other, ConstBool):
|
1124
|
-
return False
|
1125
|
-
if self.value != other.value:
|
1126
|
-
return False
|
1127
|
-
return True
|
1128
|
-
|
1129
|
-
def dump(self, indent=0, annotations=None, links=1):
|
1130
|
-
"""Returns a debug representation of this tree as a multiline string.
|
1131
|
-
indent is the number of double spaces prefixed before every line.
|
1132
|
-
annotations, if specified, must be a set-like object containing the key
|
1133
|
-
strings of the annotations that are to be printed. links specifies the
|
1134
|
-
maximum link recursion depth."""
|
1135
|
-
s = [' '*indent]
|
1136
|
-
s.append('ConstBool(')
|
1137
|
-
if annotations is None:
|
1138
|
-
annotations = []
|
1139
|
-
for key in annotations:
|
1140
|
-
if key in self:
|
1141
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
1142
|
-
s.append('\n')
|
1143
|
-
indent += 1
|
1144
|
-
s.append(' '*indent)
|
1145
|
-
s.append('value: ')
|
1146
|
-
s.append(str(self.value) + '\n')
|
1147
|
-
indent -= 1
|
1148
|
-
s.append(' '*indent)
|
1149
|
-
s.append(')')
|
1150
|
-
return ''.join(s)
|
1151
|
-
|
1152
|
-
__str__ = dump
|
1153
|
-
__repr__ = dump
|
1154
|
-
|
1155
|
-
def find_reachable(self, id_map=None):
|
1156
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
1157
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
1158
|
-
specified, found nodes are appended to it."""
|
1159
|
-
if id_map is None:
|
1160
|
-
id_map = {}
|
1161
|
-
if id(self) in id_map:
|
1162
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1163
|
-
id_map[id(self)] = len(id_map)
|
1164
|
-
return id_map
|
1165
|
-
|
1166
|
-
def check_complete(self, id_map=None):
|
1167
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
1168
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
1169
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
1170
|
-
id() codes to tree indices for all reachable nodes."""
|
1171
|
-
if id_map is None:
|
1172
|
-
id_map = self.find_reachable()
|
1173
|
-
|
1174
|
-
def copy(self):
|
1175
|
-
"""Returns a shallow copy of this node."""
|
1176
|
-
return ConstBool(
|
1177
|
-
value=self._attr_value
|
1178
|
-
)
|
1179
|
-
|
1180
|
-
def clone(self):
|
1181
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1182
|
-
deficiencies with links included; that is, links always point to the
|
1183
|
-
original tree. If you're not cloning a subtree in a context where this
|
1184
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
1185
|
-
the stdlib instead, which should copy links correctly."""
|
1186
|
-
return ConstBool(
|
1187
|
-
value=_cloned(self._attr_value)
|
1188
|
-
)
|
1189
|
-
|
1190
|
-
@staticmethod
|
1191
|
-
def _deserialize(cbor, seq_to_ob, links):
|
1192
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
1193
|
-
representation) into a node of this type. All (sub)nodes are added to
|
1194
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1195
|
-
registered in the links list by means of a two-tuple of the setter
|
1196
|
-
function for the link field and the sequence number of the target node.
|
1197
|
-
"""
|
1198
|
-
if not isinstance(cbor, dict):
|
1199
|
-
raise TypeError('node description object must be a dict')
|
1200
|
-
typ = cbor.get('@t', None)
|
1201
|
-
if typ is None:
|
1202
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
1203
|
-
if typ != 'ConstBool':
|
1204
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstBool')
|
1205
|
-
|
1206
|
-
# Deserialize the value field.
|
1207
|
-
field = cbor.get('value', None)
|
1208
|
-
if not isinstance(field, dict):
|
1209
|
-
raise ValueError('missing or invalid serialization of field value')
|
1210
|
-
if hasattr(cqasm.v1x.primitives.Bool, 'deserialize_cbor'):
|
1211
|
-
f_value = cqasm.v1x.primitives.Bool.deserialize_cbor(field)
|
1212
|
-
else:
|
1213
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Bool, field)
|
1214
|
-
|
1215
|
-
# Construct the ConstBool node.
|
1216
|
-
node = ConstBool(f_value)
|
1217
|
-
|
1218
|
-
# Deserialize annotations.
|
1219
|
-
for key, val in cbor.items():
|
1220
|
-
if not (key.startswith('{') and key.endswith('}')):
|
1221
|
-
continue
|
1222
|
-
key = key[1:-1]
|
1223
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
1224
|
-
|
1225
|
-
# Register node in sequence number lookup.
|
1226
|
-
seq = cbor.get('@i', None)
|
1227
|
-
if not isinstance(seq, int):
|
1228
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1229
|
-
if seq in seq_to_ob:
|
1230
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
1231
|
-
seq_to_ob[seq] = node
|
1232
|
-
|
1233
|
-
return node
|
1234
|
-
|
1235
|
-
def _serialize(self, id_map):
|
1236
|
-
"""Serializes this node to the Python primitive representation of its
|
1237
|
-
CBOR serialization. The tree that the node belongs to must be
|
1238
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
1239
|
-
integers, to use for the sequence number representation of links."""
|
1240
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstBool'}
|
1241
|
-
|
1242
|
-
# Serialize the value field.
|
1243
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
1244
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
1245
|
-
else:
|
1246
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Bool, self._attr_value)
|
1247
|
-
|
1248
|
-
# Serialize annotations.
|
1249
|
-
for key, val in self._annot.items():
|
1250
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
1251
|
-
|
1252
|
-
return cbor
|
1253
|
-
|
1254
|
-
|
1255
|
-
class MultiConstBool(_Multiple):
|
1256
|
-
"""Wrapper for an edge with multiple ConstBool objects."""
|
1257
|
-
|
1258
|
-
_T = ConstBool
|
1259
|
-
|
1260
|
-
|
1261
|
-
_typemap['ConstBool'] = ConstBool
|
1262
|
-
|
1263
|
-
class ConstComplex(Constant):
|
1264
|
-
"""Represents a value of type complex."""
|
1265
|
-
|
1266
|
-
__slots__ = [
|
1267
|
-
'_attr_value',
|
1268
|
-
]
|
1269
|
-
|
1270
|
-
def __init__(
|
1271
|
-
self,
|
1272
|
-
value=None,
|
1273
|
-
):
|
1274
|
-
super().__init__()
|
1275
|
-
self.value = value
|
1276
|
-
|
1277
|
-
@property
|
1278
|
-
def value(self):
|
1279
|
-
"""The contained value."""
|
1280
|
-
return self._attr_value
|
1281
|
-
|
1282
|
-
@value.setter
|
1283
|
-
def value(self, val):
|
1284
|
-
if val is None:
|
1285
|
-
del self.value
|
1286
|
-
return
|
1287
|
-
if not isinstance(val, cqasm.v1x.primitives.Complex):
|
1288
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1289
|
-
if isinstance(val, Node):
|
1290
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Complex')
|
1291
|
-
val = cqasm.v1x.primitives.Complex(val)
|
1292
|
-
self._attr_value = val
|
1293
|
-
|
1294
|
-
@value.deleter
|
1295
|
-
def value(self):
|
1296
|
-
self._attr_value = cqasm.v1x.primitives.Complex()
|
1297
|
-
|
1298
|
-
def __eq__(self, other):
|
1299
|
-
"""Equality operator. Ignores annotations!"""
|
1300
|
-
if not isinstance(other, ConstComplex):
|
1301
|
-
return False
|
1302
|
-
if self.value != other.value:
|
1303
|
-
return False
|
1304
|
-
return True
|
1305
|
-
|
1306
|
-
def dump(self, indent=0, annotations=None, links=1):
|
1307
|
-
"""Returns a debug representation of this tree as a multiline string.
|
1308
|
-
indent is the number of double spaces prefixed before every line.
|
1309
|
-
annotations, if specified, must be a set-like object containing the key
|
1310
|
-
strings of the annotations that are to be printed. links specifies the
|
1311
|
-
maximum link recursion depth."""
|
1312
|
-
s = [' '*indent]
|
1313
|
-
s.append('ConstComplex(')
|
1314
|
-
if annotations is None:
|
1315
|
-
annotations = []
|
1316
|
-
for key in annotations:
|
1317
|
-
if key in self:
|
1318
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
1319
|
-
s.append('\n')
|
1320
|
-
indent += 1
|
1321
|
-
s.append(' '*indent)
|
1322
|
-
s.append('value: ')
|
1323
|
-
s.append(str(self.value) + '\n')
|
1324
|
-
indent -= 1
|
1325
|
-
s.append(' '*indent)
|
1326
|
-
s.append(')')
|
1327
|
-
return ''.join(s)
|
1328
|
-
|
1329
|
-
__str__ = dump
|
1330
|
-
__repr__ = dump
|
1331
|
-
|
1332
|
-
def find_reachable(self, id_map=None):
|
1333
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
1334
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
1335
|
-
specified, found nodes are appended to it."""
|
1336
|
-
if id_map is None:
|
1337
|
-
id_map = {}
|
1338
|
-
if id(self) in id_map:
|
1339
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1340
|
-
id_map[id(self)] = len(id_map)
|
1341
|
-
return id_map
|
1342
|
-
|
1343
|
-
def check_complete(self, id_map=None):
|
1344
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
1345
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
1346
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
1347
|
-
id() codes to tree indices for all reachable nodes."""
|
1348
|
-
if id_map is None:
|
1349
|
-
id_map = self.find_reachable()
|
1350
|
-
|
1351
|
-
def copy(self):
|
1352
|
-
"""Returns a shallow copy of this node."""
|
1353
|
-
return ConstComplex(
|
1354
|
-
value=self._attr_value
|
1355
|
-
)
|
1356
|
-
|
1357
|
-
def clone(self):
|
1358
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1359
|
-
deficiencies with links included; that is, links always point to the
|
1360
|
-
original tree. If you're not cloning a subtree in a context where this
|
1361
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
1362
|
-
the stdlib instead, which should copy links correctly."""
|
1363
|
-
return ConstComplex(
|
1364
|
-
value=_cloned(self._attr_value)
|
1365
|
-
)
|
1366
|
-
|
1367
|
-
@staticmethod
|
1368
|
-
def _deserialize(cbor, seq_to_ob, links):
|
1369
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
1370
|
-
representation) into a node of this type. All (sub)nodes are added to
|
1371
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1372
|
-
registered in the links list by means of a two-tuple of the setter
|
1373
|
-
function for the link field and the sequence number of the target node.
|
1374
|
-
"""
|
1375
|
-
if not isinstance(cbor, dict):
|
1376
|
-
raise TypeError('node description object must be a dict')
|
1377
|
-
typ = cbor.get('@t', None)
|
1378
|
-
if typ is None:
|
1379
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
1380
|
-
if typ != 'ConstComplex':
|
1381
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstComplex')
|
1382
|
-
|
1383
|
-
# Deserialize the value field.
|
1384
|
-
field = cbor.get('value', None)
|
1385
|
-
if not isinstance(field, dict):
|
1386
|
-
raise ValueError('missing or invalid serialization of field value')
|
1387
|
-
if hasattr(cqasm.v1x.primitives.Complex, 'deserialize_cbor'):
|
1388
|
-
f_value = cqasm.v1x.primitives.Complex.deserialize_cbor(field)
|
1389
|
-
else:
|
1390
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Complex, field)
|
1391
|
-
|
1392
|
-
# Construct the ConstComplex node.
|
1393
|
-
node = ConstComplex(f_value)
|
1394
|
-
|
1395
|
-
# Deserialize annotations.
|
1396
|
-
for key, val in cbor.items():
|
1397
|
-
if not (key.startswith('{') and key.endswith('}')):
|
1398
|
-
continue
|
1399
|
-
key = key[1:-1]
|
1400
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
1401
|
-
|
1402
|
-
# Register node in sequence number lookup.
|
1403
|
-
seq = cbor.get('@i', None)
|
1404
|
-
if not isinstance(seq, int):
|
1405
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1406
|
-
if seq in seq_to_ob:
|
1407
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
1408
|
-
seq_to_ob[seq] = node
|
1409
|
-
|
1410
|
-
return node
|
1411
|
-
|
1412
|
-
def _serialize(self, id_map):
|
1413
|
-
"""Serializes this node to the Python primitive representation of its
|
1414
|
-
CBOR serialization. The tree that the node belongs to must be
|
1415
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
1416
|
-
integers, to use for the sequence number representation of links."""
|
1417
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstComplex'}
|
1418
|
-
|
1419
|
-
# Serialize the value field.
|
1420
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
1421
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
1422
|
-
else:
|
1423
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Complex, self._attr_value)
|
1424
|
-
|
1425
|
-
# Serialize annotations.
|
1426
|
-
for key, val in self._annot.items():
|
1427
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
1428
|
-
|
1429
|
-
return cbor
|
1430
|
-
|
1431
|
-
|
1432
|
-
class MultiConstComplex(_Multiple):
|
1433
|
-
"""Wrapper for an edge with multiple ConstComplex objects."""
|
1434
|
-
|
1435
|
-
_T = ConstComplex
|
1436
|
-
|
1437
|
-
|
1438
|
-
_typemap['ConstComplex'] = ConstComplex
|
1439
|
-
|
1440
|
-
class ConstComplexMatrix(Constant):
|
1441
|
-
"""Represents a value of type complex_matrix."""
|
1442
|
-
|
1443
|
-
__slots__ = [
|
1444
|
-
'_attr_value',
|
1445
|
-
]
|
1446
|
-
|
1447
|
-
def __init__(
|
1448
|
-
self,
|
1449
|
-
value=None,
|
1450
|
-
):
|
1451
|
-
super().__init__()
|
1452
|
-
self.value = value
|
1453
|
-
|
1454
|
-
@property
|
1455
|
-
def value(self):
|
1456
|
-
"""The contained value."""
|
1457
|
-
return self._attr_value
|
1458
|
-
|
1459
|
-
@value.setter
|
1460
|
-
def value(self, val):
|
1461
|
-
if val is None:
|
1462
|
-
del self.value
|
1463
|
-
return
|
1464
|
-
if not isinstance(val, cqasm.v1x.primitives.CMatrix):
|
1465
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1466
|
-
if isinstance(val, Node):
|
1467
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.CMatrix')
|
1468
|
-
val = cqasm.v1x.primitives.CMatrix(val)
|
1469
|
-
self._attr_value = val
|
1470
|
-
|
1471
|
-
@value.deleter
|
1472
|
-
def value(self):
|
1473
|
-
self._attr_value = cqasm.v1x.primitives.CMatrix()
|
1474
|
-
|
1475
|
-
def __eq__(self, other):
|
1476
|
-
"""Equality operator. Ignores annotations!"""
|
1477
|
-
if not isinstance(other, ConstComplexMatrix):
|
1478
|
-
return False
|
1479
|
-
if self.value != other.value:
|
1480
|
-
return False
|
1481
|
-
return True
|
1482
|
-
|
1483
|
-
def dump(self, indent=0, annotations=None, links=1):
|
1484
|
-
"""Returns a debug representation of this tree as a multiline string.
|
1485
|
-
indent is the number of double spaces prefixed before every line.
|
1486
|
-
annotations, if specified, must be a set-like object containing the key
|
1487
|
-
strings of the annotations that are to be printed. links specifies the
|
1488
|
-
maximum link recursion depth."""
|
1489
|
-
s = [' '*indent]
|
1490
|
-
s.append('ConstComplexMatrix(')
|
1491
|
-
if annotations is None:
|
1492
|
-
annotations = []
|
1493
|
-
for key in annotations:
|
1494
|
-
if key in self:
|
1495
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
1496
|
-
s.append('\n')
|
1497
|
-
indent += 1
|
1498
|
-
s.append(' '*indent)
|
1499
|
-
s.append('value: ')
|
1500
|
-
s.append(str(self.value) + '\n')
|
1501
|
-
indent -= 1
|
1502
|
-
s.append(' '*indent)
|
1503
|
-
s.append(')')
|
1504
|
-
return ''.join(s)
|
1505
|
-
|
1506
|
-
__str__ = dump
|
1507
|
-
__repr__ = dump
|
1508
|
-
|
1509
|
-
def find_reachable(self, id_map=None):
|
1510
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
1511
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
1512
|
-
specified, found nodes are appended to it."""
|
1513
|
-
if id_map is None:
|
1514
|
-
id_map = {}
|
1515
|
-
if id(self) in id_map:
|
1516
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1517
|
-
id_map[id(self)] = len(id_map)
|
1518
|
-
return id_map
|
1519
|
-
|
1520
|
-
def check_complete(self, id_map=None):
|
1521
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
1522
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
1523
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
1524
|
-
id() codes to tree indices for all reachable nodes."""
|
1525
|
-
if id_map is None:
|
1526
|
-
id_map = self.find_reachable()
|
1527
|
-
|
1528
|
-
def copy(self):
|
1529
|
-
"""Returns a shallow copy of this node."""
|
1530
|
-
return ConstComplexMatrix(
|
1531
|
-
value=self._attr_value
|
1532
|
-
)
|
1533
|
-
|
1534
|
-
def clone(self):
|
1535
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1536
|
-
deficiencies with links included; that is, links always point to the
|
1537
|
-
original tree. If you're not cloning a subtree in a context where this
|
1538
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
1539
|
-
the stdlib instead, which should copy links correctly."""
|
1540
|
-
return ConstComplexMatrix(
|
1541
|
-
value=_cloned(self._attr_value)
|
1542
|
-
)
|
1543
|
-
|
1544
|
-
@staticmethod
|
1545
|
-
def _deserialize(cbor, seq_to_ob, links):
|
1546
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
1547
|
-
representation) into a node of this type. All (sub)nodes are added to
|
1548
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1549
|
-
registered in the links list by means of a two-tuple of the setter
|
1550
|
-
function for the link field and the sequence number of the target node.
|
1551
|
-
"""
|
1552
|
-
if not isinstance(cbor, dict):
|
1553
|
-
raise TypeError('node description object must be a dict')
|
1554
|
-
typ = cbor.get('@t', None)
|
1555
|
-
if typ is None:
|
1556
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
1557
|
-
if typ != 'ConstComplexMatrix':
|
1558
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstComplexMatrix')
|
1559
|
-
|
1560
|
-
# Deserialize the value field.
|
1561
|
-
field = cbor.get('value', None)
|
1562
|
-
if not isinstance(field, dict):
|
1563
|
-
raise ValueError('missing or invalid serialization of field value')
|
1564
|
-
if hasattr(cqasm.v1x.primitives.CMatrix, 'deserialize_cbor'):
|
1565
|
-
f_value = cqasm.v1x.primitives.CMatrix.deserialize_cbor(field)
|
1566
|
-
else:
|
1567
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.CMatrix, field)
|
1568
|
-
|
1569
|
-
# Construct the ConstComplexMatrix node.
|
1570
|
-
node = ConstComplexMatrix(f_value)
|
1571
|
-
|
1572
|
-
# Deserialize annotations.
|
1573
|
-
for key, val in cbor.items():
|
1574
|
-
if not (key.startswith('{') and key.endswith('}')):
|
1575
|
-
continue
|
1576
|
-
key = key[1:-1]
|
1577
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
1578
|
-
|
1579
|
-
# Register node in sequence number lookup.
|
1580
|
-
seq = cbor.get('@i', None)
|
1581
|
-
if not isinstance(seq, int):
|
1582
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1583
|
-
if seq in seq_to_ob:
|
1584
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
1585
|
-
seq_to_ob[seq] = node
|
1586
|
-
|
1587
|
-
return node
|
1588
|
-
|
1589
|
-
def _serialize(self, id_map):
|
1590
|
-
"""Serializes this node to the Python primitive representation of its
|
1591
|
-
CBOR serialization. The tree that the node belongs to must be
|
1592
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
1593
|
-
integers, to use for the sequence number representation of links."""
|
1594
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstComplexMatrix'}
|
1595
|
-
|
1596
|
-
# Serialize the value field.
|
1597
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
1598
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
1599
|
-
else:
|
1600
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.CMatrix, self._attr_value)
|
1601
|
-
|
1602
|
-
# Serialize annotations.
|
1603
|
-
for key, val in self._annot.items():
|
1604
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
1605
|
-
|
1606
|
-
return cbor
|
1607
|
-
|
1608
|
-
|
1609
|
-
class MultiConstComplexMatrix(_Multiple):
|
1610
|
-
"""Wrapper for an edge with multiple ConstComplexMatrix objects."""
|
1611
|
-
|
1612
|
-
_T = ConstComplexMatrix
|
1613
|
-
|
1614
|
-
|
1615
|
-
_typemap['ConstComplexMatrix'] = ConstComplexMatrix
|
1616
|
-
|
1617
|
-
class ConstInt(Constant):
|
1618
|
-
"""Represents a value of type int."""
|
1619
|
-
|
1620
|
-
__slots__ = [
|
1621
|
-
'_attr_value',
|
1622
|
-
]
|
1623
|
-
|
1624
|
-
def __init__(
|
1625
|
-
self,
|
1626
|
-
value=None,
|
1627
|
-
):
|
1628
|
-
super().__init__()
|
1629
|
-
self.value = value
|
1630
|
-
|
1631
|
-
@property
|
1632
|
-
def value(self):
|
1633
|
-
"""The contained value."""
|
1634
|
-
return self._attr_value
|
1635
|
-
|
1636
|
-
@value.setter
|
1637
|
-
def value(self, val):
|
1638
|
-
if val is None:
|
1639
|
-
del self.value
|
1640
|
-
return
|
1641
|
-
if not isinstance(val, cqasm.v1x.primitives.Int):
|
1642
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1643
|
-
if isinstance(val, Node):
|
1644
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Int')
|
1645
|
-
val = cqasm.v1x.primitives.Int(val)
|
1646
|
-
self._attr_value = val
|
1647
|
-
|
1648
|
-
@value.deleter
|
1649
|
-
def value(self):
|
1650
|
-
self._attr_value = cqasm.v1x.primitives.Int()
|
1651
|
-
|
1652
|
-
def __eq__(self, other):
|
1653
|
-
"""Equality operator. Ignores annotations!"""
|
1654
|
-
if not isinstance(other, ConstInt):
|
1655
|
-
return False
|
1656
|
-
if self.value != other.value:
|
1657
|
-
return False
|
1658
|
-
return True
|
1659
|
-
|
1660
|
-
def dump(self, indent=0, annotations=None, links=1):
|
1661
|
-
"""Returns a debug representation of this tree as a multiline string.
|
1662
|
-
indent is the number of double spaces prefixed before every line.
|
1663
|
-
annotations, if specified, must be a set-like object containing the key
|
1664
|
-
strings of the annotations that are to be printed. links specifies the
|
1665
|
-
maximum link recursion depth."""
|
1666
|
-
s = [' '*indent]
|
1667
|
-
s.append('ConstInt(')
|
1668
|
-
if annotations is None:
|
1669
|
-
annotations = []
|
1670
|
-
for key in annotations:
|
1671
|
-
if key in self:
|
1672
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
1673
|
-
s.append('\n')
|
1674
|
-
indent += 1
|
1675
|
-
s.append(' '*indent)
|
1676
|
-
s.append('value: ')
|
1677
|
-
s.append(str(self.value) + '\n')
|
1678
|
-
indent -= 1
|
1679
|
-
s.append(' '*indent)
|
1680
|
-
s.append(')')
|
1681
|
-
return ''.join(s)
|
1682
|
-
|
1683
|
-
__str__ = dump
|
1684
|
-
__repr__ = dump
|
1685
|
-
|
1686
|
-
def find_reachable(self, id_map=None):
|
1687
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
1688
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
1689
|
-
specified, found nodes are appended to it."""
|
1690
|
-
if id_map is None:
|
1691
|
-
id_map = {}
|
1692
|
-
if id(self) in id_map:
|
1693
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1694
|
-
id_map[id(self)] = len(id_map)
|
1695
|
-
return id_map
|
1696
|
-
|
1697
|
-
def check_complete(self, id_map=None):
|
1698
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
1699
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
1700
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
1701
|
-
id() codes to tree indices for all reachable nodes."""
|
1702
|
-
if id_map is None:
|
1703
|
-
id_map = self.find_reachable()
|
1704
|
-
|
1705
|
-
def copy(self):
|
1706
|
-
"""Returns a shallow copy of this node."""
|
1707
|
-
return ConstInt(
|
1708
|
-
value=self._attr_value
|
1709
|
-
)
|
1710
|
-
|
1711
|
-
def clone(self):
|
1712
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1713
|
-
deficiencies with links included; that is, links always point to the
|
1714
|
-
original tree. If you're not cloning a subtree in a context where this
|
1715
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
1716
|
-
the stdlib instead, which should copy links correctly."""
|
1717
|
-
return ConstInt(
|
1718
|
-
value=_cloned(self._attr_value)
|
1719
|
-
)
|
1720
|
-
|
1721
|
-
@staticmethod
|
1722
|
-
def _deserialize(cbor, seq_to_ob, links):
|
1723
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
1724
|
-
representation) into a node of this type. All (sub)nodes are added to
|
1725
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1726
|
-
registered in the links list by means of a two-tuple of the setter
|
1727
|
-
function for the link field and the sequence number of the target node.
|
1728
|
-
"""
|
1729
|
-
if not isinstance(cbor, dict):
|
1730
|
-
raise TypeError('node description object must be a dict')
|
1731
|
-
typ = cbor.get('@t', None)
|
1732
|
-
if typ is None:
|
1733
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
1734
|
-
if typ != 'ConstInt':
|
1735
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstInt')
|
1736
|
-
|
1737
|
-
# Deserialize the value field.
|
1738
|
-
field = cbor.get('value', None)
|
1739
|
-
if not isinstance(field, dict):
|
1740
|
-
raise ValueError('missing or invalid serialization of field value')
|
1741
|
-
if hasattr(cqasm.v1x.primitives.Int, 'deserialize_cbor'):
|
1742
|
-
f_value = cqasm.v1x.primitives.Int.deserialize_cbor(field)
|
1743
|
-
else:
|
1744
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Int, field)
|
1745
|
-
|
1746
|
-
# Construct the ConstInt node.
|
1747
|
-
node = ConstInt(f_value)
|
1748
|
-
|
1749
|
-
# Deserialize annotations.
|
1750
|
-
for key, val in cbor.items():
|
1751
|
-
if not (key.startswith('{') and key.endswith('}')):
|
1752
|
-
continue
|
1753
|
-
key = key[1:-1]
|
1754
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
1755
|
-
|
1756
|
-
# Register node in sequence number lookup.
|
1757
|
-
seq = cbor.get('@i', None)
|
1758
|
-
if not isinstance(seq, int):
|
1759
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1760
|
-
if seq in seq_to_ob:
|
1761
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
1762
|
-
seq_to_ob[seq] = node
|
1763
|
-
|
1764
|
-
return node
|
1765
|
-
|
1766
|
-
def _serialize(self, id_map):
|
1767
|
-
"""Serializes this node to the Python primitive representation of its
|
1768
|
-
CBOR serialization. The tree that the node belongs to must be
|
1769
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
1770
|
-
integers, to use for the sequence number representation of links."""
|
1771
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstInt'}
|
1772
|
-
|
1773
|
-
# Serialize the value field.
|
1774
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
1775
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
1776
|
-
else:
|
1777
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Int, self._attr_value)
|
1778
|
-
|
1779
|
-
# Serialize annotations.
|
1780
|
-
for key, val in self._annot.items():
|
1781
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
1782
|
-
|
1783
|
-
return cbor
|
1784
|
-
|
1785
|
-
|
1786
|
-
class MultiConstInt(_Multiple):
|
1787
|
-
"""Wrapper for an edge with multiple ConstInt objects."""
|
1788
|
-
|
1789
|
-
_T = ConstInt
|
1790
|
-
|
1791
|
-
|
1792
|
-
_typemap['ConstInt'] = ConstInt
|
1793
|
-
|
1794
|
-
class ConstJson(Constant):
|
1795
|
-
"""Represents a value of type json."""
|
1796
|
-
|
1797
|
-
__slots__ = [
|
1798
|
-
'_attr_value',
|
1799
|
-
]
|
1800
|
-
|
1801
|
-
def __init__(
|
1802
|
-
self,
|
1803
|
-
value=None,
|
1804
|
-
):
|
1805
|
-
super().__init__()
|
1806
|
-
self.value = value
|
1807
|
-
|
1808
|
-
@property
|
1809
|
-
def value(self):
|
1810
|
-
"""The contained value."""
|
1811
|
-
return self._attr_value
|
1812
|
-
|
1813
|
-
@value.setter
|
1814
|
-
def value(self, val):
|
1815
|
-
if val is None:
|
1816
|
-
del self.value
|
1817
|
-
return
|
1818
|
-
if not isinstance(val, cqasm.v1x.primitives.Str):
|
1819
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1820
|
-
if isinstance(val, Node):
|
1821
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Str')
|
1822
|
-
val = cqasm.v1x.primitives.Str(val)
|
1823
|
-
self._attr_value = val
|
1824
|
-
|
1825
|
-
@value.deleter
|
1826
|
-
def value(self):
|
1827
|
-
self._attr_value = cqasm.v1x.primitives.Str()
|
1828
|
-
|
1829
|
-
def __eq__(self, other):
|
1830
|
-
"""Equality operator. Ignores annotations!"""
|
1831
|
-
if not isinstance(other, ConstJson):
|
1832
|
-
return False
|
1833
|
-
if self.value != other.value:
|
1834
|
-
return False
|
1835
|
-
return True
|
1836
|
-
|
1837
|
-
def dump(self, indent=0, annotations=None, links=1):
|
1838
|
-
"""Returns a debug representation of this tree as a multiline string.
|
1839
|
-
indent is the number of double spaces prefixed before every line.
|
1840
|
-
annotations, if specified, must be a set-like object containing the key
|
1841
|
-
strings of the annotations that are to be printed. links specifies the
|
1842
|
-
maximum link recursion depth."""
|
1843
|
-
s = [' '*indent]
|
1844
|
-
s.append('ConstJson(')
|
1845
|
-
if annotations is None:
|
1846
|
-
annotations = []
|
1847
|
-
for key in annotations:
|
1848
|
-
if key in self:
|
1849
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
1850
|
-
s.append('\n')
|
1851
|
-
indent += 1
|
1852
|
-
s.append(' '*indent)
|
1853
|
-
s.append('value: ')
|
1854
|
-
s.append(str(self.value) + '\n')
|
1855
|
-
indent -= 1
|
1856
|
-
s.append(' '*indent)
|
1857
|
-
s.append(')')
|
1858
|
-
return ''.join(s)
|
1859
|
-
|
1860
|
-
__str__ = dump
|
1861
|
-
__repr__ = dump
|
1862
|
-
|
1863
|
-
def find_reachable(self, id_map=None):
|
1864
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
1865
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
1866
|
-
specified, found nodes are appended to it."""
|
1867
|
-
if id_map is None:
|
1868
|
-
id_map = {}
|
1869
|
-
if id(self) in id_map:
|
1870
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
1871
|
-
id_map[id(self)] = len(id_map)
|
1872
|
-
return id_map
|
1873
|
-
|
1874
|
-
def check_complete(self, id_map=None):
|
1875
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
1876
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
1877
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
1878
|
-
id() codes to tree indices for all reachable nodes."""
|
1879
|
-
if id_map is None:
|
1880
|
-
id_map = self.find_reachable()
|
1881
|
-
|
1882
|
-
def copy(self):
|
1883
|
-
"""Returns a shallow copy of this node."""
|
1884
|
-
return ConstJson(
|
1885
|
-
value=self._attr_value
|
1886
|
-
)
|
1887
|
-
|
1888
|
-
def clone(self):
|
1889
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
1890
|
-
deficiencies with links included; that is, links always point to the
|
1891
|
-
original tree. If you're not cloning a subtree in a context where this
|
1892
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
1893
|
-
the stdlib instead, which should copy links correctly."""
|
1894
|
-
return ConstJson(
|
1895
|
-
value=_cloned(self._attr_value)
|
1896
|
-
)
|
1897
|
-
|
1898
|
-
@staticmethod
|
1899
|
-
def _deserialize(cbor, seq_to_ob, links):
|
1900
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
1901
|
-
representation) into a node of this type. All (sub)nodes are added to
|
1902
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
1903
|
-
registered in the links list by means of a two-tuple of the setter
|
1904
|
-
function for the link field and the sequence number of the target node.
|
1905
|
-
"""
|
1906
|
-
if not isinstance(cbor, dict):
|
1907
|
-
raise TypeError('node description object must be a dict')
|
1908
|
-
typ = cbor.get('@t', None)
|
1909
|
-
if typ is None:
|
1910
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
1911
|
-
if typ != 'ConstJson':
|
1912
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstJson')
|
1913
|
-
|
1914
|
-
# Deserialize the value field.
|
1915
|
-
field = cbor.get('value', None)
|
1916
|
-
if not isinstance(field, dict):
|
1917
|
-
raise ValueError('missing or invalid serialization of field value')
|
1918
|
-
if hasattr(cqasm.v1x.primitives.Str, 'deserialize_cbor'):
|
1919
|
-
f_value = cqasm.v1x.primitives.Str.deserialize_cbor(field)
|
1920
|
-
else:
|
1921
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Str, field)
|
1922
|
-
|
1923
|
-
# Construct the ConstJson node.
|
1924
|
-
node = ConstJson(f_value)
|
1925
|
-
|
1926
|
-
# Deserialize annotations.
|
1927
|
-
for key, val in cbor.items():
|
1928
|
-
if not (key.startswith('{') and key.endswith('}')):
|
1929
|
-
continue
|
1930
|
-
key = key[1:-1]
|
1931
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
1932
|
-
|
1933
|
-
# Register node in sequence number lookup.
|
1934
|
-
seq = cbor.get('@i', None)
|
1935
|
-
if not isinstance(seq, int):
|
1936
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
1937
|
-
if seq in seq_to_ob:
|
1938
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
1939
|
-
seq_to_ob[seq] = node
|
1940
|
-
|
1941
|
-
return node
|
1942
|
-
|
1943
|
-
def _serialize(self, id_map):
|
1944
|
-
"""Serializes this node to the Python primitive representation of its
|
1945
|
-
CBOR serialization. The tree that the node belongs to must be
|
1946
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
1947
|
-
integers, to use for the sequence number representation of links."""
|
1948
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstJson'}
|
1949
|
-
|
1950
|
-
# Serialize the value field.
|
1951
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
1952
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
1953
|
-
else:
|
1954
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Str, self._attr_value)
|
1955
|
-
|
1956
|
-
# Serialize annotations.
|
1957
|
-
for key, val in self._annot.items():
|
1958
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
1959
|
-
|
1960
|
-
return cbor
|
1961
|
-
|
1962
|
-
|
1963
|
-
class MultiConstJson(_Multiple):
|
1964
|
-
"""Wrapper for an edge with multiple ConstJson objects."""
|
1965
|
-
|
1966
|
-
_T = ConstJson
|
1967
|
-
|
1968
|
-
|
1969
|
-
_typemap['ConstJson'] = ConstJson
|
1970
|
-
|
1971
|
-
class ConstReal(Constant):
|
1972
|
-
"""Represents a value of type real."""
|
1973
|
-
|
1974
|
-
__slots__ = [
|
1975
|
-
'_attr_value',
|
1976
|
-
]
|
1977
|
-
|
1978
|
-
def __init__(
|
1979
|
-
self,
|
1980
|
-
value=None,
|
1981
|
-
):
|
1982
|
-
super().__init__()
|
1983
|
-
self.value = value
|
1984
|
-
|
1985
|
-
@property
|
1986
|
-
def value(self):
|
1987
|
-
"""The contained value."""
|
1988
|
-
return self._attr_value
|
1989
|
-
|
1990
|
-
@value.setter
|
1991
|
-
def value(self, val):
|
1992
|
-
if val is None:
|
1993
|
-
del self.value
|
1994
|
-
return
|
1995
|
-
if not isinstance(val, cqasm.v1x.primitives.Real):
|
1996
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1997
|
-
if isinstance(val, Node):
|
1998
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Real')
|
1999
|
-
val = cqasm.v1x.primitives.Real(val)
|
2000
|
-
self._attr_value = val
|
2001
|
-
|
2002
|
-
@value.deleter
|
2003
|
-
def value(self):
|
2004
|
-
self._attr_value = cqasm.v1x.primitives.Real()
|
2005
|
-
|
2006
|
-
def __eq__(self, other):
|
2007
|
-
"""Equality operator. Ignores annotations!"""
|
2008
|
-
if not isinstance(other, ConstReal):
|
2009
|
-
return False
|
2010
|
-
if self.value != other.value:
|
2011
|
-
return False
|
2012
|
-
return True
|
2013
|
-
|
2014
|
-
def dump(self, indent=0, annotations=None, links=1):
|
2015
|
-
"""Returns a debug representation of this tree as a multiline string.
|
2016
|
-
indent is the number of double spaces prefixed before every line.
|
2017
|
-
annotations, if specified, must be a set-like object containing the key
|
2018
|
-
strings of the annotations that are to be printed. links specifies the
|
2019
|
-
maximum link recursion depth."""
|
2020
|
-
s = [' '*indent]
|
2021
|
-
s.append('ConstReal(')
|
2022
|
-
if annotations is None:
|
2023
|
-
annotations = []
|
2024
|
-
for key in annotations:
|
2025
|
-
if key in self:
|
2026
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
2027
|
-
s.append('\n')
|
2028
|
-
indent += 1
|
2029
|
-
s.append(' '*indent)
|
2030
|
-
s.append('value: ')
|
2031
|
-
s.append(str(self.value) + '\n')
|
2032
|
-
indent -= 1
|
2033
|
-
s.append(' '*indent)
|
2034
|
-
s.append(')')
|
2035
|
-
return ''.join(s)
|
2036
|
-
|
2037
|
-
__str__ = dump
|
2038
|
-
__repr__ = dump
|
2039
|
-
|
2040
|
-
def find_reachable(self, id_map=None):
|
2041
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
2042
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
2043
|
-
specified, found nodes are appended to it."""
|
2044
|
-
if id_map is None:
|
2045
|
-
id_map = {}
|
2046
|
-
if id(self) in id_map:
|
2047
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
2048
|
-
id_map[id(self)] = len(id_map)
|
2049
|
-
return id_map
|
2050
|
-
|
2051
|
-
def check_complete(self, id_map=None):
|
2052
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
2053
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
2054
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
2055
|
-
id() codes to tree indices for all reachable nodes."""
|
2056
|
-
if id_map is None:
|
2057
|
-
id_map = self.find_reachable()
|
2058
|
-
|
2059
|
-
def copy(self):
|
2060
|
-
"""Returns a shallow copy of this node."""
|
2061
|
-
return ConstReal(
|
2062
|
-
value=self._attr_value
|
2063
|
-
)
|
2064
|
-
|
2065
|
-
def clone(self):
|
2066
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
2067
|
-
deficiencies with links included; that is, links always point to the
|
2068
|
-
original tree. If you're not cloning a subtree in a context where this
|
2069
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
2070
|
-
the stdlib instead, which should copy links correctly."""
|
2071
|
-
return ConstReal(
|
2072
|
-
value=_cloned(self._attr_value)
|
2073
|
-
)
|
2074
|
-
|
2075
|
-
@staticmethod
|
2076
|
-
def _deserialize(cbor, seq_to_ob, links):
|
2077
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
2078
|
-
representation) into a node of this type. All (sub)nodes are added to
|
2079
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
2080
|
-
registered in the links list by means of a two-tuple of the setter
|
2081
|
-
function for the link field and the sequence number of the target node.
|
2082
|
-
"""
|
2083
|
-
if not isinstance(cbor, dict):
|
2084
|
-
raise TypeError('node description object must be a dict')
|
2085
|
-
typ = cbor.get('@t', None)
|
2086
|
-
if typ is None:
|
2087
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
2088
|
-
if typ != 'ConstReal':
|
2089
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstReal')
|
2090
|
-
|
2091
|
-
# Deserialize the value field.
|
2092
|
-
field = cbor.get('value', None)
|
2093
|
-
if not isinstance(field, dict):
|
2094
|
-
raise ValueError('missing or invalid serialization of field value')
|
2095
|
-
if hasattr(cqasm.v1x.primitives.Real, 'deserialize_cbor'):
|
2096
|
-
f_value = cqasm.v1x.primitives.Real.deserialize_cbor(field)
|
2097
|
-
else:
|
2098
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Real, field)
|
2099
|
-
|
2100
|
-
# Construct the ConstReal node.
|
2101
|
-
node = ConstReal(f_value)
|
2102
|
-
|
2103
|
-
# Deserialize annotations.
|
2104
|
-
for key, val in cbor.items():
|
2105
|
-
if not (key.startswith('{') and key.endswith('}')):
|
2106
|
-
continue
|
2107
|
-
key = key[1:-1]
|
2108
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
2109
|
-
|
2110
|
-
# Register node in sequence number lookup.
|
2111
|
-
seq = cbor.get('@i', None)
|
2112
|
-
if not isinstance(seq, int):
|
2113
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
2114
|
-
if seq in seq_to_ob:
|
2115
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
2116
|
-
seq_to_ob[seq] = node
|
2117
|
-
|
2118
|
-
return node
|
2119
|
-
|
2120
|
-
def _serialize(self, id_map):
|
2121
|
-
"""Serializes this node to the Python primitive representation of its
|
2122
|
-
CBOR serialization. The tree that the node belongs to must be
|
2123
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
2124
|
-
integers, to use for the sequence number representation of links."""
|
2125
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstReal'}
|
2126
|
-
|
2127
|
-
# Serialize the value field.
|
2128
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
2129
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
2130
|
-
else:
|
2131
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Real, self._attr_value)
|
2132
|
-
|
2133
|
-
# Serialize annotations.
|
2134
|
-
for key, val in self._annot.items():
|
2135
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
2136
|
-
|
2137
|
-
return cbor
|
2138
|
-
|
2139
|
-
|
2140
|
-
class MultiConstReal(_Multiple):
|
2141
|
-
"""Wrapper for an edge with multiple ConstReal objects."""
|
2142
|
-
|
2143
|
-
_T = ConstReal
|
2144
|
-
|
2145
|
-
|
2146
|
-
_typemap['ConstReal'] = ConstReal
|
2147
|
-
|
2148
|
-
class ConstRealMatrix(Constant):
|
2149
|
-
"""Represents a value of type real_matrix."""
|
2150
|
-
|
2151
|
-
__slots__ = [
|
2152
|
-
'_attr_value',
|
2153
|
-
]
|
2154
|
-
|
2155
|
-
def __init__(
|
2156
|
-
self,
|
2157
|
-
value=None,
|
2158
|
-
):
|
2159
|
-
super().__init__()
|
2160
|
-
self.value = value
|
2161
|
-
|
2162
|
-
@property
|
2163
|
-
def value(self):
|
2164
|
-
"""The contained value."""
|
2165
|
-
return self._attr_value
|
2166
|
-
|
2167
|
-
@value.setter
|
2168
|
-
def value(self, val):
|
2169
|
-
if val is None:
|
2170
|
-
del self.value
|
2171
|
-
return
|
2172
|
-
if not isinstance(val, cqasm.v1x.primitives.RMatrix):
|
2173
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
2174
|
-
if isinstance(val, Node):
|
2175
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.RMatrix')
|
2176
|
-
val = cqasm.v1x.primitives.RMatrix(val)
|
2177
|
-
self._attr_value = val
|
2178
|
-
|
2179
|
-
@value.deleter
|
2180
|
-
def value(self):
|
2181
|
-
self._attr_value = cqasm.v1x.primitives.RMatrix()
|
2182
|
-
|
2183
|
-
def __eq__(self, other):
|
2184
|
-
"""Equality operator. Ignores annotations!"""
|
2185
|
-
if not isinstance(other, ConstRealMatrix):
|
2186
|
-
return False
|
2187
|
-
if self.value != other.value:
|
2188
|
-
return False
|
2189
|
-
return True
|
2190
|
-
|
2191
|
-
def dump(self, indent=0, annotations=None, links=1):
|
2192
|
-
"""Returns a debug representation of this tree as a multiline string.
|
2193
|
-
indent is the number of double spaces prefixed before every line.
|
2194
|
-
annotations, if specified, must be a set-like object containing the key
|
2195
|
-
strings of the annotations that are to be printed. links specifies the
|
2196
|
-
maximum link recursion depth."""
|
2197
|
-
s = [' '*indent]
|
2198
|
-
s.append('ConstRealMatrix(')
|
2199
|
-
if annotations is None:
|
2200
|
-
annotations = []
|
2201
|
-
for key in annotations:
|
2202
|
-
if key in self:
|
2203
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
2204
|
-
s.append('\n')
|
2205
|
-
indent += 1
|
2206
|
-
s.append(' '*indent)
|
2207
|
-
s.append('value: ')
|
2208
|
-
s.append(str(self.value) + '\n')
|
2209
|
-
indent -= 1
|
2210
|
-
s.append(' '*indent)
|
2211
|
-
s.append(')')
|
2212
|
-
return ''.join(s)
|
2213
|
-
|
2214
|
-
__str__ = dump
|
2215
|
-
__repr__ = dump
|
2216
|
-
|
2217
|
-
def find_reachable(self, id_map=None):
|
2218
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
2219
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
2220
|
-
specified, found nodes are appended to it."""
|
2221
|
-
if id_map is None:
|
2222
|
-
id_map = {}
|
2223
|
-
if id(self) in id_map:
|
2224
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
2225
|
-
id_map[id(self)] = len(id_map)
|
2226
|
-
return id_map
|
2227
|
-
|
2228
|
-
def check_complete(self, id_map=None):
|
2229
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
2230
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
2231
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
2232
|
-
id() codes to tree indices for all reachable nodes."""
|
2233
|
-
if id_map is None:
|
2234
|
-
id_map = self.find_reachable()
|
2235
|
-
|
2236
|
-
def copy(self):
|
2237
|
-
"""Returns a shallow copy of this node."""
|
2238
|
-
return ConstRealMatrix(
|
2239
|
-
value=self._attr_value
|
2240
|
-
)
|
2241
|
-
|
2242
|
-
def clone(self):
|
2243
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
2244
|
-
deficiencies with links included; that is, links always point to the
|
2245
|
-
original tree. If you're not cloning a subtree in a context where this
|
2246
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
2247
|
-
the stdlib instead, which should copy links correctly."""
|
2248
|
-
return ConstRealMatrix(
|
2249
|
-
value=_cloned(self._attr_value)
|
2250
|
-
)
|
2251
|
-
|
2252
|
-
@staticmethod
|
2253
|
-
def _deserialize(cbor, seq_to_ob, links):
|
2254
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
2255
|
-
representation) into a node of this type. All (sub)nodes are added to
|
2256
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
2257
|
-
registered in the links list by means of a two-tuple of the setter
|
2258
|
-
function for the link field and the sequence number of the target node.
|
2259
|
-
"""
|
2260
|
-
if not isinstance(cbor, dict):
|
2261
|
-
raise TypeError('node description object must be a dict')
|
2262
|
-
typ = cbor.get('@t', None)
|
2263
|
-
if typ is None:
|
2264
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
2265
|
-
if typ != 'ConstRealMatrix':
|
2266
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstRealMatrix')
|
2267
|
-
|
2268
|
-
# Deserialize the value field.
|
2269
|
-
field = cbor.get('value', None)
|
2270
|
-
if not isinstance(field, dict):
|
2271
|
-
raise ValueError('missing or invalid serialization of field value')
|
2272
|
-
if hasattr(cqasm.v1x.primitives.RMatrix, 'deserialize_cbor'):
|
2273
|
-
f_value = cqasm.v1x.primitives.RMatrix.deserialize_cbor(field)
|
2274
|
-
else:
|
2275
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.RMatrix, field)
|
2276
|
-
|
2277
|
-
# Construct the ConstRealMatrix node.
|
2278
|
-
node = ConstRealMatrix(f_value)
|
2279
|
-
|
2280
|
-
# Deserialize annotations.
|
2281
|
-
for key, val in cbor.items():
|
2282
|
-
if not (key.startswith('{') and key.endswith('}')):
|
2283
|
-
continue
|
2284
|
-
key = key[1:-1]
|
2285
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
2286
|
-
|
2287
|
-
# Register node in sequence number lookup.
|
2288
|
-
seq = cbor.get('@i', None)
|
2289
|
-
if not isinstance(seq, int):
|
2290
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
2291
|
-
if seq in seq_to_ob:
|
2292
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
2293
|
-
seq_to_ob[seq] = node
|
2294
|
-
|
2295
|
-
return node
|
2296
|
-
|
2297
|
-
def _serialize(self, id_map):
|
2298
|
-
"""Serializes this node to the Python primitive representation of its
|
2299
|
-
CBOR serialization. The tree that the node belongs to must be
|
2300
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
2301
|
-
integers, to use for the sequence number representation of links."""
|
2302
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstRealMatrix'}
|
2303
|
-
|
2304
|
-
# Serialize the value field.
|
2305
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
2306
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
2307
|
-
else:
|
2308
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.RMatrix, self._attr_value)
|
2309
|
-
|
2310
|
-
# Serialize annotations.
|
2311
|
-
for key, val in self._annot.items():
|
2312
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
2313
|
-
|
2314
|
-
return cbor
|
2315
|
-
|
2316
|
-
|
2317
|
-
class MultiConstRealMatrix(_Multiple):
|
2318
|
-
"""Wrapper for an edge with multiple ConstRealMatrix objects."""
|
2319
|
-
|
2320
|
-
_T = ConstRealMatrix
|
2321
|
-
|
2322
|
-
|
2323
|
-
_typemap['ConstRealMatrix'] = ConstRealMatrix
|
2324
|
-
|
2325
|
-
class ConstString(Constant):
|
2326
|
-
"""Represents a value of type string."""
|
2327
|
-
|
2328
|
-
__slots__ = [
|
2329
|
-
'_attr_value',
|
2330
|
-
]
|
2331
|
-
|
2332
|
-
def __init__(
|
2333
|
-
self,
|
2334
|
-
value=None,
|
2335
|
-
):
|
2336
|
-
super().__init__()
|
2337
|
-
self.value = value
|
2338
|
-
|
2339
|
-
@property
|
2340
|
-
def value(self):
|
2341
|
-
"""The contained value."""
|
2342
|
-
return self._attr_value
|
2343
|
-
|
2344
|
-
@value.setter
|
2345
|
-
def value(self, val):
|
2346
|
-
if val is None:
|
2347
|
-
del self.value
|
2348
|
-
return
|
2349
|
-
if not isinstance(val, cqasm.v1x.primitives.Str):
|
2350
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
2351
|
-
if isinstance(val, Node):
|
2352
|
-
raise TypeError('value must be of type cqasm.v1x.primitives.Str')
|
2353
|
-
val = cqasm.v1x.primitives.Str(val)
|
2354
|
-
self._attr_value = val
|
2355
|
-
|
2356
|
-
@value.deleter
|
2357
|
-
def value(self):
|
2358
|
-
self._attr_value = cqasm.v1x.primitives.Str()
|
2359
|
-
|
2360
|
-
def __eq__(self, other):
|
2361
|
-
"""Equality operator. Ignores annotations!"""
|
2362
|
-
if not isinstance(other, ConstString):
|
2363
|
-
return False
|
2364
|
-
if self.value != other.value:
|
2365
|
-
return False
|
2366
|
-
return True
|
2367
|
-
|
2368
|
-
def dump(self, indent=0, annotations=None, links=1):
|
2369
|
-
"""Returns a debug representation of this tree as a multiline string.
|
2370
|
-
indent is the number of double spaces prefixed before every line.
|
2371
|
-
annotations, if specified, must be a set-like object containing the key
|
2372
|
-
strings of the annotations that are to be printed. links specifies the
|
2373
|
-
maximum link recursion depth."""
|
2374
|
-
s = [' '*indent]
|
2375
|
-
s.append('ConstString(')
|
2376
|
-
if annotations is None:
|
2377
|
-
annotations = []
|
2378
|
-
for key in annotations:
|
2379
|
-
if key in self:
|
2380
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
2381
|
-
s.append('\n')
|
2382
|
-
indent += 1
|
2383
|
-
s.append(' '*indent)
|
2384
|
-
s.append('value: ')
|
2385
|
-
s.append(str(self.value) + '\n')
|
2386
|
-
indent -= 1
|
2387
|
-
s.append(' '*indent)
|
2388
|
-
s.append(')')
|
2389
|
-
return ''.join(s)
|
2390
|
-
|
2391
|
-
__str__ = dump
|
2392
|
-
__repr__ = dump
|
2393
|
-
|
2394
|
-
def find_reachable(self, id_map=None):
|
2395
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
2396
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
2397
|
-
specified, found nodes are appended to it."""
|
2398
|
-
if id_map is None:
|
2399
|
-
id_map = {}
|
2400
|
-
if id(self) in id_map:
|
2401
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
2402
|
-
id_map[id(self)] = len(id_map)
|
2403
|
-
return id_map
|
2404
|
-
|
2405
|
-
def check_complete(self, id_map=None):
|
2406
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
2407
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
2408
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
2409
|
-
id() codes to tree indices for all reachable nodes."""
|
2410
|
-
if id_map is None:
|
2411
|
-
id_map = self.find_reachable()
|
2412
|
-
|
2413
|
-
def copy(self):
|
2414
|
-
"""Returns a shallow copy of this node."""
|
2415
|
-
return ConstString(
|
2416
|
-
value=self._attr_value
|
2417
|
-
)
|
2418
|
-
|
2419
|
-
def clone(self):
|
2420
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
2421
|
-
deficiencies with links included; that is, links always point to the
|
2422
|
-
original tree. If you're not cloning a subtree in a context where this
|
2423
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
2424
|
-
the stdlib instead, which should copy links correctly."""
|
2425
|
-
return ConstString(
|
2426
|
-
value=_cloned(self._attr_value)
|
2427
|
-
)
|
2428
|
-
|
2429
|
-
@staticmethod
|
2430
|
-
def _deserialize(cbor, seq_to_ob, links):
|
2431
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
2432
|
-
representation) into a node of this type. All (sub)nodes are added to
|
2433
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
2434
|
-
registered in the links list by means of a two-tuple of the setter
|
2435
|
-
function for the link field and the sequence number of the target node.
|
2436
|
-
"""
|
2437
|
-
if not isinstance(cbor, dict):
|
2438
|
-
raise TypeError('node description object must be a dict')
|
2439
|
-
typ = cbor.get('@t', None)
|
2440
|
-
if typ is None:
|
2441
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
2442
|
-
if typ != 'ConstString':
|
2443
|
-
raise ValueError('found node serialization for ' + typ + ', but expected ConstString')
|
2444
|
-
|
2445
|
-
# Deserialize the value field.
|
2446
|
-
field = cbor.get('value', None)
|
2447
|
-
if not isinstance(field, dict):
|
2448
|
-
raise ValueError('missing or invalid serialization of field value')
|
2449
|
-
if hasattr(cqasm.v1x.primitives.Str, 'deserialize_cbor'):
|
2450
|
-
f_value = cqasm.v1x.primitives.Str.deserialize_cbor(field)
|
2451
|
-
else:
|
2452
|
-
f_value = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Str, field)
|
2453
|
-
|
2454
|
-
# Construct the ConstString node.
|
2455
|
-
node = ConstString(f_value)
|
2456
|
-
|
2457
|
-
# Deserialize annotations.
|
2458
|
-
for key, val in cbor.items():
|
2459
|
-
if not (key.startswith('{') and key.endswith('}')):
|
2460
|
-
continue
|
2461
|
-
key = key[1:-1]
|
2462
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
2463
|
-
|
2464
|
-
# Register node in sequence number lookup.
|
2465
|
-
seq = cbor.get('@i', None)
|
2466
|
-
if not isinstance(seq, int):
|
2467
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
2468
|
-
if seq in seq_to_ob:
|
2469
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
2470
|
-
seq_to_ob[seq] = node
|
2471
|
-
|
2472
|
-
return node
|
2473
|
-
|
2474
|
-
def _serialize(self, id_map):
|
2475
|
-
"""Serializes this node to the Python primitive representation of its
|
2476
|
-
CBOR serialization. The tree that the node belongs to must be
|
2477
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
2478
|
-
integers, to use for the sequence number representation of links."""
|
2479
|
-
cbor = {'@i': id_map[id(self)], '@t': 'ConstString'}
|
2480
|
-
|
2481
|
-
# Serialize the value field.
|
2482
|
-
if hasattr(self._attr_value, 'serialize_cbor'):
|
2483
|
-
cbor['value'] = self._attr_value.serialize_cbor()
|
2484
|
-
else:
|
2485
|
-
cbor['value'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Str, self._attr_value)
|
2486
|
-
|
2487
|
-
# Serialize annotations.
|
2488
|
-
for key, val in self._annot.items():
|
2489
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
2490
|
-
|
2491
|
-
return cbor
|
2492
|
-
|
2493
|
-
|
2494
|
-
class MultiConstString(_Multiple):
|
2495
|
-
"""Wrapper for an edge with multiple ConstString objects."""
|
2496
|
-
|
2497
|
-
_T = ConstString
|
2498
|
-
|
2499
|
-
|
2500
|
-
_typemap['ConstString'] = ConstString
|
2501
|
-
|
2502
|
-
class Function(Node):
|
2503
|
-
"""This can be returned by user-defined functions as a placeholder value for
|
2504
|
-
something that needs to be evaluated at runtime rather than during constant
|
2505
|
-
propagation. Annotations should be used to attach semantic information."""
|
2506
|
-
|
2507
|
-
__slots__ = [
|
2508
|
-
'_attr_name',
|
2509
|
-
'_attr_operands',
|
2510
|
-
'_attr_return_type',
|
2511
|
-
]
|
2512
|
-
|
2513
|
-
def __init__(
|
2514
|
-
self,
|
2515
|
-
name=None,
|
2516
|
-
operands=None,
|
2517
|
-
return_type=None,
|
2518
|
-
):
|
2519
|
-
super().__init__()
|
2520
|
-
self.name = name
|
2521
|
-
self.operands = operands
|
2522
|
-
self.return_type = return_type
|
2523
|
-
|
2524
|
-
@property
|
2525
|
-
def name(self):
|
2526
|
-
"""Name of the function as it appears or should appear in the cQASM
|
2527
|
-
file."""
|
2528
|
-
return self._attr_name
|
2529
|
-
|
2530
|
-
@name.setter
|
2531
|
-
def name(self, val):
|
2532
|
-
if val is None:
|
2533
|
-
del self.name
|
2534
|
-
return
|
2535
|
-
if not isinstance(val, cqasm.v1x.primitives.Str):
|
2536
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
2537
|
-
if isinstance(val, Node):
|
2538
|
-
raise TypeError('name must be of type cqasm.v1x.primitives.Str')
|
2539
|
-
val = cqasm.v1x.primitives.Str(val)
|
2540
|
-
self._attr_name = val
|
2541
|
-
|
2542
|
-
@name.deleter
|
2543
|
-
def name(self):
|
2544
|
-
self._attr_name = cqasm.v1x.primitives.Str()
|
2545
|
-
|
2546
|
-
@property
|
2547
|
-
def operands(self):
|
2548
|
-
"""Operands for the function."""
|
2549
|
-
return self._attr_operands
|
2550
|
-
|
2551
|
-
@operands.setter
|
2552
|
-
def operands(self, val):
|
2553
|
-
if val is None:
|
2554
|
-
del self.operands
|
2555
|
-
return
|
2556
|
-
if not isinstance(val, cqasm.v1x.values.MultiNode):
|
2557
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
2558
|
-
if isinstance(val, Node):
|
2559
|
-
raise TypeError('operands must be of type cqasm.v1x.values.MultiNode')
|
2560
|
-
val = cqasm.v1x.values.MultiNode(val)
|
2561
|
-
self._attr_operands = val
|
2562
|
-
|
2563
|
-
@operands.deleter
|
2564
|
-
def operands(self):
|
2565
|
-
self._attr_operands = cqasm.v1x.values.MultiNode()
|
2566
|
-
|
2567
|
-
@property
|
2568
|
-
def return_type(self):
|
2569
|
-
"""Operands for the function."""
|
2570
|
-
return self._attr_return_type
|
2571
|
-
|
2572
|
-
@return_type.setter
|
2573
|
-
def return_type(self, val):
|
2574
|
-
if val is None:
|
2575
|
-
del self.return_type
|
2576
|
-
return
|
2577
|
-
if not isinstance(val, cqasm.v1x.types.Node):
|
2578
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
2579
|
-
if isinstance(val, Node):
|
2580
|
-
raise TypeError('return_type must be of type cqasm.v1x.types.Node')
|
2581
|
-
val = cqasm.v1x.types.Node(val)
|
2582
|
-
self._attr_return_type = val
|
2583
|
-
|
2584
|
-
@return_type.deleter
|
2585
|
-
def return_type(self):
|
2586
|
-
self._attr_return_type = None
|
2587
|
-
|
2588
|
-
def __eq__(self, other):
|
2589
|
-
"""Equality operator. Ignores annotations!"""
|
2590
|
-
if not isinstance(other, Function):
|
2591
|
-
return False
|
2592
|
-
if self.name != other.name:
|
2593
|
-
return False
|
2594
|
-
if self.operands != other.operands:
|
2595
|
-
return False
|
2596
|
-
if self.return_type != other.return_type:
|
2597
|
-
return False
|
2598
|
-
return True
|
2599
|
-
|
2600
|
-
def dump(self, indent=0, annotations=None, links=1):
|
2601
|
-
"""Returns a debug representation of this tree as a multiline string.
|
2602
|
-
indent is the number of double spaces prefixed before every line.
|
2603
|
-
annotations, if specified, must be a set-like object containing the key
|
2604
|
-
strings of the annotations that are to be printed. links specifies the
|
2605
|
-
maximum link recursion depth."""
|
2606
|
-
s = [' '*indent]
|
2607
|
-
s.append('Function(')
|
2608
|
-
if annotations is None:
|
2609
|
-
annotations = []
|
2610
|
-
for key in annotations:
|
2611
|
-
if key in self:
|
2612
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
2613
|
-
s.append('\n')
|
2614
|
-
indent += 1
|
2615
|
-
s.append(' '*indent)
|
2616
|
-
s.append('name: ')
|
2617
|
-
s.append(str(self.name) + '\n')
|
2618
|
-
s.append(' '*indent)
|
2619
|
-
s.append('operands: ')
|
2620
|
-
if not self.operands:
|
2621
|
-
s.append('-\n')
|
2622
|
-
else:
|
2623
|
-
s.append('[\n')
|
2624
|
-
for child in self.operands:
|
2625
|
-
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
2626
|
-
s.append(' '*indent + ']\n')
|
2627
|
-
s.append(' '*indent)
|
2628
|
-
s.append('return_type: ')
|
2629
|
-
if self.return_type is None:
|
2630
|
-
s.append('!MISSING\n')
|
2631
|
-
else:
|
2632
|
-
s.append('<\n')
|
2633
|
-
s.append(self.return_type.dump(indent + 1, annotations, links) + '\n')
|
2634
|
-
s.append(' '*indent + '>\n')
|
2635
|
-
indent -= 1
|
2636
|
-
s.append(' '*indent)
|
2637
|
-
s.append(')')
|
2638
|
-
return ''.join(s)
|
2639
|
-
|
2640
|
-
__str__ = dump
|
2641
|
-
__repr__ = dump
|
2642
|
-
|
2643
|
-
def find_reachable(self, id_map=None):
|
2644
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
2645
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
2646
|
-
specified, found nodes are appended to it."""
|
2647
|
-
if id_map is None:
|
2648
|
-
id_map = {}
|
2649
|
-
if id(self) in id_map:
|
2650
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
2651
|
-
id_map[id(self)] = len(id_map)
|
2652
|
-
for el in self._attr_operands:
|
2653
|
-
el.find_reachable(id_map)
|
2654
|
-
if self._attr_return_type is not None:
|
2655
|
-
self._attr_return_type.find_reachable(id_map)
|
2656
|
-
return id_map
|
2657
|
-
|
2658
|
-
def check_complete(self, id_map=None):
|
2659
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
2660
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
2661
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
2662
|
-
id() codes to tree indices for all reachable nodes."""
|
2663
|
-
if id_map is None:
|
2664
|
-
id_map = self.find_reachable()
|
2665
|
-
for child in self._attr_operands:
|
2666
|
-
child.check_complete(id_map)
|
2667
|
-
if self._attr_return_type is None:
|
2668
|
-
raise NotWellFormed('return_type is required but not set')
|
2669
|
-
if self._attr_return_type is not None:
|
2670
|
-
self._attr_return_type.check_complete(id_map)
|
2671
|
-
|
2672
|
-
def copy(self):
|
2673
|
-
"""Returns a shallow copy of this node."""
|
2674
|
-
return Function(
|
2675
|
-
name=self._attr_name,
|
2676
|
-
operands=self._attr_operands.copy(),
|
2677
|
-
return_type=self._attr_return_type
|
2678
|
-
)
|
2679
|
-
|
2680
|
-
def clone(self):
|
2681
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
2682
|
-
deficiencies with links included; that is, links always point to the
|
2683
|
-
original tree. If you're not cloning a subtree in a context where this
|
2684
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
2685
|
-
the stdlib instead, which should copy links correctly."""
|
2686
|
-
return Function(
|
2687
|
-
name=_cloned(self._attr_name),
|
2688
|
-
operands=_cloned(self._attr_operands),
|
2689
|
-
return_type=_cloned(self._attr_return_type)
|
2690
|
-
)
|
2691
|
-
|
2692
|
-
@staticmethod
|
2693
|
-
def _deserialize(cbor, seq_to_ob, links):
|
2694
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
2695
|
-
representation) into a node of this type. All (sub)nodes are added to
|
2696
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
2697
|
-
registered in the links list by means of a two-tuple of the setter
|
2698
|
-
function for the link field and the sequence number of the target node.
|
2699
|
-
"""
|
2700
|
-
if not isinstance(cbor, dict):
|
2701
|
-
raise TypeError('node description object must be a dict')
|
2702
|
-
typ = cbor.get('@t', None)
|
2703
|
-
if typ is None:
|
2704
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
2705
|
-
if typ != 'Function':
|
2706
|
-
raise ValueError('found node serialization for ' + typ + ', but expected Function')
|
2707
|
-
|
2708
|
-
# Deserialize the name field.
|
2709
|
-
field = cbor.get('name', None)
|
2710
|
-
if not isinstance(field, dict):
|
2711
|
-
raise ValueError('missing or invalid serialization of field name')
|
2712
|
-
if hasattr(cqasm.v1x.primitives.Str, 'deserialize_cbor'):
|
2713
|
-
f_name = cqasm.v1x.primitives.Str.deserialize_cbor(field)
|
2714
|
-
else:
|
2715
|
-
f_name = cqasm.v1x.primitives.deserialize(cqasm.v1x.primitives.Str, field)
|
2716
|
-
|
2717
|
-
# Deserialize the operands field.
|
2718
|
-
field = cbor.get('operands', None)
|
2719
|
-
if not isinstance(field, dict):
|
2720
|
-
raise ValueError('missing or invalid serialization of field operands')
|
2721
|
-
if field.get('@T') != '*':
|
2722
|
-
raise ValueError('unexpected edge type for field operands')
|
2723
|
-
data = field.get('@d', None)
|
2724
|
-
if not isinstance(data, list):
|
2725
|
-
raise ValueError('missing serialization of Any/Many contents')
|
2726
|
-
f_operands = cqasm.v1x.values.MultiNode()
|
2727
|
-
for element in data:
|
2728
|
-
if element.get('@T') != '1':
|
2729
|
-
raise ValueError('unexpected edge type for Any/Many element')
|
2730
|
-
f_operands.append(cqasm.v1x.values.Node._deserialize(element, seq_to_ob, links))
|
2731
|
-
|
2732
|
-
# Deserialize the return_type field.
|
2733
|
-
field = cbor.get('return_type', None)
|
2734
|
-
if not isinstance(field, dict):
|
2735
|
-
raise ValueError('missing or invalid serialization of field return_type')
|
2736
|
-
if field.get('@T') != '1':
|
2737
|
-
raise ValueError('unexpected edge type for field return_type')
|
2738
|
-
if field.get('@t', None) is None:
|
2739
|
-
f_return_type = None
|
2740
|
-
else:
|
2741
|
-
f_return_type = cqasm.v1x.types.Node._deserialize(field, seq_to_ob, links)
|
2742
|
-
|
2743
|
-
# Construct the Function node.
|
2744
|
-
node = Function(f_name, f_operands, f_return_type)
|
2745
|
-
|
2746
|
-
# Deserialize annotations.
|
2747
|
-
for key, val in cbor.items():
|
2748
|
-
if not (key.startswith('{') and key.endswith('}')):
|
2749
|
-
continue
|
2750
|
-
key = key[1:-1]
|
2751
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
2752
|
-
|
2753
|
-
# Register node in sequence number lookup.
|
2754
|
-
seq = cbor.get('@i', None)
|
2755
|
-
if not isinstance(seq, int):
|
2756
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
2757
|
-
if seq in seq_to_ob:
|
2758
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
2759
|
-
seq_to_ob[seq] = node
|
2760
|
-
|
2761
|
-
return node
|
2762
|
-
|
2763
|
-
def _serialize(self, id_map):
|
2764
|
-
"""Serializes this node to the Python primitive representation of its
|
2765
|
-
CBOR serialization. The tree that the node belongs to must be
|
2766
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
2767
|
-
integers, to use for the sequence number representation of links."""
|
2768
|
-
cbor = {'@i': id_map[id(self)], '@t': 'Function'}
|
2769
|
-
|
2770
|
-
# Serialize the name field.
|
2771
|
-
if hasattr(self._attr_name, 'serialize_cbor'):
|
2772
|
-
cbor['name'] = self._attr_name.serialize_cbor()
|
2773
|
-
else:
|
2774
|
-
cbor['name'] = cqasm.v1x.primitives.serialize(cqasm.v1x.primitives.Str, self._attr_name)
|
2775
|
-
|
2776
|
-
# Serialize the operands field.
|
2777
|
-
field = {'@T': '*'}
|
2778
|
-
lst = []
|
2779
|
-
for el in self._attr_operands:
|
2780
|
-
el = el._serialize(id_map)
|
2781
|
-
el['@T'] = '1'
|
2782
|
-
lst.append(el)
|
2783
|
-
field['@d'] = lst
|
2784
|
-
cbor['operands'] = field
|
2785
|
-
|
2786
|
-
# Serialize the return_type field.
|
2787
|
-
field = {'@T': '1'}
|
2788
|
-
if self._attr_return_type is None:
|
2789
|
-
field['@t'] = None
|
2790
|
-
else:
|
2791
|
-
field.update(self._attr_return_type._serialize(id_map))
|
2792
|
-
cbor['return_type'] = field
|
2793
|
-
|
2794
|
-
# Serialize annotations.
|
2795
|
-
for key, val in self._annot.items():
|
2796
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
2797
|
-
|
2798
|
-
return cbor
|
2799
|
-
|
2800
|
-
|
2801
|
-
class MultiFunction(_Multiple):
|
2802
|
-
"""Wrapper for an edge with multiple Function objects."""
|
2803
|
-
|
2804
|
-
_T = Function
|
2805
|
-
|
2806
|
-
|
2807
|
-
_typemap['Function'] = Function
|
2808
|
-
|
2809
|
-
class QubitRefs(Reference):
|
2810
|
-
"""Represents a qubit, or a set of qubits for single-gate-multiple-qubit
|
2811
|
-
notation. The indices must not repeat."""
|
2812
|
-
|
2813
|
-
__slots__ = [
|
2814
|
-
'_attr_index',
|
2815
|
-
]
|
2816
|
-
|
2817
|
-
def __init__(
|
2818
|
-
self,
|
2819
|
-
index=None,
|
2820
|
-
):
|
2821
|
-
super().__init__()
|
2822
|
-
self.index = index
|
2823
|
-
|
2824
|
-
@property
|
2825
|
-
def index(self):
|
2826
|
-
"""Set of qubit indices referred to, starting at 0."""
|
2827
|
-
return self._attr_index
|
2828
|
-
|
2829
|
-
@index.setter
|
2830
|
-
def index(self, val):
|
2831
|
-
if val is None:
|
2832
|
-
del self.index
|
2833
|
-
return
|
2834
|
-
if not isinstance(val, MultiConstInt):
|
2835
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
2836
|
-
if isinstance(val, Node):
|
2837
|
-
raise TypeError('index must be of type MultiConstInt')
|
2838
|
-
val = MultiConstInt(val)
|
2839
|
-
self._attr_index = val
|
2840
|
-
|
2841
|
-
@index.deleter
|
2842
|
-
def index(self):
|
2843
|
-
self._attr_index = MultiConstInt()
|
2844
|
-
|
2845
|
-
def __eq__(self, other):
|
2846
|
-
"""Equality operator. Ignores annotations!"""
|
2847
|
-
if not isinstance(other, QubitRefs):
|
2848
|
-
return False
|
2849
|
-
if self.index != other.index:
|
2850
|
-
return False
|
2851
|
-
return True
|
2852
|
-
|
2853
|
-
def dump(self, indent=0, annotations=None, links=1):
|
2854
|
-
"""Returns a debug representation of this tree as a multiline string.
|
2855
|
-
indent is the number of double spaces prefixed before every line.
|
2856
|
-
annotations, if specified, must be a set-like object containing the key
|
2857
|
-
strings of the annotations that are to be printed. links specifies the
|
2858
|
-
maximum link recursion depth."""
|
2859
|
-
s = [' '*indent]
|
2860
|
-
s.append('QubitRefs(')
|
2861
|
-
if annotations is None:
|
2862
|
-
annotations = []
|
2863
|
-
for key in annotations:
|
2864
|
-
if key in self:
|
2865
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
2866
|
-
s.append('\n')
|
2867
|
-
indent += 1
|
2868
|
-
s.append(' '*indent)
|
2869
|
-
s.append('index: ')
|
2870
|
-
if not self.index:
|
2871
|
-
s.append('!MISSING\n')
|
2872
|
-
else:
|
2873
|
-
s.append('[\n')
|
2874
|
-
for child in self.index:
|
2875
|
-
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
2876
|
-
s.append(' '*indent + ']\n')
|
2877
|
-
indent -= 1
|
2878
|
-
s.append(' '*indent)
|
2879
|
-
s.append(')')
|
2880
|
-
return ''.join(s)
|
2881
|
-
|
2882
|
-
__str__ = dump
|
2883
|
-
__repr__ = dump
|
2884
|
-
|
2885
|
-
def find_reachable(self, id_map=None):
|
2886
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
2887
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
2888
|
-
specified, found nodes are appended to it."""
|
2889
|
-
if id_map is None:
|
2890
|
-
id_map = {}
|
2891
|
-
if id(self) in id_map:
|
2892
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
2893
|
-
id_map[id(self)] = len(id_map)
|
2894
|
-
for el in self._attr_index:
|
2895
|
-
el.find_reachable(id_map)
|
2896
|
-
return id_map
|
2897
|
-
|
2898
|
-
def check_complete(self, id_map=None):
|
2899
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
2900
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
2901
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
2902
|
-
id() codes to tree indices for all reachable nodes."""
|
2903
|
-
if id_map is None:
|
2904
|
-
id_map = self.find_reachable()
|
2905
|
-
if not self._attr_index:
|
2906
|
-
raise NotWellFormed('index needs at least one node but has zero')
|
2907
|
-
for child in self._attr_index:
|
2908
|
-
child.check_complete(id_map)
|
2909
|
-
|
2910
|
-
def copy(self):
|
2911
|
-
"""Returns a shallow copy of this node."""
|
2912
|
-
return QubitRefs(
|
2913
|
-
index=self._attr_index.copy()
|
2914
|
-
)
|
2915
|
-
|
2916
|
-
def clone(self):
|
2917
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
2918
|
-
deficiencies with links included; that is, links always point to the
|
2919
|
-
original tree. If you're not cloning a subtree in a context where this
|
2920
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
2921
|
-
the stdlib instead, which should copy links correctly."""
|
2922
|
-
return QubitRefs(
|
2923
|
-
index=_cloned(self._attr_index)
|
2924
|
-
)
|
2925
|
-
|
2926
|
-
@staticmethod
|
2927
|
-
def _deserialize(cbor, seq_to_ob, links):
|
2928
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
2929
|
-
representation) into a node of this type. All (sub)nodes are added to
|
2930
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
2931
|
-
registered in the links list by means of a two-tuple of the setter
|
2932
|
-
function for the link field and the sequence number of the target node.
|
2933
|
-
"""
|
2934
|
-
if not isinstance(cbor, dict):
|
2935
|
-
raise TypeError('node description object must be a dict')
|
2936
|
-
typ = cbor.get('@t', None)
|
2937
|
-
if typ is None:
|
2938
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
2939
|
-
if typ != 'QubitRefs':
|
2940
|
-
raise ValueError('found node serialization for ' + typ + ', but expected QubitRefs')
|
2941
|
-
|
2942
|
-
# Deserialize the index field.
|
2943
|
-
field = cbor.get('index', None)
|
2944
|
-
if not isinstance(field, dict):
|
2945
|
-
raise ValueError('missing or invalid serialization of field index')
|
2946
|
-
if field.get('@T') != '+':
|
2947
|
-
raise ValueError('unexpected edge type for field index')
|
2948
|
-
data = field.get('@d', None)
|
2949
|
-
if not isinstance(data, list):
|
2950
|
-
raise ValueError('missing serialization of Any/Many contents')
|
2951
|
-
f_index = MultiConstInt()
|
2952
|
-
for element in data:
|
2953
|
-
if element.get('@T') != '1':
|
2954
|
-
raise ValueError('unexpected edge type for Any/Many element')
|
2955
|
-
f_index.append(ConstInt._deserialize(element, seq_to_ob, links))
|
2956
|
-
|
2957
|
-
# Construct the QubitRefs node.
|
2958
|
-
node = QubitRefs(f_index)
|
2959
|
-
|
2960
|
-
# Deserialize annotations.
|
2961
|
-
for key, val in cbor.items():
|
2962
|
-
if not (key.startswith('{') and key.endswith('}')):
|
2963
|
-
continue
|
2964
|
-
key = key[1:-1]
|
2965
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
2966
|
-
|
2967
|
-
# Register node in sequence number lookup.
|
2968
|
-
seq = cbor.get('@i', None)
|
2969
|
-
if not isinstance(seq, int):
|
2970
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
2971
|
-
if seq in seq_to_ob:
|
2972
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
2973
|
-
seq_to_ob[seq] = node
|
2974
|
-
|
2975
|
-
return node
|
2976
|
-
|
2977
|
-
def _serialize(self, id_map):
|
2978
|
-
"""Serializes this node to the Python primitive representation of its
|
2979
|
-
CBOR serialization. The tree that the node belongs to must be
|
2980
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
2981
|
-
integers, to use for the sequence number representation of links."""
|
2982
|
-
cbor = {'@i': id_map[id(self)], '@t': 'QubitRefs'}
|
2983
|
-
|
2984
|
-
# Serialize the index field.
|
2985
|
-
field = {'@T': '+'}
|
2986
|
-
lst = []
|
2987
|
-
for el in self._attr_index:
|
2988
|
-
el = el._serialize(id_map)
|
2989
|
-
el['@T'] = '1'
|
2990
|
-
lst.append(el)
|
2991
|
-
field['@d'] = lst
|
2992
|
-
cbor['index'] = field
|
2993
|
-
|
2994
|
-
# Serialize annotations.
|
2995
|
-
for key, val in self._annot.items():
|
2996
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
2997
|
-
|
2998
|
-
return cbor
|
2999
|
-
|
3000
|
-
|
3001
|
-
class MultiQubitRefs(_Multiple):
|
3002
|
-
"""Wrapper for an edge with multiple QubitRefs objects."""
|
3003
|
-
|
3004
|
-
_T = QubitRefs
|
3005
|
-
|
3006
|
-
|
3007
|
-
_typemap['QubitRefs'] = QubitRefs
|
3008
|
-
|
3009
|
-
class VariableRef(Reference):
|
3010
|
-
"""Represents a variable reference."""
|
3011
|
-
|
3012
|
-
__slots__ = [
|
3013
|
-
'_attr_variable',
|
3014
|
-
]
|
3015
|
-
|
3016
|
-
def __init__(
|
3017
|
-
self,
|
3018
|
-
variable=None,
|
3019
|
-
):
|
3020
|
-
super().__init__()
|
3021
|
-
self.variable = variable
|
3022
|
-
|
3023
|
-
@property
|
3024
|
-
def variable(self):
|
3025
|
-
"""The referenced variable."""
|
3026
|
-
return self._attr_variable
|
3027
|
-
|
3028
|
-
@variable.setter
|
3029
|
-
def variable(self, val):
|
3030
|
-
if val is None:
|
3031
|
-
del self.variable
|
3032
|
-
return
|
3033
|
-
if not isinstance(val, cqasm.v1x.semantic.Variable):
|
3034
|
-
raise TypeError('variable must be of type cqasm.v1x.semantic.Variable')
|
3035
|
-
self._attr_variable = val
|
3036
|
-
|
3037
|
-
@variable.deleter
|
3038
|
-
def variable(self):
|
3039
|
-
self._attr_variable = None
|
3040
|
-
|
3041
|
-
def __eq__(self, other):
|
3042
|
-
"""Equality operator. Ignores annotations!"""
|
3043
|
-
if not isinstance(other, VariableRef):
|
3044
|
-
return False
|
3045
|
-
if self.variable is not other.variable:
|
3046
|
-
return False
|
3047
|
-
return True
|
3048
|
-
|
3049
|
-
def dump(self, indent=0, annotations=None, links=1):
|
3050
|
-
"""Returns a debug representation of this tree as a multiline string.
|
3051
|
-
indent is the number of double spaces prefixed before every line.
|
3052
|
-
annotations, if specified, must be a set-like object containing the key
|
3053
|
-
strings of the annotations that are to be printed. links specifies the
|
3054
|
-
maximum link recursion depth."""
|
3055
|
-
s = [' '*indent]
|
3056
|
-
s.append('VariableRef(')
|
3057
|
-
if annotations is None:
|
3058
|
-
annotations = []
|
3059
|
-
for key in annotations:
|
3060
|
-
if key in self:
|
3061
|
-
s.append(' # {}: {}'.format(key, self[key]))
|
3062
|
-
s.append('\n')
|
3063
|
-
indent += 1
|
3064
|
-
s.append(' '*indent)
|
3065
|
-
s.append('variable --> ')
|
3066
|
-
if self.variable is None:
|
3067
|
-
s.append('!MISSING\n')
|
3068
|
-
else:
|
3069
|
-
s.append('<\n')
|
3070
|
-
if links:
|
3071
|
-
s.append(self.variable.dump(indent + 1, annotations, links - 1) + '\n')
|
3072
|
-
else:
|
3073
|
-
s.append(' '*(indent+1) + '...\n')
|
3074
|
-
s.append(' '*indent + '>\n')
|
3075
|
-
indent -= 1
|
3076
|
-
s.append(' '*indent)
|
3077
|
-
s.append(')')
|
3078
|
-
return ''.join(s)
|
3079
|
-
|
3080
|
-
__str__ = dump
|
3081
|
-
__repr__ = dump
|
3082
|
-
|
3083
|
-
def find_reachable(self, id_map=None):
|
3084
|
-
"""Returns a dictionary mapping Python id() values to stable sequence
|
3085
|
-
numbers for all nodes in the tree rooted at this node. If id_map is
|
3086
|
-
specified, found nodes are appended to it."""
|
3087
|
-
if id_map is None:
|
3088
|
-
id_map = {}
|
3089
|
-
if id(self) in id_map:
|
3090
|
-
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
3091
|
-
id_map[id(self)] = len(id_map)
|
3092
|
-
return id_map
|
3093
|
-
|
3094
|
-
def check_complete(self, id_map=None):
|
3095
|
-
"""Raises NotWellFormed if the tree rooted at this node is not
|
3096
|
-
well-formed. If id_map is specified, this tree is only a subtree in the
|
3097
|
-
context of a larger tree, and id_map must be a dict mapping from Python
|
3098
|
-
id() codes to tree indices for all reachable nodes."""
|
3099
|
-
if id_map is None:
|
3100
|
-
id_map = self.find_reachable()
|
3101
|
-
if self._attr_variable is None:
|
3102
|
-
raise NotWellFormed('variable is required but not set')
|
3103
|
-
if self._attr_variable is not None:
|
3104
|
-
if id(self._attr_variable) not in id_map:
|
3105
|
-
raise NotWellFormed('variable links to unreachable node')
|
3106
|
-
|
3107
|
-
def copy(self):
|
3108
|
-
"""Returns a shallow copy of this node."""
|
3109
|
-
return VariableRef(
|
3110
|
-
variable=self._attr_variable
|
3111
|
-
)
|
3112
|
-
|
3113
|
-
def clone(self):
|
3114
|
-
"""Returns a deep copy of this node. This mimics the C++ interface,
|
3115
|
-
deficiencies with links included; that is, links always point to the
|
3116
|
-
original tree. If you're not cloning a subtree in a context where this
|
3117
|
-
is the desired behavior, you may want to use the copy.deepcopy() from
|
3118
|
-
the stdlib instead, which should copy links correctly."""
|
3119
|
-
return VariableRef(
|
3120
|
-
variable=self._attr_variable
|
3121
|
-
)
|
3122
|
-
|
3123
|
-
@staticmethod
|
3124
|
-
def _deserialize(cbor, seq_to_ob, links):
|
3125
|
-
"""Attempts to deserialize the given cbor object (in Python primitive
|
3126
|
-
representation) into a node of this type. All (sub)nodes are added to
|
3127
|
-
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
3128
|
-
registered in the links list by means of a two-tuple of the setter
|
3129
|
-
function for the link field and the sequence number of the target node.
|
3130
|
-
"""
|
3131
|
-
if not isinstance(cbor, dict):
|
3132
|
-
raise TypeError('node description object must be a dict')
|
3133
|
-
typ = cbor.get('@t', None)
|
3134
|
-
if typ is None:
|
3135
|
-
raise ValueError('type (@t) field is missing from node serialization')
|
3136
|
-
if typ != 'VariableRef':
|
3137
|
-
raise ValueError('found node serialization for ' + typ + ', but expected VariableRef')
|
3138
|
-
|
3139
|
-
# Deserialize the variable field.
|
3140
|
-
field = cbor.get('variable', None)
|
3141
|
-
if not isinstance(field, dict):
|
3142
|
-
raise ValueError('missing or invalid serialization of field variable')
|
3143
|
-
if field.get('@T') != '$':
|
3144
|
-
raise ValueError('unexpected edge type for field variable')
|
3145
|
-
f_variable = None
|
3146
|
-
l_variable = field.get('@l', None)
|
3147
|
-
|
3148
|
-
# Construct the VariableRef node.
|
3149
|
-
node = VariableRef(f_variable)
|
3150
|
-
|
3151
|
-
# Register links to be made after tree construction.
|
3152
|
-
links.append((lambda val: VariableRef.variable.fset(node, val), l_variable))
|
3153
|
-
|
3154
|
-
# Deserialize annotations.
|
3155
|
-
for key, val in cbor.items():
|
3156
|
-
if not (key.startswith('{') and key.endswith('}')):
|
3157
|
-
continue
|
3158
|
-
key = key[1:-1]
|
3159
|
-
node[key] = cqasm.v1x.primitives.deserialize(key, val)
|
3160
|
-
|
3161
|
-
# Register node in sequence number lookup.
|
3162
|
-
seq = cbor.get('@i', None)
|
3163
|
-
if not isinstance(seq, int):
|
3164
|
-
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
3165
|
-
if seq in seq_to_ob:
|
3166
|
-
raise ValueError('duplicate sequence number %d' % seq)
|
3167
|
-
seq_to_ob[seq] = node
|
3168
|
-
|
3169
|
-
return node
|
3170
|
-
|
3171
|
-
def _serialize(self, id_map):
|
3172
|
-
"""Serializes this node to the Python primitive representation of its
|
3173
|
-
CBOR serialization. The tree that the node belongs to must be
|
3174
|
-
well-formed. id_map must match Python id() calls for all nodes to unique
|
3175
|
-
integers, to use for the sequence number representation of links."""
|
3176
|
-
cbor = {'@i': id_map[id(self)], '@t': 'VariableRef'}
|
3177
|
-
|
3178
|
-
# Serialize the variable field.
|
3179
|
-
field = {'@T': '$'}
|
3180
|
-
if self._attr_variable is None:
|
3181
|
-
field['@l'] = None
|
3182
|
-
else:
|
3183
|
-
field['@l'] = id_map[id(self._attr_variable)]
|
3184
|
-
cbor['variable'] = field
|
3185
|
-
|
3186
|
-
# Serialize annotations.
|
3187
|
-
for key, val in self._annot.items():
|
3188
|
-
cbor['{%s}' % key] = _py_to_cbor(cqasm.v1x.primitives.serialize(key, val))
|
3189
|
-
|
3190
|
-
return cbor
|
3191
|
-
|
3192
|
-
|
3193
|
-
class MultiVariableRef(_Multiple):
|
3194
|
-
"""Wrapper for an edge with multiple VariableRef objects."""
|
3195
|
-
|
3196
|
-
_T = VariableRef
|
3197
|
-
|
3198
|
-
|
3199
|
-
_typemap['VariableRef'] = VariableRef
|
3200
|
-
|