Adding a variable to `missings` in a `Model` does not propagate to a submodel
julia> @model demo_inner(x) = x ~ Normal()
demo_inner (generic function with 1 method)
julia> @model demo(x) = @submodel demo_inner(x)
demo (generic function with 1 method)
julia> m = demo(1.0);
julia> m()
1.0
julia> m_missing = Model{(:x, )}(m.name, m.f, m.args, m.defaults);
julia> m_missing()
1.0
And the issue is that I don't even know what the correct solution is here! E.g. you can for example have x in both parent- and submodel, and so setting x as missing as in the above example is ambiguous even if we could propagate the information.
Only proper solution I see to this is a context which allows forcing missing. This could then accomodate for variables of submodels which are potentially prefixed.
It seems the main issue is that currently it is not clearly defined if missings is based on the name of the arguments or name of random variables in the model. And they differ in submodels.
I always thought missings should be based on the random variables (and probably also allow us to specify that e.g. only x[2] is missing). Thus in the example one would have to include demo_inner.x in missings but not x. This would fix the confusion and surprises, it seems, and also allow to propagate missings by subsetting missings of the parent model in the @submodel macro.
Agreed, but:
- Maybe having
missingsin the type of the model isn't the best approach then, given that stuff likex[1]won't always be inferrable at compile-time, e.g.x[i]. - This requires making
isassumptiontake into account the "namespace"/prefix being used, i.e. it needs to look at thevarinfo.
Maybe it would make more sense to do this together with a ConditionContext? E.g. allow "deconditioning" by making isassumption return true. It's one of the things I mention as possible usecases in #274.
I don't think 2 is needed. I assume one can call _evaluate not with the model but with merge_missings(model, __model__) where merge_missings adds the missings of __model__ that begin with Symbol(model.name, ".") to model?
I don't think 2 is needed. I assume one can call _evaluate not with the model but with merge_missings(model, model) where merge_missings adds the missings of model that begin with Symbol(model.name, ".") to model?
But model.name isn't sufficient to guarantee uniqueness, so you can have other completely different prefixes for the variable. Maybe I misunderstand what you're saying? :confused: