Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

qamomile.circuit.ir

Public surface for the Qamomile IR package.

Re-exports the contributor-facing debugging and canonical-form helpers so callers can use the short form from qamomile.circuit.ir import pretty_print_block or from qamomile.circuit.ir import canonicalize.

Overview

FunctionDescription
canonicalizeReturn a canonical-form clone of block.
canonicalize_and_remapReturn canonical-form Block plus the UUID and logical_id remap tables.
content_hashCompute a content-addressable hash of block.
format_valueFormat an IR value reference as %name@vN.
pretty_print_blockReturn a MLIR-style textual dump of block.
to_canonical_bytesSerialize block to a deterministic byte representation.

Functions

canonicalize [source]

def canonicalize(block: Block) -> Block

Return a canonical-form clone of block.

The returned Block has the same structure as block but with every Value UUID and logical_id re-issued from a deterministic counter. All UUID references inside operations and value metadata are rewritten consistently. Block.kind is preserved.

Parameters:

NameTypeDescription
blockBlockThe block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

Block — A new Block with canonical UUIDs. Block.kind matches the input. Existing input/output ordering, operation ordering, metadata structure, and the param_slots manifest (carried over verbatim) are preserved.

Raises:

Example:

>>> from qamomile.qiskit import QiskitTranspiler
>>> transpiler = QiskitTranspiler()
>>> affine = transpiler.inline(transpiler.to_block(my_kernel))
>>> canon = canonicalize(affine)
>>> canon.kind is affine.kind
True

canonicalize_and_remap [source]

def canonicalize_and_remap(block: Block) -> tuple[Block, dict[str, str], dict[str, str]]

Return canonical-form Block plus the UUID and logical_id remap tables.

Useful when the caller holds external references keyed on the original Value UUIDs or logical_ids (e.g., a host-side port map) and needs to update those references to match the canonical form.

Parameters:

NameTypeDescription
blockBlockThe block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

tuple[Block, dict[str, str], dict[str, str]] — tuple[Block, dict[str, str], dict[str, str]]: A triple (canonical_block, uuid_remap, logical_id_remap) where each remap maps every original identifier encountered during the walk to its canonical counterpart. uuid and logical_id share the same monotonic counter but are tracked in separate maps.

Raises:


content_hash [source]

def content_hash(block: Block) -> str

Compute a content-addressable hash of block.

Two Blocks that canonicalize to the same form (structurally equal after UUID remapping) produce the same hash. Any IR-level change (gate added, parameter renamed, operand reordered) produces a different hash.

Parameters:

NameTypeDescription
blockBlockThe block to hash. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

str — The SHA-256 hex digest of to_canonical_bytes(block).

Raises:

Example:

>>> h1 = content_hash(canonicalize(affine_a))
>>> h2 = content_hash(canonicalize(affine_b))
>>> # If the two kernels are structurally identical, h1 == h2.

format_value [source]

def format_value(value: Any) -> str

Format an IR value reference as %name@vN.

Handles Value, ArrayValue, TupleValue, DictValue, and array-element Values (rendered as %parent[i]@vN). Constants and parameters are shown with their tagged metadata when available. Falls back to repr() for unrecognised inputs so callers can use this helper for any operand-like field without a type switch.


pretty_print_block [source]

def pretty_print_block(block: Block, *, depth: int = 0) -> str

Return a MLIR-style textual dump of block.

Parameters:

NameTypeDescription
blockBlockThe Block to format. Works on any BlockKind.
depthintHow many levels of CallBlockOperation to expand inline. 0 (default) shows only the callee name and I/O. Positive values expand the called block’s body recursively, decrementing the allowance at each step. Useful for seeing what inline will produce without actually running the pass.

Returns:

str — A newline-separated string. The format is for human debugging and str — is not guaranteed to be stable across releases.


to_canonical_bytes [source]

def to_canonical_bytes(block: Block) -> bytes

Serialize block to a deterministic byte representation.

The byte format is the internal representation backing content_hash and is not stable across qamomile versions. It is suitable for hashing and equality checks within a single deployment but should not be relied upon as a serialization format. (A stable, versioned serialization format is tracked separately.)

Parameters:

NameTypeDescription
blockBlockThe block to serialize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. The block is canonicalized first; passing an already-canonical block is harmless.

Returns:

bytes — A UTF-8-encoded byte string. Two structurally-equal Blocks produce the same bytes; changing the IR yields different bytes.

Raises:


qamomile.circuit.ir.block

Unified block representation for all pipeline stages.

Overview

ClassDescription
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
CallBlockOperation
ParamSlotMetadata for a single classical kernel argument.
ValueA typed SSA value in the IR.

Classes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

CallBlockOperation [source]

class CallBlockOperation(Operation)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    block: Block | None = None,
) -> None
Attributes
Methods
is_self_reference_to
def is_self_reference_to(self, block: Block) -> bool

Return True if this call points to the given block (self-ref).


ParamSlot [source]

class ParamSlot

Metadata for a single classical kernel argument.

A ParamSlot describes one position in the kernel’s classical parameter contract — its declared type, whether it is a runtime parameter or a compile-time-bound value, the Python default (if any), the actually-bound value (when kind is COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are immutable; pipeline passes that need to update a slot must clone via dataclasses.replace.

The slot is identified by name, which matches the kernel’s Python parameter name and the corresponding entry in Block.label_args. A slot’s name MUST never overlap between RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within one Block (this mirrors the project-level bindings / parameters disjointness rule).

Constructor
def __init__(
    self,
    name: str,
    type: 'ValueType',
    kind: ParamKind,
    ndim: int = 0,
    default: Any = None,
    bound_value: Any = None,
    differentiable: bool = False,
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.ir.canonical

Canonical form for IR blocks: deterministic UUIDs and content hashing.

This module provides a normalization pass that re-numbers every Value UUID (and logical_id) in a Block from a deterministic counter, rewriting every UUID reference embedded in operations and value metadata so the resulting Block is structurally invariant across independent builds of the same kernel.

The canonical form is intended for IR-level equality checks, debugging diffs, and a content-addressable identity (content_hash) suitable for caching and (later) for serialization keyed on IR contents rather than build-local Python state.

Supported scope:

Only BlockKind.AFFINE and BlockKind.ANALYZED are accepted. HIERARCHICAL Blocks still contain CallBlockOperations that reference sibling Blocks by Python identity; their canonical treatment is deferred (see backlog [IR design] Add named/versioned module references for cross-process kernel composition).

Output guarantees:

  1. canonicalize does not change Block.kind; it is a normalization, not a pipeline stage advance.

  2. For two builds of the same kernel that produce structurally identical IR, canonicalize returns Blocks that are equal under to_canonical_bytes (and therefore under content_hash).

  3. canonicalize is idempotent: running it twice on the same Block yields the same canonical bytes as running it once.

Canonical-bytes scope:

Display-only fields (Block.name, Block.output_names, Value.name) are excluded from to_canonical_bytes; functional fields are included. Block.label_args (input port names by position) and Block.param_slots (the kernel’s classical parameter contract) are both functional: two Blocks whose operations match but whose parameter manifests differ (e.g., a slot rebound from RUNTIME_PARAMETER to COMPILE_TIME_BOUND) hash differently. param_slots holds no Value/UUID references, so canonicalize carries the tuple over verbatim with nothing to remap.

Limitations:

Overview

FunctionDescription
canonicalizeReturn a canonical-form clone of block.
canonicalize_and_remapReturn canonical-form Block plus the UUID and logical_id remap tables.
content_hashCompute a content-addressable hash of block.
remap_indexed_identifierRemap an identifier while preserving a legacy index suffix.
remap_value_metadata_referencesRewrite UUID and logical-id references inside value metadata.
to_canonical_bytesSerialize block to a deterministic byte representation.
ClassDescription
ArrayValueAn array of typed IR values.
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
CallBlockOperation
CastOperationType cast operation for creating aliases over the same quantum resources.
CompositeGateOperationRepresents a composite gate (QPE, QFT, etc.) as a single operation.
ControlledUOperationBase class for controlled-U operations.
DictValueA dictionary value stored as stable ordered entries.
HasNestedOpsMixin for operations that contain nested operation lists.
InverseBlockOperationRepresent an inverse qkernel/block as a first-class IR operation.
TupleValueA tuple of IR values for structured data.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.
ValueMetadataTyped metadata owned by the compiler/runtime.
ValueTypeBase class for all value types in the IR.

Functions

canonicalize [source]

def canonicalize(block: Block) -> Block

Return a canonical-form clone of block.

The returned Block has the same structure as block but with every Value UUID and logical_id re-issued from a deterministic counter. All UUID references inside operations and value metadata are rewritten consistently. Block.kind is preserved.

Parameters:

NameTypeDescription
blockBlockThe block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

Block — A new Block with canonical UUIDs. Block.kind matches the input. Existing input/output ordering, operation ordering, metadata structure, and the param_slots manifest (carried over verbatim) are preserved.

Raises:

Example:

>>> from qamomile.qiskit import QiskitTranspiler
>>> transpiler = QiskitTranspiler()
>>> affine = transpiler.inline(transpiler.to_block(my_kernel))
>>> canon = canonicalize(affine)
>>> canon.kind is affine.kind
True

canonicalize_and_remap [source]

def canonicalize_and_remap(block: Block) -> tuple[Block, dict[str, str], dict[str, str]]

Return canonical-form Block plus the UUID and logical_id remap tables.

Useful when the caller holds external references keyed on the original Value UUIDs or logical_ids (e.g., a host-side port map) and needs to update those references to match the canonical form.

Parameters:

NameTypeDescription
blockBlockThe block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

tuple[Block, dict[str, str], dict[str, str]] — tuple[Block, dict[str, str], dict[str, str]]: A triple (canonical_block, uuid_remap, logical_id_remap) where each remap maps every original identifier encountered during the walk to its canonical counterpart. uuid and logical_id share the same monotonic counter but are tracked in separate maps.

Raises:


content_hash [source]

def content_hash(block: Block) -> str

Compute a content-addressable hash of block.

Two Blocks that canonicalize to the same form (structurally equal after UUID remapping) produce the same hash. Any IR-level change (gate added, parameter renamed, operand reordered) produces a different hash.

Parameters:

NameTypeDescription
blockBlockThe block to hash. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

str — The SHA-256 hex digest of to_canonical_bytes(block).

Raises:

Example:

>>> h1 = content_hash(canonicalize(affine_a))
>>> h2 = content_hash(canonicalize(affine_b))
>>> # If the two kernels are structurally identical, h1 == h2.

remap_indexed_identifier [source]

def remap_indexed_identifier(identifier: str, remap_identifier: Callable[[str], str]) -> str

Remap an identifier while preserving a legacy index suffix.

Parameters:

NameTypeDescription
identifierstrScalar identifier or legacy "<base>_<index>" carrier key.
remap_identifiertyping.Callable[[str], str]Function that remaps scalar identifiers and carrier-key bases.

Returns:

str — Remapped identifier. Numeric index suffixes are preserved after remapping the base identifier.


remap_value_metadata_references [source]

def remap_value_metadata_references(
    metadata: ValueMetadata,
    remap_uuid: Callable[[str], str],
    remap_logical_id: Callable[[str], str],
) -> ValueMetadata

Rewrite UUID and logical-id references inside value metadata.

Parameters:

NameTypeDescription
metadataValueMetadataMetadata bundle whose embedded references should be rewritten.
remap_uuidtyping.Callable[[str], str]Function that maps scalar UUID references (and carrier-key bases) to replacement UUIDs.
remap_logical_idtyping.Callable[[str], str]Function that maps scalar logical-id references (and carrier-key bases) to replacement logical IDs.

Returns:

ValueMetadata — Metadata with every embedded UUID / logical-id reference rewritten. Legacy "<uuid>_<index>" carrier keys keep their index suffix while remapping the base UUID. The original bundle is returned unchanged when no reference is rewritten.


to_canonical_bytes [source]

def to_canonical_bytes(block: Block) -> bytes

Serialize block to a deterministic byte representation.

The byte format is the internal representation backing content_hash and is not stable across qamomile versions. It is suitable for hashing and equality checks within a single deployment but should not be relied upon as a serialization format. (A stable, versioned serialization format is tracked separately.)

Parameters:

NameTypeDescription
blockBlockThe block to serialize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. The block is canonicalized first; passing an already-canonical block is harmless.

Returns:

bytes — A UTF-8-encoded byte string. Two structurally-equal Blocks produce the same bytes; changing the IR yields different bytes.

Raises:

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

CallBlockOperation [source]

class CallBlockOperation(Operation)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    block: Block | None = None,
) -> None
Attributes
Methods
is_self_reference_to
def is_self_reference_to(self, block: Block) -> bool

Return True if this call points to the given block (self-ref).


CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

CompositeGateOperation [source]

class CompositeGateOperation(Operation)

Represents a composite gate (QPE, QFT, etc.) as a single operation.

CompositeGate allows representing complex multi-gate operations as a single atomic operation in the IR. This enables:

The operands structure is:

The results structure:

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: CompositeGateType = CompositeGateType.CUSTOM,
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    resource_metadata: ResourceMetadata | None = None,
    has_implementation: bool = True,
    implementation_block: Block | None = None,
    composite_gate_instance: Any = None,
    strategy_name: str | None = None,
) -> None
Attributes

ControlledUOperation [source]

class ControlledUOperation(Operation)

Base class for controlled-U operations.

Two concrete subclasses handle distinct operand layouts:

All isinstance(op, ControlledUOperation) checks match every subclass.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int | Value = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

HasNestedOps [source]

class HasNestedOps

Mixin for operations that contain nested operation lists.

Subclasses implement nested_op_lists() and rebuild_nested() so that generic passes can recurse into control flow without isinstance chains.

Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]

Return all nested operation lists in this control flow op.

rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

Return a copy with nested operation lists replaced.

new_lists must have the same length/order as nested_op_lists().


InverseBlockOperation [source]

class InverseBlockOperation(Operation)

Represent an inverse qkernel/block as a first-class IR operation.

The operation stores both the original forward block and a Qamomile-built inverse implementation block. Emitters may use source_block with a backend-native inverse/adjoint primitive, then fall back to implementation_block when native inversion is unavailable.

Operands are ordered as control qubits, target quantum operands, then classical/object parameters. Results mirror the quantum operand layout: control results first, then one target result per target operand. Vector target operands therefore count as one operand/result while contributing their scalar width to num_target_qubits.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    source_block: Block | None = None,
    implementation_block: Block | None = None,
) -> None
Attributes

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

ValueMetadata [source]

class ValueMetadata

Typed metadata owned by the compiler/runtime.

Constructor
def __init__(
    self,
    scalar: ScalarMetadata | None = None,
    cast: CastMetadata | None = None,
    qfixed: QFixedMetadata | None = None,
    array_runtime: ArrayRuntimeMetadata | None = None,
    dict_runtime: DictRuntimeMetadata | None = None,
) -> None
Attributes

ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

qamomile.circuit.ir.operation

Overview

ClassDescription
CastOperationType cast operation for creating aliases over the same quantum resources.
CompositeGateOperationRepresents a composite gate (QPE, QFT, etc.) as a single operation.
CompositeGateTypeRegistry of known composite gate types.
ConcreteControlledUControlled-U with concrete (int) number of controls.
ControlledUOperationBase class for controlled-U operations.
DecodeQFixedOperationDecode measured bits to float (classical operation).
ExpvalOpExpectation value operation.
ForItemsOperationRepresents iteration over dict/iterable items.
GateOperationQuantum gate operation.
GateOperationType
HasNestedOpsMixin for operations that contain nested operation lists.
InverseBlockOperationRepresent an inverse qkernel/block as a first-class IR operation.
MeasureOperation
MeasureQFixedOperationMeasure a quantum fixed-point number.
MeasureVectorOperationMeasure a vector of qubits.
Operation
ReleaseSliceViewOperationMark a slice view’s borrow as explicitly returned to its parent.
ResourceMetadataResource estimation metadata for composite gates.
ReturnOperationExplicit return operation marking the end of a block with return values.
SliceArrayOperationConstruct a strided view of an ArrayValue.
SymbolicControlledUControlled-U with symbolic (Value) number of controls.

Classes

CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

CompositeGateOperation [source]

class CompositeGateOperation(Operation)

Represents a composite gate (QPE, QFT, etc.) as a single operation.

CompositeGate allows representing complex multi-gate operations as a single atomic operation in the IR. This enables:

The operands structure is:

The results structure:

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: CompositeGateType = CompositeGateType.CUSTOM,
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    resource_metadata: ResourceMetadata | None = None,
    has_implementation: bool = True,
    implementation_block: Block | None = None,
    composite_gate_instance: Any = None,
    strategy_name: str | None = None,
) -> None
Attributes

CompositeGateType [source]

class CompositeGateType(enum.Enum)

Registry of known composite gate types.

Attributes

ConcreteControlledU [source]

class ConcreteControlledU(ControlledUOperation)

Controlled-U with concrete (int) number of controls.

Operand layout: [ctrl_0, ..., ctrl_n, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_0', ..., ctrl_n', tgt_0', ..., tgt_m']

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int = 1,
) -> None
Attributes

ControlledUOperation [source]

class ControlledUOperation(Operation)

Base class for controlled-U operations.

Two concrete subclasses handle distinct operand layouts:

All isinstance(op, ControlledUOperation) checks match every subclass.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int | Value = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

DecodeQFixedOperation [source]

class DecodeQFixedOperation(Operation)

Decode measured bits to float (classical operation).

This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.

The decoding formula:

float_value = Σ bit[i] * 2^(int_bits - 1 - i)

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Example:

bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625

operands: [ArrayValue of bits (vec[bit])] results: [Float value]

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

ExpvalOp [source]

class ExpvalOp(Operation)

Expectation value operation.

This operation computes the expectation value <psi|H|psi> where psi is the quantum state and H is the Hamiltonian observable.

The operation bridges quantum and classical computation:

Example IR:

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ForItemsOperation [source]

class ForItemsOperation(HasNestedOps, Operation)

Represents iteration over dict/iterable items.

Example:

for (i, j), Jij in qmc.items(ising):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    key_vars: list[str] = list(),
    value_var: str = '',
    key_is_vector: bool = False,
    key_var_values: tuple[Value, ...] | None = None,
    value_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include the per-key/value Value fields for cloning/substitution.

Same rationale as ForOperation.all_input_values: keep the IR identity fields in lockstep with body references so UUID-keyed lookups stay valid after inline cloning.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

GateOperation [source]

class GateOperation(Operation)

Quantum gate operation.

For rotation gates (RX, RY, RZ, P, CP, RZZ), the angle parameter is stored as the last element of operands. Use the theta property for typed read access and the rotation / fixed factory class-methods for type-safe construction.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: GateOperationType | None = None,
) -> None
Attributes
Methods
fixed
@classmethod
def fixed(
    cls,
    gate_type: GateOperationType,
    qubits: list[Value],
    results: list[Value],
) -> 'GateOperation'

Create a fixed gate (H, X, CX, SWAP, …) with no angle parameter.

rotation
@classmethod
def rotation(
    cls,
    gate_type: GateOperationType,
    qubits: list[Value],
    theta: Value,
    results: list[Value],
) -> 'GateOperation'

Create a rotation gate (RX, RY, RZ, P, CP, RZZ) with an angle.


GateOperationType [source]

class GateOperationType(enum.Enum)
Attributes

HasNestedOps [source]

class HasNestedOps

Mixin for operations that contain nested operation lists.

Subclasses implement nested_op_lists() and rebuild_nested() so that generic passes can recurse into control flow without isinstance chains.

Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]

Return all nested operation lists in this control flow op.

rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

Return a copy with nested operation lists replaced.

new_lists must have the same length/order as nested_op_lists().


InverseBlockOperation [source]

class InverseBlockOperation(Operation)

Represent an inverse qkernel/block as a first-class IR operation.

The operation stores both the original forward block and a Qamomile-built inverse implementation block. Emitters may use source_block with a backend-native inverse/adjoint primitive, then fall back to implementation_block when native inversion is unavailable.

Operands are ordered as control qubits, target quantum operands, then classical/object parameters. Results mirror the quantum operand layout: control results first, then one target result per target operand. Vector target operands therefore count as one operand/result while contributing their scalar width to num_target_qubits.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    source_block: Block | None = None,
    implementation_block: Block | None = None,
) -> None
Attributes

MeasureOperation [source]

class MeasureOperation(Operation)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

MeasureQFixedOperation [source]

class MeasureQFixedOperation(Operation)

Measure a quantum fixed-point number.

This operation measures all qubits in a QFixed register and produces a Float result. During transpilation, this is lowered to individual MeasureOperations plus a DecodeQFixedOperation.

operands: [QFixed value (contains qubit_values in params)] results: [Float value]

Encoding:

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

MeasureVectorOperation [source]

class MeasureVectorOperation(Operation)

Measure a vector of qubits.

Takes a Vector[Qubit] (ArrayValue) and produces a Vector[Bit] (ArrayValue). This operation measures all qubits in the vector as a single operation.

operands: [ArrayValue of qubits] results: [ArrayValue of bits]

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


ReleaseSliceViewOperation [source]

class ReleaseSliceViewOperation(Operation)

Mark a slice view’s borrow as explicitly returned to its parent.

Emitted by :meth:Vector.__setitem__ when used with a slice index (qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold linearity checker (:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass) that the view referenced in operands[0] no longer owns its covered parent slots, mirroring the frontend’s VectorView.consume(operation_name="slice assignment") borrow release.

Like :class:SliceArrayOperation, this op is a declarative classical-side marker that does not survive into the emit stream: :class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass removes both :class:SliceArrayOperation and :class:ReleaseSliceViewOperation after :class:SliceBorrowCheckPass has observed them. Reaching emit is a compiler-internal invariant violation and is rejected with a RuntimeError from :mod:standard_emit.

Within a control-flow body (ForOperation / WhileOperation / IfOperation), this op only releases view borrows that were created within the same body. Releasing a borrow that the enclosing block has registered (an “outer-snapshot” borrow) is rejected by SliceBorrowCheckPass with SliceBorrowViolationError — the loop-merge semantics of the pass cannot propagate entry deletions out of the body, so the only way to keep the static check consistent is to forbid that pattern.

Example:

``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::

    ReleaseSliceViewOperation(
        operands=[qmc_h_result_view],  # slice_of=qs_value
        results=[],
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ResourceMetadata [source]

class ResourceMetadata

Resource estimation metadata for composite gates.

Gate count fields mirror GateCount categories.

None semantics:

Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.

When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.

Constructor
def __init__(
    self,
    query_complexity: int | None = None,
    t_gates: int | None = None,
    ancilla_qubits: int = 0,
    total_gates: int | None = None,
    single_qubit_gates: int | None = None,
    two_qubit_gates: int | None = None,
    multi_qubit_gates: int | None = None,
    clifford_gates: int | None = None,
    rotation_gates: int | None = None,
    custom_metadata: dict[str, Any] = dict(),
) -> None
Attributes

ReturnOperation [source]

class ReturnOperation(Operation)

Explicit return operation marking the end of a block with return values.

This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).

operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)

Example:

A function that returns two values (a UInt and a Float):

ReturnOperation(
    operands=[uint_value, float_value],
    results=[],
)

The signature would be:
    operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
    results=[]
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

SliceArrayOperation [source]

class SliceArrayOperation(Operation)

Construct a strided view of an ArrayValue.

The op itself performs no quantum action — it records that the result ArrayValue is a strided view of the operand parent with the given start / step. The result’s slice_of / slice_start / slice_step fields carry the affine map used by the emit-time resolver.

SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL because slicing is pure index selection — no new quantum operation is introduced. The pipeline keeps this op through PartialEvaluationPass (which invokes ConstantFoldingPass(..., strip_slice_ops=False)) so the post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass can use it as a view-declaration marker; once that check has run, StripSliceArrayOpsPass removes every SliceArrayOperation / ReleaseSliceViewOperation so segmentation (:mod:~qamomile.circuit.transpiler.passes.separate) and the downstream emit stage only see a pure quantum-op stream. By the time :mod:~qamomile.circuit.transpiler.passes.separate runs the op has therefore been stripped — reaching emit is a compiler- internal invariant violation.

Example:

``q[1::2]`` on a ``Vector[Qubit]`` emits::

    SliceArrayOperation(
        operands=[q_value, uint_1, uint_2],
        results=[sliced_value],  # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

SymbolicControlledU [source]

class SymbolicControlledU(ControlledUOperation)

Controlled-U with symbolic (Value) number of controls.

Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']

The number of control arguments k is recorded in num_control_args; the default k = 1 corresponds to the historical single-pool form (operands[0] is a Vector[Qubit] / VectorView whose length equals num_controls, or whose control_indices-selected subset does). When k > 1 the control prefix is a heterogeneous sequence of scalar Qubit values and ArrayValues whose total qubit count is num_controls; the emit pass walks them in order to recover the per-physical-qubit control set.

When control_indices is None the entire control prefix is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the prefix args equals num_controls). When non-None, the listed indices select exactly num_controls slots from a single-arg pool to act as controls; combining control_indices with the multi-arg control prefix is rejected at frontend time.

Each control_indices entry is stored as a Value of UIntType regardless of whether the frontend passed an int literal or a UInt handle, so all downstream value-substitution passes see a uniform shape.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: Value = (lambda: Value(type=(UIntType()), name=''))(),
    control_indices: tuple[Value, ...] | None = None,
    num_control_args: int = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

qamomile.circuit.ir.operation.arithmetic_operations

Overview

FunctionDescription
runtime_kind_from_binopMap a BinOpKind to its RuntimeOpKind counterpart.
runtime_kind_from_compopMap a CompOpKind to its RuntimeOpKind counterpart.
runtime_kind_from_condopMap a CondOpKind to its RuntimeOpKind counterpart.
ClassDescription
BinOpBinary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
BinOpKind
BinaryOperationBaseBase for binary operations with lhs, rhs, and output.
BitTypeType representing a classical bit.
CompOpComparison operation (EQ, NEQ, LT, LE, GT, GE).
CompOpKind
CondOpConditional logical operation (AND, OR).
CondOpKind
NotOp
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
PhiOpSSA Phi function: merge point after conditional branch.
RuntimeClassicalExprA classical expression known to require runtime evaluation.
RuntimeOpKindUnified kind for RuntimeClassicalExpr covering all classical
Signature
ValueA typed SSA value in the IR.

Functions

runtime_kind_from_binop [source]

def runtime_kind_from_binop(kind: BinOpKind) -> RuntimeOpKind

Map a BinOpKind to its RuntimeOpKind counterpart.


runtime_kind_from_compop [source]

def runtime_kind_from_compop(kind: CompOpKind) -> RuntimeOpKind

Map a CompOpKind to its RuntimeOpKind counterpart.


runtime_kind_from_condop [source]

def runtime_kind_from_condop(kind: CondOpKind) -> RuntimeOpKind

Map a CondOpKind to its RuntimeOpKind counterpart.

Classes

BinOp [source]

class BinOp(BinaryOperationBase)

Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: BinOpKind | None = None,
) -> None
Attributes

BinOpKind [source]

class BinOpKind(enum.Enum)
Attributes

BinaryOperationBase [source]

class BinaryOperationBase(Operation)

Base for binary operations with lhs, rhs, and output.

Provides common properties and validation for operations that take two operands and produce one result.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: enum.Enum | None = None,
) -> None
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


CompOp [source]

class CompOp(BinaryOperationBase)

Comparison operation (EQ, NEQ, LT, LE, GT, GE).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CompOpKind | None = None,
) -> None
Attributes

CompOpKind [source]

class CompOpKind(enum.Enum)
Attributes

CondOp [source]

class CondOp(BinaryOperationBase)

Conditional logical operation (AND, OR).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CondOpKind | None = None,
) -> None
Attributes

CondOpKind [source]

class CondOpKind(enum.Enum)
Attributes

NotOp [source]

class NotOp(Operation)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

PhiOp [source]

class PhiOp(Operation)

SSA Phi function: merge point after conditional branch.

This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.

Example:

if condition:
    x = x + 1  # true_value
else:
    x = x + 2  # false_value
# x is now PhiOp(condition, true_value, false_value)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

RuntimeClassicalExpr [source]

class RuntimeClassicalExpr(Operation)

A classical expression known to require runtime evaluation.

Lowered from CompOp / CondOp / NotOp / BinOp by ClassicalLoweringPass when the op’s operand dataflow traces back to a MeasureOperation (i.e. cannot be folded at compile-time, by emit-time loop unrolling, or by compile_time_if_lowering). Backend emit translates this 1:1 to a backend-native runtime expression (e.g. qiskit.circuit.classical.expr.Expr).

Operand convention:

The single-node + unified-kind shape (vs four parallel subclasses) keeps the backend dispatch a single match op.kind instead of four parallel hooks, and makes the IR self-documenting: a single RuntimeClassicalExpr instance signals “runtime evaluation required” regardless of which classical family it came from.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: RuntimeOpKind | None = None,
) -> None
Attributes

RuntimeOpKind [source]

class RuntimeOpKind(enum.Enum)

Unified kind for RuntimeClassicalExpr covering all classical op families that can appear at runtime.

The split between this enum and the per-family BinOpKind / CompOpKind / CondOpKind is intentional: compile-time-foldable classical ops keep their original IR types so the existing fold pipeline (constant_foldcompile_time_if_lowering → emit-time evaluate_classical_predicate) is undisturbed. Only ops identified as runtime-evaluation-only by ClassicalLoweringPass get rewritten to RuntimeClassicalExpr with a member of this enum.

Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.ir.operation.call_block_ops

Overview

ClassDescription
BlockUnified block representation for all pipeline stages.
BlockTypeType representing a block/function reference.
CallBlockOperation
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
Signature

Classes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


CallBlockOperation [source]

class CallBlockOperation(Operation)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    block: Block | None = None,
) -> None
Attributes
Methods
is_self_reference_to
def is_self_reference_to(self, block: Block) -> bool

Return True if this call points to the given block (self-ref).


Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

qamomile.circuit.ir.operation.cast

Cast operation for type conversions over the same quantum resources.

Overview

ClassDescription
CastOperationType cast operation for creating aliases over the same quantum resources.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
Signature

Classes

CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

qamomile.circuit.ir.operation.classical_ops

Classical operations for quantum-classical hybrid programs.

Overview

ClassDescription
BitTypeType representing a classical bit.
DecodeQFixedOperationDecode measured bits to float (classical operation).
FloatTypeType representing a floating-point number.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
Signature

Classes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


DecodeQFixedOperation [source]

class DecodeQFixedOperation(Operation)

Decode measured bits to float (classical operation).

This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.

The decoding formula:

float_value = Σ bit[i] * 2^(int_bits - 1 - i)

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Example:

bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625

operands: [ArrayValue of bits (vec[bit])] results: [Float value]

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

qamomile.circuit.ir.operation.composite_gate

CompositeGate operation for representing complex multi-gate operations.

Overview

ClassDescription
BlockUnified block representation for all pipeline stages.
BlockTypeType representing a block/function reference.
CompositeGateOperationRepresents a composite gate (QPE, QFT, etc.) as a single operation.
CompositeGateTypeRegistry of known composite gate types.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
QubitTypeType representing a quantum bit (qubit).
ResourceMetadataResource estimation metadata for composite gates.
Signature
ValueA typed SSA value in the IR.

Classes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


CompositeGateOperation [source]

class CompositeGateOperation(Operation)

Represents a composite gate (QPE, QFT, etc.) as a single operation.

CompositeGate allows representing complex multi-gate operations as a single atomic operation in the IR. This enables:

The operands structure is:

The results structure:

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: CompositeGateType = CompositeGateType.CUSTOM,
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    resource_metadata: ResourceMetadata | None = None,
    has_implementation: bool = True,
    implementation_block: Block | None = None,
    composite_gate_instance: Any = None,
    strategy_name: str | None = None,
) -> None
Attributes

CompositeGateType [source]

class CompositeGateType(enum.Enum)

Registry of known composite gate types.

Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


ResourceMetadata [source]

class ResourceMetadata

Resource estimation metadata for composite gates.

Gate count fields mirror GateCount categories.

None semantics:

Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.

When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.

Constructor
def __init__(
    self,
    query_complexity: int | None = None,
    t_gates: int | None = None,
    ancilla_qubits: int = 0,
    total_gates: int | None = None,
    single_qubit_gates: int | None = None,
    two_qubit_gates: int | None = None,
    multi_qubit_gates: int | None = None,
    clifford_gates: int | None = None,
    rotation_gates: int | None = None,
    custom_metadata: dict[str, Any] = dict(),
) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.ir.operation.control_flow

Overview

ClassDescription
BitTypeType representing a classical bit.
BlockTypeType representing a block/function reference.
ForItemsOperationRepresents iteration over dict/iterable items.
ForOperationRepresents a for loop operation.
HasNestedOpsMixin for operations that contain nested operation lists.
IfOperationRepresents an if-else conditional operation.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
PhiOpSSA Phi function: merge point after conditional branch.
Signature
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.
WhileOperationRepresents a while loop operation.

Classes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


ForItemsOperation [source]

class ForItemsOperation(HasNestedOps, Operation)

Represents iteration over dict/iterable items.

Example:

for (i, j), Jij in qmc.items(ising):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    key_vars: list[str] = list(),
    value_var: str = '',
    key_is_vector: bool = False,
    key_var_values: tuple[Value, ...] | None = None,
    value_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include the per-key/value Value fields for cloning/substitution.

Same rationale as ForOperation.all_input_values: keep the IR identity fields in lockstep with body references so UUID-keyed lookups stay valid after inline cloning.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

ForOperation [source]

class ForOperation(HasNestedOps, Operation)

Represents a for loop operation.

Example:

for i in range(start, stop, step):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    loop_var: str = '',
    loop_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include loop_var_value so cloning/substitution stays consistent.

Without this override, UUIDRemapper would clone every body reference to the loop variable to a fresh UUID, but leave loop_var_value pointing at the un-cloned original — emit-time UUID-keyed lookups for the loop variable would then miss.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

HasNestedOps [source]

class HasNestedOps

Mixin for operations that contain nested operation lists.

Subclasses implement nested_op_lists() and rebuild_nested() so that generic passes can recurse into control flow without isinstance chains.

Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]

Return all nested operation lists in this control flow op.

rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

Return a copy with nested operation lists replaced.

new_lists must have the same length/order as nested_op_lists().


IfOperation [source]

class IfOperation(HasNestedOps, Operation)

Represents an if-else conditional operation.

Example:

if condition:
    true_body
else:
    false_body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    true_operations: list[Operation] = list(),
    false_operations: list[Operation] = list(),
    phi_ops: list[PhiOp] = list(),
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

PhiOp [source]

class PhiOp(Operation)

SSA Phi function: merge point after conditional branch.

This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.

Example:

if condition:
    x = x + 1  # true_value
else:
    x = x + 2  # false_value
# x is now PhiOp(condition, true_value, false_value)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

WhileOperation [source]

class WhileOperation(HasNestedOps, Operation)

Represents a while loop operation.

Only measurement-backed conditions are supported: the condition must be a Bit value produced by qmc.measure(). Non-measurement conditions (classical variables, constants, comparisons) are rejected by ValidateWhileContractPass before reaching backend emit.

Example::

bit = qmc.measure(q)
while bit:
    q = qmc.h(q)
    bit = qmc.measure(q)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    operations: list[Operation] = list(),
    max_iterations: int | None = None,
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

qamomile.circuit.ir.operation.expval

Expectation value operation for computing <psi|H|psi>.

This module defines the ExpvalOp IR operation that represents computing the expectation value of a Hamiltonian observable with respect to a quantum state.

Overview

ClassDescription
ExpvalOpExpectation value operation.
FloatTypeType representing a floating-point number.
ObservableTypeType representing a Hamiltonian observable parameter.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
Signature
ValueA typed SSA value in the IR.

Classes

ExpvalOp [source]

class ExpvalOp(Operation)

Expectation value operation.

This operation computes the expectation value <psi|H|psi> where psi is the quantum state and H is the Hamiltonian observable.

The operation bridges quantum and classical computation:

Example IR:

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.ir.operation.gate

Overview

ClassDescription
BitTypeType representing a classical bit.
BlockUnified block representation for all pipeline stages.
ConcreteControlledUControlled-U with concrete (int) number of controls.
ControlledUOperationBase class for controlled-U operations.
FloatTypeType representing a floating-point number.
GateOperationQuantum gate operation.
GateOperationType
MeasureOperation
MeasureQFixedOperationMeasure a quantum fixed-point number.
MeasureVectorOperationMeasure a vector of qubits.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
QubitTypeType representing a quantum bit (qubit).
Signature
SymbolicControlledUControlled-U with symbolic (Value) number of controls.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.

Classes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


ConcreteControlledU [source]

class ConcreteControlledU(ControlledUOperation)

Controlled-U with concrete (int) number of controls.

Operand layout: [ctrl_0, ..., ctrl_n, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_0', ..., ctrl_n', tgt_0', ..., tgt_m']

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int = 1,
) -> None
Attributes

ControlledUOperation [source]

class ControlledUOperation(Operation)

Base class for controlled-U operations.

Two concrete subclasses handle distinct operand layouts:

All isinstance(op, ControlledUOperation) checks match every subclass.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int | Value = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


GateOperation [source]

class GateOperation(Operation)

Quantum gate operation.

For rotation gates (RX, RY, RZ, P, CP, RZZ), the angle parameter is stored as the last element of operands. Use the theta property for typed read access and the rotation / fixed factory class-methods for type-safe construction.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: GateOperationType | None = None,
) -> None
Attributes
Methods
fixed
@classmethod
def fixed(
    cls,
    gate_type: GateOperationType,
    qubits: list[Value],
    results: list[Value],
) -> 'GateOperation'

Create a fixed gate (H, X, CX, SWAP, …) with no angle parameter.

rotation
@classmethod
def rotation(
    cls,
    gate_type: GateOperationType,
    qubits: list[Value],
    theta: Value,
    results: list[Value],
) -> 'GateOperation'

Create a rotation gate (RX, RY, RZ, P, CP, RZZ) with an angle.


GateOperationType [source]

class GateOperationType(enum.Enum)
Attributes

MeasureOperation [source]

class MeasureOperation(Operation)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

MeasureQFixedOperation [source]

class MeasureQFixedOperation(Operation)

Measure a quantum fixed-point number.

This operation measures all qubits in a QFixed register and produces a Float result. During transpilation, this is lowered to individual MeasureOperations plus a DecodeQFixedOperation.

operands: [QFixed value (contains qubit_values in params)] results: [Float value]

Encoding:

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

MeasureVectorOperation [source]

class MeasureVectorOperation(Operation)

Measure a vector of qubits.

Takes a Vector[Qubit] (ArrayValue) and produces a Vector[Bit] (ArrayValue). This operation measures all qubits in the vector as a single operation.

operands: [ArrayValue of qubits] results: [ArrayValue of bits]

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

SymbolicControlledU [source]

class SymbolicControlledU(ControlledUOperation)

Controlled-U with symbolic (Value) number of controls.

Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']

The number of control arguments k is recorded in num_control_args; the default k = 1 corresponds to the historical single-pool form (operands[0] is a Vector[Qubit] / VectorView whose length equals num_controls, or whose control_indices-selected subset does). When k > 1 the control prefix is a heterogeneous sequence of scalar Qubit values and ArrayValues whose total qubit count is num_controls; the emit pass walks them in order to recover the per-physical-qubit control set.

When control_indices is None the entire control prefix is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the prefix args equals num_controls). When non-None, the listed indices select exactly num_controls slots from a single-arg pool to act as controls; combining control_indices with the multi-arg control prefix is rejected at frontend time.

Each control_indices entry is stored as a Value of UIntType regardless of whether the frontend passed an int literal or a UInt handle, so all downstream value-substitution passes see a uniform shape.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: Value = (lambda: Value(type=(UIntType()), name=''))(),
    control_indices: tuple[Value, ...] | None = None,
    num_control_args: int = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

qamomile.circuit.ir.operation.inverse_block

First-class inverse block operation.

InverseBlockOperation represents “apply the inverse of this block” as a single IR operation. It shares the operand layout convention of :class:~qamomile.circuit.ir.operation.composite_gate.CompositeGateOperation (control qubits, then quantum targets, then classical/object parameters) but is an independent :class:Operation subclass, not a composite-gate variant.

Overview

ClassDescription
ArrayValueAn array of typed IR values.
BlockUnified block representation for all pipeline stages.
BlockTypeType representing a block/function reference.
InverseBlockOperationRepresent an inverse qkernel/block as a first-class IR operation.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
QubitTypeType representing a quantum bit (qubit).
Signature
ValueA typed SSA value in the IR.

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


InverseBlockOperation [source]

class InverseBlockOperation(Operation)

Represent an inverse qkernel/block as a first-class IR operation.

The operation stores both the original forward block and a Qamomile-built inverse implementation block. Emitters may use source_block with a backend-native inverse/adjoint primitive, then fall back to implementation_block when native inversion is unavailable.

Operands are ordered as control qubits, target quantum operands, then classical/object parameters. Results mirror the quantum operand layout: control results first, then one target result per target operand. Vector target operands therefore count as one operand/result while contributing their scalar width to num_target_qubits.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    source_block: Block | None = None,
    implementation_block: Block | None = None,
) -> None
Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.ir.operation.operation

Overview

ClassDescription
CInitOperationInitialize the classical values (const, arguments etc)
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
QInitOperationInitialize the qubit
Signature
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.

Classes

CInitOperation [source]

class CInitOperation(Operation)

Initialize the classical values (const, arguments etc)

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

QInitOperation [source]

class QInitOperation(Operation)

Initialize the qubit

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

qamomile.circuit.ir.operation.pauli_evolve

Pauli evolution operation for applying exp(-i * gamma * H).

This module defines the PauliEvolveOp IR operation that represents applying Hamiltonian time evolution to a quantum state.

Overview

ClassDescription
FloatTypeType representing a floating-point number.
ObservableTypeType representing a Hamiltonian observable parameter.
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
PauliEvolveOpPauli evolution operation: exp(-i * gamma * H).
Signature
ValueA typed SSA value in the IR.

Classes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

PauliEvolveOp [source]

class PauliEvolveOp(Operation)

Pauli evolution operation: exp(-i * gamma * H).

This operation applies the time evolution of a Pauli Hamiltonian to a quantum register.

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.ir.operation.return_operation

Return operation for explicit block termination.

Overview

ClassDescription
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
ReturnOperationExplicit return operation marking the end of a block with return values.
Signature

Classes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

ReturnOperation [source]

class ReturnOperation(Operation)

Explicit return operation marking the end of a block with return values.

This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).

operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)

Example:

A function that returns two values (a UInt and a Float):

ReturnOperation(
    operands=[uint_value, float_value],
    results=[],
)

The signature would be:
    operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
    results=[]
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

qamomile.circuit.ir.operation.slice_array

Slice operation that produces a strided view of an array.

Overview

ClassDescription
Operation
OperationKindClassification of operations for classical/quantum separation.
ParamHint
ReleaseSliceViewOperationMark a slice view’s borrow as explicitly returned to its parent.
Signature
SliceArrayOperationConstruct a strided view of an ArrayValue.

Classes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


OperationKind [source]

class OperationKind(enum.Enum)

Classification of operations for classical/quantum separation.

This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.

Values:

QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)

Attributes

ParamHint [source]

class ParamHint
Constructor
def __init__(self, name: str, type: ValueType) -> None
Attributes

ReleaseSliceViewOperation [source]

class ReleaseSliceViewOperation(Operation)

Mark a slice view’s borrow as explicitly returned to its parent.

Emitted by :meth:Vector.__setitem__ when used with a slice index (qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold linearity checker (:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass) that the view referenced in operands[0] no longer owns its covered parent slots, mirroring the frontend’s VectorView.consume(operation_name="slice assignment") borrow release.

Like :class:SliceArrayOperation, this op is a declarative classical-side marker that does not survive into the emit stream: :class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass removes both :class:SliceArrayOperation and :class:ReleaseSliceViewOperation after :class:SliceBorrowCheckPass has observed them. Reaching emit is a compiler-internal invariant violation and is rejected with a RuntimeError from :mod:standard_emit.

Within a control-flow body (ForOperation / WhileOperation / IfOperation), this op only releases view borrows that were created within the same body. Releasing a borrow that the enclosing block has registered (an “outer-snapshot” borrow) is rejected by SliceBorrowCheckPass with SliceBorrowViolationError — the loop-merge semantics of the pass cannot propagate entry deletions out of the body, so the only way to keep the static check consistent is to forbid that pattern.

Example:

``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::

    ReleaseSliceViewOperation(
        operands=[qmc_h_result_view],  # slice_of=qs_value
        results=[],
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Signature [source]

class Signature
Constructor
def __init__(
    self,
    operands: list[ParamHint | None] = list(),
    results: list[ParamHint] = list(),
) -> None
Attributes

SliceArrayOperation [source]

class SliceArrayOperation(Operation)

Construct a strided view of an ArrayValue.

The op itself performs no quantum action — it records that the result ArrayValue is a strided view of the operand parent with the given start / step. The result’s slice_of / slice_start / slice_step fields carry the affine map used by the emit-time resolver.

SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL because slicing is pure index selection — no new quantum operation is introduced. The pipeline keeps this op through PartialEvaluationPass (which invokes ConstantFoldingPass(..., strip_slice_ops=False)) so the post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass can use it as a view-declaration marker; once that check has run, StripSliceArrayOpsPass removes every SliceArrayOperation / ReleaseSliceViewOperation so segmentation (:mod:~qamomile.circuit.transpiler.passes.separate) and the downstream emit stage only see a pure quantum-op stream. By the time :mod:~qamomile.circuit.transpiler.passes.separate runs the op has therefore been stripped — reaching emit is a compiler- internal invariant violation.

Example:

``q[1::2]`` on a ``Vector[Qubit]`` emits::

    SliceArrayOperation(
        operands=[q_value, uint_1, uint_2],
        results=[sliced_value],  # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

qamomile.circuit.ir.parameter

First-class manifest of a kernel’s classical parameter interface.

This module defines ParamSlot and ParamKind, which together describe every classical (non-quantum) argument of a @qkernel function so the kernel’s parameter contract is recoverable from the IR alone — without an external Python-side manifest.

Motivation:

The project rule documented in CLAUDE.md keeps bindings and parameters strictly disjoint at the Transpiler.transpile() API boundary, but the IR itself does not record which name was decided which way. After partial_eval folds a binding into a concrete constant, downstream readers cannot tell whether a constant value originated from a compile-time binding or was a literal in the kernel source. This is especially limiting for the “qamomile as subgraph of an outer DSL’s computation graph” use case, where the receiver needs to know the kernel’s full classical interface (name, type, default, runtime-or-bound) to rebind values in subsequent calls.

Per-kernel-argument metadata also makes it natural to attach optional hints (currently just differentiable) for outer DSL tooling such as parameter-shift gradient back-ends.

Scope:

ParamSlot covers only classical (non-quantum) arguments. Qubit and Vector[Qubit] inputs are not part of the parameter slot manifest; they appear in Block.input_values instead.

The companion Block.parameters: dict[str, Value] field is retained for callers (passes, emitters) that need a direct Value reference for runtime parameters; Block.param_slots is the canonical, fully-typed contract that survives the pipeline.

Overview

ClassDescription
ParamKindLifecycle classification for a classical kernel argument.
ParamSlotMetadata for a single classical kernel argument.

Classes

ParamKind [source]

class ParamKind(enum.Enum)

Lifecycle classification for a classical kernel argument.

Values:

RUNTIME_PARAMETER: The argument is intended to be bound at execution time by the backend (or, more generally, by the outer caller in a hybrid loop). It survives the compilation pipeline as a symbolic parameter. COMPILE_TIME_BOUND: The argument was provided as a binding (or via a Python default) and is folded into the IR by resolve_parameter_shapes / partial_eval. No symbolic counterpart remains in the emitted circuit.

Attributes

ParamSlot [source]

class ParamSlot

Metadata for a single classical kernel argument.

A ParamSlot describes one position in the kernel’s classical parameter contract — its declared type, whether it is a runtime parameter or a compile-time-bound value, the Python default (if any), the actually-bound value (when kind is COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are immutable; pipeline passes that need to update a slot must clone via dataclasses.replace.

The slot is identified by name, which matches the kernel’s Python parameter name and the corresponding entry in Block.label_args. A slot’s name MUST never overlap between RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within one Block (this mirrors the project-level bindings / parameters disjointness rule).

Constructor
def __init__(
    self,
    name: str,
    type: 'ValueType',
    kind: ParamKind,
    ndim: int = 0,
    default: Any = None,
    bound_value: Any = None,
    differentiable: bool = False,
) -> None
Attributes

qamomile.circuit.ir.printer

Text pretty-printer for the Block IR.

This module provides a contributor-facing textual dump of the intermediate representation, similar in spirit to MLIR’s textual IR format. Useful for debugging the transpiler pipeline by inspecting the block at each stage (HIERARCHICAL / AFFINE / ANALYZED).

Example:

>>> from qamomile.circuit.ir import pretty_print_block
>>> block = transpiler.to_block(my_kernel, bindings={"n": 3})
>>> print(pretty_print_block(block))
block my_kernel [HIERARCHICAL] (n: UIntType) -> Vector[BitType]
  ...

The output is intended for human inspection, not for machine parsing; its format may change between Qamomile releases.

Overview

FunctionDescription
format_valueFormat an IR value reference as %name@vN.
pretty_print_blockReturn a MLIR-style textual dump of block.
ClassDescription
ArrayValueAn array of typed IR values.
BinOpBinary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
BlockUnified block representation for all pipeline stages.
CallBlockOperation
CompOpComparison operation (EQ, NEQ, LT, LE, GT, GE).
CondOpConditional logical operation (AND, OR).
DecodeQFixedOperationDecode measured bits to float (classical operation).
DictValueA dictionary value stored as stable ordered entries.
ExpvalOpExpectation value operation.
ForOperationRepresents a for loop operation.
IfOperationRepresents an if-else conditional operation.
NotOp
PauliEvolveOpPauli evolution operation: exp(-i * gamma * H).
PhiOpSSA Phi function: merge point after conditional branch.
TupleValueA tuple of IR values for structured data.
ValueA typed SSA value in the IR.
WhileOperationRepresents a while loop operation.

Functions

format_value [source]

def format_value(value: Any) -> str

Format an IR value reference as %name@vN.

Handles Value, ArrayValue, TupleValue, DictValue, and array-element Values (rendered as %parent[i]@vN). Constants and parameters are shown with their tagged metadata when available. Falls back to repr() for unrecognised inputs so callers can use this helper for any operand-like field without a type switch.


pretty_print_block [source]

def pretty_print_block(block: Block, *, depth: int = 0) -> str

Return a MLIR-style textual dump of block.

Parameters:

NameTypeDescription
blockBlockThe Block to format. Works on any BlockKind.
depthintHow many levels of CallBlockOperation to expand inline. 0 (default) shows only the callee name and I/O. Positive values expand the called block’s body recursively, decrementing the allowance at each step. Useful for seeing what inline will produce without actually running the pass.

Returns:

str — A newline-separated string. The format is for human debugging and str — is not guaranteed to be stable across releases.

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

BinOp [source]

class BinOp(BinaryOperationBase)

Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: BinOpKind | None = None,
) -> None
Attributes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


CallBlockOperation [source]

class CallBlockOperation(Operation)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    block: Block | None = None,
) -> None
Attributes
Methods
is_self_reference_to
def is_self_reference_to(self, block: Block) -> bool

Return True if this call points to the given block (self-ref).


CompOp [source]

class CompOp(BinaryOperationBase)

Comparison operation (EQ, NEQ, LT, LE, GT, GE).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CompOpKind | None = None,
) -> None
Attributes

CondOp [source]

class CondOp(BinaryOperationBase)

Conditional logical operation (AND, OR).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CondOpKind | None = None,
) -> None
Attributes

DecodeQFixedOperation [source]

class DecodeQFixedOperation(Operation)

Decode measured bits to float (classical operation).

This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.

The decoding formula:

float_value = Σ bit[i] * 2^(int_bits - 1 - i)

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Example:

bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625

operands: [ArrayValue of bits (vec[bit])] results: [Float value]

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

ExpvalOp [source]

class ExpvalOp(Operation)

Expectation value operation.

This operation computes the expectation value <psi|H|psi> where psi is the quantum state and H is the Hamiltonian observable.

The operation bridges quantum and classical computation:

Example IR:

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ForOperation [source]

class ForOperation(HasNestedOps, Operation)

Represents a for loop operation.

Example:

for i in range(start, stop, step):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    loop_var: str = '',
    loop_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include loop_var_value so cloning/substitution stays consistent.

Without this override, UUIDRemapper would clone every body reference to the loop variable to a fresh UUID, but leave loop_var_value pointing at the un-cloned original — emit-time UUID-keyed lookups for the loop variable would then miss.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

IfOperation [source]

class IfOperation(HasNestedOps, Operation)

Represents an if-else conditional operation.

Example:

if condition:
    true_body
else:
    false_body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    true_operations: list[Operation] = list(),
    false_operations: list[Operation] = list(),
    phi_ops: list[PhiOp] = list(),
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

NotOp [source]

class NotOp(Operation)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

PauliEvolveOp [source]

class PauliEvolveOp(Operation)

Pauli evolution operation: exp(-i * gamma * H).

This operation applies the time evolution of a Pauli Hamiltonian to a quantum register.

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

PhiOp [source]

class PhiOp(Operation)

SSA Phi function: merge point after conditional branch.

This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.

Example:

if condition:
    x = x + 1  # true_value
else:
    x = x + 2  # false_value
# x is now PhiOp(condition, true_value, false_value)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


WhileOperation [source]

class WhileOperation(HasNestedOps, Operation)

Represents a while loop operation.

Only measurement-backed conditions are supported: the condition must be a Bit value produced by qmc.measure(). Non-measurement conditions (classical variables, constants, comparisons) are rejected by ValidateWhileContractPass before reaching backend emit.

Example::

bit = qmc.measure(q)
while bit:
    q = qmc.h(q)
    bit = qmc.measure(q)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    operations: list[Operation] = list(),
    max_iterations: int | None = None,
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

qamomile.circuit.ir.serialize

Public surface for the Qamomile IR serialization package.

Two wire formats are supported on top of a shared intermediate dict schema (see :mod:qamomile.circuit.ir.serialize.schema):

to_dict / from_dict are exposed for tests and tooling that want to operate on the intermediate Python dict directly.

Scope: BlockKind.AFFINE and BlockKind.ANALYZED only. HIERARCHICAL blocks still hold CallBlockOperation references by Python identity and are deferred.

Overview

FunctionDescription
dump_jsonEncode block into a UTF-8 JSON byte string.
dump_msgpackEncode block into a msgpack byte string.
from_dictReconstruct a Block from a dict envelope.
load_jsonDecode a JSON document back into a Block.
load_msgpackDecode a msgpack payload back into a Block.
to_dictEncode a Block into the intermediate dict envelope.

Constants

Functions

dump_json [source]

def dump_json(block: Block) -> bytes

Encode block into a UTF-8 JSON byte string.

The serialized form contains the schema_version envelope from :func:qamomile.circuit.ir.serialize.encode.to_dict plus base64-wrapped bytes payloads (numpy array data, raw bytes bound values) so the output stays JSON-text-safe.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be AFFINE or ANALYZED.

Returns:

bytes — A UTF-8 encoded JSON document.

Raises:


dump_msgpack [source]

def dump_msgpack(block: Block) -> bytes

Encode block into a msgpack byte string.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be AFFINE or ANALYZED.

Returns:

bytes — A msgpack-encoded payload. Compatible with the standard msgpack package; no extension types are used.

Raises:


from_dict [source]

def from_dict(envelope: dict[str, Any]) -> Block

Reconstruct a Block from a dict envelope.

Parameters:

NameTypeDescription
envelopedict[str, Any]The dict produced by :func:qamomile.circuit.ir.serialize.encode.to_dict (or an equivalent producer that respects the schema).

Returns:

Block — The reconstructed Block at AFFINE or ANALYZED.

Raises:


load_json [source]

def load_json(payload: bytes | str) -> Block

Decode a JSON document back into a Block.

Parameters:

NameTypeDescription
payloadbytes | strJSON bytes (UTF-8) or a JSON string.

Returns:

Block — The reconstructed Block.

Raises:


load_msgpack [source]

def load_msgpack(payload: bytes) -> Block

Decode a msgpack payload back into a Block.

The unpacker is configured with raw=False so strings come back as Python str, and strict_map_key=False so non-string map keys (numeric, etc.) are accepted (qamomile’s schema only uses string keys today, but this keeps the loader robust to future schema extensions).

Parameters:

NameTypeDescription
payloadbytesA msgpack-encoded payload produced by :func:dump_msgpack or an equivalent encoder.

Returns:

Block — The reconstructed Block.

Raises:


to_dict [source]

def to_dict(block: Block) -> dict[str, Any]

Encode a Block into the intermediate dict envelope.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

dict[str, Any] — dict[str, Any]: {"schema_version": SCHEMA_VERSION, "block": <block dict>} ready to be passed to a wire-format encoder (JSON / msgpack).

Raises:


qamomile.circuit.ir.serialize.decode

Intermediate dict → IR decoder.

Reconstructs a Block from the dict envelope produced by :mod:qamomile.circuit.ir.serialize.encode. The decoder NEVER performs dynamic class resolution: every $type tag is routed through a hard-coded factory table, and unknown tags raise ValueError. This is the load-bearing security invariant — see :mod:qamomile.circuit.ir.serialize.schema for the rationale.

Values are materialized lazily via depth-first recursion so any referenced parent_array / element_indices / shape Value is instantiated before the Value that points at it. A cycle (defensive; not produced by the canonical encoder) raises ValueError.

Overview

FunctionDescription
dict_to_arrayDecode a wrapper dict back into a numpy ndarray.
dict_to_hamiltonianDecode a wrapper dict back into a Hamiltonian.
from_dictReconstruct a Block from a dict envelope.
is_array_wrapperReturn True if d is a numpy-array wrapper dict.
is_hamiltonian_wrapperReturn True if d is a Hamiltonian wrapper dict.
is_plain_intReturn True if value is a Python int but not a bool.
ClassDescription
ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
ArrayValueAn array of typed IR values.
BinOpBinary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
BinOpKind
BitTypeType representing a classical bit.
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
BlockTypeType representing a block/function reference.
CInitOperationInitialize the classical values (const, arguments etc)
CastMetadataMetadata describing a cast carrier and its underlying qubits.
CastOperationType cast operation for creating aliases over the same quantum resources.
CompOpComparison operation (EQ, NEQ, LT, LE, GT, GE).
CompOpKind
ConcreteControlledUControlled-U with concrete (int) number of controls.
CondOpConditional logical operation (AND, OR).
CondOpKind
DecodeQFixedOperationDecode measured bits to float (classical operation).
DictRuntimeMetadataMetadata for transpile-time bound dict values.
DictTypeType representing a dictionary mapping keys to values.
DictValueA dictionary value stored as stable ordered entries.
FloatTypeType representing a floating-point number.
ForOperationRepresents a for loop operation.
IfOperationRepresents an if-else conditional operation.
NotOp
ObservableTypeType representing a Hamiltonian observable parameter.
ParamKindLifecycle classification for a classical kernel argument.
ParamSlotMetadata for a single classical kernel argument.
PauliEvolveOpPauli evolution operation: exp(-i * gamma * H).
PhiOpSSA Phi function: merge point after conditional branch.
QFixedMetadataMetadata for QFixed carriers.
QFixedTypeQuantum fixed-point type.
QInitOperationInitialize the qubit
QUIntTypeQuantum unsigned integer type.
QubitTypeType representing a quantum bit (qubit).
ReleaseSliceViewOperationMark a slice view’s borrow as explicitly returned to its parent.
ResourceMetadataResource estimation metadata for composite gates.
RuntimeClassicalExprA classical expression known to require runtime evaluation.
RuntimeOpKindUnified kind for RuntimeClassicalExpr covering all classical
ScalarMetadataMetadata for scalar constants and symbolic parameters.
SliceArrayOperationConstruct a strided view of an ArrayValue.
SymbolicControlledUControlled-U with symbolic (Value) number of controls.
TupleTypeType representing a tuple of values.
TupleValueA tuple of IR values for structured data.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.
ValueMetadataTyped metadata owned by the compiler/runtime.
ValueTypeBase class for all value types in the IR.
WhileOperationRepresents a while loop operation.

Constants

Functions

dict_to_array [source]

def dict_to_array(d: dict[str, Any]) -> np.ndarray

Decode a wrapper dict back into a numpy ndarray.

Parameters:

NameTypeDescription
ddict[str, Any]A wrapper dict previously produced by :func:array_to_dict (possibly after a JSON round-trip that converted the data field between bytes and base64).

Returns:

np.ndarray — np.ndarray: The reconstructed array with the original dtype and shape.

Raises:


dict_to_hamiltonian [source]

def dict_to_hamiltonian(d: dict[str, Any]) -> Hamiltonian

Decode a wrapper dict back into a Hamiltonian.

Terms are re-added in wire order through the public add_term API, which is the identity on the canonical term form the encoder emits (operators sorted per term, no identities) and preserves the term-dict insertion order.

Parameters:

NameTypeDescription
ddict[str, Any]A wrapper dict previously produced by :func:hamiltonian_to_dict (possibly after a JSON / msgpack round-trip).

Returns:

Hamiltonian — The reconstructed Hamiltonian, equal to the original (same terms in the same order, same coefficient types, same constant, same declared register width).

Raises:


from_dict [source]

def from_dict(envelope: dict[str, Any]) -> Block

Reconstruct a Block from a dict envelope.

Parameters:

NameTypeDescription
envelopedict[str, Any]The dict produced by :func:qamomile.circuit.ir.serialize.encode.to_dict (or an equivalent producer that respects the schema).

Returns:

Block — The reconstructed Block at AFFINE or ANALYZED.

Raises:


is_array_wrapper [source]

def is_array_wrapper(d: Any) -> bool

Return True if d is a numpy-array wrapper dict.

Parameters:

NameTypeDescription
dAnyA value to check. Typically the result of a recursive dict walk from decode.

Returns:

boolTrue when d is a dict carrying the $np_array tag with a True-ish value.


is_hamiltonian_wrapper [source]

def is_hamiltonian_wrapper(d: Any) -> bool

Return True if d is a Hamiltonian wrapper dict.

Parameters:

NameTypeDescription
dAnyA value to check. Typically the result of a recursive dict walk from decode.

Returns:

boolTrue when d is a dict carrying the $hamiltonian tag with a True value.


is_plain_int [source]

def is_plain_int(value: object) -> bool

Return True if value is a Python int but not a bool.

bool is a subclass of int in Python, so isinstance(True, int) is True. This helper distinguishes a genuine integer from a boolean, which matters wherever a boolean must be rejected in an integer slot — for example, validating decoded wire data or a register width.

Parameters:

NameTypeDescription
valueobjectThe value to test.

Returns:

boolTrue when value is an int and not a bool.

Classes

ArrayRuntimeMetadata [source]

class ArrayRuntimeMetadata

Metadata for array literals and explicit element identity tracking.

element_parent_uuids / element_parent_indices are parallel to element_uuids: for each tracked element they record the root array’s UUID and the element’s index within that root (as resolved by :func:resolve_root_qubit_address at trace time). They let an emit pass map a packed element back to the physical qubit registered under the root array’s QubitAddress(root_uuid, index) key even when the element’s own UUID was never registered. The sentinel ("", -1) marks an element with no array parent (a standalone qubit), for which a flat UUID lookup is used.

Constructor
def __init__(
    self,
    const_array: Any = None,
    element_uuids: tuple[str, ...] = (),
    element_logical_ids: tuple[str, ...] = (),
    element_parent_uuids: tuple[str, ...] = (),
    element_parent_indices: tuple[int, ...] = (),
) -> None
Attributes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

BinOp [source]

class BinOp(BinaryOperationBase)

Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: BinOpKind | None = None,
) -> None
Attributes

BinOpKind [source]

class BinOpKind(enum.Enum)
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


CInitOperation [source]

class CInitOperation(Operation)

Initialize the classical values (const, arguments etc)

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

CastMetadata [source]

class CastMetadata

Metadata describing a cast carrier and its underlying qubits.

Constructor
def __init__(
    self,
    source_uuid: str,
    qubit_uuids: tuple[str, ...],
    source_logical_id: str | None = None,
    qubit_logical_ids: tuple[str, ...] = (),
) -> None
Attributes

CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

CompOp [source]

class CompOp(BinaryOperationBase)

Comparison operation (EQ, NEQ, LT, LE, GT, GE).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CompOpKind | None = None,
) -> None
Attributes

CompOpKind [source]

class CompOpKind(enum.Enum)
Attributes

ConcreteControlledU [source]

class ConcreteControlledU(ControlledUOperation)

Controlled-U with concrete (int) number of controls.

Operand layout: [ctrl_0, ..., ctrl_n, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_0', ..., ctrl_n', tgt_0', ..., tgt_m']

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int = 1,
) -> None
Attributes

CondOp [source]

class CondOp(BinaryOperationBase)

Conditional logical operation (AND, OR).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CondOpKind | None = None,
) -> None
Attributes

CondOpKind [source]

class CondOpKind(enum.Enum)
Attributes

DecodeQFixedOperation [source]

class DecodeQFixedOperation(Operation)

Decode measured bits to float (classical operation).

This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.

The decoding formula:

float_value = Σ bit[i] * 2^(int_bits - 1 - i)

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Example:

bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625

operands: [ArrayValue of bits (vec[bit])] results: [Float value]

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

DictRuntimeMetadata [source]

class DictRuntimeMetadata

Metadata for transpile-time bound dict values.

Constructor
def __init__(self, bound_data: tuple[tuple[Any, Any], ...] = ()) -> None
Attributes

DictType [source]

class DictType(ValueType)

Type representing a dictionary mapping keys to values.

Unlike simple types, DictType stores the key and value types, so equality and hashing depend on those types. When key_type and value_type are None, represents a generic Dict type.

Quantum/classical classification is derived from key/value types.

Constructor
def __init__(
    self,
    key_type: ValueType | None = None,
    value_type: ValueType | None = None,
) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ForOperation [source]

class ForOperation(HasNestedOps, Operation)

Represents a for loop operation.

Example:

for i in range(start, stop, step):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    loop_var: str = '',
    loop_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include loop_var_value so cloning/substitution stays consistent.

Without this override, UUIDRemapper would clone every body reference to the loop variable to a fresh UUID, but leave loop_var_value pointing at the un-cloned original — emit-time UUID-keyed lookups for the loop variable would then miss.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

IfOperation [source]

class IfOperation(HasNestedOps, Operation)

Represents an if-else conditional operation.

Example:

if condition:
    true_body
else:
    false_body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    true_operations: list[Operation] = list(),
    false_operations: list[Operation] = list(),
    phi_ops: list[PhiOp] = list(),
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

NotOp [source]

class NotOp(Operation)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

ParamKind [source]

class ParamKind(enum.Enum)

Lifecycle classification for a classical kernel argument.

Values:

RUNTIME_PARAMETER: The argument is intended to be bound at execution time by the backend (or, more generally, by the outer caller in a hybrid loop). It survives the compilation pipeline as a symbolic parameter. COMPILE_TIME_BOUND: The argument was provided as a binding (or via a Python default) and is folded into the IR by resolve_parameter_shapes / partial_eval. No symbolic counterpart remains in the emitted circuit.

Attributes

ParamSlot [source]

class ParamSlot

Metadata for a single classical kernel argument.

A ParamSlot describes one position in the kernel’s classical parameter contract — its declared type, whether it is a runtime parameter or a compile-time-bound value, the Python default (if any), the actually-bound value (when kind is COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are immutable; pipeline passes that need to update a slot must clone via dataclasses.replace.

The slot is identified by name, which matches the kernel’s Python parameter name and the corresponding entry in Block.label_args. A slot’s name MUST never overlap between RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within one Block (this mirrors the project-level bindings / parameters disjointness rule).

Constructor
def __init__(
    self,
    name: str,
    type: 'ValueType',
    kind: ParamKind,
    ndim: int = 0,
    default: Any = None,
    bound_value: Any = None,
    differentiable: bool = False,
) -> None
Attributes

PauliEvolveOp [source]

class PauliEvolveOp(Operation)

Pauli evolution operation: exp(-i * gamma * H).

This operation applies the time evolution of a Pauli Hamiltonian to a quantum register.

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

PhiOp [source]

class PhiOp(Operation)

SSA Phi function: merge point after conditional branch.

This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.

Example:

if condition:
    x = x + 1  # true_value
else:
    x = x + 2  # false_value
# x is now PhiOp(condition, true_value, false_value)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

QFixedMetadata [source]

class QFixedMetadata

Metadata for QFixed carriers.

Constructor
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> None
Attributes

QFixedType [source]

class QFixedType(QuantumTypeMixin, ValueType)

Quantum fixed-point type.

Represents a quantum register encoding a fixed-point number with specified integer and fractional bits.

Constructor
def __init__(
    self,
    integer_bits: int | Value[UIntType] = 0,
    fractional_bits: int | Value[UIntType] = 0,
) -> None
Attributes
Methods
label
def label(self) -> str

QInitOperation [source]

class QInitOperation(Operation)

Initialize the qubit

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

QUIntType [source]

class QUIntType(QuantumTypeMixin, ValueType)

Quantum unsigned integer type.

Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).

Constructor
def __init__(self, width: int | Value[UIntType]) -> None
Attributes
Methods
label
def label(self) -> str

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


ReleaseSliceViewOperation [source]

class ReleaseSliceViewOperation(Operation)

Mark a slice view’s borrow as explicitly returned to its parent.

Emitted by :meth:Vector.__setitem__ when used with a slice index (qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold linearity checker (:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass) that the view referenced in operands[0] no longer owns its covered parent slots, mirroring the frontend’s VectorView.consume(operation_name="slice assignment") borrow release.

Like :class:SliceArrayOperation, this op is a declarative classical-side marker that does not survive into the emit stream: :class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass removes both :class:SliceArrayOperation and :class:ReleaseSliceViewOperation after :class:SliceBorrowCheckPass has observed them. Reaching emit is a compiler-internal invariant violation and is rejected with a RuntimeError from :mod:standard_emit.

Within a control-flow body (ForOperation / WhileOperation / IfOperation), this op only releases view borrows that were created within the same body. Releasing a borrow that the enclosing block has registered (an “outer-snapshot” borrow) is rejected by SliceBorrowCheckPass with SliceBorrowViolationError — the loop-merge semantics of the pass cannot propagate entry deletions out of the body, so the only way to keep the static check consistent is to forbid that pattern.

Example:

``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::

    ReleaseSliceViewOperation(
        operands=[qmc_h_result_view],  # slice_of=qs_value
        results=[],
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ResourceMetadata [source]

class ResourceMetadata

Resource estimation metadata for composite gates.

Gate count fields mirror GateCount categories.

None semantics:

Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.

When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.

Constructor
def __init__(
    self,
    query_complexity: int | None = None,
    t_gates: int | None = None,
    ancilla_qubits: int = 0,
    total_gates: int | None = None,
    single_qubit_gates: int | None = None,
    two_qubit_gates: int | None = None,
    multi_qubit_gates: int | None = None,
    clifford_gates: int | None = None,
    rotation_gates: int | None = None,
    custom_metadata: dict[str, Any] = dict(),
) -> None
Attributes

RuntimeClassicalExpr [source]

class RuntimeClassicalExpr(Operation)

A classical expression known to require runtime evaluation.

Lowered from CompOp / CondOp / NotOp / BinOp by ClassicalLoweringPass when the op’s operand dataflow traces back to a MeasureOperation (i.e. cannot be folded at compile-time, by emit-time loop unrolling, or by compile_time_if_lowering). Backend emit translates this 1:1 to a backend-native runtime expression (e.g. qiskit.circuit.classical.expr.Expr).

Operand convention:

The single-node + unified-kind shape (vs four parallel subclasses) keeps the backend dispatch a single match op.kind instead of four parallel hooks, and makes the IR self-documenting: a single RuntimeClassicalExpr instance signals “runtime evaluation required” regardless of which classical family it came from.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: RuntimeOpKind | None = None,
) -> None
Attributes

RuntimeOpKind [source]

class RuntimeOpKind(enum.Enum)

Unified kind for RuntimeClassicalExpr covering all classical op families that can appear at runtime.

The split between this enum and the per-family BinOpKind / CompOpKind / CondOpKind is intentional: compile-time-foldable classical ops keep their original IR types so the existing fold pipeline (constant_foldcompile_time_if_lowering → emit-time evaluate_classical_predicate) is undisturbed. Only ops identified as runtime-evaluation-only by ClassicalLoweringPass get rewritten to RuntimeClassicalExpr with a member of this enum.

Attributes

ScalarMetadata [source]

class ScalarMetadata

Metadata for scalar constants and symbolic parameters.

Constructor
def __init__(
    self,
    const_value: int | float | bool | None = None,
    parameter_name: str | None = None,
) -> None
Attributes

SliceArrayOperation [source]

class SliceArrayOperation(Operation)

Construct a strided view of an ArrayValue.

The op itself performs no quantum action — it records that the result ArrayValue is a strided view of the operand parent with the given start / step. The result’s slice_of / slice_start / slice_step fields carry the affine map used by the emit-time resolver.

SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL because slicing is pure index selection — no new quantum operation is introduced. The pipeline keeps this op through PartialEvaluationPass (which invokes ConstantFoldingPass(..., strip_slice_ops=False)) so the post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass can use it as a view-declaration marker; once that check has run, StripSliceArrayOpsPass removes every SliceArrayOperation / ReleaseSliceViewOperation so segmentation (:mod:~qamomile.circuit.transpiler.passes.separate) and the downstream emit stage only see a pure quantum-op stream. By the time :mod:~qamomile.circuit.transpiler.passes.separate runs the op has therefore been stripped — reaching emit is a compiler- internal invariant violation.

Example:

``q[1::2]`` on a ``Vector[Qubit]`` emits::

    SliceArrayOperation(
        operands=[q_value, uint_1, uint_2],
        results=[sliced_value],  # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

SymbolicControlledU [source]

class SymbolicControlledU(ControlledUOperation)

Controlled-U with symbolic (Value) number of controls.

Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']

The number of control arguments k is recorded in num_control_args; the default k = 1 corresponds to the historical single-pool form (operands[0] is a Vector[Qubit] / VectorView whose length equals num_controls, or whose control_indices-selected subset does). When k > 1 the control prefix is a heterogeneous sequence of scalar Qubit values and ArrayValues whose total qubit count is num_controls; the emit pass walks them in order to recover the per-physical-qubit control set.

When control_indices is None the entire control prefix is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the prefix args equals num_controls). When non-None, the listed indices select exactly num_controls slots from a single-arg pool to act as controls; combining control_indices with the multi-arg control prefix is rejected at frontend time.

Each control_indices entry is stored as a Value of UIntType regardless of whether the frontend passed an int literal or a UInt handle, so all downstream value-substitution passes see a uniform shape.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: Value = (lambda: Value(type=(UIntType()), name=''))(),
    control_indices: tuple[Value, ...] | None = None,
    num_control_args: int = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

TupleType [source]

class TupleType(ValueType)

Type representing a tuple of values.

Unlike simple types, TupleType stores the types of its elements, so equality and hashing depend on the element types.

Quantum/classical classification is derived from element types: quantum if any element is quantum, classical if all are classical.

Constructor
def __init__(self, element_types: tuple[ValueType, ...]) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

ValueMetadata [source]

class ValueMetadata

Typed metadata owned by the compiler/runtime.

Constructor
def __init__(
    self,
    scalar: ScalarMetadata | None = None,
    cast: CastMetadata | None = None,
    qfixed: QFixedMetadata | None = None,
    array_runtime: ArrayRuntimeMetadata | None = None,
    dict_runtime: DictRuntimeMetadata | None = None,
) -> None
Attributes

ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

WhileOperation [source]

class WhileOperation(HasNestedOps, Operation)

Represents a while loop operation.

Only measurement-backed conditions are supported: the condition must be a Bit value produced by qmc.measure(). Non-measurement conditions (classical variables, constants, comparisons) are rejected by ValidateWhileContractPass before reaching backend emit.

Example::

bit = qmc.measure(q)
while bit:
    q = qmc.h(q)
    bit = qmc.measure(q)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    operations: list[Operation] = list(),
    max_iterations: int | None = None,
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

qamomile.circuit.ir.serialize.encode

IR → intermediate dict encoder.

Walks a Block (AFFINE or ANALYZED) and produces the dict shape documented in :mod:qamomile.circuit.ir.serialize.schema. Values are deduplicated into value_table and referenced elsewhere by UUID.

Every encoder branch is dispatched through a hard-coded table keyed on the runtime class; there is no dynamic resolution, no getattr on user data, and no importlib use. The decoder mirrors this discipline (see :mod:qamomile.circuit.ir.serialize.decode).

Overview

FunctionDescription
array_to_dictEncode a numpy ndarray into the wrapper dict.
hamiltonian_to_dictEncode a Hamiltonian into the wrapper dict.
is_plain_intReturn True if value is a Python int but not a bool.
to_dictEncode a Block into the intermediate dict envelope.
ClassDescription
ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
ArrayValueAn array of typed IR values.
BinOpBinary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
BitTypeType representing a classical bit.
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
BlockTypeType representing a block/function reference.
CInitOperationInitialize the classical values (const, arguments etc)
CallBlockOperation
CastMetadataMetadata describing a cast carrier and its underlying qubits.
CastOperationType cast operation for creating aliases over the same quantum resources.
CompOpComparison operation (EQ, NEQ, LT, LE, GT, GE).
ConcreteControlledUControlled-U with concrete (int) number of controls.
CondOpConditional logical operation (AND, OR).
DecodeQFixedOperationDecode measured bits to float (classical operation).
DictRuntimeMetadataMetadata for transpile-time bound dict values.
DictTypeType representing a dictionary mapping keys to values.
DictValueA dictionary value stored as stable ordered entries.
FloatTypeType representing a floating-point number.
ForOperationRepresents a for loop operation.
HamiltonianRepresents a quantum Hamiltonian as a sum of Pauli operator products.
IfOperationRepresents an if-else conditional operation.
NotOp
ObservableTypeType representing a Hamiltonian observable parameter.
ParamSlotMetadata for a single classical kernel argument.
PauliEvolveOpPauli evolution operation: exp(-i * gamma * H).
PhiOpSSA Phi function: merge point after conditional branch.
QFixedMetadataMetadata for QFixed carriers.
QFixedTypeQuantum fixed-point type.
QInitOperationInitialize the qubit
QUIntTypeQuantum unsigned integer type.
QubitTypeType representing a quantum bit (qubit).
ReleaseSliceViewOperationMark a slice view’s borrow as explicitly returned to its parent.
ResourceMetadataResource estimation metadata for composite gates.
RuntimeClassicalExprA classical expression known to require runtime evaluation.
ScalarMetadataMetadata for scalar constants and symbolic parameters.
SliceArrayOperationConstruct a strided view of an ArrayValue.
SymbolicControlledUControlled-U with symbolic (Value) number of controls.
TupleTypeType representing a tuple of values.
TupleValueA tuple of IR values for structured data.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.
ValueMetadataTyped metadata owned by the compiler/runtime.
ValueTypeBase class for all value types in the IR.
WhileOperationRepresents a while loop operation.

Constants

Functions

array_to_dict [source]

def array_to_dict(arr: np.ndarray) -> dict[str, Any]

Encode a numpy ndarray into the wrapper dict.

Parameters:

NameTypeDescription
arrnp.ndarraySource array. arr.dtype.name must be in the allow-list (:data:_ALLOWED_DTYPES).

Returns:

dict[str, Any] — dict[str, Any]: A wrapper dict with $np_array, dtype, shape (list[int]), and data (raw bytes from ndarray.tobytes()). The wire encoders are responsible for any further bytes ⇄ text conversion at format boundaries.

Raises:


hamiltonian_to_dict [source]

def hamiltonian_to_dict(h: Hamiltonian) -> dict[str, Any]

Encode a Hamiltonian into the wrapper dict.

Terms are emitted in the Hamiltonian’s own term-dict iteration order; each term is a [operators, coefficient] pair where operators is a list of [pauli_name, qubit_index] entries.

Parameters:

NameTypeDescription
hHamiltonianThe Hamiltonian to encode. Term coefficients and the constant must be int, float, or complex, or a numpy scalar of one of those kinds (coerced via .item()).

Returns:

dict[str, Any] — dict[str, Any]: A wrapper dict with $hamiltonian, terms, constant, and num_qubits (the declared register width passed to the constructor, or None).

Raises:


is_plain_int [source]

def is_plain_int(value: object) -> bool

Return True if value is a Python int but not a bool.

bool is a subclass of int in Python, so isinstance(True, int) is True. This helper distinguishes a genuine integer from a boolean, which matters wherever a boolean must be rejected in an integer slot — for example, validating decoded wire data or a register width.

Parameters:

NameTypeDescription
valueobjectThe value to test.

Returns:

boolTrue when value is an int and not a bool.


to_dict [source]

def to_dict(block: Block) -> dict[str, Any]

Encode a Block into the intermediate dict envelope.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

dict[str, Any] — dict[str, Any]: {"schema_version": SCHEMA_VERSION, "block": <block dict>} ready to be passed to a wire-format encoder (JSON / msgpack).

Raises:

Classes

ArrayRuntimeMetadata [source]

class ArrayRuntimeMetadata

Metadata for array literals and explicit element identity tracking.

element_parent_uuids / element_parent_indices are parallel to element_uuids: for each tracked element they record the root array’s UUID and the element’s index within that root (as resolved by :func:resolve_root_qubit_address at trace time). They let an emit pass map a packed element back to the physical qubit registered under the root array’s QubitAddress(root_uuid, index) key even when the element’s own UUID was never registered. The sentinel ("", -1) marks an element with no array parent (a standalone qubit), for which a flat UUID lookup is used.

Constructor
def __init__(
    self,
    const_array: Any = None,
    element_uuids: tuple[str, ...] = (),
    element_logical_ids: tuple[str, ...] = (),
    element_parent_uuids: tuple[str, ...] = (),
    element_parent_indices: tuple[int, ...] = (),
) -> None
Attributes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

BinOp [source]

class BinOp(BinaryOperationBase)

Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: BinOpKind | None = None,
) -> None
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


CInitOperation [source]

class CInitOperation(Operation)

Initialize the classical values (const, arguments etc)

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

CallBlockOperation [source]

class CallBlockOperation(Operation)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    block: Block | None = None,
) -> None
Attributes
Methods
is_self_reference_to
def is_self_reference_to(self, block: Block) -> bool

Return True if this call points to the given block (self-ref).


CastMetadata [source]

class CastMetadata

Metadata describing a cast carrier and its underlying qubits.

Constructor
def __init__(
    self,
    source_uuid: str,
    qubit_uuids: tuple[str, ...],
    source_logical_id: str | None = None,
    qubit_logical_ids: tuple[str, ...] = (),
) -> None
Attributes

CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

CompOp [source]

class CompOp(BinaryOperationBase)

Comparison operation (EQ, NEQ, LT, LE, GT, GE).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CompOpKind | None = None,
) -> None
Attributes

ConcreteControlledU [source]

class ConcreteControlledU(ControlledUOperation)

Controlled-U with concrete (int) number of controls.

Operand layout: [ctrl_0, ..., ctrl_n, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_0', ..., ctrl_n', tgt_0', ..., tgt_m']

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int = 1,
) -> None
Attributes

CondOp [source]

class CondOp(BinaryOperationBase)

Conditional logical operation (AND, OR).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: CondOpKind | None = None,
) -> None
Attributes

DecodeQFixedOperation [source]

class DecodeQFixedOperation(Operation)

Decode measured bits to float (classical operation).

This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.

The decoding formula:

float_value = Σ bit[i] * 2^(int_bits - 1 - i)

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

Example:

bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625

operands: [ArrayValue of bits (vec[bit])] results: [Float value]

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_bits: int = 0,
    int_bits: int = 0,
) -> None
Attributes

DictRuntimeMetadata [source]

class DictRuntimeMetadata

Metadata for transpile-time bound dict values.

Constructor
def __init__(self, bound_data: tuple[tuple[Any, Any], ...] = ()) -> None
Attributes

DictType [source]

class DictType(ValueType)

Type representing a dictionary mapping keys to values.

Unlike simple types, DictType stores the key and value types, so equality and hashing depend on those types. When key_type and value_type are None, represents a generic Dict type.

Quantum/classical classification is derived from key/value types.

Constructor
def __init__(
    self,
    key_type: ValueType | None = None,
    value_type: ValueType | None = None,
) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ForOperation [source]

class ForOperation(HasNestedOps, Operation)

Represents a for loop operation.

Example:

for i in range(start, stop, step):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    loop_var: str = '',
    loop_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include loop_var_value so cloning/substitution stays consistent.

Without this override, UUIDRemapper would clone every body reference to the loop variable to a fresh UUID, but leave loop_var_value pointing at the un-cloned original — emit-time UUID-keyed lookups for the loop variable would then miss.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Hamiltonian [source]

class Hamiltonian

Represents a quantum Hamiltonian as a sum of Pauli operator products.

The Hamiltonian is stored as a dictionary where keys are tuples of PauliOperators and values are their corresponding coefficients.

Example:

>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.Z, 2),), 1.0)
>>> print(H.terms)
{(X0, Y1): 0.5, (Z2,): 1.0}
Constructor
def __init__(self, num_qubits: int | None = None) -> None
Attributes
Methods
add_term
def add_term(self, operators: tuple[PauliOperator, ...], coeff: float | complex)

Adds a term to the Hamiltonian.

This method adds a product of Pauli operators with a given coefficient to the Hamiltonian. If the term already exists, the coefficients are summed.

Parameters:

NameTypeDescription
operatorsTuple[PauliOperator, ...]A tuple of PauliOperators representing the term.
coeffUnion[float, complex]The coefficient of the term.

Example:

>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5j)
>>> print(H.terms)
{(X0, Y1): (0.5+0.5j)}
copy
def copy(self) -> Hamiltonian

Return an independent copy sharing no mutable state with self.

Produces a new Hamiltonian with the same terms, constant, and declared _num_qubits. The underlying _terms dict is fresh, so subsequent add_term / constant mutations on either instance do not affect the other. PauliOperator instances inside the term tuples are reused — they are dataclass(frozen=True) values and safely shared.

Returns:

Hamiltonian — A shallow-cloned Hamiltonian instance.

Example:

>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.Z, 0),), 1.0)
>>> H2 = H.copy()
>>> H2.add_term((PauliOperator(Pauli.X, 1),), 0.5)
>>> H.num_qubits  # unchanged by H2's mutation
1
identity
@classmethod
def identity(
    cls,
    coeff: float | complex = 1.0,
    num_qubits: int | None = None,
) -> Hamiltonian

Create a scalar times identity Hamiltonian.

remap_qubits
def remap_qubits(self, qubit_map: dict[int, int]) -> Hamiltonian

Remap qubit indices according to the given mapping.

This is used to translate Pauli indices (logical indices within an expval call) to physical qubit indices in the actual quantum circuit.

Parameters:

NameTypeDescription
qubit_mapdict[int, int]Mapping from logical index to physical index. e.g., {0: 5, 1: 3} maps logical index 0 → physical qubit 5

Returns:

Hamiltonian — New Hamiltonian with remapped qubit indices.

single_pauli
@classmethod
def single_pauli(cls, pauli: Pauli, index: int, coeff: float | complex = 1.0) -> Hamiltonian

Create a single Pauli term Hamiltonian.

to_latex
def to_latex(self) -> str

Converts the Hamiltonian to a LaTeX representation.

This function does not add constant term when we show the Hamiltonian. This function does not add $ symbols.

Returns:

str — A LaTeX representation of the Hamiltonian.

import qamomile.core.operator as qm_o
import IPython.display as ipd

h = qm_o.Hamiltonian()
h += -qm_o.X(0) * qm_o.Y(1) - 2.0 * qm_o.Z(0) * qm_o.Z(1)

# Show the Hamiltonian in LaTeX at Jupyter Notebook
ipd.display(ipd.Latex("$" + h.to_latex() + "$"))
to_numpy
def to_numpy(self) -> np.ndarray

Convert the Hamiltonian to a dense NumPy matrix.

Qubit 0 is mapped to the least-significant bit of computational-basis indices, matching :meth:qamomile.linalg.HermitianMatrix.to_hamiltonian. The returned array has shape (2**n, 2**n) where n is :attr:num_qubits.

zero
@classmethod
def zero(cls, num_qubits: int | None = None) -> Hamiltonian

Create a zero Hamiltonian.


IfOperation [source]

class IfOperation(HasNestedOps, Operation)

Represents an if-else conditional operation.

Example:

if condition:
    true_body
else:
    false_body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    true_operations: list[Operation] = list(),
    false_operations: list[Operation] = list(),
    phi_ops: list[PhiOp] = list(),
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

NotOp [source]

class NotOp(Operation)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

ParamSlot [source]

class ParamSlot

Metadata for a single classical kernel argument.

A ParamSlot describes one position in the kernel’s classical parameter contract — its declared type, whether it is a runtime parameter or a compile-time-bound value, the Python default (if any), the actually-bound value (when kind is COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are immutable; pipeline passes that need to update a slot must clone via dataclasses.replace.

The slot is identified by name, which matches the kernel’s Python parameter name and the corresponding entry in Block.label_args. A slot’s name MUST never overlap between RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within one Block (this mirrors the project-level bindings / parameters disjointness rule).

Constructor
def __init__(
    self,
    name: str,
    type: 'ValueType',
    kind: ParamKind,
    ndim: int = 0,
    default: Any = None,
    bound_value: Any = None,
    differentiable: bool = False,
) -> None
Attributes

PauliEvolveOp [source]

class PauliEvolveOp(Operation)

Pauli evolution operation: exp(-i * gamma * H).

This operation applies the time evolution of a Pauli Hamiltonian to a quantum register.

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

PhiOp [source]

class PhiOp(Operation)

SSA Phi function: merge point after conditional branch.

This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.

Example:

if condition:
    x = x + 1  # true_value
else:
    x = x + 2  # false_value
# x is now PhiOp(condition, true_value, false_value)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

QFixedMetadata [source]

class QFixedMetadata

Metadata for QFixed carriers.

Constructor
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> None
Attributes

QFixedType [source]

class QFixedType(QuantumTypeMixin, ValueType)

Quantum fixed-point type.

Represents a quantum register encoding a fixed-point number with specified integer and fractional bits.

Constructor
def __init__(
    self,
    integer_bits: int | Value[UIntType] = 0,
    fractional_bits: int | Value[UIntType] = 0,
) -> None
Attributes
Methods
label
def label(self) -> str

QInitOperation [source]

class QInitOperation(Operation)

Initialize the qubit

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

QUIntType [source]

class QUIntType(QuantumTypeMixin, ValueType)

Quantum unsigned integer type.

Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).

Constructor
def __init__(self, width: int | Value[UIntType]) -> None
Attributes
Methods
label
def label(self) -> str

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


ReleaseSliceViewOperation [source]

class ReleaseSliceViewOperation(Operation)

Mark a slice view’s borrow as explicitly returned to its parent.

Emitted by :meth:Vector.__setitem__ when used with a slice index (qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold linearity checker (:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass) that the view referenced in operands[0] no longer owns its covered parent slots, mirroring the frontend’s VectorView.consume(operation_name="slice assignment") borrow release.

Like :class:SliceArrayOperation, this op is a declarative classical-side marker that does not survive into the emit stream: :class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass removes both :class:SliceArrayOperation and :class:ReleaseSliceViewOperation after :class:SliceBorrowCheckPass has observed them. Reaching emit is a compiler-internal invariant violation and is rejected with a RuntimeError from :mod:standard_emit.

Within a control-flow body (ForOperation / WhileOperation / IfOperation), this op only releases view borrows that were created within the same body. Releasing a borrow that the enclosing block has registered (an “outer-snapshot” borrow) is rejected by SliceBorrowCheckPass with SliceBorrowViolationError — the loop-merge semantics of the pass cannot propagate entry deletions out of the body, so the only way to keep the static check consistent is to forbid that pattern.

Example:

``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::

    ReleaseSliceViewOperation(
        operands=[qmc_h_result_view],  # slice_of=qs_value
        results=[],
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

ResourceMetadata [source]

class ResourceMetadata

Resource estimation metadata for composite gates.

Gate count fields mirror GateCount categories.

None semantics:

Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.

When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.

Constructor
def __init__(
    self,
    query_complexity: int | None = None,
    t_gates: int | None = None,
    ancilla_qubits: int = 0,
    total_gates: int | None = None,
    single_qubit_gates: int | None = None,
    two_qubit_gates: int | None = None,
    multi_qubit_gates: int | None = None,
    clifford_gates: int | None = None,
    rotation_gates: int | None = None,
    custom_metadata: dict[str, Any] = dict(),
) -> None
Attributes

RuntimeClassicalExpr [source]

class RuntimeClassicalExpr(Operation)

A classical expression known to require runtime evaluation.

Lowered from CompOp / CondOp / NotOp / BinOp by ClassicalLoweringPass when the op’s operand dataflow traces back to a MeasureOperation (i.e. cannot be folded at compile-time, by emit-time loop unrolling, or by compile_time_if_lowering). Backend emit translates this 1:1 to a backend-native runtime expression (e.g. qiskit.circuit.classical.expr.Expr).

Operand convention:

The single-node + unified-kind shape (vs four parallel subclasses) keeps the backend dispatch a single match op.kind instead of four parallel hooks, and makes the IR self-documenting: a single RuntimeClassicalExpr instance signals “runtime evaluation required” regardless of which classical family it came from.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: RuntimeOpKind | None = None,
) -> None
Attributes

ScalarMetadata [source]

class ScalarMetadata

Metadata for scalar constants and symbolic parameters.

Constructor
def __init__(
    self,
    const_value: int | float | bool | None = None,
    parameter_name: str | None = None,
) -> None
Attributes

SliceArrayOperation [source]

class SliceArrayOperation(Operation)

Construct a strided view of an ArrayValue.

The op itself performs no quantum action — it records that the result ArrayValue is a strided view of the operand parent with the given start / step. The result’s slice_of / slice_start / slice_step fields carry the affine map used by the emit-time resolver.

SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL because slicing is pure index selection — no new quantum operation is introduced. The pipeline keeps this op through PartialEvaluationPass (which invokes ConstantFoldingPass(..., strip_slice_ops=False)) so the post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass can use it as a view-declaration marker; once that check has run, StripSliceArrayOpsPass removes every SliceArrayOperation / ReleaseSliceViewOperation so segmentation (:mod:~qamomile.circuit.transpiler.passes.separate) and the downstream emit stage only see a pure quantum-op stream. By the time :mod:~qamomile.circuit.transpiler.passes.separate runs the op has therefore been stripped — reaching emit is a compiler- internal invariant violation.

Example:

``q[1::2]`` on a ``Vector[Qubit]`` emits::

    SliceArrayOperation(
        operands=[q_value, uint_1, uint_2],
        results=[sliced_value],  # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
    )
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

SymbolicControlledU [source]

class SymbolicControlledU(ControlledUOperation)

Controlled-U with symbolic (Value) number of controls.

Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']

The number of control arguments k is recorded in num_control_args; the default k = 1 corresponds to the historical single-pool form (operands[0] is a Vector[Qubit] / VectorView whose length equals num_controls, or whose control_indices-selected subset does). When k > 1 the control prefix is a heterogeneous sequence of scalar Qubit values and ArrayValues whose total qubit count is num_controls; the emit pass walks them in order to recover the per-physical-qubit control set.

When control_indices is None the entire control prefix is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the prefix args equals num_controls). When non-None, the listed indices select exactly num_controls slots from a single-arg pool to act as controls; combining control_indices with the multi-arg control prefix is rejected at frontend time.

Each control_indices entry is stored as a Value of UIntType regardless of whether the frontend passed an int literal or a UInt handle, so all downstream value-substitution passes see a uniform shape.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: Value = (lambda: Value(type=(UIntType()), name=''))(),
    control_indices: tuple[Value, ...] | None = None,
    num_control_args: int = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

TupleType [source]

class TupleType(ValueType)

Type representing a tuple of values.

Unlike simple types, TupleType stores the types of its elements, so equality and hashing depend on the element types.

Quantum/classical classification is derived from element types: quantum if any element is quantum, classical if all are classical.

Constructor
def __init__(self, element_types: tuple[ValueType, ...]) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

ValueMetadata [source]

class ValueMetadata

Typed metadata owned by the compiler/runtime.

Constructor
def __init__(
    self,
    scalar: ScalarMetadata | None = None,
    cast: CastMetadata | None = None,
    qfixed: QFixedMetadata | None = None,
    array_runtime: ArrayRuntimeMetadata | None = None,
    dict_runtime: DictRuntimeMetadata | None = None,
) -> None
Attributes

ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

WhileOperation [source]

class WhileOperation(HasNestedOps, Operation)

Represents a while loop operation.

Only measurement-backed conditions are supported: the condition must be a Bit value produced by qmc.measure(). Non-measurement conditions (classical variables, constants, comparisons) are rejected by ValidateWhileContractPass before reaching backend emit.

Example::

bit = qmc.measure(q)
while bit:
    q = qmc.h(q)
    bit = qmc.measure(q)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    operations: list[Operation] = list(),
    max_iterations: int | None = None,
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

qamomile.circuit.ir.serialize.hamiltonian_io

Hamiltonian wrapper used by both JSON and msgpack pipelines.

ParamSlot.bound_value and ArrayRuntimeMetadata.const_array may carry :class:qamomile.observable.Hamiltonian objects — the bound values of Observable kernel parameters (e.g. the documented Trotter pattern kernel.build(Hs=[1.2 * Z(0), 0.8 * X(0)], ...)). This module defines the tagged-dict wire representation for those payloads: a sum of Pauli products plus a constant offset and the declared qubit register width.

The wrapper is JSON-native (numbers, strings, lists, dicts — no raw bytes), so both wire formats carry it unchanged.

Two fidelity properties are load-bearing:

Security: decoding never resolves classes dynamically. Pauli names are mapped through an explicit allow-map, and only Pauli / PauliOperator / Hamiltonian instances are constructed.

Overview

FunctionDescription
dict_to_hamiltonianDecode a wrapper dict back into a Hamiltonian.
hamiltonian_to_dictEncode a Hamiltonian into the wrapper dict.
is_hamiltonian_wrapperReturn True if d is a Hamiltonian wrapper dict.
is_plain_intReturn True if value is a Python int but not a bool.
ClassDescription
HamiltonianRepresents a quantum Hamiltonian as a sum of Pauli operator products.
PauliEnum class for Pauli operators.
PauliOperatorRepresents a single Pauli operator acting on a specific qubit.

Functions

dict_to_hamiltonian [source]

def dict_to_hamiltonian(d: dict[str, Any]) -> Hamiltonian

Decode a wrapper dict back into a Hamiltonian.

Terms are re-added in wire order through the public add_term API, which is the identity on the canonical term form the encoder emits (operators sorted per term, no identities) and preserves the term-dict insertion order.

Parameters:

NameTypeDescription
ddict[str, Any]A wrapper dict previously produced by :func:hamiltonian_to_dict (possibly after a JSON / msgpack round-trip).

Returns:

Hamiltonian — The reconstructed Hamiltonian, equal to the original (same terms in the same order, same coefficient types, same constant, same declared register width).

Raises:


hamiltonian_to_dict [source]

def hamiltonian_to_dict(h: Hamiltonian) -> dict[str, Any]

Encode a Hamiltonian into the wrapper dict.

Terms are emitted in the Hamiltonian’s own term-dict iteration order; each term is a [operators, coefficient] pair where operators is a list of [pauli_name, qubit_index] entries.

Parameters:

NameTypeDescription
hHamiltonianThe Hamiltonian to encode. Term coefficients and the constant must be int, float, or complex, or a numpy scalar of one of those kinds (coerced via .item()).

Returns:

dict[str, Any] — dict[str, Any]: A wrapper dict with $hamiltonian, terms, constant, and num_qubits (the declared register width passed to the constructor, or None).

Raises:


is_hamiltonian_wrapper [source]

def is_hamiltonian_wrapper(d: Any) -> bool

Return True if d is a Hamiltonian wrapper dict.

Parameters:

NameTypeDescription
dAnyA value to check. Typically the result of a recursive dict walk from decode.

Returns:

boolTrue when d is a dict carrying the $hamiltonian tag with a True value.


is_plain_int [source]

def is_plain_int(value: object) -> bool

Return True if value is a Python int but not a bool.

bool is a subclass of int in Python, so isinstance(True, int) is True. This helper distinguishes a genuine integer from a boolean, which matters wherever a boolean must be rejected in an integer slot — for example, validating decoded wire data or a register width.

Parameters:

NameTypeDescription
valueobjectThe value to test.

Returns:

boolTrue when value is an int and not a bool.

Classes

Hamiltonian [source]

class Hamiltonian

Represents a quantum Hamiltonian as a sum of Pauli operator products.

The Hamiltonian is stored as a dictionary where keys are tuples of PauliOperators and values are their corresponding coefficients.

Example:

>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.Z, 2),), 1.0)
>>> print(H.terms)
{(X0, Y1): 0.5, (Z2,): 1.0}
Constructor
def __init__(self, num_qubits: int | None = None) -> None
Attributes
Methods
add_term
def add_term(self, operators: tuple[PauliOperator, ...], coeff: float | complex)

Adds a term to the Hamiltonian.

This method adds a product of Pauli operators with a given coefficient to the Hamiltonian. If the term already exists, the coefficients are summed.

Parameters:

NameTypeDescription
operatorsTuple[PauliOperator, ...]A tuple of PauliOperators representing the term.
coeffUnion[float, complex]The coefficient of the term.

Example:

>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5j)
>>> print(H.terms)
{(X0, Y1): (0.5+0.5j)}
copy
def copy(self) -> Hamiltonian

Return an independent copy sharing no mutable state with self.

Produces a new Hamiltonian with the same terms, constant, and declared _num_qubits. The underlying _terms dict is fresh, so subsequent add_term / constant mutations on either instance do not affect the other. PauliOperator instances inside the term tuples are reused — they are dataclass(frozen=True) values and safely shared.

Returns:

Hamiltonian — A shallow-cloned Hamiltonian instance.

Example:

>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.Z, 0),), 1.0)
>>> H2 = H.copy()
>>> H2.add_term((PauliOperator(Pauli.X, 1),), 0.5)
>>> H.num_qubits  # unchanged by H2's mutation
1
identity
@classmethod
def identity(
    cls,
    coeff: float | complex = 1.0,
    num_qubits: int | None = None,
) -> Hamiltonian

Create a scalar times identity Hamiltonian.

remap_qubits
def remap_qubits(self, qubit_map: dict[int, int]) -> Hamiltonian

Remap qubit indices according to the given mapping.

This is used to translate Pauli indices (logical indices within an expval call) to physical qubit indices in the actual quantum circuit.

Parameters:

NameTypeDescription
qubit_mapdict[int, int]Mapping from logical index to physical index. e.g., {0: 5, 1: 3} maps logical index 0 → physical qubit 5

Returns:

Hamiltonian — New Hamiltonian with remapped qubit indices.

single_pauli
@classmethod
def single_pauli(cls, pauli: Pauli, index: int, coeff: float | complex = 1.0) -> Hamiltonian

Create a single Pauli term Hamiltonian.

to_latex
def to_latex(self) -> str

Converts the Hamiltonian to a LaTeX representation.

This function does not add constant term when we show the Hamiltonian. This function does not add $ symbols.

Returns:

str — A LaTeX representation of the Hamiltonian.

import qamomile.core.operator as qm_o
import IPython.display as ipd

h = qm_o.Hamiltonian()
h += -qm_o.X(0) * qm_o.Y(1) - 2.0 * qm_o.Z(0) * qm_o.Z(1)

# Show the Hamiltonian in LaTeX at Jupyter Notebook
ipd.display(ipd.Latex("$" + h.to_latex() + "$"))
to_numpy
def to_numpy(self) -> np.ndarray

Convert the Hamiltonian to a dense NumPy matrix.

Qubit 0 is mapped to the least-significant bit of computational-basis indices, matching :meth:qamomile.linalg.HermitianMatrix.to_hamiltonian. The returned array has shape (2**n, 2**n) where n is :attr:num_qubits.

zero
@classmethod
def zero(cls, num_qubits: int | None = None) -> Hamiltonian

Create a zero Hamiltonian.


Pauli [source]

class Pauli(enum.Enum)

Enum class for Pauli operators.

Attributes

PauliOperator [source]

class PauliOperator

Represents a single Pauli operator acting on a specific qubit.

Frozen so that Hamiltonian.copy() can share term operator references across the original and the copy without risk of one side mutating an operator the other still observes. None of the existing callers mutate pauli or index after construction, so freezing is a no-op behaviourally but makes the immutability claim that Hamiltonian.copy()'s docstring relies on real.

Example:

>>> X0 = PauliOperator(Pauli.X, 0)
>>> print(X0)
X0
Constructor
def __init__(self, pauli: Pauli, index: int) -> None
Attributes

qamomile.circuit.ir.serialize.json_io

JSON wire format for the IR serialization pipeline.

JSON has no native bytes type, so this module is responsible for converting raw bytes (used by numpy wrapper data fields) to / from base64 strings at the wire boundary. Apart from that, the JSON output is a faithful rendering of the intermediate dict produced by :mod:qamomile.circuit.ir.serialize.encode.

A small sentinel field ($bytes_b64) distinguishes a base64-string representation of bytes from a plain JSON string, so the decoder can restore the original bytes value losslessly.

Overview

FunctionDescription
dump_jsonEncode block into a UTF-8 JSON byte string.
from_dictReconstruct a Block from a dict envelope.
load_jsonDecode a JSON document back into a Block.
to_dictEncode a Block into the intermediate dict envelope.
ClassDescription
BlockUnified block representation for all pipeline stages.

Functions

dump_json [source]

def dump_json(block: Block) -> bytes

Encode block into a UTF-8 JSON byte string.

The serialized form contains the schema_version envelope from :func:qamomile.circuit.ir.serialize.encode.to_dict plus base64-wrapped bytes payloads (numpy array data, raw bytes bound values) so the output stays JSON-text-safe.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be AFFINE or ANALYZED.

Returns:

bytes — A UTF-8 encoded JSON document.

Raises:


from_dict [source]

def from_dict(envelope: dict[str, Any]) -> Block

Reconstruct a Block from a dict envelope.

Parameters:

NameTypeDescription
envelopedict[str, Any]The dict produced by :func:qamomile.circuit.ir.serialize.encode.to_dict (or an equivalent producer that respects the schema).

Returns:

Block — The reconstructed Block at AFFINE or ANALYZED.

Raises:


load_json [source]

def load_json(payload: bytes | str) -> Block

Decode a JSON document back into a Block.

Parameters:

NameTypeDescription
payloadbytes | strJSON bytes (UTF-8) or a JSON string.

Returns:

Block — The reconstructed Block.

Raises:


to_dict [source]

def to_dict(block: Block) -> dict[str, Any]

Encode a Block into the intermediate dict envelope.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

dict[str, Any] — dict[str, Any]: {"schema_version": SCHEMA_VERSION, "block": <block dict>} ready to be passed to a wire-format encoder (JSON / msgpack).

Raises:

Classes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


qamomile.circuit.ir.serialize.msgpack_io

msgpack wire format for the IR serialization pipeline.

msgpack carries bytes natively (bin type), so the numpy wrapper’s data field passes through unchanged. This module is mostly a thin wrapper around :func:qamomile.circuit.ir.serialize.encode.to_dict / :func:qamomile.circuit.ir.serialize.decode.from_dict, with safe unpack defaults.

Overview

FunctionDescription
dump_msgpackEncode block into a msgpack byte string.
from_dictReconstruct a Block from a dict envelope.
load_msgpackDecode a msgpack payload back into a Block.
to_dictEncode a Block into the intermediate dict envelope.
ClassDescription
BlockUnified block representation for all pipeline stages.

Functions

dump_msgpack [source]

def dump_msgpack(block: Block) -> bytes

Encode block into a msgpack byte string.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be AFFINE or ANALYZED.

Returns:

bytes — A msgpack-encoded payload. Compatible with the standard msgpack package; no extension types are used.

Raises:


from_dict [source]

def from_dict(envelope: dict[str, Any]) -> Block

Reconstruct a Block from a dict envelope.

Parameters:

NameTypeDescription
envelopedict[str, Any]The dict produced by :func:qamomile.circuit.ir.serialize.encode.to_dict (or an equivalent producer that respects the schema).

Returns:

Block — The reconstructed Block at AFFINE or ANALYZED.

Raises:


load_msgpack [source]

def load_msgpack(payload: bytes) -> Block

Decode a msgpack payload back into a Block.

The unpacker is configured with raw=False so strings come back as Python str, and strict_map_key=False so non-string map keys (numeric, etc.) are accepted (qamomile’s schema only uses string keys today, but this keeps the loader robust to future schema extensions).

Parameters:

NameTypeDescription
payloadbytesA msgpack-encoded payload produced by :func:dump_msgpack or an equivalent encoder.

Returns:

Block — The reconstructed Block.

Raises:


to_dict [source]

def to_dict(block: Block) -> dict[str, Any]

Encode a Block into the intermediate dict envelope.

Parameters:

NameTypeDescription
blockBlockThe block to encode. Must be at BlockKind.AFFINE or BlockKind.ANALYZED.

Returns:

dict[str, Any] — dict[str, Any]: {"schema_version": SCHEMA_VERSION, "block": <block dict>} ready to be passed to a wire-format encoder (JSON / msgpack).

Raises:

Classes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
    param_slots: tuple[ParamSlot, ...] = tuple(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


qamomile.circuit.ir.serialize.numpy_io

numpy ndarray wrapper used by both JSON and msgpack pipelines.

The wrapper is a tagged dict that both wire formats produce and consume in identical shape; only the encoding of the "data" field differs at the wire boundary (base64 string in JSON, native bin in msgpack).

Allowed dtypes are restricted to an explicit allow-list. The decoder rejects any dtype string outside the list, so a malicious payload cannot coax numpy into instantiating an unexpected dtype object.

Overview

FunctionDescription
array_to_dictEncode a numpy ndarray into the wrapper dict.
dict_to_arrayDecode a wrapper dict back into a numpy ndarray.
is_array_wrapperReturn True if d is a numpy-array wrapper dict.
is_plain_intReturn True if value is a Python int but not a bool.

Functions

array_to_dict [source]

def array_to_dict(arr: np.ndarray) -> dict[str, Any]

Encode a numpy ndarray into the wrapper dict.

Parameters:

NameTypeDescription
arrnp.ndarraySource array. arr.dtype.name must be in the allow-list (:data:_ALLOWED_DTYPES).

Returns:

dict[str, Any] — dict[str, Any]: A wrapper dict with $np_array, dtype, shape (list[int]), and data (raw bytes from ndarray.tobytes()). The wire encoders are responsible for any further bytes ⇄ text conversion at format boundaries.

Raises:


dict_to_array [source]

def dict_to_array(d: dict[str, Any]) -> np.ndarray

Decode a wrapper dict back into a numpy ndarray.

Parameters:

NameTypeDescription
ddict[str, Any]A wrapper dict previously produced by :func:array_to_dict (possibly after a JSON round-trip that converted the data field between bytes and base64).

Returns:

np.ndarray — np.ndarray: The reconstructed array with the original dtype and shape.

Raises:


is_array_wrapper [source]

def is_array_wrapper(d: Any) -> bool

Return True if d is a numpy-array wrapper dict.

Parameters:

NameTypeDescription
dAnyA value to check. Typically the result of a recursive dict walk from decode.

Returns:

boolTrue when d is a dict carrying the $np_array tag with a True-ish value.


is_plain_int [source]

def is_plain_int(value: object) -> bool

Return True if value is a Python int but not a bool.

bool is a subclass of int in Python, so isinstance(True, int) is True. This helper distinguishes a genuine integer from a boolean, which matters wherever a boolean must be rejected in an integer slot — for example, validating decoded wire data or a register width.

Parameters:

NameTypeDescription
valueobjectThe value to test.

Returns:

boolTrue when value is an int and not a bool.


qamomile.circuit.ir.serialize.schema

Intermediate dict schema for IR serialization.

This module defines SCHEMA_VERSION and the shape of the intermediate Python dict that encode produces and decode consumes. The wire encoders (json_io, msgpack_io) work on top of this dict.

Top-level envelope

::

{
    "schema_version": <int>,
    "block": <block dict>
}

SCHEMA_VERSION increments whenever the schema changes in a way that breaks backward compatibility — i.e. the current decoder can no longer read previously-written payloads (required fields added or removed, field semantics changed). Purely additive changes do not bump the version: new optional fields are read with d.get(...)-with-default semantics (old payloads decode to the default), and unknown extra fields in newer payloads are ignored by older readers. New operation $type tags are likewise additive — an older reader rejects them loudly with the closed-dispatch ValueError rather than mis-decoding. The current value and the per-bump history are recorded next to the constant at the bottom of this module.

Block dict

::

{
    "$type": "Block",
    "kind": "AFFINE" | "ANALYZED",
    "name": <str>,
    "label_args": [<str>, ...],
    "input_value_refs": [<uuid>, ...],
    "output_value_refs": [<uuid>, ...],
    "output_names": [<str>, ...],
    "parameters": {<name>: <uuid>, ...},
    "param_slots": [<param_slot dict>, ...],
    "value_table": [<value dict>, ...],   # every Value appears once
    "operations": [<op dict>, ...]
}

Only BlockKind.AFFINE and BlockKind.ANALYZED are accepted. HIERARCHICAL and TRACED raise on encode because they may embed CallBlockOperation references to sibling Blocks by Python identity; cross-process module references will be addressed separately.

Type tags

Every polymorphic structure carries a "$type" string used by the decoder’s closed dispatch table. The decoder NEVER imports modules or looks up classes from these strings; it dispatches through a hard-coded $type -> factory map. Unknown tags raise ValueError. This is the load-bearing security invariant.

Value references

Within a Block dict, every Value appears in exactly one place: value_table. Everything else (operand lists, output lists, parameter slots, parent_array pointers, etc.) references Values by their canonical UUID string. The dict shape is therefore a tree (no Python-level cycles) plus a flat Value table.

Numpy arrays

ParamSlot.bound_value and metadata fields like ArrayRuntimeMetadata.const_array may carry numpy.ndarray payloads. They are encoded with the tagged-dict wrapper defined in :mod:qamomile.circuit.ir.serialize.numpy_io::

{
    "$np_array": True,
    "dtype": <str>,         # one of the allow-list
    "shape": [<int>, ...],
    "data": <bytes>         # ndarray.tobytes()
}

JSON I/O converts data bytes to a base64 string at the JSON boundary and back on read; msgpack passes the bytes through as a bin native type.

Hamiltonian payloads

ParamSlot.bound_value and ArrayRuntimeMetadata.const_array may carry qamomile.observable.Hamiltonian objects — the bound values of Observable kernel parameters (e.g. a Trotter kernel built with bindings={"Hs": [1.2 * Z(0), 0.8 * X(0)]}). They are encoded with the tagged-dict wrapper defined in :mod:qamomile.circuit.ir.serialize.hamiltonian_io::

{
    "$hamiltonian": True,
    "terms": [
        [[["Z", 0], ["X", 1]], <coeff>],   # one Pauli product per entry
        ...
    ],
    "constant": <coeff>,
    "num_qubits": <int | None>             # declared register width
}

<coeff> is a plain int / float, or — for complex coefficients — {"$complex": True, "real": <float>, "imag": <float>}. Term order follows the Hamiltonian’s own term-dict iteration order and the float-vs-complex distinction is preserved, so the reconstructed object is repr-identical to the original; both properties feed content_hash, which stringifies opaque payloads via repr. The wrapper contains no raw bytes, so both wire formats carry it unchanged.

Forward compatibility

When the decoder encounters a Block whose schema_version exceeds the loader’s SCHEMA_VERSION, it raises ValueError rather than guess at unknown fields. Earlier versions are likewise rejected today; a future PR may add a migration table.

Constants


qamomile.circuit.ir.types

qamomile.circuit.ir.types module.

qamomile.circuit.ir.types is most fundamental module defining types used in Qamomile IR.

Overview

ClassDescription
BitTypeType representing a classical bit.
DictTypeType representing a dictionary mapping keys to values.
FloatTypeType representing a floating-point number.
ObservableTypeType representing a Hamiltonian observable parameter.
QFixedTypeQuantum fixed-point type.
QUIntTypeQuantum unsigned integer type.
QubitTypeType representing a quantum bit (qubit).
TupleTypeType representing a tuple of values.
UIntTypeType representing an unsigned integer.
ValueTypeBase class for all value types in the IR.

Classes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


DictType [source]

class DictType(ValueType)

Type representing a dictionary mapping keys to values.

Unlike simple types, DictType stores the key and value types, so equality and hashing depend on those types. When key_type and value_type are None, represents a generic Dict type.

Quantum/classical classification is derived from key/value types.

Constructor
def __init__(
    self,
    key_type: ValueType | None = None,
    value_type: ValueType | None = None,
) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

QFixedType [source]

class QFixedType(QuantumTypeMixin, ValueType)

Quantum fixed-point type.

Represents a quantum register encoding a fixed-point number with specified integer and fractional bits.

Constructor
def __init__(
    self,
    integer_bits: int | Value[UIntType] = 0,
    fractional_bits: int | Value[UIntType] = 0,
) -> None
Attributes
Methods
label
def label(self) -> str

QUIntType [source]

class QUIntType(QuantumTypeMixin, ValueType)

Quantum unsigned integer type.

Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).

Constructor
def __init__(self, width: int | Value[UIntType]) -> None
Attributes
Methods
label
def label(self) -> str

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


TupleType [source]

class TupleType(ValueType)

Type representing a tuple of values.

Unlike simple types, TupleType stores the types of its elements, so equality and hashing depend on the element types.

Quantum/classical classification is derived from element types: quantum if any element is quantum, classical if all are classical.

Constructor
def __init__(self, element_types: tuple[ValueType, ...]) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

qamomile.circuit.ir.types.hamiltonian

Observable type for Hamiltonian parameter representation.

This module defines the ObservableType for the Qamomile IR, which represents a reference to a Hamiltonian observable provided via bindings during transpilation.

Unlike the previous HamiltonianExprType, this is purely a reference type - the actual qamomile.observable.Hamiltonian is provided from Python code.

Overview

ClassDescription
ObjectTypeMixin
ObservableTypeType representing a Hamiltonian observable parameter.
ValueTypeBase class for all value types in the IR.

Classes

ObjectTypeMixin [source]

class ObjectTypeMixin
Methods
is_object
def is_object(self) -> bool

ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

qamomile.circuit.ir.types.primitives

Overview

ClassDescription
BitTypeType representing a classical bit.
BlockTypeType representing a block/function reference.
ClassicalTypeMixin
DictTypeType representing a dictionary mapping keys to values.
FloatTypeType representing a floating-point number.
ObjectTypeMixin
QuantumTypeMixin
QubitTypeType representing a quantum bit (qubit).
TupleTypeType representing a tuple of values.
UIntTypeType representing an unsigned integer.
ValueTypeBase class for all value types in the IR.

Classes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


BlockType [source]

class BlockType(ObjectTypeMixin, ValueType)

Type representing a block/function reference.


ClassicalTypeMixin [source]

class ClassicalTypeMixin
Methods
is_classical
def is_classical(self) -> bool

DictType [source]

class DictType(ValueType)

Type representing a dictionary mapping keys to values.

Unlike simple types, DictType stores the key and value types, so equality and hashing depend on those types. When key_type and value_type are None, represents a generic Dict type.

Quantum/classical classification is derived from key/value types.

Constructor
def __init__(
    self,
    key_type: ValueType | None = None,
    value_type: ValueType | None = None,
) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ObjectTypeMixin [source]

class ObjectTypeMixin
Methods
is_object
def is_object(self) -> bool

QuantumTypeMixin [source]

class QuantumTypeMixin
Methods
is_quantum
def is_quantum(self) -> bool

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


TupleType [source]

class TupleType(ValueType)

Type representing a tuple of values.

Unlike simple types, TupleType stores the types of its elements, so equality and hashing depend on the element types.

Quantum/classical classification is derived from element types: quantum if any element is quantum, classical if all are classical.

Constructor
def __init__(self, element_types: tuple[ValueType, ...]) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

qamomile.circuit.ir.types.q_register

Overview

ClassDescription
QFixedTypeQuantum fixed-point type.
QUIntTypeQuantum unsigned integer type.
QuantumTypeMixin
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
ValueTypeBase class for all value types in the IR.

Classes

QFixedType [source]

class QFixedType(QuantumTypeMixin, ValueType)

Quantum fixed-point type.

Represents a quantum register encoding a fixed-point number with specified integer and fractional bits.

Constructor
def __init__(
    self,
    integer_bits: int | Value[UIntType] = 0,
    fractional_bits: int | Value[UIntType] = 0,
) -> None
Attributes
Methods
label
def label(self) -> str

QUIntType [source]

class QUIntType(QuantumTypeMixin, ValueType)

Quantum unsigned integer type.

Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).

Constructor
def __init__(self, width: int | Value[UIntType]) -> None
Attributes
Methods
label
def label(self) -> str

QuantumTypeMixin [source]

class QuantumTypeMixin
Methods
is_quantum
def is_quantum(self) -> bool

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

qamomile.circuit.ir.value

Value types and typed metadata for the Qamomile IR.

Overview

FunctionDescription
remap_indexed_identifierRemap an identifier while preserving a legacy index suffix.
remap_value_metadata_referencesRewrite UUID and logical-id references inside value metadata.
resolve_root_array_indexFold a view-local element index into the root array’s index space.
resolve_root_qubit_addressResolve an array-element value to its root (array_uuid, index).
split_indexed_identifierSplit a legacy indexed identifier into base and index suffix.
ClassDescription
ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
ArrayValueAn array of typed IR values.
CastMetadataMetadata describing a cast carrier and its underlying qubits.
DictRuntimeMetadataMetadata for transpile-time bound dict values.
DictValueA dictionary value stored as stable ordered entries.
QFixedMetadataMetadata for QFixed carriers.
ScalarMetadataMetadata for scalar constants and symbolic parameters.
TupleTypeType representing a tuple of values.
TupleValueA tuple of IR values for structured data.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.
ValueMetadataTyped metadata owned by the compiler/runtime.

Constants

Functions

remap_indexed_identifier [source]

def remap_indexed_identifier(identifier: str, remap_identifier: Callable[[str], str]) -> str

Remap an identifier while preserving a legacy index suffix.

Parameters:

NameTypeDescription
identifierstrScalar identifier or legacy "<base>_<index>" carrier key.
remap_identifiertyping.Callable[[str], str]Function that remaps scalar identifiers and carrier-key bases.

Returns:

str — Remapped identifier. Numeric index suffixes are preserved after remapping the base identifier.


remap_value_metadata_references [source]

def remap_value_metadata_references(
    metadata: ValueMetadata,
    remap_uuid: Callable[[str], str],
    remap_logical_id: Callable[[str], str],
) -> ValueMetadata

Rewrite UUID and logical-id references inside value metadata.

Parameters:

NameTypeDescription
metadataValueMetadataMetadata bundle whose embedded references should be rewritten.
remap_uuidtyping.Callable[[str], str]Function that maps scalar UUID references (and carrier-key bases) to replacement UUIDs.
remap_logical_idtyping.Callable[[str], str]Function that maps scalar logical-id references (and carrier-key bases) to replacement logical IDs.

Returns:

ValueMetadata — Metadata with every embedded UUID / logical-id reference rewritten. Legacy "<uuid>_<index>" carrier keys keep their index suffix while remapping the base UUID. The original bundle is returned unchanged when no reference is rewritten.


resolve_root_array_index [source]

def resolve_root_array_index(array: 'ArrayValue', index: int) -> tuple['ArrayValue', int] | None

Fold a view-local element index into the root array’s index space.

Walks the slice_of chain root-ward, composing each strided view’s affine map parent_index = start + step * local_index. This is the array-level counterpart of :func:resolve_root_qubit_address (which starts from an array-element Value); both must stay consistent with the composite carrier keys "<root_uuid>_<root_index>" registered by QInitOperation at emit time.

Parameters:

NameTypeDescription
arrayArrayValueArray the index is local to. May be a root array (slice_of unset) or an arbitrarily nested strided view.
indexintElement index in array’s own index space.

Returns:

tuple['ArrayValue', int] | None — tuple[ArrayValue, int] | None: (root_array, composed_index) when every slice bound on the chain is compile-time constant and satisfies the frontend contract (non-negative slice_start, positive slice_step). None when any slice_start / slice_step on the chain is missing, symbolic, or violates that contract; callers must then defer resolution rather than guess. Out-of-contract bounds would compose index onto a wrong root slot, so they are refused here too (the frontend rejects them at trace time; this guard covers programmatically constructed IR).


resolve_root_qubit_address [source]

def resolve_root_qubit_address(value: 'Value') -> tuple[str, int] | None

Resolve an array-element value to its root (array_uuid, index).

Walks the parent_array / slice_of chain and composes the nested affine slice maps, so view[i] resolves to (root_uuid, start + step * i) for the composed (start, step). The returned pair is the build-stable identity of the physical qubit slot: the root array’s QInitOperation always registers it as QubitAddress(root_uuid, index), so this address resolves even when the element’s own (per-version) UUID was never registered.

The transpiler’s resource allocator uses the same walk to resolve gate and measurement operands; this shared helper keeps both call sites consistent.

Parameters:

NameTypeDescription
valueValueThe value to resolve. Expected to be an array element (parent_array set with a single constant element_indices entry).

Returns:

tuple[str, int] | None — tuple[str, int] | None: (root_array_uuid, composed_index) when value is an array element with a constant index whose entire slice_of chain has constant slice_start / slice_step. None when value is not an array element, when its index is non-constant, or when any slice bound in the chain is non-constant (those cases are deferred to the emit-time resolver, which has bindings available). Also None for a negative constant index or a chain frame with negative slice_start / non-positive slice_step — composing those would silently address a wrong root slot, so they are refused rather than guessed (the frontend rejects them at trace time; this guard covers programmatically constructed IR).


split_indexed_identifier [source]

def split_indexed_identifier(identifier: str) -> tuple[str, str] | None

Split a legacy indexed identifier into base and index suffix.

Parameters:

NameTypeDescription
identifierstrIdentifier to inspect. Legacy carrier keys use the "<base>_<index>" spelling, where index is decimal.

Returns:

tuple[str, str] | None — tuple[str, str] | None: (base, index) when identifier carries a numeric suffix, otherwise None.

Classes

ArrayRuntimeMetadata [source]

class ArrayRuntimeMetadata

Metadata for array literals and explicit element identity tracking.

element_parent_uuids / element_parent_indices are parallel to element_uuids: for each tracked element they record the root array’s UUID and the element’s index within that root (as resolved by :func:resolve_root_qubit_address at trace time). They let an emit pass map a packed element back to the physical qubit registered under the root array’s QubitAddress(root_uuid, index) key even when the element’s own UUID was never registered. The sentinel ("", -1) marks an element with no array parent (a standalone qubit), for which a flat UUID lookup is used.

Constructor
def __init__(
    self,
    const_array: Any = None,
    element_uuids: tuple[str, ...] = (),
    element_logical_ids: tuple[str, ...] = (),
    element_parent_uuids: tuple[str, ...] = (),
    element_parent_indices: tuple[int, ...] = (),
) -> None
Attributes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

CastMetadata [source]

class CastMetadata

Metadata describing a cast carrier and its underlying qubits.

Constructor
def __init__(
    self,
    source_uuid: str,
    qubit_uuids: tuple[str, ...],
    source_logical_id: str | None = None,
    qubit_logical_ids: tuple[str, ...] = (),
) -> None
Attributes

DictRuntimeMetadata [source]

class DictRuntimeMetadata

Metadata for transpile-time bound dict values.

Constructor
def __init__(self, bound_data: tuple[tuple[Any, Any], ...] = ()) -> None
Attributes

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

QFixedMetadata [source]

class QFixedMetadata

Metadata for QFixed carriers.

Constructor
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> None
Attributes

ScalarMetadata [source]

class ScalarMetadata

Metadata for scalar constants and symbolic parameters.

Constructor
def __init__(
    self,
    const_value: int | float | bool | None = None,
    parameter_name: str | None = None,
) -> None
Attributes

TupleType [source]

class TupleType(ValueType)

Type representing a tuple of values.

Unlike simple types, TupleType stores the types of its elements, so equality and hashing depend on the element types.

Quantum/classical classification is derived from element types: quantum if any element is quantum, classical if all are classical.

Constructor
def __init__(self, element_types: tuple[ValueType, ...]) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

ValueMetadata [source]

class ValueMetadata

Typed metadata owned by the compiler/runtime.

Constructor
def __init__(
    self,
    scalar: ScalarMetadata | None = None,
    cast: CastMetadata | None = None,
    qfixed: QFixedMetadata | None = None,
    array_runtime: ArrayRuntimeMetadata | None = None,
    dict_runtime: DictRuntimeMetadata | None = None,
) -> None
Attributes

qamomile.circuit.ir.value_mapping

Provide shared IR value substitution utilities.

Overview

FunctionDescription
resolve_root_array_indexFold a view-local element index into the root array’s index space.
resolve_root_qubit_addressResolve an array-element value to its root (array_uuid, index).
split_indexed_identifierSplit a legacy indexed identifier into base and index suffix.
ClassDescription
ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
ArrayValueAn array of typed IR values.
CastMetadataMetadata describing a cast carrier and its underlying qubits.
CastOperationType cast operation for creating aliases over the same quantum resources.
DictValueA dictionary value stored as stable ordered entries.
IfOperationRepresents an if-else conditional operation.
QFixedMetadataMetadata for QFixed carriers.
TupleValueA tuple of IR values for structured data.
ValueA typed SSA value in the IR.
ValueBaseProtocol for IR values with typed metadata.
ValueMetadataTyped metadata owned by the compiler/runtime.
ValueSubstitutorSubstitute IR values in operations using a UUID-keyed mapping.

Functions

resolve_root_array_index [source]

def resolve_root_array_index(array: 'ArrayValue', index: int) -> tuple['ArrayValue', int] | None

Fold a view-local element index into the root array’s index space.

Walks the slice_of chain root-ward, composing each strided view’s affine map parent_index = start + step * local_index. This is the array-level counterpart of :func:resolve_root_qubit_address (which starts from an array-element Value); both must stay consistent with the composite carrier keys "<root_uuid>_<root_index>" registered by QInitOperation at emit time.

Parameters:

NameTypeDescription
arrayArrayValueArray the index is local to. May be a root array (slice_of unset) or an arbitrarily nested strided view.
indexintElement index in array’s own index space.

Returns:

tuple['ArrayValue', int] | None — tuple[ArrayValue, int] | None: (root_array, composed_index) when every slice bound on the chain is compile-time constant and satisfies the frontend contract (non-negative slice_start, positive slice_step). None when any slice_start / slice_step on the chain is missing, symbolic, or violates that contract; callers must then defer resolution rather than guess. Out-of-contract bounds would compose index onto a wrong root slot, so they are refused here too (the frontend rejects them at trace time; this guard covers programmatically constructed IR).


resolve_root_qubit_address [source]

def resolve_root_qubit_address(value: 'Value') -> tuple[str, int] | None

Resolve an array-element value to its root (array_uuid, index).

Walks the parent_array / slice_of chain and composes the nested affine slice maps, so view[i] resolves to (root_uuid, start + step * i) for the composed (start, step). The returned pair is the build-stable identity of the physical qubit slot: the root array’s QInitOperation always registers it as QubitAddress(root_uuid, index), so this address resolves even when the element’s own (per-version) UUID was never registered.

The transpiler’s resource allocator uses the same walk to resolve gate and measurement operands; this shared helper keeps both call sites consistent.

Parameters:

NameTypeDescription
valueValueThe value to resolve. Expected to be an array element (parent_array set with a single constant element_indices entry).

Returns:

tuple[str, int] | None — tuple[str, int] | None: (root_array_uuid, composed_index) when value is an array element with a constant index whose entire slice_of chain has constant slice_start / slice_step. None when value is not an array element, when its index is non-constant, or when any slice bound in the chain is non-constant (those cases are deferred to the emit-time resolver, which has bindings available). Also None for a negative constant index or a chain frame with negative slice_start / non-positive slice_step — composing those would silently address a wrong root slot, so they are refused rather than guessed (the frontend rejects them at trace time; this guard covers programmatically constructed IR).


split_indexed_identifier [source]

def split_indexed_identifier(identifier: str) -> tuple[str, str] | None

Split a legacy indexed identifier into base and index suffix.

Parameters:

NameTypeDescription
identifierstrIdentifier to inspect. Legacy carrier keys use the "<base>_<index>" spelling, where index is decimal.

Returns:

tuple[str, str] | None — tuple[str, str] | None: (base, index) when identifier carries a numeric suffix, otherwise None.

Classes

ArrayRuntimeMetadata [source]

class ArrayRuntimeMetadata

Metadata for array literals and explicit element identity tracking.

element_parent_uuids / element_parent_indices are parallel to element_uuids: for each tracked element they record the root array’s UUID and the element’s index within that root (as resolved by :func:resolve_root_qubit_address at trace time). They let an emit pass map a packed element back to the physical qubit registered under the root array’s QubitAddress(root_uuid, index) key even when the element’s own UUID was never registered. The sentinel ("", -1) marks an element with no array parent (a standalone qubit), for which a flat UUID lookup is used.

Constructor
def __init__(
    self,
    const_array: Any = None,
    element_uuids: tuple[str, ...] = (),
    element_logical_ids: tuple[str, ...] = (),
    element_parent_uuids: tuple[str, ...] = (),
    element_parent_indices: tuple[int, ...] = (),
) -> None
Attributes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

When slice_of is set, this array is a strided view over another array. Element accesses on a sliced ArrayValue resolve to physical slots on the root parent via the affine map parent_index = slice_start + slice_step * view_local_index, applied recursively along slice_of chains. The emit-time resolver walks this chain to produce the final qubit index; passes that substitute or clone values must treat slice_of / slice_start / slice_step as Value references that need to track through the same mapping as parent_array.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
    slice_of: 'ArrayValue | None' = None,
    slice_start: 'Value | None' = None,
    slice_step: 'Value | None' = None,
) -> None
Attributes
Methods
is_slice
def is_slice(self) -> bool

Return True if this array is a strided view of another array.

Returns:

boolTrue iff slice_of is non-None.

next_version
def next_version(self) -> ArrayValue[T]

CastMetadata [source]

class CastMetadata

Metadata describing a cast carrier and its underlying qubits.

Constructor
def __init__(
    self,
    source_uuid: str,
    qubit_uuids: tuple[str, ...],
    source_logical_id: str | None = None,
    qubit_logical_ids: tuple[str, ...] = (),
) -> None
Attributes

CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

IfOperation [source]

class IfOperation(HasNestedOps, Operation)

Represents an if-else conditional operation.

Example:

if condition:
    true_body
else:
    false_body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    true_operations: list[Operation] = list(),
    false_operations: list[Operation] = list(),
    phi_ops: list[PhiOp] = list(),
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

QFixedMetadata [source]

class QFixedMetadata

Metadata for QFixed carriers.

Constructor
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> None
Attributes

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueBase [source]

class ValueBase(Protocol)

Protocol for IR values with typed metadata.

Attributes are declared as read-only properties to match frozen dataclass fields in concrete implementations (Value, ArrayValue, etc.).

Attributes
Methods
get_const
def get_const(self) -> int | float | bool | None
is_constant
def is_constant(self) -> bool
is_parameter
def is_parameter(self) -> bool
next_version
def next_version(self) -> ValueBase
parameter_name
def parameter_name(self) -> str | None

ValueMetadata [source]

class ValueMetadata

Typed metadata owned by the compiler/runtime.

Constructor
def __init__(
    self,
    scalar: ScalarMetadata | None = None,
    cast: CastMetadata | None = None,
    qfixed: QFixedMetadata | None = None,
    array_runtime: ArrayRuntimeMetadata | None = None,
    dict_runtime: DictRuntimeMetadata | None = None,
) -> None
Attributes

ValueSubstitutor [source]

class ValueSubstitutor

Substitute IR values in operations using a UUID-keyed mapping.

Parameters:

NameTypeDescription
value_mapMapping[str, ValueBase]Mapping from original value UUIDs to replacement values.
transitiveboolWhether substitutions should chase chains such as A -> B -> C to the terminal value. Defaults to False.
Constructor
def __init__(self, value_map: Mapping[str, ValueBase], transitive: bool = False)

Initialize the substitutor.

Parameters:

NameTypeDescription
value_mapMapping[str, ValueBase]Mapping from original value UUIDs to replacement values.
transitiveboolWhether substitutions should chase chains to their terminal value. Defaults to False.
Methods
substitute_operation
def substitute_operation(self, op: Operation) -> Operation

Substitute values in an operation.

Parameters:

NameTypeDescription
opOperationOperation whose operands, results, and subclass-specific value fields should be substituted.

Returns:

Operation — Operation with all mapped value references replaced.

substitute_value
def substitute_value(self, value: ValueBase) -> ValueBase

Substitute a single value.

Parameters:

NameTypeDescription
valueValueBaseValue to replace or rebuild.

Returns:

ValueBase — Replacement value, rebuilt value with substituted ValueBase — metadata, or the original value when nothing maps.