@@ -5909,6 +5909,39 @@ bool CpModelPresolver::PresolveNoOverlap(ConstraintProto* ct) {
59095909 }
59105910 }
59115911
5912+ {
5913+ // Special case for "all-diff" encoded as no-overlap.
5914+ int num_size_zero_or_one = 0;
5915+ for (const int index : proto->intervals()) {
5916+ const IntervalConstraintProto& interval =
5917+ context_->working_model->constraints(index).interval();
5918+ const LinearExpressionProto& size = interval.size();
5919+ if (size.vars().empty() && size.offset() >= 0 && size.offset() <= 1) {
5920+ ++num_size_zero_or_one;
5921+ } else {
5922+ break; // early abort
5923+ }
5924+ }
5925+ const int initial_num_intervals = proto->intervals().size();
5926+ if (num_size_zero_or_one == initial_num_intervals) {
5927+ // If there is only size one, we can remove the size zero as there is
5928+ // no constraint on them.
5929+ int new_size = 0;
5930+ for (const int index : proto->intervals()) {
5931+ const IntervalConstraintProto& interval =
5932+ context_->working_model->constraints(index).interval();
5933+ if (interval.size().offset() == 0) continue;
5934+ proto->set_intervals(new_size++, index);
5935+ }
5936+ if (new_size < initial_num_intervals) {
5937+ proto->mutable_intervals()->Truncate(new_size);
5938+ changed = true;
5939+ context_->UpdateRuleStats("no_overlap: removed size 0 from all diff.");
5940+ }
5941+ context_->UpdateRuleStats("TODO no_overlap: only size one !");
5942+ }
5943+ }
5944+
59125945 if (proto->intervals_size() == 1) {
59135946 context_->UpdateRuleStats("no_overlap: only one interval");
59145947 return RemoveConstraint(ct);
0 commit comments