1
1
using Test, DynamicPPL, Accessors
2
+ using AbstractPPL: getoptic
2
3
using DynamicPPL:
3
4
leafcontext,
4
5
setleafcontext,
@@ -57,7 +58,7 @@ Base.IteratorEltype(::Type{<:AbstractContext}) = Base.EltypeUnknown()
57
58
(x= 1.0 ,), DynamicPPL. TestUtils. TestParentContext (ConditionContext ((y= 2.0 ,)))
58
59
),
59
60
:condition3 => ConditionContext (
60
- (x= 1.0 ,), PrefixContext {:a} (ConditionContext (Dict (@varname (a . y) => 2.0 )))
61
+ (x= 1.0 ,), PrefixContext {:a} (ConditionContext (Dict (@varname (y) => 2.0 )))
61
62
),
62
63
:condition4 => ConditionContext ((x= [1.0 , missing ],)),
63
64
)
@@ -70,91 +71,53 @@ Base.IteratorEltype(::Type{<:AbstractContext}) = Base.EltypeUnknown()
70
71
end
71
72
end
72
73
73
- @testset " contextual_isassumption" begin
74
- @testset " $(name) " for (name, context) in contexts
75
- # Any `context` should return `true` by default.
76
- @test contextual_isassumption (context, VarName {gensym(:x)} ())
77
-
78
- if any (Base. Fix2 (isa, ConditionContext), context)
79
- # We have a `ConditionContext` among us.
80
- # Let's first extract the conditioned variables.
81
- conditioned_values = DynamicPPL. conditioned (context)
82
-
83
- # The conditioned values might be a NamedTuple, or a Dict.
84
- # We convert to a Dict for consistency
85
- if conditioned_values isa NamedTuple
86
- conditioned_values = Dict (
87
- VarName {sym} () => val for (sym, val) in pairs (conditioned_values)
88
- )
89
- end
90
-
91
- for (vn, val) in pairs (conditioned_values)
92
- # We need to drop the prefix of `var` since in `contextual_isassumption`
93
- # it will be threaded through the `PrefixContext` before it reaches
94
- # `ConditionContext` with the conditioned variable.
95
- vn_without_prefix = if getoptic (vn) isa PropertyLens
96
- # Hacky: This assumes that there is exactly one level of prefixing
97
- # that we need to undo. This is appropriate for the :condition3
98
- # test case above, but is not generally correct.
99
- AbstractPPL. unprefix (vn, VarName {getsym(vn)} ())
100
- else
101
- vn
102
- end
103
-
104
- @show DynamicPPL. TestUtils. varname_leaves (vn_without_prefix, val)
105
- # Let's check elementwise.
106
- for vn_child in
107
- DynamicPPL. TestUtils. varname_leaves (vn_without_prefix, val)
108
- if getoptic (vn_child)(val) === missing
109
- @test contextual_isassumption (context, vn_child)
110
- else
111
- @test ! contextual_isassumption (context, vn_child)
112
- end
113
- end
114
- end
115
- end
116
- end
117
- end
74
+ @testset " extracting conditioned values" begin
75
+ # This testset tests `contextual_isassumption`, `getconditioned_nested`, and
76
+ # `hasconditioned_nested`.
118
77
119
- @testset " getconditioned_nested & hasconditioned_nested " begin
120
- @testset " $name " for (name, context) in contexts
78
+ @testset " $(name) " for (name, context) in contexts
79
+ # If the varname doesn't exist, it should always be an assumption.
121
80
fake_vn = VarName {gensym(:x)} ()
81
+ @test contextual_isassumption (context, fake_vn)
122
82
@test ! hasconditioned_nested (context, fake_vn)
123
83
@test_throws ErrorException getconditioned_nested (context, fake_vn)
124
84
125
85
if any (Base. Fix2 (isa, ConditionContext), context)
126
- # `ConditionContext` specific.
127
-
86
+ # We have a `ConditionContext` among us.
128
87
# Let's first extract the conditioned variables.
129
88
conditioned_values = DynamicPPL. conditioned (context)
89
+
130
90
# The conditioned values might be a NamedTuple, or a Dict.
131
91
# We convert to a Dict for consistency
132
- if conditioned_values isa NamedTuple
133
- conditioned_values = Dict (
134
- VarName {sym} () => val for (sym, val) in pairs (conditioned_values)
135
- )
136
- end
137
-
138
- for (vn, val) in pairs (conditioned_values)
139
- # We need to drop the prefix of `var` since in `contextual_isassumption`
140
- # it will be threaded through the `PrefixContext` before it reaches
141
- # `ConditionContext` with the conditioned variable.
142
- vn_without_prefix = if getoptic (vn) isa PropertyLens
143
- # Hacky: This assumes that there is exactly one level of prefixing
144
- # that we need to undo. This is appropriate for the :condition3
145
- # test case above, but is not generally correct.
146
- AbstractPPL. unprefix (vn, VarName {getsym(vn)} ())
92
+ conditioned_values = DynamicPPL. to_varname_dict (conditioned_values)
93
+
94
+ # Extract all conditioned variables. We also use varname_leaves
95
+ # here to split up arrays which could potentially have some,
96
+ # but not all, elements being `missing`.
97
+ conditioned_vns = mapreduce (
98
+ p -> DynamicPPL. TestUtils. varname_leaves (p. first, p. second),
99
+ vcat,
100
+ pairs (conditioned_values),
101
+ )
102
+ @show conditioned_vns
103
+
104
+ # We can now loop over them to check which ones are missing. We use
105
+ # `getvalue` to handle the awkward case where sometimes
106
+ # `conditioned_values` contains the full Varname (e.g. `a.x`) and
107
+ # sometimes only the main symbol (e.g. it contains `x` when
108
+ # `vn` is `x[1]`)
109
+ for vn in conditioned_vns
110
+ val = DynamicPPL. getvalue (conditioned_values, vn)
111
+ # These VarNames are present in the conditioning values, so
112
+ # we should always be able to extract the value.
113
+ @test hasconditioned_nested (context, vn)
114
+ @test getconditioned_nested (context, vn) === val
115
+ # However, the return value of contextual_isassumption depends on
116
+ # whether the value is missing or not.
117
+ if ismissing (val)
118
+ @test contextual_isassumption (context, vn)
147
119
else
148
- vn
149
- end
150
-
151
- for vn_child in
152
- DynamicPPL. TestUtils. varname_leaves (vn_without_prefix, val)
153
- # `vn_child` should be in `context`.
154
- @test hasconditioned_nested (context, vn_child)
155
- # Value should be the same as extracted above.
156
- @test getconditioned_nested (context, vn_child) ===
157
- getoptic (vn_child)(val)
120
+ @test ! contextual_isassumption (context, vn)
158
121
end
159
122
end
160
123
end
0 commit comments