qasm_example/
qasm_example.rs

1//! Example demonstrating OpenQASM 3.0 import/export functionality
2
3use 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    // Example 1: Export a circuit to QASM
11    export_example();
12
13    // Example 2: Parse QASM code
14    parse_example();
15
16    // Example 3: Validate QASM programs
17    validation_example();
18
19    // Example 4: Round-trip conversion
20    round_trip_example();
21}
22
23fn export_example() {
24    println!("1. Exporting a circuit to OpenQASM 3.0");
25    println!("--------------------------------------");
26
27    // Create a quantum teleportation circuit
28    let mut builder = CircuitBuilder::<3>::new();
29
30    // Create Bell pair between Alice and Bob
31    let _ = builder.h(Qubit::new(1));
32    let _ = builder.cx(Qubit::new(1), Qubit::new(2));
33
34    // Alice's operations
35    let _ = builder.cx(Qubit::new(0), Qubit::new(1));
36    let _ = builder.h(Qubit::new(0));
37
38    // Measurements (in real teleportation, these would be mid-circuit)
39    let _ = builder.measure(Qubit::new(0));
40    let _ = builder.measure(Qubit::new(1));
41
42    // Bob's corrections (would be conditional in real circuit)
43    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    // Export with default options
49    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    // Export with custom options
58    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            // Pretty print the parsed program
116            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    // Valid program
128    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    // Program with errors
156    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    // Create a variational circuit
187    let mut builder = CircuitBuilder::<4>::new();
188
189    // Layer 1: Single-qubit rotations
190    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    // Layer 2: Entangling gates
196    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)); // Circular connectivity
200
201    // Layer 3: More rotations
202    for i in 0..4 {
203        let _ = builder.rx(Qubit::new(i), -0.2);
204    }
205
206    // Measurements
207    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    // Export to QASM
219    match export_qasm3(&original) {
220        Ok(qasm) => {
221            println!("\nExported QASM:");
222            println!("{}", qasm);
223
224            // Parse it back
225            match parse_qasm3(&qasm) {
226                Ok(program) => {
227                    println!("\n✓ Successfully parsed the exported QASM!");
228
229                    // Validate it
230                    match validate_qasm3(&program) {
231                        Ok(()) => println!("✓ Validation passed!"),
232                        Err(e) => println!("✗ Validation error: {}", e),
233                    }
234
235                    // Count operations
236                    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
262// Additional example showing advanced QASM 3.0 features
263fn 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            // Analyze the program
312            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            // Validate
347            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}