Repository: Qiskit/qiskit

Issue:
Dag equality 
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues to confirm this idea does not exist. -->

### What is the expected enhancement?

A method to check if two dags are the same. 

#1363 and #1349 are holding this up



Discussion:

Resolving patch:
diff --git a/qiskit/dagcircuit/_dagcircuit.py b/qiskit/dagcircuit/_dagcircuit.py
--- a/qiskit/dagcircuit/_dagcircuit.py
+++ b/qiskit/dagcircuit/_dagcircuit.py
@@ -908,6 +908,25 @@ def _full_pred_succ_maps(self, pred_map, succ_map, input_circuit,
 
         return full_pred_map, full_succ_map
 
+    @staticmethod
+    def _match_dag_nodes(node1, node2):
+        """
+        Check if DAG nodes are considered equivalent, e.g. as a node_match for nx.is_isomorphic.
+        Args:
+            node1 (dict): A node to compare.
+            node2 (dict): The other node to compare.
+
+        Returns:
+            Bool: If node1 == node2
+        """
+        copy_node1 = {k: v for (k, v) in node1.items()}
+        copy_node2 = {k: v for (k, v) in node2.items()}
+        return copy_node1 == copy_node2
+
+    def __eq__(self, other):
+        return nx.is_isomorphic(self.multi_graph, other.multi_graph,
+                                node_match=DAGCircuit._match_dag_nodes)
+
     def node_nums_in_topological_order(self):
         """
         Returns the nodes (their ids) in topological order.


Test patch:
diff --git a/test/python/test_dagcircuit.py b/test/python/test_dagcircuit.py
--- a/test/python/test_dagcircuit.py
+++ b/test/python/test_dagcircuit.py
@@ -165,5 +165,46 @@ def test_circuit_factors(self):
         self.assertEqual(self.dag.num_tensor_factors(), 2)
 
 
+class TestDagEquivalence(QiskitTestCase):
+    """DAGCircuit equivalence check."""
+    def setUp(self):
+        self.qr1 = QuantumRegister(4, 'qr1')
+        self.qr2 = QuantumRegister(2, 'qr2')
+        circ1 = QuantumCircuit(self.qr2, self.qr1)
+        circ1.h(self.qr1[0])
+        circ1.cx(self.qr1[2], self.qr1[3])
+        circ1.h(self.qr1[2])
+        circ1.t(self.qr1[2])
+        circ1.ch(self.qr1[2], self.qr1[1])
+        circ1.u2(0.1, 0.2, self.qr1[3])
+        circ1.ccx(self.qr2[0], self.qr2[1], self.qr1[0])
+        self.dag1 = DAGCircuit.fromQuantumCircuit(circ1)
+
+    def test_dag_eq(self):
+        circ2 = QuantumCircuit(self.qr1, self.qr2)
+        circ2.cx(self.qr1[2], self.qr1[3])
+        circ2.u2(0.1, 0.2, self.qr1[3])
+        circ2.h(self.qr1[0])
+        circ2.h(self.qr1[2])
+        circ2.t(self.qr1[2])
+        circ2.ch(self.qr1[2], self.qr1[1])
+        circ2.ccx(self.qr2[0], self.qr2[1], self.qr1[0])
+        dag2 = DAGCircuit.fromQuantumCircuit(circ2)
+
+        self.assertEqual(self.dag1, dag2)
+
+    def test_dag_neq(self):
+        circ2 = QuantumCircuit(self.qr1, self.qr2)
+        circ2.cx(self.qr1[2], self.qr1[3])
+        circ2.u2(0.1, 0.2, self.qr1[3])
+        circ2.h(self.qr1[0])
+        circ2.h(self.qr1[2])
+        circ2.t(self.qr1[2])
+        circ2.ch(self.qr1[0], self.qr1[1])  # <--- The difference
+        circ2.ccx(self.qr2[0], self.qr2[1], self.qr1[0])
+        dag2 = DAGCircuit.fromQuantumCircuit(circ2)
+
+        self.assertNotEqual(self.dag1, dag2)
+
 if __name__ == '__main__':
     unittest.main()