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))
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
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
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)
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)