A quick summary on how data in a dense_table (and sparse table, for that matter) is ordered:
As I mentioned, a factor is defined by a probability mass function, which is stored in a an N-d matrix defined by a dense_table. The N-d matrix of the dense_table spans the domain defined by the factor's neighboring variables. So, for instance, the domain of cbj is defined as the cross product of the domains of the two attached variables, bool_var_b and foo.
However, the ordering of the domain is important, and I admit, a little counter-intuitive. (It is a hold-over from an older version of this library and maintained for performance reasons.) The domain is ordered such that the variable with the smallest ID iterates fastest. That is, each variable (created with belief_prop::factor_graph::add_variable(...)) is a assigned a consecutive ID. A discrete_domain can then be constructed over a vector of variables and a dense_table can be constructed over the domain. When iterating over the table's domain, the smallest stride will be for the variable with the smallest ID (not, for example, the first variable added to the domain...). So in our example, foo was created before bool_var_b, so the linear index of cbj's domain is,