# Conditional Independence

**TLDR**: Use `ciid`

to convert a function `f(ω::) = ...`

into a `RandVar`

. If the function calls other random variables

```

Previously we saw that we could use `ciid`

to turn a function rng into a `RandVar`

. Here we cover the meaning of ciid. Use `ciid(x)`

to create a random variable that is identical in distribution to `x`

but conditionally independent given its parents.

```
μ = uniform(0.0, 1.0)
y1 = normal(μ, 1.0)
y2 =~ y1
rand((y1, y2))
```

`Omega.ciid`

— Function.`ciid(f)`

`RandVar`

that is **c**onditionally **i**ndependent given its parents, but **i**dentically **d**istributed to `f`

`ciid`

is the primary mechanism to construct a `RandVar`

from a function.

```
function x_(ω)
x = normal(ω, 0, 1)
end
x = ciid(x_)
rand(x)
```

**Important:** any parents of `f`

are shared. That is, if `X`

is a `RandVar`

, then `X(ω)`

will return the same value from whatever context it is called.

Example:

```
numflips = poisson(2)
flips_(ω) = [bernoulli(ω, 0.5, Bool) for i = 1:numflips(ω)]
flips = ciid(flips_)
"At least one of numflips is true"
anyheads_(ω) = any(flips(ω))
anyheads = ciid(anyheads_)
"All flips are true"
allheads_(ω) = all(flips(ω))
allheads = ciid(allheads_) # `allheads` and `anyheads` share `flips`
rand((numflips, flips, anyheads, allheads))
```

ciid(x::RandVar)

`RandVar`

identically distributed to `x`

but conditionally independent given parents`

```
ciid(f, args)
```

ciid with arguments

If arguments are random variables they are resolved to values.

Equivalent to:

`ciid(ω -> f(ω, (arg isa RandVar ? arg(ω) : arg for arg in args)...))`

Example:

```
function f_(ω, n)
x = 0.0
for i = 1:n
x += uniform(ω, 0, 1)
end
x
end
f = ciid(f_, poisson(3))
```