def test_transform_bad_tree(): with pytest.raises(TypeError): _ = list(op_tree.transform_op_tree(None)) with pytest.raises(TypeError): _ = list(op_tree.transform_op_tree(5)) with pytest.raises(TypeError): _ = list(op_tree.flatten_op_tree(op_tree.transform_op_tree([ Operation(Gate(), [QubitId()]), (4,) ])))
def control(controllee: op_tree.OP_TREE, control_qubits: Sequence['cirq.Qid'] = None, default: Any = RaiseTypeErrorIfNotProvided) -> Any: """Returns a Controlled version of the given value, if defined. Controllees define how to be controlled by defining a method controlled_by(self, control_qubits). Note that the method may return NotImplemented to indicate a particular controlling can't be done. Args: controllee: The operation or iterable of operations to control. control_qubits: A list of Qids that would control this controllee. default: Determines the fallback behavior when `controllee` doesn't have a controlling defined. If `default` is not set and the fallback occurs, a TypeError is raised instead. TODO: add control_values and control_qid_shape Returns: If `controllee` has a controlled_by method that returns something besides NotImplemented, that result is returned. For an OP_TREE, transformation is applied at the leaf. Otherwise, if a default value was specified, the default value is returned. Raises: TypeError: `controllee` doesn't have a controlled_by method (or that method returned NotImplemented) and no `default` was specified. """ if control_qubits is None: control_qubits = [] controller = getattr(controllee, 'controlled_by', None) result = NotImplemented if controller is None else controller( *control_qubits) if result is not NotImplemented: return result if isinstance(controllee, Iterable): return op_tree.transform_op_tree( controllee, op_transformation=lambda op: control(op, control_qubits)) if default is not RaiseTypeErrorIfNotProvided: return default if controller is None: raise TypeError("object of type '{}' has no controlled_by " "method.".format(type(controllee))) raise TypeError("object of type '{}' does have a controlled_by method, " "but it returned NotImplemented.".format(type(controllee)))
def inverse(root: op_tree.OP_TREE, extensions: Extensions = None) -> op_tree.OP_TREE: """Generates OP_TREE inverses. Args: root: An operation tree containing only invertible operations. extensions: For caller-provided implementations of gate inverses. Returns: An OP_TREE that performs the inverse operation of the given OP_TREE. """ ext = extensions or Extensions() return op_tree.transform_op_tree( root=root, op_transformation=lambda e: _reverse_operation(e, ext), iter_transformation=lambda e: reversed(list(e)))
def skip_tree_freeze(root): return op_tree.freeze_op_tree( op_tree.transform_op_tree(root, iter_transformation=skip_first))
def move_tree_left_freeze(root): return op_tree.freeze_op_tree( op_tree.transform_op_tree(root, move_left))