include "globals.mzn";
int: n; % number of tasks
int: m; % number of resources
array [1..m] of int: c; % resource capacities
array [1..n] of int: d; % durations
array [1..n,1..m] of int: r; % resource requirements
array [1..n] of set of int: succ; % The task successors
array [1..n] of var 0..10000: s; % start times
var int: objective;
constraint forall (i in 1..n, j in succ[i]) (s[i] + d[i] <= s[j]);
constraint forall (i in 1..n) (s[i] + d[i] <= objective);
constraint forall (i in 1..m) (cumulative(s, d, [r[j,i] | j in 1..n], c[i]));
% Dominance breaking constraints
constraint forall (i in 1..n) (
let { var int: t } in
element(t, [0] ++ [s[j] + d[j] | j in 1..n where
i in succ[j] \/ exists (k in 1..m) (r[i,k] >= 0 /\ r[j,k] >= 0)], s[i])
);
solve minimize objective;