示例#1
0
def test_iadd_isub():
    q = qp.Quint(qp.NamedQureg('test', 10))

    with pytest.raises(TypeError):
        q += None

    with qp.RandomSim(measure_bias=0.5):
        with qp.capture() as out:
            q += 5
    assert qp.ccz_count(out) == 18

    with qp.RandomSim(measure_bias=0.5):
        with qp.capture() as out:
            q += 4
    assert qp.ccz_count(out) == 14

    with qp.RandomSim(measure_bias=0.5):
        with qp.capture() as out:
            q -= 3
    assert qp.ccz_count(out) == 18

    q2 = qp.Quint(qp.NamedQureg('test2', 5))
    with qp.RandomSim(measure_bias=0.5):
        with qp.capture() as out:
            q += q2
    assert qp.ccz_count(out) == 18

    # Classes can specify custom behavior via __riadd__.
    class Riadd:
        def __riadd__(self, other):
            qp.phase_flip()
            return other
    with qp.capture() as out:
        q += Riadd()
    assert out == [('phase_flip', qp.QubitIntersection.ALWAYS)]
def test_quint_borrowed():
    @qp.semi_quantum
    def f(x: qp.Quint.Borrowed):
        return x

    q = qp.Quint(qp.NamedQureg('a', 10))
    assert f(q) is q

    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            v = f(2)
            assert isinstance(v, qp.Quint)
    cirq.testing.assert_has_diagram(circuit,
                                    """
_f_x[0]: -------alloc-------Mxc--------cxM---release---
                |           |          |     |
_f_x[1]: -------alloc---X---Mxc--------cxM---release---

global phase:                     pi
    """,
                                    use_unicode_characters=False)

    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            v = f(True)
            assert isinstance(v, qp.Quint)
    cirq.testing.assert_has_diagram(circuit,
                                    """
_f_x: ----------alloc---X---Mxc--------cxM---release---

global phase:                     pi
        """,
                                    use_unicode_characters=False)

    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            rval = qp.LookupTable([1, 2, 3])[q]
            v = f(rval)
            assert isinstance(v, qp.Quint)
    cirq.testing.assert_has_diagram(circuit,
                                    """
_f_x[0]: ----------alloc-------------------------------------X------------------------------------------X-----------------------------Mxc---X---@---X-------------------Z-------------------------------------X---------@---------Mxc--------cxM---cxM---release---
                   |                                         |                                          |                             |         |   |                   |                                     |         |                          |     |
_f_x[1]: ----------alloc-------------------------------------|--------X---------------------------------X-----------------------------Mxc-------X---@-------------------|---Z---------------------------------@---Mxc---|---cxM--------------------cxM---release---
                                                             |        |                                 |                                       |                       |   |                                           |
_lookup_prefix: -----------alloc---X---X---alloc---@X---@X---@---@X---@---Mxc---@---cxM---release---X---@---Mxc-------cxM---release-------------|-------alloc---X---X---@---@---X---Mxc-------cxM---release-------------|------------------------------------------
                                   |               |                            |                                                               |               |                                                       |
a[0]: -----------------------------|---------------@----------------------------Z---------------------------------------------------------------@---------------|-------------------------------------------------------Z------------------------------------------
                                   |                                                                                                                            |
a[1]: -----------------------------@------------------------------------------------------------------------------Z---------------------------------------------@-------------------------Z------------------------------------------------------------------------

global phase:                                                                                                                                                                                                                           pi
            """,
                                    use_unicode_characters=False)

    with pytest.raises(TypeError, match='quantum integer expression'):
        _ = f('test')
def test_prefix():
    @qp.semi_quantum(alloc_prefix='_test_')
    def f(x: qp.Qubit.Borrowed):
        return x

    with qp.RandomSim(measure_bias=0.5):
        with qp.capture():
            q = f(False)
    assert q.name == '_test_x'
def test_multiple():
    @qp.semi_quantum
    def add(target: qp.Quint,
            offset: qp.Quint.Borrowed,
            *,
            control: qp.Qubit.Control = False):
        assert isinstance(target, qp.Quint)
        assert isinstance(offset, qp.Quint)
        assert isinstance(control, qp.QubitIntersection)
        target += offset & qp.controlled_by(control)

    a = qp.Quint(qp.NamedQureg('a', 5))
    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            add(a, 10, control=True)
    assert len(circuit) >= 5
def test_qubit_control():
    @qp.semi_quantum
    def f(x: qp.Qubit.Control):
        return x

    q = qp.Qubit('a', 10)
    q2 = qp.Qubit('b', 8)

    # Note: The lack of capture context means we are implicitly asserting the following invokations perform no
    # quantum operations such as allocating a qubit.

    # Definitely false.
    assert f(False) == qp.QubitIntersection.NEVER
    assert f(qp.QubitIntersection.NEVER) == qp.QubitIntersection.NEVER

    # Definitely true.
    assert f(qp.QubitIntersection.ALWAYS) == qp.QubitIntersection.ALWAYS
    assert f(None) == qp.QubitIntersection.ALWAYS
    assert f(True) == qp.QubitIntersection.ALWAYS

    # Single qubit.
    assert f(q) == qp.QubitIntersection((q, ))
    assert f(qp.QubitIntersection((q, ))) == qp.QubitIntersection((q, ))

    # Multi qubit intersection.
    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            v = f(q & q2)
            assert isinstance(v, qp.QubitIntersection)
            del v
    cirq.testing.assert_has_diagram(circuit,
                                    """
_f_x: ----alloc---X---Mxc-------cxM---release---
                  |
a[10]: -----------@---------@-------------------
                  |         |
b[8]: ------------@---------Z-------------------
        """,
                                    use_unicode_characters=False)

    # Arbitrary expression
    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            rval = qp.Quint(qp.NamedQureg('a', 2)) > qp.Quint(
                qp.NamedQureg('b', 2))
            v = f(rval)
            assert isinstance(v, qp.QubitIntersection)
            q = v.qubits[0]
            assert q.name == '_f_x'
            del q
            del v
    cirq.testing.assert_has_diagram(circuit,
                                    """
_do_if_less_than_or_equal: -----------alloc---@---X---@-------------------------------@---X---@---Mxc---cxM---release---------alloc---@---X---@-------------------------------@---X---@---Mxc---cxM---release-------------------
                                              |   |   |                               |   |   |                                       |   |   |                               |   |   |
_f_x: ------------------------alloc-----------|---|---|---------------X---------------|---|---|-------------------------Mxc-----------|---|---|-------------------------------|---|---|-------------------------cxM---release---
                                              |   |   |               |               |   |   |                                       |   |   |                               |   |   |
a[0]: ----------------------------------------|---@---X---@---X---@---|---@---X---@---X---@---|---------------------------------------|---@---X---@---X---@-------@---X---@---X---@---|-----------------------------------------
                                              |       |   |   |   |   |   |   |   |   |       |                                       |       |   |   |   |       |   |   |   |       |
a[1]: ----------------------------------------|-------|---|---@---X---@---X---@---|---|-------|---------------------------------------|-------|---|---@---X---Z---X---@---|---|-------|-----------------------------------------
                                              |       |   |       |       |       |   |       |                                       |       |   |       |       |       |   |       |
b[0]: ----------------------------------------X-------@---|-------|-------|-------|---@-------X---------------------------------------X-------@---|-------|-------|-------|---@-------X-----------------------------------------
                                                          |       |       |       |                                                               |       |       |       |
b[1]: ----------------------------------------------------X-------@-------@-------X---------------------------------------------------------------X-------@-------@-------X-----------------------------------------------------
        """,
                                    use_unicode_characters=False)

    with pytest.raises(TypeError, match='quantum control expression'):
        _ = f('test')
    with pytest.raises(TypeError, match='quantum control expression'):
        _ = f(qp.Quint(qp.NamedQureg('a', 10)))
    with pytest.raises(TypeError, match='quantum control expression'):
        _ = f(qp.Quint(qp.NamedQureg('a', 10)))
def test_qubit_borrowed():
    @qp.semi_quantum
    def f(x: qp.Qubit.Borrowed):
        return x

    q = qp.Qubit('a', 10)
    assert f(q) is q

    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            v = f(True)
            assert isinstance(v, qp.Qubit)
            del v
    cirq.testing.assert_has_diagram(circuit,
                                    """
_f_x: ----------alloc---X---Mxc--------cxM---release---

global phase:                     pi
                """,
                                    use_unicode_characters=False)

    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            v = f(0)
            assert isinstance(v, qp.Qubit)
            del v
    cirq.testing.assert_has_diagram(circuit,
                                    """
_f_x: ---alloc---Mxc---cxM---release---
                """,
                                    use_unicode_characters=False)

    with qp.RandomSim(measure_bias=1):
        with qp.LogCirqCircuit() as circuit:
            rval = qp.Quint(qp.NamedQureg('a', 3)) > qp.Quint(
                qp.NamedQureg('b', 3))
            v = f(rval)
            assert isinstance(v, qp.Qubit)
            del v
    cirq.testing.assert_has_diagram(circuit,
                                    """
_do_if_less_than_or_equal: -----------alloc---@---X---@-------------------------------------------------------@---X---@---Mxc---cxM---release---------alloc---@---X---@-------------------------------------------------------@---X---@---Mxc---cxM---release-------------------
                                              |   |   |                                                       |   |   |                                       |   |   |                                                       |   |   |
_f_x: ------------------------alloc-----------|---|---|---------------------------X---------------------------|---|---|-------------------------Mxc-----------|---|---|-------------------------------------------------------|---|---|-------------------------cxM---release---
                                              |   |   |                           |                           |   |   |                                       |   |   |                                                       |   |   |
a[0]: ----------------------------------------|---@---X---@---X---@---------------|---------------@---X---@---X---@---|---------------------------------------|---@---X---@---X---@-------------------------------@---X---@---X---@---|-----------------------------------------
                                              |       |   |   |   |               |               |   |   |   |       |                                       |       |   |   |   |                               |   |   |   |       |
a[1]: ----------------------------------------|-------|---|---@---X---@---X---@---|---@---X---@---X---@---|---|-------|---------------------------------------|-------|---|---@---X---@---X---@-------@---X---@---X---@---|---|-------|-----------------------------------------
                                              |       |   |       |   |   |   |   |   |   |   |   |       |   |       |                                       |       |   |       |   |   |   |       |   |   |   |       |   |       |
a[2]: ----------------------------------------|-------|---|-------|---|---@---X---@---X---@---|---|-------|---|-------|---------------------------------------|-------|---|-------|---|---@---X---Z---X---@---|---|-------|---|-------|-----------------------------------------
                                              |       |   |       |   |       |       |       |   |       |   |       |                                       |       |   |       |   |       |       |       |   |       |   |       |
b[0]: ----------------------------------------X-------@---|-------|---|-------|-------|-------|---|-------|---@-------X---------------------------------------X-------@---|-------|---|-------|-------|-------|---|-------|---@-------X-----------------------------------------
                                                          |       |   |       |       |       |   |       |                                                               |       |   |       |       |       |   |       |
b[1]: ----------------------------------------------------X-------@---|-------|-------|-------|---@-------X---------------------------------------------------------------X-------@---|-------|-------|-------|---@-------X-----------------------------------------------------
                                                                      |       |       |       |                                                                                       |       |       |       |
b[2]: ----------------------------------------------------------------X-------@-------@-------X---------------------------------------------------------------------------------------X-------@-------@-------X-----------------------------------------------------------------
        """,
                                    use_unicode_characters=False)

    with pytest.raises(TypeError, match='quantum boolean expression'):
        _ = f('test')