The nodes in an Advisor tree, starting at a PIR on down, represent nodes in a Bayesian belief network. Each node has a number of states which we call AssertionStates that represent the different values possible for that node. Each of these states currently holds a probability which represents the belief that the node is in that state (has the value represented by the state). Each node also holds (within the AssertionState nodes) an array of values which represent the conditional probability of the various states of the node. A conditional probability represents the probability that, given that the parent node has some value x, what is probability of this node being in state y (having value y). This is often written in the literature as P(y|x). Each of our AssertionStates holds one of these conditional probabilities for each state of it's node's parent.
In order to properly calculate the belief values (the AssertionState probabilities) for a node, it is also required to keep track of two more values within each AssertionState: a value representing the effect of the tree above our parent node, and a value representing the effect of our children nodes and their descendents. These are often referred to as the pi and lambda values. The belief value of a node is the pi and lambda values multiplied together for any given AssertionState, and then normalized so that the total of the belief values in a node sums to one.
In order to calculate the correct belief value for any node, The node must update its pi and lambda values, and then calculate its belief.
In order to calculate its lambda values, it must ask for a lambda message from each of its children. This message contains the lambda values of the child multiplied by the child's cross probability matrix. The node then updates its own lambda values by multiplying together the values from the lambda messages of its children.
In order to update its pi values, the node requests a pi message from its parent. The parent calculates the pi values for a particlar child by multiplying together its own pi values and the lambda messages from each of the children other than the child requesting the pi value, and then normalizing (making sure the sum of the values is 1). Upon receiving this message, the node calculates its own pi values by multiplying together the message values and its conditional probability matrix.
Note that there are two exceptions: the top node and the leaf (or evidence) nodes. The top node will never have its pi values changed, but its belief will change as the lambda values are varied. The top node's pi values must be set arbitrarily by the designer. This is also known as a prior probability. The evidence nodes, on the other hand, can only have their lambda values changed by the arrival of a piece of evidence. Before any evidence has arrived, all lambda values in evidence nodes are set to 1 (it's not necessary to normalize lambda values, only belief values.) When evidence arrives, the lamda value corresponding to the 'true' state is set to 1, and the others are set to 0, depending on one's confidence in the evidence.
Therefore in JointAdvisor, after initializing the system, when a piece of evidence arrives, the lambda values of the appropriate evidence are changed. Then, a message will be sent to parent of that node, giving the parent node its appropriate lambda values.
When any node receives a 'propagateUp' message from one of its children, it will first calculate its own new lambda values (by multiplying together all the conditioned lambda values it receives from its children), and then it will send a 'propagateUp' message to its parent. Now, however, it must send new pi messages to each of it's other children (called propagateDown in the code), because their pi values have changed (since they depend on the lamda values of their siblings, and now one of those have changed).
When any node receives a pi message, it must recalculate and send pi messages to each of its children, since the pi value of a child also depends on the pi value of the parent node.
Thus, from the point of evidence entry, propagateUp messages will be passed up the tree, and propagateDown messages will move down the tree along every path but that taken by the propagateUp messages.
The above algorithm is heavily based on the message passing system outlined in Chapter 4 of 'Probabilistic Reasoning in Intelligent Systems: Networks of Plausible Inference' by Judea Pearl, 1988, Morgan Kaufmann Publishers, Inc., San Fransisco.