I'm developing a Minizinc model and I ran into this issue: given this model
enum req_type = {roads, rivers};
enum cities = {city1, city2, city3}
array[cities, cities] of var bool: are_connected; % true if cities are connected, false otherwise
array[cities, req_type] of var 0..1000: requests;
array[cities, req_type] of var 0..1000: approved_requests;
i want to model the following constraint: if two cities are connected by a road and they both make a request for roads, then the request is approved to only one of the two cities; otherwise, it is approved to both.
I've tried to model this constraint as follows:
constraint
forall(i,j in cities where i != j) (
if are_connected[i,j]
then
approved_requests[i, roads] = requests[i, roads] /\ approved_requests[j, roads] = 0 \/
approved_requests[j, roads] = requests[j, roads] /\ approved_requests[i, roads] = 0
else
approved_requests[i, roads] = requests[i, roads] /\ approved_requests[j, roads] = requests[j, roads]
endif
);
When i provide an are_connected which contains true values I get the following warning, and the model is unsatisfiable.
Warning: model inconsistency detected
...
in call 'forall'
in array comprehension expression
with i = 2
with j = 4
...
in if-then-else expression
...
in binary '\/' operator expression
=====UNSATISFIABLE=====
% time elapsed: 0.07 s
An example of are_connected that causes this problem is the following:
are_connected = [|
false, false, false, false |
false, false, false, true |
false, false, false, false |
false, true, false, false |
|];
How can I solve this issue or reformulate the constraint? Thank you!
EDIT: I noticed I was using OR but what I'm really trying to achieve is exclusive OR: only one OR the other request can be different than zero.
I figured it out. Let's take this adjacency matrix for the cities
c1, c2, c3:With the previous constraints, we would have the following combination of cities to be tested:
In this case, since
c1, c2are connected, the solver might assign the value ofrequest[c1, roads]toapproved[c1, roads], and 0 toapproved[c2, roads]. When evaluating the pairc2, c3, theelsebranch will try to set bothapproved[c1, roads], approved[c2, roads]values to the respectiverequestvalue, but since we previously said thatapproved[c2, roads]= 0we get the inconsistency.The following constraints solve the issue:
I think these constraints can be simplified further but this change solved the issue.