Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colon doesn't subsume itself #99

Closed
mhauru opened this issue Aug 15, 2024 · 5 comments
Closed

Colon doesn't subsume itself #99

mhauru opened this issue Aug 15, 2024 · 5 comments

Comments

@mhauru
Copy link
Member

mhauru commented Aug 15, 2024

Is there a reason why this is intentional?

julia> DynamicPPL.subsumes(@varname(x[:]), @varname(x[:]))
ERROR: Colons cannot be subsumed
@sunxd3
Copy link
Member

sunxd3 commented Aug 15, 2024

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?

@mhauru
Copy link
Member Author

mhauru commented Aug 16, 2024

This came about in TuringLang/DynamicPPL.jl#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.

@sunxd3
Copy link
Member

sunxd3 commented Aug 16, 2024

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

ref:

@varname(expr, concretize=false)

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?

@mhauru
Copy link
Member Author

mhauru commented Aug 16, 2024

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?

@sunxd3
Copy link
Member

sunxd3 commented Aug 16, 2024

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

@mhauru mhauru closed this as completed Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants