Syntax rules
HOBBS deliberately stays close to C while adding a small number of model-specific constructs.
Core rules
- Parameter declarations are top-level statements and end with semicolons.
- Use
paramfor continuous state anddparamfor bounded integer state. - Parameter and data indexing is one-based:
beta(j),x(i,j),u(j,l). - Model dimensions are positive integer literals or named scalar values supplied in the R data list.
- A
blockname must correspond to the parameter it updates. - Array blocks can use multiple active indices, such as
block u(j,l); the transition still changes one scalar coordinate at a time. - A probability statement uses
~and ends with a semicolon. - A range such as
1:2can be passed to a multivariate probability statement. func name()takes no arguments and is expanded at the call site.- Standard C-like
if,else, loops, assignments, arithmetic, and local scalar declarations can be used inside model code. - Temporary multivariate objects can use
vecandmatdeclarations. proposal(parameter(index))andcurrent(parameter(index))are used inside deterministic updates to express the staged difference.- A custom log contribution can be added with
target += ...;.
A compact example
param beta(p) sampler=slice;
param logsigma(1);
dparam gamma(p, 0, 1);
func llk() {
double sigma = exp(logsigma(1));
for (i = 1:n) {
y(i) ~ dnorm(mu(i), sigma);
}
}
block beta(j) {
beta(j) ~ dnorm(0, 1);
if (gamma(j) != 0) {
llk();
}
} update mu(n) {
if (gamma(j) != 0) {
for (i = 1:n) {
mu(i) += (proposal(beta(j)) - current(beta(j))) * x(i,j);
}
}
}
The important correctness point is the matching condition: if an excluded coefficient does not affect the model predictor, its cache update must also do nothing.
Distribution parameterization
Use the HOBBS signatures shown on the distribution reference. In particular, HOBBS dnorm(mean, sd) uses a standard deviation, whereas JAGS dnorm(mean, precision) uses a precision. The validation pages show the corresponding HOBBS, Stan, and JAGS versions side by side.