Skip to content

Commit 808a41a

Browse files
authored
Always squash symbolic circuits in Transforms::squash_1qb_to_Rz_PhasedX() (#2162)
1 parent 7fdae57 commit 808a41a

9 files changed

Lines changed: 43 additions & 17 deletions

File tree

‎TKET_VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.82
1+
2.1.83

‎pytket/docs/changelog.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Changelog
22

3-
# 2.17.0 (unreleased)
3+
# 2.17.0 (May 2026)
44

55
Fixes:
6-
- Fix handling of wasm function calls in circuit boxes
6+
- Fix handling of wasm function calls in circuit boxes.
7+
- Fix handling of symbolic circuits in Transforms::squash_1qb_to_Rz_PhasedX().
78

89
## 2.16.0 (March 2026)
910

‎tket-c-api/src/tket-c-api.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ TketError tket_clifford_simp(
149149
TketError tket_squash_phasedx_rz(TketCircuit *tc) {
150150
if (!tc) return TKET_ERROR_NULL_POINTER;
151151

152-
Transforms::squash_1qb_to_Rz_PhasedX(true).apply(tc->circuit);
152+
Transforms::squash_1qb_to_Rz_PhasedX().apply(tc->circuit);
153153

154154
return TKET_SUCCESS;
155155
}

‎tket/include/tket/Transformations/BasicOptimisation.hpp‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,8 @@ Transform normalise_TK2();
132132
* @brief Squash single qubit gates into PhasedX and Rz gates.
133133
*
134134
* Commute Rzs to the back if possible.
135-
*
136-
* @param always_squash_symbols whether to squash symbols regardless of
137-
* complexity increase
138135
*/
139-
Transform squash_1qb_to_Rz_PhasedX(bool always_squash_symbols = false);
136+
Transform squash_1qb_to_Rz_PhasedX();
140137

141138
/**
142139
* Generate a transform that rounds all angles to the nearest \f$ \pi / 2^n \f$.

‎tket/src/Predicates/PassGenerators.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ PassPtr gen_auto_rebase_pass(const OpTypeSet& allowed_gates, bool allow_swaps) {
270270
PassPtr gen_auto_squash_pass(const OpTypeSet& singleqs) {
271271
auto find_squash = [singleqs]() {
272272
if (singleqs.contains(OpType::Rz) && singleqs.contains(OpType::PhasedX)) {
273-
return Transforms::squash_1qb_to_Rz_PhasedX(false);
273+
return Transforms::squash_1qb_to_Rz_PhasedX();
274274
} else {
275275
auto tk1_replacement = find_tk1_replacement(singleqs);
276276
return Transforms::squash_factory(singleqs, tk1_replacement, false);

‎tket/src/Predicates/PassLibrary.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ const PassPtr &ZZPhaseToRz() {
470470

471471
const PassPtr &SquashRzPhasedX() {
472472
static const PassPtr pp([]() {
473-
Transform t = Transforms::squash_1qb_to_Rz_PhasedX(true);
473+
Transform t = Transforms::squash_1qb_to_Rz_PhasedX();
474474
PredicatePtrMap s_ps;
475475
PredicateClassGuarantees g_postcons{
476476
{typeid(GateSetPredicate), Guarantee::Clear}};

‎tket/src/Transformations/RzPhasedXSquash.cpp‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414

1515
#include "tket/Transformations/RzPhasedXSquash.hpp"
1616

17+
#include <algorithm>
1718
#include <memory>
19+
#include <tkassert/Assert.hpp>
20+
#include <vector>
1821

22+
#include "tket/Circuit/Command.hpp"
23+
#include "tket/OpType/OpType.hpp"
1924
#include "tket/Transformations/BasicOptimisation.hpp"
2025
#include "tket/Transformations/Decomposition.hpp"
2126
#include "tket/Transformations/PQPSquash.hpp"
@@ -93,15 +98,20 @@ std::pair<Circuit, Gate_ptr> RzPhasedXSquasher::flush(
9398
return {replacement, rz3_gate};
9499
}
95100

96-
Transform squash_1qb_to_Rz_PhasedX(bool always_squash_symbols) {
97-
return Transform([always_squash_symbols](Circuit &circ) {
101+
Transform squash_1qb_to_Rz_PhasedX() {
102+
return Transform([](Circuit &circ) {
98103
bool reverse = false;
99104
bool success = decompose_ZX().apply(circ);
100105
auto squasher = std::make_unique<RzPhasedXSquasher>(reverse);
101-
return SingleQubitSquash(
102-
std::move(squasher), circ, reverse, always_squash_symbols)
103-
.squash() ||
104-
success;
106+
success =
107+
SingleQubitSquash(std::move(squasher), circ, reverse, true).squash() ||
108+
success;
109+
// Assert that all the Rx gates resulting from decompose_ZX() have gone.
110+
std::vector<Command> cmds = circ.get_commands();
111+
TKET_ASSERT(!std::any_of(cmds.begin(), cmds.end(), [](const Command &cmd) {
112+
return cmd.get_op_ptr()->get_type() == OpType::Rx;
113+
}));
114+
return success;
105115
});
106116
}
107117

‎tket/test/src/test_CompilerPass.cpp‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,24 @@ SCENARIO("AutoSquash") {
23502350
REQUIRE_THROWS_AS(gen_auto_squash_pass({OpType::Rx}), Unsupported);
23512351
REQUIRE_THROWS_AS(gen_auto_squash_pass({}), Unsupported);
23522352
}
2353+
GIVEN("Squashing PhasedX and Rz with a symbolic circuit") {
2354+
// https://github.com/Quantinuum/tket/issues/2152
2355+
Sym asym = SymEngine::symbol("a");
2356+
Expr alpha(asym);
2357+
Circuit circ0(2);
2358+
circ0.add_op<unsigned>(OpType::PhasedX, {0.5, 0.5}, {1});
2359+
circ0.add_op<unsigned>(OpType::Rz, alpha, {1});
2360+
circ0.add_op<unsigned>(OpType::PhasedX, {0.5, 0.0}, {1});
2361+
circ0.add_op<unsigned>(OpType::ZZPhase, 1.0, {0, 1});
2362+
CompilationUnit cu(circ0);
2363+
gen_auto_squash_pass({OpType::PhasedX, OpType::Rz})->apply(cu);
2364+
Circuit circ1 = cu.get_circ_ref();
2365+
symbol_map_t symmap;
2366+
symmap[asym] = 0.0;
2367+
circ0.symbol_substitution(symmap);
2368+
circ1.symbol_substitution(symmap);
2369+
REQUIRE(test_unitary_comparison(circ0, circ1));
2370+
}
23532371
}
23542372

23552373
SCENARIO("Efficient TK2 synthesis") {

‎tket/test/src/test_Synthesis.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2148,7 +2148,7 @@ SCENARIO("Test squash Rz PhasedX") {
21482148
circ.add_op<unsigned>(OpType::PhasedX, {alpha, beta}, {0});
21492149
circ.add_op<unsigned>(OpType::Rz, 0.5, {0});
21502150
circ.add_op<unsigned>(OpType::PhasedX, {0.5, 0.5}, {0});
2151-
Transforms::squash_1qb_to_Rz_PhasedX(true).apply(circ);
2151+
Transforms::squash_1qb_to_Rz_PhasedX().apply(circ);
21522152
OpTypeSet allowed = {OpType::Rz, OpType::PhasedX};
21532153
for (const Command &cmd : circ) {
21542154
OpType optype = cmd.get_op_ptr()->get_type();

0 commit comments

Comments
 (0)