Skip to content

Commit

Permalink
Add convenience method Circuit.add_clexpr_from_logicexp() (#1681)
Browse files Browse the repository at this point in the history
  • Loading branch information
cqc-alec authored Nov 19, 2024
1 parent 6c23c79 commit b551702
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
29 changes: 29 additions & 0 deletions pytket/binders/circuit/Circuit/add_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,35 @@ void init_circuit_add_op(py::class_<Circuit, std::shared_ptr<Circuit>> &c) {
":param args: The bits to apply the expression to\n"
":return: the new :py:class:`Circuit`",
py::arg("expr"), py::arg("args"))
.def(
"add_clexpr_from_logicexp",
[](Circuit *circ, const py::tket_custom::LogicExpression &exp,
const py::tket_custom::SequenceVec<Bit> &output_bits,
const py::kwargs &kwargs) {
py::list outputs;
for (const auto &bit : output_bits) {
outputs.append(bit);
}
py::module clexpr = py::module::import("pytket.circuit.clexpr");
py::object add_op =
clexpr.attr("_add_clexpr_to_circuit_from_logicexp");
add_op(circ, exp, outputs, **kwargs);
return circ;
},
"Append a :py:class:`ClExprOp` defined in terms of a logical "
"expression.\n\n"
"Example:\n"
">>> c = Circuit()\n"
">>> x_reg = c.add_c_register('x', 3)\n"
">>> y_reg = c.add_c_register('y', 3)\n"
">>> z_reg = c.add_c_register('z', 3)\n"
">>> c.add_clexpr_from_logicexp(x_reg | y_reg, z_reg.to_list())\n"
">>> [ClExpr x[0], x[1], x[2], y[0], y[1], y[2], z[0], z[1], z[2]; "
"]\n\n"
":param exp: logical expression\n"
":param output_bits: list of bits in output\n"
":return: the updated circuit",
py::arg("exp"), py::arg("output_bits"))
.def(
"add_custom_gate",
[](Circuit *circ, const composite_def_ptr_t &definition,
Expand Down
1 change: 1 addition & 0 deletions pytket/docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Features:
* Use `ClExprOp` by default when converting from QASM.
* Extend `DecomposeClassicalExp` to handle `ClExprOp` as well as
`ClassicalExpBox`.
* Add convenience method `Circuit.add_clecpr_from_logicexp()`.

Deprecations:

Expand Down
16 changes: 16 additions & 0 deletions pytket/pytket/_tket/circuit.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,22 @@ class Circuit:
:param args: The bits to apply the expression to
:return: the new :py:class:`Circuit`
"""
def add_clexpr_from_logicexp(self, exp: pytket.circuit.logic_exp.LogicExp, output_bits: typing.Sequence[pytket._tket.unit_id.Bit], **kwargs: Any) -> Circuit:
"""
Append a :py:class:`ClExprOp` defined in terms of a logical expression.
Example:
>>> c = Circuit()
>>> x_reg = c.add_c_register('x', 3)
>>> y_reg = c.add_c_register('y', 3)
>>> z_reg = c.add_c_register('z', 3)
>>> c.add_clexpr_from_logicexp(x_reg | y_reg, z_reg.to_list())
>>> [ClExpr x[0], x[1], x[2], y[0], y[1], y[2], z[0], z[1], z[2]; ]
:param exp: logical expression
:param output_bits: list of bits in output
:return: the updated circuit
"""
@typing.overload
def add_conditional_barrier(self, barrier_qubits: typing.Sequence[int], barrier_bits: typing.Sequence[int], condition_bits: typing.Sequence[int], value: int, data: str = '') -> Circuit:
"""
Expand Down
8 changes: 8 additions & 0 deletions pytket/pytket/circuit/clexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from dataclasses import dataclass
from typing import Any

from pytket.circuit import (
Bit,
Expand Down Expand Up @@ -194,3 +195,10 @@ def check_register_alignments(circ: Circuit) -> bool:
):
return False
return True


def _add_clexpr_to_circuit_from_logicexp(
circ: Circuit, exp: LogicExp, output_bits: list[Bit], **kwargs: Any
) -> None:
wexpr, args = wired_clexpr_from_logic_exp(exp, output_bits)
circ.add_clexpr(wexpr, args, **kwargs)
20 changes: 20 additions & 0 deletions pytket/tests/clexpr_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,23 @@ def test_circbox() -> None:
c2 = c1.copy()
c2.flatten_registers()
assert c1 == c2


def test_add_logicexp_as_clexpr() -> None:
c = Circuit()
a_reg = c.add_c_register("a", 3)
b_reg = c.add_c_register("b", 3)
c_reg = c.add_c_register("c", 3)
c.add_clexpr_from_logicexp(a_reg | b_reg, c_reg.to_list())
qasm = circuit_to_qasm_str(c, header="hqslib1")
assert (
qasm
== """OPENQASM 2.0;
include "hqslib1.inc";
creg a[3];
creg b[3];
creg c[3];
c = (a | b);
"""
)

0 comments on commit b551702

Please sign in to comment.