This is an old version, view current version.

11.3 Extra-grammatical constraints

Type constraints

A well-formed Stan program must satisfy the type constraints imposed by functions and distributions. For example, the binomial distribution requires an integer total count parameter and integer variate and when truncated would require integer truncation points. If these constraints are violated, the program will be rejected during compilation with an error message indicating the location of the problem.

Operator precedence and associativity

In the Stan grammar provided in this chapter, the expression 1 + 2 * 3 has two parses. As described in the operator precedence table, Stan disambiguates between the meaning \(1 + (2 \times 3)\) and the meaning \((1 + 2) \times 3\) based on operator precedences and associativities.

Typing of compound declaration and definition

In a compound variable declaration and definition, the type of the right-hand side expression must be assignable to the variable being declared. The assignability constraint restricts compound declarations and definitions to local variables and variables declared in the transformed data, transformed parameters, and generated quantities blocks.

Typing of array expressions

The types of expressions used for elements in array expressions ('{' expressions '}') must all be of the same type or a mixture of scalar (int, real and complex) types (in which case the result is promoted to be of the highest type on the int -> real -> complex hierarchy).

Forms of numbers

Integer literals longer than one digit may not start with 0 and real literals cannot consist of only a period or only an exponent.

Conditional arguments

Both the conditional if-then-else statement and while-loop statement require the expression denoting the condition to be a primitive type, integer or real.

For loop containers

The for loop statement requires that we specify in addition to the loop identifier, either a range consisting of two expressions denoting an integer, separated by ‘:’, or a single expression denoting a container. The loop variable will be of type integer in the former case and of the contained type in the latter case. Furthermore, the loop variable must not be in scope (i.e., there is no masking of variables).

Only break and continue in loops

The break and continue statements may only be used within the body of a for-loop or while-loop.

PRNG function locations

Functions ending in _rng may only be called in the transformed data and generated quantities block, and within the bodies of user-defined functions with names ending in _rng.

Probability function naming

A probability function literal must have one of the following suffixes: _lpdf, _lpmf, _lcdf, or _lccdf.

Algebraic solver argument types and origins

The algebra_solver function may be used without control parameters; in this case

  • its first argument refers to a function with signature ( vector, vector, array[] real, array[] int) : vector,

  • the remaining four arguments must be assignable to types vector, vector, array[] real, array[] int, respectively and

  • the fourth and fifth arguments must be expressions containing only variables originating from the data or transformed data blocks.

The algebra_solver function may accept three additional arguments, which like the second, fourth, and fifth arguments, must be expressions free of parameter references. The final free arguments must be assignable to types real, real, and int, respectively.

Integrate 1D argument types and origins

The integrate_1d function requires

  • its first argument to refer to a function wth signature (real, real, array[] real, array[] real, array[] int) : real,

  • the remaining six arguments are assignable to types real, real, array[] real, array[] real, and array[] int, and

  • the fourth and fifth arguments must be expressions not containing any variables not originating in the data or transformed data blocks.

integrate_1d can accept an extra argument, which, like the fourth and fifth arguments, must be expressions free of parameter references. This optional sixth argument must be assignable to a real type.

ODE solver argument types and origins

The integrate_ode, integrate_ode_rk45, and integrate_ode_bdf functions may be used without control parameters; in this case

  • its first argument to refer to a function with signature (real, array[] real, array[] real, array[] real, array[] int) : array[] real,

  • the remaining six arguments must assignable to types array[] real, real, array[] real, array[] real, array[] real, and array[] int, respectively, and

  • the third, fourth, and sixth arguments must be expressions not containing any variables not originating in the data or transformed data blocks.

The integrate_ode_rk45 and integrate_ode_bdf functions may accept three additional arguments, which like the third, fourth, and sixth arguments, must be expressions free of parameter references. The final three arguments must be assignable to types real, real, and int, respectively.

Indexes

Standalone expressions used as indexes must denote either an integer (int) or an integer array (array[] int). Expressions participating in range indexes (e.g., a and b in a : b) must denote integers (int).

A second condition is that there not be more indexes provided than dimensions of the underlying expression (in general) or variable (on the left side of assignments) being indexed. A vector or row vector adds 1 to the array dimension and a matrix adds 2. That is, the type matrix[ , , ], a three-dimensional array of matrices, has five index positions: three for the array, one for the row of the matrix and one for the column.