## 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`