Skip to content
EXCEPTION - Ungrounded Variable

Error Code: EXCEPTION - Ungrounded Variable

This guide explains why an ungrounded variable error may occur and describes how to fix it.

In Rel, a variable is grounded when it can be instantiated to a specific, finite set of values.

For instance, in the expression x: range(1, 100, 1, x), the variable x is instantiated with the values 1, 2, ..., 100.

By contrast, a variable is not grounded or is ungrounded if the system is unable to determine a way to instantiate a finite set of values.

Example: Infinite Possibilities

For example, in x: minimum(1, x, 1), there are infinitely many values of x for which minimum(1, x, 1) is true. In fact, this is the case in many relations defined in Rel Libraries, such as in the example above with minimum.

Consider another example that returns an ungrounded variable error:

def my_string = substring["abcd", -2]
def output = my_string
Error example from the RAI Console

The example above defines the relation my_string as a substring of the "abcd" string, using the built-in substring relation. This returns an EXCEPTION error thrown by the query optimizer.

Because this third argument is allowed to be larger than the length of the string, the number of valid values is infinite. To fix this problem, you need to provide another argument to substring that states where the substring should end. For example, the substring could end after the second character:

// read query
 
def my_string = substring["abcd", -2, 2]
def output = my_string

Example: Nonlinear Dependencies

Another reason an ungrounded variable error can occur is when nonlinear mathematical dependencies need to be resolved. In general, no closed form solutions (opens in a new tab) exist for these nonlinear dependencies, making it impossible for the system to determine all valid values.

For example:

def output(x, y) {
    x = 4
    and y^2 = x
}
Error example from the RAI Console

The code above leads to an ungrounded variable error because the equation y^2=x is nonlinear. In this case, the valid values for y are known to be 2 and -2, yet the system can’t resolve this due to the nonlinear nature of the equation.

One solution is to rewrite the equation such that it’s linear in y (if possible):

// read query
 
def output(x, y) {
    x = 4
    and (y = sqrt[x] or y = -sqrt[x])
}

Or you can provide an explicit finite domain for y:

// read query
 
def D = range[-10, 10, 1]
 
def output(x, y in D) {
    x = 4
    and y^2 = x
}

In this way, the mathematical equation turns into a filter and only keeps (x, y) pairs that fulfill the equation.

See Grounded Variables in the Rel Language Reference manual and Rel Primer: Advanced Syntax for more details.

Was this doc helpful?