Skip to content
Conditional Expression

Conditional Expression

Expr := "if" Expr "then" Expr "else" Expr "end"

The condition must be a formula, that is, an expression of arity 0.

If the condition is true, then the value of the expression is the value of the expression in the then branch, and the expression in the else branch is not evaluated. Otherwise the value is the value of the expression in the else branch, and the expression in the then branch is not evaluated. The then and else branches can have arbitrary arity.

The expression if e1 then e2 else e3 end has the same meaning as (e1, e2); (not(e1), e3).

Examples:

if 1 < 2 then 'a' else 'b' end

This gives ('a',).

def p = 1
def q = 2,3
def r = 4,5
def output = if p(1) then q else r end

This gives (2, 3).

def output = if p > 1 then q else r end

This gives (4, 5).

def p = 1; 2; 3
def output = if x = 1 then 'a' else 'b' end for x in p

This gives the following:

(1, 'a')
(2, 'b')
(3, 'b')

Conditional expressions can be nested, as shown in the example below, which defines a relation that computes the factorial of a positive integer. The relation is named my_factorial to avoid conflict with the function factorial in the Standard Library. See also the annotation @ondemand.

// read query
 
@ondemand
def my_factorial[n in Int] =
    if n < 0 then false
    else if n = 0 then 1
         else n * my_factorial[n - 1]
         end
     end
def output = my_factorial[5]

In Rel such definitions are usually expressed in a more idiomatic way:

@ondemand
def my_factorial[n in Int] = 1,  n = 0
def my_factorial[n in Int] = n * my_factorial[n - 1],  n > 0

This version features the infix comma operator, which denotes the Cartesian product of its arguments. If n = 0 is true, then the body of the first definition will be 1, which is the Cartesian product of {(1,)} and {()}. In that case the body of the second definition will be the empty relation, because n > 0 will be false, that is {}, and a Cartesian product of anything with an empty relation is an empty relation.

Similarly, if n > 0, then the body of the first definition will be the empty relation, and the body of the second definition will be the relation produced by the expression that precedes the comma.

You can think of n = 0 and n > 0 as guards that allow each of the two definitions to be used only in some particular situations. If these guards are mutually exclusive, then the effect is a more concise formulation of what can be achieved with a conditional expression or nested conditional expressions.

Note that, in general, these guards do not have to be mutually exclusive. If they are not, then both definitions will contribute to the result for a given value of n, and the effect may be different from that of a conditional expression. In this particular example, however, changing n > 0 to n >= 0 will not affect the result, because my_factorial[-1] will produce an empty relation.

Next: Constants

Was this doc helpful?