예제 #1
0
 def test_inverse_x(self, num_ctrl_qubits):
     """test inverting ControlledGate"""
     cnx = XGate().control(num_ctrl_qubits)
     inv_cnx = cnx.inverse()
     result = Operator(cnx).compose(Operator(inv_cnx))
     np.testing.assert_array_almost_equal(result.data,
                                          np.identity(result.dim[0]))
예제 #2
0
    def test_is_identity(self):
        """ The is_identity function determines whether a pair of gates
            forms the identity, when ignoring control qubits.
        """
        seq = [
            DAGNode({
                'type': 'op',
                'op': XGate().control()
            }),
            DAGNode({
                'type': 'op',
                'op': XGate().control(2)
            })
        ]
        self.assertTrue(HoareOptimizer()._is_identity(seq))

        seq = [
            DAGNode({
                'type': 'op',
                'op': RZGate(-pi / 2).control()
            }),
            DAGNode({
                'type': 'op',
                'op': RZGate(pi / 2).control(2)
            })
        ]
        self.assertTrue(HoareOptimizer()._is_identity(seq))

        seq = [
            DAGNode({
                'type': 'op',
                'op': CSwapGate()
            }),
            DAGNode({
                'type': 'op',
                'op': SwapGate()
            })
        ]
        self.assertTrue(HoareOptimizer()._is_identity(seq))

        seq = [
            DAGNode({
                'type': 'op',
                'op': UnitaryGate([[1, 0], [0, 1j]]).control()
            }),
            DAGNode({
                'type': 'op',
                'op': UnitaryGate([[1, 0], [0, -1j]])
            })
        ]
    def test_open_controlled_gate(self):
        """
        Test controlled gates with control on '0'
        """
        base_gate = XGate()
        base_mat = base_gate.to_matrix()
        num_ctrl_qubits = 3

        ctrl_state = 5
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = None
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = 0
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = 7
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = '110'
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))
    def test_multi_control_toffoli_matrix_advanced_dirty_ancillas(
            self, num_controls):
        """Test the multi-control Toffoli gate with dirty ancillas (advanced).

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py
        """
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)
        qc = QuantumCircuit(q_controls, q_target)

        q_ancillas = None
        if num_controls <= 4:
            num_ancillas = 0
        else:
            num_ancillas = 1
            q_ancillas = QuantumRegister(num_ancillas)
            qc.add_register(q_ancillas)

        qc.mct(q_controls, q_target[0], q_ancillas, mode='advanced')

        simulated = execute(
            qc,
            BasicAer.get_backend('unitary_simulator')).result().get_unitary(qc)
        if num_ancillas > 0:
            simulated = simulated[:2**(num_controls + 1), :2**(num_controls +
                                                               1)]

        base = XGate().to_matrix()
        expected = _compute_control_matrix(base, num_controls)
        self.assertTrue(matrix_equal(simulated, expected, atol=1e-8))
    def test_relative_phase_toffoli_gates(self, num_ctrl_qubits):
        """Test the relative phase Toffoli gates.

        This test compares the matrix representation of the relative phase gate classes
        (i.e. RCCXGate().to_matrix()), the matrix obtained from the unitary simulator,
        and the exact version of the gate as obtained through `_compute_control_matrix`.
        """
        # get target matrix (w/o relative phase)
        base_mat = XGate().to_matrix()
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits)

        # build the matrix for the relative phase toffoli using the unitary simulator
        circuit = QuantumCircuit(num_ctrl_qubits + 1)
        if num_ctrl_qubits == 2:
            circuit.rccx(0, 1, 2)
        else:  # num_ctrl_qubits == 3:
            circuit.rcccx(0, 1, 2, 3)
        simulator = BasicAer.get_backend('unitary_simulator')
        simulated_mat = execute(circuit, simulator).result().get_unitary()

        # get the matrix representation from the class itself
        if num_ctrl_qubits == 2:
            repr_mat = RCCXGate().to_matrix()
        else:  # num_ctrl_qubits == 3:
            repr_mat = RC3XGate().to_matrix()

        # test up to phase
        # note, that all entries may have an individual phase! (as opposed to a global phase)
        self.assertTrue(matrix_equal(np.abs(simulated_mat), target_mat))

        # compare simulated matrix with the matrix representation provided by the class
        self.assertTrue(matrix_equal(simulated_mat, repr_mat))
예제 #6
0
 def definition(self) -> List:
     """Return definition in terms of other basic gates. If the gate has
     open controls, as determined from `self.ctrl_state`, the returned
     definition is conjugated with X without changing the internal
     `_definition`.
     """
     if not self._definition:
         self._define()
     # pylint: disable=cyclic-import
     from qiskit.extensions.standard import XGate, CXGate
     bit_ctrl_state = bin(self.ctrl_state)[2:].zfill(self.num_ctrl_qubits)
     # hacky way to get register assuming single register
     if self._definition:
         qreg = self._definition[0][1][0].register
         definition = self._definition
     elif isinstance(self, CXGate):
         qreg = QuantumRegister(self.num_qubits, 'q')
         definition = [(self, [qreg[0], qreg[1]], [])]
     open_rules = []
     for qind, val in enumerate(bit_ctrl_state[::-1]):
         if val == '0':
             open_rules.append([XGate(), [qreg[qind]], []])
     if open_rules:
         return open_rules + definition + open_rules
     else:
         return self._definition
    def test_multi_control_toffoli_matrix_clean_ancillas(self, num_controls):
        """Test the multi-control Toffoli gate with clean ancillas.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py
        """
        # set up circuit
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)
        qc = QuantumCircuit(q_controls, q_target)

        if num_controls > 2:
            num_ancillas = num_controls - 2
            q_ancillas = QuantumRegister(num_controls)
            qc.add_register(q_ancillas)
        else:
            num_ancillas = 0
            q_ancillas = None

        # apply hadamard on control qubits and toffoli gate
        qc.mct(q_controls, q_target[0], q_ancillas, mode='basic')

        # execute the circuit and obtain statevector result
        backend = BasicAer.get_backend('unitary_simulator')
        simulated = execute(qc, backend).result().get_unitary(qc)

        # compare to expectation
        if num_ancillas > 0:
            simulated = simulated[:2**(num_controls + 1), :2**(num_controls +
                                                               1)]

        base = XGate().to_matrix()
        expected = _compute_control_matrix(base, num_controls)
        self.assertTrue(matrix_equal(simulated, expected))
예제 #8
0
    def correct_error(self):
        self.qc.h(self.qr[0])
        self.qc.h(self.qr[1])
        self.qc.h(self.qr[2])

        self.qc.cx(self.qr[0], self.qr[1])
        self.qc.cx(self.qr[0], self.qr[2])
        c2x_gate = XGate().control(2)
        self.qc.append(c2x_gate, [2, 1, 0])
 def test_open_controlled_gate_raises(self):
     """
     Test controlled gates with open controls raises if ctrl_state isn't allowed.
     """
     base_gate = XGate()
     num_ctrl_qubits = 3
     with self.assertRaises(CircuitError):
         base_gate.control(num_ctrl_qubits, ctrl_state=-1)
     with self.assertRaises(CircuitError):
         base_gate.control(num_ctrl_qubits, ctrl_state=2**num_ctrl_qubits)
     with self.assertRaises(CircuitError):
         base_gate.control(num_ctrl_qubits, ctrl_state='201')
예제 #10
0
    def test_contains(self):
        """Verify checking if a inst/qarg/carg tuple is in circuit.data."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.h(0)

        self.assertTrue((HGate(), [qr[0]], []) in qc.data)
        self.assertFalse((HGate(), [qr[1]], []) in qc.data)
        self.assertFalse((XGate(), [qr[0]], []) in qc.data)
예제 #11
0
    def from_label(cls, label):
        """Return a tensor product of single-qubit operators.

        Args:
            label (string): single-qubit operator string.

        Returns:
            Operator: The N-qubit operator.

        Raises:
            QiskitError: if the label contains invalid characters, or the
                         length of the label is larger than an explicitly
                         specified num_qubits.

        Additional Information:
            The labels correspond to the single-qubit matrices:
            'I': [[1, 0], [0, 1]]
            'X': [[0, 1], [1, 0]]
            'Y': [[0, -1j], [1j, 0]]
            'Z': [[1, 0], [0, -1]]
            'H': [[1, 1], [1, -1]] / sqrt(2)
            'S': [[1, 0], [0 , 1j]]
            'T': [[1, 0], [0, (1+1j) / sqrt(2)]]
            '0': [[1, 0], [0, 0]]
            '1': [[0, 0], [0, 1]]
            '+': [[0.5, 0.5], [0.5 , 0.5]]
            '-': [[0.5, -0.5], [-0.5 , 0.5]]
            'r': [[0.5, -0.5j], [0.5j , 0.5]]
            'l': [[0.5, 0.5j], [-0.5j , 0.5]]
        """
        # Check label is valid
        label_mats = {
            'I': IGate().to_matrix(),
            'X': XGate().to_matrix(),
            'Y': YGate().to_matrix(),
            'Z': ZGate().to_matrix(),
            'H': HGate().to_matrix(),
            'S': SGate().to_matrix(),
            'T': TGate().to_matrix(),
            '0': np.array([[1, 0], [0, 0]], dtype=complex),
            '1': np.array([[0, 0], [0, 1]], dtype=complex),
            '+': np.array([[0.5, 0.5], [0.5, 0.5]], dtype=complex),
            '-': np.array([[0.5, -0.5], [-0.5, 0.5]], dtype=complex),
            'r': np.array([[0.5, -0.5j], [0.5j, 0.5]], dtype=complex),
            'l': np.array([[0.5, 0.5j], [-0.5j, 0.5]], dtype=complex),
        }
        if re.match(r'^[IXYZHST01rl\-+]+$', label) is None:
            raise QiskitError('Label contains invalid characters.')
        # Initialize an identity matrix and apply each gate
        num_qubits = len(label)
        op = Operator(np.eye(2**num_qubits, dtype=complex))
        for qubit, char in enumerate(reversed(label)):
            if char != 'I':
                op = op.compose(label_mats[char], qargs=[qubit])
        return op
예제 #12
0
 def test_from_label(self):
     """Test from_label method"""
     label = 'IXYZHS'
     CI = Clifford(IGate())
     CX = Clifford(XGate())
     CY = Clifford(YGate())
     CZ = Clifford(ZGate())
     CH = Clifford(HGate())
     CS = Clifford(SGate())
     target = CI.tensor(CX).tensor(CY).tensor(CZ).tensor(CH).tensor(CS)
     self.assertEqual(Clifford.from_label(label), target)
예제 #13
0
 def to_instruction(self):
     """Convert to Pauli circuit instruction."""
     from qiskit.circuit import QuantumCircuit, QuantumRegister
     from qiskit.extensions.standard import IdGate, XGate, YGate, ZGate
     gates = {'I': IdGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate()}
     label = self.to_label()
     n_qubits = self.numberofqubits
     qreg = QuantumRegister(n_qubits)
     circuit = QuantumCircuit(qreg, name='Pauli:{}'.format(label))
     for i, pauli in enumerate(reversed(label)):
         circuit.append(gates[pauli], [qreg[i]])
     return circuit.to_instruction()
예제 #14
0
class TestParameterCtrlState(QiskitTestCase):
    """Test gate equality with ctrl_state parameter."""
    @data((RXGate(0.5), CRXGate(0.5)), (RYGate(0.5), CRYGate(0.5)),
          (RZGate(0.5), CRZGate(0.5)), (XGate(), CXGate()),
          (YGate(), CYGate()), (ZGate(), CZGate()),
          (U1Gate(0.5), CU1Gate(0.5)), (SwapGate(), CSwapGate()),
          (HGate(), CHGate()), (U3Gate(0.1, 0.2, 0.3), CU3Gate(0.1, 0.2, 0.3)))
    @unpack
    def test_ctrl_state_one(self, gate, controlled_gate):
        """Test controlled gates with ctrl_state
        See https://github.com/Qiskit/qiskit-terra/pull/4025
        """
        self.assertEqual(gate.control(1, ctrl_state='1'), controlled_gate)
예제 #15
0
    def test_open_controlled_unitary_matrix(self, num_ctrl_qubits):
        """test open controlled unitary matrix"""
        # verify truth table
        num_target_qubits = 2
        num_qubits = num_ctrl_qubits + num_target_qubits
        target_op = Operator(XGate())
        for i in range(num_target_qubits - 1):
            target_op = target_op.tensor(XGate())

        for i in range(2**num_qubits):
            input_bitstring = bin(i)[2:].zfill(num_qubits)
            input_target = input_bitstring[0:num_target_qubits]
            input_ctrl = input_bitstring[-num_ctrl_qubits:]
            phi = Statevector.from_label(input_bitstring)
            cop = Operator(
                _compute_control_matrix(target_op.data,
                                        num_ctrl_qubits,
                                        ctrl_state=input_ctrl))
            for j in range(2**num_qubits):
                output_bitstring = bin(j)[2:].zfill(num_qubits)
                output_target = output_bitstring[0:num_target_qubits]
                output_ctrl = output_bitstring[-num_ctrl_qubits:]
                psi = Statevector.from_label(output_bitstring)
                cxout = np.dot(phi.data, psi.evolve(cop).data)
                if input_ctrl == output_ctrl:
                    # flip the target bits
                    cond_output = ''.join(
                        [str(int(not int(a))) for a in input_target])
                else:
                    cond_output = input_target
                if cxout == 1:
                    self.assertTrue((output_ctrl == input_ctrl)
                                    and (output_target == cond_output))
                else:
                    self.assertTrue(((output_ctrl == input_ctrl) and
                                     (output_target != cond_output))
                                    or output_ctrl != input_ctrl)
예제 #16
0
    def test_multi_control_toffoli_matrix_noancilla_dirty_ancillas(self, num_controls):
        """Test the multi-control Toffoli gate with dirty ancillas (noancilla).

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py
        """
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)
        qc = QuantumCircuit(q_controls, q_target)

        qc.mct(q_controls, q_target[0], None, mode='noancilla')

        simulated = execute(qc, BasicAer.get_backend('unitary_simulator')).result().get_unitary(qc)

        base = XGate().to_matrix()
        expected = _compute_control_matrix(base, num_controls)
        self.assertTrue(matrix_equal(simulated, expected, atol=1e-8))
예제 #17
0
def random_clifford_circuit(num_qubits, num_gates, gates='all', seed=None):
    """Generate a pseudo random Clifford circuit."""

    if gates == 'all':
        if num_qubits == 1:
            gates = ['i', 'x', 'y', 'z', 'h', 's', 'sdg', 'v', 'w']
        else:
            gates = [
                'i', 'x', 'y', 'z', 'h', 's', 'sdg', 'v', 'w', 'cx', 'cz',
                'swap'
            ]

    instructions = {
        'i': (IGate(), 1),
        'x': (XGate(), 1),
        'y': (YGate(), 1),
        'z': (ZGate(), 1),
        'h': (HGate(), 1),
        's': (SGate(), 1),
        'sdg': (SdgGate(), 1),
        'v': (VGate(), 1),
        'w': (WGate(), 1),
        'cx': (CXGate(), 2),
        'cz': (CZGate(), 2),
        'swap': (SwapGate(), 2)
    }

    if isinstance(seed, np.random.RandomState):
        rng = seed
    else:
        rng = np.random.RandomState(seed=seed)

    samples = rng.choice(gates, num_gates)

    circ = QuantumCircuit(num_qubits)

    for name in samples:
        gate, nqargs = instructions[name]
        qargs = rng.choice(range(num_qubits), nqargs, replace=False).tolist()
        circ.append(gate, qargs)

    return circ
예제 #18
0
    def test_targetsuccessive_identity_advanced_removal(self):
        """ Should remove target successive identity gates
            with DIFFERENT sets of control qubits.
            In this case CCCX(4,5,6,7) & CCX(5,6,7).
        """
        circuit = QuantumCircuit(8)
        circuit.h(0)
        circuit.h(1)
        circuit.h(2)
        circuit.h(3)
        circuit.h(4)
        circuit.h(5)
        for i in range(3):
            circuit.cx(i * 2 + 1, i * 2)
        circuit.cx(3, 5)
        for i in range(2):
            circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3)
            circuit.cx(i * 2 + 3, i * 2 + 2)
        circuit.ccx(4, 5, 6)
        for i in range(1, -1, -1):
            circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        circuit.cx(3, 5)
        circuit.cx(5, 6)
        circuit.cx(3, 5)
        circuit.x(6)
        for i in range(2):
            circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        for i in range(1, -1, -1):
            circuit.cx(i * 2 + 3, i * 2 + 2)
            circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        circuit.cx(1, 0)
        circuit.ccx(6, 1, 0)
        circuit.ccx(0, 1, 3)
        circuit.ccx(6, 3, 2)
        circuit.ccx(2, 3, 5)
        circuit.ccx(6, 5, 4)
        circuit.append(XGate().control(3), [4, 5, 6, 7], [])
        for i in range(1, -1, -1):
            circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        circuit.cx(3, 5)
        for i in range(1, 3):
            circuit.cx(i * 2 + 1, i * 2)
        circuit.ccx(5, 6, 7)

        expected = QuantumCircuit(8)
        expected.h(0)
        expected.h(1)
        expected.h(2)
        expected.h(3)
        expected.h(4)
        expected.h(5)
        for i in range(3):
            expected.cx(i * 2 + 1, i * 2)
        expected.cx(3, 5)
        for i in range(2):
            expected.ccx(i * 2, i * 2 + 1, i * 2 + 3)
            expected.cx(i * 2 + 3, i * 2 + 2)
        expected.ccx(4, 5, 6)
        for i in range(1, -1, -1):
            expected.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        expected.cx(3, 5)
        expected.cx(5, 6)
        expected.cx(3, 5)
        expected.x(6)
        for i in range(2):
            expected.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        for i in range(1, -1, -1):
            expected.cx(i * 2 + 3, i * 2 + 2)
            expected.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        expected.cx(1, 0)
        expected.ccx(6, 1, 0)
        expected.ccx(0, 1, 3)
        expected.ccx(6, 3, 2)
        expected.ccx(2, 3, 5)
        expected.ccx(6, 5, 4)
        for i in range(1, -1, -1):
            expected.ccx(i * 2, i * 2 + 1, i * 2 + 3)
        expected.cx(3, 5)
        for i in range(1, 3):
            expected.cx(i * 2 + 1, i * 2)

        stv = Statevector.from_label('0' * circuit.num_qubits)
        self.assertEqual(stv @ circuit, stv @ expected)

        pass_ = HoareOptimizer(size=5)
        result = pass_.run(circuit_to_dag(circuit))

        self.assertEqual(result, circuit_to_dag(expected))
예제 #19
0
 def test_controlled_x(self):
     """Test creation of controlled x gate"""
     self.assertEqual(XGate().control(), CnotGate())
예제 #20
0
파일: customGates.py 프로젝트: gkotas/IBM
    def _define(self):
        definition = []
        #   q = c1, c2, b, anc
        q = QuantumRegister(self.total_n, "q")

        # No easy way to inverse other than reverse the order of gates and
        # invert them.
        if not self._inverse:
            rule = [
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N, self.n, inverse=True),
                 [q[i] for i in range(2, self.n + 2)], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N, self.n, c1=q[self.total_n - 1]),
                 [q[i]
                  for i in range(2, self.n + 2)] + [q[self.total_n - 1]], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (XGate(), [q[self.total_n - 2]], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (XGate(), [q[self.total_n - 2]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
            ]
        else:
            rule = [
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (XGate(), [q[self.total_n - 2]], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (XGate(), [q[self.total_n - 2]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N,
                             self.n,
                             c1=q[self.total_n - 1],
                             inverse=True),
                 [q[i]
                  for i in range(2, self.n + 2)] + [q[self.total_n - 1]], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N,
                             self.n), [q[i]
                                       for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
            ]

        for inst in rule:
            definition.append(inst)
        self.definition = definition