Skip to content

Commit 93ceec4

Browse files
committed
Re-add tests and doctests
1 parent 9752c48 commit 93ceec4

File tree

2 files changed

+159
-6
lines changed

2 files changed

+159
-6
lines changed

src/model.jl

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ Return the conditioned values in `model`.
446446
```jldoctest
447447
julia> using Distributions
448448
449-
julia> using DynamicPPL: conditioned, contextualize
449+
julia> using DynamicPPL: conditioned
450450
451451
julia> @model function demo()
452452
m ~ Normal()
@@ -456,8 +456,24 @@ demo (generic function with 2 methods)
456456
457457
julia> m = demo();
458458
459-
julia> # Returns all the variables we have conditioned on + their values.
460-
conditioned(condition(m, x=100.0, m=1.0))
459+
julia> # Condition on some values.
460+
cm = m | (; x = 100.0, m = 1.0);
461+
462+
julia> # Returns all the variables we have conditioned on, and their values.
463+
conditioned(cm)
464+
(x = 100.0, m = 1.0)
465+
466+
julia> # If we prefix the model, the conditioned variables will also be prefixed.
467+
pm = prefix(cm, @varname(f)); conditioned(pm)
468+
Dict{VarName{:f}, Float64} with 2 entries:
469+
f.x => 100.0
470+
f.m => 1.0
471+
472+
julia> # If we condition _after_ the prefix, the prefix is not applied.
473+
pm2 = prefix(m, @varname(f)); cm2 = pm2 | (; x = 100.0, m = 1.0);
474+
475+
julia> # When running this model, the variables inside are not treated as conditioned!
476+
conditioned(cm2)
461477
(x = 100.0, m = 1.0)
462478
```
463479
"""
@@ -762,7 +778,7 @@ Return the fixed values in `model`.
762778
```jldoctest
763779
julia> using Distributions
764780
765-
julia> using DynamicPPL: fixed, contextualize
781+
julia> using DynamicPPL: fixed
766782
767783
julia> @model function demo()
768784
m ~ Normal()
@@ -772,8 +788,24 @@ demo (generic function with 2 methods)
772788
773789
julia> m = demo();
774790
775-
julia> # Returns all the variables we have fixed on + their values.
776-
fixed(fix(m, x=100.0, m=1.0))
791+
julia> # Fix some values.
792+
fm = fix(m, (; x = 100.0, m = 1.0));
793+
794+
julia> # Returns all the variables we have fixed on, and their values.
795+
fixed(fm)
796+
(x = 100.0, m = 1.0)
797+
798+
julia> # If we prefix the model, the fixed variables will also be prefixed.
799+
pm = prefix(fm, @varname(f)); fixed(pm)
800+
Dict{VarName{:f}, Float64} with 2 entries:
801+
f.x => 100.0
802+
f.m => 1.0
803+
804+
julia> # If we fix _after_ the prefix, the prefix is not applied.
805+
pm2 = prefix(m, @varname(f)); fm2 = fix(pm2, (; x = 100.0, m = 1.0));
806+
807+
julia> # When running this model, the variables inside are not treated as fixed!
808+
fixed(fm2)
777809
(x = 100.0, m = 1.0)
778810
```
779811
"""

test/prefix.jl

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
"""
2+
Note that `test/submodel.jl` also contains a number of tests which make use of
3+
prefixing functionality (more like end-to-end tests). This file contains what
4+
are essentially unit tests for prefixing functions.
5+
"""
6+
module DPPLPrefixTests
7+
8+
using DynamicPPL
9+
# not exported
10+
using DynamicPPL: FixedContext, prefix_cond_and_fixed_variables, childcontext
11+
using Distributions
12+
using Test
13+
14+
@testset "prefix.jl" begin
15+
@testset "prefix_cond_and_fixed_variables" begin
16+
@testset "ConditionContext" begin
17+
c1 = ConditionContext((c=1, d=2))
18+
c1_prefixed = prefix_cond_and_fixed_variables(c1, @varname(a))
19+
@test c1_prefixed isa ConditionContext
20+
@test childcontext(c1_prefixed) isa DefaultContext
21+
@test length(c1_prefixed.values) == 2
22+
@test c1_prefixed.values[@varname(a.c)] == 1
23+
@test c1_prefixed.values[@varname(a.d)] == 2
24+
end
25+
26+
@testset "FixedContext" begin
27+
c2 = FixedContext((f=1, g=2))
28+
c2_prefixed = prefix_cond_and_fixed_variables(c2, @varname(a))
29+
@test c2_prefixed isa FixedContext
30+
@test childcontext(c2_prefixed) isa DefaultContext
31+
@test length(c2_prefixed.values) == 2
32+
@test c2_prefixed.values[@varname(a.f)] == 1
33+
@test c2_prefixed.values[@varname(a.g)] == 2
34+
end
35+
36+
@testset "Nested ConditionContext and FixedContext" begin
37+
c3 = ConditionContext((c=1, d=2), FixedContext((f=1, g=2)))
38+
c3_prefixed = prefix_cond_and_fixed_variables(c3, @varname(a))
39+
c3_prefixed_child = childcontext(c3_prefixed)
40+
@test c3_prefixed isa ConditionContext
41+
@test length(c3_prefixed.values) == 2
42+
@test c3_prefixed.values[@varname(a.c)] == 1
43+
@test c3_prefixed.values[@varname(a.d)] == 2
44+
@test c3_prefixed_child isa FixedContext
45+
@test length(c3_prefixed_child.values) == 2
46+
@test c3_prefixed_child.values[@varname(a.f)] == 1
47+
@test c3_prefixed_child.values[@varname(a.g)] == 2
48+
@test childcontext(c3_prefixed_child) isa DefaultContext
49+
end
50+
end
51+
52+
@testset "DynamicPPL.prefix(::Model, x)" begin
53+
@model function demo()
54+
x ~ Normal()
55+
return y ~ Normal()
56+
end
57+
model = demo()
58+
59+
@testset "No conditioning / fixing" begin
60+
pmodel = DynamicPPL.prefix(model, @varname(a))
61+
@test pmodel.prefix == @varname(a)
62+
vi = VarInfo(pmodel)
63+
@test Set(keys(vi)) == Set([@varname(a.x), @varname(a.y)])
64+
end
65+
66+
@testset "Prefixing a conditioned model" begin
67+
cmodel = model | (; x=1.0)
68+
# Sanity check.
69+
vi = VarInfo(cmodel)
70+
@test Set(keys(vi)) == Set([@varname(y)])
71+
# Now prefix.
72+
pcmodel = DynamicPPL.prefix(cmodel, @varname(a))
73+
@test pcmodel.prefix == @varname(a)
74+
# Because the model was conditioned on `x` _prior_ to prefixing,
75+
# the resulting `a.x` variable should also be conditioned. In
76+
# other words, which variables are treated as conditioned should be
77+
# invariant to prefixing.
78+
vi = VarInfo(pcmodel)
79+
@test Set(keys(vi)) == Set([@varname(a.y)])
80+
end
81+
82+
@testset "Prefixing a fixed model" begin
83+
# Same as above but for FixedContext rather than Condition.
84+
fmodel = fix(model, (; y=1.0))
85+
# Sanity check.
86+
vi = VarInfo(fmodel)
87+
@test Set(keys(vi)) == Set([@varname(x)])
88+
# Now prefix.
89+
pfmodel = DynamicPPL.prefix(fmodel, @varname(a))
90+
@test pfmodel.prefix == @varname(a)
91+
# Because the model was conditioned on `x` _prior_ to prefixing,
92+
# the resulting `a.x` variable should also be conditioned. In
93+
# other words, which variables are treated as conditioned should be
94+
# invariant to prefixing.
95+
vi = VarInfo(pfmodel)
96+
@test Set(keys(vi)) == Set([@varname(a.x)])
97+
end
98+
99+
@testset "Conditioning a prefixed model" begin
100+
# If the prefixing happens first, then we want to make sure that the
101+
# user is forced to apply conditioning WITH the prefix.
102+
pmodel = DynamicPPL.prefix(model, @varname(a))
103+
104+
# If this doesn't happen...
105+
cpmodel_wrong = pmodel | (; x=1.0)
106+
@test cpmodel_wrong.prefix == @varname(a)
107+
vi = VarInfo(cpmodel_wrong)
108+
# Then `a.x` will be `assume`d
109+
@test Set(keys(vi)) == Set([@varname(a.x), @varname(a.y)])
110+
111+
# If it does...
112+
cpmodel_right = pmodel | (@varname(a.x) => 1.0)
113+
@test cpmodel_right.prefix == @varname(a)
114+
vi = VarInfo(cpmodel_right)
115+
# Then `a.x` will be `observe`d
116+
@test Set(keys(vi)) == Set([@varname(a.y)])
117+
end
118+
end
119+
end
120+
121+
end

0 commit comments

Comments
 (0)