probcomp / Venturecxx

Primary implementation of the Venture probabilistic programming system
http://probcomp.csail.mit.edu/venture/
GNU General Public License v3.0
28 stars 6 forks source link

Option: Define destructuring observe #231

Open lenaqr opened 8 years ago

lenaqr commented 8 years ago

@axch:

In principle, however, it should be feasible to add a destructuring observe to Venture that observes a list of refs in one statement

This would be analogous to #220, but for observe:

[observe (list (ref foo) (ref bar) (ref baz)) (list quux quaggle frotz)]

which should expand to something like

[assume %%name%% (list (ref foo) (ref bar) (ref baz))]
[observe (deref (lookup %%name%% 0)) quux]
[observe (deref (lookup %%name%% 1)) quaggle]
[observe (deref (lookup %%name%% 2)) frotz]
lenaqr commented 8 years ago

There's actually an additional obstacle to this, which is that a toplevel observe requires its value to be a literal, so you would have to somehow provide a list literal on the right hand side. Fixing that is #74.

riastradh-probcomp commented 8 years ago

How do you distinguish that syntactically from a single-value observe?

lenaqr commented 8 years ago

Right, so one version of this would be that the right hand side has to be a syntactically-fixed list of values, so that it can statically expand it as described. Another option, which is not quite "destructuring", would be a runtime behavior that says that if the right hand side evaluates to a list, then it has the effect of constraining a deference + lookup for each element of the list. Not sure which was intended.

axch commented 8 years ago

Actually, there are two different behaviors, which are reasonable to distinguish, e.g. by the name.

(observe expr1 expr2)

evaluates expr1 in the model and requires it to be a constrainable random variable; evaluates expr2 in the inference program, and constrains the former to be the latter, regardless of whether any lists are involved or not. Typical expr1's that return lists are not constrainable, so this does not occur in our corpus.

(observe-by-reference expr1 expr2)

would evaluate expr1 in the model and require it to be a list (actually, I suppose any Foldable would be fine) of refs whose derefs are required to be constrainable random variables; evaluate expr2 in the inference program; and do sequence $ zipWith constrain $ (toList v1) (toList v2), i.e. traverse them in lock step constraining corresponding elements. There is a choice of how much to require the structures to match (vectors vs lists, length agreement).

vkmvkmvkmvkm commented 8 years ago

++axch

Two questions:

Vikash ᐧ

On Mon, Dec 28, 2015 at 10:54 PM, axch notifications@github.com wrote:

Actually, there are two different behaviors, which are reasonable to distinguish, e.g. by the name.

(observe expr1 expr2)

evaluates expr1 in the model and requires it to be a constrainable random variable; evaluates expr2 in the inference program, and constrains the former to be the latter, regardless of whether any lists are involved or not. Typical expr1's that return lists are not constrainable, so this does not occur in our corpus.

(observe-by-reference expr1 expr2)

would evaluate expr1 in the model and require it to be a list (actually, I suppose any Foldable would be fine) of refs whose derefs are required to be constrainable random variables; evaluate expr2 in the inference program; and do sequence $ zipWith constrain $ (toList v1) (toList v2), i.e. traverse them in lock step constraining corresponding elements. There is a choice of how much to require the structures to match (vectors vs lists, length agreement).

— Reply to this email directly or view it on GitHub https://github.com/probcomp/Venturecxx/issues/231#issuecomment-167714093 .

lenaqr commented 8 years ago

I'm not sure we want to be in a regime where lists vs arrays matters a lot in the first place. What seems most important to me is being able to resample the elements without reconstructing the whole datastructure, and list-of-refs already does that.

++ dicts though, because it seems convenient to be able to group several random variables together in a named fashion.

vkmvkmvkmvkm commented 8 years ago

We need to give predictable astmptotics (and, relative to platform-general overhead, tolerable constants) for collections, and avoid the hidden quadratics from lists/alists/etc.

If we have only 1 collection type that we bother to make fast (and alias others to it) I think it should be the dictionary. When used with dense sets of integer keys (and possibly initialized with tuning params) it can act like a vector, so we haven't lost anything.

On Sun, Jan 3, 2016, 4:32 PM Anthony Lu notifications@github.com wrote:

I'm not sure we want to be in a regime where lists vs arrays matters a lot in the first place. What seems most important to me is being able to resample the elements without reconstructing the whole datastructure, and list-of-refs already does that.

++ dicts though, because it seems convenient to be able to group several random variables together in a named fashion.

— Reply to this email directly or view it on GitHub https://github.com/probcomp/Venturecxx/issues/231#issuecomment-168542351 .

axch commented 8 years ago

Let's not forget about the hidden quadratics involved in building up an array non-destructively one element at a time, and, of course, all the problems of destructive modifications of mutable data structures.

In any case, whatever we do for observe-by-reference now will be smoothly generalizable to consume all foldable structures, so we are not making a binding commitment. I suggest migrating the discussion of what the smoothly-integrated default data structure should be to a separate ticket.