def has_channel(val: Any) -> bool: """Returns whether the value has a channel representation. Returns: If `val` has a `_has_channel_` method and its result is not NotImplemented, that result is returned. Otherwise, if `val` has a `_has_mixture_` method and its result is not NotImplemented, that result is returned. Otherwise if `val` has a `_has_unitary_` method and its results is not NotImplemented, that result is returned. Otherwise, if the value has a _channel_ method return if that has a non-default value. Returns False if none of these functions exists. """ channel_getter = getattr(val, '_has_channel_', None) result = NotImplemented if channel_getter is None else channel_getter() if result is not NotImplemented: return result result = has_mixture(val) if result is not NotImplemented and result: return result # No has methods, use `_channel_` or delegates instead. return channel(val, None) is not None
def has_channel(val: Any, *, allow_decompose: bool = True) -> bool: """Returns whether the value has a channel representation. Args: val: The value to check. allow_decompose: Used by internal methods to stop redundant decompositions from being performed (e.g. there's no need to decompose an object to check if it is unitary as part of determining if the object is a quantum channel, when the quantum channel check will already be doing a more general decomposition check). Defaults to True. When False, the decomposition strategy for determining the result is skipped. Returns: If `val` has a `_has_kraus_` method and its result is not NotImplemented, that result is returned. Otherwise, if `val` has a `_has_mixture_` method and its result is not NotImplemented, that result is returned. Otherwise if `val` has a `_has_unitary_` method and its results is not NotImplemented, that result is returned. Otherwise, if the value has a _kraus_ method return if that has a non-default value. Returns False if none of these functions exists. """ channel_getter = getattr(val, '_has_channel_', None) if channel_getter is not None: warnings.warn( '_has_channel_ is deprecated and will be removed in cirq 0.13, rename to _has_kraus_', DeprecationWarning, ) kraus_getter = getattr(val, '_has_kraus_', None) result = NotImplemented if kraus_getter is None else kraus_getter() if result is not NotImplemented: return result result = has_mixture(val, allow_decompose=False) if result is not NotImplemented and result: return result result = NotImplemented if channel_getter is None else channel_getter() if result is not NotImplemented: return result if allow_decompose: operations, _, _ = _try_decompose_into_operations_and_qubits(val) if operations is not None: return all(has_channel(val) for val in operations) # No has methods, use `_kraus_` or delegates instead. return channel(val, None) is not None