# Delay

abstract class Delay

Base class for objects supporting delayed sampling.

classDiagram Delay <|-- Expression Delay <|-- Distribution Expression <|-- Random link Delay "../Delay/" link Expression "../Expression/" link Random "../Random/"

Classes derived from Delay support delayed sampling. Ostensibly this includes all Distribution and Expression classes, although among Expression classes only Random actually implements the interface.

### Design & Implementation

The $M$-path for delayed sampling is kept as a singly-linked list of Delay objects directed from root to leaf along the $M$-path. While all objects in the path are ostensibly of abstract type Delay, they are alternately of concrete type Random and Distribution (R* denotes a Random object, D* a Distribution object):

graph LR R1((R1)) --> D2((D2)) --> R2((R2)) --> D3((D3))

The root is necessarily of type Random, but the leaf may be of either type Distribution (as above) or, if a Random has been associated with that Distribution, of type Random. In the latter case the final node is doubly-linked:

graph LR R1((R1)) --> D2((D2)) --> R2((R2)) --> D3((D3)) --> R3((R3)) R3((R3)) .-> D3

While, if the leaf node is of type Random, it has a backward link to its associated Distribution, note that all other nodes of type Random only have a forward link to the distribution associated with their child node on the $M$-path.

User code maintains external references to the Random objects, but typically not the Distribution objects. Delayed sampling operations are triggered by the use of these references.

Tip

One advantage of this arrangement is that variable elimination naturally occurs as a result of garbage collection. Once no references remain to a Random that is the root of an $M$-path it is collected, usually along with the next Distribution in the list. Not only has it then been marginalized out in establishing the $M$-path, but it has now been eliminated as the program has discarded it without it ever being sampled.

Events on the list are triggered by user operations on the Random objects, to which the user code maintains references.

The graft operation occurs when the leaf node is a Random, and that Random enters the construction of a new Distribution object in a form that allows it to be marginalized out. The Distribution is appened to the list and the existing backward link remove:

graph LR R1((R1)) --> D2((D2)) --> R2((R2)) --> D3((D3)) --> R3((R3)) --> D4((D4))

If a Random is subsequently associated with the Distribution it is added as before:

graph LR R1((R1)) --> D2((D2)) --> R2((R2)) --> D3((D3)) --> R3((R3)) --> D4((D4)) --> R4((R4)) R4((R4)) .-> D4

If a Random leaf node must be realized it simply simulates a value from its associated distribution and removes its backward link:

graph LR R1((R1)) --> D2((D2)) --> R2((R2)) --> D3((D3)) --> R3((R3)) --> D4((D4)) --> R4
graph LR R1((R1)) --> D2((D2)) --> R2((R2)) --> D3((D3)) --> R3((R3)) --> D4((D4'))

### Member Variables

Name Description
child:Delay? Child node on the $M$-path.
coparent:Delay? Co-parent node on the $M$-path. This is used only for peculiar cases to establish joint distributions over two or more Randoms, such as for the normal-inverse-gamma distribution.
n:Integer If a co-parent, the number of this among those co-parents.

### Member Functions

Name Description
graft Extend the $M$-path below this.
graft Extend the $M$-path below this.
graftReplace Replace an existing $M$-path below this.
graftReplace Replace an existing $M$-path below this.
prune Prune the $M$-path from below this.
prune Prune the $M$-path from below this.
isGrandChildOf Is this the grandchild of node on the $M$-path.
join Join this with another node to become coparents on the $M$-path.

### Member Function Details

#### graft

function graft(node:Delay)

Extend the $M$-path below this.

• node: Node to become the child of this.

function graft(node:Delay, n:Integer)

Extend the $M$-path below this.

• node: Node to become the child of this.
• n: Where node is grafted to multiple parents, the number of this among those parents.

#### graftReplace

function graftReplace(node:Delay)

Replace an existing $M$-path below this.

• node: Node to become the child of this.

function graftReplace(node:Delay, n:Integer)

Replace an existing $M$-path below this.

• node: Node to become the child of this.
• n: Where node is grafted to multiple parents, the number of this among those parents.

#### isGrandChildOf

function isGrandChildOf(node:Delay) -> Boolean

Is this the grandchild of node on the $M$-path.

#### join

function join(node:Delay)

Join this with another node to become coparents on the $M$-path. This is used only for peculiar cases to establish joint distributions over two or more Randoms, such as for the normal-inverse-gamma distribution.

#### prune

function prune() -> Delay

Prune the $M$-path from below this.

Return: If this is a Random node, then this. If this is a Distribution node, then the updated Distribution for the first parent, which is now the leaf of the $M$-path.

function prune(n:Integer) -> Delay

Prune the $M$-path from below this.

Return: If this is a Random node, then this. If this is a Distribution node, then the updated Distribution for the nth parent, which is now the leaf of the $M$-path.