libqasm 0.6.6__cp39-cp39-win_amd64.whl → 0.6.7__cp39-cp39-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/__init__.py +71 -22
- cqasm/v3x/ast.py +298 -0
- cqasm/v3x/primitives.py +5 -0
- libqasm/_libqasm.cp39-win_amd64.pyd +0 -0
- libqasm/libqasm.py +6 -6
- libqasm-0.6.7.dist-info/METADATA +127 -0
- libqasm-0.6.7.dist-info/RECORD +16 -0
- {libqasm-0.6.6.dist-info → libqasm-0.6.7.dist-info}/WHEEL +1 -1
- libqasm-0.6.6.dist-info/METADATA +0 -224
- libqasm-0.6.6.dist-info/RECORD +0 -16
- {libqasm-0.6.6.dist-info → libqasm-0.6.7.dist-info}/LICENSE.md +0 -0
- {libqasm-0.6.6.dist-info → libqasm-0.6.7.dist-info}/top_level.txt +0 -0
cqasm/v3x/__init__.py
CHANGED
@@ -4,16 +4,58 @@ import libqasm
|
|
4
4
|
|
5
5
|
|
6
6
|
class Analyzer(libqasm.V3xAnalyzer):
|
7
|
-
|
8
|
-
|
9
|
-
# analyze_file and analyze_string are not static methods because they change the status of the analyzer
|
7
|
+
"""!
|
8
|
+
Main class for parsing and analyzing cQASM v3.0 files.
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
This class works as a binding for accessing C++ code from Python.
|
11
|
+
|
12
|
+
The parsing methods are static because they do not change the status of the analyzer.
|
13
|
+
Instead, they just invoke free functions that create a temporary instance of a parser.
|
14
|
+
|
15
|
+
None of the parsing or the analyzing methods perform any version check.
|
16
|
+
|
17
|
+
`parse_file`, `parse_string`, `analyze_file`, and `analyze_string`:
|
18
|
+
|
19
|
+
- return a vector of strings.
|
20
|
+
If the length of the vector is 1, the string is a serialization
|
21
|
+
of the syntactic/semantic (in the case of parsing/analyzing) Abstract Syntax Tree (AST)
|
22
|
+
of the input program.
|
23
|
+
Otherwise, it is a list of errors.
|
24
|
+
|
25
|
+
`parse_file_to_json`, `parse_string_to_json`, `analyze_file_to_json`, and `analyze_string_to_json`:
|
26
|
+
|
27
|
+
- return a string in JSON format.
|
28
|
+
If the parsing was successful, the string contains a JSON representation
|
29
|
+
of the AST of the input program.
|
30
|
+
Otherwise, it will contain a list of errors.
|
31
|
+
The JSON representation of each error follows the Language Server Protocol (LSP) specification.
|
32
|
+
Every error is mapped to an LSP Diagnostic structure:
|
33
|
+
`severity` is hardcoded to 1 at the moment (value corresponding to an Error level).
|
34
|
+
|
35
|
+
`parse_string`, `parse_string_to_json`, `analyze_string, and `analyze_string_to_json`:
|
36
|
+
|
37
|
+
- have an optional second argument: `file_name`. It is only used when reporting errors.
|
38
|
+
|
39
|
+
**Example**:
|
40
|
+
|
41
|
+
result = libqasm.analyze_file("grover.cq");
|
42
|
+
|
43
|
+
**Example**:
|
44
|
+
|
45
|
+
program = r'''
|
46
|
+
version 3.0
|
47
|
+
qubit[2] q
|
48
|
+
bit[2] b
|
49
|
+
H q[0]
|
50
|
+
CNOT q[0], q[1]
|
51
|
+
b = measure q
|
52
|
+
'''
|
53
|
+
result = libqasm.parse_string_to_json(program, "bell.cq");
|
54
|
+
"""
|
14
55
|
|
15
56
|
@staticmethod
|
16
|
-
def parse_file(*args):
|
57
|
+
def parse_file(*args) -> list[str]:
|
58
|
+
"""! Parses a file containing a cQASM v3.0 program."""
|
17
59
|
ret = libqasm.V3xAnalyzer.parse_file(*args)
|
18
60
|
if len(ret) == 1:
|
19
61
|
serialized_ast_str = str(ret[0])
|
@@ -23,7 +65,13 @@ class Analyzer(libqasm.V3xAnalyzer):
|
|
23
65
|
return [str(error) for error in ret[1:]]
|
24
66
|
|
25
67
|
@staticmethod
|
26
|
-
def
|
68
|
+
def parse_file_to_json(*args) -> str:
|
69
|
+
"""! Parses a file containing a cQASM v3.0 program."""
|
70
|
+
return libqasm.V3xAnalyzer.parse_file_to_json(*args)
|
71
|
+
|
72
|
+
@staticmethod
|
73
|
+
def parse_string(*args) -> list[str]:
|
74
|
+
"""! Parses a string containing a cQASM v3.0 program."""
|
27
75
|
ret = libqasm.V3xAnalyzer.parse_string(*args)
|
28
76
|
if len(ret) == 1:
|
29
77
|
serialized_ast_str = str(ret[0])
|
@@ -32,7 +80,13 @@ class Analyzer(libqasm.V3xAnalyzer):
|
|
32
80
|
return deserialized_ast
|
33
81
|
return [str(error) for error in ret[1:]]
|
34
82
|
|
35
|
-
|
83
|
+
@staticmethod
|
84
|
+
def parse_string_to_json(*args) -> str:
|
85
|
+
"""! Parses a string containing a cQASM v3.0 program."""
|
86
|
+
return libqasm.V3xAnalyzer.parse_string_to_json(*args)
|
87
|
+
|
88
|
+
def analyze_file(self, *args) -> list[str]:
|
89
|
+
"""! Parses and analyzes a file containing a cQASM v3.0 program."""
|
36
90
|
ret = super().analyze_file(*args)
|
37
91
|
if len(ret) == 1:
|
38
92
|
serialized_ast_str = str(ret[0])
|
@@ -41,7 +95,12 @@ class Analyzer(libqasm.V3xAnalyzer):
|
|
41
95
|
return deserialized_ast
|
42
96
|
return [str(error) for error in ret[1:]]
|
43
97
|
|
44
|
-
def
|
98
|
+
def analyze_file_to_json(self, *args) -> str:
|
99
|
+
"""! Parses and analyzes a file containing a cQASM v3.0 program."""
|
100
|
+
return super().analyze_file_to_json(*args)
|
101
|
+
|
102
|
+
def analyze_string(self, *args) -> list[str]:
|
103
|
+
"""! Parses and analyzes a string containing a cQASM v3.0 program."""
|
45
104
|
ret = super().analyze_string(*args)
|
46
105
|
if len(ret) == 1:
|
47
106
|
serialized_ast_str = str(ret[0])
|
@@ -50,16 +109,6 @@ class Analyzer(libqasm.V3xAnalyzer):
|
|
50
109
|
return deserialized_ast
|
51
110
|
return [str(error) for error in ret[1:]]
|
52
111
|
|
53
|
-
|
54
|
-
|
55
|
-
return libqasm.V3xAnalyzer.parse_file_to_json(*args)
|
56
|
-
|
57
|
-
@staticmethod
|
58
|
-
def parse_string_to_json(*args):
|
59
|
-
return libqasm.V3xAnalyzer.parse_string_to_json(*args)
|
60
|
-
|
61
|
-
def analyze_file_to_json(self, *args):
|
62
|
-
return super().analyze_file_to_json(*args)
|
63
|
-
|
64
|
-
def analyze_string_to_json(self, *args):
|
112
|
+
def analyze_string_to_json(self, *args) -> str:
|
113
|
+
"""! Parses and analyzes a string containing a cQASM v3.0 program."""
|
65
114
|
return super().analyze_string_to_json(*args)
|
cqasm/v3x/ast.py
CHANGED
@@ -1172,6 +1172,8 @@ class Annotated(Node):
|
|
1172
1172
|
return Gate._deserialize(cbor, seq_to_ob, links)
|
1173
1173
|
if typ == 'MeasureInstruction':
|
1174
1174
|
return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
|
1175
|
+
if typ == 'ResetInstruction':
|
1176
|
+
return ResetInstruction._deserialize(cbor, seq_to_ob, links)
|
1175
1177
|
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
1176
1178
|
|
1177
1179
|
def _serialize(self, id_map):
|
@@ -2526,6 +2528,8 @@ class Statement(Annotated):
|
|
2526
2528
|
return Gate._deserialize(cbor, seq_to_ob, links)
|
2527
2529
|
if typ == 'MeasureInstruction':
|
2528
2530
|
return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
|
2531
|
+
if typ == 'ResetInstruction':
|
2532
|
+
return ResetInstruction._deserialize(cbor, seq_to_ob, links)
|
2529
2533
|
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
2530
2534
|
|
2531
2535
|
def _serialize(self, id_map):
|
@@ -2588,6 +2592,8 @@ class BlockStatement(Statement):
|
|
2588
2592
|
return Gate._deserialize(cbor, seq_to_ob, links)
|
2589
2593
|
if typ == 'MeasureInstruction':
|
2590
2594
|
return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
|
2595
|
+
if typ == 'ResetInstruction':
|
2596
|
+
return ResetInstruction._deserialize(cbor, seq_to_ob, links)
|
2591
2597
|
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
2592
2598
|
|
2593
2599
|
def _serialize(self, id_map):
|
@@ -5003,6 +5009,8 @@ class Instruction(BlockStatement):
|
|
5003
5009
|
return Gate._deserialize(cbor, seq_to_ob, links)
|
5004
5010
|
if typ == 'MeasureInstruction':
|
5005
5011
|
return MeasureInstruction._deserialize(cbor, seq_to_ob, links)
|
5012
|
+
if typ == 'ResetInstruction':
|
5013
|
+
return ResetInstruction._deserialize(cbor, seq_to_ob, links)
|
5006
5014
|
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
5007
5015
|
|
5008
5016
|
def _serialize(self, id_map):
|
@@ -9089,6 +9097,296 @@ class MultiProgram(_Multiple):
|
|
9089
9097
|
|
9090
9098
|
_typemap['Program'] = Program
|
9091
9099
|
|
9100
|
+
class ResetInstruction(Instruction):
|
9101
|
+
__slots__ = [
|
9102
|
+
'_attr_name',
|
9103
|
+
'_attr_operand',
|
9104
|
+
]
|
9105
|
+
|
9106
|
+
def __init__(
|
9107
|
+
self,
|
9108
|
+
name=None,
|
9109
|
+
operand=None,
|
9110
|
+
annotations=None,
|
9111
|
+
):
|
9112
|
+
super().__init__(annotations=annotations)
|
9113
|
+
self.name = name
|
9114
|
+
self.operand = operand
|
9115
|
+
|
9116
|
+
@property
|
9117
|
+
def name(self):
|
9118
|
+
return self._attr_name
|
9119
|
+
|
9120
|
+
@name.setter
|
9121
|
+
def name(self, val):
|
9122
|
+
if val is None:
|
9123
|
+
del self.name
|
9124
|
+
return
|
9125
|
+
if not isinstance(val, Identifier):
|
9126
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
9127
|
+
if isinstance(val, Node):
|
9128
|
+
raise TypeError('name must be of type Identifier')
|
9129
|
+
val = Identifier(val)
|
9130
|
+
self._attr_name = val
|
9131
|
+
|
9132
|
+
@name.deleter
|
9133
|
+
def name(self):
|
9134
|
+
self._attr_name = None
|
9135
|
+
|
9136
|
+
@property
|
9137
|
+
def operand(self):
|
9138
|
+
return self._attr_operand
|
9139
|
+
|
9140
|
+
@operand.setter
|
9141
|
+
def operand(self, val):
|
9142
|
+
if val is None:
|
9143
|
+
del self.operand
|
9144
|
+
return
|
9145
|
+
if not isinstance(val, Expression):
|
9146
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
9147
|
+
if isinstance(val, Node):
|
9148
|
+
raise TypeError('operand must be of type Expression')
|
9149
|
+
val = Expression(val)
|
9150
|
+
self._attr_operand = val
|
9151
|
+
|
9152
|
+
@operand.deleter
|
9153
|
+
def operand(self):
|
9154
|
+
self._attr_operand = None
|
9155
|
+
|
9156
|
+
def __eq__(self, other):
|
9157
|
+
"""Equality operator. Ignores annotations!"""
|
9158
|
+
if not isinstance(other, ResetInstruction):
|
9159
|
+
return False
|
9160
|
+
if self.name != other.name:
|
9161
|
+
return False
|
9162
|
+
if self.operand != other.operand:
|
9163
|
+
return False
|
9164
|
+
if self.annotations != other.annotations:
|
9165
|
+
return False
|
9166
|
+
return True
|
9167
|
+
|
9168
|
+
def dump(self, indent=0, annotations=None, links=1):
|
9169
|
+
"""Returns a debug representation of this tree as a multiline string.
|
9170
|
+
indent is the number of double spaces prefixed before every line.
|
9171
|
+
annotations, if specified, must be a set-like object containing the key
|
9172
|
+
strings of the annotations that are to be printed. links specifies the
|
9173
|
+
maximum link recursion depth."""
|
9174
|
+
s = [' '*indent]
|
9175
|
+
s.append('ResetInstruction(')
|
9176
|
+
if annotations is None:
|
9177
|
+
annotations = []
|
9178
|
+
for key in annotations:
|
9179
|
+
if key in self:
|
9180
|
+
s.append(' # {}: {}'.format(key, self[key]))
|
9181
|
+
s.append('\n')
|
9182
|
+
indent += 1
|
9183
|
+
s.append(' '*indent)
|
9184
|
+
s.append('name: ')
|
9185
|
+
if self.name is None:
|
9186
|
+
s.append('!MISSING\n')
|
9187
|
+
else:
|
9188
|
+
s.append('<\n')
|
9189
|
+
s.append(self.name.dump(indent + 1, annotations, links) + '\n')
|
9190
|
+
s.append(' '*indent + '>\n')
|
9191
|
+
s.append(' '*indent)
|
9192
|
+
s.append('operand: ')
|
9193
|
+
if self.operand is None:
|
9194
|
+
s.append('-\n')
|
9195
|
+
else:
|
9196
|
+
s.append('<\n')
|
9197
|
+
s.append(self.operand.dump(indent + 1, annotations, links) + '\n')
|
9198
|
+
s.append(' '*indent + '>\n')
|
9199
|
+
s.append(' '*indent)
|
9200
|
+
s.append('annotations: ')
|
9201
|
+
if not self.annotations:
|
9202
|
+
s.append('-\n')
|
9203
|
+
else:
|
9204
|
+
s.append('[\n')
|
9205
|
+
for child in self.annotations:
|
9206
|
+
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
9207
|
+
s.append(' '*indent + ']\n')
|
9208
|
+
indent -= 1
|
9209
|
+
s.append(' '*indent)
|
9210
|
+
s.append(')')
|
9211
|
+
return ''.join(s)
|
9212
|
+
|
9213
|
+
__str__ = dump
|
9214
|
+
__repr__ = dump
|
9215
|
+
|
9216
|
+
def find_reachable(self, id_map=None):
|
9217
|
+
"""Returns a dictionary mapping Python id() values to stable sequence
|
9218
|
+
numbers for all nodes in the tree rooted at this node. If id_map is
|
9219
|
+
specified, found nodes are appended to it."""
|
9220
|
+
if id_map is None:
|
9221
|
+
id_map = {}
|
9222
|
+
if id(self) in id_map:
|
9223
|
+
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
9224
|
+
id_map[id(self)] = len(id_map)
|
9225
|
+
if self._attr_name is not None:
|
9226
|
+
self._attr_name.find_reachable(id_map)
|
9227
|
+
if self._attr_operand is not None:
|
9228
|
+
self._attr_operand.find_reachable(id_map)
|
9229
|
+
for el in self._attr_annotations:
|
9230
|
+
el.find_reachable(id_map)
|
9231
|
+
return id_map
|
9232
|
+
|
9233
|
+
def check_complete(self, id_map=None):
|
9234
|
+
"""Raises NotWellFormed if the tree rooted at this node is not
|
9235
|
+
well-formed. If id_map is specified, this tree is only a subtree in the
|
9236
|
+
context of a larger tree, and id_map must be a dict mapping from Python
|
9237
|
+
id() codes to tree indices for all reachable nodes."""
|
9238
|
+
if id_map is None:
|
9239
|
+
id_map = self.find_reachable()
|
9240
|
+
if self._attr_name is None:
|
9241
|
+
raise NotWellFormed('name is required but not set')
|
9242
|
+
if self._attr_name is not None:
|
9243
|
+
self._attr_name.check_complete(id_map)
|
9244
|
+
if self._attr_operand is not None:
|
9245
|
+
self._attr_operand.check_complete(id_map)
|
9246
|
+
for child in self._attr_annotations:
|
9247
|
+
child.check_complete(id_map)
|
9248
|
+
|
9249
|
+
def copy(self):
|
9250
|
+
"""Returns a shallow copy of this node."""
|
9251
|
+
return ResetInstruction(
|
9252
|
+
name=self._attr_name,
|
9253
|
+
operand=self._attr_operand,
|
9254
|
+
annotations=self._attr_annotations.copy()
|
9255
|
+
)
|
9256
|
+
|
9257
|
+
def clone(self):
|
9258
|
+
"""Returns a deep copy of this node. This mimics the C++ interface,
|
9259
|
+
deficiencies with links included; that is, links always point to the
|
9260
|
+
original tree. If you're not cloning a subtree in a context where this
|
9261
|
+
is the desired behavior, you may want to use the copy.deepcopy() from
|
9262
|
+
the stdlib instead, which should copy links correctly."""
|
9263
|
+
return ResetInstruction(
|
9264
|
+
name=_cloned(self._attr_name),
|
9265
|
+
operand=_cloned(self._attr_operand),
|
9266
|
+
annotations=_cloned(self._attr_annotations)
|
9267
|
+
)
|
9268
|
+
|
9269
|
+
@staticmethod
|
9270
|
+
def _deserialize(cbor, seq_to_ob, links):
|
9271
|
+
"""Attempts to deserialize the given cbor object (in Python primitive
|
9272
|
+
representation) into a node of this type. All (sub)nodes are added to
|
9273
|
+
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
9274
|
+
registered in the links list by means of a two-tuple of the setter
|
9275
|
+
function for the link field and the sequence number of the target node.
|
9276
|
+
"""
|
9277
|
+
if not isinstance(cbor, dict):
|
9278
|
+
raise TypeError('node description object must be a dict')
|
9279
|
+
typ = cbor.get('@t', None)
|
9280
|
+
if typ is None:
|
9281
|
+
raise ValueError('type (@t) field is missing from node serialization')
|
9282
|
+
if typ != 'ResetInstruction':
|
9283
|
+
raise ValueError('found node serialization for ' + typ + ', but expected ResetInstruction')
|
9284
|
+
|
9285
|
+
# Deserialize the name field.
|
9286
|
+
field = cbor.get('name', None)
|
9287
|
+
if not isinstance(field, dict):
|
9288
|
+
raise ValueError('missing or invalid serialization of field name')
|
9289
|
+
if field.get('@T') != '1':
|
9290
|
+
raise ValueError('unexpected edge type for field name')
|
9291
|
+
if field.get('@t', None) is None:
|
9292
|
+
f_name = None
|
9293
|
+
else:
|
9294
|
+
f_name = Identifier._deserialize(field, seq_to_ob, links)
|
9295
|
+
|
9296
|
+
# Deserialize the operand field.
|
9297
|
+
field = cbor.get('operand', None)
|
9298
|
+
if not isinstance(field, dict):
|
9299
|
+
raise ValueError('missing or invalid serialization of field operand')
|
9300
|
+
if field.get('@T') != '?':
|
9301
|
+
raise ValueError('unexpected edge type for field operand')
|
9302
|
+
if field.get('@t', None) is None:
|
9303
|
+
f_operand = None
|
9304
|
+
else:
|
9305
|
+
f_operand = Expression._deserialize(field, seq_to_ob, links)
|
9306
|
+
|
9307
|
+
# Deserialize the annotations field.
|
9308
|
+
field = cbor.get('annotations', None)
|
9309
|
+
if not isinstance(field, dict):
|
9310
|
+
raise ValueError('missing or invalid serialization of field annotations')
|
9311
|
+
if field.get('@T') != '*':
|
9312
|
+
raise ValueError('unexpected edge type for field annotations')
|
9313
|
+
data = field.get('@d', None)
|
9314
|
+
if not isinstance(data, list):
|
9315
|
+
raise ValueError('missing serialization of Any/Many contents')
|
9316
|
+
f_annotations = MultiAnnotationData()
|
9317
|
+
for element in data:
|
9318
|
+
if element.get('@T') != '1':
|
9319
|
+
raise ValueError('unexpected edge type for Any/Many element')
|
9320
|
+
f_annotations.append(AnnotationData._deserialize(element, seq_to_ob, links))
|
9321
|
+
|
9322
|
+
# Construct the ResetInstruction node.
|
9323
|
+
node = ResetInstruction(f_name, f_operand, f_annotations)
|
9324
|
+
|
9325
|
+
# Deserialize annotations.
|
9326
|
+
for key, val in cbor.items():
|
9327
|
+
if not (key.startswith('{') and key.endswith('}')):
|
9328
|
+
continue
|
9329
|
+
key = key[1:-1]
|
9330
|
+
node[key] = cqasm.v3x.primitives.deserialize(key, val)
|
9331
|
+
|
9332
|
+
# Register node in sequence number lookup.
|
9333
|
+
seq = cbor.get('@i', None)
|
9334
|
+
if not isinstance(seq, int):
|
9335
|
+
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
9336
|
+
if seq in seq_to_ob:
|
9337
|
+
raise ValueError('duplicate sequence number %d' % seq)
|
9338
|
+
seq_to_ob[seq] = node
|
9339
|
+
|
9340
|
+
return node
|
9341
|
+
|
9342
|
+
def _serialize(self, id_map):
|
9343
|
+
"""Serializes this node to the Python primitive representation of its
|
9344
|
+
CBOR serialization. The tree that the node belongs to must be
|
9345
|
+
well-formed. id_map must match Python id() calls for all nodes to unique
|
9346
|
+
integers, to use for the sequence number representation of links."""
|
9347
|
+
cbor = {'@i': id_map[id(self)], '@t': 'ResetInstruction'}
|
9348
|
+
|
9349
|
+
# Serialize the name field.
|
9350
|
+
field = {'@T': '1'}
|
9351
|
+
if self._attr_name is None:
|
9352
|
+
field['@t'] = None
|
9353
|
+
else:
|
9354
|
+
field.update(self._attr_name._serialize(id_map))
|
9355
|
+
cbor['name'] = field
|
9356
|
+
|
9357
|
+
# Serialize the operand field.
|
9358
|
+
field = {'@T': '?'}
|
9359
|
+
if self._attr_operand is None:
|
9360
|
+
field['@t'] = None
|
9361
|
+
else:
|
9362
|
+
field.update(self._attr_operand._serialize(id_map))
|
9363
|
+
cbor['operand'] = field
|
9364
|
+
|
9365
|
+
# Serialize the annotations field.
|
9366
|
+
field = {'@T': '*'}
|
9367
|
+
lst = []
|
9368
|
+
for el in self._attr_annotations:
|
9369
|
+
el = el._serialize(id_map)
|
9370
|
+
el['@T'] = '1'
|
9371
|
+
lst.append(el)
|
9372
|
+
field['@d'] = lst
|
9373
|
+
cbor['annotations'] = field
|
9374
|
+
|
9375
|
+
# Serialize annotations.
|
9376
|
+
for key, val in self._annot.items():
|
9377
|
+
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
9378
|
+
|
9379
|
+
return cbor
|
9380
|
+
|
9381
|
+
|
9382
|
+
class MultiResetInstruction(_Multiple):
|
9383
|
+
"""Wrapper for an edge with multiple ResetInstruction objects."""
|
9384
|
+
|
9385
|
+
_T = ResetInstruction
|
9386
|
+
|
9387
|
+
|
9388
|
+
_typemap['ResetInstruction'] = ResetInstruction
|
9389
|
+
|
9092
9390
|
class ShiftExpression(BinaryExpression):
|
9093
9391
|
__slots__ = []
|
9094
9392
|
|
cqasm/v3x/primitives.py
CHANGED
@@ -45,6 +45,11 @@ def serialize(typ, val):
|
|
45
45
|
def deserialize(typ, val):
|
46
46
|
if isinstance(typ, str):
|
47
47
|
return None
|
48
|
+
elif typ is Str and isinstance(val['x'], bytes):
|
49
|
+
# CBOR strings are bytes objects. The correct conversion to Str would be through a decoding.
|
50
|
+
# Str(b'qubit', 'utf-8') would generate the string "qubit". This is the same as b'qubit'.decode('utf-8')
|
51
|
+
# Whereas Str(b'qubit') would generate the string "b'qubit'"
|
52
|
+
return Str(val['x'], 'utf-8')
|
48
53
|
elif typ is Str:
|
49
54
|
return Str(val['x'])
|
50
55
|
elif typ is Bool:
|
Binary file
|
libqasm/libqasm.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# This file was automatically generated by SWIG (https://www.swig.org).
|
2
|
-
# Version 4.
|
2
|
+
# Version 4.2.1
|
3
3
|
#
|
4
4
|
# Do not make changes to this file unless you know what you are doing - modify
|
5
5
|
# the SWIG interface file instead.
|
@@ -443,11 +443,6 @@ class ostream(ios):
|
|
443
443
|
|
444
444
|
# Register ostream in _libqasm:
|
445
445
|
_libqasm.ostream_swigregister(ostream)
|
446
|
-
cin = cvar.cin
|
447
|
-
cout = cvar.cout
|
448
|
-
cerr = cvar.cerr
|
449
|
-
clog = cvar.clog
|
450
|
-
|
451
446
|
class istream(ios):
|
452
447
|
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
|
453
448
|
__repr__ = _swig_repr
|
@@ -507,6 +502,11 @@ class iostream(istream, ostream):
|
|
507
502
|
|
508
503
|
# Register iostream in _libqasm:
|
509
504
|
_libqasm.iostream_swigregister(iostream)
|
505
|
+
cin = cvar.cin
|
506
|
+
cout = cvar.cout
|
507
|
+
cerr = cvar.cerr
|
508
|
+
clog = cvar.clog
|
509
|
+
|
510
510
|
endl_cb_ptr = _libqasm.endl_cb_ptr
|
511
511
|
endl = _libqasm.endl
|
512
512
|
ends_cb_ptr = _libqasm.ends_cb_ptr
|
@@ -0,0 +1,127 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: libqasm
|
3
|
+
Version: 0.6.7
|
4
|
+
Summary: libqasm Python Package
|
5
|
+
Home-page: https://github.com/QuTech-Delft/libqasm
|
6
|
+
Author: QuTech, TU Delft
|
7
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
8
|
+
Classifier: Operating System :: POSIX :: Linux
|
9
|
+
Classifier: Operating System :: MacOS
|
10
|
+
Classifier: Operating System :: Microsoft :: Windows
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
17
|
+
Description-Content-Type: text/markdown
|
18
|
+
License-File: LICENSE.md
|
19
|
+
Requires-Dist: numpy
|
20
|
+
|
21
|
+
# libQASM
|
22
|
+
|
23
|
+
[](https://github.com/qutech-delft/libqasm/actions)
|
24
|
+
[](https://conan.io/center/recipes/libqasm)
|
25
|
+
[](https://pypi.org/project/libqasm/)
|
26
|
+

|
27
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
28
|
+
|
29
|
+
libQASM is a library to parse programs written in the cQASM quantum programming language, developed by QuTech.
|
30
|
+
At the moment, libQASM only supports cQASM v3.0 programs.
|
31
|
+
|
32
|
+
It performs lexical, syntactic, and semantic analysis of an input program received via a file or a string.
|
33
|
+
It produces one of the following results:
|
34
|
+
|
35
|
+
- A syntactic or semantic AST (Abstract Syntax Tree) object. Depending on if we are parsing or analysing.
|
36
|
+
- A list of parsing or analysing errors. In case the input program was malformed.
|
37
|
+
- A JSON representation of either the AST or the list of errors.
|
38
|
+
|
39
|
+
It can be used within:
|
40
|
+
|
41
|
+
- C++ projects (as a [Conan package](https://conan.io/center/recipes/libqasm)).
|
42
|
+
- Python projects (as a [Python package](https://pypi.org/project/libqasm/)).
|
43
|
+
- Emscripten projects (via a Typescript frontend).
|
44
|
+
|
45
|
+
Check out [QX simulator](https://github.com/QuTech-Delft/qx-simulator)
|
46
|
+
and [OpenSquirrel](https://github.com/QuTech-Delft/OpenSquirrel) compiler
|
47
|
+
for an example of use in a C++ and a Python project, respectively.
|
48
|
+
|
49
|
+
## Getting started
|
50
|
+
|
51
|
+
Given a cQASM program `example.cq`.
|
52
|
+
|
53
|
+
```cQASM
|
54
|
+
version 3.0
|
55
|
+
|
56
|
+
qubit[2] q
|
57
|
+
bit[2] b
|
58
|
+
|
59
|
+
H q[0]
|
60
|
+
CNOT q[0], q[1]
|
61
|
+
b = measure q
|
62
|
+
```
|
63
|
+
|
64
|
+
We can parse or analyze this circuit, using libQASM through the following programming language:
|
65
|
+
|
66
|
+
### C++
|
67
|
+
|
68
|
+
```cpp
|
69
|
+
#include "v3/cqasm-py.hpp"
|
70
|
+
|
71
|
+
int main() {
|
72
|
+
auto parse_result = V3xAnalyzer::parse_file("example.cq");
|
73
|
+
|
74
|
+
auto analyzer = V3xAnalyzer();
|
75
|
+
auto analysis_result = analyzer.analyze_file("example.cq");
|
76
|
+
}
|
77
|
+
```
|
78
|
+
|
79
|
+
|
80
|
+
### Emscripten
|
81
|
+
|
82
|
+
The emscripten API only allows to input a cQASM program as a string.
|
83
|
+
|
84
|
+
```typescript
|
85
|
+
import { default as wrapper } from 'cqasm_emscripten.mjs';
|
86
|
+
|
87
|
+
wrapper().then(function(result: any) {
|
88
|
+
let analyzer = new result["EmscriptenWrapper"]()
|
89
|
+
let program = `
|
90
|
+
version 3
|
91
|
+
qubit[2] q
|
92
|
+
bit[2] b
|
93
|
+
H q[0]
|
94
|
+
CNOT q[0], q[1]
|
95
|
+
b = measure q
|
96
|
+
`
|
97
|
+
let output = analyzer.parse_string_to_json(program)
|
98
|
+
analyzer.delete()
|
99
|
+
}).catch((error: any) => {
|
100
|
+
console.error("unhandledRejection", error, "\n");
|
101
|
+
});
|
102
|
+
```
|
103
|
+
|
104
|
+
### Python
|
105
|
+
|
106
|
+
```python
|
107
|
+
from libqasm import Analyzer
|
108
|
+
|
109
|
+
if __name__ == "__main__":
|
110
|
+
parse_result = Analyzer.parse_file('example.cq')
|
111
|
+
|
112
|
+
analyzer = Analyzer()
|
113
|
+
analysis_result = analyzer.analyze_file('example.cq')
|
114
|
+
```
|
115
|
+
|
116
|
+
## Documentation
|
117
|
+
|
118
|
+
The [libQASM documentation](https://QuTech-Delft.github.io/libqasm/) is hosted through GitHub Pages.
|
119
|
+
|
120
|
+
## License
|
121
|
+
|
122
|
+
libQASM is licensed under the Apache License, Version 2.0.
|
123
|
+
See [LICENSE](https://github.com/QuTech-Delft/libqasm/blob/master/LICENSE.md) for the full license text.
|
124
|
+
|
125
|
+
## Authors
|
126
|
+
|
127
|
+
Quantum Inspire: [support@quantum-inspire.com](mailto:"support@quantum-inspire.com")
|
@@ -0,0 +1,16 @@
|
|
1
|
+
cqasm/__init__.py,sha256=_6Yl-eMBve0mGQA-aiFg4qvQ7GUCV5eGvIcoRf4mEPw,3
|
2
|
+
cqasm/v3x/__init__.py,sha256=7TEhDqL-4KxL_9nUkjOWYvgo9nOOY1YiDusYP2Bf8tU,4890
|
3
|
+
cqasm/v3x/ast.py,sha256=Zng-B1PS3WLQ21WFnlTmlQli9Fe4SWh5XBaILtfzzkg,431665
|
4
|
+
cqasm/v3x/instruction.py,sha256=VAOqFpCH94CrutgMUZnQq8JXFIq_-C-ndTOjHLsg6_8,1219
|
5
|
+
cqasm/v3x/primitives.py,sha256=lkxg0gHMFba-O803cOh0QqOANFHsZDK0iHvIluFz-qI,2110
|
6
|
+
cqasm/v3x/semantic.py,sha256=wN9awUdn76sNp1WlzV5P4R4Z54r-W0JC4D-xaDzQec4,88679
|
7
|
+
cqasm/v3x/types.py,sha256=krT1WB5URT0F7lhKTLwYAs_UtTCn9CZ7-M0WMGmxtU4,65070
|
8
|
+
cqasm/v3x/values.py,sha256=SfKw6zIjpMrXJggvN_QGPqsoZXDR7HwUjgUMOBnIzuo,63394
|
9
|
+
libqasm/__init__.py,sha256=X0G-HBFW9_uEcsaGROQ1nzxYfHzSuglOiXrpTpjF9_E,752
|
10
|
+
libqasm/_libqasm.cp39-win_amd64.pyd,sha256=4wHZ4r_JNkikT-7ewElNxA8I64_gUIFm1QVxfv6wIKY,2302464
|
11
|
+
libqasm/libqasm.py,sha256=s0RWrMGoy0vl-lES8ff61BLCa-Rv0FRlQFnaw40u7T0,31677
|
12
|
+
libqasm-0.6.7.dist-info/LICENSE.md,sha256=395F6Sje50f5Too7yWFAoS_owYO4aOtjbMeQd_go_sk,579
|
13
|
+
libqasm-0.6.7.dist-info/METADATA,sha256=2jnb_TDMrtMvYqgg6fTZXVIkmQFFn-j8A6wIRGb_E0A,4094
|
14
|
+
libqasm-0.6.7.dist-info/WHEEL,sha256=Os6_QENWp0Y99Uhn6SmX8k6DheJPHPoZtAIvme4kS_I,99
|
15
|
+
libqasm-0.6.7.dist-info/top_level.txt,sha256=iZ8PSLyg3lJwvSUCvWE8VCJGU-nmQY2YIrbMe7M7kLw,14
|
16
|
+
libqasm-0.6.7.dist-info/RECORD,,
|
libqasm-0.6.6.dist-info/METADATA
DELETED
@@ -1,224 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: libqasm
|
3
|
-
Version: 0.6.6
|
4
|
-
Summary: libqasm Python Package
|
5
|
-
Home-page: https://github.com/QuTech-Delft/libqasm
|
6
|
-
Author: QuTech, TU Delft
|
7
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
8
|
-
Classifier: Operating System :: POSIX :: Linux
|
9
|
-
Classifier: Operating System :: MacOS
|
10
|
-
Classifier: Operating System :: Microsoft :: Windows
|
11
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
12
|
-
Classifier: Topic :: Scientific/Engineering
|
13
|
-
Description-Content-Type: text/markdown
|
14
|
-
License-File: LICENSE.md
|
15
|
-
Requires-Dist: numpy
|
16
|
-
|
17
|
-
# libQASM: Library to parse cQASM v3.0 files
|
18
|
-
|
19
|
-
[](https://github.com/qutech-delft/libqasm/actions)
|
20
|
-
[](https://pypi.org/project/libqasm/)
|
21
|
-
|
22
|
-
## File organization
|
23
|
-
|
24
|
-
For development, see:
|
25
|
-
|
26
|
-
- `include`: public headers.
|
27
|
-
- `src`: source files.
|
28
|
-
- `test`: test files.
|
29
|
-
- `python`: SWIG interface.
|
30
|
-
- `res`: resource files, for testing.
|
31
|
-
|
32
|
-
For build process, continuous integration, and documentation:
|
33
|
-
|
34
|
-
- `conan`: Conan profiles.
|
35
|
-
- `emscripten`: bindings and test for the emscripten binaries.
|
36
|
-
- `scripts`: helper scripts used during the build process.
|
37
|
-
- `.github`: GitHub Actions configuration files.
|
38
|
-
- `doc`: documentation.
|
39
|
-
|
40
|
-
Build outputs may go into:
|
41
|
-
|
42
|
-
- `build/<build type>`: the C++ library output files generated by Conan.
|
43
|
-
- `pybuild`: the Python library output files generated by `setup.py`.
|
44
|
-
|
45
|
-
## Dependencies
|
46
|
-
|
47
|
-
* C++ compiler with C++20 support (gcc 11, clang 14, msvc 17)
|
48
|
-
* `CMake` >= 3.12
|
49
|
-
* `git`
|
50
|
-
* `Python` 3.x plus `pip`, with the following package:
|
51
|
-
* `conan` >= 2.0
|
52
|
-
|
53
|
-
### ARM specific dependencies
|
54
|
-
|
55
|
-
We are having problems when using the `zulu-opendjk` Conan package on an ARMv8 architecture.
|
56
|
-
`zulu-openjdk` provides the Java JRE required by the ANTLR generator.
|
57
|
-
So, for the time being, we are installing Java manually for this platform.
|
58
|
-
|
59
|
-
* `Java JRE` >= 11
|
60
|
-
|
61
|
-
## Build
|
62
|
-
|
63
|
-
This version of `libqasm` can only be compiled via the Conan package manager.
|
64
|
-
You'll need to create a default profile before using it for the first time.
|
65
|
-
|
66
|
-
The installation of dependencies, as well as the compilation, can be done in one go.
|
67
|
-
|
68
|
-
```
|
69
|
-
git clone https://github.com/QuTech-Delft/libqasm.git
|
70
|
-
cd libqasm
|
71
|
-
conan profile detect
|
72
|
-
conan build . -pr:a=conan/profiles/tests-debug -b missing
|
73
|
-
```
|
74
|
-
|
75
|
-
Notice:
|
76
|
-
- the `conan profile` command only has to be run only once, and not before every build.
|
77
|
-
- the `conan build` command is building `libqasm` in Debug mode with tests using the `tests-debug` profile.
|
78
|
-
- the `-b missing` parameter asks `conan` to build packages from sources
|
79
|
-
in case it cannot find the binary packages for the current configuration (platform, OS, compiler, build type...).
|
80
|
-
|
81
|
-
### Build profiles
|
82
|
-
|
83
|
-
A group of predefined profiles is provided under the `conan/profiles` folder.<br/>
|
84
|
-
They follow the `[tests](-build_type)(-compiler)(-os)(-arch)[-shared]` naming convention:
|
85
|
-
- `tests`: if tests are being built.
|
86
|
-
- `build_type`: can be `debug` or `release`.
|
87
|
-
- `compiler`: `apple-clang`, `clang`, `gcc`, `msvc`.
|
88
|
-
- `os`: `emscripten`, `linux`, `macos`, `windows`.
|
89
|
-
- `arch`: `arm64`, `wasm`, `x64`.
|
90
|
-
- `shared`: if the library is being built in shared mode.
|
91
|
-
|
92
|
-
All the profiles set the C++ standard to 20.<br/>
|
93
|
-
All the `tests`, except for `linux-x64` profiles, enable Address Sanitizer.
|
94
|
-
|
95
|
-
### Build options
|
96
|
-
|
97
|
-
Profiles are a shorthand for command line options. The command above could be written, similarly, as:
|
98
|
-
|
99
|
-
```
|
100
|
-
conan build . -s:a compiler.cppstd=20 -s:a libqasm/*:build_type=Debug -o libqasm/*:build_tests=True -o libqasm/*:asan_enabled=True -b missing
|
101
|
-
```
|
102
|
-
|
103
|
-
This is the list of options that could be specified either in a profile or in the command line:
|
104
|
-
|
105
|
-
- `libqasm/*:asan_enabled={True,False}`: enables Address Sanitizer.
|
106
|
-
- `libqasm/*:build_type={Debug,Release}`: builds in debug or release mode.
|
107
|
-
- `libqasm/*:shared={True,False}`: builds a shared object library instead of a static library, if applicable.
|
108
|
-
|
109
|
-
Tests are enabled by default. To disable them, use `-c tools.build:skip_test=True`.
|
110
|
-
|
111
|
-
## Install
|
112
|
-
|
113
|
-
### From Python
|
114
|
-
|
115
|
-
Install from the project root directory as follows:
|
116
|
-
|
117
|
-
```
|
118
|
-
python3 -m pip install --verbose .
|
119
|
-
```
|
120
|
-
|
121
|
-
You can test if it works by running:
|
122
|
-
|
123
|
-
```
|
124
|
-
python3 -m pytest
|
125
|
-
```
|
126
|
-
|
127
|
-
### From C++
|
128
|
-
|
129
|
-
The `CMakeLists.txt` file in the root directory includes install targets:
|
130
|
-
|
131
|
-
```
|
132
|
-
conan create --version 0.6.6 . -pr:a=tests-debug -b missing
|
133
|
-
```
|
134
|
-
|
135
|
-
You can test if it works by doing:
|
136
|
-
|
137
|
-
```
|
138
|
-
cd test/Debug
|
139
|
-
ctest -C Debug --output-on-failure
|
140
|
-
```
|
141
|
-
|
142
|
-
## Use from another project
|
143
|
-
|
144
|
-
### From Python
|
145
|
-
|
146
|
-
The `libqasm` module should provide access to the `V3xAnalyzer` API:
|
147
|
-
- `parse_file`,
|
148
|
-
- `parse_string`,
|
149
|
-
- `analyze_file`, and
|
150
|
-
- `analyzer_string`.
|
151
|
-
|
152
|
-
The `cqasm.v3x` module is also available for a more fine-grained use of the library.
|
153
|
-
|
154
|
-
```
|
155
|
-
import cqasm.v3x.ast
|
156
|
-
import cqasm.v3x.instruction
|
157
|
-
import cqasm.v3x.primitives
|
158
|
-
import cqasm.v3x.semantic
|
159
|
-
import cqasm.v3x.types
|
160
|
-
import cqasm.v3x.values
|
161
|
-
```
|
162
|
-
|
163
|
-
### From C++
|
164
|
-
|
165
|
-
`libqasm` can be requested as a Conan package from a `conanfile.py`.
|
166
|
-
|
167
|
-
```
|
168
|
-
def build_requirements(self):
|
169
|
-
self.tool_requires("libqasm/0.6.5")
|
170
|
-
def requirements(self):
|
171
|
-
self.requires("libqasm/0.6.5")
|
172
|
-
```
|
173
|
-
|
174
|
-
And then linked against from a `CMakeLists.txt`:
|
175
|
-
|
176
|
-
```
|
177
|
-
target_link_libraries(<your target> PUBLIC libqasm::libqasm)
|
178
|
-
```
|
179
|
-
|
180
|
-
Note that the following dependency is required for `libqasm` to build:
|
181
|
-
|
182
|
-
* `Java JRE` >= 11
|
183
|
-
|
184
|
-
The header file `cqasm.hpp` should provide access to the following API:
|
185
|
-
- `cqasm::v3x::analyze_file`, and
|
186
|
-
- `cqasm::v3x::analyze_string`.
|
187
|
-
|
188
|
-
Again, other header files are available for a more fine-grained use of the library.
|
189
|
-
|
190
|
-
## Docker
|
191
|
-
|
192
|
-
This tests the library in a container with the bare minimum requirements for `libqasm`.
|
193
|
-
|
194
|
-
```
|
195
|
-
docker build .
|
196
|
-
```
|
197
|
-
|
198
|
-
**Note for Windows users:** The above might fail on Windows due to the `autocrlf` transformation that git does.
|
199
|
-
If you are having trouble with this just create new clone of this repository using:
|
200
|
-
|
201
|
-
```
|
202
|
-
git clone --config core.autocrlf=input git@github.com:QuTech-Delft/libqasm.git
|
203
|
-
```
|
204
|
-
|
205
|
-
## Emscripten
|
206
|
-
|
207
|
-
The generation of emscripten binaries has been tested as a cross-compilation from an ubuntu/x64 platform.
|
208
|
-
|
209
|
-
```
|
210
|
-
conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing
|
211
|
-
```
|
212
|
-
|
213
|
-
The output of this build lives in `build/Release/emscripten`:
|
214
|
-
- `cqasm_emscripten.js`.
|
215
|
-
- `cqasm_emscripten.wasm`.
|
216
|
-
|
217
|
-
Note that `cqasm_emscripten.js` is an ES6 module. An example of how to use it would be:
|
218
|
-
|
219
|
-
```
|
220
|
-
cd build/Release/emscripten
|
221
|
-
mv cqasm_emscripten.js cqasm_emscripten.mjs
|
222
|
-
cd ../../../emscripten
|
223
|
-
deno run -A test_libqasm.ts
|
224
|
-
```
|
libqasm-0.6.6.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
cqasm/__init__.py,sha256=_6Yl-eMBve0mGQA-aiFg4qvQ7GUCV5eGvIcoRf4mEPw,3
|
2
|
-
cqasm/v3x/__init__.py,sha256=FlmtSTjj083f3t9kTkJBsgs3rQBcgVEkYBqcJ4aKmzs,2850
|
3
|
-
cqasm/v3x/ast.py,sha256=snvmnaN80AU5_uJhUAaRsooakjFiMxUG5fUJshkjcVM,420170
|
4
|
-
cqasm/v3x/instruction.py,sha256=VAOqFpCH94CrutgMUZnQq8JXFIq_-C-ndTOjHLsg6_8,1219
|
5
|
-
cqasm/v3x/primitives.py,sha256=cR3SvCcG5lCzjSFMwHrMSRpf4Bj3Q1tkxUgaaltYJg8,1731
|
6
|
-
cqasm/v3x/semantic.py,sha256=wN9awUdn76sNp1WlzV5P4R4Z54r-W0JC4D-xaDzQec4,88679
|
7
|
-
cqasm/v3x/types.py,sha256=krT1WB5URT0F7lhKTLwYAs_UtTCn9CZ7-M0WMGmxtU4,65070
|
8
|
-
cqasm/v3x/values.py,sha256=SfKw6zIjpMrXJggvN_QGPqsoZXDR7HwUjgUMOBnIzuo,63394
|
9
|
-
libqasm/__init__.py,sha256=X0G-HBFW9_uEcsaGROQ1nzxYfHzSuglOiXrpTpjF9_E,752
|
10
|
-
libqasm/_libqasm.cp39-win_amd64.pyd,sha256=yeNjv58yvFKmUBJEk5bCrt_N3FpsCNT9jVqd-kWPqJY,2291200
|
11
|
-
libqasm/libqasm.py,sha256=TBkHUGljxJ3aWcBoPqTRcftMXAF2cDkwbw6HLP7zZuM,31677
|
12
|
-
libqasm-0.6.6.dist-info/LICENSE.md,sha256=395F6Sje50f5Too7yWFAoS_owYO4aOtjbMeQd_go_sk,579
|
13
|
-
libqasm-0.6.6.dist-info/METADATA,sha256=Hi6F1jn1w0o-S3SzPjbXbDJUsIMUE5K1Bj3vtNDGzwc,6775
|
14
|
-
libqasm-0.6.6.dist-info/WHEEL,sha256=Z6c-bE0pUM47a70GvqO_SvH_XXU0lm62gEAKtoNJ08A,100
|
15
|
-
libqasm-0.6.6.dist-info/top_level.txt,sha256=iZ8PSLyg3lJwvSUCvWE8VCJGU-nmQY2YIrbMe7M7kLw,14
|
16
|
-
libqasm-0.6.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|