From ad650edbef6da4b9625b7d8b93a10a3d0335fa3d Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Mon, 15 Apr 2024 13:32:00 -0400 Subject: [PATCH 01/33] initial changes to the way tags are stored --- src/queries.jl | 15 ++++++++++++--- src/states_registers.jl | 9 +++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 41a8b03..2df58ee 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -5,8 +5,10 @@ Assign a tag to a slot in a register. It returns the list of all currently present tags for that register. See also: [`query`](@ref), [`untag!`](@ref)""" -function tag!(ref::RegRef, tag::Tag) - push!(ref.reg.tags[ref.idx], tag) +function tag!(ref::RegRef, tag::Tag, time=nothing) + push!(ref.reg.tags, tag) + push!(ref.tag_idx, size(ref.reg.tags)[1]) + push!(ref.tag_time, time) end tag!(ref, tag) = tag!(ref, Tag(tag)) @@ -23,7 +25,14 @@ See also: [`query`](@ref), [`tag!`](@ref) function untag!(ref::RegRef, tag::Tag) # TODO rather slow implementation. See issue #74 tags = ref.reg.tags[ref.idx] i = findfirst(==(tag), tags) - isnothing(i) ? throw(KeyError(tag)) : deleteat!(tags, i) # TODO make sure there is a clear error message + if isnothing(i) + throw(KeyError(tag)) # TODO make sure there is a clear error message + else + idx = findfirst(==(i), ref.tag_idx) # everytime a tag is untagged or `querydelete!` is called the `idx` is removed from ref.tag_idx, so we won't have any duplicates + deleteat!(tags, i) + deleteat!(ref.tag_idx, idx) + deleteat!(ref.tag_time, idx) + end end diff --git a/src/states_registers.jl b/src/states_registers.jl index e5aabe8..270d2b1 100644 --- a/src/states_registers.jl +++ b/src/states_registers.jl @@ -20,12 +20,12 @@ struct Register # TODO better type description stateindices::Vector{Int} accesstimes::Vector{Float64} # TODO do not hardcode the type locks::Vector{Any} - tags::Vector{Vector{Tag}} # TODO this is a rather inefficient way to store tags, but at least it provides a FIFO ordering; see issue #74 + tags::Vector{Tag} # TODO this is a rather inefficient way to store tags, but at least it provides a FIFO ordering; see issue #74 end function Register(traits, reprs, bg, sr, si, at) env = ConcurrentSim.Simulation() - Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], [Vector{Tag}() for _ in traits]) + Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], Vector{Tag}()) end Register(traits,reprs,bg,sr,si) = Register(traits,reprs,bg,sr,si,zeros(length(traits))) Register(traits,reprs,bg) = Register(traits,reprs,bg,fill(nothing,length(traits)),zeros(Int,length(traits)),zeros(length(traits))) @@ -49,6 +49,11 @@ julia> r = Register(2) struct RegRef reg::Register idx::Int + tag_idx::Vector{Int} + tag_time::Vector{Float64} end +function RegRef(r::Register, idx::Int) + RegRef(r, idx, [], []) +end #Base.:(==)(r1::Register, r2::Register) = From 242024e699452cc1438fe8576e631c331171bc2a Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 17 Apr 2024 11:10:44 -0400 Subject: [PATCH 02/33] Revert "initial changes to the way tags are stored" This reverts commit ad650edbef6da4b9625b7d8b93a10a3d0335fa3d. --- src/queries.jl | 15 +++------------ src/states_registers.jl | 9 ++------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 2df58ee..41a8b03 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -5,10 +5,8 @@ Assign a tag to a slot in a register. It returns the list of all currently present tags for that register. See also: [`query`](@ref), [`untag!`](@ref)""" -function tag!(ref::RegRef, tag::Tag, time=nothing) - push!(ref.reg.tags, tag) - push!(ref.tag_idx, size(ref.reg.tags)[1]) - push!(ref.tag_time, time) +function tag!(ref::RegRef, tag::Tag) + push!(ref.reg.tags[ref.idx], tag) end tag!(ref, tag) = tag!(ref, Tag(tag)) @@ -25,14 +23,7 @@ See also: [`query`](@ref), [`tag!`](@ref) function untag!(ref::RegRef, tag::Tag) # TODO rather slow implementation. See issue #74 tags = ref.reg.tags[ref.idx] i = findfirst(==(tag), tags) - if isnothing(i) - throw(KeyError(tag)) # TODO make sure there is a clear error message - else - idx = findfirst(==(i), ref.tag_idx) # everytime a tag is untagged or `querydelete!` is called the `idx` is removed from ref.tag_idx, so we won't have any duplicates - deleteat!(tags, i) - deleteat!(ref.tag_idx, idx) - deleteat!(ref.tag_time, idx) - end + isnothing(i) ? throw(KeyError(tag)) : deleteat!(tags, i) # TODO make sure there is a clear error message end diff --git a/src/states_registers.jl b/src/states_registers.jl index 270d2b1..e5aabe8 100644 --- a/src/states_registers.jl +++ b/src/states_registers.jl @@ -20,12 +20,12 @@ struct Register # TODO better type description stateindices::Vector{Int} accesstimes::Vector{Float64} # TODO do not hardcode the type locks::Vector{Any} - tags::Vector{Tag} # TODO this is a rather inefficient way to store tags, but at least it provides a FIFO ordering; see issue #74 + tags::Vector{Vector{Tag}} # TODO this is a rather inefficient way to store tags, but at least it provides a FIFO ordering; see issue #74 end function Register(traits, reprs, bg, sr, si, at) env = ConcurrentSim.Simulation() - Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], Vector{Tag}()) + Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], [Vector{Tag}() for _ in traits]) end Register(traits,reprs,bg,sr,si) = Register(traits,reprs,bg,sr,si,zeros(length(traits))) Register(traits,reprs,bg) = Register(traits,reprs,bg,fill(nothing,length(traits)),zeros(Int,length(traits)),zeros(length(traits))) @@ -49,11 +49,6 @@ julia> r = Register(2) struct RegRef reg::Register idx::Int - tag_idx::Vector{Int} - tag_time::Vector{Float64} end -function RegRef(r::Register, idx::Int) - RegRef(r, idx, [], []) -end #Base.:(==)(r1::Register, r2::Register) = From dcbedeb8b291fcf3d4c85f9a34f0935f37b96fa0 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 1 May 2024 18:10:56 -0400 Subject: [PATCH 03/33] make the internals compatible with dictionary for query and tagging --- src/ProtocolZoo/ProtocolZoo.jl | 28 +++---- src/QuantumSavory.jl | 6 ++ src/networks.jl | 1 + src/queries.jl | 105 +++++++++++++------------ src/states_registers.jl | 5 +- test/test_entanglement_consumer.jl | 1 + test/test_entanglement_tracker.jl | 20 +++-- test/test_entanglement_tracker_grid.jl | 30 +++---- test/test_tags_and_queries.jl | 80 ++++++++++--------- 9 files changed, 143 insertions(+), 133 deletions(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index ff24c86..76d9fee 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -1,7 +1,7 @@ module ProtocolZoo using QuantumSavory -import QuantumSavory: get_time_tracker, Tag +import QuantumSavory: get_time_tracker, Tag, guid using QuantumSavory: Wildcard using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap @@ -190,9 +190,9 @@ end @yield timeout(prot.sim, prot.local_busy_time_post) # tag local node a with EntanglementCounterpart remote_node_idx_b remote_slot_idx_b - tag!(a, EntanglementCounterpart, prot.nodeB, b.idx) + tag!(a, EntanglementCounterpart, prot.nodeB, b.idx; tag_time = now(prot.sim), id = guid()) # tag local node b with EntanglementCounterpart remote_node_idx_a remote_slot_idx_a - tag!(b, EntanglementCounterpart, prot.nodeA, a.idx) + tag!(b, EntanglementCounterpart, prot.nodeA, a.idx; tag_time = now(prot.sim), id = guid()) @debug "EntanglerProt between $(prot.nodeA) and $(prot.nodeB)|round $(round): Entangled .$(a.idx) and .$(b.idx)" unlock(a) @@ -253,18 +253,18 @@ end continue end - (q1, tag1) = qubit_pair[1].slot, qubit_pair[1].tag - (q2, tag2) = qubit_pair[2].slot, qubit_pair[2].tag + (q1, id1, tag1) = qubit_pair[1].slot, qubit_pair[1].id, qubit_pair[1].tag + (q2, id2, tag2) = qubit_pair[2].slot, qubit_pair[2].id, qubit_pair[2].tag @yield lock(q1) & lock(q2) # this should not really need a yield thanks to `findswapablequbits`, but it is better to be defensive @yield timeout(prot.sim, prot.local_busy_time) - untag!(q1, tag1) + untag!(q1, id1) # store a history of whom we were entangled to: remote_node_idx, remote_slot_idx, remote_swapnode_idx, remote_swapslot_idx, local_swap_idx - tag!(q1, EntanglementHistory, tag1[2], tag1[3], tag2[2], tag2[3], q2.idx) + tag!(q1, EntanglementHistory, tag1[2], tag1[3], tag2[2], tag2[3], q2.idx; tag_time = now(prot.sim), id = guid()) - untag!(q2, tag2) + untag!(q2, id2) # store a history of whom we were entangled to: remote_node_idx, remote_slot_idx, remote_swapnode_idx, remote_swapslot_idx, local_swap_idx - tag!(q2, EntanglementHistory, tag2[2], tag2[3], tag1[2], tag1[3], q1.idx) + tag!(q2, EntanglementHistory, tag2[2], tag2[3], tag1[2], tag1[3], q1.idx; tag_time = now(prot.sim), id = guid()) uptotime!((q1, q2), now(prot.sim)) swapcircuit = LocalEntanglementSwap() @@ -350,7 +350,7 @@ end apply!(localslot, updategate) end # tag local with updated EntanglementCounterpart new_remote_node new_remote_slot_idx - tag!(localslot, EntanglementCounterpart, newremotenode, newremoteslotid) + tag!(localslot, EntanglementCounterpart, newremotenode, newremoteslotid; tag_time=now(prot.sim), id = guid()) unlock(localslot) continue end @@ -362,8 +362,8 @@ end ❓) # which local slot used to be entangled with whom we swapped with if !isnothing(history) # @debug "tracker @$(prot.node) history: $(history) | msg: $msg" - _, _, _, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx = history - tag!(localslot, EntanglementHistory, newremotenode, newremoteslotid, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx) + _, _, _, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx = history[1] + tag!(localslot, EntanglementHistory, newremotenode, newremoteslotid, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx; tag_time=now(prot.sim), id=guid()) @debug "EntanglementTracker @$(prot.node): history=`$(history)` | message=`$msg` | Sending to $(whoweswappedwith_node).$(whoweswappedwith_slotidx)" msghist = Tag(updatetagsymbol, pastremotenode, pastremoteslotid, whoweswappedwith_slotidx, newremotenode, newremoteslotid, correction) put!(channel(prot.net, prot.node=>whoweswappedwith_node; permit_forward=true), msghist) @@ -429,8 +429,8 @@ end @yield lock(q1) & lock(q2) @debug "EntanglementConsumer between $(prot.nodeA) and $(prot.nodeB): queries successful, consuming entanglement" - untag!(q1, query1.tag) - untag!(q2, query2.tag) + untag!(q1, query1.id) + untag!(q2, query2.id) # TODO do we need to add EntanglementHistory and should that be a different EntanglementHistory since the current one is specifically for SwapperProt # TODO currently when calculating the observable we assume that EntanglerProt.pairstate is always (|00⟩ + |11⟩)/√2, make it more general for other states ob1 = real(observable((q1, q2), Z⊗Z)) diff --git a/src/QuantumSavory.jl b/src/QuantumSavory.jl index b6928b1..9fc9569 100644 --- a/src/QuantumSavory.jl +++ b/src/QuantumSavory.jl @@ -1,5 +1,11 @@ module QuantumSavory +const glcnt = Ref{Int128}(0) + +function guid() + glcnt[] += 1 +end + using Reexport using DocStringExtensions diff --git a/src/networks.jl b/src/networks.jl index b0f9e53..1d5d6da 100644 --- a/src/networks.jl +++ b/src/networks.jl @@ -14,6 +14,7 @@ struct RegisterNet end function RegisterNet(graph::SimpleGraph, registers, vertex_metadata, edge_metadata, directed_edge_metadata) + glcnt[] = 0 # set the global counter of `guid`s to zero whenever a new network is initialized env = get_time_tracker(registers[1]) all_are_at_zero = all(iszero(ConcurrentSim.now(get_time_tracker(r))) && isempty(get_time_tracker(r).heap) && isnothing(get_time_tracker(r).active_proc) for r in registers) diff --git a/src/queries.jl b/src/queries.jl index 41a8b03..ca8a5a1 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -5,11 +5,13 @@ Assign a tag to a slot in a register. It returns the list of all currently present tags for that register. See also: [`query`](@ref), [`untag!`](@ref)""" -function tag!(ref::RegRef, tag::Tag) - push!(ref.reg.tags[ref.idx], tag) +function tag!(ref::RegRef, tag::Tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) + id = isnothing(id) ? guid() : id + push!(ref.reg.guids, id) + ref.reg.tag_info[id] = (tag, ref.idx, tag_time) end -tag!(ref, tag) = tag!(ref, Tag(tag)) +tag!(ref, tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) = tag!(ref,Tag(tag); tag_time=tag_time, id=id) """$TYPEDSIGNATURES @@ -20,10 +22,11 @@ It returns the list of all currently present tags for that register. See also: [`query`](@ref), [`tag!`](@ref) """ -function untag!(ref::RegRef, tag::Tag) # TODO rather slow implementation. See issue #74 - tags = ref.reg.tags[ref.idx] - i = findfirst(==(tag), tags) - isnothing(i) ? throw(KeyError(tag)) : deleteat!(tags, i) # TODO make sure there is a clear error message +function untag!(ref::RegRef, id::Int128) # TODO rather slow implementation. See issue #74 + i = findfirst(==(id), ref.reg.guids) + isnothing(i) ? throw(KeyError(tag)) : deleteat!(ref.reg.guids, i) # TODO make sure there is a clear error message + delete!(ref.reg.tag_info, id) + nothing end @@ -125,16 +128,18 @@ julia> query(r, Int, 4, <(7)) See also: [`queryall`](@ref), [`tag!`](@ref), [`W`](@ref), [`❓`](@ref) """ -function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true) where {allB} - _query(reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned) +function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true, ref=nothing) where {allB} + _query(reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned, ref=ref) end -function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing) where {allB, filoB} - result = NamedTuple{(:slot, :depth, :tag), Tuple{RegRef, Int, Tag}}[] - for i in 1:length(reg) - if _nothingor(locked, islocked(reg[i])) && _nothingor(assigned, isassigned(reg[i])) - for res in _query(reg[i], tag, Val{true}(), Val{filoB}()) - allB ? push!(result, (slot=reg[i],res...)) : return (slot=reg[i],res...) +function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref=nothing) where {allB, filoB} + result = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] + f = filoB ? reverse : identity + for i in f(reg.guids) + slot = reg[reg.tag_info[i][2]] + if reg.tag_info[i][1] == tag && (isnothing(ref) || (ref == slot)) # Need to check slot when calling from `query` dispatch on RegRef + if _nothingor(locked, islocked(slot) && _nothingor(assigned, isassigned(slot))) + allB ? push!(result, (slot=slot, id=i, tag=reg.tag_info[i][1])) : return (slot=slot, id=i, tag=reg.tag_info[i][1]) end end end @@ -163,20 +168,8 @@ julia> queryall(r[2], :symbol, 2, 3) (depth = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) ``` """ -function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(); filo::Bool=true) where {allB} # TODO this should support locked and assigned like query(::Register) - _query(ref, tag, Val{allB}(), Val{filo}()) -end - -function _query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}()) where {allB, filoB} # TODO there is a lot of code duplication here - if allB - i = findall(==(tag), ref.reg.tags[ref.idx]) - i = filoB ? reverse(i) : i - return NamedTuple{(:depth, :tag), Tuple{Int, Tag}}[(depth=i, tag=tag) for i in i] - else - find = filoB ? findlast : findfirst - i = find(==(tag), ref.reg.tags[ref.idx]) - return isnothing(i) ? nothing : (;depth=i, tag=tag) - end +function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true) where {allB} + _query(ref.reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned, ref=ref) end @@ -272,16 +265,25 @@ function querydelete!(mb::MessageBuffer, args...) return isnothing(r) ? nothing : popat!(mb.buffer, r.depth) end +""" +$TYPEDSIGNATURES +A [`query`](@ref) for [`Register`](@ref) that also deletes the tag from the tag dictionary for the `Register`. +""" +function querydelete!(reg::Register, args...;ref=nothing) + r = query(reg, args...;ref=ref) + ret = !isnothing(r) ? reg.tag_info[r.id] : return nothing + untag!(r.slot, r.id) + return ret +end """ $TYPEDSIGNATURES -A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag list for the `RegRef`. +A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag dictionary for the `Register`. """ -function querydelete!(ref::RegRef, args...) # TODO there is a lot of code duplication here - r = query(ref, args...) - return isnothing(r) ? nothing : popat!(ref.reg.tags[ref.idx], r.depth) +function querydelete!(ref::RegRef, args...) + querydelete!(ref.reg, args...;ref=ref) end @@ -300,8 +302,8 @@ for (tagsymbol, tagvariant) in pairs(tag_types) args = (:a, :b, :c, :d, :e, :f, :g)[1:length(sig)] argssig = [:($a::$t) for (a,t) in zip(args, sig)] - eval(quote function tag!(ref::RegRef, $(argssig...)) - tag!(ref, ($tagvariant)($(args...))) + eval(quote function tag!(ref::RegRef, $(argssig...); tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) + tag!(ref, ($tagvariant)($(args...)); tag_time=tag_time, id=id) end end) eval(quote function Tag($(argssig...)) @@ -321,17 +323,16 @@ for (tagsymbol, tagvariant) in pairs(tag_types) argssig_wild = [:($a::$t) for (a,t) in zip(args, sig_wild)] wild_checks = [:(isa($(args[i]),Wildcard) || $(args[i])(tag[$i])) for i in idx] nonwild_checks = [:(tag[$i]==$(args[i])) for i in complement_idx] - newmethod_reg = quote function query(reg::Register, $(argssig_wild...), ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true) where {allB} - res = NamedTuple{(:slot, :depth, :tag), Tuple{RegRef, Int, Tag}}[] - for (reg_idx, tags) in enumerate(reg.tags) - slot = reg[reg_idx] - for depth in (filo ? reverse(keys(tags)) : keys(tags)) - tag = tags[depth] - if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol - (_nothingor(locked, islocked(slot)) && _nothingor(assigned, isassigned(slot))) || continue - if _all($(nonwild_checks...)) && _all($(wild_checks...)) - allB ? push!(res, (;slot, depth, tag)) : return (;slot, depth, tag) - end + newmethod_reg = quote function query(reg::Register, $(argssig_wild...), ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true, ref=nothing) where {allB} + res = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] + op_guid = filo ? reverse : identity + for i in op_guid(reg.guids) + tag = reg.tag_info[i][1] + slot = reg[reg.tag_info[i][2]] + if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol + (_nothingor(locked, islocked(slot)) && _nothingor(assigned, isassigned(slot))) || continue + if _all($(nonwild_checks...)) && _all($(wild_checks...)) && (isnothing(ref) || (ref == slot)) + allB ? push!(res, (slot=slot, id=i, tag=tag)) : return (slot=slot, id=i, tag=tag) end end end @@ -347,13 +348,13 @@ for (tagsymbol, tagvariant) in pairs(tag_types) end end end newmethod_rr = quote function query(ref::RegRef, $(argssig_wild...), ::Val{allB}=Val{false}(); filo::Bool=true) where {allB} - res = NamedTuple{(:depth, :tag), Tuple{Int, Tag}}[] - tags = ref.reg.tags[ref.idx] - for depth in (filo ? reverse(keys(tags)) : keys(tags)) - tag = tags[depth] + res = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] + op_guid = filo ? reverse : identity + for i in op_guid(ref.reg.guids) + tag = ref.reg.tag_info[i][1] if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol - if _all($(nonwild_checks...)) && _all($(wild_checks...)) - allB ? push!(res, (;depth, tag)) : return (;depth, tag) + if _all($(nonwild_checks...)) && _all($(wild_checks...)) && (ref.reg[ref.reg.tag_info[i][2]] == ref) + allB ? push!(res, (slot=ref, id=i, tag=tag)) : return (slot=ref, id=i, tag=tag) end end end diff --git a/src/states_registers.jl b/src/states_registers.jl index e5aabe8..0d721f5 100644 --- a/src/states_registers.jl +++ b/src/states_registers.jl @@ -20,12 +20,13 @@ struct Register # TODO better type description stateindices::Vector{Int} accesstimes::Vector{Float64} # TODO do not hardcode the type locks::Vector{Any} - tags::Vector{Vector{Tag}} # TODO this is a rather inefficient way to store tags, but at least it provides a FIFO ordering; see issue #74 + tag_info::Dict{Int128, Tuple{Tag, Int64, Union{Float64, Nothing}}} + guids::Vector{Int128} end function Register(traits, reprs, bg, sr, si, at) env = ConcurrentSim.Simulation() - Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], [Vector{Tag}() for _ in traits]) + Register(traits, reprs, bg, sr, si, at, [ConcurrentSim.Resource(env) for _ in traits], Dict{Int128, Tuple{Tag, Int64, Float64}}(), []) end Register(traits,reprs,bg,sr,si) = Register(traits,reprs,bg,sr,si,zeros(length(traits))) Register(traits,reprs,bg) = Register(traits,reprs,bg,fill(nothing,length(traits)),zeros(Int,length(traits)),zeros(length(traits))) diff --git a/test/test_entanglement_consumer.jl b/test/test_entanglement_consumer.jl index 1dc7b5e..2b8279a 100644 --- a/test/test_entanglement_consumer.jl +++ b/test/test_entanglement_consumer.jl @@ -13,6 +13,7 @@ end for i in 1:30, n in 3:30 + @show i, n net = RegisterNet([Register(10) for j in 1:n]) sim = get_time_tracker(net) diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index b75ac75..bf9a922 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -28,8 +28,7 @@ for i in 1:10 @process entangler1() run(sim, 20) - @test net[1].tags == [[Tag(EntanglementCounterpart, 2, 1)],[],[]] - + @test collect(values(net[1].tag_info))[1][1] == Tag(EntanglementCounterpart, 2, 1) entangler2 = EntanglerProt(sim, net, 2, 3; rounds=1) @process entangler2() @@ -38,10 +37,10 @@ for i in 1:10 @process entangler3() run(sim, 60) - @test net[1].tags == [[Tag(EntanglementCounterpart, 2, 1)],[],[]] - @test net[2].tags == [[Tag(EntanglementCounterpart, 1, 1)],[Tag(EntanglementCounterpart, 3, 1)],[],[]] - @test net[3].tags == [[Tag(EntanglementCounterpart, 2, 2)],[Tag(EntanglementCounterpart, 4, 1)]] - @test net[4].tags == [[Tag(EntanglementCounterpart, 3, 2)],[],[]] + @test collect(values(net[1].tag_info))[1][1] == Tag(EntanglementCounterpart, 2, 1) + @test [t[1] for t in collect(values(net[2].tag_info))] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] + @test [t[1] for t in collect(values(net[3].tag_info))] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] + @test [t[1] for t in collect(values(net[4].tag_info))] == [Tag(EntanglementCounterpart, 3, 2)] @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false @@ -53,10 +52,10 @@ for i in 1:10 run(sim, 80) # In the absence of an entanglement tracker the tags will not all be updated - @test net[1].tags == [[Tag(EntanglementCounterpart, 2, 1)],[],[]] - @test net[2].tags == [[Tag(EntanglementHistory, 1, 1, 3, 1, 2)],[Tag(EntanglementHistory, 3, 1, 1, 1, 1)],[],[]] - @test net[3].tags == [[Tag(EntanglementHistory, 2, 2, 4, 1, 2)],[Tag(EntanglementHistory, 4, 1, 2, 2, 1)]] - @test net[4].tags == [[Tag(EntanglementCounterpart, 3, 2)],[],[]] + @test collect(values(net[1].tag_info))[1][1] == Tag(EntanglementCounterpart, 2, 1) + @test [t[1] for t in collect(values(net[2].tag_info))] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] + @test [t[1] for t in collect(values(net[3].tag_info))] == [Tag(EntanglementHistory, 4, 1, 2, 2, 1), Tag(EntanglementHistory, 2, 2, 4, 1, 2)] + @test [t[1] for t in collect(values(net[4].tag_info))] == [Tag(EntanglementCounterpart, 3, 2)] @test isassigned(net[1][1]) && isassigned(net[4][1]) @test !isassigned(net[2][1]) && !isassigned(net[3][1]) @@ -90,7 +89,6 @@ end # same but this time with an entanglement tracker for i in 1:30, n in 2:30 - #@show n, i net = RegisterNet([Register(j+3) for j in 1:n]) sim = get_time_tracker(net) for j in vertices(net) diff --git a/test/test_entanglement_tracker_grid.jl b/test/test_entanglement_tracker_grid.jl index 2bb9969..13b4b72 100644 --- a/test/test_entanglement_tracker_grid.jl +++ b/test/test_entanglement_tracker_grid.jl @@ -73,7 +73,7 @@ for path in paths @process entangler1() run(sim, 20) - @test net[1].tags == [[Tag(EntanglementCounterpart, path[1], 1)],[],[]] + @test [t[1] for t in collect(values(net[1].tag_info))] == [Tag(EntanglementCounterpart, path[1], 1)] # For no particular reason we are starting the entangler protocols at different times @@ -94,13 +94,13 @@ for path in paths @process entangler6() run(sim, 120) - @test net[1].tags == [[Tag(EntanglementCounterpart, path[1], 1)],[],[]] - @test net[path[1]].tags == [[Tag(EntanglementCounterpart, 1, 1)],[Tag(EntanglementCounterpart, path[2], 1)],[]] - @test net[path[2]].tags == [[Tag(EntanglementCounterpart, path[1], 2)],[Tag(EntanglementCounterpart, path[3], 1)], []] - @test net[path[3]].tags == [[Tag(EntanglementCounterpart, path[2], 2)],[Tag(EntanglementCounterpart, path[4], 1)], []] - @test net[path[4]].tags == [[Tag(EntanglementCounterpart, path[3], 2)],[Tag(EntanglementCounterpart, path[5], 1)], []] - @test net[path[5]].tags == [[Tag(EntanglementCounterpart, path[4], 2)],[Tag(EntanglementCounterpart, 16, 1)], []] - @test net[16].tags == [[Tag(EntanglementCounterpart, path[5], 2)],[],[]] + @test [t[1] for t in collect(values(net[1].tag_info))] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [t[1] for t in collect(values(net[path[1]].tag_info))] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] + @test [t[1] for t in collect(values(net[path[2]].tag_info))] == [Tag(EntanglementCounterpart, path[3], 1), Tag(EntanglementCounterpart, path[1], 2)] + @test [t[1] for t in collect(values(net[path[3]].tag_info))] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] + @test [t[1] for t in collect(values(net[path[4]].tag_info))] == [Tag(EntanglementCounterpart, path[5], 1), Tag(EntanglementCounterpart, path[3], 2)] + @test [t[1] for t in collect(values(net[path[5]].tag_info))] == [Tag(EntanglementCounterpart, 16, 1), Tag(EntanglementCounterpart, path[4], 2)] + @test [t[1] for t in collect(values(net[16].tag_info))] == [Tag(EntanglementCounterpart, path[5], 2)] @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false @@ -115,13 +115,13 @@ for path in paths run(sim, 200) # In the absence of an entanglement tracker the tags will not all be updated - @test net[1].tags == [[Tag(EntanglementCounterpart, path[1], 1)],[],[]] - @test net[path[1]].tags == [[Tag(EntanglementHistory, 1, 1, path[2], 1, 2)],[Tag(EntanglementHistory, path[2], 1, 1, 1, 1)],[]] - @test net[path[2]].tags == [[Tag(EntanglementHistory, path[1], 2, path[3], 1, 2)],[Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)], []] - @test net[path[3]].tags == [[Tag(EntanglementHistory, path[2], 2, path[4], 1, 2)],[Tag(EntanglementHistory, path[4], 1, path[2], 2, 1)], []] - @test net[path[4]].tags == [[Tag(EntanglementHistory, path[3], 2, path[5], 1, 2)],[Tag(EntanglementHistory, path[5], 1, path[3], 2, 1)], []] - @test net[path[5]].tags == [[Tag(EntanglementHistory, path[4], 2, 16, 1, 2)],[Tag(EntanglementHistory, 16, 1, path[4], 2, 1)], []] - @test net[16].tags == [[Tag(EntanglementCounterpart, path[5], 2)],[],[]] + @test [t[1] for t in collect(values(net[1].tag_info))] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [t[1] for t in collect(values(net[path[1]].tag_info))] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] + @test [t[1] for t in collect(values(net[path[2]].tag_info))] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] + @test [t[1] for t in collect(values(net[path[3]].tag_info))] == [Tag(EntanglementHistory, path[4], 1, path[2], 2, 1), Tag(EntanglementHistory, path[2], 2, path[4], 1, 2)] + @test [t[1] for t in collect(values(net[path[4]].tag_info))] == [Tag(EntanglementHistory, path[5], 1, path[3], 2, 1), Tag(EntanglementHistory, path[3], 2, path[5], 1, 2)] + @test [t[1] for t in collect(values(net[path[5]].tag_info))] == [Tag(EntanglementHistory, 16, 1, path[4], 2, 1), Tag(EntanglementHistory, path[4], 2, 16, 1, 2)] + @test [t[1] for t in collect(values(net[16].tag_info))] == [Tag(EntanglementCounterpart, path[5], 2)] @test isassigned(net[1][1]) && isassigned(net[16][1]) @test !isassigned(net[path[1]][1]) && !isassigned(net[path[2]][1]) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index 8e29552..9564aa7 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -8,31 +8,33 @@ using Test r = Register(10) tag!(r[1], :symbol1, 2, 3) tag!(r[2], :symbol1, 4, 5) +tag!(r[3], :symbol1, 4, 1) tag!(r[5], Int, 4, 5) @test Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3) -@test query(r, :symbol1, 4, ❓) == (slot=r[2], depth=1, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) -@test query(r, :symbol1, 4, 5) == (slot=r[2], depth=1, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) -@test query(r, :symbol1, ❓, ❓) == (slot=r[1], depth=1, tag=tag_types.SymbolIntInt(:symbol1, 2, 3)) +@test query(r, :symbol1, 4, ❓) == (slot=r[3], id=3, tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) +@test query(r, :symbol1, 4, 5) == (slot=r[2], id=2, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) +@test query(r, :symbol1, ❓, ❓) == (slot=r[3], id=3, tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order @test query(r, :symbol2, ❓, ❓) == nothing -@test query(r, Int, 4, 5) == (slot=r[5], depth=1, tag=tag_types.TypeIntInt(Int, 4, 5)) +@test query(r, Int, 4, 5) == (slot=r[5], id=4, tag=tag_types.TypeIntInt(Int, 4, 5)) @test query(r, Float32, 4, 5) == nothing @test query(r, Int, 4, >(5)) == nothing -@test query(r, Int, 4, <(6)) == (slot=r[5], depth=1, tag=tag_types.TypeIntInt(Int, 4, 5)) +@test query(r, Int, 4, <(6)) == (slot=r[5], id=4, tag=tag_types.TypeIntInt(Int, 4, 5)) -@test queryall(r, :symbol1, ❓, ❓) == [(slot=r[1], depth=1, tag=tag_types.SymbolIntInt(:symbol1, 2, 3)), (slot=r[2], depth=1, tag=tag_types.SymbolIntInt(:symbol1, 4, 5))] +@test queryall(r, :symbol1, ❓, ❓) == [(slot=r[3], id=3, tag=tag_types.SymbolIntInt(:symbol1, 4, 1)), (slot=r[2], id=2, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)), (slot=r[1], id=1, tag=tag_types.SymbolIntInt(:symbol1, 2, 3))] # filo by default @test isempty(queryall(r, :symbol2, ❓, ❓)) -@test query(r[2], Tag(:symbol1, 4, 5)) == (depth=1, tag=Tag(:symbol1, 4, 5)) -@test queryall(r[2], Tag(:symbol1, 4, 5)) == [(depth=1, tag=Tag(:symbol1, 4, 5))] -@test query(r[2], :symbol1, 4, 5) == (depth=1, tag=Tag(:symbol1, 4, 5)) -@test queryall(r[2], :symbol1, 4, 5) == [(depth=1, tag=Tag(:symbol1, 4, 5))] +@test query(r[2], Tag(:symbol1, 4, 5)) == (slot=r[2], id=2, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) +@test queryall(r[2], Tag(:symbol1, 4, 5)) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] +@test query(r[2], :symbol1, 4, 5) == (slot=r[2], id=2, tag=Tag(:symbol1, 4, 5)) +@test queryall(r[2], :symbol1, 4, 5) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] -@test query(r[2], :symbol1, 4, ❓) == (depth=1, tag=Tag(:symbol1, 4, 5)) -@test queryall(r[2], :symbol1, 4, ❓) == [(depth=1, tag=Tag(:symbol1, 4, 5))] +@test query(r[2], :symbol1, 4, ❓) == (slot=r[2], id=2, tag=Tag(:symbol1, 4, 5)) +@test queryall(r[2], :symbol1, 4, ❓) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] -@test querydelete!(r[2], :symbol1, 4, ❓) == Tag(:symbol1, 4, 5) +@test querydelete!(r[2], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 5), 2, nothing) @test querydelete!(r[2], :symbol1, 4, ❓) === nothing +@test querydelete!(r[3], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 1), 3, nothing) # tests for fifo and filo order queries (default is filo) @@ -49,25 +51,25 @@ tag!(reg[3], EntanglementCounterpart, 2, 20) tag!(reg[3], EntanglementCounterpart, 1, 10) @test query(reg[3], EntanglementCounterpart, 1, 11) === nothing -@test query(reg[3], EntanglementCounterpart, 1, 10) == (depth = 8, tag = Tag(EntanglementCounterpart,1,10)) -@test query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=false) == (depth = 1, tag = Tag(EntanglementCounterpart,1,10)) -@test query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=true) == (depth = 8, tag = Tag(EntanglementCounterpart,1,10)) +@test query(reg[3], EntanglementCounterpart, 1, 10) == (slot = reg[3], id = 12, tag = Tag(EntanglementCounterpart,1,10)) +@test query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=false) == (slot = reg[3], id = 5, tag = Tag(EntanglementCounterpart,1,10)) +@test query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=true) == (slot = reg[3], id = 12, tag = Tag(EntanglementCounterpart,1,10)) -@test query(reg[3], EntanglementCounterpart, 2, ❓) == (depth = 7, tag = Tag(EntanglementCounterpart,2,20)) -@test query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=false) == (depth = 2, tag = Tag(EntanglementCounterpart,2,20)) -@test query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=true) == (depth = 7, tag = Tag(EntanglementCounterpart,2,20)) +@test query(reg[3], EntanglementCounterpart, 2, ❓) == (slot = reg[3], id = 11, tag = Tag(EntanglementCounterpart,2,20)) +@test query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=false) == (slot = reg[3], id = 6, tag = Tag(EntanglementCounterpart,2,20)) +@test query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=true) == (slot = reg[3], id = 11, tag = Tag(EntanglementCounterpart,2,20)) @test queryall(reg, EntanglementCounterpart, 1, 11) == [] -@test queryall(reg[3], EntanglementCounterpart, 1, 10) == [(depth = d, tag = Tag(EntanglementCounterpart,1,10)) for d in (8,5,1)] -@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false) == [(depth = d, tag = Tag(EntanglementCounterpart,1,10)) for d in (1,5,8)] -@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true) == [(depth = d, tag = Tag(EntanglementCounterpart,1,10)) for d in (8,5,1)] +@test queryall(reg[3], EntanglementCounterpart, 1, 10) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] +@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (5, 9, 12)] +@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true) == [(slot = reg[3], id = 12, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] -@test queryall(reg[3], EntanglementCounterpart, 2, ❓) == [(depth = d, tag = Tag(EntanglementCounterpart,2,20)) for d in (7,4,2)] -@test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=false) == [(depth = d, tag = Tag(EntanglementCounterpart,2,20)) for d in (2,4,7)] -@test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=true) == [(depth = d, tag = Tag(EntanglementCounterpart,2,20)) for d in (7,4,2)] +@test queryall(reg[3], EntanglementCounterpart, 2, ❓) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (11, 8, 6)] +@test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=false) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (6, 8, 11)] +@test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=true) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (11, 8, 6)] # tests for fifo and filo order queries (default is filo) -# for RegRefs +# for Register reg = Register(5) for i in 2:4 @@ -82,24 +84,24 @@ for i in 2:4 end @test query(reg, EntanglementCounterpart, 1, 10) === nothing -@test query(reg, EntanglementCounterpart, 1, 12) == (slot = reg[2], depth = 1, tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, EntanglementCounterpart, 1, 12) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) @test query(reg, EntanglementCounterpart, 1, 12) == query(reg, EntanglementCounterpart, ==(1), ==(12)) @test query(reg, Tag(EntanglementCounterpart, 1, 10)) === nothing -@test query(reg, Tag(EntanglementCounterpart, 1, 12)) == (slot = reg[2], depth = 1, tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=false) == (slot = reg[2], depth = 1, tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=true) == (slot = reg[2], depth = 1, tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, Tag(EntanglementCounterpart, 1, 12)) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=false) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=true) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) @test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=false) == query(reg, EntanglementCounterpart, 1, ==(12), Val(false); filo=false) @test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=true) == query(reg, EntanglementCounterpart, 1, ==(12), Val(false); filo=true) -@test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=false) == (slot = reg[2], depth = 1, tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=true) == (slot = reg[2], depth = 8, tag = Tag(EntanglementCounterpart,1,312)) +@test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=false) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) +@test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=true) == (slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart,1,314)) -@test queryall(reg, EntanglementCounterpart, 1, ❓) == [(slot = reg[i], depth = d, tag = Tag(EntanglementCounterpart,1,j+i)) for i in 2:4 for (d,j) in ((8,310),(5,110),(1,10))] -@test queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) == [(slot = reg[i], depth = d, tag = Tag(EntanglementCounterpart,1,j+i)) for i in 2:4 for (d,j) in ((8,310),(5,110),(1,10))] -@test queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) == [(slot = reg[i], depth = d, tag = Tag(EntanglementCounterpart,1,j+i)) for i in 2:4 for (d,j) in reverse(((8,310),(5,110),(1,10)))] +@test queryall(reg, EntanglementCounterpart, 1, ❓) == [(slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], id = 33, tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], id = 29, tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], id = 28, tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], id = 25, tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], id = 21, tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], id = 20, tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], id = 17, tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart, 1, 12))] +@test queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) == [(slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], id = 33, tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], id = 29, tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], id = 28, tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], id = 25, tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], id = 21, tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], id = 20, tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], id = 17, tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart, 1, 12))] +@test queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) == reverse([(slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], id = 33, tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], id = 29, tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], id = 28, tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], id = 25, tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], id = 21, tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], id = 20, tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], id = 17, tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart, 1, 12))]) -@test query(reg, EntanglementCounterpart, 2, 22) == (slot = reg[2], depth = 7, tag = Tag(EntanglementCounterpart,2,22)) -@test queryall(reg, EntanglementCounterpart, 2, 22) == [(slot = reg[2], depth = 7, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], depth = 2, tag = Tag(EntanglementCounterpart,2,22))] -@test queryall(reg, Tag(EntanglementCounterpart, 2, 22)) == [(slot = reg[2], depth = 7, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], depth = 2, tag = Tag(EntanglementCounterpart,2,22))] +@test query(reg, EntanglementCounterpart, 2, 22) == (slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)) +@test queryall(reg, EntanglementCounterpart, 2, 22) == [(slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], id = 14, tag = Tag(EntanglementCounterpart,2,22))] +@test queryall(reg, Tag(EntanglementCounterpart, 2, 22)) == [(slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], id = 14, tag = Tag(EntanglementCounterpart,2,22))] @test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) -@test queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) == reverse([(slot = reg[2], depth = 7, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], depth = 2, tag = Tag(EntanglementCounterpart,2,22))]) +@test queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) == [(slot = reg[2], id = 14, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22))] @test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) From 42342a3d003de7db113e18485388e3b583a93d44 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 1 May 2024 19:18:28 -0400 Subject: [PATCH 04/33] fix typo --- test/test_tags_and_queries.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index 4c680a1..3016d95 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -62,7 +62,7 @@ tag!(reg[3], EntanglementCounterpart, 1, 10) @test queryall(reg, EntanglementCounterpart, 1, 11) == [] @test queryall(reg[3], EntanglementCounterpart, 1, 10) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] @test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (5, 9, 12)] -@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true) == [(slot = reg[3], id = 12, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] +@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] @test queryall(reg[3], EntanglementCounterpart, 2, ❓) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (11, 8, 6)] @test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=false) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (6, 8, 11)] From 1935828e4f23874fe2b1cc7c2de40b4f69f1caa8 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 2 May 2024 15:52:25 -0400 Subject: [PATCH 05/33] Complete missing `querydelete!` tests --- src/queries.jl | 12 ++++++------ test/test_tags_and_queries.jl | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 43eda6a..89dcd37 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -260,8 +260,8 @@ t=1.0: query returns nothing t=3.0: query returns SymbolIntInt(:second_tag, 123, 456)::Tag received from node 3 ``` """ -function querydelete!(mb::MessageBuffer, args...) - r = query(mb, args...) +function querydelete!(mb::MessageBuffer, args...;filo=true) + r = query(mb, args...;filo=filo) return isnothing(r) ? nothing : popat!(mb.buffer, r.depth) end @@ -270,8 +270,8 @@ $TYPEDSIGNATURES A [`query`](@ref) for [`Register`](@ref) that also deletes the tag from the tag dictionary for the `Register`. """ -function querydelete!(reg::Register, args...;ref=nothing) - r = query(reg, args...;ref=ref) +function querydelete!(reg::Register, args...;ref=nothing, filo=true) + r = query(reg, args...;ref=ref, filo=filo) ret = !isnothing(r) ? reg.tag_info[r.id] : return nothing untag!(r.slot, r.id) return ret @@ -283,8 +283,8 @@ $TYPEDSIGNATURES A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag list for the `RegRef`. Allows the user to specify order of accessing tags to be FILO or FIFO. """ -function querydelete!(ref::RegRef, args...) - querydelete!(ref.reg, args...;ref=ref) +function querydelete!(ref::RegRef, args...;filo=true) + querydelete!(ref.reg, args...;ref=ref,filo=filo) end diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index 3016d95..df7cdd3 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -114,8 +114,8 @@ tag!(reg[1], EntanglementCounterpart, 4, 9) tag!(reg[1], EntanglementCounterpart, 2, 3) tag!(reg[1], EntanglementCounterpart, 4, 9) -@test reg.tags[1] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3), Tag(EntanglementCounterpart, 4, 9)] +@test [reg.tag_info[i][1] for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3), Tag(EntanglementCounterpart, 4, 9)] querydelete!(reg[1], EntanglementCounterpart, 4, 9) -@test reg.tags[1] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] +@test [reg.tag_info[i][1] for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] querydelete!(reg[1], EntanglementCounterpart, 4, 9;filo=false) -@test reg.tags[1] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] \ No newline at end of file +@test [reg.tag_info[i][1] for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] \ No newline at end of file From c1aa85dbfc151c0b74a745b5dc9ba545032252f4 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 2 May 2024 16:41:31 -0400 Subject: [PATCH 06/33] simplify tests --- src/queries.jl | 2 +- test/test_entanglement_tracker.jl | 18 ++++++++-------- test/test_entanglement_tracker_grid.jl | 30 +++++++++++++------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 89dcd37..24abb26 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -261,7 +261,7 @@ t=3.0: query returns SymbolIntInt(:second_tag, 123, 456)::Tag received from node ``` """ function querydelete!(mb::MessageBuffer, args...;filo=true) - r = query(mb, args...;filo=filo) + r = query(mb, args...) return isnothing(r) ? nothing : popat!(mb.buffer, r.depth) end diff --git a/test/test_entanglement_tracker.jl b/test/test_entanglement_tracker.jl index bf9a922..afc4230 100644 --- a/test/test_entanglement_tracker.jl +++ b/test/test_entanglement_tracker.jl @@ -28,7 +28,7 @@ for i in 1:10 @process entangler1() run(sim, 20) - @test collect(values(net[1].tag_info))[1][1] == Tag(EntanglementCounterpart, 2, 1) + @test [net[1].tag_info[i][1] for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] entangler2 = EntanglerProt(sim, net, 2, 3; rounds=1) @process entangler2() @@ -37,10 +37,10 @@ for i in 1:10 @process entangler3() run(sim, 60) - @test collect(values(net[1].tag_info))[1][1] == Tag(EntanglementCounterpart, 2, 1) - @test [t[1] for t in collect(values(net[2].tag_info))] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] - @test [t[1] for t in collect(values(net[3].tag_info))] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] - @test [t[1] for t in collect(values(net[4].tag_info))] == [Tag(EntanglementCounterpart, 3, 2)] + @test [net[1].tag_info[i][1] for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[2].tag_info[i][1] for i in net[2].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, 3, 1)] + @test [net[3].tag_info[i][1] for i in net[3].guids] == [Tag(EntanglementCounterpart, 2, 2), Tag(EntanglementCounterpart, 4, 1)] + @test [net[4].tag_info[i][1] for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false @@ -52,10 +52,10 @@ for i in 1:10 run(sim, 80) # In the absence of an entanglement tracker the tags will not all be updated - @test collect(values(net[1].tag_info))[1][1] == Tag(EntanglementCounterpart, 2, 1) - @test [t[1] for t in collect(values(net[2].tag_info))] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] - @test [t[1] for t in collect(values(net[3].tag_info))] == [Tag(EntanglementHistory, 4, 1, 2, 2, 1), Tag(EntanglementHistory, 2, 2, 4, 1, 2)] - @test [t[1] for t in collect(values(net[4].tag_info))] == [Tag(EntanglementCounterpart, 3, 2)] + @test [net[1].tag_info[i][1] for i in net[1].guids] == [Tag(EntanglementCounterpart, 2, 1)] + @test [net[2].tag_info[i][1] for i in net[2].guids] == [Tag(EntanglementHistory, 1, 1, 3, 1, 2),Tag(EntanglementHistory, 3, 1, 1, 1, 1)] + @test [net[3].tag_info[i][1] for i in net[3].guids] == [Tag(EntanglementHistory, 2, 2, 4, 1, 2), Tag(EntanglementHistory, 4, 1, 2, 2, 1)] + @test [net[4].tag_info[i][1] for i in net[4].guids] == [Tag(EntanglementCounterpart, 3, 2)] @test isassigned(net[1][1]) && isassigned(net[4][1]) @test !isassigned(net[2][1]) && !isassigned(net[3][1]) diff --git a/test/test_entanglement_tracker_grid.jl b/test/test_entanglement_tracker_grid.jl index 13b4b72..a21977b 100644 --- a/test/test_entanglement_tracker_grid.jl +++ b/test/test_entanglement_tracker_grid.jl @@ -73,7 +73,7 @@ for path in paths @process entangler1() run(sim, 20) - @test [t[1] for t in collect(values(net[1].tag_info))] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[1].tag_info[i][1] for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] # For no particular reason we are starting the entangler protocols at different times @@ -94,13 +94,13 @@ for path in paths @process entangler6() run(sim, 120) - @test [t[1] for t in collect(values(net[1].tag_info))] == [Tag(EntanglementCounterpart, path[1], 1)] - @test [t[1] for t in collect(values(net[path[1]].tag_info))] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] - @test [t[1] for t in collect(values(net[path[2]].tag_info))] == [Tag(EntanglementCounterpart, path[3], 1), Tag(EntanglementCounterpart, path[1], 2)] - @test [t[1] for t in collect(values(net[path[3]].tag_info))] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] - @test [t[1] for t in collect(values(net[path[4]].tag_info))] == [Tag(EntanglementCounterpart, path[5], 1), Tag(EntanglementCounterpart, path[3], 2)] - @test [t[1] for t in collect(values(net[path[5]].tag_info))] == [Tag(EntanglementCounterpart, 16, 1), Tag(EntanglementCounterpart, path[4], 2)] - @test [t[1] for t in collect(values(net[16].tag_info))] == [Tag(EntanglementCounterpart, path[5], 2)] + @test [net[1].tag_info[i][1] for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[path[1]].tag_info[i][1] for i in net[path[1]].guids] == [Tag(EntanglementCounterpart, 1, 1), Tag(EntanglementCounterpart, path[2], 1)] + @test [net[path[2]].tag_info[i][1] for i in net[path[2]].guids] == [Tag(EntanglementCounterpart, path[1], 2), Tag(EntanglementCounterpart, path[3], 1)] + @test [net[path[3]].tag_info[i][1] for i in net[path[3]].guids] == [Tag(EntanglementCounterpart, path[2], 2), Tag(EntanglementCounterpart, path[4], 1)] + @test [net[path[4]].tag_info[i][1] for i in net[path[4]].guids] == [Tag(EntanglementCounterpart, path[3], 2), Tag(EntanglementCounterpart, path[5], 1)] + @test [net[path[5]].tag_info[i][1] for i in net[path[5]].guids] == [Tag(EntanglementCounterpart, path[4], 2), Tag(EntanglementCounterpart, 16, 1)] + @test [net[16].tag_info[i][1] for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] @test [islocked(ref) for i in vertices(net) for ref in net[i]] |> any == false @@ -115,13 +115,13 @@ for path in paths run(sim, 200) # In the absence of an entanglement tracker the tags will not all be updated - @test [t[1] for t in collect(values(net[1].tag_info))] == [Tag(EntanglementCounterpart, path[1], 1)] - @test [t[1] for t in collect(values(net[path[1]].tag_info))] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] - @test [t[1] for t in collect(values(net[path[2]].tag_info))] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] - @test [t[1] for t in collect(values(net[path[3]].tag_info))] == [Tag(EntanglementHistory, path[4], 1, path[2], 2, 1), Tag(EntanglementHistory, path[2], 2, path[4], 1, 2)] - @test [t[1] for t in collect(values(net[path[4]].tag_info))] == [Tag(EntanglementHistory, path[5], 1, path[3], 2, 1), Tag(EntanglementHistory, path[3], 2, path[5], 1, 2)] - @test [t[1] for t in collect(values(net[path[5]].tag_info))] == [Tag(EntanglementHistory, 16, 1, path[4], 2, 1), Tag(EntanglementHistory, path[4], 2, 16, 1, 2)] - @test [t[1] for t in collect(values(net[16].tag_info))] == [Tag(EntanglementCounterpart, path[5], 2)] + @test [net[1].tag_info[i][1] for i in net[1].guids] == [Tag(EntanglementCounterpart, path[1], 1)] + @test [net[path[1]].tag_info[i][1] for i in net[path[1]].guids] == [Tag(EntanglementHistory, 1, 1, path[2], 1, 2), Tag(EntanglementHistory, path[2], 1, 1, 1, 1)] + @test [net[path[2]].tag_info[i][1] for i in net[path[2]].guids] == [Tag(EntanglementHistory, path[1], 2, path[3], 1, 2), Tag(EntanglementHistory, path[3], 1, path[1], 2, 1)] + @test [net[path[3]].tag_info[i][1] for i in net[path[3]].guids] == [Tag(EntanglementHistory, path[2], 2, path[4], 1, 2), Tag(EntanglementHistory, path[4], 1, path[2], 2, 1)] + @test [net[path[4]].tag_info[i][1] for i in net[path[4]].guids] == [Tag(EntanglementHistory, path[3], 2, path[5], 1, 2), Tag(EntanglementHistory, path[5], 1, path[3], 2, 1)] + @test [net[path[5]].tag_info[i][1] for i in net[path[5]].guids] == [Tag(EntanglementHistory, path[4], 2, 16, 1, 2), Tag(EntanglementHistory, 16, 1, path[4], 2, 1)] + @test [net[16].tag_info[i][1] for i in net[16].guids] == [Tag(EntanglementCounterpart, path[5], 2)] @test isassigned(net[1][1]) && isassigned(net[16][1]) @test !isassigned(net[path[1]][1]) && !isassigned(net[path[2]][1]) From 1c49cd8536e49a4cc83ece9877662a77e8d66175 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 2 May 2024 21:23:26 -0400 Subject: [PATCH 07/33] Fixes to doctests --- src/queries.jl | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 24abb26..2e6bcf9 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -2,8 +2,6 @@ Assign a tag to a slot in a register. -It returns the list of all currently present tags for that register. - See also: [`query`](@ref), [`untag!`](@ref)""" function tag!(ref::RegRef, tag::Tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) id = isnothing(id) ? guid() : id @@ -18,8 +16,6 @@ tag!(ref, tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Noth Removes the first instance of tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) -It returns the list of all currently present tags for that register. - See also: [`query`](@ref), [`tag!`](@ref) """ function untag!(ref::RegRef, id::Int128) # TODO rather slow implementation. See issue #74 @@ -65,15 +61,15 @@ julia> r = Register(10); julia> queryall(r, :symbol, ❓, ❓) 2-element Vector{@NamedTuple{slot::RegRef, depth::Int64, tag::Tag}}: - (slot = Slot 1, depth = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) - (slot = Slot 2, depth = 1, tag = SymbolIntInt(:symbol, 4, 5)::Tag) + (slot = Slot 2, id = 2, tag = SymbolIntInt(:symbol, 4, 5)::Tag) + (slot = Slot 1, id = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) julia> queryall(r, :symbol, ❓, >(4)) 1-element Vector{@NamedTuple{slot::RegRef, depth::Int64, tag::Tag}}: - (slot = Slot 2, depth = 1, tag = SymbolIntInt(:symbol, 4, 5)::Tag) + (slot = Slot 2, id = 2, tag = SymbolIntInt(:symbol, 4, 5)::Tag) julia> queryall(r, :symbol, ❓, >(5)) -@NamedTuple{slot::RegRef, depth::Int64, tag::Tag}[] +@NamedTuple{slot::RegRef, id::128, tag::Tag}[] ``` """ queryall(args...; filo=true, kwargs...) = query(args..., Val{true}(); filo, kwargs...) @@ -98,7 +94,7 @@ julia> r = Register(10); julia> query(r, :symbol, 4, 5) -(slot = Slot 2, depth = 1, tag = SymbolIntInt(:symbol, 4, 5)::Tag) +(slot = Slot 2, id = 4, tag = SymbolIntInt(:symbol, 4, 5)::Tag) julia> lock(r[1]); @@ -106,7 +102,7 @@ julia> query(r, :symbol, 4, 5; locked=false) |> isnothing false julia> query(r, :symbol, ❓, 3) -(slot = Slot 1, depth = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) +(slot = Slot 1, id = 3, tag = SymbolIntInt(:symbol, 2, 3)::Tag) julia> query(r, :symbol, ❓, 3; assigned=true) |> isnothing true @@ -123,7 +119,7 @@ julia> query(r, Int, 4, >(7)) |> isnothing true julia> query(r, Int, 4, <(7)) -(slot = Slot 5, depth = 1, tag = TypeIntInt(Int64, 4, 5)::Tag) +(slot = Slot 5, id = 5, tag = TypeIntInt(Int64, 4, 5)::Tag) ``` See also: [`queryall`](@ref), [`tag!`](@ref), [`W`](@ref), [`❓`](@ref) @@ -134,8 +130,8 @@ end function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref=nothing) where {allB, filoB} result = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] - f = filoB ? reverse : identity - for i in f(reg.guids) + op_guid = filoB ? reverse : identity + for i in op_guid(reg.guids) slot = reg[reg.tag_info[i][2]] if reg.tag_info[i][1] == tag && (isnothing(ref) || (ref == slot)) # Need to check slot when calling from `query` dispatch on RegRef if _nothingor(locked, islocked(slot) && _nothingor(assigned, isassigned(slot))) @@ -158,14 +154,14 @@ julia> r = Register(5); julia> tag!(r[2], :symbol, 2, 3); julia> query(r[2], :symbol, 2, 3) -(depth = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) +(slot = Slot 2, id = 6, tag = SymbolIntInt(:symbol, 2, 3)::Tag) julia> query(r[3], :symbol, 2, 3) === nothing true julia> queryall(r[2], :symbol, 2, 3) 1-element Vector{@NamedTuple{depth::Int64, tag::Tag}}: - (depth = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) + (slot = Slot 2, id = 6, tag = SymbolIntInt(:symbol, 2, 3)::Tag) ``` """ function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true) where {allB} From f847609d3b46120bfa81412d28508b3a8db1ef57 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 2 May 2024 21:47:45 -0400 Subject: [PATCH 08/33] fix --- src/queries.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 2e6bcf9..aadf605 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -60,16 +60,16 @@ julia> r = Register(10); tag!(r[2], :symbol, 4, 5); julia> queryall(r, :symbol, ❓, ❓) -2-element Vector{@NamedTuple{slot::RegRef, depth::Int64, tag::Tag}}: +2-element Vector{@NamedTuple{slot::RegRef, id::Int128, tag::Tag}}: (slot = Slot 2, id = 2, tag = SymbolIntInt(:symbol, 4, 5)::Tag) (slot = Slot 1, id = 1, tag = SymbolIntInt(:symbol, 2, 3)::Tag) julia> queryall(r, :symbol, ❓, >(4)) -1-element Vector{@NamedTuple{slot::RegRef, depth::Int64, tag::Tag}}: +1-element Vector{@NamedTuple{slot::RegRef, id::Int128, tag::Tag}}: (slot = Slot 2, id = 2, tag = SymbolIntInt(:symbol, 4, 5)::Tag) julia> queryall(r, :symbol, ❓, >(5)) -@NamedTuple{slot::RegRef, id::128, tag::Tag}[] +@NamedTuple{slot::RegRef, id::Int128, tag::Tag}[] ``` """ queryall(args...; filo=true, kwargs...) = query(args..., Val{true}(); filo, kwargs...) @@ -160,7 +160,7 @@ julia> query(r[3], :symbol, 2, 3) === nothing true julia> queryall(r[2], :symbol, 2, 3) -1-element Vector{@NamedTuple{depth::Int64, tag::Tag}}: +1-element Vector{@NamedTuple{slot::RegRef, id::Int128, tag::Tag}}: (slot = Slot 2, id = 6, tag = SymbolIntInt(:symbol, 2, 3)::Tag) ``` """ From f82afbea9bffb5f02eee477cb18b0fb2a16498ba Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Fri, 3 May 2024 20:49:03 -0400 Subject: [PATCH 09/33] apply suggestions from code review --- src/ProtocolZoo/ProtocolZoo.jl | 14 +++++++------- src/networks.jl | 1 - src/queries.jl | 5 +++-- test/test_entanglement_consumer.jl | 1 - 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 76d9fee..de684dc 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -1,7 +1,7 @@ module ProtocolZoo using QuantumSavory -import QuantumSavory: get_time_tracker, Tag, guid +import QuantumSavory: get_time_tracker, Tag using QuantumSavory: Wildcard using QuantumSavory.CircuitZoo: EntanglementSwap, LocalEntanglementSwap @@ -190,9 +190,9 @@ end @yield timeout(prot.sim, prot.local_busy_time_post) # tag local node a with EntanglementCounterpart remote_node_idx_b remote_slot_idx_b - tag!(a, EntanglementCounterpart, prot.nodeB, b.idx; tag_time = now(prot.sim), id = guid()) + tag!(a, EntanglementCounterpart, prot.nodeB, b.idx) # tag local node b with EntanglementCounterpart remote_node_idx_a remote_slot_idx_a - tag!(b, EntanglementCounterpart, prot.nodeA, a.idx; tag_time = now(prot.sim), id = guid()) + tag!(b, EntanglementCounterpart, prot.nodeA, a.idx) @debug "EntanglerProt between $(prot.nodeA) and $(prot.nodeB)|round $(round): Entangled .$(a.idx) and .$(b.idx)" unlock(a) @@ -260,11 +260,11 @@ end untag!(q1, id1) # store a history of whom we were entangled to: remote_node_idx, remote_slot_idx, remote_swapnode_idx, remote_swapslot_idx, local_swap_idx - tag!(q1, EntanglementHistory, tag1[2], tag1[3], tag2[2], tag2[3], q2.idx; tag_time = now(prot.sim), id = guid()) + tag!(q1, EntanglementHistory, tag1[2], tag1[3], tag2[2], tag2[3], q2.idx) untag!(q2, id2) # store a history of whom we were entangled to: remote_node_idx, remote_slot_idx, remote_swapnode_idx, remote_swapslot_idx, local_swap_idx - tag!(q2, EntanglementHistory, tag2[2], tag2[3], tag1[2], tag1[3], q1.idx; tag_time = now(prot.sim), id = guid()) + tag!(q2, EntanglementHistory, tag2[2], tag2[3], tag1[2], tag1[3], q1.idx) uptotime!((q1, q2), now(prot.sim)) swapcircuit = LocalEntanglementSwap() @@ -350,7 +350,7 @@ end apply!(localslot, updategate) end # tag local with updated EntanglementCounterpart new_remote_node new_remote_slot_idx - tag!(localslot, EntanglementCounterpart, newremotenode, newremoteslotid; tag_time=now(prot.sim), id = guid()) + tag!(localslot, EntanglementCounterpart, newremotenode, newremoteslotid) unlock(localslot) continue end @@ -363,7 +363,7 @@ end if !isnothing(history) # @debug "tracker @$(prot.node) history: $(history) | msg: $msg" _, _, _, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx = history[1] - tag!(localslot, EntanglementHistory, newremotenode, newremoteslotid, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx; tag_time=now(prot.sim), id=guid()) + tag!(localslot, EntanglementHistory, newremotenode, newremoteslotid, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx) @debug "EntanglementTracker @$(prot.node): history=`$(history)` | message=`$msg` | Sending to $(whoweswappedwith_node).$(whoweswappedwith_slotidx)" msghist = Tag(updatetagsymbol, pastremotenode, pastremoteslotid, whoweswappedwith_slotidx, newremotenode, newremoteslotid, correction) put!(channel(prot.net, prot.node=>whoweswappedwith_node; permit_forward=true), msghist) diff --git a/src/networks.jl b/src/networks.jl index 1d5d6da..b0f9e53 100644 --- a/src/networks.jl +++ b/src/networks.jl @@ -14,7 +14,6 @@ struct RegisterNet end function RegisterNet(graph::SimpleGraph, registers, vertex_metadata, edge_metadata, directed_edge_metadata) - glcnt[] = 0 # set the global counter of `guid`s to zero whenever a new network is initialized env = get_time_tracker(registers[1]) all_are_at_zero = all(iszero(ConcurrentSim.now(get_time_tracker(r))) && isempty(get_time_tracker(r).heap) && isnothing(get_time_tracker(r).active_proc) for r in registers) diff --git a/src/queries.jl b/src/queries.jl index aadf605..10942aa 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -4,6 +4,7 @@ Assign a tag to a slot in a register. See also: [`query`](@ref), [`untag!`](@ref)""" function tag!(ref::RegRef, tag::Tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) + tag_time = isnothing(tag_time) ? now(get_time_tracker(ref)) : tag_time id = isnothing(id) ? guid() : id push!(ref.reg.guids, id) ref.reg.tag_info[id] = (tag, ref.idx, tag_time) @@ -299,8 +300,8 @@ for (tagsymbol, tagvariant) in pairs(tag_types) args = (:a, :b, :c, :d, :e, :f, :g)[1:length(sig)] argssig = [:($a::$t) for (a,t) in zip(args, sig)] - eval(quote function tag!(ref::RegRef, $(argssig...); tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) - tag!(ref, ($tagvariant)($(args...)); tag_time=tag_time, id=id) + eval(quote function tag!(ref::RegRef, $(argssig...); kwa...) + tag!(ref, ($tagvariant)($(args...)); kwa...) end end) eval(quote function Tag($(argssig...)) diff --git a/test/test_entanglement_consumer.jl b/test/test_entanglement_consumer.jl index 2b8279a..1dc7b5e 100644 --- a/test/test_entanglement_consumer.jl +++ b/test/test_entanglement_consumer.jl @@ -13,7 +13,6 @@ end for i in 1:30, n in 3:30 - @show i, n net = RegisterNet([Register(10) for j in 1:n]) sim = get_time_tracker(net) From b702261bacb18552c5db09563f64398353a87d0c Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Fri, 3 May 2024 21:03:29 -0400 Subject: [PATCH 10/33] update test_tags_and_queries.jl --- test/test_tags_and_queries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index df7cdd3..cb8b9ec 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -32,9 +32,9 @@ tag!(r[5], Int, 4, 5) @test query(r[2], :symbol1, 4, ❓) == (slot=r[2], id=2, tag=Tag(:symbol1, 4, 5)) @test queryall(r[2], :symbol1, 4, ❓) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] -@test querydelete!(r[2], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 5), 2, nothing) +@test querydelete!(r[2], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 5), 2, 0.0) @test querydelete!(r[2], :symbol1, 4, ❓) === nothing -@test querydelete!(r[3], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 1), 3, nothing) +@test querydelete!(r[3], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 1), 3, 0.0) # tests for fifo and filo order queries (default is filo) From 13c7a058bb5ed8de81c11d9bed9a5980221365d0 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 7 May 2024 20:14:30 -0400 Subject: [PATCH 11/33] use `_querydelete` for both registers and refs --- src/queries.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 10942aa..c1cdad4 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -267,8 +267,12 @@ $TYPEDSIGNATURES A [`query`](@ref) for [`Register`](@ref) that also deletes the tag from the tag dictionary for the `Register`. """ -function querydelete!(reg::Register, args...;ref=nothing, filo=true) - r = query(reg, args...;ref=ref, filo=filo) +function querydelete!(reg::Register, args...; kwa...) + _querydelete(reg, args...; filo=filo) +end + +function _querydelete!(reg::Register, args...; kwa...) + r = query(reg, args...; kwa...) ret = !isnothing(r) ? reg.tag_info[r.id] : return nothing untag!(r.slot, r.id) return ret @@ -280,8 +284,8 @@ $TYPEDSIGNATURES A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag list for the `RegRef`. Allows the user to specify order of accessing tags to be FILO or FIFO. """ -function querydelete!(ref::RegRef, args...;filo=true) - querydelete!(ref.reg, args...;ref=ref,filo=filo) +function querydelete!(ref::RegRef, args...; filo=true) + _querydelete!(ref.reg, args...;ref=ref,filo=filo) end From b9481d6f42e6489db743562fd67c9c2a5b8ed49c Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 7 May 2024 20:16:01 -0400 Subject: [PATCH 12/33] Version bump for breaking release --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 3abbbec..ee45d01 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "QuantumSavory" uuid = "2de2e421-972c-4cb5-a0c3-999c85908079" authors = ["Stefan Krastanov "] -version = "0.3.4" +version = "0.4.0" [deps] Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" From 691911f970cc16804c42da2123273133ae0cfa05 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 7 May 2024 21:23:10 -0400 Subject: [PATCH 13/33] some more refinement on query interface --- src/queries.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index c1cdad4..d80e5d3 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -125,8 +125,8 @@ julia> query(r, Int, 4, <(7)) See also: [`queryall`](@ref), [`tag!`](@ref), [`W`](@ref), [`❓`](@ref) """ -function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true, ref=nothing) where {allB} - _query(reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned, ref=ref) +function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true) where {allB} + _query(reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned) end function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref=nothing) where {allB, filoB} @@ -267,12 +267,12 @@ $TYPEDSIGNATURES A [`query`](@ref) for [`Register`](@ref) that also deletes the tag from the tag dictionary for the `Register`. """ -function querydelete!(reg::Register, args...; kwa...) - _querydelete(reg, args...; filo=filo) +function querydelete!(reg::Register, args...; filo=true, kwa...) + _querydelete(reg, args...; filo=filo, kwa...) end -function _querydelete!(reg::Register, args...; kwa...) - r = query(reg, args...; kwa...) +function _querydelete!(reg::Register, args...; ref=nothing, kwa...) + r = isnothing(ref) ? query(reg, args..., Val{false}(); kwa...) : query(ref, args..., Val{false}(), ; kwa...) ret = !isnothing(r) ? reg.tag_info[r.id] : return nothing untag!(r.slot, r.id) return ret @@ -284,8 +284,8 @@ $TYPEDSIGNATURES A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag list for the `RegRef`. Allows the user to specify order of accessing tags to be FILO or FIFO. """ -function querydelete!(ref::RegRef, args...; filo=true) - _querydelete!(ref.reg, args...;ref=ref,filo=filo) +function querydelete!(ref::RegRef, args...; filo=true, kwa...) + _querydelete!(ref.reg, args...;filo=filo, ref=ref, kwa...) end @@ -325,7 +325,7 @@ for (tagsymbol, tagvariant) in pairs(tag_types) argssig_wild = [:($a::$t) for (a,t) in zip(args, sig_wild)] wild_checks = [:(isa($(args[i]),Wildcard) || $(args[i])(tag[$i])) for i in idx] nonwild_checks = [:(tag[$i]==$(args[i])) for i in complement_idx] - newmethod_reg = quote function query(reg::Register, $(argssig_wild...), ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true, ref=nothing) where {allB} + newmethod_reg = quote function query(reg::Register, $(argssig_wild...), ::Val{allB}=Val{false}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, filo::Bool=true) where {allB} res = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] op_guid = filo ? reverse : identity for i in op_guid(reg.guids) @@ -333,7 +333,7 @@ for (tagsymbol, tagvariant) in pairs(tag_types) slot = reg[reg.tag_info[i][2]] if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol (_nothingor(locked, islocked(slot)) && _nothingor(assigned, isassigned(slot))) || continue - if _all($(nonwild_checks...)) && _all($(wild_checks...)) && (isnothing(ref) || (ref == slot)) + if _all($(nonwild_checks...)) && _all($(wild_checks...)) allB ? push!(res, (slot=slot, id=i, tag=tag)) : return (slot=slot, id=i, tag=tag) end end From 68273649f20714a325573525b36a5110f0b3cfc8 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 7 May 2024 21:33:43 -0400 Subject: [PATCH 14/33] update queries.jl --- src/queries.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/queries.jl b/src/queries.jl index d80e5d3..2be7a89 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -56,6 +56,7 @@ $TYPEDSIGNATURES A query function that returns all slots of a register that have a given tag, with support for predicates and wildcards. ```jldoctest +julia> QuantumSavory.glcnt[] = 0; julia> r = Register(10); tag!(r[1], :symbol, 2, 3); tag!(r[2], :symbol, 4, 5); From 0900da9025d57e0597753419e1d71d82568b8cff Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt <46929125+Abhishek-1Bhatt@users.noreply.github.com> Date: Wed, 8 May 2024 13:17:44 -0400 Subject: [PATCH 15/33] Update queries.jl --- src/queries.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/queries.jl b/src/queries.jl index 2be7a89..657ad13 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -57,6 +57,7 @@ A query function that returns all slots of a register that have a given tag, wit ```jldoctest julia> QuantumSavory.glcnt[] = 0; + julia> r = Register(10); tag!(r[1], :symbol, 2, 3); tag!(r[2], :symbol, 4, 5); From 0540e90748b945d6d24f4d2d9f63b6008114c6bd Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 16 May 2024 14:42:54 -0400 Subject: [PATCH 16/33] Apply suggestions from code review --- src/queries.jl | 9 ++++----- test/test_tags_and_queries.jl | 16 ++++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 657ad13..154fa92 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -3,14 +3,13 @@ Assign a tag to a slot in a register. See also: [`query`](@ref), [`untag!`](@ref)""" -function tag!(ref::RegRef, tag::Tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) - tag_time = isnothing(tag_time) ? now(get_time_tracker(ref)) : tag_time - id = isnothing(id) ? guid() : id +function tag!(ref::RegRef, tag::Tag) + id = guid() push!(ref.reg.guids, id) - ref.reg.tag_info[id] = (tag, ref.idx, tag_time) + ref.reg.tag_info[id] = (tag, ref.idx, now(get_time_tracker(ref))) end -tag!(ref, tag; tag_time::Union{Float64, Nothing}=nothing, id::Union{Int128, Nothing}=nothing) = tag!(ref,Tag(tag); tag_time=tag_time, id=id) +tag!(ref, tag) = tag!(ref,Tag(tag)) """$TYPEDSIGNATURES diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index cb8b9ec..fec1ffd 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -5,6 +5,10 @@ using Test @test tag_types.SymbolIntInt(:symbol1, 4, 5) == Tag(:symbol1, 4, 5) +function strip_id(info_vector) + return [(slot=n.slot, tag=n.tag) for n in info_vector] +end + r = Register(10) tag!(r[1], :symbol1, 2, 3) tag!(r[2], :symbol1, 4, 5) @@ -95,15 +99,15 @@ end @test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=false) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) @test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=true) == (slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart,1,314)) -@test queryall(reg, EntanglementCounterpart, 1, ❓) == [(slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], id = 33, tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], id = 29, tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], id = 28, tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], id = 25, tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], id = 21, tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], id = 20, tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], id = 17, tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart, 1, 12))] -@test queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) == [(slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], id = 33, tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], id = 29, tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], id = 28, tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], id = 25, tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], id = 21, tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], id = 20, tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], id = 17, tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart, 1, 12))] -@test queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) == reverse([(slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], id = 33, tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], id = 29, tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], id = 28, tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], id = 25, tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], id = 21, tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], id = 20, tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], id = 17, tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart, 1, 12))]) +@test strip_id(queryall(reg, EntanglementCounterpart, 1, ❓)) == [(slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 12))] +@test strip_id(queryall(reg, EntanglementCounterpart, 1, ❓; filo=true)) == [(slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 12))] +@test strip_id(queryall(reg, EntanglementCounterpart, 1, ❓; filo=false)) == reverse([(slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 12))]) @test query(reg, EntanglementCounterpart, 2, 22) == (slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)) -@test queryall(reg, EntanglementCounterpart, 2, 22) == [(slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], id = 14, tag = Tag(EntanglementCounterpart,2,22))] -@test queryall(reg, Tag(EntanglementCounterpart, 2, 22)) == [(slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], id = 14, tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] @test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) -@test queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) == [(slot = reg[2], id = 14, tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] @test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) reg = Register(4) From 9930bac430c2971ebdd91816572fcab21279b8f0 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 19:00:01 -0400 Subject: [PATCH 17/33] remove misleading keyword argument from `querydelete!(::MessageBuffer)` - the keyword was not actually used anywhere - message buffer queries are first-in-first-out, not filo --- src/queries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 154fa92..5c28db3 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -6,7 +6,7 @@ See also: [`query`](@ref), [`untag!`](@ref)""" function tag!(ref::RegRef, tag::Tag) id = guid() push!(ref.reg.guids, id) - ref.reg.tag_info[id] = (tag, ref.idx, now(get_time_tracker(ref))) + ref.reg.tag_info[id] = (tag, ref.idx, now(get_time_tracker(ref))) end tag!(ref, tag) = tag!(ref,Tag(tag)) @@ -258,7 +258,7 @@ t=1.0: query returns nothing t=3.0: query returns SymbolIntInt(:second_tag, 123, 456)::Tag received from node 3 ``` """ -function querydelete!(mb::MessageBuffer, args...;filo=true) +function querydelete!(mb::MessageBuffer, args...) r = query(mb, args...) return isnothing(r) ? nothing : popat!(mb.buffer, r.depth) end From c6f874e15ce423ff188eadc855b2c54835d36b37 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 19:06:16 -0400 Subject: [PATCH 18/33] remove internal implementation details from docstring --- src/queries.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries.jl b/src/queries.jl index 5c28db3..8ffb27d 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -266,7 +266,7 @@ end """ $TYPEDSIGNATURES -A [`query`](@ref) for [`Register`](@ref) that also deletes the tag from the tag dictionary for the `Register`. +A [`query`](@ref) for [`Register`](@ref) that also deletes the tag. """ function querydelete!(reg::Register, args...; filo=true, kwa...) _querydelete(reg, args...; filo=filo, kwa...) From 064d8a5800f7ea3c5be2e2f14d8adb3471e113e2 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 19:10:09 -0400 Subject: [PATCH 19/33] fix a typo leading to a broken `querydelete!(::Register)` and add doctest (note the need for a filter regex in the doctest) --- src/queries.jl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/queries.jl b/src/queries.jl index 8ffb27d..87f041b 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -267,9 +267,28 @@ end $TYPEDSIGNATURES A [`query`](@ref) for [`Register`](@ref) that also deletes the tag. + +```jldoctest; filter = r"id = (\\d*), " +julia> reg = Register(3) + tag!(reg[1], :tagA, 1, 2, 3) + tag!(reg[2], :tagA, 10, 20, 30) + tag!(reg[2], :tagB, 6, 7, 8); + +julia> queryall(reg, :tagA, ❓, ❓, ❓) +2-element Vector{@NamedTuple{slot::RegRef, id::Int128, tag::Tag}}: + (slot = Slot 2, id = 4, tag = SymbolIntIntInt(:tagA, 10, 20, 30)::Tag) + (slot = Slot 1, id = 3, tag = SymbolIntIntInt(:tagA, 1, 2, 3)::Tag) + +julia> querydelete!(reg, :tagA, ❓, ❓, ❓) +(SymbolIntIntInt(:tagA, 10, 20, 30)::Tag, 2, 0.0) + +julia> queryall(reg, :tagA, ❓, ❓, ❓) +1-element Vector{@NamedTuple{slot::RegRef, id::Int128, tag::Tag}}: + (slot = Slot 1, id = 3, tag = SymbolIntIntInt(:tagA, 1, 2, 3)::Tag) +``` """ function querydelete!(reg::Register, args...; filo=true, kwa...) - _querydelete(reg, args...; filo=filo, kwa...) + _querydelete!(reg, args...; filo=filo, kwa...) end function _querydelete!(reg::Register, args...; ref=nothing, kwa...) From 5264da149b48d00ef2677afa9c2c107a2058978b Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 22:40:44 -0400 Subject: [PATCH 20/33] simplify querydelete! (needs updating tests) --- src/queries.jl | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 87f041b..7b6f06f 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -266,7 +266,7 @@ end """ $TYPEDSIGNATURES -A [`query`](@ref) for [`Register`](@ref) that also deletes the tag. +A [`query`](@ref) for [`Register`](@ref) or a register slot (i.e. a [`RefRef`](@ref)) that also deletes the tag. ```jldoctest; filter = r"id = (\\d*), " julia> reg = Register(3) @@ -280,32 +280,17 @@ julia> queryall(reg, :tagA, ❓, ❓, ❓) (slot = Slot 1, id = 3, tag = SymbolIntIntInt(:tagA, 1, 2, 3)::Tag) julia> querydelete!(reg, :tagA, ❓, ❓, ❓) -(SymbolIntIntInt(:tagA, 10, 20, 30)::Tag, 2, 0.0) +(slot = Slot 2, id = 4, tag = SymbolIntIntInt(:tagA, 10, 20, 30)::Tag) julia> queryall(reg, :tagA, ❓, ❓, ❓) 1-element Vector{@NamedTuple{slot::RegRef, id::Int128, tag::Tag}}: (slot = Slot 1, id = 3, tag = SymbolIntIntInt(:tagA, 1, 2, 3)::Tag) ``` """ -function querydelete!(reg::Register, args...; filo=true, kwa...) - _querydelete!(reg, args...; filo=filo, kwa...) -end - -function _querydelete!(reg::Register, args...; ref=nothing, kwa...) - r = isnothing(ref) ? query(reg, args..., Val{false}(); kwa...) : query(ref, args..., Val{false}(), ; kwa...) - ret = !isnothing(r) ? reg.tag_info[r.id] : return nothing - untag!(r.slot, r.id) - return ret -end - -""" -$TYPEDSIGNATURES - -A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag list for the `RegRef`. -Allows the user to specify order of accessing tags to be FILO or FIFO. -""" -function querydelete!(ref::RegRef, args...; filo=true, kwa...) - _querydelete!(ref.reg, args...;filo=filo, ref=ref, kwa...) +function querydelete!(reg::Union{Register,RegRef}, args...; kwa...) + r = query(reg, args..., Val{false}(); kwa...) + isnothing(r) || untag!(r.slot, r.id) + return r end From 266f26a75a7b54cd9e669dfd60fcfea407aafc6c Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 22:43:09 -0400 Subject: [PATCH 21/33] clean up and simplify the first 45 lines of tests --- test/test_tags_and_queries.jl | 36 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index fec1ffd..6ba5586 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -5,10 +5,12 @@ using Test @test tag_types.SymbolIntInt(:symbol1, 4, 5) == Tag(:symbol1, 4, 5) -function strip_id(info_vector) - return [(slot=n.slot, tag=n.tag) for n in info_vector] +function strip_id(query_result) + return (;slot=query_result.slot, tag=query_result.tag) end +strip_id(::Nothing) = nothing + r = Register(10) tag!(r[1], :symbol1, 2, 3) tag!(r[2], :symbol1, 4, 5) @@ -16,31 +18,31 @@ tag!(r[3], :symbol1, 4, 1) tag!(r[5], Int, 4, 5) @test Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3) -@test query(r, :symbol1, 4, ❓) == (slot=r[3], id=3, tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) -@test query(r, :symbol1, 4, 5) == (slot=r[2], id=2, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) -@test query(r, :symbol1, ❓, ❓) == (slot=r[3], id=3, tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order +@test strip_id(query(r, :symbol1, 4, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) +@test strip_id(query(r, :symbol1, 4, 5)) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) +@test strip_id(query(r, :symbol1, ❓, ❓)) == (slot=r[3], tag=tag_types.SymbolIntInt(:symbol1, 4, 1)) #returns latest tag in filo order @test query(r, :symbol2, ❓, ❓) == nothing -@test query(r, Int, 4, 5) == (slot=r[5], id=4, tag=tag_types.TypeIntInt(Int, 4, 5)) +@test strip_id(query(r, Int, 4, 5)) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) @test query(r, Float32, 4, 5) == nothing @test query(r, Int, 4, >(5)) == nothing -@test query(r, Int, 4, <(6)) == (slot=r[5], id=4, tag=tag_types.TypeIntInt(Int, 4, 5)) +@test strip_id(query(r, Int, 4, <(6))) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5)) -@test queryall(r, :symbol1, ❓, ❓) == [(slot=r[3], id=3, tag=tag_types.SymbolIntInt(:symbol1, 4, 1)), (slot=r[2], id=2, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)), (slot=r[1], id=1, tag=tag_types.SymbolIntInt(:symbol1, 2, 3))] # filo by default +@test strip_id.(queryall(r, :symbol1, ❓, ❓)) == [(slot=r[3], tag=Tag(:symbol1, 4, 1)), (slot=r[2], tag=Tag(:symbol1, 4, 5)), (slot=r[1], tag=Tag(:symbol1, 2, 3))] # filo by default @test isempty(queryall(r, :symbol2, ❓, ❓)) -@test query(r[2], Tag(:symbol1, 4, 5)) == (slot=r[2], id=2, tag=tag_types.SymbolIntInt(:symbol1, 4, 5)) -@test queryall(r[2], Tag(:symbol1, 4, 5)) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] -@test query(r[2], :symbol1, 4, 5) == (slot=r[2], id=2, tag=Tag(:symbol1, 4, 5)) -@test queryall(r[2], :symbol1, 4, 5) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] +@test strip_id(query(r[2], Tag(:symbol1, 4, 5))) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test strip_id.(queryall(r[2], Tag(:symbol1, 4, 5))) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] +@test strip_id(query(r[2], :symbol1, 4, 5)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test strip_id.(queryall(r[2], :symbol1, 4, 5)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] -@test query(r[2], :symbol1, 4, ❓) == (slot=r[2], id=2, tag=Tag(:symbol1, 4, 5)) -@test queryall(r[2], :symbol1, 4, ❓) == [(slot=r[2], id=2, tag=Tag(:symbol1, 4, 5))] +@test strip_id(query(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) +@test strip_id.(queryall(r[2], :symbol1, 4, ❓)) == [(slot=r[2], tag=Tag(:symbol1, 4, 5))] -@test querydelete!(r[2], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 5), 2, 0.0) +@test strip_id(querydelete!(r[2], :symbol1, 4, ❓)) == (slot=r[2], tag=Tag(:symbol1, 4, 5)) @test querydelete!(r[2], :symbol1, 4, ❓) === nothing -@test querydelete!(r[3], :symbol1, 4, ❓) == (Tag(:symbol1, 4, 1), 3, 0.0) - +@test strip_id(querydelete!(r[3], :symbol1, 4, ❓)) == (slot=r[3], tag=Tag(:symbol1, 4, 1)) +## # tests for fifo and filo order queries (default is filo) # for RegRefs From cfc02adc6e1e9fa1c21e321bbd88a973d8e6c419 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 22:59:00 -0400 Subject: [PATCH 22/33] clean up and simplify the tests up to line 80 --- test/test_tags_and_queries.jl | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index 6ba5586..a583942 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -48,32 +48,35 @@ tag!(r[5], Int, 4, 5) reg = Register(5) tag!(reg[3], EntanglementCounterpart, 1, 10) -tag!(reg[3], EntanglementCounterpart, 2, 20) +tag!(reg[3], EntanglementCounterpart, 2, 21) tag!(reg[3], EntanglementCounterpart, 3, 30) -tag!(reg[3], EntanglementCounterpart, 2, 20) +tag!(reg[3], EntanglementCounterpart, 2, 22) tag!(reg[3], EntanglementCounterpart, 1, 10) tag!(reg[3], EntanglementCounterpart, 6, 60) -tag!(reg[3], EntanglementCounterpart, 2, 20) +tag!(reg[3], EntanglementCounterpart, 2, 23) tag!(reg[3], EntanglementCounterpart, 1, 10) @test query(reg[3], EntanglementCounterpart, 1, 11) === nothing -@test query(reg[3], EntanglementCounterpart, 1, 10) == (slot = reg[3], id = 12, tag = Tag(EntanglementCounterpart,1,10)) -@test query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=false) == (slot = reg[3], id = 5, tag = Tag(EntanglementCounterpart,1,10)) -@test query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=true) == (slot = reg[3], id = 12, tag = Tag(EntanglementCounterpart,1,10)) +@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) +@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) +@test strip_id(query(reg[3], EntanglementCounterpart, 1, 10, Val(false); filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,1,10)) +@test query(reg[3], EntanglementCounterpart, 1, 10; filo=true).id > query(reg[3], EntanglementCounterpart, 1, 10; filo=false).id +@test query(reg[3], EntanglementCounterpart, 2, ❓; filo=true).tag[3] == 23 +@test query(reg[3], EntanglementCounterpart, 2, ❓; filo=false).tag[3] == 21 -@test query(reg[3], EntanglementCounterpart, 2, ❓) == (slot = reg[3], id = 11, tag = Tag(EntanglementCounterpart,2,20)) -@test query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=false) == (slot = reg[3], id = 6, tag = Tag(EntanglementCounterpart,2,20)) -@test query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=true) == (slot = reg[3], id = 11, tag = Tag(EntanglementCounterpart,2,20)) +@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) +@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=false)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,21)) +@test strip_id(query(reg[3], EntanglementCounterpart, 2, ❓, Val(false); filo=true)) == (slot = reg[3], tag = Tag(EntanglementCounterpart,2,23)) @test queryall(reg, EntanglementCounterpart, 1, 11) == [] -@test queryall(reg[3], EntanglementCounterpart, 1, 10) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] -@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (5, 9, 12)] -@test queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,1,10)) for i in (12, 9, 5)] - -@test queryall(reg[3], EntanglementCounterpart, 2, ❓) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (11, 8, 6)] -@test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=false) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (6, 8, 11)] -@test queryall(reg[3], EntanglementCounterpart, 2, ❓; filo=true) == [(slot = reg[3], id = i, tag = Tag(EntanglementCounterpart,2,20)) for i in (11, 8, 6)] +default_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10)] +@test default_ids == sort(default_ids, rev=true) +fifo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=false)] +@test fifo_ids == sort(fifo_ids) +filo_ids = [r.id for r in queryall(reg[3], EntanglementCounterpart, 1, 10; filo=true)] +@test filo_ids == default_ids +## # tests for fifo and filo order queries (default is filo) # for Register From 504aeb7f8fc20a92b63745ad98df8e76ba493539 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 23:39:02 -0400 Subject: [PATCH 23/33] clean up and simplify the rest of the tests --- test/test_tags_and_queries.jl | 40 +++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/test/test_tags_and_queries.jl b/test/test_tags_and_queries.jl index a583942..d0fcc91 100644 --- a/test/test_tags_and_queries.jl +++ b/test/test_tags_and_queries.jl @@ -93,26 +93,34 @@ for i in 2:4 end @test query(reg, EntanglementCounterpart, 1, 10) === nothing -@test query(reg, EntanglementCounterpart, 1, 12) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, 12)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) @test query(reg, EntanglementCounterpart, 1, 12) == query(reg, EntanglementCounterpart, ==(1), ==(12)) @test query(reg, Tag(EntanglementCounterpart, 1, 10)) === nothing -@test query(reg, Tag(EntanglementCounterpart, 1, 12)) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=false) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=true) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, Tag(EntanglementCounterpart, 1, 12))) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=true)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) @test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=false) == query(reg, EntanglementCounterpart, 1, ==(12), Val(false); filo=false) @test query(reg, EntanglementCounterpart, 1, 12, Val(false); filo=true) == query(reg, EntanglementCounterpart, 1, ==(12), Val(false); filo=true) -@test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=false) == (slot = reg[2], id = 13, tag = Tag(EntanglementCounterpart,1,12)) -@test query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=true) == (slot = reg[4], id = 36, tag = Tag(EntanglementCounterpart,1,314)) - -@test strip_id(queryall(reg, EntanglementCounterpart, 1, ❓)) == [(slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 12))] -@test strip_id(queryall(reg, EntanglementCounterpart, 1, ❓; filo=true)) == [(slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 12))] -@test strip_id(queryall(reg, EntanglementCounterpart, 1, ❓; filo=false)) == reverse([(slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 314)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 114)), (slot = reg[4], tag = Tag(EntanglementCounterpart, 1, 14)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 313)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 113)), (slot = reg[3], tag = Tag(EntanglementCounterpart, 1, 13)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 312)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 112)), (slot = reg[2], tag = Tag(EntanglementCounterpart, 1, 12))]) - -@test query(reg, EntanglementCounterpart, 2, 22) == (slot = reg[2], id = 19, tag = Tag(EntanglementCounterpart,2,22)) -@test strip_id(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] -@test strip_id(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id(query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=false)) == (slot = reg[2], tag = Tag(EntanglementCounterpart,1,12)) +@test strip_id(query(reg, EntanglementCounterpart, 1, ❓, Val(false); filo=true)) == (slot = reg[4], tag = Tag(EntanglementCounterpart,1,314)) + +default_res = queryall(reg, EntanglementCounterpart, 1, ❓) +default_res_id = [r.id for r in default_res] +@test strip_id.(default_res) == reverse([(slot = reg[i], tag = Tag(EntanglementCounterpart, 1, j+i)) for i in 2:4 for j in (10,110,310)]) +@test default_res_id == reverse(sort(default_res_id)) +filo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=true) +filo_res_id = [r.id for r in filo_res] +@test strip_id.(filo_res) == strip_id.(default_res) +@test filo_res_id == default_res_id +fifo_res = queryall(reg, EntanglementCounterpart, 1, ❓; filo=false) +fifo_res_id = [r.id for r in fifo_res] +@test strip_id.(fifo_res) == reverse(strip_id.(default_res)) +@test fifo_res_id == sort(fifo_res_id) + +@test strip_id.(queryall(reg, EntanglementCounterpart, 2, 22)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22))) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] @test queryall(reg, EntanglementCounterpart, 2, 22) == queryall(reg, EntanglementCounterpart, ==(2), ==(22)) == queryall(reg, Tag(EntanglementCounterpart, 2, 22)) -@test strip_id(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] +@test strip_id.(queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false)) == [(slot = reg[2], tag = Tag(EntanglementCounterpart,2,22)), (slot = reg[2], tag = Tag(EntanglementCounterpart,2,22))] @test queryall(reg, EntanglementCounterpart, 2, 22; filo=false) == queryall(reg, EntanglementCounterpart, ==(2), ==(22); filo=false) == queryall(reg, Tag(EntanglementCounterpart, 2, 22); filo=false) reg = Register(4) @@ -127,4 +135,4 @@ tag!(reg[1], EntanglementCounterpart, 4, 9) querydelete!(reg[1], EntanglementCounterpart, 4, 9) @test [reg.tag_info[i][1] for i in reg.guids] == [Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] querydelete!(reg[1], EntanglementCounterpart, 4, 9;filo=false) -@test [reg.tag_info[i][1] for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] \ No newline at end of file +@test [reg.tag_info[i][1] for i in reg.guids] == [Tag(EntanglementCounterpart, 5, 2), Tag(EntanglementCounterpart, 7, 7), Tag(EntanglementCounterpart, 4, 9), Tag(EntanglementCounterpart, 2, 3)] From 86c367e6d9e849b298a203185410be94ec9308d2 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 23:49:40 -0400 Subject: [PATCH 24/33] fixup for a previous change --- src/ProtocolZoo/ProtocolZoo.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index de684dc..3cb29d9 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -174,7 +174,7 @@ end margin = isentangled ? prot.margin : prot.hardmargin a = findfreeslot(prot.net[prot.nodeA]; randomize=prot.randomize, margin=margin) b = findfreeslot(prot.net[prot.nodeB]; randomize=prot.randomize, margin=margin) - + if isnothing(a) || isnothing(b) isnothing(prot.retry_lock_time) && error("We do not yet support waiting on register to make qubits available") # TODO @debug "EntanglerProt between $(prot.nodeA) and $(prot.nodeB)|round $(round): Failed to find free slots. \n Got:\n \t $a \n \t $b \n retrying..." @@ -362,7 +362,7 @@ end ❓) # which local slot used to be entangled with whom we swapped with if !isnothing(history) # @debug "tracker @$(prot.node) history: $(history) | msg: $msg" - _, _, _, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx = history[1] + _, _, _, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx = history.tag tag!(localslot, EntanglementHistory, newremotenode, newremoteslotid, whoweswappedwith_node, whoweswappedwith_slotidx, swappedlocal_slotidx) @debug "EntanglementTracker @$(prot.node): history=`$(history)` | message=`$msg` | Sending to $(whoweswappedwith_node).$(whoweswappedwith_slotidx)" msghist = Tag(updatetagsymbol, pastremotenode, pastremoteslotid, whoweswappedwith_slotidx, newremotenode, newremoteslotid, correction) @@ -423,8 +423,8 @@ end continue end end - - q1 = query1.slot + + q1 = query1.slot q2 = query2.slot @yield lock(q1) & lock(q2) From d64515defe9d8fae2ce440fbab22880772dc2176 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 23:50:30 -0400 Subject: [PATCH 25/33] speed up test_entanglement_consumer (noticed it takes 5 minutes just for that test) --- test/test_entanglement_consumer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_entanglement_consumer.jl b/test/test_entanglement_consumer.jl index 1dc7b5e..10de2d3 100644 --- a/test/test_entanglement_consumer.jl +++ b/test/test_entanglement_consumer.jl @@ -12,7 +12,7 @@ if isinteractive() end -for i in 1:30, n in 3:30 +n in 3:30 net = RegisterNet([Register(10) for j in 1:n]) sim = get_time_tracker(net) From 858002a334e8f04405f10fd0b49043c3761e595f Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 23:51:00 -0400 Subject: [PATCH 26/33] minor fixup in doctest runner --- test/test_doctests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_doctests.jl b/test/test_doctests.jl index 3c60f88..3f1ee2f 100644 --- a/test/test_doctests.jl +++ b/test/test_doctests.jl @@ -4,7 +4,7 @@ using QuantumSavory function doctests() @testset "Doctests" begin - DocMeta.setdocmeta!(QuantumSavory, :DocTestSetup, :(using QuantumSavory; using QuantumSavory.CircuitZoo; using Graphs); recursive=true) + DocMeta.setdocmeta!(QuantumSavory, :DocTestSetup, :(using QuantumSavory; using QuantumSavory.CircuitZoo; using QuantumSavory.ProtocolZoo; using QuantumSavory.StatesZoo; using Graphs); recursive=true) doctest(QuantumSavory; #fix=true ) From f254e677268e76ef53f6a6c7b6752c538a8569f8 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Mon, 20 May 2024 23:53:10 -0400 Subject: [PATCH 27/33] fixup --- test/test_entanglement_consumer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_entanglement_consumer.jl b/test/test_entanglement_consumer.jl index 10de2d3..4581bc6 100644 --- a/test/test_entanglement_consumer.jl +++ b/test/test_entanglement_consumer.jl @@ -12,7 +12,7 @@ if isinteractive() end -n in 3:30 +for n in 3:30 net = RegisterNet([Register(10) for j in 1:n]) sim = get_time_tracker(net) From 92e87c94670e5be258448580100bf0541702d82e Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 21 May 2024 00:08:45 -0400 Subject: [PATCH 28/33] remove internal implementation details from docstring --- src/queries.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 7b6f06f..c889edb 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -18,7 +18,7 @@ Removes the first instance of tag from the list to tags associated with a [`RegR See also: [`query`](@ref), [`tag!`](@ref) """ -function untag!(ref::RegRef, id::Int128) # TODO rather slow implementation. See issue #74 +function untag!(ref::RegRef, id::Int128) i = findfirst(==(id), ref.reg.guids) isnothing(i) ? throw(KeyError(tag)) : deleteat!(ref.reg.guids, i) # TODO make sure there is a clear error message delete!(ref.reg.tag_info, id) @@ -54,9 +54,7 @@ $TYPEDSIGNATURES A query function that returns all slots of a register that have a given tag, with support for predicates and wildcards. -```jldoctest -julia> QuantumSavory.glcnt[] = 0; - +```jldoctest; filter = r"id = (\\d*), " julia> r = Register(10); tag!(r[1], :symbol, 2, 3); tag!(r[2], :symbol, 4, 5); From f149b0c46391f3307affff83d6ad8f86eaa00be5 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 21 May 2024 00:19:16 -0400 Subject: [PATCH 29/33] minor simplification of _query for style consistency --- src/queries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index c889edb..ccbedd1 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -128,12 +128,12 @@ function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{ _query(reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned) end -function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref=nothing) where {allB, filoB} +function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref::Union{Nothing,Int}=nothing) where {allB, filoB} result = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] op_guid = filoB ? reverse : identity for i in op_guid(reg.guids) slot = reg[reg.tag_info[i][2]] - if reg.tag_info[i][1] == tag && (isnothing(ref) || (ref == slot)) # Need to check slot when calling from `query` dispatch on RegRef + if reg.tag_info[i][1] == tag && _nothingor(ref, slot) # Need to check slot when calling from `query` dispatch on RegRef if _nothingor(locked, islocked(slot) && _nothingor(assigned, isassigned(slot))) allB ? push!(result, (slot=slot, id=i, tag=reg.tag_info[i][1])) : return (slot=slot, id=i, tag=reg.tag_info[i][1]) end From f0709acfaf8946a6b705ec85fcfe9f80c4bc21a7 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 21 May 2024 00:20:26 -0400 Subject: [PATCH 30/33] remove unused keyword argument from `tag!` --- src/queries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index ccbedd1..3b4f025 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -307,8 +307,8 @@ for (tagsymbol, tagvariant) in pairs(tag_types) args = (:a, :b, :c, :d, :e, :f, :g)[1:length(sig)] argssig = [:($a::$t) for (a,t) in zip(args, sig)] - eval(quote function tag!(ref::RegRef, $(argssig...); kwa...) - tag!(ref, ($tagvariant)($(args...)); kwa...) + eval(quote function tag!(ref::RegRef, $(argssig...)) + tag!(ref, ($tagvariant)($(args...))) end end) eval(quote function Tag($(argssig...)) From 6f5fc67af0d75ab01428fa6099ac9e984d7c0589 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 21 May 2024 00:23:17 -0400 Subject: [PATCH 31/33] fixup --- src/queries.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries.jl b/src/queries.jl index 3b4f025..4e79745 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -128,7 +128,7 @@ function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{ _query(reg, tag, Val{allB}(), Val{filo}(); locked=locked, assigned=assigned) end -function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref::Union{Nothing,Int}=nothing) where {allB, filoB} +function _query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{filoB}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing, ref=nothing) where {allB, filoB} result = NamedTuple{(:slot, :id, :tag), Tuple{RegRef, Int128, Tag}}[] op_guid = filoB ? reverse : identity for i in op_guid(reg.guids) From 48f624088520bd43fdeb3ea7b041733e217ad412 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 21 May 2024 00:30:00 -0400 Subject: [PATCH 32/33] more filter fixes to docstrings --- src/queries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index 4e79745..d0b6c28 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -87,7 +87,7 @@ whether the given slot is locked or whether it contains a quantum state. The keyword argument `filo` can be used to specify whether the search should be done in a FIFO or FILO order, defaulting to `filo=true` (i.e. a stack-like behavior). -```jldoctest +```jldoctest; filter = r"id = (\\d*), " julia> r = Register(10); tag!(r[1], :symbol, 2, 3); tag!(r[2], :symbol, 4, 5); @@ -148,7 +148,7 @@ $TYPEDSIGNATURES A [`query`](@ref) on a single slot of a register. -```jldoctest +```jldoctest; filter = r"id = (\\d*), " julia> r = Register(5); julia> tag!(r[2], :symbol, 2, 3); From 2b3f537c90570ea5e18b143ea0452fc389ffa0a6 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 21 May 2024 00:43:53 -0400 Subject: [PATCH 33/33] fixup --- src/queries.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries.jl b/src/queries.jl index d0b6c28..44d2979 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -264,7 +264,7 @@ end """ $TYPEDSIGNATURES -A [`query`](@ref) for [`Register`](@ref) or a register slot (i.e. a [`RefRef`](@ref)) that also deletes the tag. +A [`query`](@ref) for [`Register`](@ref) or a register slot (i.e. a [`RegRef`](@ref)) that also deletes the tag. ```jldoctest; filter = r"id = (\\d*), " julia> reg = Register(3)