REL
REFERENCE
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