Repository: Qiskit/qiskit (Python)

Issue:
Open ControlledGates not marked equivalent
I think #4444 broke circuit equivalence with controlled gates:
```python
from qiskit import QuantumCircuit
from qiskit.circuit.library.standard_gates import XGate

circuit = QuantumCircuit(5)
circuit.append(XGate().control(4, ctrl_state='0101'), [0, 1, 2, 3, 4])

expected = QuantumCircuit(5)
expected.append(XGate().control(4, ctrl_state='0101'), [0, 1, 2, 3, 4])

assert circuit == expected
```
```
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-1-27d881d6a5be> in <module>
      8 expected.append(XGate().control(4, ctrl_state='0101'), [0, 1, 2, 3, 4])
      9
---> 10 assert circuit == expected

AssertionError:
```


Discussion:
This only affects open control gates. Their definitions just need to be built on the `'q'` register on https://github.com/Qiskit/qiskit-terra/blob/4f804108bba528aa95e46838235754778e0cb68c/qiskit/circuit/controlledgate.py#L117
```
$ python
Python 3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 16:30:03)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from qiskit import QuantumCircuit
/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/__init__.py:90: DeprecationWarning: Using Qiskit with Python 3.5 is deprecated as of the 0.12.0 release. Support for running Qiskit with Python 3.5 will be removed at the Python 3.5 EoL o
n 09/13/2020.
  "Python 3.5 EoL on 09/13/2020.", DeprecationWarning)
>>> from qiskit.circuit.library.standard_gates import XGate
>>> a = QuantumCircuit(2)
>>> a.append(XGate().control(1), [0, 1])
>>> b = QuantumCircuit(2)
>>> b.append(XGate().control(1), [0, 1])
>>> a == b
True
>>> a = QuantumCircuit(2)
>>> a.append(XGate().control(1, ctrl_state='0'), [0, 1])
>>> b = QuantumCircuit(2)
>>> b.append(XGate().control(1, ctrl_state='0'), [0, 1])
>>> a == b
False
>>> ag = XGate().control(1, ctrl_state='0')
>>> bg = XGate().control(1, ctrl_state='0')
>>> ag == bg
False
>>> ag.definition == bg.definition
False
>>> ag.definition
[[<qiskit.circuit.library.standard_gates.x.XGate object at 0x120061cc0>, [Qubit(QuantumRegister(2, 'q14'), 0)], []], (<qiskit.circuit.library.standard_gates.x.CXGate object at 0x1309c6b38>, QuantumRegister(2, 'q14'), []), [<qiskit.circuit.library.standard_gates.x.XGate object at 0x120061cc0>, [Qubit(QuantumRegister(2, 'q14'), 0)], []]]
>>> bg.definition
[[<qiskit.circuit.library.standard_gates.x.XGate object at 0x120061cf8>, [Qubit(QuantumRegister(2, 'q16'), 0)], []], (<qiskit.circuit.library.standard_gates.x.CXGate object at 0x1309c65f8>, QuantumRegister(2, 'q16'), []), [<qiskit.circuit.library.standard_gates.x.XGate object at 0x120061cf8>, [Qubit(QuantumRegister(2, 'q16'), 0)], []]]

```



Patch:
diff --git a/qiskit/circuit/controlledgate.py b/qiskit/circuit/controlledgate.py
index 83732d6193d2..a080c3857fee 100644
--- a/qiskit/circuit/controlledgate.py
+++ b/qiskit/circuit/controlledgate.py
@@ -114,7 +114,7 @@ def definition(self) -> List:
             # pylint: disable=cyclic-import
             from qiskit.circuit.library.standard_gates import XGate
             bit_ctrl_state = bin(self.ctrl_state)[2:].zfill(self.num_ctrl_qubits)
-            qreg = QuantumRegister(self.num_qubits)
+            qreg = QuantumRegister(self.num_qubits, 'q')
             definition = [(closed_gate, qreg, [])]
             open_rules = []
             for qind, val in enumerate(bit_ctrl_state[::-1]):
diff --git a/releasenotes/notes/4573-Open-ControlledGates-not-marked-equivalent-729bc971c897ede3.yaml b/releasenotes/notes/4573-Open-ControlledGates-not-marked-equivalent-729bc971c897ede3.yaml
new file mode 100644
index 000000000000..ab01693f4e0e
--- /dev/null
+++ b/releasenotes/notes/4573-Open-ControlledGates-not-marked-equivalent-729bc971c897ede3.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    ``ControlledGate`` instances with a set ``ctrl_state`` were in some cases
+    not being evaluated as equal, even if the compared gates were equivalent.
+    This has been resolved.


Test patch:
diff --git a/test/python/circuit/test_controlled_gate.py b/test/python/circuit/test_controlled_gate.py
index 198b9ab46cbc..933475a6d425 100644
--- a/test/python/circuit/test_controlled_gate.py
+++ b/test/python/circuit/test_controlled_gate.py
@@ -860,6 +860,31 @@ def test_open_controlled_gate_raises(self):
         with self.assertRaises(CircuitError):
             base_gate.control(num_ctrl_qubits, ctrl_state='201')
 
+    def test_open_controlled_equality(self):
+        """
+        Test open controlled gates are equal if their base gates and control states are equal.
+        """
+
+        self.assertEqual(
+            XGate().control(1),
+            XGate().control(1))
+
+        self.assertNotEqual(
+            XGate().control(1),
+            YGate().control(1))
+
+        self.assertNotEqual(
+            XGate().control(1),
+            XGate().control(2))
+
+        self.assertEqual(
+            XGate().control(1, ctrl_state='0'),
+            XGate().control(1, ctrl_state='0'))
+
+        self.assertNotEqual(
+            XGate().control(1, ctrl_state='0'),
+            XGate().control(1, ctrl_state='1'))
+
 
 @ddt
 class TestSingleControlledRotationGates(QiskitTestCase):