MiniZinc / libminizinc

The MiniZinc compiler
http://www.minizinc.org
Other
516 stars 81 forks source link

`EnumEntry` `in` `anotherEnum` is incorrect? #828

Closed LebedevRI closed 1 month ago

LebedevRI commented 3 months ago
int: NUM_W=2;
int: NUM_A=1;
int: NUM_B=1;

enum W = C(1..NUM_W);

enum A = P({ to_enum(W, c) | c in 1..NUM_A });

enum B = S({ to_enum(W, NUM_A+c) | c in 1..NUM_B });

output[show(W) ++ "\n"]; % {C(1), C(2)}
output[show(A) ++ "\n"]; % {P(C(1))}
output[show(B) ++ "\n"]; % {S(C(2))}
output[show((to_enum(A, 1))) ++ "\n"]; % P(C(1))
output[show(to_enum(W, 1) in A) ++ "\n"]; % true   <- makes sense
output[show(to_enum(W, 1) in B) ++ "\n"];  % true <- WHY???
Running Untitled2.mzn | 47msec
{W(1), W(2)}
{A(W(1))}
{B(W(2))}
A(W(1))
true
true

to_enum(W, 1) is A(W(1)), the only element of A, while the only element of B is {B(W(2))}. It looks like the in is takes the index of the enumeration element A(W(1)) within that enumeration A, and checks that there is an element within enumeration B with the same index? I'd have hoped it would have compared the actual enumeration values.

Perhaps this is working as intended, but the docs really could be a bit more verbose in places...

This is on debian sid:

$ dpkg -l | grep -i minizinc
ii  minizinc                                      2.8.3+dfsg1-1                                                 amd64        constraint modelling language and tool chain
ii  minizinc-ide                                  2.8.2-1+b1                                                    amd64        MiniZinc constraint modelling language IDE
Dekker1 commented 3 months ago
to_enum(W, 1) in A
to_enum(W, 1) in B

Both of these are incorrect from a type perspective since the first compares where a W element is part of a set of A and the latter whether it is part of a set of B.

Both should have shown an type error, but current work because the definition of in currently just always converts to int/set of int. We will change the definitions to actually perform the correct type checking.

LebedevRI commented 3 months ago

Also, is it intentional that it's possible to to_enum() where the "enum" is actually a set?

enum A = A(1..2);
set of A: B = { to_enum(A, c) | c in 1..2 };
set of A: C = { to_enum(B, c) | c in 1..2 };