# Conditional independence statements

Conditional independence (CI) statements over a ground set $N$ are triples of pairwise disjoint subsets $I, J, K \subseteq N$ denoted as $[I \mathrel{⫫} J \mid K]$. The ground set indexes objects under consideration and the CI statement asserts that once the objects in $K$ are "controlled" (conditioned on, in statistical language), the objects in $I$ reveal no information about (are independent of) the objects in $J$.

The functionality documented here deals with CI statements are combinatorial objects. Collections of CI statements are often used to state *Markov properties* of graphical models in statistics and are ultimately used to define ideals. Their interpretations as polynomial equations depend on the ambient ring (`markov_ring`

or `gaussian_ring`

).

`ci_stmt`

— Method`ci_stmt(I::Vector{<:VarName}, J::Vector{<:VarName}, K::Vector{<:VarName}; symmetric=true, semigraphoid=true)`

A conditional independence statement asserting that `I`

is independent of `J`

given `K`

. These parameters are lists of names of random variables. The sets `I`

and `J`

must be disjoint as this package cannot yet deal with functional dependencies.

If `symmetric`

is `true`

, CI statements are assumed to be symmetric in their `I`

and `J`

components. The constructor then reorders the arguments to make the `I`

field lexicographically smaller than the `J`

to ensure that comparisons and hashing respect the symmetry.

If `semigraphoid`

is set to `true`

, the constructor also removes elements in the intersection of `I`

and `K`

from `I`

(and symetrically removes the intersection of `J`

and `K`

from `J`

).

As all three fields are sets, each of them may be deduplicated and sorted to ensure consistent comparison and hashing.

**Examples**

```
julia> ci_stmt(["A"], ["B"], ["X"])
[A _||_ B | X]
julia> ci_stmt(["1"], ["2", "3"], ["4", "5"])
[1 _||_ {2, 3} | {4, 5}]
```

This function is part of the experimental code in Oscar. Please read here for more details.

`@CI_str`

— Macro`CI"I...,J...|K..."`

A literal syntax for denoting CI statements is provided for cases in which all variable names consist of a single character. If `I`

and `J`

only consist of a single element, then even the comma may be omitted. Once the three sets are extracted, `ci_stmt`

is called.

**Examples**

```
julia> CI"AB|X"
[A _||_ B | X]
julia> CI"1,23|5424"
[1 _||_ 3 | {2, 4, 5}]
```

This function is part of the experimental code in Oscar. Please read here for more details.

`==`

— Method`Base.:(==)(lhs::CIStmt, rhs::CIStmt)`

Compares `CIStmt`

s for identity in all their three fields.

This function is part of the experimental code in Oscar. Please read here for more details.

`hash`

— Method`Base.hash(stmt:;CIStmt, h::UInt)`

Computes the hash of a `CIStmt`

.

This function is part of the experimental code in Oscar. Please read here for more details.

`ci_statements`

— Method`ci_statements(random_variables::Vector{<:VarName})`

Return a list of all elementary CI statements over a given set of variable names. A `CIStmt(I, J, K)`

is elementary if both `I`

and `J`

have only one element.

As a consequence of the semigraphoid properties, these statements are enough to describe the entire CI structure of a probability distribution.

**Examples**

```
julia> ci_statements(["A", "B", "X", "Y"])
24-element Vector{CIStmt}:
[A _||_ Y | {}]
[A _||_ Y | B]
[A _||_ Y | X]
[A _||_ Y | {B, X}]
[B _||_ Y | {}]
[B _||_ Y | A]
[B _||_ Y | X]
[B _||_ Y | {A, X}]
[X _||_ Y | {}]
[X _||_ Y | A]
⋮
[A _||_ X | {B, Y}]
[B _||_ X | {}]
[B _||_ X | A]
[B _||_ X | Y]
[B _||_ X | {A, Y}]
[A _||_ B | {}]
[A _||_ B | X]
[A _||_ B | Y]
[A _||_ B | {X, Y}]
```

This function is part of the experimental code in Oscar. Please read here for more details.

`make_elementary`

— Method`make_elementary(stmt::CIStmt; semigaussoid=false)`

Convert a `CIStmt`

into an equivalent list of `CIStmt`

s all of which are elementary. The default operation assumes the semigraphoid axioms and converts $[I \mathrel{⫫} J \mid K]$ into the list consisting of $[i \mathrel{⫫} j \mid L]$ for all $i \in I$, $j \in J$ and $L$ in the interval $K \subseteq L \subseteq (I \cup J \cup K) \setminus \{i,j\}$.

If `semigaussoid`

is true, the stronger semigaussoid axioms are assumed and `L`

in the above procedure does not range in the interval above `K`

but is always fixed to `K`

. Semigaussoids are also known as *compositional graphoids*.

**Examples**

```
julia> make_elementary(CI"12,34|56")
16-element Vector{CIStmt}:
[1 _||_ 3 | {5, 6}]
[1 _||_ 3 | {5, 6, 2}]
[1 _||_ 3 | {5, 6, 4}]
[1 _||_ 3 | {5, 6, 2, 4}]
[1 _||_ 4 | {5, 6}]
[1 _||_ 4 | {5, 6, 2}]
[1 _||_ 4 | {5, 6, 3}]
[1 _||_ 4 | {5, 6, 2, 3}]
[2 _||_ 3 | {5, 6}]
[2 _||_ 3 | {5, 6, 1}]
[2 _||_ 3 | {5, 6, 4}]
[2 _||_ 3 | {5, 6, 1, 4}]
[2 _||_ 4 | {5, 6}]
[2 _||_ 4 | {5, 6, 1}]
[2 _||_ 4 | {5, 6, 3}]
[2 _||_ 4 | {5, 6, 1, 3}]
julia> make_elementary(CI"12,34|56"; semigaussoid=true)
4-element Vector{CIStmt}:
[1 _||_ 3 | {5, 6}]
[1 _||_ 4 | {5, 6}]
[2 _||_ 3 | {5, 6}]
[2 _||_ 4 | {5, 6}]
```

This function is part of the experimental code in Oscar. Please read here for more details.