@@ -78,6 +78,42 @@ function make_empty_value(dist::Distributions.LKJCholesky)
7878 end
7979end
8080
81+ """
82+ hasvalue(
83+ vals::AbstractDict,
84+ vn::VarName,
85+ dist::Distribution;
86+ error_on_incomplete::Bool=false
87+ )
88+
89+ Check if `vals` contains values for `vn` that is compatible with the
90+ distribution `dist`.
91+
92+ This is a more general version of `hasvalue(vals, vn)`, in that even if
93+ `vn` itself is not inside `vals`, it further checks if `vals` contains
94+ sub-values of `vn` that can be used to reconstruct `vn` given `dist`.
95+
96+ The `error_on_incomplete` flag can be used to detect cases where _some_ of
97+ the values needed for `vn` are present, but others are not. This may help
98+ to detect invalid cases where the user has provided e.g. data of the wrong
99+ shape.
100+
101+ For example:
102+
103+ ```jldoctest; setup=:(using Distributions, LinearAlgebra))
104+ julia> d = Dict(@varname(x[1]) => 1.0, @varname(x[2]) => 2.0);
105+
106+ julia> hasvalue(d, @varname(x), MvNormal(zeros(2), I))
107+ true
108+
109+ julia> hasvalue(d, @varname(x), MvNormal(zeros(3), I))
110+ false
111+
112+ julia> hasvalue(d, @varname(x), MvNormal(zeros(3), I); error_on_incomplete=true)
113+ ERROR: hasvalue: only partial values for `x` found in the values provided
114+ [...]
115+ ```
116+ """
81117# TODO (penelopeysm): Figure out tuple / namedtuple distributions, and LKJCholesky (grr)
82118function AbstractPPL. hasvalue (
83119 vals:: AbstractDict ,
@@ -133,6 +169,32 @@ function AbstractPPL.hasvalue(
133169 end
134170end
135171
172+ """
173+ getvalue(vals::AbstractDict, vn::VarName, dist::Distribution)
174+
175+ Retrieve the value of `vn` from `vals`, using the distribution `dist` to
176+ reconstruct the value if necessary.
177+
178+ This is a more general version of `getvalue(vals, vn)`, in that even if `vn`
179+ itself is not inside `vals`, it can still reconstruct the value of `vn`
180+ from sub-values of `vn` that are present in `vals`.
181+
182+ For example:
183+
184+ ```jldoctest; setup=:(using Distributions, LinearAlgebra))
185+ julia> d = Dict(@varname(x[1]) => 1.0, @varname(x[2]) => 2.0);
186+
187+ julia> getvalue(d, @varname(x), MvNormal(zeros(2), I))
188+ 2-element Vector{Float64}:
189+ 1.0
190+ 2.0
191+
192+ julia> # Use `hasvalue` to check for this case before calling `getvalue`.
193+ getvalue(d, @varname(x), MvNormal(zeros(3), I))
194+ ERROR: getvalue: `x` was not found in the values provided
195+ [...]
196+ ```
197+ """
136198function AbstractPPL. getvalue (
137199 vals:: AbstractDict , vn:: VarName , dist:: Distributions.Distribution ;
138200)
0 commit comments