Optimizes a circuit with XmonDevice in mind.

    Starts by converting the circuit's operations to the xmon gate set, then
    begins merging interactions and rotations, ejecting pi-rotations and phasing
    operations, dropping unnecessary operations, and pushing operations earlier.

    Args:
        circuit: The circuit to optimize.
        new_device: The device the optimized circuit should be targeted at. If
            set to None, the circuit's current device is used.
        qubit_map: Transforms the qubits (e.g. so that they are GridQubits).
        allow_partial_czs: If true, the optimized circuit may contain partial CZ
            gates.  Otherwise all partial CZ gates will be converted to full CZ
            gates.  At worst, two CZ gates will be put in place of each partial
            CZ from the input.

    Returns:
        The optimized circuit.

def optimized_for_xmon(
        circuit: circuits.Circuit,
        new_device: Optional[xmon_device.XmonDevice] = None,
        qubit_map: Callable[[ops.Qid], devices.GridQubit] =
            lambda e: cast(devices.GridQubit, e),
        allow_partial_czs: bool = False,
) -> circuits.Circuit:
    """Optimizes a circuit with XmonDevice in mind.

    Starts by converting the circuit's operations to the xmon gate set, then
    begins merging interactions and rotations, ejecting pi-rotations and phasing
    operations, dropping unnecessary operations, and pushing operations earlier.

    Args:
        circuit: The circuit to optimize.
        new_device: The device the optimized circuit should be targeted at. If
            set to None, the circuit's current device is used.
        qubit_map: Transforms the qubits (e.g. so that they are GridQubits).
        allow_partial_czs: If true, the optimized circuit may contain partial CZ
            gates.  Otherwise all partial CZ gates will be converted to full CZ
            gates.  At worst, two CZ gates will be put in place of each partial
            CZ from the input.

    Returns:
        The optimized circuit.
    """
    copy = circuit.copy()
    opts = _OPTIMIZERS_PART_CZ if allow_partial_czs else _OPTIMIZERS
    for optimizer in opts:
        optimizer(copy)

    return circuits.Circuit.from_ops(
        (op.transform_qubits(qubit_map) for op in copy.all_operations()),
        strategy=circuits.InsertStrategy.EARLIEST,
        device=new_device or copy.device)