Operands are the basic building blocks in Gecode/R. An operand is
anything you can place a **constraint** on. The most basic operands
are the various types of variables, but operand can also be
built upon to produced new operands, using **properties** defined by
operands.

All types of operands, their properties and constraints are found in the menu.

Properties are methods, defined by operands, that produce new operands.
An example is the `+`

method of integer operands
that takes another integer operand and produces a third integer operand
that represents the sum of the two operands.

new_integer_operand = int_operand1 + int_operand2

Another example is the `size`

method of set operands
that produces an integer operand representing the size of the set.

new_integer_operand = set_operand.size

Use properties to produce the operands that you want to place constraints on.

Constraints are used used to constrain the value of operands. All
constraints are placed using the `must`

or `must_not`

methods defined
by operands.

operand.must.constraint_method(params)

The following constraints `int_operand`

to be strictly greater than 5.

```
int_operand.must > 5
```

Use operand properties to constrain e.g. the sum of two integer operands.

```
(int_operand1 + int_operand2).must > 5
```

Using `must_not`

instead of `must`

negates a constraint. Not all constraints
support being negated.

Many constraints accept a **reification** option, which allows one to combine
constraints. All integer and boolean constraints (but not set constraints) also
accept a **propagation strength** option which suggests how much effort the solver
should put into pruning the search space based on a constraint.

Reification is used to link a constraint to a boolean variable in such a way that the variable is true if and only if the constraint is satisfied. The propagation goes both ways, so if the variable is constrained to be false then the constraint is not allowed to be satisfied.

Reification can be thought of as a last resort glue which can be used to combine constraints so that e.g. exactly 3 out of 17 constraints must be satisfied.

The variable to use for reification is specified with the key `:reify`

. The
following connects the boolean variable `is_large`

with a relation constraint.

number.must_be.greater_than(17, :reify => is_large)

This constraint does not force `number`

to be greater than 17 (which would be
the case if no reification has been used).

There exist some syntactic sugar for combining reifiable constraints, which can
be used with all reifiable constraints. To express a conjunction of two
constraints simply place `|`

between them, analogically for conjunctions and
`&`

. The new expression is also a reifiable constraint, so one can nest the
expressions if wanted. The following constrains that either x must be less than
0 or y must be greater than 5 and x must be 0.

x.must < 0 | (y.must > 5 & x.must == 0)

The propagation strength basically *suggests* how much effort the solver
should put into trying to prune the domains of variables using the
constraint. A higher strength can reduce the search space quicker, but
at the cost of making each propagation more costly.

Note that no set constraint accepts the propagation strength option.

It’s usually worth testing a few different strength to see how well they work, a good choice of strengths can cut down the search time depending on the problem.

The different strengths are:`:value`

- Value consistency (naive).
`:bounds`

- Bounds consistency.
`:domain`

- Domain consistency.
`:default`

- Uses the default consistency of the constraint.

The option is specified with the key `:strength`

. The following places a domain
consistent distinct constraint on `numbers`

.

numbers.must_be.distinct(:strength => :domain)

The strength generally progresses as `:value`

-> `:bounds`

-> `:domain`

(`:value`

being the weakest, `:domain`

being the strongest).

The propagation kind option *suggests* the implementation that should be
preferred if there are multiple implementations of a constraint.

`:speed`

- Prefer speed over memory consumption.
`:memory`

- Prefer low memory consumption over speed.
`:default`

- Uses the constraint’s default propagation kind.

The option is specified with the key `:kind`

. The following tells the tuple
constraint, placed on `numbers`

, to favor speed over low memory consumption.

numbers.must_be.in(tuples, :kind => :speed)