def logical_and(self,
                qr_variables,
                qb_target,
                qr_ancillae,
                flags=None,
                mct_mode='no-ancilla'):
    """Build a collective conjunction (AND) circuit in place using mct.

    Args:
        self (QuantumCircuit): The QuantumCircuit object to build the conjunction on.
        qr_variables (QuantumRegister): The QuantumRegister holding the variable qubits.
        qb_target (Qubit): The target qubit to hold the conjunction result.
        qr_ancillae (QuantumRegister): The ancillary QuantumRegister for building the mct.
        flags (list[int]): A list of +1/-1/0 to mark negations or omissions of qubits.
        mct_mode (str): The mct building mode.
    """
    # pylint: disable=cyclic-import
    from qiskit.circuit.library import AND

    warnings.warn(
        'The QuantumCircuit.AND method is deprecated as of Terra 0.13.1 / Aqua 0.7.0 and '
        'will be removed no earlier than 3 months after the release date. '
        'The logic AND has moved to qiskit.circuit.library.AND and has become a circuit '
        'object which can be appended to your existing circuit.',
        DeprecationWarning,
        stacklevel=2)
    and_circuit = AND(num_variable_qubits=len(qr_variables),
                      flags=flags,
                      mcx_mode=mct_mode)
    qubits = qr_variables[:] + [qb_target]
    if qr_ancillae:
        qubits += qr_ancillae[:and_circuit.num_ancilla_qubits]

    self.append(and_circuit.to_gate(), qubits)
Esempio n. 2
0
    def test_and(self, num_variables, flags, mcx_mode):
        """Test the and circuit."""
        and_circuit = AND(num_variables, flags, mcx_mode=mcx_mode)
        flags = flags or [1] * num_variables

        def reference(bits):
            flagged = []
            for flag, bit in zip(flags, bits):
                if flag < 0:
                    flagged += [1 - bit]
                elif flag > 0:
                    flagged += [bit]
            return np.all(flagged)

        self.assertBooleanFunctionIsCorrect(and_circuit, reference)
Esempio n. 3
0
        def build_clause(clause_expr):
            if clause_expr[0] == 'and':
                lits = [l[1] for l in clause_expr[1:]]
            elif clause_expr[0] == 'lit':
                lits = [clause_expr[1]]
            else:
                raise AquaError('Unexpected clause expression {}.'.format(clause_expr))
            flags = BooleanLogicNormalForm._lits_to_flags(lits)
            and_circuit = AND(num_variable_qubits=len(self._variable_register),
                              flags=flags, mcx_mode=mct_mode)
            qubits = self._variable_register[:] + [self._output_register[self._output_idx]]
            if self._ancillary_register:
                qubits += self._ancillary_register[:and_circuit.num_ancilla_qubits]

            circuit.compose(and_circuit, qubits, inplace=True)
    def construct_circuit(self,
                          circuit=None,
                          variable_register=None,
                          clause_register=None,
                          output_register=None,
                          ancillary_register=None,
                          mct_mode='basic'):  # pylint: disable=arguments-differ
        """
        Construct circuit.

        Args:
            circuit (QuantumCircuit): The optional circuit to extend from
            variable_register (QuantumRegister): The optional quantum register
                            to use for problem variables
            clause_register (QuantumRegister): The optional quantum register
                            to use for problem clauses
            output_register (QuantumRegister): The optional quantum register
                            to use for holding the output
            ancillary_register (QuantumRegister): The optional quantum register to use as ancilla
            mct_mode (str): The mode to use for building Multiple-Control Toffoli

        Returns:
            QuantumCircuit: quantum circuit.
        Raises:
            AquaError: invalid input
        """

        circuit = self._set_up_circuit(circuit=circuit,
                                       variable_register=variable_register,
                                       clause_register=clause_register,
                                       output_register=output_register,
                                       ancillary_register=ancillary_register,
                                       mct_mode=mct_mode)
        if self._depth == 0:
            self._construct_circuit_for_tiny_expr(circuit)
        elif self._depth == 1:
            lits = [l[1] for l in self._ast[1:]]
            flags = BooleanLogicNormalForm._lits_to_flags(lits)
            if flags is not None:
                or_circuit = OR(num_variable_qubits=len(
                    self._variable_register),
                                flags=flags,
                                mcx_mode=mct_mode)
                qubits = self._variable_register[:] + [
                    self._output_register[0]
                ]
                if self._ancillary_register:
                    qubits += self._ancillary_register[:or_circuit.
                                                       num_ancilla_qubits]

                circuit.compose(or_circuit, qubits, inplace=True)
            else:
                circuit.u(pi, 0, pi, self._output_register[0])
        else:  # self._depth == 2
            # compute all clauses
            for clause_index, clause_expr in enumerate(self._ast[1:]):
                if clause_expr[0] == 'and':
                    lits = [l[1] for l in clause_expr[1:]]
                elif clause_expr[0] == 'lit':
                    lits = [clause_expr[1]]
                else:
                    raise AquaError(
                        'Operator "{}" of clause {} in logic expression {} is unexpected.'
                        .format(clause_expr[0], clause_index, self._ast))
                flags = BooleanLogicNormalForm._lits_to_flags(lits)
                if flags is not None:
                    and_circuit = AND(num_variable_qubits=len(
                        self._variable_register),
                                      flags=flags,
                                      mcx_mode=mct_mode)
                    qubits = self._variable_register[:] + [
                        self._clause_register[clause_index]
                    ]
                    if self._ancillary_register:
                        qubits += self._ancillary_register[:and_circuit.
                                                           num_ancilla_qubits]

                    circuit.compose(and_circuit, qubits, inplace=True)
                else:
                    circuit.u(pi, 0, pi, self._clause_register[clause_index])

            # init the output qubit to 1
            circuit.u(pi, 0, pi, self._output_register[self._output_idx])

            # collect results from all clauses
            circuit.u(pi, 0, pi, self._clause_register)
            circuit.mct(self._clause_register,
                        self._output_register[self._output_idx],
                        self._ancillary_register,
                        mode=mct_mode)
            circuit.u(pi, 0, pi, self._clause_register)

            # uncompute all clauses
            for clause_index, clause_expr in enumerate(self._ast[1:]):
                if clause_expr[0] == 'and':
                    lits = [l[1] for l in clause_expr[1:]]
                elif clause_expr[0] == 'lit':
                    lits = [clause_expr[1]]
                flags = BooleanLogicNormalForm._lits_to_flags(lits)
                if flags is not None:
                    and_circuit = AND(num_variable_qubits=len(
                        self._variable_register),
                                      flags=flags,
                                      mcx_mode=mct_mode)
                    qubits = self._variable_register[:] + [
                        self._clause_register[clause_index]
                    ]
                    if self._ancillary_register:
                        qubits += self._ancillary_register[:and_circuit.
                                                           num_ancilla_qubits]

                    circuit.compose(and_circuit, qubits, inplace=True)
                else:
                    circuit.u(pi, 0, pi, self._clause_register[clause_index])
        return circuit