libqasm 0.6.4__cp312-cp312-macosx_10_10_universal2.whl → 0.6.6__cp312-cp312-macosx_10_10_universal2.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 +6 -6
- cqasm/v3x/ast.py +139 -197
- cqasm/v3x/semantic.py +74 -65
- cqasm/v3x/types.py +306 -0
- {libQasm → libqasm}/__init__.py +1 -1
- libqasm/_libqasm.cpython-312-darwin.so +0 -0
- libqasm/libqasm.py +1082 -0
- {libqasm-0.6.4.dist-info → libqasm-0.6.6.dist-info}/METADATA +61 -27
- libqasm-0.6.6.dist-info/RECORD +16 -0
- libqasm-0.6.6.dist-info/top_level.txt +2 -0
- libQasm/_libQasm.cpython-312-darwin.so +0 -0
- libQasm/libQasm.py +0 -1082
- libqasm-0.6.4.dist-info/RECORD +0 -16
- libqasm-0.6.4.dist-info/top_level.txt +0 -2
- {libqasm-0.6.4.dist-info → libqasm-0.6.6.dist-info}/LICENSE.md +0 -0
- {libqasm-0.6.4.dist-info → libqasm-0.6.6.dist-info}/WHEEL +0 -0
cqasm/v3x/semantic.py
CHANGED
@@ -1553,22 +1553,22 @@ class Program(Node):
|
|
1553
1553
|
__slots__ = [
|
1554
1554
|
'_attr_api_version',
|
1555
1555
|
'_attr_version',
|
1556
|
-
'_attr_qubit_variable_declaration',
|
1557
1556
|
'_attr_block',
|
1557
|
+
'_attr_variables',
|
1558
1558
|
]
|
1559
1559
|
|
1560
1560
|
def __init__(
|
1561
1561
|
self,
|
1562
1562
|
api_version=None,
|
1563
1563
|
version=None,
|
1564
|
-
qubit_variable_declaration=None,
|
1565
1564
|
block=None,
|
1565
|
+
variables=None,
|
1566
1566
|
):
|
1567
1567
|
super().__init__()
|
1568
1568
|
self.api_version = api_version
|
1569
1569
|
self.version = version
|
1570
|
-
self.qubit_variable_declaration = qubit_variable_declaration
|
1571
1570
|
self.block = block
|
1571
|
+
self.variables = variables
|
1572
1572
|
|
1573
1573
|
@property
|
1574
1574
|
def api_version(self):
|
@@ -1614,27 +1614,6 @@ class Program(Node):
|
|
1614
1614
|
def version(self):
|
1615
1615
|
self._attr_version = None
|
1616
1616
|
|
1617
|
-
@property
|
1618
|
-
def qubit_variable_declaration(self):
|
1619
|
-
"""Qubit variable."""
|
1620
|
-
return self._attr_qubit_variable_declaration
|
1621
|
-
|
1622
|
-
@qubit_variable_declaration.setter
|
1623
|
-
def qubit_variable_declaration(self, val):
|
1624
|
-
if val is None:
|
1625
|
-
del self.qubit_variable_declaration
|
1626
|
-
return
|
1627
|
-
if not isinstance(val, Variable):
|
1628
|
-
# Try to "typecast" if this isn't an obvious mistake.
|
1629
|
-
if isinstance(val, Node):
|
1630
|
-
raise TypeError('qubit_variable_declaration must be of type Variable')
|
1631
|
-
val = Variable(val)
|
1632
|
-
self._attr_qubit_variable_declaration = val
|
1633
|
-
|
1634
|
-
@qubit_variable_declaration.deleter
|
1635
|
-
def qubit_variable_declaration(self):
|
1636
|
-
self._attr_qubit_variable_declaration = None
|
1637
|
-
|
1638
1617
|
@property
|
1639
1618
|
def block(self):
|
1640
1619
|
"""Global scope block."""
|
@@ -1656,6 +1635,27 @@ class Program(Node):
|
|
1656
1635
|
def block(self):
|
1657
1636
|
self._attr_block = None
|
1658
1637
|
|
1638
|
+
@property
|
1639
|
+
def variables(self):
|
1640
|
+
"""The list of variables."""
|
1641
|
+
return self._attr_variables
|
1642
|
+
|
1643
|
+
@variables.setter
|
1644
|
+
def variables(self, val):
|
1645
|
+
if val is None:
|
1646
|
+
del self.variables
|
1647
|
+
return
|
1648
|
+
if not isinstance(val, MultiVariable):
|
1649
|
+
# Try to "typecast" if this isn't an obvious mistake.
|
1650
|
+
if isinstance(val, Node):
|
1651
|
+
raise TypeError('variables must be of type MultiVariable')
|
1652
|
+
val = MultiVariable(val)
|
1653
|
+
self._attr_variables = val
|
1654
|
+
|
1655
|
+
@variables.deleter
|
1656
|
+
def variables(self):
|
1657
|
+
self._attr_variables = MultiVariable()
|
1658
|
+
|
1659
1659
|
def __eq__(self, other):
|
1660
1660
|
"""Equality operator. Ignores annotations!"""
|
1661
1661
|
if not isinstance(other, Program):
|
@@ -1664,10 +1664,10 @@ class Program(Node):
|
|
1664
1664
|
return False
|
1665
1665
|
if self.version != other.version:
|
1666
1666
|
return False
|
1667
|
-
if self.qubit_variable_declaration != other.qubit_variable_declaration:
|
1668
|
-
return False
|
1669
1667
|
if self.block != other.block:
|
1670
1668
|
return False
|
1669
|
+
if self.variables != other.variables:
|
1670
|
+
return False
|
1671
1671
|
return True
|
1672
1672
|
|
1673
1673
|
def dump(self, indent=0, annotations=None, links=1):
|
@@ -1697,21 +1697,22 @@ class Program(Node):
|
|
1697
1697
|
s.append(self.version.dump(indent + 1, annotations, links) + '\n')
|
1698
1698
|
s.append(' '*indent + '>\n')
|
1699
1699
|
s.append(' '*indent)
|
1700
|
-
s.append('qubit_variable_declaration: ')
|
1701
|
-
if self.qubit_variable_declaration is None:
|
1702
|
-
s.append('-\n')
|
1703
|
-
else:
|
1704
|
-
s.append('<\n')
|
1705
|
-
s.append(self.qubit_variable_declaration.dump(indent + 1, annotations, links) + '\n')
|
1706
|
-
s.append(' '*indent + '>\n')
|
1707
|
-
s.append(' '*indent)
|
1708
1700
|
s.append('block: ')
|
1709
1701
|
if self.block is None:
|
1710
|
-
s.append('
|
1702
|
+
s.append('!MISSING\n')
|
1711
1703
|
else:
|
1712
1704
|
s.append('<\n')
|
1713
1705
|
s.append(self.block.dump(indent + 1, annotations, links) + '\n')
|
1714
1706
|
s.append(' '*indent + '>\n')
|
1707
|
+
s.append(' '*indent)
|
1708
|
+
s.append('variables: ')
|
1709
|
+
if not self.variables:
|
1710
|
+
s.append('-\n')
|
1711
|
+
else:
|
1712
|
+
s.append('[\n')
|
1713
|
+
for child in self.variables:
|
1714
|
+
s.append(child.dump(indent + 1, annotations, links) + '\n')
|
1715
|
+
s.append(' '*indent + ']\n')
|
1715
1716
|
indent -= 1
|
1716
1717
|
s.append(' '*indent)
|
1717
1718
|
s.append(')')
|
@@ -1731,10 +1732,10 @@ class Program(Node):
|
|
1731
1732
|
id_map[id(self)] = len(id_map)
|
1732
1733
|
if self._attr_version is not None:
|
1733
1734
|
self._attr_version.find_reachable(id_map)
|
1734
|
-
if self._attr_qubit_variable_declaration is not None:
|
1735
|
-
self._attr_qubit_variable_declaration.find_reachable(id_map)
|
1736
1735
|
if self._attr_block is not None:
|
1737
1736
|
self._attr_block.find_reachable(id_map)
|
1737
|
+
for el in self._attr_variables:
|
1738
|
+
el.find_reachable(id_map)
|
1738
1739
|
return id_map
|
1739
1740
|
|
1740
1741
|
def check_complete(self, id_map=None):
|
@@ -1748,18 +1749,20 @@ class Program(Node):
|
|
1748
1749
|
raise NotWellFormed('version is required but not set')
|
1749
1750
|
if self._attr_version is not None:
|
1750
1751
|
self._attr_version.check_complete(id_map)
|
1751
|
-
if self.
|
1752
|
-
|
1752
|
+
if self._attr_block is None:
|
1753
|
+
raise NotWellFormed('block is required but not set')
|
1753
1754
|
if self._attr_block is not None:
|
1754
1755
|
self._attr_block.check_complete(id_map)
|
1756
|
+
for child in self._attr_variables:
|
1757
|
+
child.check_complete(id_map)
|
1755
1758
|
|
1756
1759
|
def copy(self):
|
1757
1760
|
"""Returns a shallow copy of this node."""
|
1758
1761
|
return Program(
|
1759
1762
|
api_version=self._attr_api_version,
|
1760
1763
|
version=self._attr_version,
|
1761
|
-
|
1762
|
-
|
1764
|
+
block=self._attr_block,
|
1765
|
+
variables=self._attr_variables.copy()
|
1763
1766
|
)
|
1764
1767
|
|
1765
1768
|
def clone(self):
|
@@ -1771,8 +1774,8 @@ class Program(Node):
|
|
1771
1774
|
return Program(
|
1772
1775
|
api_version=_cloned(self._attr_api_version),
|
1773
1776
|
version=_cloned(self._attr_version),
|
1774
|
-
|
1775
|
-
|
1777
|
+
block=_cloned(self._attr_block),
|
1778
|
+
variables=_cloned(self._attr_variables)
|
1776
1779
|
)
|
1777
1780
|
|
1778
1781
|
@staticmethod
|
@@ -1811,30 +1814,34 @@ class Program(Node):
|
|
1811
1814
|
else:
|
1812
1815
|
f_version = Version._deserialize(field, seq_to_ob, links)
|
1813
1816
|
|
1814
|
-
# Deserialize the qubit_variable_declaration field.
|
1815
|
-
field = cbor.get('qubit_variable_declaration', None)
|
1816
|
-
if not isinstance(field, dict):
|
1817
|
-
raise ValueError('missing or invalid serialization of field qubit_variable_declaration')
|
1818
|
-
if field.get('@T') != '?':
|
1819
|
-
raise ValueError('unexpected edge type for field qubit_variable_declaration')
|
1820
|
-
if field.get('@t', None) is None:
|
1821
|
-
f_qubit_variable_declaration = None
|
1822
|
-
else:
|
1823
|
-
f_qubit_variable_declaration = Variable._deserialize(field, seq_to_ob, links)
|
1824
|
-
|
1825
1817
|
# Deserialize the block field.
|
1826
1818
|
field = cbor.get('block', None)
|
1827
1819
|
if not isinstance(field, dict):
|
1828
1820
|
raise ValueError('missing or invalid serialization of field block')
|
1829
|
-
if field.get('@T') != '
|
1821
|
+
if field.get('@T') != '1':
|
1830
1822
|
raise ValueError('unexpected edge type for field block')
|
1831
1823
|
if field.get('@t', None) is None:
|
1832
1824
|
f_block = None
|
1833
1825
|
else:
|
1834
1826
|
f_block = Block._deserialize(field, seq_to_ob, links)
|
1835
1827
|
|
1828
|
+
# Deserialize the variables field.
|
1829
|
+
field = cbor.get('variables', None)
|
1830
|
+
if not isinstance(field, dict):
|
1831
|
+
raise ValueError('missing or invalid serialization of field variables')
|
1832
|
+
if field.get('@T') != '*':
|
1833
|
+
raise ValueError('unexpected edge type for field variables')
|
1834
|
+
data = field.get('@d', None)
|
1835
|
+
if not isinstance(data, list):
|
1836
|
+
raise ValueError('missing serialization of Any/Many contents')
|
1837
|
+
f_variables = MultiVariable()
|
1838
|
+
for element in data:
|
1839
|
+
if element.get('@T') != '1':
|
1840
|
+
raise ValueError('unexpected edge type for Any/Many element')
|
1841
|
+
f_variables.append(Variable._deserialize(element, seq_to_ob, links))
|
1842
|
+
|
1836
1843
|
# Construct the Program node.
|
1837
|
-
node = Program(f_api_version, f_version,
|
1844
|
+
node = Program(f_api_version, f_version, f_block, f_variables)
|
1838
1845
|
|
1839
1846
|
# Deserialize annotations.
|
1840
1847
|
for key, val in cbor.items():
|
@@ -1874,22 +1881,24 @@ class Program(Node):
|
|
1874
1881
|
field.update(self._attr_version._serialize(id_map))
|
1875
1882
|
cbor['version'] = field
|
1876
1883
|
|
1877
|
-
# Serialize the qubit_variable_declaration field.
|
1878
|
-
field = {'@T': '?'}
|
1879
|
-
if self._attr_qubit_variable_declaration is None:
|
1880
|
-
field['@t'] = None
|
1881
|
-
else:
|
1882
|
-
field.update(self._attr_qubit_variable_declaration._serialize(id_map))
|
1883
|
-
cbor['qubit_variable_declaration'] = field
|
1884
|
-
|
1885
1884
|
# Serialize the block field.
|
1886
|
-
field = {'@T': '
|
1885
|
+
field = {'@T': '1'}
|
1887
1886
|
if self._attr_block is None:
|
1888
1887
|
field['@t'] = None
|
1889
1888
|
else:
|
1890
1889
|
field.update(self._attr_block._serialize(id_map))
|
1891
1890
|
cbor['block'] = field
|
1892
1891
|
|
1892
|
+
# Serialize the variables field.
|
1893
|
+
field = {'@T': '*'}
|
1894
|
+
lst = []
|
1895
|
+
for el in self._attr_variables:
|
1896
|
+
el = el._serialize(id_map)
|
1897
|
+
el['@T'] = '1'
|
1898
|
+
lst.append(el)
|
1899
|
+
field['@d'] = lst
|
1900
|
+
cbor['variables'] = field
|
1901
|
+
|
1893
1902
|
# Serialize annotations.
|
1894
1903
|
for key, val in self._annot.items():
|
1895
1904
|
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
cqasm/v3x/types.py
CHANGED
@@ -639,8 +639,12 @@ class TypeBase(Node):
|
|
639
639
|
return Int._deserialize(cbor, seq_to_ob, links)
|
640
640
|
if typ == 'Float':
|
641
641
|
return Float._deserialize(cbor, seq_to_ob, links)
|
642
|
+
if typ == 'Bit':
|
643
|
+
return Bit._deserialize(cbor, seq_to_ob, links)
|
642
644
|
if typ == 'Qubit':
|
643
645
|
return Qubit._deserialize(cbor, seq_to_ob, links)
|
646
|
+
if typ == 'BitArray':
|
647
|
+
return BitArray._deserialize(cbor, seq_to_ob, links)
|
644
648
|
if typ == 'QubitArray':
|
645
649
|
return QubitArray._deserialize(cbor, seq_to_ob, links)
|
646
650
|
raise ValueError('unknown or unexpected type (@t) found in node serialization')
|
@@ -673,6 +677,308 @@ class MultiTypeBase(_Multiple):
|
|
673
677
|
|
674
678
|
_typemap['TypeBase'] = TypeBase
|
675
679
|
|
680
|
+
class Bit(TypeBase):
|
681
|
+
__slots__ = []
|
682
|
+
|
683
|
+
def __init__(
|
684
|
+
self,
|
685
|
+
size=None,
|
686
|
+
):
|
687
|
+
super().__init__(size=size)
|
688
|
+
|
689
|
+
def __eq__(self, other):
|
690
|
+
"""Equality operator. Ignores annotations!"""
|
691
|
+
if not isinstance(other, Bit):
|
692
|
+
return False
|
693
|
+
if self.size != other.size:
|
694
|
+
return False
|
695
|
+
return True
|
696
|
+
|
697
|
+
def dump(self, indent=0, annotations=None, links=1):
|
698
|
+
"""Returns a debug representation of this tree as a multiline string.
|
699
|
+
indent is the number of double spaces prefixed before every line.
|
700
|
+
annotations, if specified, must be a set-like object containing the key
|
701
|
+
strings of the annotations that are to be printed. links specifies the
|
702
|
+
maximum link recursion depth."""
|
703
|
+
s = [' '*indent]
|
704
|
+
s.append('Bit(')
|
705
|
+
if annotations is None:
|
706
|
+
annotations = []
|
707
|
+
for key in annotations:
|
708
|
+
if key in self:
|
709
|
+
s.append(' # {}: {}'.format(key, self[key]))
|
710
|
+
s.append('\n')
|
711
|
+
indent += 1
|
712
|
+
s.append(' '*indent)
|
713
|
+
s.append('size: ')
|
714
|
+
s.append(str(self.size) + '\n')
|
715
|
+
indent -= 1
|
716
|
+
s.append(' '*indent)
|
717
|
+
s.append(')')
|
718
|
+
return ''.join(s)
|
719
|
+
|
720
|
+
__str__ = dump
|
721
|
+
__repr__ = dump
|
722
|
+
|
723
|
+
def find_reachable(self, id_map=None):
|
724
|
+
"""Returns a dictionary mapping Python id() values to stable sequence
|
725
|
+
numbers for all nodes in the tree rooted at this node. If id_map is
|
726
|
+
specified, found nodes are appended to it."""
|
727
|
+
if id_map is None:
|
728
|
+
id_map = {}
|
729
|
+
if id(self) in id_map:
|
730
|
+
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
731
|
+
id_map[id(self)] = len(id_map)
|
732
|
+
return id_map
|
733
|
+
|
734
|
+
def check_complete(self, id_map=None):
|
735
|
+
"""Raises NotWellFormed if the tree rooted at this node is not
|
736
|
+
well-formed. If id_map is specified, this tree is only a subtree in the
|
737
|
+
context of a larger tree, and id_map must be a dict mapping from Python
|
738
|
+
id() codes to tree indices for all reachable nodes."""
|
739
|
+
if id_map is None:
|
740
|
+
id_map = self.find_reachable()
|
741
|
+
|
742
|
+
def copy(self):
|
743
|
+
"""Returns a shallow copy of this node."""
|
744
|
+
return Bit(
|
745
|
+
size=self._attr_size
|
746
|
+
)
|
747
|
+
|
748
|
+
def clone(self):
|
749
|
+
"""Returns a deep copy of this node. This mimics the C++ interface,
|
750
|
+
deficiencies with links included; that is, links always point to the
|
751
|
+
original tree. If you're not cloning a subtree in a context where this
|
752
|
+
is the desired behavior, you may want to use the copy.deepcopy() from
|
753
|
+
the stdlib instead, which should copy links correctly."""
|
754
|
+
return Bit(
|
755
|
+
size=_cloned(self._attr_size)
|
756
|
+
)
|
757
|
+
|
758
|
+
@staticmethod
|
759
|
+
def _deserialize(cbor, seq_to_ob, links):
|
760
|
+
"""Attempts to deserialize the given cbor object (in Python primitive
|
761
|
+
representation) into a node of this type. All (sub)nodes are added to
|
762
|
+
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
763
|
+
registered in the links list by means of a two-tuple of the setter
|
764
|
+
function for the link field and the sequence number of the target node.
|
765
|
+
"""
|
766
|
+
if not isinstance(cbor, dict):
|
767
|
+
raise TypeError('node description object must be a dict')
|
768
|
+
typ = cbor.get('@t', None)
|
769
|
+
if typ is None:
|
770
|
+
raise ValueError('type (@t) field is missing from node serialization')
|
771
|
+
if typ != 'Bit':
|
772
|
+
raise ValueError('found node serialization for ' + typ + ', but expected Bit')
|
773
|
+
|
774
|
+
# Deserialize the size field.
|
775
|
+
field = cbor.get('size', None)
|
776
|
+
if not isinstance(field, dict):
|
777
|
+
raise ValueError('missing or invalid serialization of field size')
|
778
|
+
if hasattr(cqasm.v3x.primitives.Int, 'deserialize_cbor'):
|
779
|
+
f_size = cqasm.v3x.primitives.Int.deserialize_cbor(field)
|
780
|
+
else:
|
781
|
+
f_size = cqasm.v3x.primitives.deserialize(cqasm.v3x.primitives.Int, field)
|
782
|
+
|
783
|
+
# Construct the Bit node.
|
784
|
+
node = Bit(f_size)
|
785
|
+
|
786
|
+
# Deserialize annotations.
|
787
|
+
for key, val in cbor.items():
|
788
|
+
if not (key.startswith('{') and key.endswith('}')):
|
789
|
+
continue
|
790
|
+
key = key[1:-1]
|
791
|
+
node[key] = cqasm.v3x.primitives.deserialize(key, val)
|
792
|
+
|
793
|
+
# Register node in sequence number lookup.
|
794
|
+
seq = cbor.get('@i', None)
|
795
|
+
if not isinstance(seq, int):
|
796
|
+
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
797
|
+
if seq in seq_to_ob:
|
798
|
+
raise ValueError('duplicate sequence number %d' % seq)
|
799
|
+
seq_to_ob[seq] = node
|
800
|
+
|
801
|
+
return node
|
802
|
+
|
803
|
+
def _serialize(self, id_map):
|
804
|
+
"""Serializes this node to the Python primitive representation of its
|
805
|
+
CBOR serialization. The tree that the node belongs to must be
|
806
|
+
well-formed. id_map must match Python id() calls for all nodes to unique
|
807
|
+
integers, to use for the sequence number representation of links."""
|
808
|
+
cbor = {'@i': id_map[id(self)], '@t': 'Bit'}
|
809
|
+
|
810
|
+
# Serialize the size field.
|
811
|
+
if hasattr(self._attr_size, 'serialize_cbor'):
|
812
|
+
cbor['size'] = self._attr_size.serialize_cbor()
|
813
|
+
else:
|
814
|
+
cbor['size'] = cqasm.v3x.primitives.serialize(cqasm.v3x.primitives.Int, self._attr_size)
|
815
|
+
|
816
|
+
# Serialize annotations.
|
817
|
+
for key, val in self._annot.items():
|
818
|
+
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
819
|
+
|
820
|
+
return cbor
|
821
|
+
|
822
|
+
|
823
|
+
class MultiBit(_Multiple):
|
824
|
+
"""Wrapper for an edge with multiple Bit objects."""
|
825
|
+
|
826
|
+
_T = Bit
|
827
|
+
|
828
|
+
|
829
|
+
_typemap['Bit'] = Bit
|
830
|
+
|
831
|
+
class BitArray(TypeBase):
|
832
|
+
__slots__ = []
|
833
|
+
|
834
|
+
def __init__(
|
835
|
+
self,
|
836
|
+
size=None,
|
837
|
+
):
|
838
|
+
super().__init__(size=size)
|
839
|
+
|
840
|
+
def __eq__(self, other):
|
841
|
+
"""Equality operator. Ignores annotations!"""
|
842
|
+
if not isinstance(other, BitArray):
|
843
|
+
return False
|
844
|
+
if self.size != other.size:
|
845
|
+
return False
|
846
|
+
return True
|
847
|
+
|
848
|
+
def dump(self, indent=0, annotations=None, links=1):
|
849
|
+
"""Returns a debug representation of this tree as a multiline string.
|
850
|
+
indent is the number of double spaces prefixed before every line.
|
851
|
+
annotations, if specified, must be a set-like object containing the key
|
852
|
+
strings of the annotations that are to be printed. links specifies the
|
853
|
+
maximum link recursion depth."""
|
854
|
+
s = [' '*indent]
|
855
|
+
s.append('BitArray(')
|
856
|
+
if annotations is None:
|
857
|
+
annotations = []
|
858
|
+
for key in annotations:
|
859
|
+
if key in self:
|
860
|
+
s.append(' # {}: {}'.format(key, self[key]))
|
861
|
+
s.append('\n')
|
862
|
+
indent += 1
|
863
|
+
s.append(' '*indent)
|
864
|
+
s.append('size: ')
|
865
|
+
s.append(str(self.size) + '\n')
|
866
|
+
indent -= 1
|
867
|
+
s.append(' '*indent)
|
868
|
+
s.append(')')
|
869
|
+
return ''.join(s)
|
870
|
+
|
871
|
+
__str__ = dump
|
872
|
+
__repr__ = dump
|
873
|
+
|
874
|
+
def find_reachable(self, id_map=None):
|
875
|
+
"""Returns a dictionary mapping Python id() values to stable sequence
|
876
|
+
numbers for all nodes in the tree rooted at this node. If id_map is
|
877
|
+
specified, found nodes are appended to it."""
|
878
|
+
if id_map is None:
|
879
|
+
id_map = {}
|
880
|
+
if id(self) in id_map:
|
881
|
+
raise NotWellFormed('node {!r} with id {} occurs more than once'.format(self, id(self)))
|
882
|
+
id_map[id(self)] = len(id_map)
|
883
|
+
return id_map
|
884
|
+
|
885
|
+
def check_complete(self, id_map=None):
|
886
|
+
"""Raises NotWellFormed if the tree rooted at this node is not
|
887
|
+
well-formed. If id_map is specified, this tree is only a subtree in the
|
888
|
+
context of a larger tree, and id_map must be a dict mapping from Python
|
889
|
+
id() codes to tree indices for all reachable nodes."""
|
890
|
+
if id_map is None:
|
891
|
+
id_map = self.find_reachable()
|
892
|
+
|
893
|
+
def copy(self):
|
894
|
+
"""Returns a shallow copy of this node."""
|
895
|
+
return BitArray(
|
896
|
+
size=self._attr_size
|
897
|
+
)
|
898
|
+
|
899
|
+
def clone(self):
|
900
|
+
"""Returns a deep copy of this node. This mimics the C++ interface,
|
901
|
+
deficiencies with links included; that is, links always point to the
|
902
|
+
original tree. If you're not cloning a subtree in a context where this
|
903
|
+
is the desired behavior, you may want to use the copy.deepcopy() from
|
904
|
+
the stdlib instead, which should copy links correctly."""
|
905
|
+
return BitArray(
|
906
|
+
size=_cloned(self._attr_size)
|
907
|
+
)
|
908
|
+
|
909
|
+
@staticmethod
|
910
|
+
def _deserialize(cbor, seq_to_ob, links):
|
911
|
+
"""Attempts to deserialize the given cbor object (in Python primitive
|
912
|
+
representation) into a node of this type. All (sub)nodes are added to
|
913
|
+
the seq_to_ob dict, indexed by their cbor sequence number. All links are
|
914
|
+
registered in the links list by means of a two-tuple of the setter
|
915
|
+
function for the link field and the sequence number of the target node.
|
916
|
+
"""
|
917
|
+
if not isinstance(cbor, dict):
|
918
|
+
raise TypeError('node description object must be a dict')
|
919
|
+
typ = cbor.get('@t', None)
|
920
|
+
if typ is None:
|
921
|
+
raise ValueError('type (@t) field is missing from node serialization')
|
922
|
+
if typ != 'BitArray':
|
923
|
+
raise ValueError('found node serialization for ' + typ + ', but expected BitArray')
|
924
|
+
|
925
|
+
# Deserialize the size field.
|
926
|
+
field = cbor.get('size', None)
|
927
|
+
if not isinstance(field, dict):
|
928
|
+
raise ValueError('missing or invalid serialization of field size')
|
929
|
+
if hasattr(cqasm.v3x.primitives.Int, 'deserialize_cbor'):
|
930
|
+
f_size = cqasm.v3x.primitives.Int.deserialize_cbor(field)
|
931
|
+
else:
|
932
|
+
f_size = cqasm.v3x.primitives.deserialize(cqasm.v3x.primitives.Int, field)
|
933
|
+
|
934
|
+
# Construct the BitArray node.
|
935
|
+
node = BitArray(f_size)
|
936
|
+
|
937
|
+
# Deserialize annotations.
|
938
|
+
for key, val in cbor.items():
|
939
|
+
if not (key.startswith('{') and key.endswith('}')):
|
940
|
+
continue
|
941
|
+
key = key[1:-1]
|
942
|
+
node[key] = cqasm.v3x.primitives.deserialize(key, val)
|
943
|
+
|
944
|
+
# Register node in sequence number lookup.
|
945
|
+
seq = cbor.get('@i', None)
|
946
|
+
if not isinstance(seq, int):
|
947
|
+
raise ValueError('sequence number field (@i) is not an integer or missing from node serialization')
|
948
|
+
if seq in seq_to_ob:
|
949
|
+
raise ValueError('duplicate sequence number %d' % seq)
|
950
|
+
seq_to_ob[seq] = node
|
951
|
+
|
952
|
+
return node
|
953
|
+
|
954
|
+
def _serialize(self, id_map):
|
955
|
+
"""Serializes this node to the Python primitive representation of its
|
956
|
+
CBOR serialization. The tree that the node belongs to must be
|
957
|
+
well-formed. id_map must match Python id() calls for all nodes to unique
|
958
|
+
integers, to use for the sequence number representation of links."""
|
959
|
+
cbor = {'@i': id_map[id(self)], '@t': 'BitArray'}
|
960
|
+
|
961
|
+
# Serialize the size field.
|
962
|
+
if hasattr(self._attr_size, 'serialize_cbor'):
|
963
|
+
cbor['size'] = self._attr_size.serialize_cbor()
|
964
|
+
else:
|
965
|
+
cbor['size'] = cqasm.v3x.primitives.serialize(cqasm.v3x.primitives.Int, self._attr_size)
|
966
|
+
|
967
|
+
# Serialize annotations.
|
968
|
+
for key, val in self._annot.items():
|
969
|
+
cbor['{%s}' % key] = _py_to_cbor(cqasm.v3x.primitives.serialize(key, val))
|
970
|
+
|
971
|
+
return cbor
|
972
|
+
|
973
|
+
|
974
|
+
class MultiBitArray(_Multiple):
|
975
|
+
"""Wrapper for an edge with multiple BitArray objects."""
|
976
|
+
|
977
|
+
_T = BitArray
|
978
|
+
|
979
|
+
|
980
|
+
_typemap['BitArray'] = BitArray
|
981
|
+
|
676
982
|
class Bool(TypeBase):
|
677
983
|
"""Type of a boolean."""
|
678
984
|
|
{libQasm → libqasm}/__init__.py
RENAMED
Binary file
|