From 831ec93d6f61b92612b2280f20960e37043a70b8 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 13 Feb 2025 17:49:59 +0200 Subject: [PATCH] Fixes according to PR review --- .../synthesis/boolean/boolean_expression.py | 12 ++-- .../boolean/boolean_expression_synth.py | 2 - ...an_expression_update-39c19edbbe71ba0d.yaml | 58 +++++++++++++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/qiskit/synthesis/boolean/boolean_expression.py b/qiskit/synthesis/boolean/boolean_expression.py index c16d4bf63863..9cca8f4fb4a2 100644 --- a/qiskit/synthesis/boolean/boolean_expression.py +++ b/qiskit/synthesis/boolean/boolean_expression.py @@ -16,7 +16,7 @@ import itertools import re from os.path import isfile -from typing import Union +from typing import Union, Callable import numpy as np from .boolean_expression_visitor import ( @@ -32,7 +32,7 @@ class TruthTable: 12 # above this number of bits, do not explicitly save the values in a list ) - def __init__(self, func, num_bits): + def __init__(self, func: Callable, num_bits: int): self.func = func self.num_bits = num_bits self.explicit_storage = self.num_bits <= self.EXPLICIT_REP_THRESHOLD @@ -44,15 +44,15 @@ def __init__(self, func, num_bits): else: self.implicit_values = {} - def all_assignments(self): - """Return an ordered list of all assignments, ordered from left to right + def all_assignments(self) -> list[tuple[bool]]: + """Return an ordered list of all assignments, ordered from right to left i.e. 000, 100, 010, 110, 001, 101, 011, 111""" return [ tuple(reversed(assignment)) for assignment in itertools.product([False, True], repeat=self.num_bits) ] - def __getitem__(self, key): + def __getitem__(self, key: Union[str, tuple[bool]]) -> bool: if isinstance(key, str): key = (bit != "0" for bit in key) if self.explicit_storage: @@ -61,7 +61,7 @@ def __getitem__(self, key): else: return self.implicit_values.setdefault(key, self.func(key)) - def __str__(self): + def __str__(self) -> str: if self.explicit_storage: return "".join( "1" if self[assignemnt] else "0" for assignemnt in self.all_assignments() diff --git a/qiskit/synthesis/boolean/boolean_expression_synth.py b/qiskit/synthesis/boolean/boolean_expression_synth.py index 962cbce080aa..c8314de6bd15 100644 --- a/qiskit/synthesis/boolean/boolean_expression_synth.py +++ b/qiskit/synthesis/boolean/boolean_expression_synth.py @@ -58,8 +58,6 @@ def generate_esop(self, assignment): return ["-" * self.truth_table.num_bits] # True; a don't care clause else: return [] # False - if assignment in self.cofactor_table: - return self.cofactor_table[assignment] i = len(assignment) # current variable negative_esop = self.generate_esop(assignment + (False,)) positive_esop = self.generate_esop(assignment + (True,)) diff --git a/releasenotes/notes/boolean_expression_update-39c19edbbe71ba0d.yaml b/releasenotes/notes/boolean_expression_update-39c19edbbe71ba0d.yaml index b5d80be69f42..dadbaaa82747 100644 --- a/releasenotes/notes/boolean_expression_update-39c19edbbe71ba0d.yaml +++ b/releasenotes/notes/boolean_expression_update-39c19edbbe71ba0d.yaml @@ -6,3 +6,61 @@ upgrade_circuits: :class:`.BitFlipOracle` was added as an alternative to directly synthesizing :class:`.BooleanExpression`, as this class is removed in Qiskit 2.0. + + The interface of :class:`.PhaseOracle` was simplified; it no longer + accepts a `synthesizer` paramter, and the `expression` parameter + can only be a string; `ClassicalElement` have been deprecated. + + :class:`.PhaseOracle` is used exactly as before: + .. code-block:: python + + from qiskit.circuit.library.phase_oracle import PhaseOracle + bool_expr = "(x0 & x1 | ~x2) & x4" + oracle = PhaseOracle(bool_expr) + print(oracle)) + + .. code-block:: text + + q_0: ─o──■──■─ + │ │ │ + q_1: ─┼──o──■─ + │ │ │ + q_2: ─o──o──┼─ + │ │ │ + q_3: ─■──■──■─ + +features_circuits: + - | + The new :class:`.PhaseBitFlipOracle` has the same interface as + :class:`.PhaseOracle`, but synthesizes a bit flip oracle instead + of a phase flip oracle, meaning it acts on one additional qubit + and can be seen a applying a controlled X operation, where the + control is the value of the expression encoded by the oracle. + + .. code-block:: python + + from qiskit.circuit.library.bit_flip_oracle import BitFlipOracle + bool_expr = "(x0 & x1 | ~x2) & x4" + oracle = BitFlipOracle(bool_expr) + print(oracle) + + .. code-block:: text + + q_0: ──o────■────■── + │ │ │ + q_1: ──┼────o────■── + │ │ │ + q_2: ──o────o────┼── + │ │ │ + q_3: ──■────■────■── + ┌─┴─┐┌─┴─┐┌─┴─┐ + q_4: ┤ X ├┤ X ├┤ X ├ + └───┘└───┘└───┘ + + .. code-block:: python + + print(oracle.evaluate_bitstring("1010")) + + .. code-block:: text + + True \ No newline at end of file