Frequently Asked Questions -------------------------- Q: What is the story with this `unquote`? If I write:: (assume x (mem (lambda (i) (flip theta_x)))) [define observer (lambda (i xi) (observe (x (unquote i)) xi))] it works, but if I omit the `unquote` I get an error when calling `(observer 1 True)`, giving `VentureException: *** evaluation: Cannot find symbol 'i'` A: This has to do with there being two distinct "contexts" where expressions may be interpreted: the toplevel (inference) language, and the model. You can think of these as being totally separate; they actually have different interpreters. Normally if you just type an expression in, like `(normal 0 1)`, it gets evaluated in the inference language. However, so-called "modeling directives" `assume`, `observe`, etc, operate on the model. The confusing part is that what actually happens when you do `(observe (x i) xi)`, is that the expression `(x i)` is automatically quoted -- that is, treated as an expression that is handed to `observe` (which evaluates it in the model context), rather than evaluated immediately in the inference context. Actually, it's _quasi_quoted, which means that, while it is an expression, you can still get things from the inference language into it by using `unquote`, which you can think of as expression interpolation (sort of like string interpolation). So you have this local variable `i`, which lives in the inference language, and what you want is to construct an expression `(x ${the value of i})` and that is the thing whose result you want to observe. So you use `(unquote i)` to do that. If you instead just did `(x i)`, that would treat `i` as a variable in the model, which would only work if that variable was previously defined in the model (such as by `assume`). If you like, you can sort of think of it as running this on the command line:: python -c "$foo" versus:: python -c "foo" In the first case there is a variable in the outer context that is being spliced into the expression in the inner language; in the second case there is just a symbol, which is interpreted as a variable reference in the inner lnaguage. Q: Why is the `venture` console ignoring the `--abstract-syntax` flag when reading a file written in the abstract syntax? For instance:: $ cat foo.vnts (assume earth_radius 6378) $ venture --abstract-syntax -f foo.vnts Tracing models with the Lite backend Traceback (most recent call last): venture.exception.VentureException: *** text_parse: Syntax error at 'earth_radius' (token 2) (assume earth_radius 6378) ^^^^^^^^^^^^ {'instruction_string': '(assume earth_radius 6378)', 'text_index': [8, 19]} A: The extension in `foo.vnts` tells the console to interpret the program in the concrete syntax, regardless of the `--abstract-syntax` flag. To ensure the program is interpreted in the abstract syntax, use the extension `foo.vnt` instead (without the `s`). Q: What is the difference between `sample` and `predict`? A: Mnemonic: `sample` is `predict` and `forget`. To wit, the `predict` directive evaluates its expression, conditioned on everything else present in the model, *and records it* in the model. The `sample` operation, on the other hand, samples the value of its expression, conditioned on the current state of the model, *and leaves the model unchanged*. This causes several differences: 1) Every call to the same `sample` is independent and identically distributed (conditioned on the state of the model), whereas successive calls to `predict` may influence each other, if exchangeably coupled SPs are involved. 2) Repeated `predict` will consume increasing amounts of memory tracing the predictions, whereas repeated `sample` will leave total memory use unchanged. 3) A `predict` creates a numbered (and optionally labeled) directive, which can later be inspected with `report`, `list_directives`, etc. 4) The `predict` ed expression will affect future inference: any random choices therein are subject to inference themselves, and may act as (soft) contraints on their parent choices. In the case of `default_markov_chain`, an unintentional `predict` may therefore increase rejection rates and slow convergence. Q: Why is it that `sample` ignores `mem`, except when it doesn't? For instance, what's with this:: venture[script] > assume x = mem(proc (i) { normal(0, 1) }) [] venture[script] > sample x(1) -0.249548049964 venture[script] > sample x(1) -0.277036540423 venture[script] > sample x(1) -0.357347313623 venture[script] > assume v = x(1) -0.554297447992 venture[script] > sample x(1) -0.554297447992 venture[script] > sample x(1) -0.554297447992 venture[script] > sample x(1) -0.554297447992 A: Applications of `sample` do not modify the model, and are independent and identically distributed conditioned on the current state of the model. The stochastic procedures created by `mem` are (very strongly!) exchangeably coupled across applications---even a single traced application suffices to constrain future samples. In detail: After the first `assume` in that transcript, there are no applications `x(1)` recorded in the model, so `sample x(1)` draws a new value for it. The second `sample x(1)` is different because the first `sample x(1)` does not record its application in the model trace---they are IID. After `assume v = x(1)`, however, there *is* an appliation `x(1)` in the model trace that the subsequent `sample x(1)` evaluations are conditioned on. So they return the same value every time.