From e2022aec60bb537d23573d66961149dc39a2270b Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 25 Jan 2024 13:44:41 -0500 Subject: [PATCH 01/15] added Query Interface and some doc fixes --- docs/make.jl | 1 + docs/src/query_interface.md | 120 ++++++++++++++++++++++++++++++++++++ src/queries.jl | 14 ++--- 3 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 docs/src/query_interface.md diff --git a/docs/make.jl b/docs/make.jl index adc93d8b..bc2603a7 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -30,6 +30,7 @@ function main() "Visualizations" => "visualizations.md", "Dev Documentation" => [ "Register Interface" => "register_interface.md", + "Query Interface" => "query_interface.md", ], ], "How-To Guides" => [ diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md new file mode 100644 index 00000000..e0a570dc --- /dev/null +++ b/docs/src/query_interface.md @@ -0,0 +1,120 @@ +# Query Interface + +```@meta +DocTestSetup = quote + using QuantumSavory +end +``` + + +## `Tag` +Tags are identifiers which are used to represent classical information needed for a quantum information. The library allows the construction of custom tags following the format of one of the [`tag_types`](@ref) using the `Tag` constructor. The library implements the following tags for use in the networking protocols: + +- `EntanglementCounterpart` + -`remote_node` + -`remote_slot` + It indicates the current entanglement status with a remote node's slot. + +- `EntanglementHistory` + - `remote_node` + - `remote_slot` + - `swap_remote_node` + - `swap_remote_slot` + - `swapped_local` + This tag is used to store the outdated entanglement information after a swap. It helps to direct incoming entanglement update messages to the right node after a swap. + +- `EntanglementUpdateX` + - `past_local_node` + - `past_local_slot` + - `past_remote_slot` + - `new_remote_node` + - `new_remote_slot` + - `correction` + This tag arrives as a message from a remote node to which the current node was entangled to updat the entanglement information and apply an `X` correction after the remote node performs an entanglement swap. + +- `EntanglementUpdateZ` + - `past_local_node` + - `past_local_slot` + - `past_remote_slot` + - `new_remote_node` + - `new_remote_slot` + - `correction` + This tag arrives as a message from a remote node to which the current node was entangled to updat the entanglement information and apply a `Z` correction after the remote node performs an entanglement swap. + +The tags are constructed using the `Tag` constructor +#### Tag(tagsymbol::Symbol, tagvariants...) +where `tagvariants` are the extra arguments required by the specific `tagsymbol`, for instance the `tag_types.SymbolIntInt` require two `Int` values. It supports the use of predicate functions (`Int -> Bool`) and [`Wildcard`](@ref) (❓) in place of the `tagvariants` which allows the user to perform queries for tags fulfilling certain criteria. + +## `tag!` +Adds a `Tag` to the list of tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) +#### `tag!(ref::RegRef, tag::Tag)` + +## `untag!` +Removes the first matching tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) +#### `untag!(ref::RegRef, tag::Tag)` + +## [`query`](@ref) + +[`query`](@ref) methods allow the user to query for `Tag`(s) in three different cases: +- on a particular qubit slot([`RegRef`](@ref)) in a [`Register`](@ref) node; +- on a [`Register`](@ref) to query for a slot that contains the passed `Tag`; and +- on a `MessageBuffer` to query for a particular `Tag` received from another node in a network. + +The following features are supported: +- The query methods specialized on [`RegRef`](@ref) and [`Register`](@ref) allow for the queries to be executed in `FIFO` or `FILO` order, which is set to be `FIFO` by default. This means by default, a query on a [`RegRef`](@ref) returns the `Tag` which is at the end of the vector of tags attribute in a [`Register`](@ref), as new tags are pushed to the back by [`tag!`](@ref). On a [`Register`](@ref) it returns the slot number with the highest index having the queried `Tag`. + +- The `Tag` passed to the method can be constructed using predicate functions (of the form: `Int` -> `Bool`) and [`Wildcard`](@ref) (❓). This supports querying for tags for which all the information is not known or isn't relevant, e.g, when looking for a qubit entangled with a neighbouring node in a repeater chain, we need a node that has a larger(right) or smaller(left) node number and the slot number of the neighbouring node to which its entangled is irrelevant. Hence, the `EntanglementCounterpart` tag passed to the [`query`](@ref) has a predicate `>(node)` or `<(node)` for `remote_node` and a [`Wildcard`](@ref) (❓) for `remote_slot` fields of the tag. + +- It can be specified that the target slot be locked(or unlocked) and assigned(or unassigned) using the `locked` and `assigned` keywords which take `Bool` values. By default, the [`query`](@ref) does not check for these properties. This is available for [`query`](@ref) methods defined on [`Register`](@ref) and [`RegRef`](@ref). + +#### `query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing)` + +#### `query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}())` + +#### `query(mb::MessageBuffer, tag::Tag)` + +## `querydelete!` +A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. + +#### `querydelete!(ref::RegRef, args...)` + +#### Interface Overview + +```@raw html +
+flowchart TB + A["querydelete!(ref::RegRef, args...)"] + B["query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}())"] + A --> B +
+``` + +#### `querydelete!(mb::MessageBuffer, args...)` + +#### Interface Overview + +```@raw html +
+flowchart TB + A["querydelete!(mb::MessageBuffer, args...)"] + B["query(mb::MessageBuffer, tag::Tag)"] + A --> B +
+``` + +## `queryall` +A method defined on top of [`query`](@ref) which allows to query for all tags in a [`RegRef`](@ref) or a [`Register`](@ref) that match the passed `Tag`, instead of just one matching instance. + +#### `queryall(args...; kwargs...)` + +where `args...` and `kwargs...` correspond to the arguments and keyword arguments accepted by the [`query`](@ref) method on the particular data structure on which the method is called upon. + +#### Interface Overview + +```@raw html +
+flowchart TB + A["queryall(args...; kwargs...)"] + B["query(args..., ::Val{allB}=Val{true}(), ::Val{fifo}=Val{true}; kwargs...)"] +
+``` \ No newline at end of file diff --git a/src/queries.jl b/src/queries.jl index 1af825ff..0db17ce7 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -142,7 +142,7 @@ function query(mb::MessageBuffer, tag::Tag) return isnothing(i) ? nothing : (;depth=i, src=mb.buffer[i][1], tag=mb.buffer[i][2]) end -raw"""A [`query`](@ref) for classical message buffers that also pops the message out of the buffer. +raw"""A [`query`](@ref) for classical message buffers that also deletes the message out of the buffer. ```jldoctest julia> net = RegisterNet([Register(3), Register(2)]) @@ -159,22 +159,22 @@ julia> run(get_time_tracker(net)) julia> query(messagebuffer(net, 2), :my_tag) (depth = 1, src = 1, tag = Symbol(:my_tag)::Tag) -julia> querypop!(messagebuffer(net, 2), :my_tag) +julia> querydelete!(messagebuffer(net, 2), :my_tag) (src = 1, tag = Symbol(:my_tag)::Tag) -julia> querypop!(messagebuffer(net, 2), :my_tag) === nothing +julia> querydelete!(messagebuffer(net, 2), :my_tag) === nothing true -julia> querypop!(messagebuffer(net, 2), :another_tag, ❓, ❓) +julia> querydelete!(messagebuffer(net, 2), :another_tag, ❓, ❓) (src = 1, tag = SymbolIntInt(:another_tag, 123, 456)::Tag) -julia> querypop!(messagebuffer(net, 2), :another_tag, ❓, ❓) === nothing +julia> querydelete!(messagebuffer(net, 2), :another_tag, ❓, ❓) === nothing true ``` You can also wait on a message buffer for a message to arrive before running a query: -```jldoctes +```jldoctest julia> net = RegisterNet([Register(3), Register(2), Register(3)]) A network of 3 registers in a graph of 2 edges @@ -184,7 +184,7 @@ julia> @resumable function receive_tags(env) while true mb = messagebuffer(net, 2) @yield wait(mb) - msg = querypop!(mb, :second_tag, ❓, ❓) + msg = querypodelete!(mb, :second_tag, ❓, ❓) print("t=$(now(env)): query returns ") if isnothing(msg) println("nothing") From 523493634c7e74e10ad0e1d1b2ca3565430d0b42 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 25 Jan 2024 13:47:07 -0500 Subject: [PATCH 02/15] typo --- src/queries.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries.jl b/src/queries.jl index 0db17ce7..c7835ed9 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -184,7 +184,7 @@ julia> @resumable function receive_tags(env) while true mb = messagebuffer(net, 2) @yield wait(mb) - msg = querypodelete!(mb, :second_tag, ❓, ❓) + msg = querydelete!(mb, :second_tag, ❓, ❓) print("t=$(now(env)): query returns ") if isnothing(msg) println("nothing") From 66e08ee44b1ddf65343d259bd7347b85ab5177bc Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 25 Jan 2024 16:40:52 -0500 Subject: [PATCH 03/15] fix SumTypes deprecation --- src/queries.jl | 4 ++-- src/tags.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/queries.jl b/src/queries.jl index c7835ed9..7f444c1c 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -257,8 +257,8 @@ for (tagsymbol, tagvariant) in pairs(tag_types) sig_wild = collect(sig) sig_wild[idx] .= Union{Wildcard,Function} argssig_wild = [:($a::$t) for (a,t) in zip(args, sig_wild)] - wild_checks = [:(isa($(args[i]),Wildcard) || $(args[i])(tag.data[$i])) for i in idx] - nonwild_checks = [:(tag.data[$i]==$(args[i])) for i in complement_idx] + 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) where {allB} res = NamedTuple{(:slot, :tag), Tuple{RegRef, Tag}}[] for (reg_idx, tags) in enumerate(reg.tags) diff --git a/src/tags.jl b/src/tags.jl index cb9e3de3..8af53368 100644 --- a/src/tags.jl +++ b/src/tags.jl @@ -24,9 +24,9 @@ end See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" const tag_types = Tag' -Base.getindex(tag::Tag, i::Int) = tag.data[i] -Base.length(tag::Tag) = length(tag.data.data) -Base.iterate(tag::Tag, state=1) = state > length(tag) ? nothing : (tag[state],state+1) +Base.getindex(tag::Tag, i::Int) = SumTypes.unwrap(tag)[i] +Base.length(tag::Tag) = length(SumTypes.unwrap(tag).data) +Base.iterate(tag::Tag, state=1) = state > length(tag) ? nothing : (SumTypes.unwrap(tag)[state],state+1) function SumTypes.show_sumtype(io::IO, x::Tag) data = SumTypes.unwrap(x) From cd5113f0a0293e96aff9a2ef905f79460f9e1806 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt <46929125+Abhishek-1Bhatt@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:33:00 -0500 Subject: [PATCH 04/15] Update docs/src/query_interface.md Co-authored-by: Stefan Krastanov --- docs/src/query_interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index e0a570dc..baa0b555 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -8,7 +8,7 @@ end ## `Tag` -Tags are identifiers which are used to represent classical information needed for a quantum information. The library allows the construction of custom tags following the format of one of the [`tag_types`](@ref) using the `Tag` constructor. The library implements the following tags for use in the networking protocols: +Tags are used to represent classical metadata describing the state and history of the nodes. The library allows the construction of custom tags following the format of one of the [`tag_types`](@ref) using the `Tag` constructor. The library implements the following tags for use in the networking protocols: - `EntanglementCounterpart` -`remote_node` From f4aafee0e6442f2f0555404c9bc2e8a62a407de0 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 30 Jan 2024 17:25:58 -0500 Subject: [PATCH 05/15] apply changes from code review --- docs/src/query_interface.md | 75 +++++++++++++++------------------- src/ProtocolZoo/ProtocolZoo.jl | 35 ++++++++++++++++ src/QuantumSavory.jl | 1 + src/queries.jl | 44 ++++++++++++++++---- 4 files changed, 104 insertions(+), 51 deletions(-) diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index baa0b555..8a49b3ba 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -5,57 +5,34 @@ DocTestSetup = quote using QuantumSavory end ``` +The query interface allows us to use various quantum networking protocols defined in QuantumSavory together in a simulation. It provides composability between the various protocols where each protocol can operate independently of the other without knowing its internals. This is done by using various tags to communicate metadata between the network nodes running the protocols. This leads to greater flexibility when setting up different simulations since the information about how the nodes running the protocols should interact is generally defined in the protocols and the specifics at runtime are determined by the tags passed and received. +The following lines explain in detail, the components of the query interface which make this possible. ## `Tag` Tags are used to represent classical metadata describing the state and history of the nodes. The library allows the construction of custom tags following the format of one of the [`tag_types`](@ref) using the `Tag` constructor. The library implements the following tags for use in the networking protocols: -- `EntanglementCounterpart` - -`remote_node` - -`remote_slot` - It indicates the current entanglement status with a remote node's slot. - -- `EntanglementHistory` - - `remote_node` - - `remote_slot` - - `swap_remote_node` - - `swap_remote_slot` - - `swapped_local` - This tag is used to store the outdated entanglement information after a swap. It helps to direct incoming entanglement update messages to the right node after a swap. - -- `EntanglementUpdateX` - - `past_local_node` - - `past_local_slot` - - `past_remote_slot` - - `new_remote_node` - - `new_remote_slot` - - `correction` - This tag arrives as a message from a remote node to which the current node was entangled to updat the entanglement information and apply an `X` correction after the remote node performs an entanglement swap. - -- `EntanglementUpdateZ` - - `past_local_node` - - `past_local_slot` - - `past_remote_slot` - - `new_remote_node` - - `new_remote_slot` - - `correction` - This tag arrives as a message from a remote node to which the current node was entangled to updat the entanglement information and apply a `Z` correction after the remote node performs an entanglement swap. +```@autodocs +Modules = [QuantumSavory.ProtocolZoo.EntanglementCounterpart, QuantumSavory.ProtocolZoo.EntanglementHistory, QuantumSavory.ProtocolZoo.EntanglementUpdateX, QuantumSavory.ProtocolZoo.EntanglementUpdateZ] +``` The tags are constructed using the `Tag` constructor #### Tag(tagsymbol::Symbol, tagvariants...) where `tagvariants` are the extra arguments required by the specific `tagsymbol`, for instance the `tag_types.SymbolIntInt` require two `Int` values. It supports the use of predicate functions (`Int -> Bool`) and [`Wildcard`](@ref) (❓) in place of the `tagvariants` which allows the user to perform queries for tags fulfilling certain criteria. ## `tag!` -Adds a `Tag` to the list of tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) -#### `tag!(ref::RegRef, tag::Tag)` +```@docs +Modules = [QuantumSavory.tag!] +``` ## `untag!` -Removes the first matching tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) -#### `untag!(ref::RegRef, tag::Tag)` +```@docs +Modules = [QuantumSavory.untag!] +``` ## [`query`](@ref) -[`query`](@ref) methods allow the user to query for `Tag`(s) in three different cases: +[`query`](@ref) function allow the user to query for `Tag`(s) in three different cases: - on a particular qubit slot([`RegRef`](@ref)) in a [`Register`](@ref) node; - on a [`Register`](@ref) to query for a slot that contains the passed `Tag`; and - on a `MessageBuffer` to query for a particular `Tag` received from another node in a network. @@ -67,16 +44,26 @@ The following features are supported: - It can be specified that the target slot be locked(or unlocked) and assigned(or unassigned) using the `locked` and `assigned` keywords which take `Bool` values. By default, the [`query`](@ref) does not check for these properties. This is available for [`query`](@ref) methods defined on [`Register`](@ref) and [`RegRef`](@ref). -#### `query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}(); locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing)` +Following is a detailed description of each `query` methods -#### `query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}())` +```@docs +query(::Register,::Tag,::Val{allB};locked,assigned) +``` -#### `query(mb::MessageBuffer, tag::Tag)` +```@docs +query(::RegRef,::Tag) +``` + +```@docs +query(::QuantumSavory.MessageBuffer,::Tag) +``` ## `querydelete!` A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. -#### `querydelete!(ref::RegRef, args...)` +```@docs +querydelete!(::RegRef, args...) +``` #### Interface Overview @@ -89,7 +76,9 @@ flowchart TB ``` -#### `querydelete!(mb::MessageBuffer, args...)` +```@docs +querydelete!(::QuantumSavory.MessageBuffer,args...) +``` #### Interface Overview @@ -105,9 +94,9 @@ flowchart TB ## `queryall` A method defined on top of [`query`](@ref) which allows to query for all tags in a [`RegRef`](@ref) or a [`Register`](@ref) that match the passed `Tag`, instead of just one matching instance. -#### `queryall(args...; kwargs...)` - -where `args...` and `kwargs...` correspond to the arguments and keyword arguments accepted by the [`query`](@ref) method on the particular data structure on which the method is called upon. +```@docs +queryall(args...; kwargs...) +``` #### Interface Overview diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 1226a017..21452eb0 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -22,6 +22,14 @@ get_time_tracker(prot::AbstractProtocol) = prot.sim Process(prot::AbstractProtocol, args...; kwargs...) = Process((e,a...;k...)->prot(a...;k...,_prot=prot), get_time_tracker(prot), args...; kwargs...) +""" +$TYPEDEF + +$FIELDS + +Indicates the current entanglement status with a remote node's slot. Added when a new entanglement is generated through [`EntanglerProt`](@ref) or when a swap happens and + the [`EntanglementTracker`](@ref) receives an [`EntanglementUpdate`](@ref) message. +""" @kwdef struct EntanglementCounterpart remote_node::Int remote_slot::Int @@ -29,6 +37,17 @@ end Base.show(io::IO, tag::EntanglementCounterpart) = print(io, "Entangled to $(tag.remote_node).$(tag.remote_slot)") Tag(tag::EntanglementCounterpart) = Tag(EntanglementCounterpart, tag.remote_node, tag.remote_slot) +""" +$TYPEDEF + +$FIELDS + +This tag is used to store the outdated entanglement information after a +swap. It helps to direct incoming entanglement update messages to the right node after a swap. +It helps in situations when locally we have performed a swap, but we are now receiving a message +from a distant node that does not know yet that the swap has occurred (thus the distant node might +have outdated information about who is entangled to whom and we need to update that information). +""" @kwdef struct EntanglementHistory remote_node::Int remote_slot::Int @@ -39,6 +58,14 @@ end Base.show(io::IO, tag::EntanglementHistory) = print(io, "Was entangled to $(tag.remote_node).$(tag.remote_slot), but swapped with .$(tag.swapped_local) which was entangled to $(tag.swap_remote_node).$(tag.swap_remote_slot)") Tag(tag::EntanglementHistory) = Tag(EntanglementHistory, tag.remote_node, tag.remote_slot, tag.swap_remote_node, tag.swap_remote_slot, tag.swapped_local) +""" +$TYPEDEF + +$FIELDS + +This tag arrives as a message from a remote node to which the current node was entangled to update the +entanglement information and apply an `X` correction after the remote node performs an entanglement swap. +""" @kwdef struct EntanglementUpdateX past_local_node::Int past_local_slot::Int @@ -50,6 +77,14 @@ end Base.show(io::IO, tag::EntanglementUpdateX) = print(io, "Update slot .$(tag.past_remote_slot) which used to be entangled to $(tag.past_local_node).$(tag.past_local_slot) to be entangled to $(tag.new_remote_node).$(tag.new_remote_slot) and apply correction Z$(tag.correction)") Tag(tag::EntanglementUpdateX) = Tag(EntanglementUpdateX, tag.past_local_node, tag.past_local_slot, tag.past_remote_slot, tag.new_remote_node, tag.new_remote_slot, tag.correction) +""" +$TYPEDEF + +$FIELDS + +This tag arrives as a message from a remote node to which the current node was entangled to update the +entanglement information and apply a `Z` correction after the remote node performs an entanglement swap. +""" @kwdef struct EntanglementUpdateZ past_local_node::Int past_local_slot::Int diff --git a/src/QuantumSavory.jl b/src/QuantumSavory.jl index 8b315916..6bbc25da 100644 --- a/src/QuantumSavory.jl +++ b/src/QuantumSavory.jl @@ -2,6 +2,7 @@ module QuantumSavory using Reexport +using DocStringExtensions using IterTools using LinearAlgebra using Random: randperm diff --git a/src/queries.jl b/src/queries.jl index 7f444c1c..74913b67 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -1,5 +1,7 @@ """Assign a tag to a slot in a register. +$TYPEDSIGNATURES + See also: [`query`](@ref)""" function tag!(ref::RegRef, tag::Tag) push!(ref.reg.tags[ref.idx], tag) @@ -7,6 +9,12 @@ end tag!(ref, tag) = tag!(ref, Tag(tag)) +"""Removes the first matching tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) + +$TYPEDSIGNATURES + +See also: [`query`](@ref) +""" function untag!(ref::RegRef, tag::Tag) # TODO rather slow implementation. See issue #74 tags = ref.reg.tags[ref.idx] i = findfirst(==(tag), tags) @@ -28,7 +36,10 @@ const W = Wildcard() See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" const ❓ = W -""" A query function that returns all slots of a register that have a given tag, with support for predicates and wildcards. +""" +$TYPEDSIGNATURES + +A query function that returns all slots of a register that have a given tag, with support for predicates and wildcards. ```jldoctest julia> r = Register(10); @@ -51,7 +62,10 @@ julia> queryall(r, :symbol, ❓, >(5)) queryall(args...; kwargs...) = query(args..., Val{true}(); kwargs...) -""" A query function searching for the first slot in a register that has a given tag. +""" +$TYPEDSIGNATURES + +A query function searching for the first slot in a register that has a given tag. Wildcards are supported (instances of `Wildcard` also available as the constants [`W`](@ref) or the emoji [`❓`](@ref) which can be entered as `\\:question:` in the REPL). Predicate functions are also supported (they have to be `Int`↦`Bool` functions). @@ -106,7 +120,10 @@ function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{ end end -"""A [`query`](@ref) on a single slot of a register. +""" +$TYPEDSIGNATURES + +A [`query`](@ref) on a single slot of a register. ```jldoctest julia> r = Register(5); @@ -134,15 +151,21 @@ function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}()) where {allB} # T end end -"""A [`query`](@ref) for classical message buffers. +""" +$TYPEDSIGNATURES + +A [`query`](@ref) for classical message buffers. -You are advised to actually use [`querypop!`](@ref), not `query` when working with classical message buffers.""" +You are advised to actually use [`querydelete!`](@ref), not `query` when working with classical message buffers.""" function query(mb::MessageBuffer, tag::Tag) i = findfirst(t->t.tag==tag, mb.buffer) return isnothing(i) ? nothing : (;depth=i, src=mb.buffer[i][1], tag=mb.buffer[i][2]) end -raw"""A [`query`](@ref) for classical message buffers that also deletes the message out of the buffer. +""" +$TYPEDSIGNATURES + +A [`query`](@ref) for classical message buffers that also deletes the message out of the buffer. ```jldoctest julia> net = RegisterNet([Register(3), Register(2)]) @@ -185,11 +208,11 @@ julia> @resumable function receive_tags(env) mb = messagebuffer(net, 2) @yield wait(mb) msg = querydelete!(mb, :second_tag, ❓, ❓) - print("t=$(now(env)): query returns ") + print("t=\$(now(env)): query returns ") if isnothing(msg) println("nothing") else - println("$(msg.tag) received from node $(msg.src)") + println("\$(msg.tag) received from node \$(msg.src)") end end end @@ -217,6 +240,11 @@ function querydelete!(mb::MessageBuffer, args...) return isnothing(r) ? nothing : popat!(mb.buffer, r.depth) end +""" +$TYPEDSIGNATURES + +A [`query`](@ref) for [`RegRef`](@query) that also deletes the tag from the tag list for the [`RegRef`](@query). +""" 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) From c21d60c6a7a62cdd2c6df8d2c28bfb6156b5c2f1 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 30 Jan 2024 17:30:38 -0500 Subject: [PATCH 06/15] autodocs --- docs/src/query_interface.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index 8a49b3ba..248daed9 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -21,12 +21,12 @@ The tags are constructed using the `Tag` constructor where `tagvariants` are the extra arguments required by the specific `tagsymbol`, for instance the `tag_types.SymbolIntInt` require two `Int` values. It supports the use of predicate functions (`Int -> Bool`) and [`Wildcard`](@ref) (❓) in place of the `tagvariants` which allows the user to perform queries for tags fulfilling certain criteria. ## `tag!` -```@docs +```@autodocs Modules = [QuantumSavory.tag!] ``` ## `untag!` -```@docs +```@autodocs Modules = [QuantumSavory.untag!] ``` @@ -46,22 +46,22 @@ The following features are supported: Following is a detailed description of each `query` methods -```@docs +```@autodocs query(::Register,::Tag,::Val{allB};locked,assigned) ``` -```@docs +```@autodocs query(::RegRef,::Tag) ``` -```@docs +```@autodocs query(::QuantumSavory.MessageBuffer,::Tag) ``` ## `querydelete!` A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. -```@docs +```@autodocs querydelete!(::RegRef, args...) ``` @@ -76,7 +76,7 @@ flowchart TB ``` -```@docs +```@autodocs querydelete!(::QuantumSavory.MessageBuffer,args...) ``` @@ -94,7 +94,7 @@ flowchart TB ## `queryall` A method defined on top of [`query`](@ref) which allows to query for all tags in a [`RegRef`](@ref) or a [`Register`](@ref) that match the passed `Tag`, instead of just one matching instance. -```@docs +```@autodocs queryall(args...; kwargs...) ``` From bd1538d21628f174ee7cabcb203eb955ed9b7d6c Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 31 Jan 2024 18:39:06 -0500 Subject: [PATCH 07/15] try @docs for splicing docstrings and fix some broken doctests --- docs/src/query_interface.md | 27 +++++++++++++++------------ src/queries.jl | 2 ++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index 248daed9..d523c2a0 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -12,8 +12,11 @@ The following lines explain in detail, the components of the query interface whi ## `Tag` Tags are used to represent classical metadata describing the state and history of the nodes. The library allows the construction of custom tags following the format of one of the [`tag_types`](@ref) using the `Tag` constructor. The library implements the following tags for use in the networking protocols: -```@autodocs -Modules = [QuantumSavory.ProtocolZoo.EntanglementCounterpart, QuantumSavory.ProtocolZoo.EntanglementHistory, QuantumSavory.ProtocolZoo.EntanglementUpdateX, QuantumSavory.ProtocolZoo.EntanglementUpdateZ] +```@docs +QuantumSavory.ProtocolZoo.EntanglementCounterpart +QuantumSavory.ProtocolZoo.EntanglementHistory +QuantumSavory.ProtocolZoo.EntanglementUpdateX +QuantumSavory.ProtocolZoo.EntanglementUpdateZ ``` The tags are constructed using the `Tag` constructor @@ -21,13 +24,13 @@ The tags are constructed using the `Tag` constructor where `tagvariants` are the extra arguments required by the specific `tagsymbol`, for instance the `tag_types.SymbolIntInt` require two `Int` values. It supports the use of predicate functions (`Int -> Bool`) and [`Wildcard`](@ref) (❓) in place of the `tagvariants` which allows the user to perform queries for tags fulfilling certain criteria. ## `tag!` -```@autodocs -Modules = [QuantumSavory.tag!] +```@docs +QuantumSavory.tag! ``` ## `untag!` -```@autodocs -Modules = [QuantumSavory.untag!] +```@docs +QuantumSavory.untag! ``` ## [`query`](@ref) @@ -46,22 +49,22 @@ The following features are supported: Following is a detailed description of each `query` methods -```@autodocs +```@docs query(::Register,::Tag,::Val{allB};locked,assigned) ``` -```@autodocs +```@docs query(::RegRef,::Tag) ``` -```@autodocs +```@docs query(::QuantumSavory.MessageBuffer,::Tag) ``` ## `querydelete!` A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. -```@autodocs +```@docs querydelete!(::RegRef, args...) ``` @@ -76,7 +79,7 @@ flowchart TB ``` -```@autodocs +```@docs querydelete!(::QuantumSavory.MessageBuffer,args...) ``` @@ -94,7 +97,7 @@ flowchart TB ## `queryall` A method defined on top of [`query`](@ref) which allows to query for all tags in a [`RegRef`](@ref) or a [`Register`](@ref) that match the passed `Tag`, instead of just one matching instance. -```@autodocs +```@docs queryall(args...; kwargs...) ``` diff --git a/src/queries.jl b/src/queries.jl index 74913b67..d82edc45 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -198,6 +198,8 @@ true You can also wait on a message buffer for a message to arrive before running a query: ```jldoctest +julia> using ResumableFunctions; using ConcurrentSim; + julia> net = RegisterNet([Register(3), Register(2), Register(3)]) A network of 3 registers in a graph of 2 edges From 4d34e623c9522572ef5182bf6b38e5a077e96c77 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Wed, 31 Jan 2024 19:16:48 -0500 Subject: [PATCH 08/15] update query_interface.md --- docs/src/query_interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index d523c2a0..8a7c612b 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -50,7 +50,7 @@ The following features are supported: Following is a detailed description of each `query` methods ```@docs -query(::Register,::Tag,::Val{allB};locked,assigned) +query(::Register,::Tag) ``` ```@docs From f5dec90fd5edc970e59c42906bbf4b68635b7a1f Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 1 Feb 2024 12:01:51 -0500 Subject: [PATCH 09/15] fix messagequeues.md tutorial, try to distinguish duplicate docstrings in warning --- docs/src/query_interface.md | 19 ++++++++++--------- docs/src/tutorial/message_queues.md | 12 ++++++------ src/queries.jl | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index 8a7c612b..b2f4f85a 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -50,11 +50,11 @@ The following features are supported: Following is a detailed description of each `query` methods ```@docs -query(::Register,::Tag) +query(::Register,::Tag,::Val{Bool}) ``` ```@docs -query(::RegRef,::Tag) +query(::RegRef,::Tag,::Val{Bool}) ``` ```@docs @@ -65,7 +65,7 @@ query(::QuantumSavory.MessageBuffer,::Tag) A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. ```@docs -querydelete!(::RegRef, args...) +querydelete!(::QuantumSavory.MessageBuffer,args...) ``` #### Interface Overview @@ -73,14 +73,14 @@ querydelete!(::RegRef, args...) ```@raw html
flowchart TB - A["querydelete!(ref::RegRef, args...)"] - B["query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}())"] + A["querydelete!(mb::MessageBuffer, args...)"] + B["query(mb::MessageBuffer, tag::Tag)"] A --> B
``` ```@docs -querydelete!(::QuantumSavory.MessageBuffer,args...) +querydelete!(::RegRef, args...) ``` #### Interface Overview @@ -88,17 +88,18 @@ querydelete!(::QuantumSavory.MessageBuffer,args...) ```@raw html
flowchart TB - A["querydelete!(mb::MessageBuffer, args...)"] - B["query(mb::MessageBuffer, tag::Tag)"] + A["querydelete!(ref::RegRef, args...)"] + B["query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}())"] A --> B
``` + ## `queryall` A method defined on top of [`query`](@ref) which allows to query for all tags in a [`RegRef`](@ref) or a [`Register`](@ref) that match the passed `Tag`, instead of just one matching instance. ```@docs -queryall(args...; kwargs...) +QuantumSavory.queryall ``` #### Interface Overview diff --git a/docs/src/tutorial/message_queues.md b/docs/src/tutorial/message_queues.md index 0ac3ef37..f3cc5a03 100644 --- a/docs/src/tutorial/message_queues.md +++ b/docs/src/tutorial/message_queues.md @@ -124,22 +124,22 @@ time_before_success = now(sim) ## Communication delay -Classical communication delay might be important too. There are FILO storage stacks that can simulate that, e.g. `DelayChannel(sim, delay_time)` used instead of `Storage(sim)`. Below we augment the example from above with such a delay channel and we also add some crude instrumentation and plotting. +Classical communication delay might be important too. There are FILO storage stacks that can simulate that, e.g. `DelayQueue(sim, delay_time)` used instead of `Storage(sim)`. Below we augment the example from above with such a delay channel and we also add some crude instrumentation and plotting. ```@example messagechannel sim = Simulation() communication_delay = 1.0 -channel_1to2 = DelayChannel{Bool}(sim, communication_delay) -channel_2to1 = DelayChannel{Bool}(sim, communication_delay) -channel_ready = DelayChannel{Bool}(sim, communication_delay) +channel_1to2 = DelayQueue{Bool}(sim, communication_delay) +channel_2to1 = DelayQueue{Bool}(sim, communication_delay) +channel_ready = DelayQueue{Bool}(sim, communication_delay) global_log = [] @resumable function do_random_measurement_transmit_receive_compare(sim, channel_out, channel_in) @yield timeout(sim, 2+rand()) # wait for the measurement to take place local_measurement = rand() < 0.4 # simulate a random measurement result - put(channel_out, local_measurement) - other_measurement = @yield get(channel_in) + put!(channel_out, local_measurement) + other_measurement = @yield take!(channel_in) succeeded = local_measurement == other_measurement == true return succeeded end diff --git a/src/queries.jl b/src/queries.jl index d82edc45..077bb52e 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -9,6 +9,7 @@ end tag!(ref, tag) = tag!(ref, Tag(tag)) + """Removes the first matching tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) $TYPEDSIGNATURES @@ -21,21 +22,25 @@ function untag!(ref::RegRef, tag::Tag) # TODO rather slow implementation. See is isnothing(i) ? throw(KeyError(tag)) : deleteat!(tags, i) # TODO make sure there is a clear error message end + """Wildcard for use with the tag querying functionality. See also: [`query`](@ref), [`tag!`](@ref)""" struct Wildcard end + """A wildcard instance for use with the tag querying functionality. See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" const W = Wildcard() + """A wildcard instance for use with the tag querying functionality. See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" const ❓ = W + """ $TYPEDSIGNATURES @@ -120,6 +125,8 @@ function query(reg::Register, tag::Tag, ::Val{allB}=Val{false}(); locked::Union{ end end + + """ $TYPEDSIGNATURES @@ -151,6 +158,8 @@ function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}()) where {allB} # T end end + + """ $TYPEDSIGNATURES @@ -162,6 +171,8 @@ function query(mb::MessageBuffer, tag::Tag) return isnothing(i) ? nothing : (;depth=i, src=mb.buffer[i][1], tag=mb.buffer[i][2]) end + + """ $TYPEDSIGNATURES @@ -242,6 +253,8 @@ function querydelete!(mb::MessageBuffer, args...) return isnothing(r) ? nothing : popat!(mb.buffer, r.depth) end + + """ $TYPEDSIGNATURES @@ -333,6 +346,8 @@ for (tagsymbol, tagvariant) in pairs(tag_types) end end + + """Find an empty unlocked slot in a given [`Register`](@ref). ```jldoctest @@ -359,6 +374,7 @@ function findfreeslot(reg::Register; randomize=false) end end + function Base.isassigned(r::Register,i::Int) # TODO erase r.stateindices[i] != 0 # TODO this also usually means r.staterenfs[i] !== nothing - choose one and make things consistent end From ca1eef014ac1b25d48a79959c8dbbc75d3ecee61 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Thu, 1 Feb 2024 12:42:20 -0500 Subject: [PATCH 10/15] update messagequeues.md --- docs/src/tutorial/message_queues.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/tutorial/message_queues.md b/docs/src/tutorial/message_queues.md index f3cc5a03..2f841a87 100644 --- a/docs/src/tutorial/message_queues.md +++ b/docs/src/tutorial/message_queues.md @@ -148,7 +148,7 @@ end s = now(sim) reset_duration = 2.0 @yield timeout(sim, reset_duration) - put(channel_ready, true) + put!(channel_ready, true) push!(global_log, (:reset_system, s, now(sim))) end @@ -175,7 +175,7 @@ end end push!(global_log, (:node_2_meas_tx_rx, s, now(sim))) s2 = now(sim) - @yield get(channel_ready) + @yield take!(channel_ready) push!(global_log, (:node_2_wait_for_reset, s2, now(sim))) end end From 3b9d8854e964bb3abb8c4d546dc004da30247f2c Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Sat, 3 Feb 2024 03:22:06 -0500 Subject: [PATCH 11/15] duplicate docs warning removal, protocolzoo api, minor fixes to docs --- docs/make.jl | 37 +++++++++++++++++++------------------ docs/src/API_ProtocolZoo.md | 17 +++++++++++++++++ docs/src/query_interface.md | 11 ++++++----- docs/src/references.bib | 2 +- src/QuantumSavory.jl | 2 ++ src/queries.jl | 8 +++----- 6 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 docs/src/API_ProtocolZoo.md diff --git a/docs/make.jl b/docs/make.jl index bc2603a7..693a22ef 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -21,35 +21,36 @@ function main() modules = [QuantumSavory], authors = "Stefan Krastanov", pages = [ - "QuantumSavory.jl" => "index.md", - "Getting Started Manual" => "manual.md", + # "QuantumSavory.jl" => "index.md", + # "Getting Started Manual" => "manual.md", "Explanations" => [ - "explanations.md", - "Properties and Backgrounds" => "propbackgrounds.md", - "Symbolic Expressions" => "symbolics.md", - "Visualizations" => "visualizations.md", + # "explanations.md", + # "Properties and Backgrounds" => "propbackgrounds.md", + # "Symbolic Expressions" => "symbolics.md", + # "Visualizations" => "visualizations.md", "Dev Documentation" => [ "Register Interface" => "register_interface.md", "Query Interface" => "query_interface.md", ], ], - "How-To Guides" => [ - "howto.md", - "1st-gen Repeater" => "howto/firstgenrepeater/firstgenrepeater.md", - "1st-gen Repeater (Clifford formalism)" => "howto/firstgenrepeater/firstgenrepeater-clifford.md", - "Cluster States in Atomic Memories" => "howto/colorcentermodularcluster/colorcentermodularcluster.md", - ], - "Tutorials" => [ - "tutorial.md", - "Gate duration" => "tutorial/noninstantgate.md", - "Message queues" => "tutorial/message_queues.md", - #"Depolarization and Pauli Noise" => "tutorial/depolarization_and_pauli.md", TODO - ], + # "How-To Guides" => [ + # "howto.md", + # "1st-gen Repeater" => "howto/firstgenrepeater/firstgenrepeater.md", + # "1st-gen Repeater (Clifford formalism)" => "howto/firstgenrepeater/firstgenrepeater-clifford.md", + # "Cluster States in Atomic Memories" => "howto/colorcentermodularcluster/colorcentermodularcluster.md", + # ], + # "Tutorials" => [ + # "tutorial.md", + # "Gate duration" => "tutorial/noninstantgate.md", + # "Message queues" => "tutorial/message_queues.md", + # #"Depolarization and Pauli Noise" => "tutorial/depolarization_and_pauli.md", TODO + # ], "References" => [ "references.md", "API" => "API.md", "CircuitZoo API" => "API_CircuitZoo.md", "StatesZoo API" => "API_StatesZoo.md", + "ProtocolZoo API" => "API_ProtocolZoo.md", "Bibliography" => "bibliography.md", ], ] diff --git a/docs/src/API_ProtocolZoo.md b/docs/src/API_ProtocolZoo.md new file mode 100644 index 00000000..6da6bd9b --- /dev/null +++ b/docs/src/API_ProtocolZoo.md @@ -0,0 +1,17 @@ +# Available Protocols + +```@raw html + +``` + +## Autogenerated API list for `QuantumSavory.ProtocolZoo` + +```@autodocs +Modules = [QuantumSavory.ProtocolZoo] +Private = false +``` \ No newline at end of file diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md index b2f4f85a..a2940a44 100644 --- a/docs/src/query_interface.md +++ b/docs/src/query_interface.md @@ -50,22 +50,22 @@ The following features are supported: Following is a detailed description of each `query` methods ```@docs -query(::Register,::Tag,::Val{Bool}) +query(::Register,::Tag) ``` ```@docs -query(::RegRef,::Tag,::Val{Bool}) +query(::RegRef,::Tag) ``` ```@docs -query(::QuantumSavory.MessageBuffer,::Tag) +query(::MessageBuffer,::Tag) ``` ## `querydelete!` A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. ```@docs -querydelete!(::QuantumSavory.MessageBuffer,args...) +querydelete!(::MessageBuffer) ``` #### Interface Overview @@ -80,7 +80,7 @@ flowchart TB ``` ```@docs -querydelete!(::RegRef, args...) +querydelete!(::RegRef) ``` #### Interface Overview @@ -109,5 +109,6 @@ QuantumSavory.queryall flowchart TB A["queryall(args...; kwargs...)"] B["query(args..., ::Val{allB}=Val{true}(), ::Val{fifo}=Val{true}; kwargs...)"] + A --> B ``` \ No newline at end of file diff --git a/docs/src/references.bib b/docs/src/references.bib index 7e774b61..378cdaf2 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -211,7 +211,7 @@ @article{keisuke2009doubleselection journal={Phys. Rev. A 80, 042308}, year={2009}, url={https://doi.org/10.1103/PhysRevA.80.042308}, - doi={https://doi.org/10.1103/PhysRevA.80.042308} + doi={10.1103/PhysRevA.80.042308} } @article{krastanov2019optimised, diff --git a/src/QuantumSavory.jl b/src/QuantumSavory.jl index 6bbc25da..d6848082 100644 --- a/src/QuantumSavory.jl +++ b/src/QuantumSavory.jl @@ -50,6 +50,8 @@ export uptotime!, overwritetime!, # tags.jl and queries.jl Tag, tag!, untag!, W, ❓, query, queryall, querydelete!, findfreeslot, + #messagebuffer.jl + MessageBuffer, # quantumchannel.jl QuantumChannel, # backgrounds.jl diff --git a/src/queries.jl b/src/queries.jl index 077bb52e..c6846213 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -159,14 +159,12 @@ function query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}()) where {allB} # T end - """ $TYPEDSIGNATURES -A [`query`](@ref) for classical message buffers. - -You are advised to actually use [`querydelete!`](@ref), not `query` when working with classical message buffers.""" -function query(mb::MessageBuffer, tag::Tag) +You are advised to actually use [`querydelete!`](@ref), not `query` when working with classical message buffers. +""" +function query(mb::MessageBuffer, tag::Tag, ::Val{allB}=Val{false}()) where {allB} i = findfirst(t->t.tag==tag, mb.buffer) return isnothing(i) ? nothing : (;depth=i, src=mb.buffer[i][1], tag=mb.buffer[i][2]) end From b53f74e22d3fb1a53ffb358dee69cfadab968b83 Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt Date: Tue, 13 Feb 2024 10:37:30 -0500 Subject: [PATCH 12/15] update make.jl --- docs/make.jl | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 693a22ef..438ab109 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -21,30 +21,30 @@ function main() modules = [QuantumSavory], authors = "Stefan Krastanov", pages = [ - # "QuantumSavory.jl" => "index.md", - # "Getting Started Manual" => "manual.md", + "QuantumSavory.jl" => "index.md", + "Getting Started Manual" => "manual.md", "Explanations" => [ - # "explanations.md", - # "Properties and Backgrounds" => "propbackgrounds.md", - # "Symbolic Expressions" => "symbolics.md", - # "Visualizations" => "visualizations.md", + "explanations.md", + "Properties and Backgrounds" => "propbackgrounds.md", + "Symbolic Expressions" => "symbolics.md", + "Visualizations" => "visualizations.md", "Dev Documentation" => [ "Register Interface" => "register_interface.md", "Query Interface" => "query_interface.md", ], ], - # "How-To Guides" => [ - # "howto.md", - # "1st-gen Repeater" => "howto/firstgenrepeater/firstgenrepeater.md", - # "1st-gen Repeater (Clifford formalism)" => "howto/firstgenrepeater/firstgenrepeater-clifford.md", - # "Cluster States in Atomic Memories" => "howto/colorcentermodularcluster/colorcentermodularcluster.md", - # ], - # "Tutorials" => [ - # "tutorial.md", - # "Gate duration" => "tutorial/noninstantgate.md", - # "Message queues" => "tutorial/message_queues.md", - # #"Depolarization and Pauli Noise" => "tutorial/depolarization_and_pauli.md", TODO - # ], + "How-To Guides" => [ + "howto.md", + "1st-gen Repeater" => "howto/firstgenrepeater/firstgenrepeater.md", + "1st-gen Repeater (Clifford formalism)" => "howto/firstgenrepeater/firstgenrepeater-clifford.md", + "Cluster States in Atomic Memories" => "howto/colorcentermodularcluster/colorcentermodularcluster.md", + ], + "Tutorials" => [ + "tutorial.md", + "Gate duration" => "tutorial/noninstantgate.md", + "Message queues" => "tutorial/message_queues.md", + #"Depolarization and Pauli Noise" => "tutorial/depolarization_and_pauli.md", TODO + ], "References" => [ "references.md", "API" => "API.md", From d7c3fe6818d19b7617d8fb8bafae620dcb0e61fd Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 5 Mar 2024 16:49:44 -0500 Subject: [PATCH 13/15] cleanup --- docs/make.jl | 8 +-- docs/src/API_ProtocolZoo.md | 9 +++ docs/src/explanations.md | 1 + docs/src/query_interface.md | 114 --------------------------------- docs/src/register_interface.md | 24 +++++++ docs/src/tag_query.md | 75 ++++++++++++++++++++++ src/ProtocolZoo/ProtocolZoo.jl | 51 ++++++++++----- src/baseops/traceout.jl | 4 -- src/queries.jl | 31 +++++---- src/tags.jl | 21 ++++++ 10 files changed, 188 insertions(+), 150 deletions(-) delete mode 100644 docs/src/query_interface.md create mode 100644 docs/src/tag_query.md diff --git a/docs/make.jl b/docs/make.jl index 438ab109..81ff0523 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -13,7 +13,7 @@ function main() plugins = [bib], doctest = false, clean = true, - warnonly = true, # TODO [:missing_docs], + warnonly = [:missing_docs], sitename = "QuantumSavory.jl", format = Documenter.HTML( assets=["assets/init.js"] @@ -25,13 +25,11 @@ function main() "Getting Started Manual" => "manual.md", "Explanations" => [ "explanations.md", + "Register Interface" => "register_interface.md", "Properties and Backgrounds" => "propbackgrounds.md", "Symbolic Expressions" => "symbolics.md", + "Tagging and Querying" => "tag_query.md", "Visualizations" => "visualizations.md", - "Dev Documentation" => [ - "Register Interface" => "register_interface.md", - "Query Interface" => "query_interface.md", - ], ], "How-To Guides" => [ "howto.md", diff --git a/docs/src/API_ProtocolZoo.md b/docs/src/API_ProtocolZoo.md index 6da6bd9b..d47f4f13 100644 --- a/docs/src/API_ProtocolZoo.md +++ b/docs/src/API_ProtocolZoo.md @@ -14,4 +14,13 @@ ```@autodocs Modules = [QuantumSavory.ProtocolZoo] Private = false +``` + +## Non-exported custom tags used by these protocols + +```@docs +QuantumSavory.ProtocolZoo.EntanglementCounterpart +QuantumSavory.ProtocolZoo.EntanglementHistory +QuantumSavory.ProtocolZoo.EntanglementUpdateX +QuantumSavory.ProtocolZoo.EntanglementUpdateZ ``` \ No newline at end of file diff --git a/docs/src/explanations.md b/docs/src/explanations.md index 3c49e5d1..1e5a85fd 100644 --- a/docs/src/explanations.md +++ b/docs/src/explanations.md @@ -12,6 +12,7 @@ You probably want to cover the: - `Register` and `RegisterNet` structures - basic interface used by the library - symbolic capabilities for formalism-agnostic description +- metadata tagging and metadata queries for interoperability between protocols - available simulator backends - discrete event simulations and time-tracking capabilities - background noise processes diff --git a/docs/src/query_interface.md b/docs/src/query_interface.md deleted file mode 100644 index a2940a44..00000000 --- a/docs/src/query_interface.md +++ /dev/null @@ -1,114 +0,0 @@ -# Query Interface - -```@meta -DocTestSetup = quote - using QuantumSavory -end -``` -The query interface allows us to use various quantum networking protocols defined in QuantumSavory together in a simulation. It provides composability between the various protocols where each protocol can operate independently of the other without knowing its internals. This is done by using various tags to communicate metadata between the network nodes running the protocols. This leads to greater flexibility when setting up different simulations since the information about how the nodes running the protocols should interact is generally defined in the protocols and the specifics at runtime are determined by the tags passed and received. - -The following lines explain in detail, the components of the query interface which make this possible. - -## `Tag` -Tags are used to represent classical metadata describing the state and history of the nodes. The library allows the construction of custom tags following the format of one of the [`tag_types`](@ref) using the `Tag` constructor. The library implements the following tags for use in the networking protocols: - -```@docs -QuantumSavory.ProtocolZoo.EntanglementCounterpart -QuantumSavory.ProtocolZoo.EntanglementHistory -QuantumSavory.ProtocolZoo.EntanglementUpdateX -QuantumSavory.ProtocolZoo.EntanglementUpdateZ -``` - -The tags are constructed using the `Tag` constructor -#### Tag(tagsymbol::Symbol, tagvariants...) -where `tagvariants` are the extra arguments required by the specific `tagsymbol`, for instance the `tag_types.SymbolIntInt` require two `Int` values. It supports the use of predicate functions (`Int -> Bool`) and [`Wildcard`](@ref) (❓) in place of the `tagvariants` which allows the user to perform queries for tags fulfilling certain criteria. - -## `tag!` -```@docs -QuantumSavory.tag! -``` - -## `untag!` -```@docs -QuantumSavory.untag! -``` - -## [`query`](@ref) - -[`query`](@ref) function allow the user to query for `Tag`(s) in three different cases: -- on a particular qubit slot([`RegRef`](@ref)) in a [`Register`](@ref) node; -- on a [`Register`](@ref) to query for a slot that contains the passed `Tag`; and -- on a `MessageBuffer` to query for a particular `Tag` received from another node in a network. - -The following features are supported: -- The query methods specialized on [`RegRef`](@ref) and [`Register`](@ref) allow for the queries to be executed in `FIFO` or `FILO` order, which is set to be `FIFO` by default. This means by default, a query on a [`RegRef`](@ref) returns the `Tag` which is at the end of the vector of tags attribute in a [`Register`](@ref), as new tags are pushed to the back by [`tag!`](@ref). On a [`Register`](@ref) it returns the slot number with the highest index having the queried `Tag`. - -- The `Tag` passed to the method can be constructed using predicate functions (of the form: `Int` -> `Bool`) and [`Wildcard`](@ref) (❓). This supports querying for tags for which all the information is not known or isn't relevant, e.g, when looking for a qubit entangled with a neighbouring node in a repeater chain, we need a node that has a larger(right) or smaller(left) node number and the slot number of the neighbouring node to which its entangled is irrelevant. Hence, the `EntanglementCounterpart` tag passed to the [`query`](@ref) has a predicate `>(node)` or `<(node)` for `remote_node` and a [`Wildcard`](@ref) (❓) for `remote_slot` fields of the tag. - -- It can be specified that the target slot be locked(or unlocked) and assigned(or unassigned) using the `locked` and `assigned` keywords which take `Bool` values. By default, the [`query`](@ref) does not check for these properties. This is available for [`query`](@ref) methods defined on [`Register`](@ref) and [`RegRef`](@ref). - -Following is a detailed description of each `query` methods - -```@docs -query(::Register,::Tag) -``` - -```@docs -query(::RegRef,::Tag) -``` - -```@docs -query(::MessageBuffer,::Tag) -``` - -## `querydelete!` -A method on top of [`query`](@ref) which allows to query for tag in a [`RegRef`](@ref) and `MessageBuffer` returning the tag that satisfies the passed predicates and [`Wildcard`](@ref)s and deleting it from the list at the same time. It allows the same arguments to be passed to it as the corresponding [`query`](@ref) method on the data structure its called upon. - -```@docs -querydelete!(::MessageBuffer) -``` - -#### Interface Overview - -```@raw html -
-flowchart TB - A["querydelete!(mb::MessageBuffer, args...)"] - B["query(mb::MessageBuffer, tag::Tag)"] - A --> B -
-``` - -```@docs -querydelete!(::RegRef) -``` - -#### Interface Overview - -```@raw html -
-flowchart TB - A["querydelete!(ref::RegRef, args...)"] - B["query(ref::RegRef, tag::Tag, ::Val{allB}=Val{false}(), ::Val{fifo}=Val{true}())"] - A --> B -
-``` - - -## `queryall` -A method defined on top of [`query`](@ref) which allows to query for all tags in a [`RegRef`](@ref) or a [`Register`](@ref) that match the passed `Tag`, instead of just one matching instance. - -```@docs -QuantumSavory.queryall -``` - -#### Interface Overview - -```@raw html -
-flowchart TB - A["queryall(args...; kwargs...)"] - B["query(args..., ::Val{allB}=Val{true}(), ::Val{fifo}=Val{true}; kwargs...)"] - A --> B -
-``` \ No newline at end of file diff --git a/docs/src/register_interface.md b/docs/src/register_interface.md index b80556ce..34b7f082 100644 --- a/docs/src/register_interface.md +++ b/docs/src/register_interface.md @@ -12,6 +12,10 @@ A rather diverse set of simulation libraries is used under the hood. Long term t Initialize the state of a register to a known state. +```@docs; canonical=false +initialize! +``` + #### `initialize!(refs::Vector{RegRef}, state; time)` Store a `state` in the given register slots. @@ -66,6 +70,10 @@ flowchart TB Apply a quantum operation to a register. +```@docs; canonical=false +apply! +``` + #### `apply!(refs::Vector{RegRef}, operation; time)` Applying an `operation` to the qubits referred to by the sequence of [`RegRef`](@ref)s at a specified `time`. @@ -126,6 +134,10 @@ flowchart TB Measure a quantum observable. The dispatch down the call three is very similar to the one for `apply!`. +```@docs; canonical=false +observable +``` + #### `observable(refs::Tuple{Vararg{RegRef, N}}, obs, something=nothing; time)` Calculate the value of an observable on the state in the sequence of [`RegRef`](@ref)s at a specified `time`. If these registers are not instantiated, return `something`. @@ -180,6 +192,10 @@ flowchart TB ## `project_traceout!` +```@docs; canonical=false +project_traceout! +``` + #### `project_traceout!(r::RegRef, basis; time)` Project the state in `RegRef` on `basis` at a specified `time`. `basis` can be a `Vector` or `Tuple` of basis states, or it can be a `Matrix` like `Z` or `X`. @@ -228,6 +244,10 @@ flowchart TB ## `traceout!` +```@docs; canonical=false +traceout! +``` + Perform a partial trace over a part of the system (i.e. discard a part of the system). #### `traceout!(r::RegRef)` @@ -257,6 +277,10 @@ flowchart TB ## `uptotime!` +```@docs; canonical=false +uptotime! +``` + #### `uptotime!(ref::RegRef, now)` Evolve the state in a `RegRef` upto a given time `now` diff --git a/docs/src/tag_query.md b/docs/src/tag_query.md new file mode 100644 index 00000000..7bc17fdc --- /dev/null +++ b/docs/src/tag_query.md @@ -0,0 +1,75 @@ +# Tagging and Querying + +```@meta +DocTestSetup = quote + using QuantumSavory +end +``` + +The [`query`](@ref) and [`tag!`](@ref) interface lets you manage "classical state" metadata in your simulations. In particular, this interface enables the creation of modular interoperable [control protocols](@ref "Available Protocols"). Each protocol can operate independently of others without knowledge of each others' internals. This is done by using various "tags" to communicate metadata between the network nodes running the protocols, and by the protocols querying for the presence of such tags, leading to greater flexibility when setting up different simulations. + +The components of the query interface which make this possible are described below. + +## The `Tag` type + +```@docs; canonical=false +QuantumSavory.Tag +``` + +And here are all currently supported tag signatures: + +```@example +using QuantumSavory #hide +[tuple(m.sig.types[2:end]...) for m in methods(Tag) if m.sig.types[2] ∈ (Symbol, DataType)] +``` + +## Assigning and removing tags + +```@docs; canonical=false +QuantumSavory.tag! +QuantumSavory.untag! +``` + +## Querying for the pressence of a tag + +The [`query`](@ref) function allows the user to query for [`Tag`](@ref)s in three different cases: +- on a particular qubit slot ([`RegRef`](@ref)) in a [`Register`](@ref) node; +- on a [`Register`](@ref) to query for any slot that contains the passed `Tag`; +- on a [`messagebuffer`](@ref) to query for a particular `Tag` received from another node in a network. + +The `Tag` description passed to `query` can include predicate functions (of the form `x -> pass::Bool`) and wildcards (the [`❓`](@ref) variable), for situations where we have freedom in what tag we are exactly searching for. + +The queries can search in `FIFO` or `FILO` order (`FILO` by default). E.g., for the default `FILO`, a query on a [`RegRef`](@ref) returns the `Tag` which is at the end of the vector of tags stored the given slot (as new tags are appended at the end). On a [`Register`](@ref) it returns the slot with the "youngest" age. + +One can also query by "lock" and "assignment" status of a given slot, by using the `locked` and `assigned` boolean keywords. By default these keywords are set to `nothing` and these properties are not checked. + +Following is a detailed description of each `query` methods + +```@docs; canonical=false +query(::Register,::Tag) +query(::RegRef,::Tag) +query(::MessageBuffer,::Tag) +``` + +### Wildcards + +```@docs; canonical=false +W +❓ +``` + +### `querydelete!` + +A method on top of [`query`](@ref), which allows to query for tag in a [`RegRef`](@ref) or a [`messagebuffer`](@ref), returning the tag that satisfies the passed predicates and wildcars, **and deleting it from the list at the same time**. It otherwise has the same signature as [`query`](@ref). + +```@docs; canonical=false +querydelete!(::RegRef) +querydelete!(::MessageBuffer) +``` + +### `queryall` +A method defined on top of [`query`](@ref) which allows to query for **all tags** in a [`RegRef`](@ref) or a [`Register`](@ref) that match the query. + +```@docs; canonical=false +QuantumSavory.queryall +``` \ No newline at end of file diff --git a/src/ProtocolZoo/ProtocolZoo.jl b/src/ProtocolZoo/ProtocolZoo.jl index 95c1aa96..a19edc9f 100644 --- a/src/ProtocolZoo/ProtocolZoo.jl +++ b/src/ProtocolZoo/ProtocolZoo.jl @@ -25,13 +25,15 @@ Process(prot::AbstractProtocol, args...; kwargs...) = Process((e,a...;k...)->pro """ $TYPEDEF -$FIELDS - Indicates the current entanglement status with a remote node's slot. Added when a new entanglement is generated through [`EntanglerProt`](@ref) or when a swap happens and - the [`EntanglementTracker`](@ref) receives an [`EntanglementUpdate`](@ref) message. + the [`EntanglementTracker`](@ref) receives an [`EntanglementUpdate`] message. + +$TYPEDFIELDS """ @kwdef struct EntanglementCounterpart + "the id of the remote node to which we are entangled" remote_node::Int + "the slot in the remote node containing the qubit we are entangled to" remote_slot::Int end Base.show(io::IO, tag::EntanglementCounterpart) = print(io, "Entangled to $(tag.remote_node).$(tag.remote_slot)") @@ -40,19 +42,24 @@ Tag(tag::EntanglementCounterpart) = Tag(EntanglementCounterpart, tag.remote_node """ $TYPEDEF -$FIELDS - This tag is used to store the outdated entanglement information after a swap. It helps to direct incoming entanglement update messages to the right node after a swap. -It helps in situations when locally we have performed a swap, but we are now receiving a message -from a distant node that does not know yet that the swap has occurred (thus the distant node might +It helps in situations when locally we have performed a swap, but we are now receiving a message +from a distant node that does not know yet that the swap has occurred (thus the distant node might have outdated information about who is entangled to whom and we need to update that information). + +$TYPEDFIELDS """ @kwdef struct EntanglementHistory + "the id of the remote node we used to be entangled to" remote_node::Int + "the slot of the remote node we used to be entangled to" remote_slot::Int + "the id of remote node to which we are entangled after the swap" swap_remote_node::Int + "the slot of the remote node to which we are entangled after the swap" swap_remote_slot::Int + "the slot in this register with whom we performed a swap" swapped_local::Int end Base.show(io::IO, tag::EntanglementHistory) = print(io, "Was entangled to $(tag.remote_node).$(tag.remote_slot), but swapped with .$(tag.swapped_local) which was entangled to $(tag.swap_remote_node).$(tag.swap_remote_slot)") @@ -61,17 +68,23 @@ Tag(tag::EntanglementHistory) = Tag(EntanglementHistory, tag.remote_node, tag.re """ $TYPEDEF -$FIELDS - -This tag arrives as a message from a remote node to which the current node was entangled to update the +This tag arrives as a message from a remote node to which the current node was entangled to update the entanglement information and apply an `X` correction after the remote node performs an entanglement swap. + +$TYPEDFIELDS """ @kwdef struct EntanglementUpdateX + "the id of the node to which you were entangled before the swap" past_local_node::Int + "the slot of the node to which you were entangled before the swap" past_local_slot::Int + "the slot of your node that we were entangled to" past_remote_slot::Int + "the id of the node to which you are now entangled after the swap" new_remote_node::Int + "the slot of the node to which you are now entangled after the swap" new_remote_slot::Int + "what Pauli correction you need to perform" correction::Int end Base.show(io::IO, tag::EntanglementUpdateX) = print(io, "Update slot .$(tag.past_remote_slot) which used to be entangled to $(tag.past_local_node).$(tag.past_local_slot) to be entangled to $(tag.new_remote_node).$(tag.new_remote_slot) and apply correction Z$(tag.correction)") @@ -80,17 +93,23 @@ Tag(tag::EntanglementUpdateX) = Tag(EntanglementUpdateX, tag.past_local_node, ta """ $TYPEDEF -$FIELDS - -This tag arrives as a message from a remote node to which the current node was entangled to update the +This tag arrives as a message from a remote node to which the current node was entangled to update the entanglement information and apply a `Z` correction after the remote node performs an entanglement swap. + +$TYPEDFIELDS """ @kwdef struct EntanglementUpdateZ + "the id of the node to which you were entangled before the swap" past_local_node::Int + "the slot of the node to which you were entangled before the swap" past_local_slot::Int + "the slot of your node that we were entangled to" past_remote_slot::Int + "the id of the node to which you are now entangled after the swap" new_remote_node::Int + "the slot of the node to which you are now entangled after the swap" new_remote_slot::Int + "what Pauli correction you need to perform" correction::Int end Base.show(io::IO, tag::EntanglementUpdateZ) = print(io, "Update slot .$(tag.past_remote_slot) which used to be entangled to $(tag.past_local_node).$(tag.past_local_slot) to be entangled to $(tag.new_remote_node).$(tag.new_remote_slot) and apply correction X$(tag.correction)") @@ -103,7 +122,7 @@ A protocol that generates entanglement between two nodes. Whenever a pair of empty slots is available, the protocol locks them and starts probabilistic attempts to establish entanglement. -$FIELDS +$TYPEDFIELDS """ @kwdef struct EntanglerProt{LT} <: AbstractProtocol where {LT<:Union{Float64,Nothing}} """time-and-schedule-tracking instance from `ConcurrentSim`""" @@ -182,7 +201,7 @@ $TYPEDEF A protocol, running at a given node, that finds swappable entangled pairs and performs the swap. -$FIELDS +$TYPEDFIELDS """ @kwdef struct SwapperProt{NL,NH,CL,CH,LT} <: AbstractProtocol where {NL<:Union{Int,<:Function,Wildcard}, NH<:Union{Int,<:Function,Wildcard}, CL<:Function, CH<:Function, LT<:Union{Float64,Nothing}} """time-and-schedule-tracking instance from `ConcurrentSim`""" @@ -272,7 +291,7 @@ $TYPEDEF A protocol, running at a given node, listening for messages that indicate something has happened to a remote qubit entangled with one of the local qubits. -$FIELDS +$TYPEDFIELDS """ @kwdef struct EntanglementTracker <: AbstractProtocol """time-and-schedule-tracking instance from `ConcurrentSim`""" diff --git a/src/baseops/traceout.jl b/src/baseops/traceout.jl index 09361209..f8049e67 100644 --- a/src/baseops/traceout.jl +++ b/src/baseops/traceout.jl @@ -56,11 +56,7 @@ Perform a projective measurement on the given slot of the given register. `project_traceout!(reg, slot, [stateA, stateB])` performs a projective measurement, projecting on either `stateA` or `stateB`, returning the index of the subspace on which the projection happened. It assumes the list of possible states forms a basis -<<<<<<< HEAD -for the Hilbert space. The Hilbert space of the register gets automatically shrunk. -======= for the Hilbert space. The Hilbert space of the register is automatically shrunk. ->>>>>>> 2285fd9 (spelling fixes) A basis object can be specified on its own as well, e.g. `project_traceout!(reg, slot, basis)`. diff --git a/src/queries.jl b/src/queries.jl index c6846213..9ca6c085 100644 --- a/src/queries.jl +++ b/src/queries.jl @@ -1,8 +1,10 @@ -"""Assign a tag to a slot in a register. +"""$TYPEDSIGNATURES -$TYPEDSIGNATURES +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)""" +See also: [`query`](@ref), [`untag!`](@ref)""" function tag!(ref::RegRef, tag::Tag) push!(ref.reg.tags[ref.idx], tag) end @@ -10,11 +12,13 @@ end tag!(ref, tag) = tag!(ref, Tag(tag)) -"""Removes the first matching tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) +"""$TYPEDSIGNATURES -$TYPEDSIGNATURES +Removes the first instance of tag from the list to tags associated with a [`RegRef`](@ref) in a [`Register`](@ref) -See also: [`query`](@ref) +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] @@ -23,7 +27,9 @@ function untag!(ref::RegRef, tag::Tag) # TODO rather slow implementation. See is end -"""Wildcard for use with the tag querying functionality. +"""Wildcard type for use with the tag querying functionality. + +Usually you simply want an instance of this type (available as the constant [`W`](@ref) or [`❓`](@ref)). See also: [`query`](@ref), [`tag!`](@ref)""" struct Wildcard end @@ -31,13 +37,16 @@ struct Wildcard end """A wildcard instance for use with the tag querying functionality. -See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" +See also: [`query`](@ref), [`tag!`](@ref), [`❓`](@ref)""" const W = Wildcard() """A wildcard instance for use with the tag querying functionality. -See also: [`query`](@ref), [`tag!`](@ref), [`Wildcard`](@ref)""" +This emoji can be inputted with the `\\:question:` emoji shortcut, +or you can simply use the ASCII alternative [`W`](@ref). + +See also: [`query`](@ref), [`tag!`](@ref), [`W`](@ref)""" const ❓ = W @@ -112,7 +121,7 @@ julia> query(r, Int, 4, <(7)) (slot = Slot 5, tag = TypeIntInt(Int64, 4, 5)::Tag) ``` -See also: [`queryall`](@ref), [`tag!`](@ref), [`Wildcard`](@ref) +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) where {allB} find = allB ? findall : findfirst @@ -256,7 +265,7 @@ end """ $TYPEDSIGNATURES -A [`query`](@ref) for [`RegRef`](@query) that also deletes the tag from the tag list for the [`RegRef`](@query). +A [`query`](@ref) for [`RegRef`](@ref) that also deletes the tag from the tag list for the `RegRef`. """ function querydelete!(ref::RegRef, args...) # TODO there is a lot of code duplication here r = query(ref, args...) diff --git a/src/tags.jl b/src/tags.jl index 8af53368..fd4aef7e 100644 --- a/src/tags.jl +++ b/src/tags.jl @@ -1,3 +1,24 @@ +""" +Tags are used to represent classical metadata describing the state (or even history) of nodes and their registers. The library allows the construction of custom tags using the `Tag` constructor. Currently tags are implemented as instances of a [sum type](https://github.com/MasonProtter/SumTypes.jl) and have fairly constrained structure. Most of them are contrained to contain only Symbol instances and integers. + +Here is an example of such a generic tag: + +```jldoctest +julia> Tag(:sometagdescriptor, 1, 2, -3) +SymbolIntIntInt(:sometagdescriptor, 1, 2, -3)::Tag +``` + +A tag can have a custom `DataType` as first argument, in which case additional customability in printing is available. E.g. consider the [`EntanglementHistory`] tag used to track how pairs were entangled before a swap happened. + +```jldoctest +julia> using QuantumSavory.ProtocolZoo: EntanglementHistory + +julia> Tag(EntanglementHistory, 1, 2, 3, 4, 5) +Was entangled to 1.2, but swapped with .5 which was entangled to 3.4 +``` + +See also: [`tag!`](@ref), [`query`](@ref) +""" @sum_type Tag :hidden begin Symbol(::Symbol) SymbolInt(::Symbol, ::Int) From 8f909c6812409f88a1123771af277cfcc651aef1 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 5 Mar 2024 16:51:49 -0500 Subject: [PATCH 14/15] spelling --- src/tags.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tags.jl b/src/tags.jl index fd4aef7e..374d3e77 100644 --- a/src/tags.jl +++ b/src/tags.jl @@ -1,5 +1,5 @@ """ -Tags are used to represent classical metadata describing the state (or even history) of nodes and their registers. The library allows the construction of custom tags using the `Tag` constructor. Currently tags are implemented as instances of a [sum type](https://github.com/MasonProtter/SumTypes.jl) and have fairly constrained structure. Most of them are contrained to contain only Symbol instances and integers. +Tags are used to represent classical metadata describing the state (or even history) of nodes and their registers. The library allows the construction of custom tags using the `Tag` constructor. Currently tags are implemented as instances of a [sum type](https://github.com/MasonProtter/SumTypes.jl) and have fairly constrained structure. Most of them are constrained to contain only Symbol instances and integers. Here is an example of such a generic tag: From 428b75e76335ea15ea709771ccae922ddaf00a96 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Tue, 5 Mar 2024 17:05:04 -0500 Subject: [PATCH 15/15] sum types documentation lower bound --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 05e0e0e4..348f77d2 100644 --- a/Project.toml +++ b/Project.toml @@ -53,5 +53,5 @@ Random = "1" Reexport = "1.2.2" ResumableFunctions = "0.6" Statistics = "1" -SumTypes = "0.5.1" +SumTypes = "0.5.5" julia = "1.9"