Description
This behaviour with submodels is all very reasonable:
using DynamicPPL, Distributions
@model function f()
x ~ Normal()
y ~ Normal()
end
@model function g()
a ~ to_submodel(f())
end
keys(VarInfo(g()))
# 2-element Vector{VarName{sym, typeof(identity)} where sym}:
# a.x
# a.y
Now, let's say we wanted to condition x
in the inner model. We can do that from the very outermost layer, by conditioning the model g()
. When looked at from the outside, the x
in the inner model is actually var"a.x"
, so that's what we need to use in the conditioning values. We see that this works perfectly:
cg = g() | (@varname(a.x => 1)
keys(VarInfo(cg))
# 1-element Vector{VarName{Symbol("a.y"), typeof(identity)}}:
# a.y
Now if we instead wanted to condition the submodel itself (rather than the outermost model), one should expect that we can do that without prefixing. However, it doesn't work:
@model function h()
a ~ to_submodel(f() | (x = 1,))
end
keys(VarInfo(h()))
# 2-element Vector{VarName{sym, typeof(identity)} where sym}:
# a.x
# a.y
To condition on the inner model, you still have to include the prefix:
@model function h2()
a ~ to_submodel(f() | (@varname(a.x => 1)
end
keys(VarInfo(h2()))
# 1-element Vector{VarName{Symbol("a.y"), typeof(identity)}}:
# a.y
This is quite counterintuitive and opens up things like this:
cf = f() | (x = 1,)
keys(VarInfo(cf)) # [y]
@model function h3()
a ~ to_submodel(cf)
end
keys(VarInfo(h3())) # expected [a.y]; but this is [a.x, a.y]
(Note that old @submodel
had the same issue.)
I didn't test fix
; it might have the same problem.