Skip to content

Commit

Permalink
query fixups and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Krastanov committed Nov 17, 2023
1 parent 3a314f5 commit 0c627af
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 19 deletions.
20 changes: 12 additions & 8 deletions src/QuantumSavory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export project_traceout! #TODO should move to QuantumInterface
import ConcurrentSim
using ResumableFunctions

import SumTypes: @sum_type
import SumTypes: @sum_type, isvariant
import Combinatorics: powerset

@reexport using QuantumSymbolics
Expand All @@ -34,7 +34,7 @@ export Qubit, Qumode, QuantumStateTrait,
UseAsState, UseAsObservable, UseAsOperation,
AbstractBackground
export QuantumChannel
export tag!, tag_types
export tag!, tag_types, W, ❓, query


#TODO you can not assume you can always in-place modify a state. Have all these functions work on stateref, not stateref[]
Expand Down Expand Up @@ -302,13 +302,17 @@ function Base.show(io::IO, net::RegisterNet)
end

function Base.show(io::IO, r::RegRef)
print(io, "Slot $(r.idx)/$(length(r.reg.traits)) of Register $(objectid(r.reg))") # TODO make this length call prettier
print(io, "\nContent:")
i,s = r.reg.stateindices[r.idx], r.reg.staterefs[r.idx]
if isnothing(s)
print(io, "\n nothing")
if get(io, :compact, false) | haskey(io, :typeinfo)
print(io, "Slot $(r.idx)")
else
print(io, "\n $(i) @ $(typeof(s.state[]).name.module).$(typeof(s.state[]).name.name) $(objectid(s.state[]))")
print(io, "Slot $(r.idx)/$(length(r.reg.traits)) of Register $(objectid(r.reg))") # TODO make this length call prettier
print(io, "\nContent:")
i,s = r.reg.stateindices[r.idx], r.reg.staterefs[r.idx]
if isnothing(s)
print(io, "\n nothing")
else
print(io, "\n $(i) @ $(typeof(s.state[]).name.module).$(typeof(s.state[]).name.name) $(objectid(s.state[]))")
end
end
end

Expand Down
54 changes: 43 additions & 11 deletions src/queries.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"""Assign a tag to a slot in a register.
See also: [`query`](@ref), [`tag_types`](@ref)"""
function tag!(ref::RegRef, tag::Tag)
push!(ref.reg.tags[ref.idx], tag)
end
Expand All @@ -9,18 +12,46 @@ struct Wildcard end

"""A wilcard instance for use with the tag querying functionality.
See also: [`query`](@ref), [`tag!`](@ref), [`tag_types`](@ref)"""
See also: [`query`](@ref), [`tag!`](@ref), [`tag_types`](@ref), [`Wildcard`](@ref)"""
const W = Wildcard()
const

"""A wilcard instance for use with the tag querying functionality.
See also: [`query`](@ref), [`tag!`](@ref), [`tag_types`](@ref), [`Wildcard`](@ref)"""
const= W

""" A query function checking for the first slot in a register that has a given tag.
It supports wildcards (instances of `Wildcard` also available as the constants [`W`](@ref) or [`❓`](@ref) which can be entered as `\\:question:` in the REPL).
```jldoctest
julia> r = Register(10);
tag!(r[1], :symbol, 2, 3);
tag!(r[2], :symbol, 4, 5);
tag!(r[5], Int, 4, 5);
julia> query(r, :symbol, 4, 5)
(Slot 2, SymbolIntInt(:symbol, 4, 5)::QuantumSavory.Tag)
julia> query(r, :symbol, ❓, 3)
(Slot 1, SymbolIntInt(:symbol, 2, 3)::QuantumSavory.Tag)
julia> query(r, :othersym, ❓, ❓) |> isnothing
true
julia> query(r, Float64, 4, 5) |> isnothing
true
```
"""
function query(reg::Register, tag::Tag)
i = findfirst(set -> tag set, reg.tags)
isnothing(i) ? nothing : (reg.refs[i], tag)
isnothing(i) ? nothing : (reg[i], tag)
end

_query_and() = true
_query_and(a::Bool) = a
_query_and(a::Bool, b::Bool) = a && b
_query_all() = true
_query_all(a::Bool) = a
_query_all(a::Bool, b::Bool) = a && b
_query_all(a::Bool, b::Bool, c::Bool) = a && b && c

# Create a query function for each combination of tag arguments and/or wildcard arguments
for (tagsymbol, tagvariant) in pairs(tag_types)
Expand All @@ -39,17 +70,18 @@ for (tagsymbol, tagvariant) in pairs(tag_types)
int_idx_all = [i for (i,s) in enumerate(sig) if s == Int]
int_idx_combs = powerset(int_idx_all, 1)
for idx in int_idx_combs
complement_idx = tuple(setdiff(int_idx_all, idx)...)
complement_idx = tuple(setdiff(1:length(sig), idx)...)
sig_wild = collect(sig)
sig_wild[idx] .= Wildcard
argssig_wild = [:($a::$t) for (a,t) in zip(args, sig_wild)]
nonwild_checks = [:(tag.data[i]==$(args[i])) for i in complement_idx]
nonwild_checks = [:(tag.data[$i]==$(args[i])) for i in complement_idx]
eval(quote function query(reg::Register, $(argssig_wild...))
for (reg_idx, tags) in enumerate(reg.tags)
for tag in tags
if isvariant(tag, $(tagsymbol))
if _query_all($(nonwild_checks...)) end
return (reg_idx, tag)
if isvariant(tag, ($(tagsymbol,))[1]) # a weird workaround for interpolating a symbol as a symbol
if _query_all($(nonwild_checks...))
return (reg[reg_idx], tag)
end
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREA
@doset "noninstant_and_backgrounds_qubit"
@doset "noninstant_and_backgrounds_qumode"

@doset "tags_and_queries"

@doset "circuitzoo_api"
@doset "circuitzoo_purification"
@doset "circuitzoo_superdense"
Expand Down
14 changes: 14 additions & 0 deletions test/test_tags_and_queries.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using QuantumSavory
using Test

r = Register(10)
tag!(r[1], :symbol1, 2, 3)
tag!(r[2], :symbol1, 4, 5)
tag!(r[5], Int, 4, 5)

@test query(r, :symbol1, 4, ❓) == (r[2], tag_types.SymbolIntInt(:symbol1, 4, 5))
@test query(r, :symbol1, 4, 5) == (r[2], tag_types.SymbolIntInt(:symbol1, 4, 5))
@test query(r, :symbol1, ❓, ❓) == (r[1], tag_types.SymbolIntInt(:symbol1, 2, 3))
@test query(r, :symbol2, ❓, ❓) == nothing
@test query(r, Int, 4, 5) == (r[5], tag_types.TypeIntInt(Int, 4, 5))
@test query(r, Float32, 4, 5) == nothing

0 comments on commit 0c627af

Please sign in to comment.