def test_merge_moments():
    q = cirq.LineQubit.range(3)
    c_orig = cirq.Circuit(cirq.Z.on_each(q[0], q[1]), cirq.Z.on_each(q[1], q[2]), cirq.Z.on_each(q[1], q[0]), strategy=cirq.InsertStrategy.NEW_THEN_INLINE)
    c_orig = cirq.Circuit(c_orig, cirq.CCX(*q), c_orig)
    cirq.testing.assert_has_diagram(c_orig, '\n0: ───Z───────Z───@───Z───────Z───\n                  │\n1: ───Z───Z───Z───@───Z───Z───Z───\n                  │\n2: ───────Z───────X───────Z───────\n')

    def merge_func(m1: cirq.Moment, m2: cirq.Moment) -> Optional[cirq.Moment]:

        def is_z_moment(m):
            return all(((op.gate == cirq.Z) for op in m))
        if (not (is_z_moment(m1) and is_z_moment(m2))):
            return None
        qubits = (m1.qubits | m2.qubits)

        def mul(op1, op2):
            return ((op1 or op2) if (not (op1 and op2)) else cirq.decompose_once((op1 * op2)))
        return cirq.Moment((mul(m1.operation_at(q), m2.operation_at(q)) for q in qubits))
    cirq.testing.assert_has_diagram(cirq.merge_moments(c_orig, merge_func), '\n0: ───────@───────\n          │\n1: ───Z───@───Z───\n          │\n2: ───Z───X───Z───\n')
def test_merge_moments():
    q = cirq.LineQubit.range(3)
    c_orig = cirq.Circuit(cirq.Z.on_each(q[0], q[1]), cirq.Z.on_each(q[1], q[2]), cirq.Z.on_each(q[1], q[0]), strategy=cirq.InsertStrategy.NEW_THEN_INLINE)
    c_orig = cirq.Circuit(c_orig, cirq.CCX(*q), c_orig)
    cirq.testing.assert_has_diagram(c_orig, '\n0: ───Z───────Z───@───Z───────Z───\n                  │\n1: ───Z───Z───Z───@───Z───Z───Z───\n                  │\n2: ───────Z───────X───────Z───────\n')

    def merge_func(m1: cirq.Moment, m2: cirq.Moment) -> Optional[cirq.Moment]:

        def is_z_moment(m):
            return all(((op.gate == cirq.Z) for op in m))
        if (not (is_z_moment(m1) and is_z_moment(m2))):
            return None
        qubits = (m1.qubits | m2.qubits)

        def mul(op1, op2):
            return ((op1 or op2) if (not (op1 and op2)) else cirq.decompose_once((op1 * op2)))
        return cirq.Moment((mul(m1.operation_at(q), m2.operation_at(q)) for q in qubits))
    cirq.testing.assert_has_diagram(cirq.merge_moments(c_orig, merge_func), '\n0: ───────@───────\n          │\n1: ───Z───@───Z───\n          │\n2: ───Z───X───Z───\n')