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

35 views
Skip to first unread message

Robin Lu

unread,
Jun 2, 2025, 10:52:59 PMJun 2
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 AMJun 10
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 AMJun 13
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 AMJun 13
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 AMJun 16
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