Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ Handwritten evaluators must prepare argument bindings: direct argument use → r

Debug introspection may return a body callable distinct from `model.f`: assuming `gen_evaluator_call_with_types(m)[1] === m.f` → use the returned callable and argument types. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501).

`PrefixContext` is removed: context-based prefixing → `prefix(model, vn; template)`. See [#1502](https://github.com/TuringLang/DynamicPPL.jl/pull/1502), [#1221](https://github.com/TuringLang/DynamicPPL.jl/issues/1221).

`extract_prefixes` is removed: `extract_prefixes(model.context)` → `DynamicPPL.getprefix(model)`, returning the combined prefix or `nothing`. See [#1502](https://github.com/TuringLang/DynamicPPL.jl/pull/1502).

Context-based address prefixing is removed: `prefix(ctx, vn)` → `AbstractPPL.prefix(vn, DynamicPPL.getprefix(model))` for prefixed models. See [#1502](https://github.com/TuringLang/DynamicPPL.jl/pull/1502).

Bindings outside a model’s prefix now throw: `condition(prefix(m, :p); y=v)` → `condition(prefix(m, :p), @varname(p.y) => v)`. See [#1502](https://github.com/TuringLang/DynamicPPL.jl/pull/1502).

`@vnt` is no longer exported: `@vnt` → `DynamicPPL.@vnt` or explicitly import it. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501).

`CondFixContext` is removed: context-stored observations/fixed bindings → `condition(model, values)`/`fix(model, values)`. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501).
Expand All @@ -156,7 +164,7 @@ Context binding accessors are removed: `conditioned(context)`/`fixed(context)`

Context observation hooks are removed: `tilde_observe!!(::AbstractContext, ...)` overloads → `accumulate_observe!!` implementations. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501).

Observation calls change: `tilde_observe!!(ctx, dist, value, vn, template, vi)` → `tilde_observe!!(prefix, prefix_template, dist, value, vn, template, vi)`. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501).
Observation calls take the model's prefix instead of a context: `tilde_observe!!(ctx, dist, value, vn, template, vi)` → `tilde_observe!!(prefix, dist, value, vn, template, vi)`. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501), [#1502](https://github.com/TuringLang/DynamicPPL.jl/pull/1502).

Submodel latent calls require the parent model: `tilde_assume!!(ctx, submodel, vn, template, vi)` → `tilde_assume!!(parent, ctx, submodel, vn, template, vi)`. See [#1501](https://github.com/TuringLang/DynamicPPL.jl/pull/1501).

Expand Down
10 changes: 2 additions & 8 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,15 +498,15 @@ InitContext

Customise latent value selection with an [initialisation strategy](init.md) supplied to `InitContext`.
`tilde_assume!!` dispatches on that context to initialise, transform, and accumulate a latent value.
Every observation calls `tilde_observe!!(prefix, prefix_template, right, left, vn, template, vi)`, which applies the prefix metadata and calls `accumulate_observe!!` without dispatching on a context.
Every observation calls `tilde_observe!!(prefix, right, left, vn, template, vi)`, which applies the prefix metadata and calls `accumulate_observe!!` without dispatching on a context.

```@docs
tilde_assume!!
tilde_observe!!
```

**Parent contexts**: These essentially act as 'modifiers' for leaf contexts.
`PrefixContext` supplies address metadata. Conditioned and fixed values are stored on the model.
Prefixes, conditioned values, and fixed values are stored on the model.

To implement a parent context, you have to subtype `DynamicPPL.AbstractParentContext`, and implement the `childcontext` and `setchildcontext` methods.
If needed, you can also implement `tilde_assume!!` for your context.
Expand All @@ -526,12 +526,6 @@ leafcontext
setleafcontext
```

Sometimes it is necessary to handle all `PrefixContext`s in a context stack at one go:

```@docs
extract_prefixes
```

### VarInfo initialisation

The function `init!!` is used to initialise, or overwrite, values in a VarInfo.
Expand Down
3 changes: 3 additions & 0 deletions docs/src/conditionfix.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ and complete local LHS variables retain integer indices. A **submodel namespace*
child LHS variables through addresses such as `a.x`, or through unchanged names with
`auto_prefix=false` unless manually prefixed.

Bindings on prefixed models use absolute addresses: for `prefix(m, @varname(p))`,
use `@varname(p.y) => 0.0`; binding `y=0.0` throws `ArgumentError`.

For example, if `a` is an argument, `a ~ to_submodel(child())`,
`a[1] ~ to_submodel(child())` and `a.x ~ to_submodel(child())` are rejected by the
**Submodel LHS and prefixes** rule. Use a new local name and condition the child's LHS
Expand Down
13 changes: 12 additions & 1 deletion docs/src/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ or `VectorValueAccumulator` when those outputs are needed, for example
`VarInfo(VectorValueAccumulator(), DynamicPPL.default_accumulators()...)`; `VarInfo(model)` remains
a convenience constructor that records vectorised values and log densities.

`PrefixContext` and `extract_prefixes` are removed. Use `prefix(model, vn; template)`
to set a prefix and `DynamicPPL.getprefix(model)` to read the combined prefix
(`nothing` when absent). The `prefix` field stores internal metadata for LHS variable
addresses and nested submodel namespace storage templates. Replace `prefix(ctx, vn)` with
`AbstractPPL.prefix(vn, DynamicPPL.getprefix(model))` for a prefixed model.

Bindings outside a model's prefix now throw. Replace
`condition(prefix(m, @varname(p)); y=v)` with
`condition(prefix(m, @varname(p)), @varname(p.y) => v)`.

To reuse previous values, extract them explicitly before evaluating:

```julia
Expand Down Expand Up @@ -346,7 +356,8 @@ before replaying them.

Replace context overloads of `tilde_observe!!` with `accumulate_observe!!` implementations.
For direct observation calls, replace `tilde_observe!!(ctx, dist, value, vn, template, vi)`
with the current signature `tilde_observe!!(prefix, prefix_template, dist, value, vn, template, vi)`.
with `tilde_observe!!(prefix, dist, value, vn, template, vi)`, where `prefix` is the model's
prefix value (`nothing`, a `VarName`, or a `PrefixTemplate`).
For submodel latent calls, replace `tilde_assume!!(ctx, submodel, vn, template, vi)` with
`tilde_assume!!(parent, ctx, submodel, vn, template, vi)`.
Replace `store_coloneq_value!!(ctx, vn, value, template, vi)` with
Expand Down
7 changes: 4 additions & 3 deletions docs/src/tilde.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ begin
# Conceptual branch: the compiler knows whether x is an argument.
conditioned_x = is_argument(x) ? x : get_conditioned_value(__model__, vn)
raw_x, __varinfo__ = tilde_observe!!(
__prefix__, __prefix_template__, dist, conditioned_x, vn, template, __varinfo__
__prefix__, dist, conditioned_x, vn, template, __varinfo__
)

else
Expand All @@ -46,8 +46,9 @@ begin
end
```

Here, `__prefix__` and `__prefix_template__` are the model's prefix and its storage
template, passed directly to the exported `tilde_observe!!` entry point.
Here, `__prefix__` is the model's single prefix value (`__model__.prefix`): `nothing`,
a `VarName`, or a `PrefixTemplate` containing storage metadata. It is passed directly
to the exported `tilde_observe!!` entry point.

We won't go into detail about every part of this code; by far the most interesting part is the call to `tilde_assume!!`.
Every latent tilde-statement `vn ~ dist` is transformed into one such call.
Expand Down
1 change: 1 addition & 0 deletions docs/src/to_distribution_and_to_submodel.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ initializer in unconstrained space.
to_distribution
to_submodel
DynamicPPL.prefix
DynamicPPL.getprefix
```
5 changes: 3 additions & 2 deletions ext/DynamicPPLInputProvenanceExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ function check_input_provenance(rng, model, params)
model.f,
args,
defaults,
model.context,
values;
model.prefix,
values,
model.context;
args_on_lhs=DynamicPPL._args_on_lhs(model),
)
vi = DynamicPPL.VarInfo((InputProvenanceAccumulator(),))
Expand Down
4 changes: 2 additions & 2 deletions src/DynamicPPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ export AbstractVarInfo,
setchildcontext,
leafcontext,
setleafcontext,
extract_prefixes,
# Tilde pipeline
tilde_assume!!,
tilde_observe!!,
Expand Down Expand Up @@ -226,6 +225,8 @@ export AbstractVarInfo,
generated_quantities,
typed_identity

@compat public getprefix

# Reexport
using Distributions: loglikelihood
export loglikelihood
Expand Down Expand Up @@ -264,7 +265,6 @@ include("transformed_values.jl")
include("contexts.jl")
include("contexts/default.jl")
include("contexts/init.jl")
include("contexts/prefix.jl")
include("model.jl")
include("conditionfix.jl")
@compat public Recursive
Expand Down
14 changes: 6 additions & 8 deletions src/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,7 @@ function generate_tilde_literal(left, right)
@gensym value
return quote
$value, __varinfo__ = $(DynamicPPL.tilde_observe!!)(
$(DynamicPPL._model_prefix)(__model__),
$(DynamicPPL._model_prefix_template)(__model__),
__model__.prefix,
$(DynamicPPL.check_tilde_rhs)($right),
$left,
nothing,
Expand Down Expand Up @@ -530,7 +529,7 @@ function generate_tilde(left, right; is_argument=false)
if $role isa $(DynamicPPL.Fix)
$value = $(DynamicPPL._check_tilde_value)(
$fixed_data,
$(DynamicPPL.maybe_prefix)($vn, $(DynamicPPL._model_prefix)(__model__)),
$(DynamicPPL.maybe_prefix)($vn, $(DynamicPPL.getprefix)(__model__)),
$role,
)
$(assign_or_set!!(left, value, vn, is_argument ? _set_fixed_lhs : _set_lhs))
Expand Down Expand Up @@ -558,8 +557,7 @@ function generate_tilde(left, right; is_argument=false)
)

$value, __varinfo__ = $(DynamicPPL.tilde_observe!!)(
$(DynamicPPL._model_prefix)(__model__),
$(DynamicPPL._model_prefix_template)(__model__),
__model__.prefix,
$(DynamicPPL.check_tilde_rhs)($dist),
$supplied_val,
$vn,
Expand Down Expand Up @@ -603,7 +601,7 @@ function generate_input_provenance_check(left::Union{Expr,Symbol}, vn)
__varinfo__ = $(DynamicPPL.check_input_provenance!!)(
__varinfo__,
$value,
$(DynamicPPL.maybe_prefix)($vn, $(DynamicPPL._model_prefix)(__model__)),
$(DynamicPPL.maybe_prefix)($vn, $(DynamicPPL.getprefix)(__model__)),
)
end
end
Expand Down Expand Up @@ -768,7 +766,7 @@ function build_output(
# See the docstrings of `replace_returns` for more info.
evaluatordef[:body] = MacroTools.@q begin
$(linenumbernode)
__context__ = first($(DynamicPPL.extract_prefixes)(__model__.context))
__context__ = __model__.context
$(replace_returns(add_return_to_last_statment(modeldef[:body])))
end

Expand Down Expand Up @@ -938,7 +936,7 @@ end

function prepare_model_argument(model::Model, vn::VarName, value)
binding = _get_model_binding(model, vn)
return _model_argument_value(binding, value, maybe_prefix(vn, _model_prefix(model)))
return _model_argument_value(binding, value, maybe_prefix(vn, getprefix(model)))
end
function prepare_model_argument(binding, value)
return _model_argument_value(binding, value)
Expand Down
Loading
Loading