Skip to content

Commit e6d84db

Browse files
committed
AbstractPPL 0.11; change prefixing behaviour
1 parent 324e623 commit e6d84db

File tree

11 files changed

+58
-71
lines changed

11 files changed

+58
-71
lines changed

HISTORY.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# DynamicPPL Changelog
22

3+
## 0.36.0
4+
5+
**Breaking changes**
6+
7+
### VarName prefixing behaviour
8+
9+
Previously, a prefixed varname would concatenate its prefixes with the symbol.
10+
Now, a prefixed varname creates a new field on the prefix.
11+
This is rather abstract, so it's best explained through an example.
12+
Consider this model and submodel:
13+
14+
```julia
15+
using DynamicPPL, Distributions
16+
@model inner() = x ~ Normal()
17+
@model outer() = a ~ to_submodel(inner())
18+
```
19+
20+
In previous versions, the inner variable `x` would be saved as `a.x`.
21+
However, this was represented as a single symbol `Symbol("a.x")`:
22+
23+
```julia
24+
julia> dump(keys(VarInfo(outer()))[1])
25+
VarName{Symbol("a.x"), typeof(identity)}
26+
optic: identity (function of type typeof(identity))
27+
```
28+
29+
Now, the inner variable is stored as a field `x` on the VarName `a`:
30+
31+
```julia
32+
julia> dump(keys(VarInfo(outer()))[1])
33+
VarName{:a, Accessors.PropertyLens{:x}}
34+
optic: Accessors.PropertyLens{:x} (@o _.x)
35+
```
36+
337
## 0.35.5
438

539
Several internal methods have been removed:

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ DynamicPPLMooncakeExt = ["Mooncake"]
4444
[compat]
4545
ADTypes = "1"
4646
AbstractMCMC = "5"
47-
AbstractPPL = "0.10.1"
47+
AbstractPPL = "0.11"
4848
Accessors = "0.1"
4949
BangBang = "0.4.1"
5050
Bijectors = "0.13.18, 0.14, 0.15"

src/DynamicPPL.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import Base:
3939
keys,
4040
haskey
4141

42-
import AbstractPPL: predict
42+
import AbstractPPL: predict, prefix
4343

4444
# VarInfo
4545
export AbstractVarInfo,

src/contexts.jl

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -260,21 +260,8 @@ function setchildcontext(::PrefixContext{Prefix}, child) where {Prefix}
260260
return PrefixContext{Prefix}(child)
261261
end
262262

263-
const PREFIX_SEPARATOR = Symbol(".")
264-
265-
@generated function PrefixContext{PrefixOuter}(
266-
context::PrefixContext{PrefixInner}
267-
) where {PrefixOuter,PrefixInner}
268-
return :(PrefixContext{$(QuoteNode(Symbol(PrefixOuter, PREFIX_SEPARATOR, PrefixInner)))}(
269-
context.context
270-
))
271-
end
272-
273263
function prefix(ctx::PrefixContext{Prefix}, vn::VarName{Sym}) where {Prefix,Sym}
274-
vn_prefixed_inner = prefix(childcontext(ctx), vn)
275-
return VarName{Symbol(Prefix, PREFIX_SEPARATOR, getsym(vn_prefixed_inner))}(
276-
getoptic(vn_prefixed_inner)
277-
)
264+
return AbstractPPL.prefix(vn, VarName{Symbol(Prefix)}())
278265
end
279266
prefix(ctx::AbstractContext, vn::VarName) = prefix(NodeTrait(ctx), ctx, vn)
280267
prefix(::IsLeaf, ::AbstractContext, vn::VarName) = vn

src/model.jl

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ julia> model() ≠ 1.0
243243
true
244244
245245
julia> # To condition the variable inside `demo_inner` we need to refer to it as `inner.m`.
246-
conditioned_model = model | (var"inner.m" = 1.0, );
246+
conditioned_model = model | (@varname(inner.m) => 1.0, );
247247
248248
julia> conditioned_model()
249249
1.0
@@ -255,15 +255,6 @@ julia> conditioned_model_fail()
255255
ERROR: ArgumentError: `~` with a model on the right-hand side of an observe statement is not supported
256256
[...]
257257
```
258-
259-
And similarly when using `Dict`:
260-
261-
```jldoctest condition
262-
julia> conditioned_model_dict = model | (@varname(var"inner.m") => 1.0);
263-
264-
julia> conditioned_model_dict()
265-
1.0
266-
```
267258
"""
268259
function AbstractPPL.condition(model::Model, values...)
269260
# Positional arguments - need to handle cases carefully
@@ -583,7 +574,7 @@ julia> model = demo_outer();
583574
julia> model() ≠ 1.0
584575
true
585576
586-
julia> fixed_model = fix(model, var"inner.m" = 1.0, );
577+
julia> fixed_model = fix(model, (@varname(inner.m) => 1.0, ));
587578
588579
julia> fixed_model()
589580
1.0
@@ -599,24 +590,9 @@ julia> fixed_model()
599590
2.0
600591
```
601592
602-
And similarly when using `Dict`:
603-
604-
```jldoctest fix
605-
julia> fixed_model_dict = fix(model, @varname(var"inner.m") => 1.0);
606-
607-
julia> fixed_model_dict()
608-
1.0
609-
610-
julia> fixed_model_dict = fix(model, @varname(inner) => 2.0);
611-
612-
julia> fixed_model_dict()
613-
2.0
614-
```
615-
616593
## Difference from `condition`
617594
618-
A very similar functionality is also provided by [`condition`](@ref) which,
619-
not surprisingly, _conditions_ variables instead of fixing them. The only
595+
A very similar functionality is also provided by [`condition`](@ref). The only
620596
difference between fixing and conditioning is as follows:
621597
- `condition`ed variables are considered to be observations, and are thus
622598
included in the computation [`logjoint`](@ref) and [`loglikelihood`](@ref),
@@ -798,11 +774,11 @@ julia> fixed(cm)
798774
julia> # Since we fixed on `m`, not `a.m` as it will appear after prefixed,
799775
# `a.m` is treated as a random variable.
800776
keys(VarInfo(cm))
801-
1-element Vector{VarName{Symbol("a.m"), typeof(identity)}}:
777+
1-element Vector{VarName{:a, Accessors.PropertyLens{:m}}}:
802778
a.m
803779
804780
julia> # If we instead fix on `a.m`, `m` in the model will be considered an observation.
805-
cm = fix(contextualize(m, PrefixContext{:a}(fix(var"a.m"=1.0))), x=100.0);
781+
cm = fix(contextualize(m, PrefixContext{:a}(fix(@varname(a.m) => 1.0,))), x=100.0);
806782
807783
julia> fixed(cm).x
808784
100.0

src/submodel_macro.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ julia> vi = VarInfo(demo2(missing, missing, 0.4));
9696
│ caller = ip:0x0
9797
└ @ Core :-1
9898
99-
julia> @varname(var"sub1.x") in keys(vi)
99+
julia> @varname(sub1.x) in keys(vi)
100100
true
101101
102-
julia> @varname(var"sub2.x") in keys(vi)
102+
julia> @varname(sub2.x) in keys(vi)
103103
true
104104
```
105105
@@ -116,9 +116,9 @@ false
116116
We can check that the log joint probability of the model accumulated in `vi` is correct:
117117
118118
```jldoctest submodelprefix
119-
julia> sub1_x = vi[@varname(var"sub1.x")];
119+
julia> sub1_x = vi[@varname(sub1.x)];
120120
121-
julia> sub2_x = vi[@varname(var"sub2.x")];
121+
julia> sub2_x = vi[@varname(sub2.x)];
122122
123123
julia> logprior = logpdf(Normal(), sub1_x) + logpdf(Normal(), sub2_x);
124124
@@ -157,7 +157,7 @@ julia> # Automatically determined from `a`.
157157
@model submodel_prefix_true() = @submodel prefix=true a = inner()
158158
submodel_prefix_true (generic function with 2 methods)
159159
160-
julia> @varname(var"a.x") in keys(VarInfo(submodel_prefix_true()))
160+
julia> @varname(a.x) in keys(VarInfo(submodel_prefix_true()))
161161
┌ Warning: `@submodel model` and `@submodel prefix=... model` are deprecated; see `to_submodel` for the up-to-date syntax.
162162
│ caller = ip:0x0
163163
└ @ Core :-1
@@ -167,7 +167,7 @@ julia> # Using a static string.
167167
@model submodel_prefix_string() = @submodel prefix="my prefix" a = inner()
168168
submodel_prefix_string (generic function with 2 methods)
169169
170-
julia> @varname(var"my prefix.x") in keys(VarInfo(submodel_prefix_string()))
170+
julia> @varname(var"my prefix".x) in keys(VarInfo(submodel_prefix_string()))
171171
┌ Warning: `@submodel model` and `@submodel prefix=... model` are deprecated; see `to_submodel` for the up-to-date syntax.
172172
│ caller = ip:0x0
173173
└ @ Core :-1
@@ -177,7 +177,7 @@ julia> # Using string interpolation.
177177
@model submodel_prefix_interpolation() = @submodel prefix="\$(nameof(inner()))" a = inner()
178178
submodel_prefix_interpolation (generic function with 2 methods)
179179
180-
julia> @varname(var"inner.x") in keys(VarInfo(submodel_prefix_interpolation()))
180+
julia> @varname(inner.x) in keys(VarInfo(submodel_prefix_interpolation()))
181181
┌ Warning: `@submodel model` and `@submodel prefix=... model` are deprecated; see `to_submodel` for the up-to-date syntax.
182182
│ caller = ip:0x0
183183
└ @ Core :-1
@@ -187,7 +187,7 @@ julia> # Or using some arbitrary expression.
187187
@model submodel_prefix_expr() = @submodel prefix=1 + 2 a = inner()
188188
submodel_prefix_expr (generic function with 2 methods)
189189
190-
julia> @varname(var"3.x") in keys(VarInfo(submodel_prefix_expr()))
190+
julia> @varname(var"3".x) in keys(VarInfo(submodel_prefix_expr()))
191191
┌ Warning: `@submodel model` and `@submodel prefix=... model` are deprecated; see `to_submodel` for the up-to-date syntax.
192192
│ caller = ip:0x0
193193
└ @ Core :-1

test/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
3232
[compat]
3333
ADTypes = "1"
3434
AbstractMCMC = "5"
35-
AbstractPPL = "0.10.1"
35+
AbstractPPL = "0.11"
3636
Accessors = "0.1"
3737
Aqua = "0.8"
3838
Bijectors = "0.15.1"

test/compiler.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,8 @@ module Issue537 end
481481
m = demo_useval(missing, missing)
482482
vi = VarInfo(m)
483483
ks = keys(vi)
484-
@test VarName{Symbol("sub1.x")}() ks
485-
@test VarName{Symbol("sub2.x")}() ks
484+
@test @varname(sub1.x) ks
485+
@test @varname(sub2.x) ks
486486
@test @varname(z) ks
487487
@test abs(mean([VarInfo(m)[@varname(z)] for i in 1:10]) - 100) 10
488488

@@ -514,8 +514,9 @@ module Issue537 end
514514
m = demo(ys)
515515
vi = VarInfo(m)
516516

517-
for k in [, , , Symbol("ar1_1.η"), Symbol("ar1_2.η")]
518-
@test VarName{k}() keys(vi)
517+
for vn in
518+
[@varname(α), @varname(μ), @varname(σ), @varname(ar1_1.η), @varname(ar1_2.η)]
519+
@test vn keys(vi)
519520
end
520521
end
521522

test/contexts.jl

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,6 @@ end
3939
Base.IteratorSize(::Type{<:AbstractContext}) = Base.SizeUnknown()
4040
Base.IteratorEltype(::Type{<:AbstractContext}) = Base.EltypeUnknown()
4141

42-
"""
43-
remove_prefix(vn::VarName)
44-
45-
Return `vn` but now with the prefix removed.
46-
"""
47-
function remove_prefix(vn::VarName)
48-
return VarName{Symbol(split(string(vn), string(DynamicPPL.PREFIX_SEPARATOR))[end])}(
49-
getoptic(vn)
50-
)
51-
end
52-
5342
@testset "contexts.jl" begin
5443
child_contexts = [DefaultContext(), PriorContext(), LikelihoodContext()]
5544

test/deprecated.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
@test outer()() isa Tuple{Float64,Float64}
3232
vi = VarInfo(outer())
3333
@test @varname(x) in keys(vi)
34-
@test @varname(var"sub.x") in keys(vi)
34+
@test @varname(sub.x) in keys(vi)
3535
end
3636

3737
@testset "logp is still accumulated properly" begin

0 commit comments

Comments
 (0)