From 12fe212f9528e899f5b861e0765b05e11e4f581b Mon Sep 17 00:00:00 2001 From: apkille Date: Wed, 12 Jun 2024 13:13:27 -0400 Subject: [PATCH] updates from TermInterface v1.0.1 --- ext/QuantumCliffordExt/QuantumCliffordExt.jl | 4 +-- ext/QuantumOpticsExt/QuantumOpticsExt.jl | 2 +- src/QSymbolicsBase/QSymbolicsBase.jl | 6 ++-- src/QSymbolicsBase/basic_ops_homogeneous.jl | 22 +++++++++----- src/QSymbolicsBase/basic_ops_inhomogeneous.jl | 30 ++++++++++++------- src/QSymbolicsBase/express.jl | 2 +- src/QSymbolicsBase/latexify.jl | 8 ++--- src/QSymbolicsBase/predefined.jl | 26 +++++++++------- src/QSymbolicsBase/predefined_CPTP.jl | 2 +- src/QSymbolicsBase/rules.jl | 4 +-- src/extensions.jl | 2 +- 11 files changed, 64 insertions(+), 44 deletions(-) diff --git a/ext/QuantumCliffordExt/QuantumCliffordExt.jl b/ext/QuantumCliffordExt/QuantumCliffordExt.jl index c40c3e9..1ef9376 100644 --- a/ext/QuantumCliffordExt/QuantumCliffordExt.jl +++ b/ext/QuantumCliffordExt/QuantumCliffordExt.jl @@ -9,7 +9,7 @@ using QuantumSymbolics: HGate, XGate, YGate, ZGate, CPHASEGate, CNOTGate, Symbolic import QuantumSymbolics: express, express_nolookup, express_from_cache using TermInterface -using TermInterface: istree, exprhead, operation, arguments, similarterm, metadata +using TermInterface: isexpr, head, operation, arguments, metadata using QuantumClifford @@ -24,7 +24,7 @@ express_nolookup(s::XBasisState, ::CliffordRepr) = (_qc_s₊,_qc_s₋)[s.idx] express_nolookup(s::YBasisState, ::CliffordRepr) = (_qc_i₊,_qc_i₋)[s.idx] express_nolookup(s::ZBasisState, ::CliffordRepr) = (_qc_l,_qc_h)[s.idx] function express_nolookup(s::Symbolic{T}, repr::CliffordRepr) where {T<:Union{AbstractKet,AbstractOperator}} - if istree(s) && operation(s)==⊗ + if isexpr(s) && operation(s)==⊗ #operation(s)(express.(arguments(s), (repr,))...) # TODO this does not work because QuantumClifford.⊗ is different from ⊗ QuantumClifford.tensor(express.(arguments(s), (repr,))...) else diff --git a/ext/QuantumOpticsExt/QuantumOpticsExt.jl b/ext/QuantumOpticsExt/QuantumOpticsExt.jl index 245ff80..ec0188d 100644 --- a/ext/QuantumOpticsExt/QuantumOpticsExt.jl +++ b/ext/QuantumOpticsExt/QuantumOpticsExt.jl @@ -12,7 +12,7 @@ using QuantumSymbolics: qubit_basis, inf_fock_basis import QuantumSymbolics: express, express_nolookup using TermInterface -using TermInterface: istree, exprhead, operation, arguments, similarterm, metadata +using TermInterface: isexpr, head, operation, arguments, metadata const _b2 = SpinBasis(1//2) const _l0 = spinup(_b2) diff --git a/src/QSymbolicsBase/QSymbolicsBase.jl b/src/QSymbolicsBase/QSymbolicsBase.jl index e1f352c..e4a1eb1 100644 --- a/src/QSymbolicsBase/QSymbolicsBase.jl +++ b/src/QSymbolicsBase/QSymbolicsBase.jl @@ -3,7 +3,7 @@ import Symbolics: simplify using SymbolicUtils import SymbolicUtils: Symbolic, _isone, flatten_term, isnotflat, Chain, Fixpoint using TermInterface -import TermInterface: istree, exprhead, operation, arguments, similarterm, metadata +import TermInterface: isexpr, head, iscall, children, operation, arguments, metadata using LinearAlgebra import LinearAlgebra: eigvecs @@ -47,7 +47,7 @@ end function countmap_flatten(samples, flattenhead) counts = Dict{Any,Any}() for s in samples - if istree(s) && s isa flattenhead # TODO Could you use the TermInterface `operation` here instead of `flattenhead`? + if isexpr(s) && s isa flattenhead # TODO Could you use the TermInterface `operation` here instead of `flattenhead`? coef, term = arguments(s) counts[term] = get(counts, term, 0)+coef else @@ -134,7 +134,7 @@ Base.:(-)(x::SymQObj,y::SymQObj) = x + (-y) function Base.isequal(x::X,y::Y) where {X<:SymQObj, Y<:SymQObj} if X==Y - if istree(x) + if isexpr(x) if operation(x)==operation(y) ax,ay = arguments(x),arguments(y) (length(ax) == length(ay)) && all(zip(ax,ay)) do xy isequal(xy...) end diff --git a/src/QSymbolicsBase/basic_ops_homogeneous.jl b/src/QSymbolicsBase/basic_ops_homogeneous.jl index 65c6784..9c7ef7d 100644 --- a/src/QSymbolicsBase/basic_ops_homogeneous.jl +++ b/src/QSymbolicsBase/basic_ops_homogeneous.jl @@ -9,7 +9,7 @@ struct SOperator <: Symbolic{AbstractKet} basis::Basis end const SymQ = Union{SKet, SOperator} -istree(::SymQ) = false +isexpr(::SymQ) = false metadata(::SymQ) = nothing basis(x::SymQ) = x.basis @@ -24,10 +24,12 @@ Base.show(io::IO, x::SymQObj) = print(io, symbollabel(x)) # fallback that probab obj SScaled{S}(c,k) where S = _isone(c) ? k : new{S}(c,k) end -istree(::SScaled) = true -arguments(x::SScaled) = [x.coeff, x.obj] +isexpr(::SScaled) = true +iscall(::SScaled) = true +arguments(x::SScaled) = [x.coeff,x.obj] operation(x::SScaled) = * -exprhead(x::SScaled) = :* +head(x::SScaled) = :* +children(x::SScaled) = [:*,x.coeff,x.obj] Base.:(*)(c, x::Symbolic{T}) where {T<:QObj} = SScaled{T}(c,x) Base.:(*)(x::Symbolic{T}, c) where {T<:QObj} = SScaled{T}(c,x) Base.:(/)(x::Symbolic{T}, c) where {T<:QObj} = SScaled{T}(1/c,x) @@ -63,10 +65,12 @@ end dict SAdd{S}(d) where S = length(d)==1 ? SScaled{S}(reverse(first(d))...) : new{S}(d) end -istree(::SAdd) = true +isexpr(::SAdd) = true +iscall(::SAdd) = true arguments(x::SAdd) = [SScaledKet(v,k) for (k,v) in pairs(x.dict)] operation(x::SAdd) = + -exprhead(x::SAdd) = :+ +head(x::SAdd) = :+ +children(x::SAdd) = [:+,SScaledKet(v,k) for (k,v) in pairs(x.dict)] Base.:(+)(xs::Vararg{Symbolic{T},N}) where {T<:QObj,N} = SAdd{T}(countmap_flatten(xs, SScaled{T})) Base.:(+)(xs::Vararg{Symbolic{<:QObj},0}) = 0 # to avoid undefined type parameters issue in the above method basis(x::SAdd) = basis(first(x.dict).first) @@ -86,10 +90,12 @@ Base.show(io::IO, x::SAddBra) = print(io, "("*join(map(string, arguments(x)),"+" coeff * new{S}(cleanterms) end end -istree(::STensor) = true +isexpr(::STensor) = true +iscall(::STensor) = true arguments(x::STensor) = x.terms operation(x::STensor) = ⊗ -exprhead(x::STensor) = :⊗ +head(x::STensor) = :⊗ +children(x::STensor) = pushfirst!(x.terms,:⊗) ⊗(xs::Symbolic{T}...) where {T<:QObj} = STensor{T}(collect(xs)) basis(x::STensor) = tensor(basis.(x.terms)...) diff --git a/src/QSymbolicsBase/basic_ops_inhomogeneous.jl b/src/QSymbolicsBase/basic_ops_inhomogeneous.jl index 3ce4caa..e657d34 100644 --- a/src/QSymbolicsBase/basic_ops_inhomogeneous.jl +++ b/src/QSymbolicsBase/basic_ops_inhomogeneous.jl @@ -5,10 +5,12 @@ op ket end -istree(::SApplyKet) = true +isexpr(::SApplyKet) = true +iscall(::SApplyKet) = true arguments(x::SApplyKet) = [x.op,x.ket] operation(x::SApplyKet) = * -exprhead(x::SApplyKet) = :* +head(x::SApplyKet) = :* +children(x::SApplyKet) = [:*,x.op,x.ket] Base.:(*)(op::Symbolic{AbstractOperator}, k::Symbolic{AbstractKet}) = SApplyKet(op,k) Base.show(io::IO, x::SApplyKet) = begin print(io, x.op); print(io, x.ket) end basis(x::SApplyKet) = basis(x.ket) @@ -18,10 +20,12 @@ basis(x::SApplyKet) = basis(x.ket) bra op end -istree(::SApplyBra) = true +isexpr(::SApplyBra) = true +iscall(::SApplyBra) = true arguments(x::SApplyBra) = [x.bra,x.op] operation(x::SApplyBra) = * -exprhead(x::SApplyBra) = :* +head(x::SApplyBra) = :* +children(x::SApplyBra) = [:*,x.bra,x.op] Base.:(*)(b::Symbolic{AbstractBra}, op::Symbolic{AbstractOperator}) = SApplyBra(b,op) Base.show(io::IO, x::SApplyBra) = begin print(io, x.bra); print(io, x.op) end basis(x::SApplyBra) = basis(x.bra) @@ -31,10 +35,12 @@ basis(x::SApplyBra) = basis(x.bra) bra ket end -istree(::SBraKet) = true +isexpr(::SBraKet) = true +iscall(::SBraKet) = true arguments(x::SBraKet) = [x.bra,x.ket] operation(x::SBraKet) = * -exprhead(x::SBraKet) = :* +head(x::SBraKet) = :* +children(x::SBraKet) = [:*,x.bra,x.ket] Base.:(*)(b::Symbolic{AbstractBra}, k::Symbolic{AbstractKet}) = SBraKet(b,k) function Base.show(io::IO, x::SBraKet) print(io,x.bra) @@ -46,10 +52,12 @@ end sop op end -istree(::SApplyOp) = true +isexpr(::SApplyOp) = true +iscall(::SApplyOp) = true arguments(x::SApplyOp) = [x.sop,x.op] operation(x::SApplyOp) = * -exprhead(x::SApplyOp) = :* +head(x::SApplyOp) = :* +children(x::SApplyOp) = [:*,x.sop,x.op] Base.:(*)(sop::Symbolic{AbstractSuperOperator}, op::Symbolic{AbstractOperator}) = SApplyOp(sop,op) Base.:(*)(sop::Symbolic{AbstractSuperOperator}, k::Symbolic{AbstractKet}) = SApplyOp(sop,SProjector(k)) Base.show(io::IO, x::SApplyOp) = begin print(io, x.sop); print(io, x.op) end @@ -60,10 +68,12 @@ basis(x::SApplyOp) = basis(x.op) ket bra end -istree(::SOuterKetBra) = true +isexpr(::SOuterKetBra) = true +iscall(::SOuterKetBra) = true arguments(x::SOuterKetBra) = [x.ket,x.bra] operation(x::SOuterKetBra) = * -exprhead(x::SOuterKetBra) = :* +head(x::SOuterKetBra) = :* +children(x::SOuterKetBra) = [:*,x.ket,x.bra] Base.:(*)(k::Symbolic{AbstractKet}, b::Symbolic{AbstractBra}) = SOuterKetBra(k,b) Base.:(*)(k::SScaledKet, b::Symbolic{AbstractBra}) = k.coeff*SOuterKetBra(k.obj,b) Base.:(*)(k::Symbolic{AbstractKet}, b::SScaledBra) = b.coeff*SOuterKetBra(k,b.obj) diff --git a/src/QSymbolicsBase/express.jl b/src/QSymbolicsBase/express.jl index 520d788..2e10146 100644 --- a/src/QSymbolicsBase/express.jl +++ b/src/QSymbolicsBase/express.jl @@ -78,7 +78,7 @@ express_nolookup(state, ::QuantumMCRepr) = express_nolookup(state, QuantumOptics express(state) = state function express_nolookup(s, repr::AbstractRepresentation) - if istree(s) + if isexpr(s) operation(s)(express.(arguments(s), (repr,))...) else error("Encountered an object $(s) of type $(typeof(s)) that can not be converted to $(repr) representation") # TODO make a nice error type diff --git a/src/QSymbolicsBase/latexify.jl b/src/QSymbolicsBase/latexify.jl index 66cefca..dfd68fb 100644 --- a/src/QSymbolicsBase/latexify.jl +++ b/src/QSymbolicsBase/latexify.jl @@ -28,7 +28,7 @@ end return LaTeXString("\\hat $(symbollabel(x))") end @latexrecipe function f(x::SDagger) - if istree(x.ket) + if isexpr(x.ket) return Expr(:latexifymerge, "\\left( ", x.ket, "\\right)^\\dagger") else return Expr(:latexifymerge, "\\left\\langle ", symbollabel(x), "\\right|") @@ -48,14 +48,14 @@ end end function _toexpr(x) - if istree(x) - return Expr(:call, exprhead(x), arguments(x)...) + if isexpr(x) + return Expr(:call, head(x), arguments(x)...) else x end end function _addparen(x) - if istree(x) + if isexpr(x) return Expr(:latexifymerge, "\\left(", x, "\\right)") else return x diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 9e082f9..16638a6 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -3,7 +3,7 @@ ## abstract type SpecialKet <: Symbolic{AbstractKet} end -istree(::SpecialKet) = false +isexpr(::SpecialKet) = false basis(x::SpecialKet) = x.basis Base.show(io::IO, x::SpecialKet) = print(io, "|$(symbollabel(x))⟩") @@ -84,8 +84,8 @@ abstract type AbstractSingleQubitOp <: Symbolic{AbstractOperator} end abstract type AbstractTwoQubitOp <: Symbolic{AbstractOperator} end abstract type AbstractSingleQubitGate <: AbstractSingleQubitOp end # TODO maybe an IsUnitaryTrait is a better choice abstract type AbstractTwoQubitGate <: AbstractTwoQubitOp end -istree(::AbstractSingleQubitGate) = false -istree(::AbstractTwoQubitGate) = false +isexpr(::AbstractSingleQubitGate) = false +isexpr(::AbstractTwoQubitGate) = false basis(::AbstractSingleQubitGate) = qubit_basis basis(::AbstractTwoQubitGate) = qubit_basis⊗qubit_basis Base.show(io::IO, x::AbstractSingleQubitOp) = print(io, "$(symbollabel(x))") @@ -97,7 +97,7 @@ Base.show(io::IO, x::AbstractTwoQubitOp) = print(io, "$(symbollabel(x))") indices::Vector{Int} basis::Basis end -istree(::OperatorEmbedding) = true +isexpr(::OperatorEmbedding) = true @withmetadata struct XGate <: AbstractSingleQubitGate end eigvecs(g::XGate) = [X1,X2] @@ -157,7 +157,7 @@ const CPHASE = CPHASEGate() abstract type AbstractSingleBosonOp <: Symbolic{AbstractOperator} end abstract type AbstractSingleBosonGate <: AbstractSingleBosonOp end # TODO maybe an IsUnitaryTrait is a better choice -istree(::AbstractSingleBosonGate) = false +isexpr(::AbstractSingleBosonGate) = false basis(::AbstractSingleBosonGate) = inf_fock_basis @withmetadata struct NumberOp <: AbstractSingleBosonOp end @@ -193,10 +193,12 @@ Operator(dim=2x2) @withmetadata struct SProjector <: Symbolic{AbstractOperator} ket::Symbolic{AbstractKet} # TODO parameterize end -istree(::SProjector) = true +isexpr(::SProjector) = true +iscall(::SProjector) = true arguments(x::SProjector) = [x.ket] operation(x::SProjector) = projector -exprhead(x::SProjector) = :projector +head(x::SProjector) = :projector +children(x::SProjector) = [:projector,x.ket] projector(x::Symbolic{AbstractKet}) = SProjector(x) basis(x::SProjector) = basis(x.ket) function Base.show(io::IO, x::SProjector) @@ -209,10 +211,12 @@ end @withmetadata struct SDagger <: Symbolic{AbstractBra} ket::Symbolic{AbstractKet} end -istree(::SDagger) = true +isexpr(::SDagger) = true +iscall(::SDagger) = true arguments(x::SDagger) = [x.ket] operation(x::SDagger) = dagger -exprhead(x::SDagger) = :dagger +head(x::SDagger) = :dagger +children(x::SDagger) = [:dagger, x.ket] dagger(x::Symbolic{AbstractKet}) = SDagger(x) dagger(x::SScaledKet) = SScaledBra(x.coeff, dagger(x.obj)) dagger(x::SAddKet) = SAddBra(Dict(dagger(k)=>v for (k,v) in pairs(x.dict))) @@ -250,7 +254,7 @@ julia> express(MixedState(X1⊗X2), CliffordRepr()) end MixedState(x::Symbolic{AbstractKet}) = MixedState(basis(x)) MixedState(x::Symbolic{AbstractOperator}) = MixedState(basis(x)) -istree(::MixedState) = false +isexpr(::MixedState) = false basis(x::MixedState) = x.basis symbollabel(x::MixedState) = "𝕄" @@ -269,6 +273,6 @@ Operator(dim=2x2) end IdentityOp(x::Symbolic{AbstractKet}) = IdentityOp(basis(x)) IdentityOp(x::Symbolic{AbstractOperator}) = IdentityOp(basis(x)) -istree(::IdentityOp) = false +isexpr(::IdentityOp) = false basis(x::IdentityOp) = x.basis symbollabel(x::IdentityOp) = "𝕀" diff --git a/src/QSymbolicsBase/predefined_CPTP.jl b/src/QSymbolicsBase/predefined_CPTP.jl index 19a09f3..c53fde7 100644 --- a/src/QSymbolicsBase/predefined_CPTP.jl +++ b/src/QSymbolicsBase/predefined_CPTP.jl @@ -1,7 +1,7 @@ export PauliNoiseCPTP, DephasingCPTP, DephasingCPTP, GateCPTP abstract type NoiseCPTP <: Symbolic{AbstractSuperOperator} end -istree(::NoiseCPTP) = false +isexpr(::NoiseCPTP) = false basis(x::NoiseCPTP) = x.basis """Single-qubit Pauli noise CPTP map diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index 5ab0734..b2d72b0 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -9,7 +9,7 @@ function prefactorscalings(xs) terms = [] coeff = 1::Any for x in xs - if istree(x) && operation(x) == * + if isexpr(x) && operation(x) == * c,t = arguments(x) coeff *= c push!(terms,t) @@ -30,7 +30,7 @@ function isnotflat_precheck(*) operation(x) === (*) || return false args = arguments(x) for t in args - if istree(t) && operation(t) === (*) + if isexpr(t) && operation(t) === (*) return true end end diff --git a/src/extensions.jl b/src/extensions.jl index 6ca7f99..80aceea 100644 --- a/src/extensions.jl +++ b/src/extensions.jl @@ -21,7 +21,7 @@ Ket(dim=2) @withmetadata struct StabilizerState{T} <: Symbolic{AbstractKet} where {T} stabilizer::T end -istree(::StabilizerState) = false +isexpr(::StabilizerState) = false basis(x::StabilizerState) = SpinBasis(1//2)^nqubits(x.stabilizer) Base.show(io::IO, x::StabilizerState) = print(io, "𝒮$(num_to_sub(nqubits(x.stabilizer)))")