Skip to content

Circuit

from cascaqit import Circuit

Circuit

Circuit(
    qubits: int | Sequence[str],
    *,
    program_id: str = "program.digital",
    metadata: dict[str, Any] | None = None,
)

Build a static digital circuit and optionally execute it locally. qubits accepts a positive integer, generating names q0, q1, and so on, or an explicit sequence of unique names. program_id identifies the circuit; metadata stores user information. Construction fixes logical qubit order, while measurement target order determines result bitstring order.

Gate methods, append(), compose() and measurement methods mutate and return this circuit. bind(), snapshot(), inverse(), repeat() and controlled() return independent circuits. Rotation angles are in rad. Bind referenced symbolic parameters before execution; even declared defaults require an explicit bind() call.

See the Bell-state experiment and Digital circuit walkthrough. Execution here runs a local simulation without submitting hardware jobs.

Operations and execution

append

append(
    operation: str | OperationBinding | DigitalOperationIR,
    qubits: QubitRef | Sequence[QubitRef] | None = None,
    *,
    parameters: Mapping[str, DigitalValue] | None = None,
) -> Circuit

Append a catalog operation by name, OperationBinding or DigitalOperationIR. For a name, supply operands in qubits and arguments in parameters. A binding already owns its arguments; complete IR cannot override either operands or arguments. Invalid operations, targets or parameters raise ProgramValidationError.

compose

compose(
    other: Circuit,
    *,
    qubit_map: Mapping[QubitRef, QubitRef] | None = None,
) -> Circuit

Append other to this circuit. qubit_map maps every child qubit into the receiving circuit; an omitted mapping must also resolve completely. Shared parameter names require identical defaults and bounds; measurement keys must not conflict. Operations cannot be appended after measurement.

parameter

parameter(
    name: str,
    *,
    default: float | None = None,
    lower_bound: float | None = None,
    upper_bound: float | None = None,
) -> Parameter

Declare a float parameter in radians owned by this circuit and return Parameter. Optional defaults and bounds constrain binding. Duplicate names, nonfinite defaults or invalid bounds raise ProgramValidationError.

bind

bind(values: Mapping[str, float]) -> Circuit

Bind values by name and return an independent circuit. Omitted referenced parameters use defaults or fail if none exists. Unknown names, nonfinite values and bound violations raise ProgramValidationError. Original parameter declarations remain available for inspection.

measure

measure(
    qubits: QubitRef | Sequence[QubitRef],
    *,
    key: str | None = None,
) -> Circuit

Declare computational-basis measurement of selected qubits, including partial or reordered targets. Omitted keys become m0, m1, and so on; explicit keys must be nonempty and unique. Return this circuit; later quantum gates are forbidden. Read multiple registers separately with result.measurement(key).

measure_all

measure_all(*, key: str = 'm') -> Circuit

Measure every qubit in circuit order, using key m by default. This calls measure() with all circuit qubits.

run

run(
    *,
    shots: int = 1000,
    seed: int | None = None,
    return_probabilities: bool = False,
    optimization_level: int = 0,
) -> ResultIR

Return a local simulation ResultIR. shots sets the sampling count and seed controls random sampling. Request exact state probabilities with return_probabilities=True; the default here is False. optimization_level accepts 0 or semantics-preserving simplification level 1. Unbound parameters, invalid programs or execution settings fail. Use LocalBackend for noise and job history.

validate

validate() -> tuple[DiagnosticsIR, ...]

Return a tuple of DiagnosticsIR. An unbound circuit returns an error diagnostic without simulation. Inspect each severity rather than treating every nonempty tuple as either success or failure.

to_program

to_program() -> DigitalProgramIR

Require bound parameters and return canonical DigitalProgramIR. Export does not execute the circuit; unbound parameters raise ProgramValidationError.

to_ir

to_ir() -> DigitalProgramIR

Equivalent to to_program(), returning DigitalProgramIR.

snapshot

snapshot() -> Circuit

Copy declarations, operations and source records into an independently editable circuit.

inverse

inverse() -> Circuit

Return a new circuit with reversed operation order and each operation inverted. Only invertible unitary operations are supported; measured circuits raise ProgramValidationError.

repeat

repeat(count: int) -> Circuit

Return a new circuit repeated count times. Count must be an integer from 1 to 1024, excluding booleans. A measured circuit permits only one repetition. Invalid counts or repeated measurements raise ProgramValidationError.

controlled

controlled(new_control: str) -> Circuit

Return a controlled circuit with new_control preceding the original logical order. Its name must be nonempty and new, and the circuit must not contain measurements. Catalog capabilities limit supported operations; arbitrary circuits are not guaranteed to admit this transformation.

program_id

program_id: str

Return the program identifier string.

qubits

qubits: tuple[str, ...]

Return logical qubit names in construction order as a tuple.

metadata

metadata: dict[str, Any]

Return a deep copy of user and transformation metadata. Editing this dictionary does not edit the circuit metadata.

operations

operations: tuple[DigitalOperationIR, ...]

Return a normalized operation view in source order. Unbound circuits may still retain parameter declarations; bind before numeric execution.

operation_names

operation_names: tuple[str, ...]

Return operation names in order, including declared measurement operations.

parameters

parameters: tuple[Parameter, ...]

Return parameter declarations as a tuple in declaration order.

referenced_parameter_names

referenced_parameter_names: tuple[str, ...]

Return sorted unique names actually referenced by operations. This can be a subset of declared parameters.

is_bound

is_bound: bool

Report whether operations can lower to numeric values. Symbolic references with defaults still require explicit binding.

source_map

source_map() -> ProgramSourceMapIR

Return ProgramSourceMapIR linking operations to their declaration sources. This first exports numeric IR and requires bound parameters; use source_evidence() to inspect unbound declarations.

source_evidence

source_evidence() -> tuple[ProgramSourceEntryIR, ...]

Return source records in current operation order as a tuple.

structural_payload

structural_payload() -> dict[str, Any]

Return a serializable circuit structure containing declarations, operations and classical registers for restoration with from_structural_payload().

structural_hash

structural_hash() -> str

Return a stable structural hash for comparing sources and transformations. Equal hashes do not prove that two physical experiments produced the same result.

from_structural_payload

from_structural_payload(
    payload: Mapping[str, Any],
    *,
    program_id: str = "program.digital.restored",
) -> Circuit

Restore a circuit from its structural dictionary, retaining bindable declarations. Input must match that serialization format; malformed or unsupported content fails.

parameter_occurrences

parameter_occurrences() -> tuple[
    OperationParameterOccurrence, ...
]

Return individual operation-argument occurrences with IDs, source structural hash, affine form and support status. A shared parameter appearing in multiple gates has distinct occurrences, useful for gatewise gradient analysis.

shift_parameter_occurrence

shift_parameter_occurrence(
    occurrence_id: str, shift: float
) -> Circuit

Using an occurrence ID from this snapshot, shift one symbolic RX/RY/RZ theta and return a new circuit. Shift is a finite angle in radians. Unknown IDs, numeric arguments or other gates raise ProgramValidationError.

Gate methods

These methods return this circuit. Qubits accept zero-based indices or declared names; multi-qubit operands must be distinct. Out-of-range indices, unknown names, invalid arguments or gates after measurement raise ProgramValidationError.

i

i(qubit: QubitRef) -> Circuit

Append the identity gate.

x

x(qubit: QubitRef) -> Circuit

Append Pauli X, exchanging computational basis states.

y

y(qubit: QubitRef) -> Circuit

Append Pauli Y.

z

z(qubit: QubitRef) -> Circuit

Append Pauli Z, reversing the sign of the 1-state component.

h

h(qubit: QubitRef) -> Circuit

Append a Hadamard gate.

s

s(qubit: QubitRef) -> Circuit

Append the phase gate diag(1, i).

sdg

sdg(qubit: QubitRef) -> Circuit

Append inverse S, diag(1, -i).

t

t(qubit: QubitRef) -> Circuit

Append the phase gate diag(1, exp(iπ/4)).

tdg

tdg(qubit: QubitRef) -> Circuit

Append inverse T.

rx

rx(theta: DigitalValue, qubit: QubitRef) -> Circuit

Append an X-axis rotation; theta is in radians and may be a parameter or expression.

ry

ry(theta: DigitalValue, qubit: QubitRef) -> Circuit

Append a Y-axis rotation; theta is in radians and may be a parameter or expression.

rz

rz(theta: DigitalValue, qubit: QubitRef) -> Circuit

Append a Z-axis rotation; theta is in radians and may be a parameter or expression.

p

p(theta: DigitalValue, qubit: QubitRef) -> Circuit

Append phase gate diag(1, exp(i theta)), with theta in radians.

u

u(
    theta: DigitalValue,
    phi: DigitalValue,
    lam: DigitalValue,
    qubit: QubitRef,
) -> Circuit

Append the three-angle single-qubit U gate. theta, phi and lam are in radians; use the argument order shown in the signature.

cx

cx(control: QubitRef, target: QubitRef) -> Circuit

Append controlled X with control and target in the indicated order.

cy

cy(control: QubitRef, target: QubitRef) -> Circuit

Append controlled Y.

cz

cz(control: QubitRef, target: QubitRef) -> Circuit

Append controlled Z.

swap

swap(left: QubitRef, right: QubitRef) -> Circuit

Swap two distinct qubits, left and right.

ccx

ccx(
    control0: QubitRef, control1: QubitRef, target: QubitRef
) -> Circuit

Append doubly controlled X; both controls and the target must be distinct.