I would like to declare an array x of 2n+1 domain variables, where the domain of the i-th variable of the array (with in in [1,2n+1]) is given by the following interval min(i-n,0)..max(i-n,0).
For instance, for n=3, we should have:
x[1] in -3..0
x[2] in -2..0
x[3] in -1..0
x[4] in 0..0
x[5] in 0..1
x[6] in 0..2
x[7] in 0..3
Naivily, I would write:
int: n;
array[1..2*n+1] of var min(i-n,0)..max(i-n,0): x;
but somehow I don't know how to relate i to the index in the array.
This cannot be achieved simply using the domain of an array of variables. The best way to achieve this is to employ array comprehensions. Your example would be formulated as:
int: n;
any: x ::output = [ let { var min(i-n,0)..max(i-n,0): x; } in x | i in 1..2*n+1];
Note that I added the ::output
annotation to the declaration, as using the right-hand side of a declaration will exclude it from the standard generated output by default. any
is a shorthand to take the type of the right-hand side expression (in this case array[int] of var int
).
Normal comprehensions like this will always create arrays with an index set of 1..N
. However, you can change the index set by providing the index for each element. For example, if you wanted each element i
to be indexed by i-n
, you could write:
int: n;
any: x ::output = [i-n: let { var min(i-n,0)..max(i-n,0): x; } in x | i in 1..2*n+1];