# Domain Search

The constant values in the domain of a variable can be enumerated via the predicate indomain/1. This predicate is capable of enumerating finite and infinite domains. For infinite domains it is also possible to enumerate domains that are open ended on both sides, resulting in an alternating enumeration towards inf and sup.

Examples:
```?- X in 10..15, indomain(X).
X = 10 ;
...
X = 15
?- indomain(X).
X = 0 ;
X = -1 ;
...```

As a convenience the finite domain solver provides a couple of solving techniques. We provide the following solving techniques along domain ranges when there is an attempt to label multiple variables at once. The predicate for this search is label/1. The predicate label_maximum/2 repeatedly restarts search to find a maximum:

• Brute Infinite Search
• Heuristic Finite Search
• Branch and Bound Restart

Infinite domains are filtered out first and then cantor paired. For finite domains we have implemented a search strategy, which prefers those variables with a smaller cardinality of the domain first. In certain cases this can reduce the search space. Further notions of consistency and search are discussed in [2].

Examples:
`?- [X,Y] ins 0..9, 3*X+5*Y #= 11, label([X,Y]).X = 2,Y = 1 ;No?- 3*X+5*Y #= 11, label([X,Y]).X = 2,Y = 1 ;X = -3,Y = 4 ;...`

The predicates indomain/1 and label/1 have randomized equivalents random_indomain/1 and random_label/1. For a full enumeration the randomized versions would be slower, more memory intensive and not give a random sequence, but they are still helpful in picking a first random solution and are used as part of the maximization predicate.

The following domain search predicates are provided:

indomain(V):
The predicate succeeds for every element in the domain of the variable V and instantiates the variable V with this element. The domain of the variable can be finite or infinite. A missing domain is interpreted as the full domain.
random_indomain(V):
The predicate succeeds randomly for every constant I that is in the domain of the variable V. The domain of the variable can be only finite.
label([V1, .., Vn]):
The predicate posts all the assignments of constants I1, .., In to the variables V1, .., Vn from their domains. Infinite domains are filtered out and cantor paired. Then smaller domains are enumerated first.
random_label([V1, .., Vn]):
The predicate posts randomly all the assignments of constants I1, .., In to the variables V1, .., Vn from their domains. Infinite domains are filtered out and cantor paired. Then smaller domains are enumerated first.
label_maximum([V1, .., Vn], O):
The predicate succeeds maximizing the objective function O, and then succeeds for all corresponding labelings of the variables V1, .., Vn.