1212
1313"""Phase Oracle object."""
1414
15- # Needed to avoid type hints from erroring when `classicalfunction` might not be available.
1615from __future__ import annotations
1716
18- from typing import Union , Callable , Optional , TYPE_CHECKING
17+ from qiskit . circuit import QuantumCircuit , Gate
1918
20- from qiskit .circuit import QuantumCircuit
21- from qiskit .utils import optionals as _optionals
19+ from qiskit .synthesis .boolean .boolean_expression import BooleanExpression
2220
23- if TYPE_CHECKING :
24- from qiskit .circuit .classicalfunction .boolean_expression import BooleanExpression
25- from qiskit .circuit .classicalfunction .classical_element import ClassicalElement
2621
27-
28- @_optionals .HAS_TWEEDLEDUM .require_in_instance
2922class PhaseOracle (QuantumCircuit ):
3023 r"""Phase Oracle.
3124
3225 The Phase Oracle object constructs circuits for any arbitrary
3326 input logical expressions. A logical expression is composed of logical operators
34- `&` (`AND`), `|` (`OR`), `~` (`NOT`), and `^` (`XOR`).
27+ `&` (logical `AND`), `|` (logical `OR`),
28+ `~` (logical `NOT`), and `^` (logical `XOR`).
3529 as well as symbols for literals (variables).
3630 For example, `'a & b'`, and `(v0 | ~v1) & (~v2 & v3)`
3731 are both valid string representation of boolean logical expressions.
3832
33+ A phase oracle for a boolean function `f(x)` performs the following
34+ quantum operation:
35+
36+ .. math::
37+
38+ |x\rangle \mapsto (-1)^{f(x)}|x\rangle
39+
3940 For convenience, this oracle, in addition to parsing arbitrary logical expressions,
4041 also supports input strings in the `DIMACS CNF format
41- <http ://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
42+ <https://web.archive.org/web/20190325181937/https ://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
4243 which is the standard format for specifying SATisfiability (SAT) problem instances in
4344 `Conjunctive Normal Form (CNF) <https://en.wikipedia.org/wiki/Conjunctive_normal_form>`__,
4445 which is a conjunction of one or more clauses, where a clause is a disjunction of one
@@ -50,40 +51,17 @@ class PhaseOracle(QuantumCircuit):
5051
5152 def __init__ (
5253 self ,
53- expression : Union [str , ClassicalElement ],
54- synthesizer : Optional [Callable [[BooleanExpression ], QuantumCircuit ]] = None ,
55- var_order : list = None ,
54+ expression : str ,
55+ var_order : list [str ] | None = None ,
5656 ) -> None :
57- """Creates a PhaseOracle object
58-
57+ """
5958 Args:
6059 expression: A Python-like boolean expression.
61- synthesizer: Optional. A function to convert a BooleanExpression into a QuantumCircuit
62- If None is provided, Tweedledum's `pkrm_synth` with `phase_esop` will be used.
63- var_order(list): A list with the order in which variables will be created.
60+ var_order: A list with the order in which variables will be created.
6461 (default: by appearance)
6562 """
66- from qiskit .circuit .classicalfunction .boolean_expression import BooleanExpression
67- from qiskit .circuit .classicalfunction .classical_element import ClassicalElement
68-
69- if not isinstance (expression , ClassicalElement ):
70- expression = BooleanExpression (expression , var_order = var_order )
71-
72- self .boolean_expression = expression
73-
74- if synthesizer is None :
75-
76- def synthesizer (boolean_expression ):
77- from tweedledum .synthesis import pkrm_synth # pylint: disable=import-error
78- from qiskit .circuit .classicalfunction .utils import tweedledum2qiskit
79-
80- truth_table = boolean_expression ._tweedledum_bool_expression .truth_table (
81- output_bit = 0
82- )
83- tweedledum_circuit = pkrm_synth (truth_table , {"pkrm_synth" : {"phase_esop" : True }})
84- return tweedledum2qiskit (tweedledum_circuit )
85-
86- oracle = expression .synth (synthesizer = synthesizer )
63+ self .boolean_expression = BooleanExpression (expression , var_order = var_order )
64+ oracle = self .boolean_expression .synth (circuit_type = "phase" )
8765
8866 super ().__init__ (oracle .num_qubits , name = "Phase Oracle" )
8967
@@ -107,7 +85,7 @@ def from_dimacs_file(cls, filename: str):
10785 r"""Create a PhaseOracle from the string in the DIMACS format.
10886
10987 It is possible to build a PhaseOracle from a file in `DIMACS CNF format
110- <http ://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
88+ <https://web.archive.org/web/20190325181937/https ://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
11189 which is the standard format for specifying SATisfiability (SAT) problem instances in
11290 `Conjunctive Normal Form (CNF) <https://en.wikipedia.org/wiki/Conjunctive_normal_form>`__,
11391 which is a conjunction of one or more clauses, where a clause is a disjunction of one
@@ -147,7 +125,115 @@ def from_dimacs_file(cls, filename: str):
147125 Returns:
148126 PhaseOracle: A quantum circuit with a phase oracle.
149127 """
150- from qiskit .circuit .classicalfunction .boolean_expression import BooleanExpression
128+ expr = BooleanExpression .from_dimacs_file (filename )
129+ return cls (expr )
130+
131+
132+ class PhaseOracleGate (Gate ):
133+ r"""Implements a phase oracle.
134+
135+ The Phase Oracle Gate object constructs circuits for any arbitrary
136+ input logical expressions. A logical expression is composed of logical operators
137+ `&` (logical `AND`), `|` (logical `OR`),
138+ `~` (logical `NOT`), and `^` (logical `XOR`).
139+ as well as symbols for literals (variables).
140+ For example, `'a & b'`, and `(v0 | ~v1) & (~v2 & v3)`
141+ are both valid string representation of boolean logical expressions.
142+
143+ A phase oracle for a boolean function `f(x)` performs the following
144+ quantum operation:
145+
146+ .. math::
147+
148+ |x\rangle \mapsto (-1)^{f(x)}|x\rangle
149+
150+ For convenience, this oracle, in addition to parsing arbitrary logical expressions,
151+ also supports input strings in the `DIMACS CNF format
152+ <https://web.archive.org/web/20190325181937/https://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
153+ which is the standard format for specifying SATisfiability (SAT) problem instances in
154+ `Conjunctive Normal Form (CNF) <https://en.wikipedia.org/wiki/Conjunctive_normal_form>`__,
155+ which is a conjunction of one or more clauses, where a clause is a disjunction of one
156+ or more literals. See :meth:`qiskit.circuit.library.phase_oracle.PhaseOracleGate.from_dimacs_file`.
157+
158+ From 16 variables on, possible performance issues should be expected when using the
159+ default synthesizer.
160+ """
161+
162+ def __init__ (
163+ self ,
164+ expression : str ,
165+ var_order : list [str ] | None = None ,
166+ label : str | None = None ,
167+ ) -> None :
168+ """
169+ Args:
170+ expression: A Python-like boolean expression.
171+ var_order: A list with the order in which variables will be created.
172+ (default: by appearance)
173+ label: A label for the gate to display in visualizations. Per default, the label is
174+ set to display the textual represntation of the boolean expression (truncated if needed)
175+ """
176+ self .boolean_expression = BooleanExpression (expression , var_order = var_order )
151177
178+ if label is None :
179+ short_expr_for_name = (expression [:15 ] + "..." ) if len (expression ) > 15 else expression
180+ label = short_expr_for_name
181+
182+ super ().__init__ (
183+ name = "Phase Oracle" ,
184+ num_qubits = self .boolean_expression .num_bits ,
185+ params = [],
186+ label = label ,
187+ )
188+
189+ def _define (self ):
190+ """Defined by the synthesized phase oracle"""
191+ self .definition = self .boolean_expression .synth (circuit_type = "phase" )
192+
193+ @classmethod
194+ def from_dimacs_file (cls , filename : str ) -> PhaseOracleGate :
195+ r"""Create a PhaseOracle from the string in the DIMACS format.
196+
197+ It is possible to build a PhaseOracle from a file in `DIMACS CNF format
198+ <https://web.archive.org/web/20190325181937/https://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
199+ which is the standard format for specifying SATisfiability (SAT) problem instances in
200+ `Conjunctive Normal Form (CNF) <https://en.wikipedia.org/wiki/Conjunctive_normal_form>`__,
201+ which is a conjunction of one or more clauses, where a clause is a disjunction of one
202+ or more literals.
203+
204+ The following is an example of a CNF expressed in the DIMACS format:
205+
206+ .. code:: text
207+
208+ c DIMACS CNF file with 3 satisfying assignments: 1 -2 3, -1 -2 -3, 1 2 -3.
209+ p cnf 3 5
210+ -1 -2 -3 0
211+ 1 -2 3 0
212+ 1 2 -3 0
213+ 1 -2 -3 0
214+ -1 2 3 0
215+
216+ The first line, following the `c` character, is a comment. The second line specifies that
217+ the CNF is over three boolean variables --- let us call them :math:`x_1, x_2, x_3`, and
218+ contains five clauses. The five clauses, listed afterwards, are implicitly joined by the
219+ logical `AND` operator, :math:`\land`, while the variables in each clause, represented by
220+ their indices, are implicitly disjoined by the logical `OR` operator, :math:`\lor`. The
221+ :math:`-` symbol preceding a boolean variable index corresponds to the logical `NOT`
222+ operator, :math:`\lnot`. Character `0` (zero) marks the end of each clause. Essentially,
223+ the code above corresponds to the following CNF:
224+
225+ :math:`(\lnot x_1 \lor \lnot x_2 \lor \lnot x_3)
226+ \land (x_1 \lor \lnot x_2 \lor x_3)
227+ \land (x_1 \lor x_2 \lor \lnot x_3)
228+ \land (x_1 \lor \lnot x_2 \lor \lnot x_3)
229+ \land (\lnot x_1 \lor x_2 \lor x_3)`.
230+
231+
232+ Args:
233+ filename: A file in DIMACS format.
234+
235+ Returns:
236+ PhaseOracleGate: A quantum circuit with a phase oracle.
237+ """
152238 expr = BooleanExpression .from_dimacs_file (filename )
153239 return cls (expr )
0 commit comments