Closed mhauru closed 2 months ago
My guess is that x[:]
is not concrete (in the sense that it can have different materialization under different circumstance) , so it's not safe to say if a x[:]
subsumes x[:]
.
If I am interpreting this correctly, then it might be an aesthetic choice.
Is there cases you would want otherwise?
This came about in https://github.com/TuringLang/DynamicPPL.jl/pull/637, when trying to split a type unstable VarInfo
into type stable parts, but I already worked around that issue, so that's not really concern. It just seemed strange for a varname not to subsume itself.
Can we assume that when calling subsumes
the symbols in the first argument and in the second argument refer to the same object, i.e. that in the above example x
on both sides is the "same x"? If yes, it seems to me that x[:]
should subsume itself. If not, then I do understand that it doesn't, because x[:]
is a very different thing if in one case x
is of length 2 and in the other of length 3.
There is a way to concretize
a varname like x[:]
e.g.
julia> x = ones(3)
3-element Vector{Float64}:
1.0
1.0
1.0
julia> vn1 = @varname(x[:], true)
x[:]
julia> x = ones(3, 3)
t3×3 Matrix{Float64}:
e 1.0 1.0 1.0
1.0 1.0 1.0
1.0 1.0 1.0
julia> vn2 = @varname(x[:], true)
x[:]
julia> dump(vn1)
VarName{:x, Accessors.IndexLens{Tuple{AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}}}}
optic: Accessors.IndexLens{Tuple{AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}}}
indices: Tuple{AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}}
1: AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}
range: Base.OneTo{Int64}
stop: Int64 3
julia> dump(vn2)
VarName{:x, Accessors.IndexLens{Tuple{AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}}}}
optic: Accessors.IndexLens{Tuple{AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}}}
indices: Tuple{AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}}
1: AbstractPPL.ConcretizedSlice{Int64, Base.OneTo{Int64}}
range: Base.OneTo{Int64}
stop: Int64 9
Looking at Turing's @model
macro.
julia> @macroexpand @model m(x) = x[:] ~ some_d()
quote
function m(__model__::Model, __varinfo__::AbstractVarInfo, __context__::AbstractPPL.AbstractContext, x::Any; )
#= REPL[15]:1 =#
begin
var"##dist#242" = some_d()
var"##vn#239" = (DynamicPPL.resolve_varnames)((VarName){:x}((AbstractPPL.concretize)((Accessors.opticcompose)((Accessors.IndexLens)((:,))), x)), var"##dist#242")
var"##isassumption#240" = begin
if (DynamicPPL.contextual_isassumption)(__context__, var"##vn#239")
if !((DynamicPPL.inargnames)(var"##vn#239", __model__)) || (DynamicPPL.inmissings)(var"##vn#239", __model__)
true
else
(Base.maybeview)(x, :) === missing
end
else
false
end
end
begin
#= /Users/xiandasun/.julia/packages/DynamicPPL/DvdZw/src/compiler.jl:579 =#
var"##retval#244" = if (DynamicPPL.contextual_isfixed)(__context__, var"##vn#239")
x[:] = (DynamicPPL.getfixed_nested)(__context__, var"##vn#239")
elseif var"##isassumption#240"
begin
(var"##value#243", __varinfo__) = (DynamicPPL.tilde_assume!!)(__context__, (DynamicPPL.unwrap_right_vn)((DynamicPPL.check_tilde_rhs)(var"##dist#242"), var"##vn#239")..., __varinfo__)
x = (Accessors.set)(x, (BangBang.AccessorsImpl.prefermutation)((Accessors.opticcompose)((Accessors.IndexLens)((:,)))), var"##value#243")
var"##value#243"
end
else
if !((DynamicPPL.inargnames)(var"##vn#239", __model__))
x[:] = (DynamicPPL.getconditioned_nested)(__context__, var"##vn#239")
end
(var"##value#241", __varinfo__) = (DynamicPPL.tilde_observe!!)(__context__, (DynamicPPL.check_tilde_rhs)(var"##dist#242"), (Base.maybeview)(x, :), var"##vn#239", __varinfo__)
var"##value#241"
end
#= /Users/xiandasun/.julia/packages/DynamicPPL/DvdZw/src/compiler.jl:580 =#
return (var"##retval#244", __varinfo__)
end
end
end
begin
$(Expr(:meta, :doc))
function m(x::Any; )
#= REPL[15]:1 =#
return (Model)(m, NamedTuple{(:x,)}((x,)); )
end
end
end
there is a AbstractPPL.concretize
call, so maybe unconretized varname like x[:]
should not be in the varinfo?
Is there a small example for this?
Cool thanks, I didn't know concretization was a thing at all.
The case I ran into came from using NamedDist
in this test: https://github.com/TuringLang/DynamicPPL.jl/blob/cdd340745271073bac943e73d184c0d0be5aa264/test/compiler.jl#L306
So is the answer then that for unconcretized VarNames
it is indeed correct that a VarName
may not subsume itself, because e.g. the symbol x
might refer to different objects in different contexts, and thus x[:]
in one context may not be a subset of x[:]
in another context?
for unconcretized VarNames it is indeed correct that a VarName may not subsume itself, because e.g. the symbol x might refer to different objects in different contexts, and thus x[:] in one context may not be a subset of x[:] in another context
I think so, or at least this might be the more correct thing to do
Is there a reason why this is intentional?