Type Error with disjunctive Constraint in MiniZinc: How to Fix?

37 views
Skip to first unread message

Robin Lu

unread,
Jun 2, 2025, 10:52:59 PM6/2/25
to MiniZinc
'm trying to model a truck scheduling problem in MiniZinc where each truck can't have overlapping services. I have two constraints that should achieve this, but one works and the other doesn't.

Working Constraint
constraint forall(t in TRUCK where t != dtruck) ( forall(s1, s2 in assignment[t] where s1 < s2) ( end[s1] <= start[s2] \/ end[s2] <= start[s1] ) );
Error Constraint:
But when I try to use the disjunctive global constraint instead,

constraint forall(t in TRUCK where t != dtruck) ( disjunctive ( [ start[s] | s in assignment[t] ], [ end[s] - start[s] | s in assignment[t] ] ) );

 I get a type error: 
Error: type error: no function or predicate with this signature found: `disjunctive(array[int] of var opt int,array[int] of var opt int)' Cannot use the following functions or predicates with the same identifier: predicate disjunctive(array [$$T] of var int: s,array [$$T] of var int: d); (argument 1 expects type array[int] of var int, but type array[int] of var opt int given) (argument 2 expects type array[int] of var int, but type array[int] of var opt int given) predicate disjunctive(array [$$T] of var opt int: s,array [$$T] of var int: d); (argument 2 expects type array[int] of var int, but type array[int] of var opt int given)

I have tried  different array constructions for the disjunctive arguments, but did not get it work.  How can I fix it by generate the parameter for disjunctive correctlyAny help would be greatly appreciated!

The related code is attached for your infomation.

Thank you! 
Robin Lu
++++++++ ++++ +++++++++


int: endtime; % latest time to be scheduled set of int: TIME = 0..endtime;
enum SERVICE; % services to be scheduled array[SERVICE] of TIME: start; % start time of service array[SERVICE] of TIME: end; % end time of service

enum TRUCK; % truck TRUCK: dtruck; % dummy truck array[SERVICE] of var TRUCK: truck; % which truck takes each service: dtruck if none


%% endtime = 15; SERVICE = { S1, S2, S3, S4, S5, S6, S7, S8, S9, S10 }; start = [0, 0, 0, 7, 3, 5, 6, 10, 11, 12]; end = [4, 5, 3, 11, 5, 8, 9, 12, 13, 15]; TRUCK = { DD, T1, T2, T3, T4, T5 }; dtruck = DD; %%
include "globals.mzn";
array[TRUCK] of var set of SERVICE : assignment; constraint int_set_channel(truck,assignment);
constraint forall(t in TRUCK where t != dtruck) ( forall(s1, s2 in assignment[t] where s1 < s2) ( end[s1] <= start[s2] \/ end[s2] <= start[s1] ) );
constraint forall(t in TRUCK where t != dtruck) ( disjunctive ( [ start[s]| s in assignment[t]], [ end[s]-start[s]| s in assignment[t]] ) );
solve satisfy;





Erik

unread,
Jun 10, 2025, 9:38:25 AM6/10/25
to MiniZinc
The issue is that disjunctive doesn't support var opt for the 2nd argument.
Probably caused by the fact you are using var set of SERVICE in assignment.

As a general rule, it's advisable to avoid using var set for performance reasons.

Robin Lu

unread,
Jun 13, 2025, 3:50:30 AM6/13/25
to MiniZinc
please ignore my question above. I managed to get a solution/ workaround. 

constraint forall(t in TRUCK where t != dtruck) (  disjunctive( 
 [ if s in assignment[t] then start[s] else 0 endif | s in SERVICE], 
 [ if s in assignment[t] then end[s] - start[s] else 0 endif | s in SERVICE]  ));

or 

constraint forall(t in TRUCK where t != dtruck)
( let { array[int] of var opt int: filtered_start = 
[start[s] | s in SERVICE where truck[s] == t],
array[int] of var int: filtered_dur = 
[end[s] - start[s] | s in SERVICE ]
in 
if length(filtered_start) > 0 
then disjunctive(filtered_start, filtered_dur)
else true 
endif

Robin Lu

unread,
Jun 13, 2025, 3:50:34 AM6/13/25
to MiniZinc
Thanks a lot for your reply.  
I also find a workaround  by creating a array of var opt so that it can call disjunctive directly. 


array[SERVICE] of var TIME: duration;constraint forall(s in SERVICE) (duration[s] = end[s] - start[s]);
array[SERVICE, TRUCK] of var opt TIME: O;
constraint forall( t in TRUCK) ( card(assignment[t])>0 -> forall( s in assignment[t]) ( O[s,t] = start[s]));
constraint forall(t in TRUCK) ( disjunctive([O[s,t] | s in SERVICE], [duration[s] | s in SERVICE]));

Erik

unread,
Jun 16, 2025, 5:39:59 AM6/16/25
to MiniZinc
Glad you figured out a work-around.
Be advised that using a set approach like this will probably not scale with good performance
Reply all
Reply to author
Forward
0 new messages