Declaring multiple variables with one statement in MiniZinc - minizinc

When writing MiniZinc models, I often declare multiple variables like this:
var int: dog;
var int: cat;
var int: bird;
var int: mammal;
var int: horse;
I tried to declare all of these variables on one line, but it produced a syntax error:
var int: dog, cat, bird, mammal, horse;
Is it possible to declare all of these variables in a more concise way, using just one statement?

There is no enumeration type or similar in MiniZinc. There are some hints that at some type of enumerations will be included in a future release, though I'm note sure if it will work with decision variables ("var int"), perhaps it will just parameter (constant) variables.
Here are some hopefully relevant side notes.
What I tend to do is use an array of decision variables:
int: n = 5;
array[1..n] of var int: x;
And then one can use x[1] etc. Explicit arrays are also often needed - or at least convenient - in the model to simplify certain constraints such as "all_different" etc.
But it's often better to use the named variables in the constraints.
If you also want to use the names variables in your model, you have to define them with their names and connect them to the "x" array.
var int: dog = x[1];
var int: cat = x[2];
var int: bird = x[3];
var int: mammal = x[4];
var int: horse = x[5];
Or connect then in another way:
int: n = 5;
var int: dog;
var int: cat;
var int: bird;
var int: mammal;
var int: horse;
array[1..n] of var int: x = [dog,cat,bird,mammal,horse];
[And I usually define as small domains as possible for the variables, e.g. "var 1..10: dogs", etc.]

Related

Do properties in F# classes double memory used in private fields?

F# classes have the nice property that arguments automatically become immutable private fields. If I want to make one such field available externally I can create a property, like I in the code below:
type MyClass (i: int list) =
member this.I with get() = i
member this.foo x = i.Head + x
let mc = MyClass [0..10]
mc.foo 10 // 10
mc.I // [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Does I in the code above double the amount of memory used for i or is it just a function that returns the value of i?
(Of course this is only relevant if the argument uses a lot of memory, which is not the case in the example above)
No: i gets stored as a private field inside of MyClass; MyClass.I is a property whose get function returns the value of said field.
list<'T> is a reference type, so persisting it inside of the class is effectively a shallow copy and will not duplicate the data inside of the list.

Confused by the `m..n` notation in MiniZinc

I have seen the "dot-dot" notation (..) in different places. In the following example, 0..n tells us the domain of the decision variable (which in this case, are the entries of the array s).
int: n;
array[0..n-1] of var 0..n: s;
Another example would be in the for-loop:
constraint forall(i in 0..sequence_length)(
t[i] = sum(k in 0..sequence_length)((bool2int(t[k] == i)))
);
In fact, we can even do something like
par var 1..5: x
My feeling is that the expression m..n is generally used when we define a variable (instead of a parameter), and we want to specify the domain of the variable. But in the second case, we are not defining any variable. So when do we use m..n? What is it exactly (e.g. does it have a type?)?
m..n denotes the set of (consecutive) integers from m to n. It could also be written explicitly as {m,m+1,m+2,...,n-1,n}.
Using a set as the domain, e.g.
var 0..5: x;
could be written as
var {0,1,2,3,4,5}: x;
or (which is probably a weird style):
var {1,5,2,3,0,4}: x;
but both represents the set 0..5.
When using m..n in a forall(i in m..n) ( .... ) loop it means that i is assigned from m to n.
A set is always ordered as this little model shows:
solve satisfy;
constraint
forall(i in {0,4,3,1,2,5}) (
trace("i: \(i)\n")
)
;
The trace function prints the following, i.e. ordered:
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5

Can't mutate [Int] using .remove(at:)

var bigNum = [2,34,5].remove(at: 2)
Error:
Playground execution failed: error: CalculatorPlayGround.playground:35:14: error: cannot use mutating member on immutable value of type '[Int]'
var bigNum = [2,34,5].remove(at: 2)
But
var bigNum = [2,34,5]
var b = bigNum.remove(at: 2)
is ok.
What is the difference? Why does it work in the second case?
.remove(at:) tries to mutate the array you call it on.
When you create the array like you did in your first example ([1,2,3].whatever), it creates an immutable constant, as if you were to create it like this:
let array = [2, 34, 5] //not mutable
If you force it to create the array as a variable, it is mutable:
var array = [2, 34, 5] //mutable
Note
I don't know exactly what you are trying to do, but bigNum makes me assume you're trying to get a number from the array? Because right now, bigNum would become this array: [2, 34] instead of just a number.
[2,34,5] in itself is a literal, and as such is immutable in Swift (i.e. you can't write [2,34,5].remove(at: 2)). To apply a mutating function, you first need to store your array in a mutable container, using the var keyword:
var bigNum = [2,34,5]
Only after doing so, you can use mutating func .remove(at:) on mutable bigNum.

MiniZinc: type error: expected `array[int] of int', actual `array[int] of var opt int

I am trying to write a predicate that performs the same operation as circuit, but ignores zeros in the array, and I keep getting the following error:
MiniZinc: type error: initialisation value for 'x_without_0' has invalid type-inst: expected 'array[int] of int', actual 'array[int] of var opt int'
in the code:
% [0,5,2,0,7,0,3,0] -> true
% [0,5,2,0,4,0,3,0] -> false (no circuit)
% [0,5,2,0,3,0,8,7] -> false (two circuits)
predicate circuit_ignoring_0(array[int] of var int: x) =
let {
array[int] of int: x_without_0 = [x[i] | i in 1..length(x) where x[i] != 0],
int: lbx = min(x_without_0),
int: ubx = max(x_without_0),
int: len = length(x_without_0),
array[1..len] of var lbx..ubx: order
} in
alldifferent(x_without_0) /\
alldifferent(order) /\
order[1] = x_without_0[1] /\
forall(i in 2..len) (
order[i] = x_without_0[order[i-1]]
)
/\ % last value is the minimum (symmetry breaking)
order[ubx] = lbx
;
I am using MiniZinc v2.0.11
Edit
Per Kobbe's suggestion that it was an issue with having a variable length array, I used "the usual workaround" of keeping the order array the same size as the original array x, and using a parameter, nnonzeros, to keep track of the part of the array I care about:
set of int: S = index_set(x),
int: u = max(S),
var int: nnonzeros = among(x, S),
array[S] of var 0..u: order
This kind of answers your question:
The problem you are experiencing is that your array size is dependent on a var. This means that MiniZinc can not really know the size of the array is should create and the opt type is used. I would suggest that you stay away from the opt type if you do not know how to handle it.
Generally the solution is to make some workaround where your arrays are not dependent of the size of an var. My solution is most often to pad the array, i.e [2,0,5,0,8] -> [2,2,5,5,8], if the application allows it, or
var int : a;
[i * bool2int(i == a) in 1..5]
if you are okay with zeroes in your answer (I guess not in this case).
Furthermore, the alldifferent_except_0 could be in interest for you, or at least you can look how alldifferent_except_0 solves the problem with zeroes in the answer.
predicate alldifferent_except_0(array [int] of var int: vs) =
forall ( i, j in index_set(vs) where i < j ) (
vs[i]!=0 /\ vs[j]!=0 -> vs[i]!=vs[j]
)
from MiniZinc documentation

Swift for..in and for loop

Why does for loop require var while for..in does not allow use of var?
for loop
for var index = 0; index < 10; i++ {
}
for..in loop
for index in "test" {
}
instead of:
for var index in "test" {
}
The Swift documentation sums it up pretty nicely:
index is a constant whose value is automatically set at the start of each iteration of the loop. As such, it does not have to be declared before it is used. It is implicitly declared simply by its inclusion in the loop declaration, without the need for a let declaration keyword.
In other words, the variable used in a for/in loop can only be a constant; thus, there's really no need to require that let be used.
The variable(s) used in a "traditional" for loop, however, can be variables or constants, so var or let is required. (Generally, they will be variables, but it is possible to use a constant in a for loop.) They can also be declared outside of the for loop (i.e., before it) and still used in the for loop. Because of this flexibility, you are required to declare it as a constant or variable.
The compiler expands for x in 0..<5 to the following:
var g = (0..<5).generate() {
while let x = g.next() {
// Use x in loop body
}
Every time around the loop, x is a freshly declared variable, the value of unwrapping the next result from calling next on the generator.
Now, that while can be rewritten in this fashion:
while var x = g.next() {
// use x here
}
I guess for this reason, for...in doesn't support the var syntax for declaring the loop counter so that it doesn't give you the wrong impression that x is mutable.