# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=redefined-builtin
"""Object to represent the information at a node in the DAGCircuit."""
from qiskit.exceptions import QiskitError
[docs]class DAGDepNode:
"""Object to represent the information at a node in the DAGDependency().
It is used as the return value from `*_nodes()` functions and can
be supplied to functions that take a node.
"""
__slots__ = [
"type",
"_op",
"name",
"_qargs",
"cargs",
"sort_key",
"node_id",
"successors",
"predecessors",
"reachable",
"matchedwith",
"isblocked",
"successorstovisit",
"qindices",
"cindices",
]
def __init__(
self,
type=None,
op=None,
name=None,
qargs=(),
cargs=(),
successors=None,
predecessors=None,
reachable=None,
matchedwith=None,
successorstovisit=None,
isblocked=None,
qindices=None,
cindices=None,
nid=-1,
):
self.type = type
self._op = op
self.name = name
self._qargs = tuple(qargs) if qargs is not None else ()
self.cargs = tuple(cargs) if cargs is not None else ()
self.node_id = nid
self.sort_key = str(self._qargs)
self.successors = successors if successors is not None else []
self.predecessors = predecessors if predecessors is not None else []
self.reachable = reachable
self.matchedwith = matchedwith if matchedwith is not None else []
self.isblocked = isblocked
self.successorstovisit = successorstovisit if successorstovisit is not None else []
self.qindices = qindices if qindices is not None else []
self.cindices = cindices if cindices is not None else []
@property
def op(self):
"""Returns the Instruction object corresponding to the op for the node, else None"""
if not self.type or self.type != "op":
raise QiskitError("The node %s is not an op node" % (str(self)))
return self._op
@op.setter
def op(self, data):
self._op = data
@property
def qargs(self):
"""
Returns list of Qubit, else an empty list.
"""
return self._qargs
@qargs.setter
def qargs(self, new_qargs):
"""Sets the qargs to be the given list of qargs."""
self._qargs = tuple(new_qargs)
self.sort_key = str(new_qargs)
[docs] @staticmethod
def semantic_eq(node1, node2):
"""
Check if DAG nodes are considered equivalent, e.g., as a node_match for nx.is_isomorphic.
Args:
node1 (DAGDepNode): A node to compare.
node2 (DAGDepNode): The other node to compare.
Return:
Bool: If node1 == node2
"""
# For barriers, qarg order is not significant so compare as sets
if "barrier" == node1.name == node2.name:
return set(node1._qargs) == set(node2._qargs)
if node1.type == node2.type:
if node1._op == node2._op:
if node1.name == node2.name:
if node1._qargs == node2._qargs:
if node1.cargs == node2.cargs:
if node1.type == "op":
if getattr(node1._op, "condition", None) != getattr(
node2._op, "condition", None
):
return False
return True
return False
[docs] def copy(self):
"""
Function to copy a DAGDepNode object.
Returns:
DAGDepNode: a copy of a DAGDepNode object.
"""
dagdepnode = DAGDepNode()
dagdepnode.type = self.type
dagdepnode._op = self.op
dagdepnode.name = self.name
dagdepnode._qargs = self._qargs
dagdepnode.cargs = self.cargs
dagdepnode.node_id = self.node_id
dagdepnode.sort_key = self.sort_key
dagdepnode.successors = self.successors
dagdepnode.predecessors = self.predecessors
dagdepnode.reachable = self.reachable
dagdepnode.isblocked = self.isblocked
dagdepnode.successorstovisit = self.successorstovisit
dagdepnode.qindices = self.qindices
dagdepnode.cindices = self.cindices
dagdepnode.matchedwith = self.matchedwith.copy()
return dagdepnode