def qfree(
        target: Union[qp.Qubit, qp.Qureg, qp.Quint],
        equivalent_expression: 'Union[None, bool, int, qp.RValue[Any]]' = None,
        dirty: bool = False):
    """Deallocates quantum objects.

    Args:
        target: The quantum object to free.
        equivalent_expression: An entangled expression with the same computational basis value as the quantum object.
            Used to uncompute the quantum object before freeing it, to avoid revealing information.
        dirty: Indicates that the quantum object is not expected to be zero'd.
    """

    if equivalent_expression is not None:
        qp.rval(equivalent_expression).clear_storage_location(
            target, qp.QubitIntersection.ALWAYS)

    if isinstance(target, qp.Qubit):
        assert target.index is None, "Can't deallocate individual qubits from within a register."
        reg = qp.NamedQureg(name=target.name, length=1)
    elif isinstance(target, qp.Qureg):
        reg = target
    elif isinstance(target, qp.Quint):
        reg = target.qureg
    elif isinstance(target, qp.QuintMod):
        reg = target.qureg
    else:
        raise NotImplementedError()
    if len(reg):
        sink.global_sink.do_release(qp.ReleaseQuregOperation(reg, dirty=dirty))
Exemple #2
0
    def __isub__(self, other):
        other, controls = qp.ControlledRValue.split(other)
        if controls == qp.QubitIntersection.NEVER:
            return self

        rval_other = qp.rval(other, default=other)
        rev = getattr(rval_other, '__risub__', None)
        if rev is not None:
            result = rev(qp.ControlledLValue(controls, self))
            if result is not NotImplemented:
                return result

        if isinstance(other, int):
            qp.arithmetic_mod.do_plus_const_mod(lvalue=self[:],
                                                offset=other,
                                                modulus=self.modulus,
                                                control=controls,
                                                forward=False)
            return self

        if isinstance(other, (qp.Quint, qp.RValue)):
            other, controls = qp.ControlledRValue.split(other)
            qp.arithmetic_mod.do_plus_mod(lvalue=self[:],
                                          offset=other,
                                          modulus=self.modulus,
                                          control=controls,
                                          forward=False)
            return self

        return NotImplemented
Exemple #3
0
 def __and__(self, other):
     if isinstance(other, ControlledRValue):
         return ControlledRValue(self.controls & other.controls,
                                 other.rvalue)
     if isinstance(other, (int, qp.Quint, qp.RValue)):
         return ControlledRValue(self.controls, qp.rval(other))
     return NotImplemented
Exemple #4
0
def hold(
    val: Union[T, 'qp.RValue[T]', 'qp.Qubit', 'qp.Quint'],
    *,
    name: str = '',
    controls: 'Optional[qp.QubitIntersection]' = None
) -> 'qp.HeldRValueManager[T]':
    """Returns a context manager that ensures the given rvalue is allocated.

    Usage:
        ```
        with qp.hold(5) as reg:
            # reg is an allocated quint storing the value 5
            ...
        ```

    Args:
        val: The value to hold.
        name: Optional name to use when allocating space for the value.
        controls: If any of these are not set, the result is a default value
            (e.g. False or 0) instead of the rvalue.

    Returns:
        A qp.HeldRValueManager wrapping the given value.
    """
    return qp.HeldRValueManager(
        qp.rval(val),
        controls=qp.QubitIntersection.ALWAYS if controls is None else controls,
        name=name)
Exemple #5
0
 def init(self,
          value: Union[int, 'qp.RValue[int]'],
          controls: 'qp.QubitIntersection' = None):
     if controls is None:
         controls = qp.QubitIntersection.ALWAYS
         qp.rval(value).init_storage_location(self[:], controls)
 def clear(self,
           value: Union[bool, 'qp.RValue[bool]'],
           controls: 'qp.QubitIntersection' = None):
     if controls is None:
         controls = qp.QubitIntersection.ALWAYS
     qp.rval(value).clear_storage_location(self, controls)