Next: , Up: Available Constraints   [Contents][Index]

#### Arithmetic Relations

`?Expr RelOp ?Expr   reifiable`

defines an arithmetic relation. The syntax for Expr and RelOp is defined by a grammar (see Syntax of Arithmetic Expressions). Note that the expressions are not restricted to being linear. Constraints over nonlinear expressions, however, will usually yield less constraint propagation than constraints over linear expressions.

Arithmetic relations can be reified as e.g.:

```| ?- X in 1..2, Y in 3..5, X#=<Y #<=> B.
B = 1,
X in 1..2,
Y in 3..5
```

Linear arithmetic relations, except equalities, maintain bounds consistency. Their reified versions detect bounds entailment and disentailment.

#### Partiality and Undefined Values

Some arithmetic functions are partial, i.e., they do not have a defined value for all combinations of arguments. Those are:

`X / Y`
`X // Y`
`X div Y`
`X mod Y`
`X rem Y`

for `Y #= 0`

`X ^ Y`

for `Y #< 0` if `abs(X) #\= 1`. Note that this differs from the MiniZinc semantics. In MiniZinc, `X ^ Y` = `1 div (X ^ -Y)` if `Y < 0`. In SICStus, the CLPFD value is equal to the Prolog value if the latter is defined and integer.

`if_then_else(X,Y,Z)`

for `X` not in `0..1`

Like MiniZinc, SICStus implements the relational semantics of partial functions. Quoting [MiniZincHandbook], “any undefinedness bubbles up to the closest Boolean context and becomes `false` there”. Here, a Boolean context is simply an arithmetic relation. A few examples illustrate how this works:

```| ?- Y in -1 .. 1, 10 div Y #= Z, indomain(Y).
Y = -1,
Z = -10 ? ;
Y = 1,
Z = 10 ? ;
```

Here, the division by zero silently made the `#=` constraint fail.

```| ?- Y in 0..1, 10 div Y #= 10 #<=> B, indomain(Y).
Y = 0,
B = 0 ? ;
Y = 1,
B = 1 ? ;
```

Here, the division by zero again made the `#=` constraint fail, reflected in the answer `B = 0`.

```| ?- Y in -1 .. 1, Z #= if_then_else(1, 2, 10 div Y), indomain(Y).
Y = -1,
Z = 2 ? ;
Y = 1,
Z = 2 ? ;
```

Here, the division by zero “bubbled up” through the if-then-else expression, making `#=` fail for `Y = 0`, even though `if_then_else/3` actually did not use its third argument.

```| ?- X in 1..2, Y in -1 .. 1, X ^ Y #= Z, indomain(X), indomain(Y).
X = 1,
Y = -1,
Z = 1 ? ;
X = 1,
Y = 0,
Z = 1 ? ;
X = 1,
Y = 1,
Z = 1 ? ;
X = 2,
Y = 0,
Z = 1 ? ;
X = 2,
Y = 1,
Z = 2 ? ;
```

Here, `2 ^ -1 #= Z` failed, because `2 ^ -1` is undefined.

#### Other Arithmetic Constraints

The following constraints are among the library constraints that general arithmetic constraints compile to. They express a relation between a sum or a scalar product and a value, using a dedicated algorithm, which avoids creating any temporary variables holding intermediate values. If you are computing a sum or a scalar product, then it can be much more efficient to compute lists of coefficients and variables and post a single sum or scalar product constraint than to post a sequence of elementary constraints.

`sum(+Xs, +RelOp, ?Value)`

where Xs is a list of domain variables, RelOp is a relational symbol as above, and Value is an integer or a domain variable. True if `sum(Xs) RelOp Value`. Corresponds roughly to `sumlist/2` in `library(lists)`.

`scalar_product(+Coeffs, +Xs, +RelOp, ?Value)   reifiable`
`scalar_product(+Coeffs, +Xs, +RelOp, ?Value, +Options)   reifiable`

where Coeffs is a list of length n of integers, Xs is a list of length n of integers or domain variables, RelOp is a relational symbol as above, and Value is a domain variable. True if `sum(Coeffs*Xs) RelOp Value`.

Options is a list that may include the following options:

`among(Least,Most,Range)   since release 4.3.1`

If given, then Least and Most should be integers and Range should be a ConstantRange (see Syntax of Indexicals). This option imposes the additional constraint on Xs that at least Least and at most Most elements belong to Range. This side constraint invokes the algorithm of [Razakarison, Carlsson, Beldiceanu & Simonis 13].

`consistency(Cons)`

This can be used to control the level of consistency used by the constraint. The value is one of the following:

`domain`

The constraint maintains domain consistency. Please note: This option is only meaningful if RelOp is `#=`, and requires that any domain variables have finite bounds.

`bounds`
`value`

The constraint tries to maintain bounds consistency (the default).

`scalar_product_reif(+Coeffs, +Xs, +RelOp, ?Value, ?Reif)   since release 4.5`
`scalar_product_reif(+Coeffs, +Xs, +RelOp, ?Value, ?Reif, +Options)`

is the reified version of `scalar_product/[4,5]`, i.e., Reif is 1 if `scalar_product/[4,5]` with the same argument holds; otherwise, Reif is 0.

The following constraints constrain a variable to be the minimum (maximum) value of a given list.

`minimum(?Value, +Xs)`

where Xs is a list of domain variables, and Value is a domain variable. True if Value is the minimum of Xs. Corresponds to `min_member/2` in `library(lists)` and to `minimum` in MiniZinc.

`maximum(?Value, +Xs)`

where Xs is a list of domain variables, and Value is a domain variable. True if Value is the maximum of Xs. Corresponds to `max_member/2` in `library(lists)` and to `maximum` in MiniZinc.

The following constraints constrain a variable to be index of the minimum (maximum) value of a given list. They maintain domain consistency.

`minimum_arg(+Xs, ?Index)   since release 4.6`

where Xs is a list of domain variables, and Index is a domain variable. True if Index is the index of the minimum value of Xs. If that value occurs more than once, Index is the index of the first occurrence. Corresponds to `arg_min` and `minimum_arg` in MiniZinc.

`maximum_arg(+Xs, ?Index)   since release 4.6`

where Xs is a list of domain variables, and Index is a domain variable. True if Index is the index of the maximum value of Xs. If that value occurs more than once, Index is the index of the first occurrence. Corresponds to `arg_max` and `maximum_arg` in MiniZinc.

The following constrains a variable to take the value of either of two other variables, depending on a Boolean variable. It maintains domain consistency.

`if_then_else(If, Then, Else, Value)   since release 4.8.0`

True if If=1 and Value=Then, or If=0 and Value=Else. Corresponds to if-then-else expressions in most programming and modeling languages.

Send feedback on this subject.