|  | 
|  | 1 | +""" | 
|  | 2 | +Note that `test/submodel.jl` also contains a number of tests which make use of | 
|  | 3 | +prefixing functionality (more like end-to-end tests). This file contains what | 
|  | 4 | +are essentially unit tests for prefixing functions. | 
|  | 5 | +""" | 
|  | 6 | +module DPPLPrefixTests | 
|  | 7 | + | 
|  | 8 | +using DynamicPPL | 
|  | 9 | +# not exported | 
|  | 10 | +using DynamicPPL: FixedContext, prefix_cond_and_fixed_variables, childcontext | 
|  | 11 | +using Distributions | 
|  | 12 | +using Test | 
|  | 13 | + | 
|  | 14 | +@testset "prefix.jl" begin | 
|  | 15 | +    @testset "prefix_cond_and_fixed_variables" begin | 
|  | 16 | +        @testset "ConditionContext" begin | 
|  | 17 | +            c1 = ConditionContext((c=1, d=2)) | 
|  | 18 | +            c1_prefixed = prefix_cond_and_fixed_variables(c1, @varname(a)) | 
|  | 19 | +            @test c1_prefixed isa ConditionContext | 
|  | 20 | +            @test childcontext(c1_prefixed) isa DefaultContext | 
|  | 21 | +            @test length(c1_prefixed.values) == 2 | 
|  | 22 | +            @test c1_prefixed.values[@varname(a.c)] == 1 | 
|  | 23 | +            @test c1_prefixed.values[@varname(a.d)] == 2 | 
|  | 24 | +        end | 
|  | 25 | + | 
|  | 26 | +        @testset "FixedContext" begin | 
|  | 27 | +            c2 = FixedContext((f=1, g=2)) | 
|  | 28 | +            c2_prefixed = prefix_cond_and_fixed_variables(c2, @varname(a)) | 
|  | 29 | +            @test c2_prefixed isa FixedContext | 
|  | 30 | +            @test childcontext(c2_prefixed) isa DefaultContext | 
|  | 31 | +            @test length(c2_prefixed.values) == 2 | 
|  | 32 | +            @test c2_prefixed.values[@varname(a.f)] == 1 | 
|  | 33 | +            @test c2_prefixed.values[@varname(a.g)] == 2 | 
|  | 34 | +        end | 
|  | 35 | + | 
|  | 36 | +        @testset "Nested ConditionContext and FixedContext" begin | 
|  | 37 | +            c3 = ConditionContext((c=1, d=2), FixedContext((f=1, g=2))) | 
|  | 38 | +            c3_prefixed = prefix_cond_and_fixed_variables(c3, @varname(a)) | 
|  | 39 | +            c3_prefixed_child = childcontext(c3_prefixed) | 
|  | 40 | +            @test c3_prefixed isa ConditionContext | 
|  | 41 | +            @test length(c3_prefixed.values) == 2 | 
|  | 42 | +            @test c3_prefixed.values[@varname(a.c)] == 1 | 
|  | 43 | +            @test c3_prefixed.values[@varname(a.d)] == 2 | 
|  | 44 | +            @test c3_prefixed_child isa FixedContext | 
|  | 45 | +            @test length(c3_prefixed_child.values) == 2 | 
|  | 46 | +            @test c3_prefixed_child.values[@varname(a.f)] == 1 | 
|  | 47 | +            @test c3_prefixed_child.values[@varname(a.g)] == 2 | 
|  | 48 | +            @test childcontext(c3_prefixed_child) isa DefaultContext | 
|  | 49 | +        end | 
|  | 50 | +    end | 
|  | 51 | + | 
|  | 52 | +    @testset "DynamicPPL.prefix(::Model, x)" begin | 
|  | 53 | +        @model function demo() | 
|  | 54 | +            x ~ Normal() | 
|  | 55 | +            return y ~ Normal() | 
|  | 56 | +        end | 
|  | 57 | +        model = demo() | 
|  | 58 | + | 
|  | 59 | +        @testset "No conditioning / fixing" begin | 
|  | 60 | +            pmodel = DynamicPPL.prefix(model, @varname(a)) | 
|  | 61 | +            @test pmodel.prefix == @varname(a) | 
|  | 62 | +            vi = VarInfo(pmodel) | 
|  | 63 | +            @test Set(keys(vi)) == Set([@varname(a.x), @varname(a.y)]) | 
|  | 64 | +        end | 
|  | 65 | + | 
|  | 66 | +        @testset "Prefixing a conditioned model" begin | 
|  | 67 | +            cmodel = model | (; x=1.0) | 
|  | 68 | +            # Sanity check. | 
|  | 69 | +            vi = VarInfo(cmodel) | 
|  | 70 | +            @test Set(keys(vi)) == Set([@varname(y)]) | 
|  | 71 | +            # Now prefix. | 
|  | 72 | +            pcmodel = DynamicPPL.prefix(cmodel, @varname(a)) | 
|  | 73 | +            @test pcmodel.prefix == @varname(a) | 
|  | 74 | +            # Because the model was conditioned on `x` _prior_ to prefixing, | 
|  | 75 | +            # the resulting `a.x` variable should also be conditioned. In | 
|  | 76 | +            # other words, which variables are treated as conditioned should be | 
|  | 77 | +            # invariant to prefixing. | 
|  | 78 | +            vi = VarInfo(pcmodel) | 
|  | 79 | +            @test Set(keys(vi)) == Set([@varname(a.y)]) | 
|  | 80 | +        end | 
|  | 81 | + | 
|  | 82 | +        @testset "Prefixing a fixed model" begin | 
|  | 83 | +            # Same as above but for FixedContext rather than Condition. | 
|  | 84 | +            fmodel = fix(model, (; y=1.0)) | 
|  | 85 | +            # Sanity check. | 
|  | 86 | +            vi = VarInfo(fmodel) | 
|  | 87 | +            @test Set(keys(vi)) == Set([@varname(x)]) | 
|  | 88 | +            # Now prefix. | 
|  | 89 | +            pfmodel = DynamicPPL.prefix(fmodel, @varname(a)) | 
|  | 90 | +            @test pfmodel.prefix == @varname(a) | 
|  | 91 | +            # Because the model was conditioned on `x` _prior_ to prefixing, | 
|  | 92 | +            # the resulting `a.x` variable should also be conditioned. In | 
|  | 93 | +            # other words, which variables are treated as conditioned should be | 
|  | 94 | +            # invariant to prefixing. | 
|  | 95 | +            vi = VarInfo(pfmodel) | 
|  | 96 | +            @test Set(keys(vi)) == Set([@varname(a.x)]) | 
|  | 97 | +        end | 
|  | 98 | + | 
|  | 99 | +        @testset "Conditioning a prefixed model" begin | 
|  | 100 | +            # If the prefixing happens first, then we want to make sure that the | 
|  | 101 | +            # user is forced to apply conditioning WITH the prefix. | 
|  | 102 | +            pmodel = DynamicPPL.prefix(model, @varname(a)) | 
|  | 103 | + | 
|  | 104 | +            # If this doesn't happen... | 
|  | 105 | +            cpmodel_wrong = pmodel | (; x=1.0) | 
|  | 106 | +            @test cpmodel_wrong.prefix == @varname(a) | 
|  | 107 | +            vi = VarInfo(cpmodel_wrong) | 
|  | 108 | +            # Then `a.x` will be `assume`d | 
|  | 109 | +            @test Set(keys(vi)) == Set([@varname(a.x), @varname(a.y)]) | 
|  | 110 | + | 
|  | 111 | +            # If it does... | 
|  | 112 | +            cpmodel_right = pmodel | (@varname(a.x) => 1.0) | 
|  | 113 | +            @test cpmodel_right.prefix == @varname(a) | 
|  | 114 | +            vi = VarInfo(cpmodel_right) | 
|  | 115 | +            # Then `a.x` will be `observe`d | 
|  | 116 | +            @test Set(keys(vi)) == Set([@varname(a.y)]) | 
|  | 117 | +        end | 
|  | 118 | +    end | 
|  | 119 | +end | 
|  | 120 | + | 
|  | 121 | +end | 
0 commit comments