Пример #1
0
 def __init__(self, name: str, tl: Timeline):
     super().__init__(name, tl)
     self.kept_memo = Memory('%s.kept_memo' % name, tl, 0.9, 2000, 1, -1, 500)
     self.kept_memo.owner = self
     self.meas_memo = Memory('%s.meas_memo' % name, tl, 0.9, 2000, 1, -1, 500)
     self.meas_memo.owner = self
     self.resource_manager = SimpleManager()
     self.protocols = []
Пример #2
0
def test_Memory_update_state():
    new_state = [complex(0), complex(1)]

    tl = Timeline()
    mem = Memory("mem",
                 tl,
                 fidelity=1,
                 frequency=0,
                 efficiency=1,
                 coherence_time=-1,
                 wavelength=500)

    mem.update_state(new_state)

    assert len(tl.quantum_manager.states) == 1
    assert (tl.quantum_manager.get(mem.qstate_key) == np.array(new_state)).all
Пример #3
0
def entangle_memory(memo1: Memory, memo2: Memory, fidelity: float):
    memo1.reset()
    memo2.reset()

    memo1.entangled_memory['node_id'] = memo2.owner.name
    memo1.entangled_memory['memo_id'] = memo2.name
    memo2.entangled_memory['node_id'] = memo1.owner.name
    memo2.entangled_memory['memo_id'] = memo1.name

    memo1.fidelity = memo2.fidelity = fidelity
Пример #4
0
 def __init__(self, name, timeline):
     super().__init__(name, timeline)
     self.memory = Memory(name + ".memory",
                          tl,
                          fidelity=1,
                          frequency=0,
                          efficiency=1,
                          coherence_time=0,
                          wavelength=500)
     self.memory.owner = self
Пример #5
0
def test_Rule_do():
    class FakeRuleManager(RuleManager):
        def __init__(self):
            RuleManager.__init__(self)
            self.log = []

        def send_request(self, protocol, req_dst, req_condition):
            self.log.append((protocol.name, req_dst, req_condition))

    class FakeProtocol():
        def __init__(self, name):
            self.name = name
            self.rule = None
            self.memories = []

    def fake_action(memories_info):
        if len(memories_info) == 1:
            return FakeProtocol("protocol1"), ["req_dst1"], ["req_condition1"]
        else:
            return FakeProtocol("protocol2"), [None], [None]

    tl = Timeline()
    rule_manager = FakeRuleManager()
    rule = Rule(1, fake_action, None)
    rule.set_rule_manager(rule_manager)
    assert rule.priority == 1 and len(rule.protocols) == 0
    memory = Memory("mem", tl, fidelity=1, frequency=0, efficiency=1, coherence_time=-1, wavelength=500)
    memories_info = [MemoryInfo(memory, 0)]
    assert len(memory._observers) == 0
    rule.do(memories_info)
    assert len(rule.protocols) == 1 and rule.protocols[0].name == "protocol1"
    assert len(rule_manager.log) == 1 and rule_manager.log[0] == ("protocol1", "req_dst1", "req_condition1")
    assert rule.protocols[0].rule == rule
    assert len(memory._observers) == 1
    mem1 = Memory("1", tl, fidelity=1, frequency=0, efficiency=1, coherence_time=-1, wavelength=500)
    mem2 = Memory("2", tl, fidelity=1, frequency=0, efficiency=1, coherence_time=-1, wavelength=500)
    memories_info = [MemoryInfo(mem1, 0), MemoryInfo(mem2, 1)]
    rule.do(memories_info)
    assert len(rule.protocols) == 2 and rule.protocols[1].name == "protocol2"
    assert len(rule_manager.log) == 2 and rule_manager.log[1] == ("protocol2", None, None)
    assert rule.protocols[1].rule == rule
    assert len(mem1._observers) == len(mem2._observers) == 1
Пример #6
0
def test_Memory__schedule_expiration():
    tl = Timeline()
    mem = Memory("mem",
                 tl,
                 fidelity=1,
                 frequency=0,
                 efficiency=1,
                 coherence_time=1,
                 wavelength=500)
    parent = DumbParent(mem)

    process = Process(mem, "expire", [])
    event = Event(1e12, process)
    tl.schedule(event)
    mem.expiration_event = event

    mem._schedule_expiration()

    counter = 0
    for event in tl.events:
        if event.is_invalid():
            counter += 1
    assert counter == 1
Пример #7
0
def test_BBPSSW1():
    tl = Timeline()
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    cc = ClassicalChannel("cc", tl, 0, 1e5)
    cc.delay = 1e9
    cc.set_ends(a1, a2)

    tl.init()
    for i in range(1000):
        fidelity = numpy.random.uniform(0.5, 1)
        kept_memo1 = Memory("a1.kept",
                            tl,
                            fidelity=fidelity,
                            frequency=0,
                            efficiency=1,
                            coherence_time=1,
                            wavelength=500)
        kept_memo2 = Memory("a2.kept", tl, fidelity, 0, 1, 1, 500)
        meas_memo1 = Memory("a1.meas", tl, fidelity, 0, 1, 1, 500)
        meas_memo2 = Memory("a2.meas", tl, fidelity, 0, 1, 1, 500)

        kept_memo1.entangled_memory["node_id"] = "a2"
        kept_memo1.entangled_memory["memo_id"] = "a2.kept"
        kept_memo1.fidelity = fidelity
        kept_memo2.entangled_memory["node_id"] = "a1"
        kept_memo2.entangled_memory["memo_id"] = "a1.kept"
        kept_memo2.fidelity = fidelity
        meas_memo1.entangled_memory["node_id"] = "a2"
        meas_memo1.entangled_memory["memo_id"] = "a2.meas"
        meas_memo1.fidelity = fidelity
        meas_memo2.entangled_memory["node_id"] = "a1"
        meas_memo2.entangled_memory["memo_id"] = "a1.meas"
        meas_memo2.fidelity = fidelity

        ep1 = BBPSSW(a1, "a1.ep1.%d" % i, kept_memo1, meas_memo1)
        ep2 = BBPSSW(a2, "a2.ep2.%d" % i, kept_memo2, meas_memo2)
        a1.protocols.append(ep1)
        a2.protocols.append(ep2)
        ep1.set_others(ep2)
        ep2.set_others(ep1)

        ep1.start()
        ep2.start()

        assert ep1.is_success == ep2.is_success

        tl.run()

        assert a1.resource_manager.log[-2] == (meas_memo1, "RAW")
        assert a2.resource_manager.log[-2] == (meas_memo2, "RAW")
        assert meas_memo1.fidelity == meas_memo2.fidelity == 0

        if ep1.is_success:
            assert kept_memo1.fidelity == kept_memo2.fidelity == BBPSSW.improved_fidelity(
                fidelity)
            assert kept_memo1.entangled_memory[
                "node_id"] == "a2" and kept_memo2.entangled_memory[
                    "node_id"] == "a1"
            assert a1.resource_manager.log[-1] == (kept_memo1, "ENTANGLED")
            assert a2.resource_manager.log[-1] == (kept_memo2, "ENTANGLED")
        else:
            assert kept_memo1.fidelity == kept_memo2.fidelity == 0
            assert kept_memo1.entangled_memory[
                "node_id"] == kept_memo2.entangled_memory["node_id"] == None
            assert a1.resource_manager.log[-1] == (kept_memo1, "RAW")
            assert a2.resource_manager.log[-1] == (kept_memo2, "RAW")
Пример #8
0
def test_BBPSSW2():
    tl = Timeline()
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    cc = ClassicalChannel("cc", tl, 0, 1e5)
    cc.delay = 1e9
    cc.set_ends(a1, a2)

    tl.init()
    counter1 = counter2 = 0
    fidelity = 0.8

    for i in range(1000):
        kept_memo1 = Memory("a1.kept",
                            tl,
                            fidelity=fidelity,
                            frequency=0,
                            efficiency=1,
                            coherence_time=1,
                            wavelength=500)
        kept_memo2 = Memory("a2.kept", tl, fidelity, 0, 1, 1, 500)
        meas_memo1 = Memory("a1.meas", tl, fidelity, 0, 1, 1, 500)
        meas_memo2 = Memory("a2.meas", tl, fidelity, 0, 1, 1, 500)

        kept_memo1.entangled_memory["node_id"] = "a2"
        kept_memo1.entangled_memory["memo_id"] = "a2.kept"
        kept_memo1.fidelity = fidelity
        kept_memo2.entangled_memory["node_id"] = "a1"
        kept_memo2.entangled_memory["memo_id"] = "a1.kept"
        kept_memo2.fidelity = fidelity
        meas_memo1.entangled_memory["node_id"] = "a2"
        meas_memo1.entangled_memory["memo_id"] = "a2.meas"
        meas_memo1.fidelity = fidelity
        meas_memo2.entangled_memory["node_id"] = "a1"
        meas_memo2.entangled_memory["memo_id"] = "a1.meas"
        meas_memo2.fidelity = fidelity

        ep1 = BBPSSW(a1, "a1.ep1.%d" % i, kept_memo1, meas_memo1)
        ep2 = BBPSSW(a2, "a2.ep2.%d" % i, kept_memo2, meas_memo2)
        a1.protocols.append(ep1)
        a2.protocols.append(ep2)
        ep1.set_others(ep2)
        ep2.set_others(ep1)

        ep1.start()
        ep2.start()

        assert ep1.is_success == ep2.is_success
        if ep1.is_success:
            counter1 += 1
        else:
            counter2 += 1

        tl.run()

    assert abs(counter1 / (counter1 + counter2) -
               BBPSSW.success_probability(fidelity)) < 0.1
Пример #9
0
def test_Memory_excite():
    NUM_TESTS = 1000

    tl = Timeline()
    rec = DumbReceiver()
    mem = Memory("mem",
                 tl,
                 fidelity=1,
                 frequency=0,
                 efficiency=1,
                 coherence_time=-1,
                 wavelength=500)
    mem.owner = rec

    # test with perfect efficiency

    for _ in range(NUM_TESTS):
        mem.excite()

    assert len(rec.photon_list) == NUM_TESTS
    null_photons = [p for p in rec.photon_list if p.is_null]
    null_ratio = len(null_photons) / NUM_TESTS
    assert null_ratio == 1

    # test with imperfect efficiency

    rec.photon_list = []
    mem.efficiency = 0.7
    mem.update_state([complex(0), complex(1)])

    for _ in range(NUM_TESTS):
        mem.excite()

    assert abs(len(rec.photon_list) / NUM_TESTS - 0.7) < 0.1
    null_photons = [p for p in rec.photon_list if p.is_null]
    null_ratio = len(null_photons) / len(rec.photon_list)
    assert null_ratio == 0

    # test with perfect efficiency, + state

    rec.photon_list = []
    mem.efficiency = 1
    plus = [math.sqrt(1 / 2), math.sqrt(1 / 2)]

    for _ in range(NUM_TESTS):
        mem.update_state(plus)
        mem.excite()

    assert len(rec.photon_list) == NUM_TESTS
    null_photons = [p for p in rec.photon_list if p.is_null]
    null_ratio = len(null_photons) / NUM_TESTS
    assert abs(null_ratio - 0.5) < 0.1
Пример #10
0
def test_Memory_expire():
    class FakeProtocol(EntanglementProtocol):
        def __init__(self, name):
            super().__init__(None, name)
            self.is_expire = False

        def set_others(self, other: "EntanglementProtocol") -> None:
            pass

        def start(self) -> None:
            pass

        def is_ready(self) -> bool:
            pass

        def memory_expire(self, memory) -> None:
            self.is_expire = True

        def received_message(self, src: str, msg: "Message"):
            pass

        def expire(self, memory: Memory):
            self.memory_expire(memory)

    tl = Timeline()
    mem = Memory("mem",
                 tl,
                 fidelity=1,
                 frequency=0,
                 efficiency=1,
                 coherence_time=-1,
                 wavelength=500)
    parent = DumbParent(mem)
    protocol = FakeProtocol("upper_protocol")
    mem.attach(protocol)
    mem.update_state([math.sqrt(1 / 2), math.sqrt(1 / 2)])
    entangled_memory = {"node_id": "node", "memo_id": 0}
    mem.entangled_memory = entangled_memory

    # expire when the protocol controls memory
    mem.detach(parent)
    assert len(parent.pop_log) == 0 and protocol.is_expire is False
    mem.expire()
    assert (tl.quantum_manager.get(mem.qstate_key).state == np.array(
        [1, 0])).all  # check if collapsed to |0> state
    assert mem.entangled_memory == {"node_id": None, "memo_id": None}
    assert len(parent.pop_log) == 0 and protocol.is_expire is True

    # expire when the resource manager controls memory
    mem.attach(parent)
    mem.detach(protocol)
    mem.update_state([math.sqrt(1 / 2), math.sqrt(1 / 2)])
    entangled_memory = {"node_id": "node", "memo_id": 0}
    mem.entangled_memory = entangled_memory
    mem.expire()
    assert len(parent.pop_log) == 1
def test_BBPSSW_success_rate():
    tl = Timeline()
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    cc0 = ClassicalChannel("cc0", tl, 0, 1e5)
    cc1 = ClassicalChannel("cc1", tl, 0, 1e5)
    cc0.delay = ONE_MILLISECOND
    cc1.delay = ONE_MILLISECOND
    cc0.set_ends(a1, a2)
    cc1.set_ends(a2, a1)

    tl.init()
    counter1 = counter2 = 0
    fidelity = 0.8

    for i in range(1000):
        kept_memo1 = Memory("a1.kept", tl, fidelity=fidelity, frequency=0, efficiency=1, coherence_time=1,
                            wavelength=HALF_MICRON)
        kept_memo2 = Memory("a2.kept", tl, fidelity, 0, 1, 1, HALF_MICRON)
        meas_memo1 = Memory("a1.meas", tl, fidelity, 0, 1, 1, HALF_MICRON)
        meas_memo2 = Memory("a2.meas", tl, fidelity, 0, 1, 1, HALF_MICRON)

        kept_memo1.entangled_memory["node_id"] = "a2"
        kept_memo1.entangled_memory["memo_id"] = "a2.kept"
        kept_memo1.fidelity = fidelity
        kept_memo2.entangled_memory["node_id"] = "a1"
        kept_memo2.entangled_memory["memo_id"] = "a1.kept"
        kept_memo2.fidelity = fidelity
        meas_memo1.entangled_memory["node_id"] = "a2"
        meas_memo1.entangled_memory["memo_id"] = "a2.meas"
        meas_memo1.fidelity = fidelity
        meas_memo2.entangled_memory["node_id"] = "a1"
        meas_memo2.entangled_memory["memo_id"] = "a1.meas"
        meas_memo2.fidelity = fidelity

        pair1 = np.random.choice(range(4), 1,
                                 p=[fidelity, (1 - fidelity) / 3, (1 - fidelity) / 3, (1 - fidelity) / 3])
        pair2 = np.random.choice(range(4), 1,
                                 p=[fidelity, (1 - fidelity) / 3, (1 - fidelity) / 3, (1 - fidelity) / 3])
        tl.quantum_manager.set([kept_memo1.qstate_key, kept_memo2.qstate_key], BELL_STATES[pair1[0]])
        tl.quantum_manager.set([meas_memo1.qstate_key, meas_memo2.qstate_key], BELL_STATES[pair2[0]])

        ep1 = BBPSSW(a1, "a1.ep1.%d" % i, kept_memo1, meas_memo1)
        ep2 = BBPSSW(a2, "a2.ep2.%d" % i, kept_memo2, meas_memo2)
        a1.protocols.append(ep1)
        a2.protocols.append(ep2)
        ep1.set_others(ep2)
        ep2.set_others(ep1)

        ep1.start()
        ep2.start()

        if ep1.meas_res == ep2.meas_res:
            counter1 += 1
        else:
            counter2 += 1

        tl.run()

    assert abs(counter1 / (counter1 + counter2) - BBPSSW.success_probability(fidelity)) < 0.1
def test_BBPSSW_fidelity():
    tl = Timeline()
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    cc0 = ClassicalChannel("cc0", tl, 0, 1e5)
    cc1 = ClassicalChannel("cc1", tl, 0, 1e5)
    cc0.delay = ONE_MILLISECOND
    cc1.delay = ONE_MILLISECOND
    cc0.set_ends(a1, a2)
    cc1.set_ends(a2, a1)

    tl.init()

    for i in range(1000):
        fidelity = np.random.uniform(0.5, 1)
        kept_memo1 = Memory("a1.kept", tl, fidelity=fidelity, frequency=0, efficiency=1, coherence_time=1,
                            wavelength=HALF_MICRON)
        kept_memo2 = Memory("a2.kept", tl, fidelity, 0, 1, 1, HALF_MICRON)
        meas_memo1 = Memory("a1.meas", tl, fidelity, 0, 1, 1, HALF_MICRON)
        meas_memo2 = Memory("a2.meas", tl, fidelity, 0, 1, 1, HALF_MICRON)

        kept_memo1.entangled_memory["node_id"] = "a2"
        kept_memo1.entangled_memory["memo_id"] = "a2.kept"
        kept_memo1.fidelity = fidelity
        kept_memo2.entangled_memory["node_id"] = "a1"
        kept_memo2.entangled_memory["memo_id"] = "a1.kept"
        kept_memo2.fidelity = fidelity
        meas_memo1.entangled_memory["node_id"] = "a2"
        meas_memo1.entangled_memory["memo_id"] = "a2.meas"
        meas_memo1.fidelity = fidelity
        meas_memo2.entangled_memory["node_id"] = "a1"
        meas_memo2.entangled_memory["memo_id"] = "a1.meas"
        meas_memo2.fidelity = fidelity

        pair1 = np.random.choice(range(4), 1,
                                 p=[fidelity, (1 - fidelity) / 3, (1 - fidelity) / 3, (1 - fidelity) / 3])
        pair2 = np.random.choice(range(4), 1,
                                 p=[fidelity, (1 - fidelity) / 3, (1 - fidelity) / 3, (1 - fidelity) / 3])
        tl.quantum_manager.set([kept_memo1.qstate_key, kept_memo2.qstate_key], BELL_STATES[pair1[0]])
        tl.quantum_manager.set([meas_memo1.qstate_key, meas_memo2.qstate_key], BELL_STATES[pair2[0]])

        ep1 = BBPSSW(a1, "a1.ep1.%d" % i, kept_memo1, meas_memo1)
        ep2 = BBPSSW(a2, "a2.ep2.%d" % i, kept_memo2, meas_memo2)
        a1.protocols.append(ep1)
        a2.protocols.append(ep2)
        ep1.set_others(ep2)
        ep2.set_others(ep1)

        ep1.start()
        ep2.start()

        tl.run()

        assert a1.resource_manager.log[-2] == (meas_memo1, RAW)
        assert a2.resource_manager.log[-2] == (meas_memo2, RAW)
        assert meas_memo1.fidelity == meas_memo2.fidelity == 0

        if ep1.meas_res == ep2.meas_res:
            assert kept_memo1.fidelity == kept_memo2.fidelity == BBPSSW.improved_fidelity(fidelity)
            assert kept_memo1.entangled_memory["node_id"] == "a2" and kept_memo2.entangled_memory["node_id"] == "a1"
            assert a1.resource_manager.log[-1] == (kept_memo1, ENTANGLED)
            assert a2.resource_manager.log[-1] == (kept_memo2, ENTANGLED)
        else:
            assert kept_memo1.fidelity == kept_memo2.fidelity == 0
            assert kept_memo1.entangled_memory["node_id"] == kept_memo2.entangled_memory["node_id"] == None
            assert a1.resource_manager.log[-1] == (kept_memo1, RAW)
            assert a2.resource_manager.log[-1] == (kept_memo2, RAW)
def create_scenario(state1, state2, seed):
    tl = Timeline()
    tl.seed(seed)
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    cc0 = ClassicalChannel("cc0", tl, 0, 1e5)
    cc1 = ClassicalChannel("cc1", tl, 0, 1e5)
    cc0.delay = ONE_MILLISECOND
    cc1.delay = ONE_MILLISECOND
    cc0.set_ends(a1, a2)
    cc1.set_ends(a2, a1)

    kept1 = Memory('kept1', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON)
    kept2 = Memory('kept2', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON)
    meas1 = Memory('mea1', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON)
    meas2 = Memory('mea2', tl, fidelity=1, frequency=0, efficiency=1, coherence_time=1, wavelength=HALF_MICRON)

    tl.init()

    tl.quantum_manager.set([kept1.qstate_key, kept2.qstate_key], state1)
    tl.quantum_manager.set([meas1.qstate_key, meas2.qstate_key], state2)

    kept1.entangled_memory = {'node_id': 'a2', 'memo_id': 'kept2'}
    kept2.entangled_memory = {'node_id': 'a1', 'memo_id': 'kept1'}
    meas1.entangled_memory = {'node_id': 'a2', 'memo_id': 'meas2'}
    meas2.entangled_memory = {'node_id': 'a1', 'memo_id': 'meas1'}
    kept1.fidelity = kept2.fidelity = meas1.fidelity = meas2.fidelity = 1

    ep1 = BBPSSW(a1, "a1.ep1", kept1, meas1)
    ep2 = BBPSSW(a2, "a2.ep2", kept2, meas2)
    a1.protocols.append(ep1)
    a2.protocols.append(ep2)
    ep1.set_others(ep2)
    ep2.set_others(ep1)

    ep1.start()
    ep2.start()

    tl.run()

    assert meas1.entangled_memory == meas2.entangled_memory == {'node_id': None, 'memo_id': None}

    return tl, kept1, kept2, meas1, meas2, ep1, ep2
def test_EntanglementSwapping():
    tl = Timeline()
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    a3 = FakeNode("a3", tl)
    cc0 = ClassicalChannel("a2-a1", tl, 0, 1e5)
    cc1 = ClassicalChannel("a2-a3", tl, 0, 1e5)
    cc0.set_ends(a2, a1)
    cc1.set_ends(a2, a3)
    tl.init()
    counter1 = counter2 = 0

    for i in range(1000):
        memo1 = Memory("a1.%d" % i, timeline=tl, fidelity=0.9, frequency=0, efficiency=1, coherence_time=1,
                       wavelength=500)
        memo2 = Memory("a2.%d" % i, tl, 0.9, 0, 1, 1, 500)
        memo3 = Memory("a2.%d" % i, tl, 0.9, 0, 1, 1, 500)
        memo4 = Memory("a3.%d" % i, tl, 0.9, 0, 1, 1, 500)

        memo1.entangled_memory["node_id"] = "a2"
        memo1.entangled_memory["memo_id"] = memo2.name
        memo1.fidelity = 0.9
        memo2.entangled_memory["node_id"] = "a1"
        memo2.entangled_memory["memo_id"] = memo1.name
        memo2.fidelity = 0.9
        memo3.entangled_memory["node_id"] = "a3"
        memo3.entangled_memory["memo_id"] = memo4.name
        memo3.fidelity = 0.9
        memo4.entangled_memory["node_id"] = "a2"
        memo4.entangled_memory["memo_id"] = memo3.name
        memo4.fidelity = 0.9

        es1 = EntanglementSwappingB(a1, "a1.ESb%d" % i, memo1)
        a1.protocols.append(es1)
        es2 = EntanglementSwappingA(a2, "a2.ESa%d" % i, memo2, memo3, success_prob=0.2)
        a2.protocols.append(es2)
        es3 = EntanglementSwappingB(a3, "a3.ESb%d" % i, memo4)
        a3.protocols.append(es3)

        es1.set_others(es2)
        es3.set_others(es2)
        es2.set_others(es1)
        es2.set_others(es3)

        es2.start()

        assert memo2.fidelity == memo3.fidelity == 0
        assert memo1.entangled_memory["node_id"] == memo4.entangled_memory["node_id"] == "a2"
        assert memo2.entangled_memory["node_id"] == memo3.entangled_memory["node_id"] == None
        assert memo2.entangled_memory["memo_id"] == memo3.entangled_memory["memo_id"] == None
        assert a2.resource_manager.log[-2] == (memo2, "RAW")
        assert a2.resource_manager.log[-1] == (memo3, "RAW")

        tl.run()

        if es2.is_success:
            counter1 += 1
            assert memo1.entangled_memory["node_id"] == "a3" and memo4.entangled_memory["node_id"] == "a1"
            assert memo1.fidelity == memo4.fidelity <= memo1.raw_fidelity
            assert a1.resource_manager.log[-1] == (memo1, "ENTANGLED")
            assert a3.resource_manager.log[-1] == (memo4, "ENTANGLED")
        else:
            counter2 += 1
            assert memo1.entangled_memory["node_id"] == memo4.entangled_memory["node_id"] == None
            assert memo1.fidelity == memo4.fidelity == 0
            assert a1.resource_manager.log[-1] == (memo1, "RAW")
            assert a3.resource_manager.log[-1] == (memo4, "RAW")

    assert abs((counter1 / (counter1 + counter2)) - 0.2) < 0.1
def create_scenario(state1, state2, seed):
    tl = Timeline()
    tl.seed(seed)
    a1 = FakeNode("a1", tl)
    a2 = FakeNode("a2", tl)
    a3 = FakeNode("a3", tl)
    cc0 = ClassicalChannel("a2-a1", tl, 0, 1e5)
    cc1 = ClassicalChannel("a2-a3", tl, 0, 1e5)
    cc0.set_ends(a2, a1)
    cc1.set_ends(a2, a3)
    tl.init()

    memo1 = Memory("a1.0", timeline=tl, fidelity=0.9, frequency=0, efficiency=1, coherence_time=1, wavelength=500)
    memo2 = Memory("a2.0", tl, 0.9, 0, 1, 1, 500)
    memo3 = Memory("a2.1", tl, 0.9, 0, 1, 1, 500)
    memo4 = Memory("a3.0", tl, 0.9, 0, 1, 1, 500)

    memo1.fidelity = memo2.fidelity = memo3.fidelity = memo4.fidelity = 1
    memo1.entangled_memory = {'node_id': 'a2', 'memo_id': memo2.name}
    memo2.entangled_memory = {'node_id': 'a1', 'memo_id': memo1.name}
    memo3.entangled_memory = {'node_id': 'a3', 'memo_id': memo4.name}
    memo4.entangled_memory = {'node_id': 'a2', 'memo_id': memo3.name}

    tl.quantum_manager.set([memo1.qstate_key, memo2.qstate_key], state1)
    tl.quantum_manager.set([memo3.qstate_key, memo4.qstate_key], state2)

    es1 = EntanglementSwappingB(a1, "a1.ESb0", memo1)
    a1.protocols.append(es1)
    es2 = EntanglementSwappingA(a2, "a2.ESa0", memo2, memo3)
    a2.protocols.append(es2)
    es3 = EntanglementSwappingB(a3, "a3.ESb1", memo4)
    a3.protocols.append(es3)

    es1.set_others(es2)
    es3.set_others(es2)
    es2.set_others(es1)
    es2.set_others(es3)

    es2.start()

    tl.run()

    ket1, ket2, ket3, ket4 = map(tl.quantum_manager.get,
                                 [memo1.qstate_key, memo2.qstate_key, memo3.qstate_key, memo4.qstate_key])

    assert id(ket1) == id(ket4)
    assert id(ket2) != id(ket3)
    assert len(ket1.keys) == 2 and memo1.qstate_key in ket1.keys and memo4.qstate_key in ket1.keys
    assert len(ket2.keys) == 1

    assert memo2.entangled_memory == memo3.entangled_memory == {'node_id': None, 'memo_id': None}
    assert memo1.entangled_memory["node_id"] == "a3" and memo4.entangled_memory["node_id"] == "a1"
    assert a1.resource_manager.log[-1] == (memo1, "ENTANGLED")
    assert a3.resource_manager.log[-1] == (memo4, "ENTANGLED")
    return ket1, ket2, ket3, ket4, a3