@@ -230,8 +230,9 @@ julia> @model demo_inner() = m ~ Normal()
230
230
demo_inner (generic function with 2 methods)
231
231
232
232
julia> @model function demo_outer()
233
- m ~ to_submodel(demo_inner())
234
- return m
233
+ # By default, `to_submodel` prefixes the variables using the left-hand side of `~`.
234
+ inner ~ to_submodel(demo_inner())
235
+ return inner
235
236
end
236
237
demo_outer (generic function with 2 methods)
237
238
@@ -240,63 +241,28 @@ julia> model = demo_outer();
240
241
julia> model() ≠ 1.0
241
242
true
242
243
243
- julia> conditioned_model = model | (m = 1.0, );
244
+ julia> # To condition the variable inside `demo_inner` we need to refer to it as `inner.m`.
245
+ conditioned_model = model | (var"inner.m" = 1.0, );
244
246
245
247
julia> conditioned_model()
246
248
1.0
247
- ```
248
-
249
- But one needs to be careful when prefixing variables in the nested models:
250
-
251
- ```jldoctest condition
252
- julia> @model function demo_outer_prefix()
253
- m ~ to_submodel(prefix(demo_inner(), "inner"), false)
254
- return m
255
- end
256
- demo_outer_prefix (generic function with 2 methods)
257
-
258
- julia> # (×) This doesn't work now!
259
- conditioned_model = demo_outer_prefix() | (m = 1.0, );
260
-
261
- julia> conditioned_model() == 1.0
262
- false
263
249
264
- julia> # (✓) `m` in `demo_inner` is referred to as `inner.m` internally, so we do:
265
- conditioned_model = demo_outer_prefix() | (var" inner.m" = 1.0, );
250
+ julia> # However, it's not possible to condition `inner` directly.
251
+ conditioned_model_fail = model | (inner = 1.0, );
266
252
267
- julia> conditioned_model()
268
- 1.0
269
-
270
- julia> # Note that the above `var"..."` is just standard Julia syntax:
271
- keys((var"inner.m" = 1.0, ))
272
- (Symbol("inner.m"),)
253
+ julia> conditioned_model_fail()
254
+ ERROR: ArgumentError: `~` with a model on the right-hand side of an observe statement is not supported
255
+ [...]
273
256
```
274
257
275
258
And similarly when using `Dict`:
276
259
277
260
```jldoctest condition
278
- julia> conditioned_model_dict = demo_outer_prefix() | (@varname(var"inner.m") => 1.0);
261
+ julia> conditioned_model_dict = model | (@varname(var"inner.m") => 1.0);
279
262
280
263
julia> conditioned_model_dict()
281
264
1.0
282
265
```
283
-
284
- The difference is maybe more obvious once we look at how these different
285
- in their trace/`VarInfo`:
286
-
287
- ```jldoctest condition
288
- julia> keys(VarInfo(demo_outer()))
289
- 1-element Vector{VarName{:m, typeof(identity)}}:
290
- m
291
-
292
- julia> keys(VarInfo(demo_outer_prefix()))
293
- 1-element Vector{VarName{Symbol("inner.m"), typeof(identity)}}:
294
- inner.m
295
- ```
296
-
297
- From this we can tell what the correct way to condition `m` within `demo_inner`
298
- is in the two different models.
299
-
300
266
"""
301
267
AbstractPPL. condition (model:: Model ; values... ) = condition (model, NamedTuple (values))
302
268
function AbstractPPL. condition (model:: Model , value, values... )
@@ -578,15 +544,15 @@ true
578
544
## Nested models
579
545
580
546
`fix` of course also supports the use of nested models through
581
- the use of [`to_submodel`](@ref).
547
+ the use of [`to_submodel`](@ref), similar to [`condition`](@ref) .
582
548
583
549
```jldoctest fix
584
550
julia> @model demo_inner() = m ~ Normal()
585
551
demo_inner (generic function with 2 methods)
586
552
587
553
julia> @model function demo_outer()
588
- m ~ to_submodel(demo_inner())
589
- return m
554
+ inner ~ to_submodel(demo_inner())
555
+ return inner
590
556
end
591
557
demo_outer (generic function with 2 methods)
592
558
@@ -595,63 +561,36 @@ julia> model = demo_outer();
595
561
julia> model() ≠ 1.0
596
562
true
597
563
598
- julia> fixed_model = model | (m = 1.0, );
564
+ julia> fixed_model = fix( model, var"inner.m" = 1.0, );
599
565
600
566
julia> fixed_model()
601
567
1.0
602
568
```
603
569
604
- But one needs to be careful when prefixing variables in the nested models:
605
-
606
- ```jldoctest fix
607
- julia> @model function demo_outer_prefix()
608
- m ~ to_submodel(prefix(demo_inner(), "inner"), false)
609
- return m
610
- end
611
- demo_outer_prefix (generic function with 2 methods)
570
+ However, unlike [`condition`](@ref), `fix` can also be used to fix the
571
+ return-value of the submodel:
612
572
613
- julia> # (×) This doesn't work now!
614
- fixed_model = demo_outer_prefix() | (m = 1.0, );
615
-
616
- julia> fixed_model() == 1.0
617
- false
618
-
619
- julia> # (✓) `m` in `demo_inner` is referred to as `inner.m` internally, so we do:
620
- fixed_model = demo_outer_prefix() | (var"inner.m" = 1.0, );
573
+ ```julia
574
+ julia> fixed_model = fix(model, inner = 2.0,);
621
575
622
576
julia> fixed_model()
623
- 1.0
624
-
625
- julia> # Note that the above `var"..."` is just standard Julia syntax:
626
- keys((var"inner.m" = 1.0, ))
627
- (Symbol("inner.m"),)
577
+ 2.0
628
578
```
629
579
630
580
And similarly when using `Dict`:
631
581
632
582
```jldoctest fix
633
- julia> fixed_model_dict = demo_outer_prefix() | ( @varname(var"inner.m") => 1.0);
583
+ julia> fixed_model_dict = fix(model, @varname(var"inner.m") => 1.0);
634
584
635
585
julia> fixed_model_dict()
636
586
1.0
637
- ```
638
587
639
- The difference is maybe more obvious once we look at how these different
640
- in their trace/`VarInfo`:
588
+ julia> fixed_model_dict = fix(model, @varname(inner) => 2.0);
641
589
642
- ```jldoctest fix
643
- julia> keys(VarInfo(demo_outer()))
644
- 1-element Vector{VarName{:m, typeof(identity)}}:
645
- m
646
-
647
- julia> keys(VarInfo(demo_outer_prefix()))
648
- 1-element Vector{VarName{Symbol("inner.m"), typeof(identity)}}:
649
- inner.m
590
+ julia> fixed_model_dict()
591
+ 2.0
650
592
```
651
593
652
- From this we can tell what the correct way to fix `m` within `demo_inner`
653
- is in the two different models.
654
-
655
594
## Difference from `condition`
656
595
657
596
A very similar functionality is also provided by [`condition`](@ref) which,
0 commit comments