Source code for qbraid.passes.qasm3.format

# Copyright (C) 2024 qBraid
#
# This file is part of the qBraid-SDK
#
# The qBraid-SDK is free software released under the GNU General Public License v3
# or later. You can redistribute and/or modify it under the terms of the GPL v3.
# See the LICENSE file in the project root or <https://www.gnu.org/licenses/gpl-3.0.html>.
#
# THERE IS NO WARRANTY for the qBraid-SDK, as per Section 15 of the GPL v3.

"""
Module for providing transforamtions to ensure consistency
in the way OpenQASM 3 strings are formatted.

"""

import re


def _remove_empty_lines(input_string: str) -> str:
    """Removes all empty lines from the provided string."""
    return "\n".join(line for line in input_string.split("\n") if line.strip())


def _remove_double_empty_lines(qasm: str) -> str:
    """Replace double empty lines with single lines from a QASM string."""
    return re.sub(r"\n\n\n", "\n\n", qasm)


def _remove_gate_definition(qasm: str, gate_name: str) -> str:
    """Remove a gate definition from a QASM string."""
    lines = iter(qasm.split("\n"))
    new_qasm = ""

    for line in lines:
        if re.search(r"gate\s+(\w+)", line) is not None:
            # extract the gate name
            current_gate_name = re.search(r"gate\s+(\w+)", line).group(1)
            # remove lines from start curly brace to end curly brace
            if current_gate_name == gate_name:
                while "}" not in line:
                    line = next(lines)
            else:
                new_qasm += line + "\n"
        else:
            new_qasm += line + "\n"

    new_qasm = _remove_double_empty_lines(new_qasm)

    return new_qasm.strip()


[docs] def remove_unused_gates(qasm: str) -> str: """Remove unused gate definitions from a QASM string.""" lines = iter(qasm.split("\n")) all_gates = {} for line in lines: if re.search(r"^\s*gate\s+(\w+)", line) is not None: gate_name = re.search(r"^\s*gate\s+(\w+)", line).group(1) all_gates[gate_name] = -1 for gate in all_gates: if re.search(r"\b" + re.escape(gate) + r"\b", line): all_gates[gate] += 1 new_qasm = qasm unused_gates = [gate for gate, count in all_gates.items() if count == 0] for gate in unused_gates: new_qasm = _remove_gate_definition(new_qasm, gate) if len(unused_gates) > 0: return remove_unused_gates(new_qasm) return new_qasm.strip()