Hi everybody, I'm using CPLEX Optimization Studio 12.6 x64 on Windows 8.1 x64 and I noticed a strange behavior using the *all* syntax over arrays indexed by tuples.

Consider the following constraint model:

using CP;

range T = 0..4;

tuple Task {

key string id;

int duration;

}

tuple TaskExecution {

Task task;

int execution;

}

tuple TaskExecutionIndex {

TaskExecution task_execution;

int index;

}

{Task} J = {<"j0",2>, <"j1",3>};

{TaskExecution} A = {<j,x> | j in J, x in 0..0};

{TaskExecutionIndex} AP = {<a,p> | a in A, p in 0..a.task.duration-1};

dvar int task_executions[j in J] in T;

dvar int active[ap in AP] in T;

dexpr int active_task[j in J, t in T] = count(all(x in 0..task_executions[j]-1, p in 0..j.duration-1) active[<<j,x>,p>], t);

dexpr int load[t in T] = sum(j in J) active_task[j, t];

subject to{

forall(t in T)

c1: load[t] <= 1;

c2: active[<<<"j0",2>,0>,0>] == 0;

c3: active[<<<"j0",2>,0>,1>] == 1;

c4: active[<<<"j1",3>,0>,0>] == 0;

c5: active[<<<"j1",3>,0>,1>] == 3;

c6: active[<<<"j1",3>,0>,2>] == 4;

c7: task_executions[<"j0",2>] == 1;

c8: task_executions[<"j1",3>] == 1;

}

The constraints *c1-c8* are used in this example to assign some values to the variables *active* and *task_executions*. Clearly, *load[0] == 2* in contrast with the constraint *c1*, but still the problem is deemed feasible by CP. This also happens if I explicitly state that *load[0]* should be equal to *2*, for instance by adding a last line in the *subject to* block: *c9: load[0] == 2;*. It's like CP is ignoring the constraints where *load* is present.

Moreover, if I remove the constraints *c2-c8* and replace *c1*:*load[t] <= 1* with *c1: load[t] == 1*, CP deems that the problem is infeasible, while it clearly is feasible. For instance, a solution has the following assignments:

c2: active[<<<"j0",2>,0>,0>] == 0;

c3: active[<<<"j0",2>,0>,1>] == 1;

c4: active[<<<"j1",3>,0>,0>] == 2;

c5: active[<<<"j1",3>,0>,1>] == 3;

c6: active[<<<"j1",3>,0>,2>] == 4;

c7: task_executions[<"j0",2>] == 1;

c8: task_executions[<"j1",3>] == 1;

Indeed, if once again I remove *c1: load[t] == 1* and keep these new *c2-c8*, I get the expected solution where *load = [1,1,1,1,1]*, that clearly respects *c1.* Again, here it looks like CP deems unfeasible every problem with an equality constraint on the dexpr *load.*

What is going on here? I guess there's something big that I'm missing on how count/all works in dexprs.

Regards,

Stefano