Skip to content

Commit 49f01e4

Browse files
authored
Merge pull request #241 from ReactiveBayes/dev-stack-constraints
Do not use the plus for stacked constraints
2 parents b3ae2a6 + 423b2f4 commit 49f01e4

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

docs/src/plugins/constraint_specification.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@ We can specify constraints over the first `toy_model` submodel using the followi
6969
end
7070
```
7171

72+
## Stacked functional form constraints
73+
In the constraints macro, we can specify multiple functional form constraints over the same variable. For example, suppose we have the following model:
74+
```@example constraints
75+
@constraints begin
76+
q(x) :: Normal :: Beta
77+
end
78+
```
79+
In this constraint the posterior over `x` will first be constrained to be a normal distribution, and then the result with be constrained to be a beta distribution.
80+
This might be useful to create a chain of constraints that are applied in order. The resulting constraint is a tuple of constraints.
81+
82+
!!! note
83+
The inference backend must support stacked constraints for this feature to work. Some combinations of stacked constraints might not be supported or theoretically sound.
84+
7285
## Default constraints
7386
While we can specify constraints over all instances of a submodel at a specific layer of the hierarchy, we're not guaranteed to have all instances of a submodel at a specific layer of the hierarchy. To this extent, we can specify default constraints that apply to all instances of a specific submodel. For example, we can define the following model, where we have a `recursive_model` instance at every layer of the hierarchy:
7487
```@example constraints

src/plugins/variational_constraints/variational_constraints_macro.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,14 @@ function create_submodel_constraints(e::Expr)
6666
end
6767
end
6868

69+
stack_constraints(a, b) = (a, b)
70+
stack_constraints(a, b::Tuple) = (a, b...)
71+
stack_constraints(a::Tuple, b) = (a..., b)
72+
stack_constraints(a::Tuple, b::Tuple) = (a..., b...)
73+
6974
function rewrite_stacked_constraints(e::Expr)
7075
if @capture(e, (a_::b_::c_))
71-
return :($a::($b + $c))
76+
return :($a::(GraphPPL.stack_constraints($b, $c)))
7277
else
7378
return e
7479
end

test/plugins/variational_constraints/variational_constraints_macro_tests.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ end
170170
end
171171
output = quote
172172
q(x, y) = q(x)q(y)
173-
q(x)::(PointMass() + SampleList())
173+
q(x)::GraphPPL.stack_constraints(PointMass(), SampleList())
174174
end
175175
@test_expression_generating apply_pipeline(input, rewrite_stacked_constraints) output
176176

@@ -181,11 +181,20 @@ end
181181
end
182182
output = quote
183183
q(x, y) = q(x)q(y)
184-
q(x)::((PointMass() + Sample) + SampleList())
184+
q(x)::GraphPPL.stack_constraints(GraphPPL.stack_constraints(PointMass(), Sample), SampleList())
185185
end
186186
@test_expression_generating apply_pipeline(input, rewrite_stacked_constraints) output
187187
end
188188

189+
@testitem "stack_constraints" begin
190+
import GraphPPL: stack_constraints
191+
192+
@test stack_constraints(1, 2) == (1, 2)
193+
@test stack_constraints(1, (2, 1)) == (1, 2, 1)
194+
@test stack_constraints((1, 2), 3) == (1, 2, 3)
195+
@test stack_constraints((1, 3), (2, 1)) == (1, 3, 2, 1)
196+
end
197+
189198
@testitem "replace_begin_end" begin
190199
import GraphPPL: replace_begin_end, apply_pipeline
191200

0 commit comments

Comments
 (0)