zenna / Omega.jl

Causal, Higher-Order, Probabilistic Programming
MIT License
163 stars 17 forks source link

Intervening the result of a higher-order RandVar (for structure learning, etc) #119

Closed zenna closed 3 years ago

zenna commented 5 years ago

There's an opportunity to be able to easily express within Omega problems of structure learning. But there are some snags. For example

x1 = normal(0, 1)
x2 = normal(0, 1)
y = x1 + 10
xs = uniform([x1, x2]) # Random variable of random variables x1 and x2
y_ = replace(y, xs => 100)

we want y_ to be y as if either x1 or x2 were intervened to be 100. This won't work as intended, because xs is random variable with no children and hence intervening on it has no effect. In a sense, rather than xs we want something like the random variable that is returned from xs.

One way to do this is to introduce a new construct. Lacking a good name, let's just call it result and hence y_ = replace(y, result(xs) => 100). replace(y, result(xs) would return some special kind of random variable, and the intervention code would be special cased to it.

I'm a bit averse to adding new constructs but I'm not sure of any other way. It's unclear whether result would have any use outside of this higher-order random variables case. Maybe, rather than have result be an independent construct, we should consider it as a different kind of intervention I'm less averse to a diversity of ways to intervene models than new basic constructs.

jkoppel commented 5 years ago

This is an instance of the general problem of defining an intervention for something other than "set variable to value." It's not simple to define an intervention "Make x an even number," and it's not obvious to me that it's easier to say "Set xs to an array whose first element is 100." It's certainly not easier to say "Set the length of xs to 10."

Reminds me of this: https://en.wikipedia.org/wiki/Two_envelopes_problem#Nalebuff_asymmetric_variant