Repository: Qiskit/qiskit

Issue:
DAGCircuitError running Aqua VQC
### Information

- Master
- 3.6
- Linux, Mac, Windows...

### What is the current behavior?
When running Aqua unit test test_vqc we get a DAGCircuitError in latest master code (not in stable). See Aqua PR https://github.com/Qiskit/qiskit-aqua/pull/719 where 'decompose' was in feature_maps/pauli_expansion.py
```
                inst = evolution_instruction([[1, p]], coeff, 1)
                qc.append(inst, qr)
                qc = qc.decompose()   <---- With this we get DAGCircuitError
        return qc
```
decompose was used to allow caching of resultant ccts. Cache in Aqua does not support instruction so it was decomposed. Since we have now deprecated cache I have removed the above line since we do not need it and it causes the failure. However it maybe that this is something that needs looking into in Terra hence this PR.

### Steps to reproduce the problem
Install latest Aqua, Terra from master. Modify feature_maps/pauli_expansion.py to add the decompose line back above (i.e. revert what was done in the PR for that file). Run unit test test_vqc


### What is the expected behavior?
Unit test passes with no DAGCircuitError


### Suggested solutions
-




Discussion:
Hi @woodsp-ibm , the error from https://github.com/Qiskit/qiskit-aqua/pull/719
```
qiskit.dagcircuit.exceptions.DAGCircuitError: 'Cannot replace node of width (2 qubits, 0 clbits) with instruction of mismatched with (1 qubits, 0 clbits).'
```
indicates that one of the gates in the circuit has a definition which does not use all of the qubits over which the gate is defined. (e.g. A 3-qubit composite gate which only has instructions on `q0` and `q1`.) It looks like that is the case for https://github.com/Qiskit/qiskit-aqua/blob/86f3f70/qiskit/aqua/operators/common.py#L229 .

This issue came up previously for `isometry` gates ( https://github.com/Qiskit/qiskit-terra/pull/3233#issuecomment-546662030 ). The thinking then was that instruction definitions should always match the shape of the instruction. Is there a use case for `evolution_instruction` or any instruction having a definition of a different width than the instruction?

It does seem that `QuantumCircuit` could detect and raise earlier if there are idle qubits when `.to_instruction()` is called.

Having investigated further here is what is happening: The failures came as result of building an instruction from a Pauli string. Lets say we have an Hamiltonian where we have Pauli strings over 2 qubits. So we building out a circuit, including appending an instruction created from the Pauli string. Since its on 2 qubits it spans two qubits but when it comes to building the gates, say its 'ZI' then we get a gate on one qubit, but since the other was Identity no gate was applied to that qubit to form the instruction corresponding to the Pauli String. It is this that is failing to decompose when the circuit containing such an instruction is decomposed. This is the use case under which it was failing as per the above.

Resolving patch:
diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py
--- a/qiskit/dagcircuit/dagcircuit.py
+++ b/qiskit/dagcircuit/dagcircuit.py
@@ -886,7 +886,7 @@ def substitute_node(self, node, op, inplace=False):
         ):
             raise DAGCircuitError(
                 'Cannot replace node of width ({} qubits, {} clbits) with '
-                'instruction of mismatched with ({} qubits, {} clbits).'.format(
+                'instruction of mismatched width ({} qubits, {} clbits).'.format(
                     node.op.num_qubits, node.op.num_clbits,
                     op.num_qubits, op.num_clbits))
 
diff --git a/qiskit/transpiler/passes/decompose.py b/qiskit/transpiler/passes/decompose.py
--- a/qiskit/transpiler/passes/decompose.py
+++ b/qiskit/transpiler/passes/decompose.py
@@ -47,7 +47,7 @@ def run(self, dag):
             # TODO: allow choosing among multiple decomposition rules
             rule = node.op.definition
 
-            if len(rule) == 1:
+            if len(rule) == 1 and len(node.qargs) == len(rule[0][1]):
                 dag.substitute_node(node, rule[0][0], inplace=True)
             else:
                 # hacky way to build a dag on the same register as the rule is defined


Test patch:
diff --git a/test/python/circuit/test_isometry.py b/test/python/circuit/test_isometry.py
--- a/test/python/circuit/test_isometry.py
+++ b/test/python/circuit/test_isometry.py
@@ -49,8 +49,13 @@ def test_isometry(self):
                 q = QuantumRegister(n)
                 qc = QuantumCircuit(q)
                 qc.iso(iso, q[:num_q_input], q[num_q_input:])
+
+                # Verify the circuit can be decomposed
+                self.assertIsInstance(qc.decompose(), QuantumCircuit)
+
                 # Decompose the gate
                 qc = transpile(qc, basis_gates=['u1', 'u3', 'u2', 'cx', 'id'])
+
                 # Simulate the decomposed gate
                 simulator = BasicAer.get_backend('unitary_simulator')
                 result = execute(qc, simulator).result()
diff --git a/test/python/transpiler/test_decompose.py b/test/python/transpiler/test_decompose.py
--- a/test/python/transpiler/test_decompose.py
+++ b/test/python/transpiler/test_decompose.py
@@ -88,3 +88,17 @@ def test_decompose_conditional(self):
         ref_dag = circuit_to_dag(ref_circuit)
 
         self.assertEqual(after_dag, ref_dag)
+
+    def test_decompose_oversized_instruction(self):
+        """Test decompose on a single-op gate that doesn't use all qubits."""
+        # ref: https://github.com/Qiskit/qiskit-terra/issues/3440
+        qc1 = QuantumCircuit(2)
+        qc1.x(0)
+        gate = qc1.to_gate()
+
+        qc2 = QuantumCircuit(2)
+        qc2.append(gate, [0, 1])
+
+        output = qc2.decompose()
+
+        self.assertEqual(qc1, output)