quant_iron/
macros.rs

1/// Creates a `Circuit` object using a domain-specific language.
2///
3/// The macro provides a concise, intuitive way to define a quantum circuit.
4///
5/// # Syntax
6///
7/// The basic structure is:
8/// ```ignore
9/// circuit! {
10///     qubits: <number_of_qubits>,
11///     <operation_1>,
12///     <operation_2>,
13///     ...
14/// }
15/// ```
16///
17/// Where `<operation>` can be one of the following:
18///
19/// ## Single-Qubit Gates
20///
21/// Apply a gate to a single qubit or multiple qubits individually.
22/// - `h(qubit)` or `h([qubit1, qubit2, ...])`
23/// - `x(qubit)` or `x([qubit1, qubit2, ...])`
24/// - `y(qubit)` or `y([qubit1, qubit2, ...])`
25/// - `z(qubit)` or `z([qubit1, qubit2, ...])`
26/// - `s(qubit)` or `s([qubit1, qubit2, ...])`
27/// - `t(qubit)` or `t([qubit1, qubit2, ...])`
28/// - `sdag(qubit)` or `sdag([qubit1, qubit2, ...])`
29/// - `tdag(qubit)` or `tdag([qubit1, qubit2, ...])`
30/// - `id(qubit)` or `id([qubit1, qubit2, ...])`
31///
32/// ## Two-Qubit Gates
33///
34/// - `cnot(control, target)`
35/// - `swap(qubit1, qubit2)`
36///
37/// ## Controlled Gates
38///
39/// Controlled gates can have single or multiple targets and controls.
40/// - `ch(target, control)` or `ch([targets], [controls])`
41/// - `cx(target, control)` or `cx([targets], [controls])`
42/// - `cy(target, control)` or `cy([targets], [controls])`
43/// - `cz(target, control)` or `cz([targets], [controls])`
44/// - `cs(target, control)` or `cs([targets], [controls])`
45/// - `csdag(target, control)` or `csdag([targets], [controls])`
46/// - `ct(target, control)` or `ct([targets], [controls])`
47/// - `ctdag(target, control)` or `ctdag([targets], [controls])`
48///
49/// ## Gates with Angles
50///
51/// Angles are `f64` values.
52/// - `rx(qubit, angle)` or `rx([qubits], angle)`
53/// - `ry(qubit, angle)` or `ry([qubits], angle)`
54/// - `rz(qubit, angle)` or `rz([qubits], angle)`
55/// - `p(qubit, angle)` or `p([qubits], angle)`
56/// - `ry_phase(qubit, theta, phi)` or `ry_phase([qubits], theta, phi)`
57/// - `ry_phase_dag(qubit, theta, phi)` or `ry_phase_dag([qubits], theta, phi)`
58///
59/// ## Controlled Gates with Angles
60///
61/// - `crx(target, control, angle)` or `crx([targets], [controls], angle)`
62/// - `cry(target, control, angle)` or `cry([targets], [controls], angle)`
63/// - `crz(target, control, angle)` or `crz([targets], [controls], angle)`
64/// - `cp(target, control, angle)` or `cp([targets], [controls], angle)`
65/// - `cry_phase(target, control, theta, phi)` or `cry_phase([targets], [controls], theta, phi)`
66/// - `cry_phase_dag(target, control, theta, phi)` or `cry_phase_dag([targets], [controls], theta, phi)`
67///
68/// ## Special Gates
69///
70/// - `toffoli(target, control1, control2)`
71/// - `cswap(target1, target2, control)` or `cswap(target1, target2, [controls])`
72/// - `matchgate(target, theta, phi1, phi2)`
73/// - `cmatchgate(target, control, theta, phi1, phi2)` or `cmatchgate(target, [controls], theta, phi1, phi2)`
74/// - `pauli_string(pauli_string)`
75/// - `pauli_time_evolution(pauli_string, time)`
76///
77/// ## Unitary Gates
78///
79/// Apply a custom unitary matrix.
80/// - `unitary(qubit, matrix)`
81/// - `unitary([qubits], matrix)`
82/// - `cunitary(target, control, matrix)` or `cunitary([targets], [controls], matrix)`
83/// 
84/// ### Warning
85/// 
86/// * The `matrix` must be a valid unitary matrix. if the matrix is not unitary, the macro will panic.
87///
88/// ## Measurement Gates
89///
90/// - `measurex(qubit)` or `measurex([qubits])`
91/// - `measurey(qubit)` or `measurey([qubits])`
92/// - `measurez(qubit)` or `measurez([qubits])`
93/// - `measure_custom(qubit, matrix)` or `measure_custom([qubits], matrix)`
94/// 
95/// # Returns
96/// 
97/// * `Result<Circuit, Error>` - A result containing the constructed `Circuit` or an error if the circuit cannot be built.
98#[macro_export]
99macro_rules! circuit {
100    (qubits: $num_qubits:expr, $($rest:tt)*) => {
101        {
102            let mut builder = $crate::circuit::CircuitBuilder::new($num_qubits);
103            $crate::circuit_internal!(builder, $($rest)*);
104            builder.build_final()
105        }
106    };
107}
108
109#[doc(hidden)]
110#[macro_export]
111macro_rules! circuit_internal {
112    // Base case: No more tokens to process.
113    ($builder:ident,) => {};
114
115    // --- Gate Overloading rules (with trailing comma) ---
116    // For each gate, most specific form (arrays) -> least specific form (single qubits) for disambiguation.
117
118    // Multi-qubit gates
119    ($builder:ident, h([$($qubits:expr),*]), $($rest:tt)*) => { $builder.h_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
120    ($builder:ident, x([$($qubits:expr),*]), $($rest:tt)*) => { $builder.x_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
121    ($builder:ident, y([$($qubits:expr),*]), $($rest:tt)*) => { $builder.y_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
122    ($builder:ident, z([$($qubits:expr),*]), $($rest:tt)*) => { $builder.z_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
123    ($builder:ident, s([$($qubits:expr),*]), $($rest:tt)*) => { $builder.s_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
124    ($builder:ident, t([$($qubits:expr),*]), $($rest:tt)*) => { $builder.t_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
125    ($builder:ident, id([$($qubits:expr),*]), $($rest:tt)*) => { $builder.id_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
126    ($builder:ident, sdag([$($qubits:expr),*]), $($rest:tt)*) => { $builder.sdag_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
127    ($builder:ident, tdag([$($qubits:expr),*]), $($rest:tt)*) => { $builder.tdag_gates(vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
128
129    // Single-qubit gates
130    ($builder:ident, h($qubit:expr), $($rest:tt)*) => { $builder.h_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
131    ($builder:ident, x($qubit:expr), $($rest:tt)*) => { $builder.x_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
132    ($builder:ident, y($qubit:expr), $($rest:tt)*) => { $builder.y_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
133    ($builder:ident, z($qubit:expr), $($rest:tt)*) => { $builder.z_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
134    ($builder:ident, s($qubit:expr), $($rest:tt)*) => { $builder.s_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
135    ($builder:ident, t($qubit:expr), $($rest:tt)*) => { $builder.t_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
136    ($builder:ident, id($qubit:expr), $($rest:tt)*) => { $builder.id_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
137    ($builder:ident, sdag($qubit:expr), $($rest:tt)*) => { $builder.sdag_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
138    ($builder:ident, tdag($qubit:expr), $($rest:tt)*) => { $builder.tdag_gate($qubit); $crate::circuit_internal!($builder, $($rest)*); };
139
140    // Two-argument gates
141    ($builder:ident, cnot($arg1:expr, $arg2:expr), $($rest:tt)*) => { $builder.cnot_gate($arg1, $arg2); $crate::circuit_internal!($builder, $($rest)*); };
142    ($builder:ident, swap($arg1:expr, $arg2:expr), $($rest:tt)*) => { $builder.swap_gate($arg1, $arg2); $crate::circuit_internal!($builder, $($rest)*); };
143
144    // --- Controlled gate overloading ---
145    ($builder:ident, ch([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.ch_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
146    ($builder:ident, ch([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.ch_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
147    ($builder:ident, ch($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.ch_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
148    ($builder:ident, ch($target:expr, $control:expr), $($rest:tt)*) => { $builder.ch_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
149    ($builder:ident, cx([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.cx_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
150    ($builder:ident, cx([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.cx_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
151    ($builder:ident, cx($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.cx_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
152    ($builder:ident, cx($target:expr, $control:expr), $($rest:tt)*) => { $builder.cx_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
153    ($builder:ident, cy([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.cy_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
154    ($builder:ident, cy([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.cy_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
155    ($builder:ident, cy($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.cy_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
156    ($builder:ident, cy($target:expr, $control:expr), $($rest:tt)*) => { $builder.cy_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
157    ($builder:ident, cz([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.cz_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
158    ($builder:ident, cz([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.cz_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
159    ($builder:ident, cz($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.cz_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
160    ($builder:ident, cz($target:expr, $control:expr), $($rest:tt)*) => { $builder.cz_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
161    ($builder:ident, cs([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.cs_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
162    ($builder:ident, cs([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.cs_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
163    ($builder:ident, cs($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.cs_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
164    ($builder:ident, cs($target:expr, $control:expr), $($rest:tt)*) => { $builder.cs_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
165    ($builder:ident, csdag([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.csdag_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
166    ($builder:ident, csdag([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.csdag_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
167    ($builder:ident, csdag($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.csdag_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
168    ($builder:ident, csdag($target:expr, $control:expr), $($rest:tt)*) => { $builder.csdag_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
169    ($builder:ident, ct([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.ct_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
170    ($builder:ident, ct([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.ct_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
171    ($builder:ident, ct($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.ct_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
172    ($builder:ident, ct($target:expr, $control:expr), $($rest:tt)*) => { $builder.ct_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
173    ($builder:ident, ctdag([$($targets:expr),*], [$($controls:expr),*]), $($rest:tt)*) => { $builder.ctdag_gates(vec![$($targets),*], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
174    ($builder:ident, ctdag([$($targets:expr),*], $control:expr), $($rest:tt)*) => { $builder.ctdag_gates(vec![$($targets),*], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
175    ($builder:ident, ctdag($target:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.ctdag_gates(vec![$target], vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
176    ($builder:ident, ctdag($target:expr, $control:expr), $($rest:tt)*) => { $builder.ctdag_gates(vec![$target], vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
177
178    // Gates with angles
179    ($builder:ident, rx([$($qubits:expr),*], $angle:expr), $($rest:tt)*) => { $builder.rx_gates(vec![$($qubits),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
180    ($builder:ident, ry([$($qubits:expr),*], $angle:expr), $($rest:tt)*) => { $builder.ry_gates(vec![$($qubits),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
181    ($builder:ident, rz([$($qubits:expr),*], $angle:expr), $($rest:tt)*) => { $builder.rz_gates(vec![$($qubits),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
182    ($builder:ident, p([$($qubits:expr),*], $angle:expr), $($rest:tt)*) => { $builder.p_gates(vec![$($qubits),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
183    ($builder:ident, ry_phase([$($qubits:expr),*], $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.ry_phase_gates(vec![$($qubits),*], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
184    ($builder:ident, ry_phase_dag([$($qubits:expr),*], $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.ry_phase_dag_gates(vec![$($qubits),*], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
185    ($builder:ident, rx($qubit:expr, $angle:expr), $($rest:tt)*) => { $builder.rx_gate($qubit, $angle); $crate::circuit_internal!($builder, $($rest)*); };
186    ($builder:ident, ry($qubit:expr, $angle:expr), $($rest:tt)*) => { $builder.ry_gate($qubit, $angle); $crate::circuit_internal!($builder, $($rest)*); };
187    ($builder:ident, rz($qubit:expr, $angle:expr), $($rest:tt)*) => { $builder.rz_gate($qubit, $angle); $crate::circuit_internal!($builder, $($rest)*); };
188    ($builder:ident, p($qubit:expr, $angle:expr), $($rest:tt)*) => { $builder.p_gate($qubit, $angle); $crate::circuit_internal!($builder, $($rest)*); };
189    ($builder:ident, ry_phase($qubit:expr, $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.ry_phase_gate($qubit, $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
190    ($builder:ident, ry_phase_dag($qubit:expr, $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.ry_phase_dag_gate($qubit, $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
191
192    // --- Controlled angle gate overloading ---
193    ($builder:ident, crx([$($targets:expr),*], [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.crx_gates(vec![$($targets),*], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
194    ($builder:ident, crx([$($targets:expr),*], $control:expr, $angle:expr), $($rest:tt)*) => { $builder.crx_gates(vec![$($targets),*], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
195    ($builder:ident, crx($target:expr, [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.crx_gates(vec![$target], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
196    ($builder:ident, crx($target:expr, $control:expr, $angle:expr), $($rest:tt)*) => { $builder.crx_gates(vec![$target], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
197    ($builder:ident, cry([$($targets:expr),*], [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.cry_gates(vec![$($targets),*], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
198    ($builder:ident, cry([$($targets:expr),*], $control:expr, $angle:expr), $($rest:tt)*) => { $builder.cry_gates(vec![$($targets),*], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
199    ($builder:ident, cry($target:expr, [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.cry_gates(vec![$target], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
200    ($builder:ident, cry($target:expr, $control:expr, $angle:expr), $($rest:tt)*) => { $builder.cry_gates(vec![$target], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
201    ($builder:ident, crz([$($targets:expr),*], [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.crz_gates(vec![$($targets),*], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
202    ($builder:ident, crz([$($targets:expr),*], $control:expr, $angle:expr), $($rest:tt)*) => { $builder.crz_gates(vec![$($targets),*], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
203    ($builder:ident, crz($target:expr, [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.crz_gates(vec![$target], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
204    ($builder:ident, crz($target:expr, $control:expr, $angle:expr), $($rest:tt)*) => { $builder.crz_gates(vec![$target], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
205    ($builder:ident, cp([$($targets:expr),*], [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.cp_gates(vec![$($targets),*], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
206    ($builder:ident, cp([$($targets:expr),*], $control:expr, $angle:expr), $($rest:tt)*) => { $builder.cp_gates(vec![$($targets),*], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
207    ($builder:ident, cp($target:expr, [$($controls:expr),*], $angle:expr), $($rest:tt)*) => { $builder.cp_gates(vec![$target], vec![$($controls),*], $angle); $crate::circuit_internal!($builder, $($rest)*); };
208    ($builder:ident, cp($target:expr, $control:expr, $angle:expr), $($rest:tt)*) => { $builder.cp_gates(vec![$target], vec![$control], $angle); $crate::circuit_internal!($builder, $($rest)*); };
209    ($builder:ident, cry_phase([$($targets:expr),*], [$($controls:expr),*], $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_gates(vec![$($targets),*], vec![$($controls),*], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
210    ($builder:ident, cry_phase([$($targets:expr),*], $control:expr, $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_gates(vec![$($targets),*], vec![$control], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
211    ($builder:ident, cry_phase($target:expr, [$($controls:expr),*], $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_gates(vec![$target], vec![$($controls),*], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
212    ($builder:ident, cry_phase($target:expr, $control:expr, $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_gates(vec![$target], vec![$control], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
213    ($builder:ident, cry_phase_dag([$($targets:expr),*], [$($controls:expr),*], $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_dag_gates(vec![$($targets),*], vec![$($controls),*], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
214    ($builder:ident, cry_phase_dag([$($targets:expr),*], $control:expr, $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_dag_gates(vec![$($targets),*], vec![$control], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
215    ($builder:ident, cry_phase_dag($target:expr, [$($controls:expr),*], $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_dag_gates(vec![$target], vec![$($controls),*], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
216    ($builder:ident, cry_phase_dag($target:expr, $control:expr, $theta:expr, $phi:expr), $($rest:tt)*) => { $builder.cry_phase_dag_gates(vec![$target], vec![$control], $theta, $phi); $crate::circuit_internal!($builder, $($rest)*); };
217
218    // --- Unitary and controlled unitary gates ---
219    ($builder:ident, unitary([$($qubits:expr),*], $matrix:expr), $($rest:tt)*) => { $builder.unitary_gates(vec![$($qubits),*], $matrix).unwrap(); $crate::circuit_internal!($builder, $($rest)*); };
220    ($builder:ident, unitary($qubit:expr, $matrix:expr), $($rest:tt)*) => { $builder.unitary_gate($qubit, $matrix).unwrap(); $crate::circuit_internal!($builder, $($rest)*); };
221    ($builder:ident, cunitary([$($targets:expr),*], [$($controls:expr),*], $matrix:expr), $($rest:tt)*) => { $builder.cunitary_gates(vec![$($targets),*], vec![$($controls),*], $matrix).unwrap(); $crate::circuit_internal!($builder, $($rest)*); };
222    ($builder:ident, cunitary([$($targets:expr),*], $control:expr, $matrix:expr), $($rest:tt)*) => { $builder.cunitary_gates(vec![$($targets),*], vec![$control], $matrix).unwrap(); $crate::circuit_internal!($builder, $($rest)*); };
223    ($builder:ident, cunitary($target:expr, [$($controls:expr),*], $matrix:expr), $($rest:tt)*) => { $builder.cunitary_gates(vec![$target], vec![$($controls),*], $matrix).unwrap(); $crate::circuit_internal!($builder, $($rest)*); };
224    ($builder:ident, cunitary($target:expr, $control:expr, $matrix:expr), $($rest:tt)*) => { $builder.cunitary_gates(vec![$target], vec![$control], $matrix).unwrap(); $crate::circuit_internal!($builder, $($rest)*); };
225
226    // --- Special gates ---
227    ($builder:ident, toffoli($target:expr, $control1:expr, $control2:expr), $($rest:tt)*) => { $builder.toffoli_gate($target, $control1, $control2); $crate::circuit_internal!($builder, $($rest)*); };
228    ($builder:ident, cswap($target1:expr, $target2:expr, [$($controls:expr),*]), $($rest:tt)*) => { $builder.cswap_gate($target1, $target2, vec![$($controls),*]); $crate::circuit_internal!($builder, $($rest)*); };
229    ($builder:ident, cswap($target1:expr, $target2:expr, $control:expr), $($rest:tt)*) => { $builder.cswap_gate($target1, $target2, vec![$control]); $crate::circuit_internal!($builder, $($rest)*); };
230    ($builder:ident, matchgate($target1:expr, $theta:expr, $phi1:expr, $phi2:expr), $($rest:tt)*) => { $builder.matchgate($target1, $theta, $phi1, $phi2); $crate::circuit_internal!($builder, $($rest)*); };
231    ($builder:ident, cmatchgate($target1:expr, [$($controls:expr),*], $theta:expr, $phi1:expr, $phi2:expr), $($rest:tt)*) => { $builder.cmatchgate($target1, vec![$($controls),*], $theta, $phi1, $phi2); $crate::circuit_internal!($builder, $($rest)*); };
232    ($builder:ident, cmatchgate($target1:expr, $control:expr, $theta:expr, $phi1:expr, $phi2:expr), $($rest:tt)*) => { $builder.cmatchgate($target1, vec![$control], $theta, $phi1, $phi2); $crate::circuit_internal!($builder, $($rest)*); };
233    ($builder:ident, pauli_string($pauli_string:expr), $($rest:tt)*) => { $builder.pauli_string_gate($pauli_string); $crate::circuit_internal!($builder, $($rest)*); };
234    ($builder:ident, pauli_time_evolution($pauli_string:expr, $time:expr), $($rest:tt)*) => { $builder.pauli_time_evolution_gate($pauli_string, $time); $crate::circuit_internal!($builder, $($rest)*); };
235
236    // --- Measurement rules ---
237    ($builder:ident, measurex([$($qubits:expr),*]), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::X, vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
238    ($builder:ident, measurex($qubit:expr), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::X, vec![$qubit]); $crate::circuit_internal!($builder, $($rest)*); };
239    ($builder:ident, measurey([$($qubits:expr),*]), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Y, vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
240    ($builder:ident, measurey($qubit:expr), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Y, vec![$qubit]); $crate::circuit_internal!($builder, $($rest)*); };
241    ($builder:ident, measurez([$($qubits:expr),*]), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Computational, vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
242    ($builder:ident, measurez($qubit:expr), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Computational, vec![$qubit]); $crate::circuit_internal!($builder, $($rest)*); };
243    ($builder:ident, measure_custom([$($qubits:expr),*], $matrix:expr), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Custom($matrix), vec![$($qubits),*]); $crate::circuit_internal!($builder, $($rest)*); };
244    ($builder:ident, measure_custom($qubit:expr, $matrix:expr), $($rest:tt)*) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Custom($matrix), vec![$qubit]); $crate::circuit_internal!($builder, $($rest)*); };
245
246    // --- Terminating Rules (no trailing comma) ---
247
248    // Multi-qubit gates
249    ($builder:ident, h([$($qubits:expr),*])) => { $builder.h_gates(vec![$($qubits),*]); };
250    ($builder:ident, x([$($qubits:expr),*])) => { $builder.x_gates(vec![$($qubits),*]); };
251    ($builder:ident, y([$($qubits:expr),*])) => { $builder.y_gates(vec![$($qubits),*]); };
252    ($builder:ident, z([$($qubits:expr),*])) => { $builder.z_gates(vec![$($qubits),*]); };
253    ($builder:ident, s([$($qubits:expr),*])) => { $builder.s_gates(vec![$($qubits),*]); };
254    ($builder:ident, t([$($qubits:expr),*])) => { $builder.t_gates(vec![$($qubits),*]); };
255    ($builder:ident, id([$($qubits:expr),*])) => { $builder.id_gates(vec![$($qubits),*]); };
256    ($builder:ident, sdag([$($qubits:expr),*])) => { $builder.sdag_gates(vec![$($qubits),*]); };
257    ($builder:ident, tdag([$($qubits:expr),*])) => { $builder.tdag_gates(vec![$($qubits),*]); };
258
259    // Single-qubit gates
260    ($builder:ident, h($qubit:expr)) => { $builder.h_gate($qubit); };
261    ($builder:ident, x($qubit:expr)) => { $builder.x_gate($qubit); };
262    ($builder:ident, y($qubit:expr)) => { $builder.y_gate($qubit); };
263    ($builder:ident, z($qubit:expr)) => { $builder.z_gate($qubit); };
264    ($builder:ident, s($qubit:expr)) => { $builder.s_gate($qubit); };
265    ($builder:ident, t($qubit:expr)) => { $builder.t_gate($qubit); };
266    ($builder:ident, id($qubit:expr)) => { $builder.id_gate($qubit); };
267    ($builder:ident, sdag($qubit:expr)) => { $builder.sdag_gate($qubit); };
268    ($builder:ident, tdag($qubit:expr)) => { $builder.tdag_gate($qubit); };
269
270    // Two-argument gates
271    ($builder:ident, cnot($arg1:expr, $arg2:expr)) => { $builder.cnot_gate($arg1, $arg2); };
272    ($builder:ident, swap($arg1:expr, $arg2:expr)) => { $builder.swap_gate($arg1, $arg2); };
273
274    // Controlled gates
275    ($builder:ident, ch([$($targets:expr),*], [$($controls:expr),*])) => { $builder.ch_gates(vec![$($targets),*], vec![$($controls),*]); };
276    ($builder:ident, ch([$($targets:expr),*], $control:expr)) => { $builder.ch_gates(vec![$($targets),*], vec![$control]); };
277    ($builder:ident, ch($target:expr, [$($controls:expr),*])) => { $builder.ch_gates(vec![$target], vec![$($controls),*]); };
278    ($builder:ident, ch($target:expr, $control:expr)) => { $builder.ch_gates(vec![$target], vec![$control]); };
279    ($builder:ident, cx([$($targets:expr),*], [$($controls:expr),*])) => { $builder.cx_gates(vec![$($targets),*], vec![$($controls),*]); };
280    ($builder:ident, cx([$($targets:expr),*], $control:expr)) => { $builder.cx_gates(vec![$($targets),*], vec![$control]); };
281    ($builder:ident, cx($target:expr, [$($controls:expr),*])) => { $builder.cx_gates(vec![$target], vec![$($controls),*]); };
282    ($builder:ident, cx($target:expr, $control:expr)) => { $builder.cx_gates(vec![$target], vec![$control]); };
283    ($builder:ident, cy([$($targets:expr),*], [$($controls:expr),*])) => { $builder.cy_gates(vec![$($targets),*], vec![$($controls),*]); };
284    ($builder:ident, cy([$($targets:expr),*], $control:expr)) => { $builder.cy_gates(vec![$($targets),*], vec![$control]); };
285    ($builder:ident, cy($target:expr, [$($controls:expr),*])) => { $builder.cy_gates(vec![$target], vec![$($controls),*]); };
286    ($builder:ident, cy($target:expr, $control:expr)) => { $builder.cy_gates(vec![$target], vec![$control]); };
287    ($builder:ident, cz([$($targets:expr),*], [$($controls:expr),*])) => { $builder.cz_gates(vec![$($targets),*], vec![$($controls),*]); };
288    ($builder:ident, cz([$($targets:expr),*], $control:expr)) => { $builder.cz_gates(vec![$($targets),*], vec![$control]); };
289    ($builder:ident, cz($target:expr, [$($controls:expr),*])) => { $builder.cz_gates(vec![$target], vec![$($controls),*]); };
290    ($builder:ident, cz($target:expr, $control:expr)) => { $builder.cz_gates(vec![$target], vec![$control]); };
291    ($builder:ident, cs([$($targets:expr),*], [$($controls:expr),*])) => { $builder.cs_gates(vec![$($targets),*], vec![$($controls),*]); };
292    ($builder:ident, cs([$($targets:expr),*], $control:expr)) => { $builder.cs_gates(vec![$($targets),*], vec![$control]); };
293    ($builder:ident, cs($target:expr, [$($controls:expr),*])) => { $builder.cs_gates(vec![$target], vec![$($controls),*]); };
294    ($builder:ident, cs($target:expr, $control:expr)) => { $builder.cs_gates(vec![$target], vec![$control]); };
295    ($builder:ident, csdag([$($targets:expr),*], [$($controls:expr),*])) => { $builder.csdag_gates(vec![$($targets),*], vec![$($controls),*]); };
296    ($builder:ident, csdag([$($targets:expr),*], $control:expr)) => { $builder.csdag_gates(vec![$($targets),*], vec![$control]); };
297    ($builder:ident, csdag($target:expr, [$($controls:expr),*])) => { $builder.csdag_gates(vec![$target], vec![$($controls),*]); };
298    ($builder:ident, csdag($target:expr, $control:expr)) => { $builder.csdag_gates(vec![$target], vec![$control]); };
299    ($builder:ident, ct([$($targets:expr),*], [$($controls:expr),*])) => { $builder.ct_gates(vec![$($targets),*], vec![$($controls),*]); };
300    ($builder:ident, ct([$($targets:expr),*], $control:expr)) => { $builder.ct_gates(vec![$($targets),*], vec![$control]); };
301    ($builder:ident, ct($target:expr, [$($controls:expr),*])) => { $builder.ct_gates(vec![$target], vec![$($controls),*]); };
302    ($builder:ident, ct($target:expr, $control:expr)) => { $builder.ct_gates(vec![$target], vec![$control]); };
303    ($builder:ident, ctdag([$($targets:expr),*], [$($controls:expr),*])) => { $builder.ctdag_gates(vec![$($targets),*], vec![$($controls),*]); };
304    ($builder:ident, ctdag([$($targets:expr),*], $control:expr)) => { $builder.ctdag_gates(vec![$($targets),*], vec![$control]); };
305    ($builder:ident, ctdag($target:expr, [$($controls:expr),*])) => { $builder.ctdag_gates(vec![$target], vec![$($controls),*]); };
306    ($builder:ident, ctdag($target:expr, $control:expr)) => { $builder.ctdag_gates(vec![$target], vec![$control]); };
307
308    // Gates with angles
309    ($builder:ident, rx([$($qubits:expr),*], $angle:expr)) => { $builder.rx_gates(vec![$($qubits),*], $angle); };
310    ($builder:ident, ry([$($qubits:expr),*], $angle:expr)) => { $builder.ry_gates(vec![$($qubits),*], $angle); };
311    ($builder:ident, rz([$($qubits:expr),*], $angle:expr)) => { $builder.rz_gates(vec![$($qubits),*], $angle); };
312    ($builder:ident, p([$($qubits:expr),*], $angle:expr)) => { $builder.p_gates(vec![$($qubits),*], $angle); };
313    ($builder:ident, ry_phase([$($qubits:expr),*], $theta:expr, $phi:expr)) => { $builder.ry_phase_gates(vec![$($qubits),*], $theta, $phi); };
314    ($builder:ident, ry_phase_dag([$($qubits:expr),*], $theta:expr, $phi:expr)) => { $builder.ry_phase_dag_gates(vec![$($qubits),*], $theta, $phi); };
315    ($builder:ident, rx($qubit:expr, $angle:expr)) => { $builder.rx_gate($qubit, $angle); };
316    ($builder:ident, ry($qubit:expr, $angle:expr)) => { $builder.ry_gate($qubit, $angle); };
317    ($builder:ident, rz($qubit:expr, $angle:expr)) => { $builder.rz_gate($qubit, $angle); };
318    ($builder:ident, p($qubit:expr, $angle:expr)) => { $builder.p_gate($qubit, $angle); };
319    ($builder:ident, ry_phase($qubit:expr, $theta:expr, $phi:expr)) => { $builder.ry_phase_gate($qubit, $theta, $phi); };
320    ($builder:ident, ry_phase_dag($qubit:expr, $theta:expr, $phi:expr)) => { $builder.ry_phase_dag_gate($qubit, $theta, $phi); };
321
322    // Controlled angle gates
323    ($builder:ident, crx([$($targets:expr),*], [$($controls:expr),*], $angle:expr)) => { $builder.crx_gates(vec![$($targets),*], vec![$($controls),*], $angle); };
324    ($builder:ident, crx([$($targets:expr),*], $control:expr, $angle:expr)) => { $builder.crx_gates(vec![$($targets),*], vec![$control], $angle); };
325    ($builder:ident, crx($target:expr, [$($controls:expr),*], $angle:expr)) => { $builder.crx_gates(vec![$target], vec![$($controls),*], $angle); };
326    ($builder:ident, crx($target:expr, $control:expr, $angle:expr)) => { $builder.crx_gates(vec![$target], vec![$control], $angle); };
327    ($builder:ident, cry([$($targets:expr),*], [$($controls:expr),*], $angle:expr)) => { $builder.cry_gates(vec![$($targets),*], vec![$($controls),*], $angle); };
328    ($builder:ident, cry([$($targets:expr),*], $control:expr, $angle:expr)) => { $builder.cry_gates(vec![$($targets),*], vec![$control], $angle); };
329    ($builder:ident, cry($target:expr, [$($controls:expr),*], $angle:expr)) => { $builder.cry_gates(vec![$target], vec![$($controls),*], $angle); };
330    ($builder:ident, cry($target:expr, $control:expr, $angle:expr)) => { $builder.cry_gates(vec![$target], vec![$control], $angle); };
331    ($builder:ident, crz([$($targets:expr),*], [$($controls:expr),*], $angle:expr)) => { $builder.crz_gates(vec![$($targets),*], vec![$($controls),*], $angle); };
332    ($builder:ident, crz([$($targets:expr),*], $control:expr, $angle:expr)) => { $builder.crz_gates(vec![$($targets),*], vec![$control], $angle); };
333    ($builder:ident, crz($target:expr, [$($controls:expr),*], $angle:expr)) => { $builder.crz_gates(vec![$target], vec![$($controls),*], $angle); };
334    ($builder:ident, crz($target:expr, $control:expr, $angle:expr)) => { $builder.crz_gates(vec![$target], vec![$control], $angle); };
335    ($builder:ident, cp([$($targets:expr),*], [$($controls:expr),*], $angle:expr)) => { $builder.cp_gates(vec![$($targets),*], vec![$($controls),*], $angle); };
336    ($builder:ident, cp([$($targets:expr),*], $control:expr, $angle:expr)) => { $builder.cp_gates(vec![$($targets),*], vec![$control], $angle); };
337    ($builder:ident, cp($target:expr, [$($controls:expr),*], $angle:expr)) => { $builder.cp_gates(vec![$target], vec![$($controls),*], $angle); };
338    ($builder:ident, cp($target:expr, $control:expr, $angle:expr)) => { $builder.cp_gates(vec![$target], vec![$control], $angle); };
339    ($builder:ident, cry_phase([$($targets:expr),*], [$($controls:expr),*], $theta:expr, $phi:expr)) => { $builder.cry_phase_gates(vec![$($targets),*], vec![$($controls),*], $theta, $phi); };
340    ($builder:ident, cry_phase([$($targets:expr),*], $control:expr, $theta:expr, $phi:expr)) => { $builder.cry_phase_gates(vec![$($targets),*], vec![$control], $theta, $phi); };
341    ($builder:ident, cry_phase($target:expr, [$($controls:expr),*], $theta:expr, $phi:expr)) => { $builder.cry_phase_gates(vec![$target], vec![$($controls),*], $theta, $phi); };
342    ($builder:ident, cry_phase($target:expr, $control:expr, $theta:expr, $phi:expr)) => { $builder.cry_phase_gates(vec![$target], vec![$control], $theta, $phi); };
343    ($builder:ident, cry_phase_dag([$($targets:expr),*], [$($controls:expr),*], $theta:expr, $phi:expr)) => { $builder.cry_phase_dag_gates(vec![$($targets),*], vec![$($controls),*], $theta, $phi); };
344    ($builder:ident, cry_phase_dag([$($targets:expr),*], $control:expr, $theta:expr, $phi:expr)) => { $builder.cry_phase_dag_gates(vec![$($targets),*], vec![$control], $theta, $phi); };
345    ($builder:ident, cry_phase_dag($target:expr, [$($controls:expr),*], $theta:expr, $phi:expr)) => { $builder.cry_phase_dag_gates(vec![$target], vec![$($controls),*], $theta, $phi); };
346    ($builder:ident, cry_phase_dag($target:expr, $control:expr, $theta:expr, $phi:expr)) => { $builder.cry_phase_dag_gates(vec![$target], vec![$control], $theta, $phi); };
347
348    // Unitary and Controlled Unitary Gates
349    ($builder:ident, unitary([$($qubits:expr),*], $matrix:expr)) => { $builder.unitary_gates(vec![$($qubits),*], $matrix).unwrap(); };
350    ($builder:ident, unitary($qubit:expr, $matrix:expr)) => { $builder.unitary_gate($qubit, $matrix).unwrap(); };
351    ($builder:ident, cunitary([$($targets:expr),*], [$($controls:expr),*], $matrix:expr)) => { $builder.cunitary_gates(vec![$($targets),*], vec![$($controls),*], $matrix).unwrap(); };
352    ($builder:ident, cunitary([$($targets:expr),*], $control:expr, $matrix:expr)) => { $builder.cunitary_gates(vec![$($targets),*], vec![$control], $matrix).unwrap(); };
353    ($builder:ident, cunitary($target:expr, [$($controls:expr),*], $matrix:expr)) => { $builder.cunitary_gates(vec![$target], vec![$($controls),*], $matrix).unwrap(); };
354    ($builder:ident, cunitary($target:expr, $control:expr, $matrix:expr)) => { $builder.cunitary_gates(vec![$target], vec![$control], $matrix).unwrap(); };
355
356    // Special Gates
357    ($builder:ident, toffoli($target:expr, $control1:expr, $control2:expr)) => { $builder.toffoli_gate($target, $control1, $control2); };
358    ($builder:ident, cswap($target1:expr, $target2:expr, [$($controls:expr),*])) => { $builder.cswap_gate($target1, $target2, vec![$($controls),*]); };
359    ($builder:ident, cswap($target1:expr, $target2:expr, $control:expr)) => { $builder.cswap_gate($target1, $target2, vec![$control]); };
360    ($builder:ident, matchgate($target1:expr, $theta:expr, $phi1:expr, $phi2:expr)) => { $builder.matchgate($target1, $theta, $phi1, $phi2); };
361    ($builder:ident, cmatchgate($target1:expr, [$($controls:expr),*], $theta:expr, $phi1:expr, $phi2:expr)) => { $builder.cmatchgate($target1, vec![$($controls),*], $theta, $phi1, $phi2); };
362    ($builder:ident, cmatchgate($target1:expr, $control:expr, $theta:expr, $phi1:expr, $phi2:expr)) => { $builder.cmatchgate($target1, vec![$control], $theta, $phi1, $phi2); };
363    ($builder:ident, pauli_string($pauli_string:expr)) => { $builder.pauli_string_gate($pauli_string); };
364    ($builder:ident, pauli_time_evolution($pauli_string:expr, $time:expr)) => { $builder.pauli_time_evolution_gate($pauli_string, $time); };
365
366    // Measurement gates
367    ($builder:ident, measurex([$($qubits:expr),*])) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::X, vec![$($qubits),*]); };
368    ($builder:ident, measurex($qubit:expr)) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::X, vec![$qubit]); };
369    ($builder:ident, measurey([$($qubits:expr),*])) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Y, vec![$($qubits),*]); };
370    ($builder:ident, measurey($qubit:expr)) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Y, vec![$qubit]); };
371    ($builder:ident, measurez([$($qubits:expr),*])) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Computational, vec![$($qubits),*]); };
372    ($builder:ident, measurez($qubit:expr)) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Computational, vec![$qubit]); };
373    ($builder:ident, measure_custom([$($qubits:expr),*], $matrix:expr)) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Custom($matrix), vec![$($qubits),*]); };
374    ($builder:ident, measure_custom($qubit:expr, $matrix:expr)) => { $builder.measure_gate($crate::components::measurement::MeasurementBasis::Custom($matrix), vec![$qubit]); };
375
376    // --- Error Handling ---
377    // This is a compile-time error, as it indicates a failure to match any known gate pattern.
378    ($builder:ident, $bad_token:tt, $($rest:tt)*) => {
379        compile_error!(concat!("Unrecognised gate or syntax: `", stringify!($bad_token), "`"));
380    };
381}