qasm_example/
qasm_example.rs1use quantrs2_circuit::builder::CircuitBuilder;
4use quantrs2_circuit::prelude::*;
5use quantrs2_core::qubit::QubitId;
6
7fn main() {
8 println!("=== OpenQASM 3.0 Import/Export Example ===\n");
9
10 export_example();
12
13 parse_example();
15
16 validation_example();
18
19 round_trip_example();
21}
22
23fn export_example() {
24 println!("1. Exporting a circuit to OpenQASM 3.0");
25 println!("--------------------------------------");
26
27 let mut builder = CircuitBuilder::<3>::new();
29
30 let _ = builder.h(Qubit::new(1));
32 let _ = builder.cx(Qubit::new(1), Qubit::new(2));
33
34 let _ = builder.cx(Qubit::new(0), Qubit::new(1));
36 let _ = builder.h(Qubit::new(0));
37
38 let _ = builder.measure(Qubit::new(0));
40 let _ = builder.measure(Qubit::new(1));
41
42 let _ = builder.cx(Qubit::new(1), Qubit::new(2));
44 let _ = builder.cz(Qubit::new(0), Qubit::new(2));
45
46 let circuit = builder.build();
47
48 match export_qasm3(&circuit) {
50 Ok(qasm) => {
51 println!("Teleportation circuit in OpenQASM 3.0:");
52 println!("{}", qasm);
53 }
54 Err(e) => println!("Export error: {}", e),
55 }
56
57 let options = ExportOptions {
59 include_stdgates: true,
60 decompose_custom: true,
61 include_gate_comments: true,
62 optimize: true,
63 pretty_print: true,
64 };
65
66 let mut exporter = QasmExporter::new(options);
67 match exporter.export(&circuit) {
68 Ok(qasm) => {
69 println!("\nWith custom options:");
70 println!("{}", qasm);
71 }
72 Err(e) => println!("Export error: {}", e),
73 }
74}
75
76fn parse_example() {
77 println!("\n2. Parsing OpenQASM 3.0 code");
78 println!("----------------------------");
79
80 let qasm_code = r#"
81OPENQASM 3.0;
82include "stdgates.inc";
83
84// Quantum registers
85qubit[5] q;
86bit[5] c;
87
88// Create W state
89reset q;
90ry(1.91063) q[0]; // arccos(1/sqrt(5))
91cx q[0], q[1];
92
93// Controlled rotations to distribute amplitude
94cry(1.10715) q[1], q[2]; // arccos(1/2)
95cx q[1], q[2];
96
97cry(0.95532) q[2], q[3]; // arccos(1/sqrt(3))
98cx q[2], q[3];
99
100cry(pi/4) q[3], q[4];
101cx q[3], q[4];
102
103// Measure all qubits
104measure q -> c;
105"#;
106
107 match parse_qasm3(qasm_code) {
108 Ok(program) => {
109 println!("Successfully parsed QASM program!");
110 println!("Version: {}", program.version);
111 println!("Includes: {:?}", program.includes);
112 println!("Declarations: {} items", program.declarations.len());
113 println!("Statements: {} operations", program.statements.len());
114
115 println!("\nReconstructed QASM:");
117 println!("{}", program);
118 }
119 Err(e) => println!("Parse error: {}", e),
120 }
121}
122
123fn validation_example() {
124 println!("\n3. Validating QASM programs");
125 println!("---------------------------");
126
127 let valid_qasm = r#"
129OPENQASM 3.0;
130
131gate mybell a, b {
132 h a;
133 cx a, b;
134}
135
136qubit[4] q;
137bit[2] c;
138
139mybell q[0], q[1];
140mybell q[2], q[3];
141
142measure q[0] -> c[0];
143measure q[2] -> c[1];
144"#;
145
146 println!("Validating correct program...");
147 match parse_qasm3(valid_qasm) {
148 Ok(program) => match validate_qasm3(&program) {
149 Ok(()) => println!("✓ Program is valid!"),
150 Err(e) => println!("✗ Validation error: {}", e),
151 },
152 Err(e) => println!("Parse error: {}", e),
153 }
154
155 let invalid_qasm = r#"
157OPENQASM 3.0;
158
159qubit[2] q;
160bit[2] c;
161
162// Error: using undefined register
163h r[0];
164
165// Error: index out of bounds
166cx q[0], q[5];
167
168// Error: wrong number of parameters
169rx q[0]; // Missing angle parameter
170"#;
171
172 println!("\nValidating program with errors...");
173 match parse_qasm3(invalid_qasm) {
174 Ok(program) => match validate_qasm3(&program) {
175 Ok(()) => println!("Program is valid (unexpected!)"),
176 Err(e) => println!("✓ Caught validation error: {}", e),
177 },
178 Err(e) => println!("Parse error: {}", e),
179 }
180}
181
182fn round_trip_example() {
183 println!("\n4. Round-trip conversion");
184 println!("------------------------");
185
186 let mut builder = CircuitBuilder::<4>::new();
188
189 for i in 0..4 {
191 let _ = builder.ry(Qubit::new(i), 0.5);
192 let _ = builder.rz(Qubit::new(i), 0.3);
193 }
194
195 for i in 0..3 {
197 let _ = builder.cx(Qubit::new(i), Qubit::new(i + 1));
198 }
199 let _ = builder.cx(Qubit::new(3), Qubit::new(0)); for i in 0..4 {
203 let _ = builder.rx(Qubit::new(i), -0.2);
204 }
205
206 for i in 0..4 {
208 let _ = builder.measure(Qubit::new(i));
209 }
210
211 let original = builder.build();
212
213 println!(
214 "Original circuit created with {} gates",
215 original.gates().len()
216 );
217
218 match export_qasm3(&original) {
220 Ok(qasm) => {
221 println!("\nExported QASM:");
222 println!("{}", qasm);
223
224 match parse_qasm3(&qasm) {
226 Ok(program) => {
227 println!("\n✓ Successfully parsed the exported QASM!");
228
229 match validate_qasm3(&program) {
231 Ok(()) => println!("✓ Validation passed!"),
232 Err(e) => println!("✗ Validation error: {}", e),
233 }
234
235 let gate_count = program
237 .statements
238 .iter()
239 .filter(|s| {
240 matches!(s, quantrs2_circuit::qasm::ast::QasmStatement::Gate(_))
241 })
242 .count();
243 let measure_count = program
244 .statements
245 .iter()
246 .filter(|s| {
247 matches!(s, quantrs2_circuit::qasm::ast::QasmStatement::Measure(_))
248 })
249 .count();
250
251 println!("\nParsed circuit has:");
252 println!(" - {} gate operations", gate_count);
253 println!(" - {} measurements", measure_count);
254 }
255 Err(e) => println!("Parse error: {}", e),
256 }
257 }
258 Err(e) => println!("Export error: {}", e),
259 }
260}
261
262fn advanced_features_example() {
264 println!("\n5. Advanced QASM 3.0 Features");
265 println!("-----------------------------");
266
267 let advanced_qasm = r#"
268OPENQASM 3.0;
269include "stdgates.inc";
270
271// Constants and expressions
272const n_layers = 3;
273const rotation_angle = pi / 4;
274
275// Quantum and classical registers
276qubit[4] q;
277bit[4] c;
278bit[1] syndrome;
279
280// Gate with modifiers
281ctrl(2) x q[0], q[1], q[2]; // Toffoli gate
282inv s q[3]; // Inverse S gate
283
284// Parameterized gate with expression
285rx(2 * rotation_angle) q[0];
286
287// For loop
288for layer in [0:n_layers] {
289 for i in [0:3] {
290 ry(rotation_angle * (layer + 1)) q[i];
291 }
292 barrier q;
293}
294
295// Conditional operation
296measure q[0] -> c[0];
297if (c[0] == 1) {
298 x q[1];
299 measure q[1] -> syndrome[0];
300}
301
302// Reset and final measurements
303reset q[0];
304measure q -> c;
305"#;
306
307 match parse_qasm3(advanced_qasm) {
308 Ok(program) => {
309 println!("Successfully parsed advanced QASM features!");
310
311 let mut constants = 0;
313 let mut gates_with_modifiers = 0;
314 let mut control_flow = 0;
315
316 for decl in &program.declarations {
317 if matches!(
318 decl,
319 quantrs2_circuit::qasm::ast::Declaration::Constant(_, _)
320 ) {
321 constants += 1;
322 }
323 }
324
325 for stmt in &program.statements {
326 match stmt {
327 quantrs2_circuit::qasm::ast::QasmStatement::Gate(gate) => {
328 if gate.control.is_some() || gate.inverse || gate.power.is_some() {
329 gates_with_modifiers += 1;
330 }
331 }
332 quantrs2_circuit::qasm::ast::QasmStatement::If(_, _)
333 | quantrs2_circuit::qasm::ast::QasmStatement::For(_)
334 | quantrs2_circuit::qasm::ast::QasmStatement::While(_, _) => {
335 control_flow += 1;
336 }
337 _ => {}
338 }
339 }
340
341 println!("\nProgram analysis:");
342 println!(" - {} constants defined", constants);
343 println!(" - {} gates with modifiers", gates_with_modifiers);
344 println!(" - {} control flow statements", control_flow);
345
346 match validate_qasm3(&program) {
348 Ok(()) => println!("\n✓ All advanced features validated successfully!"),
349 Err(e) => println!("\n✗ Validation error: {}", e),
350 }
351 }
352 Err(e) => println!("Parse error: {}", e),
353 }
354}