Closed
Description
Consider the following simple programs
using Gen
@gen function model_ok()
k ~ poisson(5)
for i=1:k
{i} ~ uniform(0,1)
end
end
@gen function model_bad()
k ~ poisson(5)
for i=1:k
{:value => i} ~ uniform(0,1)
end
end
Do we expect that Gen.update
operates differently in these two cases. For model_ok
, if we call update
in such a way that reduces k
then the discard address {i}
are correctly placed in the discard
, but in model_bad
, the address {:value => i}
are not in the discard. See following example:
Discard for model_ok
julia> tr, = Gen.generate(model_ok, (), choicemap(:k=>3));
julia> (new_trace, weight, _, discard) = Gen.update(tr, Gen.choicemap(:k=>1));
julia> display(discard)
│
├── :k : 3
│
├── 2 : 0.552591934644268
│
└── 3 : 0.6198635352707209
Discard for model_bad
julia> tr, = Gen.generate(model_bad, (), choicemap(:k=>3));
julia> (new_trace, weight, _, discard) = Gen.update(tr, Gen.choicemap(:k=>1));
julia> display(discard)
│
└── :k : 3
Possible Reason
The following lines seem to be the culprit: the recursive call to add_unvisited_to_discard!
use an anonymous choicemap when subdiscard
is empty, so the call to set_submap!
fills out a subdiscard
that we never access again.
Lines 177 to 181 in 7955b07
Changing these lines to
subdiscard = get_submap(discard, key)
subdiscard_recursive = isempty(subdiscard) ? choicemap() : subdiscard
add_unvisited_to_discard!(
subdiscard_recursive,
subvisited, submap)
set_submap!(discard, key, subdiscard_recursive)
seems to fix the issue.