Source code for autoqasm.operators.slices

# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
#     http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.


"""Operators for slices."""

import collections
from typing import Any

import oqpy.base

from autoqasm import program
from autoqasm.types import is_qasm_type, wrap_value


[docs] class GetItemOpts(collections.namedtuple("GetItemOpts", ("element_dtype",))): pass
[docs] def get_item(target: Any, i: Any, opts: GetItemOpts) -> Any: """The slice read operator (i.e. __getitem__). Args: target (Any): An entity that supports getitem semantics. i (Any): Index to read from. opts (GetItemOpts): A GetItemOpts object. Returns: Any: The read element. """ if is_qasm_type(target) or is_qasm_type(i): return _oqpy_get_item(target, i, opts) else: return _py_get_item(target, i)
def _oqpy_get_item(target: Any, i: Any, opts: GetItemOpts) -> Any: """Overload of get_item that produces an oqpy list read.""" oqpy_program = program.get_program_conversion_context().get_oqpy_program() if isinstance(target, oqpy.ArrayVar): base_type = target.base_type elif isinstance(target, oqpy.BitVar): base_type = type(target) else: raise TypeError(f"{type(target)!s} object is not subscriptable") var = base_type() oqpy_program.set(var, target[i]) return var def _py_get_item(target: Any, i: Any) -> Any: """Overload of get_item that executes a Python list read.""" return target[i]
[docs] def set_item(target: Any, i: Any, x: Any) -> Any: """The slice write operator (i.e. __setitem__). Note: it is unspecified whether target will be mutated or not. In general, if target is mutable (like Python lists), it will be mutated. Args: target (Any): An entity that supports setitem semantics. i (Any): Index to modify. x (Any): The new element value. Returns: Any: Same as target, after the update was performed. """ if is_qasm_type(target) or is_qasm_type(i): return _oqpy_set_item(target, i, x) else: return _py_set_item(target, i, x)
def _oqpy_set_item(target: Any, i: Any, x: Any) -> Any: """Overload of set_item that produces an oqpy list modification.""" if not isinstance(target, (oqpy.BitVar, oqpy.ArrayVar)): raise NotImplementedError("Only BitVar and ArrayVar types support slice assignment.") x = wrap_value(x) is_var_name_used = program.get_program_conversion_context().is_var_name_used(x.name) oqpy_program = program.get_program_conversion_context().get_oqpy_program() if is_var_name_used or x.init_expression is None: oqpy_program.set(target[i], x) else: # Set to `x.init_expression` to avoid declaring an unnecessary variable. oqpy_program.set(target[i], x.init_expression) return target def _py_set_item(target: Any, i: Any, x: Any) -> Any: """Overload of set_item that executes a Python list modification.""" target[i] = x return target