@@ -423,6 +423,20 @@ std::string ValidateIntDivConstraint(const CpModelProto& model,
423423 return " " ;
424424}
425425
426+ void AppendToOverflowValidator (const LinearExpressionProto& input,
427+ LinearExpressionProto* output,
428+ int64_t prod = 1 ) {
429+ output->mutable_vars ()->Add (input.vars ().begin (), input.vars ().end ());
430+ for (const int64_t coeff : input.coeffs ()) {
431+ output->add_coeffs (coeff * prod);
432+ }
433+
434+ // We add the absolute value to be sure that future computation will not
435+ // overflow depending on the order they are performed in.
436+ output->set_offset (
437+ CapAdd (std::abs (output->offset ()), std::abs (input.offset ())));
438+ }
439+
426440std::string ValidateElementConstraint (const CpModelProto& model,
427441 const ConstraintProto& ct) {
428442 const ElementConstraintProto& element = ct.element ();
@@ -484,10 +498,7 @@ std::string ValidateElementConstraint(const CpModelProto& model,
484498 for (const LinearExpressionProto& expr : element.exprs ()) {
485499 RETURN_IF_NOT_EMPTY (ValidateAffineExpression (model, expr));
486500 LinearExpressionProto overflow_detection = ct.element ().linear_target ();
487- for (int i = 0 ; i < expr.vars_size (); ++i) {
488- overflow_detection.add_vars (expr.vars (i));
489- overflow_detection.add_coeffs (-expr.coeffs (i));
490- }
501+ AppendToOverflowValidator (expr, &overflow_detection, -1 );
491502 overflow_detection.set_offset (overflow_detection.offset () -
492503 expr.offset ());
493504 if (PossibleIntegerOverflow (model, overflow_detection.vars (),
@@ -647,17 +658,6 @@ std::string ValidateRoutesConstraint(const ConstraintProto& ct) {
647658 return ValidateGraphInput (/* is_route=*/ true , ct.routes ());
648659}
649660
650- void AppendToOverflowValidator (const LinearExpressionProto& input,
651- LinearExpressionProto* output) {
652- output->mutable_vars ()->Add (input.vars ().begin (), input.vars ().end ());
653- output->mutable_coeffs ()->Add (input.coeffs ().begin (), input.coeffs ().end ());
654-
655- // We add the absolute value to be sure that future computation will not
656- // overflow depending on the order they are performed in.
657- output->set_offset (
658- CapAdd (std::abs (output->offset ()), std::abs (input.offset ())));
659- }
660-
661661std::string ValidateIntervalConstraint (const CpModelProto& model,
662662 const ConstraintProto& ct) {
663663 if (ct.enforcement_literal ().size () > 1 ) {
@@ -705,7 +705,7 @@ std::string ValidateIntervalConstraint(const CpModelProto& model,
705705 " variable are currently not supported." ;
706706 }
707707 RETURN_IF_NOT_EMPTY (ValidateLinearExpression (model, arg.end ()));
708- AppendToOverflowValidator (arg.end (), &for_overflow_validation);
708+ AppendToOverflowValidator (arg.end (), &for_overflow_validation, - 1 );
709709
710710 if (PossibleIntegerOverflow (model, for_overflow_validation.vars (),
711711 for_overflow_validation.coeffs (),
@@ -1484,6 +1484,7 @@ class ConstraintChecker {
14841484 bool CumulativeConstraintIsFeasible (const CpModelProto& model,
14851485 const ConstraintProto& ct) {
14861486 const int64_t capacity = LinearExpressionValue (ct.cumulative ().capacity ());
1487+ if (capacity < 0 ) return false ;
14871488 const int num_intervals = ct.cumulative ().intervals_size ();
14881489 std::vector<std::pair<int64_t , int64_t >> events;
14891490 for (int i = 0 ; i < num_intervals; ++i) {
0 commit comments