Source code for mimiqcircuits.decomposition.rules.canonical

#
# Copyright © 2022-2024 University of Strasbourg. All Rights Reserved.
# Copyright © 2023-2025 QPerfect. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Canonical rewrite rule for decomposing operations to GateU and GateCX."""

from __future__ import annotations

from typing import TYPE_CHECKING, Sequence

from mimiqcircuits.decomposition.abstract import RewriteRule

if TYPE_CHECKING:
    from mimiqcircuits import Circuit, Operation


[docs] class CanonicalRewrite(RewriteRule): """Rewrite rule that decomposes operations using their built-in decomposition. This rule delegates to each operation's ``_decompose`` method, which typically reduces gates to a minimal set of primitives (GateU, GateCX, etc.). The canonical decomposition is the default decomposition defined by each gate class. Most gates decompose down to GateU (arbitrary single-qubit) and GateCX (two-qubit entangling gate). Example: >>> from mimiqcircuits import GateH >>> from mimiqcircuits.decomposition import CanonicalRewrite >>> rule = CanonicalRewrite() >>> rule.matches(GateH()) True >>> circ = rule.decompose_step(GateH(), [0], [], []) >>> print(circ) 1-qubit circuit with 1 instruction: └── U((1/2)*pi, 0, pi, 0.0) @ q[0] """
[docs] def matches(self, op: Operation) -> bool: """Check if this rule can decompose the operation. Matches every operation that has a canonical decomposition, that is whose ``supports_canonical_rewrite()`` is true. The answer does not depend on any basis: an operation that :class:`CanonicalBasis` keeps terminal (such as ``ResetX``) still matches, so other bases can expand it. Primitives without a decomposition (``GateU``, ``GateCX``, ``Measure``, ``Reset``, ``Barrier``, ...) do not match. Args: op: The operation to check. Returns: True if the operation should be rewritten by canonical decomposition. """ return op.supports_canonical_rewrite()
[docs] def decompose_step( self, op: Operation, qubits: Sequence[int], bits: Sequence[int], zvars: Sequence[int], ) -> Circuit: """Decompose the operation using its built-in decomposition. Args: op: The operation to decompose. qubits: Qubit indices for the operation. bits: Classical bit indices for the operation. zvars: Z-variable indices for the operation. Returns: A Circuit containing the decomposed instructions. """ import mimiqcircuits as mc circ = mc.Circuit() op._decompose(circ, list(qubits), list(bits), list(zvars)) return circ
__all__ = ["CanonicalRewrite"]