## 5.2 Constraint Extensions and Combinators

### Operators

Missing: fd compare

<statement> ::=
E1`::` E2 |  | `{`FD.int`` E2`` E1`}`

<statement> ::=
E1`:::` E2 |  | `{`FD.dom`` E2`` E1`}`

<expression> ::=
E1`::` E2 |  | `{`FD.reified.int`` E2`` E1`}`

<expression> ::=
E1`:::` E2 |  | `{`FD.reified.dom`` E2`` E1`}`

### Failure

<statement>, <expression> ::=
`fail` |  | `raise failure(`...`) end`
where the omitted parts of the exception are implementation-dependent.

### Combinators

<statement> ::=
`not` S `end` |  | `{`Combinator.'not'` proc {$}` S `end}`

<statement>, <expression> ::=
`cond` L1`[]` ...`[]` Ln `end` |  | `cond` L1`[]` ...`[]` Ln `else raise error(kernel(noElse` ...`)` ...`) end end`
where the omitted parts of the exception are implementation-dependent.

<cond statement clause>, <dis statement clause> ::=
D `in` S1`` [ `then` S2 ] |  | x1`` ...`` xn `in` D'`` S1`` [ `then` S2 ]
if D is not a sequence of distinct variables and where {x1, ..., xn} = PV(D) and D' is D with singleton variables and escapes removed.

<cond expression clause> ::=
D `in` S `then` E |  | x1`` ...`` xn `in` D'`` S `then` E
if D is not a sequence of distinct variables and where {x1, ..., xn} = PV(D) and D' is D with singleton variables and escapes removed.

Missing: translation of `cond`/`or`/`dis`/`choice` expression into statement

The following rewrite rules make use of an auxiliary function Proc, defined as follows:

L | Proc(L)
--- | ---
S1 `in` S2 | `proc {$}` S1 `in` S2 `end`
S1 `in` S2 `then` S3 | `fun {$}` S1 `in` S2 `proc {$}` S3 `end end`

<statement> ::=
`cond` L1`[]` ...`[]` Ln `else` S `end` |  | `{`Combinator.'cond'` '#'(`Proc(L1)`` ...`` Proc(Ln)`) proc {$}` S `end}`

<statement> ::=
`or` L1`[]` ...`[]` Ln `end` |  | `{`Combinator.'or'` '#'(`Proc(L1)`` ...`` Proc(Ln)`)`

<statement> ::=
`dis` L1`[]` ...`[]` Ln `end` |  | `{`Combinator.'dis'` '#'(`Proc(L1)`` ...`` Proc(Ln)`)`

<statement> ::=
`choice` S1`[]` ...`[]` Sn |  | `case {`Space.choose`` n`} of 1 then` S1`[]` ...`[]` n `then` Sn `end`