// This code is part of Cqlib.
//
// (C) Copyright China Telecom Quantum Group 2026
//
// This code is licensed under the Apache License, Version 2.0. You may
// obtain a copy of this license in the LICENSE.txt file in the root directory
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.
rule merge_rx {
match { RX(a) 0, RX(b) 0 }
rewrite { RX(a + b) 0 }
}
rule merge_ry {
match {
RY(a) 0,
RY(b) 0
}
rewrite {
RY(a + b) 0
}
}
rule merge_rz {
match {
RZ(a) 0,
RZ(b) 0
}
rewrite {
RZ(a + b) 0
}
}
rule merge_phase {
match {
Phase(a) 0,
Phase(b) 0
}
rewrite {
Phase(a + b) 0
}
}
rule merge_rxx {
match {
RXX(a) 0 1,
RXX(b) 0 1
}
rewrite {
RXX(a + b) 0 1
}
}
rule merge_rxx_swapped {
match {
RXX(a) 0 1,
RXX(b) 1 0
}
rewrite {
RXX(a + b) 0 1
}
}
rule merge_ryy {
match {
RYY(a) 0 1,
RYY(b) 0 1
}
rewrite {
RYY(a + b) 0 1
}
}
rule merge_ryy_swapped {
match {
RYY(a) 0 1,
RYY(b) 1 0
}
rewrite {
RYY(a + b) 0 1
}
}
rule merge_rzz {
match {
RZZ(a) 0 1,
RZZ(b) 0 1
}
rewrite {
RZZ(a + b) 0 1
}
}
// RZZ(θ) is symmetric in wire order; merge adjacent RZZ on 0-1 then 1-0.
rule merge_rzz_swapped {
match {
RZZ(a) 0 1,
RZZ(b) 1 0
}
rewrite {
RZZ(a + b) 0 1
}
}
rule merge_rzx {
match {
RZX(a) 0 1,
RZX(b) 0 1
}
rewrite {
RZX(a + b) 0 1
}
}
rule merge_crx {
match {
CRX(a) 0 1,
CRX(b) 0 1
}
rewrite {
CRX(a + b) 0 1
}
}
rule merge_cry {
match {
CRY(a) 0 1,
CRY(b) 0 1
}
rewrite {
CRY(a + b) 0 1
}
}
rule merge_crz {
match {
CRZ(a) 0 1,
CRZ(b) 0 1
}
rewrite {
CRZ(a + b) 0 1
}
}
rule merge_gphase {
match {
GPhase(a),
GPhase(b)
}
rewrite {
GPhase(a + b)
}
}
rule merge_s_to_z {
match {
S 0,
S 0
}
rewrite {
Z 0
}
}
rule merge_sdg_to_z {
match {
SDG 0,
SDG 0
}
rewrite {
Z 0
}
}
rule merge_t_to_s {
match {
T 0,
T 0
}
rewrite {
S 0
}
}
rule merge_tdg_to_sdg {
match {
TDG 0,
TDG 0
}
rewrite {
SDG 0
}
}
rule merge_x2p_to_x {
match {
X2P 0,
X2P 0
}
rewrite {
X 0,
GPhase(-π/2)
}
}
rule merge_x2m_to_x {
match {
X2M 0,
X2M 0
}
rewrite {
X 0,
GPhase(π/2)
}
}
rule merge_y2p_to_y {
match {
Y2P 0,
Y2P 0
}
rewrite {
Y 0,
GPhase(-π/2)
}
}
rule merge_y2m_to_y {
match {
Y2M 0,
Y2M 0
}
rewrite {
Y 0,
GPhase(π/2)
}
}
rule merge_rxy {
match { RXY(a, phi_a) 0, RXY(b, phi_b) 0 }
require { phi_b - phi_a == 0 mod 2*π }
rewrite { RXY(a + b, phi_a) 0 }
}
rule merge_xy2p {
match { XY2P(a) 0, XY2P(b) 0 }
require { b - a == 0 mod 2*π }
rewrite { XY(a) 0 }
}
rule merge_xy2m {
match { XY2M(a) 0, XY2M(b) 0 }
require { b - a == 0 mod 2*π }
rewrite { XY(π + a) 0 }
}
rule merge_fsim {
match { FSIM(a, b) 0 1, FSIM(c, d) 0 1 }
rewrite { FSIM(a + c, b + d) 0 1 }
}
rule merge_xy2p_xy2m_to_xy {
match { XY2P(a) 0, XY2M(b) 0 }
require { b - a == π mod 2*π }
rewrite { XY(a) 0 }
}
rule merge_xy2m_xy2p_to_xy {
match { XY2M(a) 0, XY2P(b) 0 }
require { b - a == π mod 2*π }
rewrite { XY(π + a) 0 }
}
// General equatorial pi-pulse products and opposite-axis rotations.
rule merge_xy_pair_to_rz {
match { XY(a) 0, XY(b) 0 }
rewrite { RZ(2*(b - a)) 0, GPhase(π) }
}
rule merge_rxy_opposite_axis {
match { RXY(a, phi_a) 0, RXY(b, phi_b) 0 }
require { phi_b - phi_a == π mod 2*π }
rewrite { RXY(a - b, phi_a) 0 }
}