quant-iron 2.0.0

A high-performance, hardware-accelerated modular quantum computing library with a focus on physical applications. Quant-Iron provides tools to represent quantum states, apply standard quantum gates, perform measurements, build quantum circuits, and implement quantum algorithms.
Documentation
/// Enum representing the type of QASM instruction.
/// 
/// Used for hoisting variable declarations to the top of the QASM string.
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum QasmInstruction {
    /// Represents a bit register declaration used for representing measurement results.
    /// Needs to be hoisted to the top of the QASM string.
    BitRegisterDeclaration(usize),

    /// Represents a gate declaration in QASM.
    GateDeclaration(String),

    /// Represents a new measurement instruction
    MeasurementDeclaration(String),

    /// Represents raw QASM code that should be included as-is.
    RawQASM(String),

    /// Represents the start of a new measurement group.
    StartMeasurementGroup,
}

/// Represents a circuit in QASM format as a collection of instructions.
pub(crate) struct QasmCircuit {
    /// The QASM instructions in the circuit.
    pub(crate) instructions: Vec<QasmInstruction>,
    
    /// The number of qubits in the circuit.
    pub(crate) num_qubits: usize,
}

impl QasmCircuit {
    /// Creates a new `QasmCircuit` from a vector of `QasmInstruction`s and the number of qubits.
    pub(crate) fn new(instructions: Vec<QasmInstruction>, num_qubits: usize) -> Self {
        QasmCircuit {
            instructions,
            num_qubits,
        }
    }

    /// Converts the circuit to a QASM string representation.
    pub(crate) fn to_qasm_string(&self) -> String {
        let mut header = String::new();
        let mut body = String::new();

        // Opening line
        header.push_str("OPENQASM 3.0;\n");
        // Include standard library
        header.push_str("include \"stdgates.inc\";\n");

        // Include function definitions for basis measurements
        header.push_str("def xmeasure(qubit q) -> bit { h q; return measure q; } // Defines x-basis measurement\n");
        header.push_str("def ymeasure(qubit q) -> bit { h q; s q; return measure q; } // Defines y-basis measurement\n");

        // Comment indicating source of QASM code
        header.push_str("// Generated by QuantIron's QASM Compiler\n\n");

        // Declare qubit register
        header.push_str(&format!("qubit[{}] q; // Main register\n\n", self.num_qubits));

        let mut measurement_register_idx = -1;
        let mut measurement_bit_idx = 0;
        let mut measurement_idx = 0;

        // Add instructions to the QASM string
        for instruction in self.instructions.iter() {
            match instruction {
                QasmInstruction::BitRegisterDeclaration(len) => {
                    header.push_str(&format!("bit[{}] m{}; // Measurement result for measurement {}\n", len, measurement_idx, measurement_idx));
                    measurement_idx += 1;
                }
                QasmInstruction::GateDeclaration(gate) => {
                    if !body.is_empty() && !body.ends_with('\n') {
                        body.push('\n');
                    }
                    body.push_str(gate.trim());
                    body.push('\n');
                }
                QasmInstruction::MeasurementDeclaration(measurement_str) => {
                    body.push_str(&format!(
                        "m{}[{}] = {};\n",
                        measurement_register_idx, measurement_bit_idx, measurement_str
                    ));
                    measurement_bit_idx += 1;
                }
                QasmInstruction::RawQASM(raw) => {
                    body.push_str(&format!("\n{}", raw.trim()));
                }
                QasmInstruction::StartMeasurementGroup => {
                    measurement_register_idx += 1;
                    measurement_bit_idx = 0;
                    if !body.is_empty() && !body.ends_with("\n\n") {
                         body.push('\n');
                    }
                    body.push_str(&format!("// Measurement {}\n", measurement_register_idx));
                }
            }
        }

        // Return the final QASM string
        let mut final_header = header.trim_end().to_string();
        if !body.is_empty() {
            final_header.push_str("\n\n");
        }
        format!("{}{}", final_header, body.trim_start()).trim().to_string()
    }
}

// TO CONVERT IR TO QASM INSTRUCTIONS
// 1. Convert each `InstructionIR` to `QasmInstruction` and collect all `QasmInstruction`s into a `Vec<QasmInstruction>`.
// 2. Use following format to generate QASM file:
// 
// Opening line: `OPENQASM 3.0;`
// Include standard library: `include "stdgates.inc";`
// Include function defs for basis measurements: 
// def xmeasure(qubit q) -> bit { h q; return measure q; }
// def ymeasure(qubit q) -> bit { h q; s q; return measure q; }
//
// Comment: `// Generated by QuantIron's QASM Compiler`
// Declare qubit register given number of qubits. Call it `q`.
// Declare bit register for each measurement result with comment `// Measurement result for measurement {index}`
// Declare and apply gates for each Instruction with comment, eg. `// Hadamard gate on qubit {index} with controls {controls}`
// Store result of each measurement in the corresponding bit registers