40 const std::function<int64_t(
Variable*)>& evaluator) {
46 return evaluator(arg.
Var());
49 LOG(FATAL) <<
"Cannot evaluate " << arg.
DebugString();
59int64_t EvalAt(
const Argument& arg,
int pos,
60 const std::function<int64_t(
Variable*)>& evaluator) {
66 return evaluator(arg.
VarAt(pos));
69 LOG(FATAL) <<
"Cannot evaluate " << arg.
DebugString();
75std::vector<int64_t> SetEval(
77 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
83 std::vector<int64_t> result;
85 for (int64_t i = arg.
values[0]; i <= arg.
values[1]; ++i) {
94 return set_evaluator(arg.
Var());
97 LOG(FATAL) <<
"Cannot evaluate " << arg.
DebugString();
103std::vector<int64_t> SetEvalAt(
105 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
109 if (domain.
empty()) {
112 std::vector<int64_t> result;
113 result.reserve(domain.
Max() - domain.
Min() + 1);
114 for (int64_t i = domain.
Min(); i <= domain.
Max(); ++i) {
123 return set_evaluator(arg.
variables[pos]);
126 LOG(FATAL) <<
"Cannot evaluate " << arg.
DebugString();
134 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
146 return set_evaluator(arg.
Var()).size();
149 LOG(FATAL) <<
"Cannot get the size of " << arg.
DebugString();
157bool CheckAllDifferentInt(
159 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
160 absl::flat_hash_set<int64_t> visited;
161 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
162 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator);
163 if (visited.contains(value)) {
166 visited.insert(value);
172bool CheckAllDifferentSet(
174 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
175 std::vector<std::vector<int64_t>> values;
177 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
178 values.push_back(SetEvalAt(ct.
arguments[0], i, set_evaluator));
180 for (
int i = 0; i + 1 < values.size(); ++i) {
181 for (
int j = i + 1; j < values.size(); ++j) {
182 if (values[i] == values[j]) {
190bool CheckAlldifferentExcept0(
192 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
193 absl::flat_hash_set<int64_t> visited;
194 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
195 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator);
196 if (value != 0 && visited.contains(value)) {
199 visited.insert(value);
205bool CheckAllDisjoint(
207 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
208 absl::flat_hash_set<int64_t> visited;
209 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
210 for (
const int64_t value : SetEvalAt(ct.
arguments[0], i, set_evaluator)) {
211 if (visited.contains(value)) {
214 visited.insert(value);
222 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
223 const int64_t expected = Eval(ct.
arguments[0], evaluator);
225 for (
int i = 0; i < Length(ct.
arguments[1]); ++i) {
226 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator);
227 count += ct.
arguments[2].Contains(value);
230 return count == expected;
233bool CheckArrayBoolAnd(
235 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
238 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
239 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator);
240 result = std::min(result, value);
243 return result == Eval(ct.
arguments[1], evaluator);
246bool CheckArrayBoolOr(
248 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
251 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
252 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator);
253 result = std::max(result, value);
256 return result == Eval(ct.
arguments[1], evaluator);
259bool CheckArrayBoolXor(
261 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
264 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
265 result += EvalAt(ct.
arguments[0], i, evaluator);
268 return result % 2 == 1;
271bool CheckArrayIntElement(
273 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
275 const int64_t shifted_index = Eval(ct.
arguments[0], evaluator) - 1;
276 const int64_t element = EvalAt(ct.
arguments[1], shifted_index, evaluator);
277 const int64_t target = Eval(ct.
arguments[2], evaluator);
278 return element == target;
281bool CheckArrayIntElementNonShifted(
283 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
284 CHECK_EQ(ct.
arguments[0].variables.size(), 1);
285 const int64_t index = Eval(ct.
arguments[0], evaluator);
286 const int64_t element = EvalAt(ct.
arguments[1], index, evaluator);
287 const int64_t target = Eval(ct.
arguments[2], evaluator);
288 return element == target;
291bool CheckArrayVarIntElement(
293 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
295 const int64_t shifted_index = Eval(ct.
arguments[0], evaluator) - 1;
296 const int64_t element = EvalAt(ct.
arguments[1], shifted_index, evaluator);
297 const int64_t target = Eval(ct.
arguments[2], evaluator);
298 return element == target;
301bool CheckOrToolsArgMaxInt(
303 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
304 const int rank = evaluator(ct.
arguments[1].Var());
305 const int min_index = ct.
arguments[2].Value();
306 const int multiplier = ct.
arguments[3].Value();
308 int64_t max_value = std::numeric_limits<int64_t>::min();
309 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
310 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator) * multiplier;
311 if (value > max_value) {
316 return index + min_index == rank;
319bool CheckOrToolsArrayIntElement(
321 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
322 const int64_t min_index = ct.
arguments[1].values[0];
323 const int64_t index = Eval(ct.
arguments[0], evaluator) - min_index;
324 const int64_t element = EvalAt(ct.
arguments[2], index, evaluator);
325 const int64_t target = Eval(ct.
arguments[3], evaluator);
326 return element == target;
331 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
332 const int64_t expected = Eval(ct.
arguments[0], evaluator);
333 const int64_t value = Eval(ct.
arguments[2], evaluator);
336 for (
int i = 0; i < Length(ct.
arguments[1]); ++i) {
337 count += EvalAt(ct.
arguments[1], i, evaluator) == value;
339 return count <= expected;
344 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
345 const int64_t left = Eval(ct.
arguments[0], evaluator);
346 const int64_t right = Eval(ct.
arguments[1], evaluator);
347 const int64_t status = Eval(ct.
arguments[2], evaluator);
348 return status == std::min(left, right);
353 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
357 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
358 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator);
359 result = std::max(result, value);
362 for (
int i = 0; i < Length(ct.
arguments[1]); ++i) {
363 const int64_t value = EvalAt(ct.
arguments[1], i, evaluator);
364 result = std::max(result, 1 - value);
372 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
373 const int64_t left = Eval(ct.
arguments[0], evaluator);
374 const int64_t right = Eval(ct.
arguments[1], evaluator);
375 return left == 1 - right;
380 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
381 const int64_t left = Eval(ct.
arguments[0], evaluator);
382 const int64_t right = Eval(ct.
arguments[1], evaluator);
383 const int64_t status = Eval(ct.
arguments[2], evaluator);
384 return status == std::max(left, right);
389 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
390 const int64_t left = Eval(ct.
arguments[0], evaluator);
391 const int64_t right = Eval(ct.
arguments[1], evaluator);
392 const int64_t target = Eval(ct.
arguments[2], evaluator);
393 return target == (left + right == 1);
398 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
399 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
400 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
401 std::vector<int64_t> computed_intersection;
402 std::set_intersection(values_x.begin(), values_x.end(), values_y.begin(),
404 std::back_inserter(computed_intersection));
405 return computed_intersection.empty();
408bool CheckOrToolsCircuit(
410 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
411 const int size = Length(ct.
arguments[0]);
414 absl::flat_hash_set<int64_t> visited;
416 for (
int i = 0; i < size; ++i) {
417 const int64_t next = EvalAt(ct.
arguments[0], current, evaluator) -
base;
418 visited.insert(next);
421 return visited.size() == size;
424bool CheckOrToolsBinPacking(
426 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
427 const int64_t capacity = ct.
arguments[0].Value();
428 const int num_positions = Length(ct.
arguments[1]);
429 const std::vector<int64_t>& weights = ct.
arguments[2].values;
430 absl::flat_hash_map<int64_t, int64_t> loads;
431 for (
int i = 0; i < num_positions; ++i) {
432 const int64_t selected_bin = EvalAt(ct.
arguments[1], i, evaluator);
433 loads[selected_bin] += weights[i];
435 for (
const auto& [pos, load] : loads) {
436 if (load > capacity) {
443bool CheckOrToolsBinPackingCapa(
445 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
446 const std::vector<int64_t>& capacities = ct.
arguments[0].values;
447 const int num_positions = Length(ct.
arguments[1]);
448 const int64_t first_bin = ct.
arguments[2].values[0];
449 const int64_t last_bin = ct.
arguments[2].values[1];
450 const std::vector<int64_t>& weights = ct.
arguments[3].values;
451 std::vector<int64_t> actual_loads(last_bin - first_bin + 1, 0);
452 for (
int i = 0; i < num_positions; ++i) {
453 const int64_t selected_bin = EvalAt(ct.
arguments[1], i, evaluator);
454 actual_loads[selected_bin - first_bin] += weights[i];
456 for (
int i = first_bin; i <= last_bin; ++i) {
457 if (actual_loads[i - first_bin] > capacities[i - first_bin]) {
464bool CheckOrToolsBinPackingLoad(
466 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
467 const int num_positions = Length(ct.
arguments[1]);
468 const int64_t first_bin = ct.
arguments[2].values[0];
469 const int64_t last_bin = ct.
arguments[2].values[1];
470 const std::vector<int64_t>& weights = ct.
arguments[3].values;
471 std::vector<int64_t> actual_loads(last_bin - first_bin + 1, 0);
472 for (
int p = 0; p < num_positions; ++p) {
473 const int64_t pos = EvalAt(ct.
arguments[1], p, evaluator);
474 actual_loads[pos - first_bin] += weights[p];
476 for (
int b = first_bin; b <= last_bin; ++b) {
477 const int64_t expected_load =
478 EvalAt(ct.
arguments[0], b - first_bin, evaluator);
479 if (actual_loads[b - first_bin] != expected_load) {
486bool CheckOrToolsNValue(
488 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
489 const int64_t card = Eval(ct.
arguments[0], evaluator);
490 absl::flat_hash_set<int64_t> values;
491 for (
int i = 0; i < Length(ct.
arguments[1]); ++i) {
492 values.insert(EvalAt(ct.
arguments[1], i, evaluator));
494 return card == values.size();
498 const std::function<int64_t(
Variable*)>& evaluator) {
500 const int64_t value = Eval(ct.
arguments[1], evaluator);
501 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
502 result += EvalAt(ct.
arguments[0], i, evaluator) == value;
507bool CheckOrToolsCountEq(
509 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
510 const int64_t count = ComputeCount(ct, evaluator);
511 const int64_t expected = Eval(ct.
arguments[2], evaluator);
512 return count == expected;
517 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
518 const int64_t count = ComputeCount(ct, evaluator);
519 const int64_t expected = Eval(ct.
arguments[2], evaluator);
520 return count >= expected;
525 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
526 const int64_t count = ComputeCount(ct, evaluator);
527 const int64_t expected = Eval(ct.
arguments[2], evaluator);
528 return count > expected;
533 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
534 const int64_t count = ComputeCount(ct, evaluator);
535 const int64_t expected = Eval(ct.
arguments[2], evaluator);
536 return count <= expected;
541 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
542 const int64_t count = ComputeCount(ct, evaluator);
543 const int64_t expected = Eval(ct.
arguments[2], evaluator);
544 return count < expected;
549 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
550 const int64_t count = ComputeCount(ct, evaluator);
551 const int64_t expected = Eval(ct.
arguments[2], evaluator);
552 return count != expected;
557 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
558 const int64_t count = ComputeCount(ct, evaluator);
559 const int64_t expected = Eval(ct.
arguments[2], evaluator);
560 const int64_t status = Eval(ct.
arguments[3], evaluator);
561 return status == (expected == count);
566 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
568 const int64_t capacity = Eval(ct.
arguments[3], evaluator);
569 const int size = Length(ct.
arguments[0]);
572 absl::flat_hash_map<int64_t, int64_t> usage;
573 for (
int i = 0; i < size; ++i) {
574 const int64_t start = EvalAt(ct.
arguments[0], i, evaluator);
575 const int64_t duration = EvalAt(ct.
arguments[1], i, evaluator);
576 const int64_t requirement = EvalAt(ct.
arguments[2], i, evaluator);
577 for (int64_t t = start; t < start + duration; ++t) {
578 usage[t] += requirement;
579 if (usage[t] > capacity) {
587bool CheckOrToolsCumulativeOpt(
589 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
591 const int64_t capacity = Eval(ct.
arguments[4], evaluator);
592 const int size = Length(ct.
arguments[0]);
596 absl::flat_hash_map<int64_t, int64_t> usage;
597 for (
int i = 0; i < size; ++i) {
598 if (EvalAt(ct.
arguments[0], i, evaluator) == 0)
continue;
599 const int64_t start = EvalAt(ct.
arguments[1], i, evaluator);
600 const int64_t duration = EvalAt(ct.
arguments[2], i, evaluator);
601 const int64_t requirement = EvalAt(ct.
arguments[3], i, evaluator);
602 for (int64_t t = start; t < start + duration; ++t) {
603 usage[t] += requirement;
604 if (usage[t] > capacity) {
614 const std::function<int64_t(
Variable*)>& ,
615 const std::function<std::vector<int64_t>(
Variable*)>& ) {
621 const std::function<int64_t(
Variable*)>& ,
622 const std::function<std::vector<int64_t>(
Variable*)>& ) {
626bool CheckDiffnNonStrict(
628 const std::function<int64_t(
Variable*)>& ,
629 const std::function<std::vector<int64_t>(
Variable*)>& ) {
633bool CheckDiffnNonStrictK(
635 const std::function<int64_t(
Variable*)>& ,
636 const std::function<std::vector<int64_t>(
Variable*)>& ) {
640bool CheckDisjunctive(
642 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
643 const int size = Length(ct.
arguments[0]);
645 std::vector<std::pair<int64_t, int64_t>> start_durations_pairs;
646 start_durations_pairs.reserve(size);
647 for (
int i = 0; i + 1 < size; ++i) {
648 const int64_t duration = EvalAt(ct.
arguments[1], i, evaluator);
649 if (duration == 0)
continue;
650 const int64_t start = EvalAt(ct.
arguments[0], i, evaluator);
651 start_durations_pairs.push_back({start, duration});
653 std::sort(start_durations_pairs.begin(), start_durations_pairs.end());
654 int64_t previous_end = std::numeric_limits<int64_t>::min();
655 for (
const auto& pair : start_durations_pairs) {
656 if (pair.first < previous_end)
return false;
657 previous_end = pair.first + pair.second;
662bool CheckDisjunctiveStrict(
664 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
665 const int size = Length(ct.
arguments[0]);
667 std::vector<std::pair<int64_t, int64_t>> start_durations_pairs;
668 start_durations_pairs.reserve(size);
669 for (
int i = 0; i + 1 < size; ++i) {
670 const int64_t start = EvalAt(ct.
arguments[0], i, evaluator);
671 const int64_t duration = EvalAt(ct.
arguments[1], i, evaluator);
672 start_durations_pairs.push_back({start, duration});
674 std::sort(start_durations_pairs.begin(), start_durations_pairs.end());
675 int64_t previous_end = std::numeric_limits<int64_t>::min();
676 for (
const auto& pair : start_durations_pairs) {
677 if (pair.first < previous_end)
return false;
678 previous_end = pair.first + pair.second;
683bool CheckOrToolsDisjunctiveStrictOpt(
685 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
686 const int size = Length(ct.
arguments[0]);
689 std::vector<std::pair<int64_t, int64_t>> start_durations_pairs;
690 start_durations_pairs.reserve(size);
691 for (
int i = 0; i + 1 < size; ++i) {
692 if (EvalAt(ct.
arguments[0], i, evaluator) == 0)
continue;
693 const int64_t start = EvalAt(ct.
arguments[1], i, evaluator);
694 const int64_t duration = EvalAt(ct.
arguments[2], i, evaluator);
695 start_durations_pairs.push_back({start, duration});
697 std::sort(start_durations_pairs.begin(), start_durations_pairs.end());
698 int64_t previous_end = std::numeric_limits<int64_t>::min();
699 for (
const auto& pair : start_durations_pairs) {
700 if (pair.first < previous_end)
return false;
701 previous_end = pair.first + pair.second;
706bool CheckPartitionSet(
708 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
709 absl::flat_hash_set<int64_t> visited;
710 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
711 for (
const int64_t value : SetEvalAt(ct.
arguments[0], i, set_evaluator)) {
712 if (visited.contains(value)) {
715 visited.insert(value);
718 const std::vector<int64_t> universe = SetEval(ct.
arguments[1], set_evaluator);
719 if (universe.size() != visited.size())
return false;
720 for (
const int64_t value : universe) {
721 if (!visited.contains(value)) {
729bool CheckFalseConstraint(
731 const std::function<int64_t(
Variable*)>& ,
732 const std::function<std::vector<int64_t>(
Variable*)>& ) {
736std::vector<int64_t> ComputeGlobalCardinalityCards(
738 std::vector<int64_t> cards(Length(ct.
arguments[1]), 0);
739 absl::flat_hash_map<int64_t, int> positions;
740 for (
int i = 0; i < ct.
arguments[1].values.size(); ++i) {
741 const int64_t value = ct.
arguments[1].values[i];
742 CHECK(!positions.contains(value));
743 positions[value] = i;
745 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
746 const int value = EvalAt(ct.
arguments[0], i, evaluator);
747 if (positions.contains(value)) {
748 cards[positions[value]]++;
754bool CheckOrToolsGlobalCardinality(
756 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
757 const std::vector<int64_t> cards =
758 ComputeGlobalCardinalityCards(ct, evaluator);
759 CHECK_EQ(cards.size(), Length(ct.
arguments[2]));
760 const bool is_closed = Eval(ct.
arguments[3], evaluator) != 0;
761 for (
int i = 0; i < Length(ct.
arguments[2]); ++i) {
762 const int64_t card = EvalAt(ct.
arguments[2], i, evaluator);
763 if (card != cards[i]) {
769 int64_t sum_of_cards = 0;
770 for (int64_t card : cards) {
771 sum_of_cards += card;
773 return sum_of_cards == Length(ct.
arguments[0]);
778bool CheckOrToolsGlobalCardinalityLowUp(
780 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
781 const std::vector<int64_t> cards =
782 ComputeGlobalCardinalityCards(ct, evaluator);
783 CHECK_EQ(cards.size(), ct.
arguments[2].values.size());
784 CHECK_EQ(cards.size(), ct.
arguments[3].values.size());
785 const bool is_closed = Eval(ct.
arguments[4], evaluator) != 0;
786 for (
int i = 0; i < cards.size(); ++i) {
787 const int64_t card = cards[i];
794 int64_t sum_of_cards = 0;
795 for (int64_t card : cards) {
796 sum_of_cards += card;
798 return sum_of_cards == Length(ct.
arguments[0]);
805 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
806 const int64_t left = Eval(ct.
arguments[0], evaluator);
807 const int64_t right = Eval(ct.
arguments[1], evaluator);
808 return std::abs(left) == right;
813 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
814 const int64_t left = Eval(ct.
arguments[0], evaluator);
815 const int64_t right = Eval(ct.
arguments[1], evaluator);
816 const int64_t target = Eval(ct.
arguments[2], evaluator);
817 return target == left / right;
822 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
823 const int64_t left = Eval(ct.
arguments[0], evaluator);
824 const int64_t right = Eval(ct.
arguments[1], evaluator);
825 return left == right;
830 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
831 const int64_t left = Eval(ct.
arguments[0], evaluator);
832 const int64_t right = Eval(ct.
arguments[1], evaluator);
833 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
834 return (status && (left == right)) || !status;
839 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
840 const int64_t left = Eval(ct.
arguments[0], evaluator);
841 const int64_t right = Eval(ct.
arguments[1], evaluator);
842 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
843 return status == (left == right);
848 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
849 const int64_t left = Eval(ct.
arguments[0], evaluator);
850 const int64_t right = Eval(ct.
arguments[1], evaluator);
851 return left >= right;
856 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
857 const int64_t left = Eval(ct.
arguments[0], evaluator);
858 const int64_t right = Eval(ct.
arguments[1], evaluator);
859 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
860 return (status && (left >= right)) || !status;
865 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
866 const int64_t left = Eval(ct.
arguments[0], evaluator);
867 const int64_t right = Eval(ct.
arguments[1], evaluator);
868 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
869 return status == (left >= right);
874 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
875 const int64_t left = Eval(ct.
arguments[0], evaluator);
876 const int64_t right = Eval(ct.
arguments[1], evaluator);
882 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
883 const int64_t left = Eval(ct.
arguments[0], evaluator);
884 const int64_t right = Eval(ct.
arguments[1], evaluator);
885 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
886 return (status && (left > right)) || !status;
891 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
892 const int64_t left = Eval(ct.
arguments[0], evaluator);
893 const int64_t right = Eval(ct.
arguments[1], evaluator);
894 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
895 return status == (left > right);
900 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
901 const int64_t left = Eval(ct.
arguments[0], evaluator);
902 const int64_t right = Eval(ct.
arguments[1], evaluator);
903 return left <= right;
908 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
909 const int64_t left = Eval(ct.
arguments[0], evaluator);
910 const int64_t right = Eval(ct.
arguments[1], evaluator);
911 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
912 return (status && (left <= right)) || !status;
917 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
918 const int64_t left = Eval(ct.
arguments[0], evaluator);
919 const int64_t right = Eval(ct.
arguments[1], evaluator);
920 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
921 return status == (left <= right);
926 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
927 const int64_t left = Eval(ct.
arguments[0], evaluator);
928 const int64_t right = Eval(ct.
arguments[1], evaluator);
934 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
935 const int64_t left = Eval(ct.
arguments[0], evaluator);
936 const int64_t right = Eval(ct.
arguments[1], evaluator);
937 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
938 return (status && (left < right)) || !status;
943 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
944 const int64_t left = Eval(ct.
arguments[0], evaluator);
945 const int64_t right = Eval(ct.
arguments[1], evaluator);
946 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
947 return status == (left < right);
951 const std::function<int64_t(
Variable*)>& evaluator) {
953 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
954 result += EvalAt(ct.
arguments[0], i, evaluator) *
962 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
963 const int64_t left = ComputeIntLin(ct, evaluator);
964 const int64_t right = Eval(ct.
arguments[2], evaluator);
965 return left == right;
968bool CheckIntLinEqImp(
970 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
971 const int64_t left = ComputeIntLin(ct, evaluator);
972 const int64_t right = Eval(ct.
arguments[2], evaluator);
973 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
974 return (status && (left == right)) || !status;
977bool CheckIntLinEqReif(
979 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
980 const int64_t left = ComputeIntLin(ct, evaluator);
981 const int64_t right = Eval(ct.
arguments[2], evaluator);
982 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
983 return status == (left == right);
988 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
989 const int64_t left = ComputeIntLin(ct, evaluator);
990 const int64_t right = Eval(ct.
arguments[2], evaluator);
991 return left >= right;
994bool CheckIntLinGeImp(
996 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
997 const int64_t left = ComputeIntLin(ct, evaluator);
998 const int64_t right = Eval(ct.
arguments[2], evaluator);
999 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
1000 return (status && (left >= right)) || !status;
1003bool CheckIntLinGeReif(
1005 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1006 const int64_t left = ComputeIntLin(ct, evaluator);
1007 const int64_t right = Eval(ct.
arguments[2], evaluator);
1008 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
1009 return status == (left >= right);
1014 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1015 const int64_t left = ComputeIntLin(ct, evaluator);
1016 const int64_t right = Eval(ct.
arguments[2], evaluator);
1017 return left <= right;
1020bool CheckIntLinLeImp(
1022 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1023 const int64_t left = ComputeIntLin(ct, evaluator);
1024 const int64_t right = Eval(ct.
arguments[2], evaluator);
1025 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
1026 return (status && (left <= right)) || !status;
1029bool CheckIntLinLeReif(
1031 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1032 const int64_t left = ComputeIntLin(ct, evaluator);
1033 const int64_t right = Eval(ct.
arguments[2], evaluator);
1034 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
1035 return status == (left <= right);
1040 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1041 const int64_t left = ComputeIntLin(ct, evaluator);
1042 const int64_t right = Eval(ct.
arguments[2], evaluator);
1043 return left != right;
1046bool CheckIntLinNeImp(
1048 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1049 const int64_t left = ComputeIntLin(ct, evaluator);
1050 const int64_t right = Eval(ct.
arguments[2], evaluator);
1051 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
1052 return (status && (left != right)) || !status;
1055bool CheckIntLinNeReif(
1057 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1058 const int64_t left = ComputeIntLin(ct, evaluator);
1059 const int64_t right = Eval(ct.
arguments[2], evaluator);
1060 const bool status = Eval(ct.
arguments[3], evaluator) != 0;
1061 return status == (left != right);
1066 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1067 const int64_t left = Eval(ct.
arguments[0], evaluator);
1068 const int64_t right = Eval(ct.
arguments[1], evaluator);
1069 const int64_t status = Eval(ct.
arguments[2], evaluator);
1070 return status == std::max(left, right);
1075 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1076 const int64_t left = Eval(ct.
arguments[0], evaluator);
1077 const int64_t right = Eval(ct.
arguments[1], evaluator);
1078 const int64_t status = Eval(ct.
arguments[2], evaluator);
1079 return status == std::min(left, right);
1084 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1085 const int64_t left = Eval(ct.
arguments[0], evaluator);
1086 const int64_t right = Eval(ct.
arguments[1], evaluator);
1087 const int64_t target = Eval(ct.
arguments[2], evaluator);
1088 return target == left - right;
1093 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1094 const int64_t left = Eval(ct.
arguments[0], evaluator);
1095 const int64_t right = Eval(ct.
arguments[1], evaluator);
1096 const int64_t target = Eval(ct.
arguments[2], evaluator);
1097 return target == left % right;
1102 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1103 const int64_t left = Eval(ct.
arguments[0], evaluator);
1104 const int64_t right = Eval(ct.
arguments[1], evaluator);
1105 return left != right;
1110 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1111 const int64_t left = Eval(ct.
arguments[0], evaluator);
1112 const int64_t right = Eval(ct.
arguments[1], evaluator);
1113 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1114 return (status && (left != right)) || !status;
1119 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1120 const int64_t left = Eval(ct.
arguments[0], evaluator);
1121 const int64_t right = Eval(ct.
arguments[1], evaluator);
1122 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1123 return status == (left != right);
1128 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1129 const int64_t left = Eval(ct.
arguments[0], evaluator);
1130 const int64_t right = Eval(ct.
arguments[1], evaluator);
1131 return left == -right;
1136 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1137 const int64_t left = Eval(ct.
arguments[0], evaluator);
1138 const int64_t right = Eval(ct.
arguments[1], evaluator);
1139 const int64_t target = Eval(ct.
arguments[2], evaluator);
1140 return target == left + right;
1145 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1146 const int64_t left = Eval(ct.
arguments[0], evaluator);
1147 const int64_t right = Eval(ct.
arguments[1], evaluator);
1148 const int64_t target = Eval(ct.
arguments[2], evaluator);
1149 return target == left * right;
1152bool CheckOrToolsInverse(
1154 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1156 const int size = Length(ct.
arguments[0]);
1157 const int f_base = ct.
arguments[2].Value();
1158 const int invf_base = ct.
arguments[3].Value();
1160 for (
int i = 0; i < size; ++i) {
1161 const int64_t x = EvalAt(ct.
arguments[0], i, evaluator) - invf_base;
1162 const int64_t y = EvalAt(ct.
arguments[1], i, evaluator) - f_base;
1163 if (x < 0 || x >= size || y < 0 || y >= size) {
1169 for (
int i = 0; i < size; ++i) {
1170 const int64_t fi = EvalAt(ct.
arguments[0], i, evaluator) - invf_base;
1171 const int64_t invf_fi = EvalAt(ct.
arguments[1], fi, evaluator) - f_base;
1180bool CheckOrToolsLexLessInt(
1182 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1183 const int min_size =
1185 for (
int i = 0; i < min_size; ++i) {
1186 const int64_t x = EvalAt(ct.
arguments[0], i, evaluator);
1187 const int64_t y = EvalAt(ct.
arguments[1], i, evaluator);
1199bool CheckOrToolsLexLesseqInt(
1201 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1202 const int min_size =
1204 for (
int i = 0; i < min_size; ++i) {
1205 const int64_t x = EvalAt(ct.
arguments[0], i, evaluator);
1206 const int64_t y = EvalAt(ct.
arguments[1], i, evaluator);
1218bool CheckMaximumArgInt(
1220 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1221 const int64_t max_index = Eval(ct.
arguments[1], evaluator) - 1;
1222 const int64_t max_value = EvalAt(ct.
arguments[0], max_index, evaluator);
1224 for (
int i = 0; i < max_index; ++i) {
1225 if (EvalAt(ct.
arguments[0], i, evaluator) >= max_value) {
1230 for (
int i = max_index + 1; i < Length(ct.
arguments[0]); i++) {
1231 if (EvalAt(ct.
arguments[0], i, evaluator) > max_value) {
1239bool CheckMaximumInt(
1241 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1242 int64_t max_value = std::numeric_limits<int64_t>::min();
1243 for (
int i = 0; i < Length(ct.
arguments[1]); ++i) {
1244 max_value = std::max(max_value, EvalAt(ct.
arguments[1], i, evaluator));
1246 return max_value == Eval(ct.
arguments[0], evaluator);
1249bool CheckMinimumArgInt(
1251 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1252 const int64_t min_index = Eval(ct.
arguments[1], evaluator) - 1;
1253 const int64_t min_value = EvalAt(ct.
arguments[0], min_index, evaluator);
1255 for (
int i = 0; i < min_index; ++i) {
1256 if (EvalAt(ct.
arguments[0], i, evaluator) <= min_value) {
1261 for (
int i = min_index + 1; i < Length(ct.
arguments[0]); i++) {
1262 if (EvalAt(ct.
arguments[0], i, evaluator) < min_value) {
1270bool CheckMinimumInt(
1272 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1273 int64_t min_value = std::numeric_limits<int64_t>::max();
1274 for (
int i = 0; i < Length(ct.
arguments[1]); ++i) {
1275 min_value = std::min(min_value, EvalAt(ct.
arguments[1], i, evaluator));
1277 return min_value == Eval(ct.
arguments[0], evaluator);
1280bool CheckNetworkFlowConservation(
1283 const std::function<int64_t(
Variable*)>& evaluator) {
1284 std::vector<int64_t> balance(balance_input.
values);
1285 const int num_arcs = Length(arcs) / 2;
1286 for (
int arc = 0; arc < num_arcs; arc++) {
1287 const int tail = arcs.
values[arc * 2] - base_node;
1288 const int head = arcs.
values[arc * 2 + 1] - base_node;
1289 const int64_t flow = EvalAt(flow_vars, arc, evaluator);
1290 balance[tail] -= flow;
1291 balance[head] += flow;
1294 for (
const int64_t value : balance) {
1295 if (value != 0)
return false;
1301bool CheckOrToolsNetworkFlow(
1303 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1309bool CheckOrToolsNetworkFlowCost(
1311 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1318 int64_t total_cost = 0;
1319 const int num_arcs = Length(ct.
arguments[3]);
1320 for (
int arc = 0; arc < num_arcs; arc++) {
1321 const int64_t flow = EvalAt(ct.
arguments[3], arc, evaluator);
1322 const int64_t unit_cost = ct.
arguments[4].ValueAt(arc);
1323 total_cost += flow * unit_cost;
1326 return total_cost == Eval(ct.
arguments[5], evaluator);
1329bool CheckOrToolsRegular(
1331 const std::function<int64_t(
Variable*)>& ,
1332 const std::function<std::vector<int64_t>(
Variable*)>& ) {
1336bool CheckRegularNfa(
1338 const std::function<int64_t(
Variable*)>& ,
1339 const std::function<std::vector<int64_t>(
Variable*)>& ) {
1345 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1346 const int64_t set_size = SetSize(ct.
arguments[0], set_evaluator);
1347 const int64_t cardinality = Eval(ct.
arguments[1], evaluator);
1348 return set_size == cardinality;
1351bool CheckArraySetElement(
1353 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1354 const int64_t index = Eval(ct.
arguments[0], evaluator);
1355 const int64_t min_index = ct.
arguments[0].Var()->domain.Min();
1356 const std::vector<int64_t> element =
1357 SetEvalAt(ct.
arguments[1], index - min_index, set_evaluator);
1358 const std::vector<int64_t> target = SetEval(ct.
arguments[2], set_evaluator);
1359 return element == target;
1364 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1365 const int64_t value = Eval(ct.
arguments[0], evaluator);
1366 const std::vector<int64_t> set = SetEval(ct.
arguments[1], set_evaluator);
1367 return std::find(set.begin(), set.end(), value) != set.end();
1372 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1373 const int64_t value = Eval(ct.
arguments[0], evaluator);
1374 const std::vector<int64_t> set = SetEval(ct.
arguments[1], set_evaluator);
1375 return std::find(set.begin(), set.end(), value) == set.end();
1380 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1381 const int64_t value = Eval(ct.
arguments[0], evaluator);
1382 const std::vector<int64_t> set = SetEval(ct.
arguments[1], set_evaluator);
1383 const bool contain = std::find(set.begin(), set.end(), value) != set.end();
1384 const int64_t status = Eval(ct.
arguments[2], evaluator);
1385 return contain == (status == 1);
1388bool CheckSetIntersect(
1390 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1391 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1392 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1393 const std::vector<int64_t> values_r = SetEval(ct.
arguments[2], set_evaluator);
1394 absl::flat_hash_set<int64_t> set_r(values_r.begin(), values_r.end());
1395 absl::flat_hash_set<int64_t> computed_intersection;
1396 std::set_intersection(
1397 values_x.begin(), values_x.end(), values_y.begin(), values_y.end(),
1398 std::inserter(computed_intersection, computed_intersection.begin()));
1399 return computed_intersection == set_r;
1404 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1405 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1406 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1407 const std::vector<int64_t> values_r = SetEval(ct.
arguments[2], set_evaluator);
1408 absl::flat_hash_set<int64_t> set_r(values_r.begin(), values_r.end());
1409 absl::flat_hash_set<int64_t> computed_intersection;
1411 values_x.begin(), values_x.end(), values_y.begin(), values_y.end(),
1412 std::inserter(computed_intersection, computed_intersection.begin()));
1413 return computed_intersection == set_r;
1418 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1419 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1420 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1421 return std::includes(values_y.begin(), values_y.end(), values_x.begin(),
1425bool CheckSetSubsetReif(
1427 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1428 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1429 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1430 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1431 return std::includes(values_y.begin(), values_y.end(), values_x.begin(),
1432 values_x.end()) == status;
1435bool CheckSetSuperset(
1437 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1438 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1439 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1440 return std::includes(values_x.begin(), values_x.end(), values_y.begin(),
1444bool CheckSetSupersetReif(
1446 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1447 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1448 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1449 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1450 return std::includes(values_x.begin(), values_x.end(), values_y.begin(),
1451 values_y.end()) == status;
1456 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1457 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1458 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1459 const std::vector<int64_t> values_r = SetEval(ct.
arguments[2], set_evaluator);
1460 absl::flat_hash_set<int64_t> set_r(values_r.begin(), values_r.end());
1461 absl::flat_hash_set<int64_t> computed_diff;
1462 std::set_difference(values_x.begin(), values_x.end(), values_y.begin(),
1464 std::inserter(computed_diff, computed_diff.begin()));
1465 return computed_diff == set_r;
1468bool CheckSetSymDiff(
1470 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1471 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1472 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1473 const std::vector<int64_t> values_r = SetEval(ct.
arguments[2], set_evaluator);
1474 absl::flat_hash_set<int64_t> set_r(values_r.begin(), values_r.end());
1475 absl::flat_hash_set<int64_t> computed_sym_diff;
1476 std::set_symmetric_difference(
1477 values_x.begin(), values_x.end(), values_y.begin(), values_y.end(),
1478 std::inserter(computed_sym_diff, computed_sym_diff.begin()));
1479 return computed_sym_diff == set_r;
1484 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1485 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1486 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1487 return values_x == values_y;
1492 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1493 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1494 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1495 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1496 return (values_x == values_y) == status;
1501 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1502 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1503 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1504 return values_x != values_y;
1509 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1510 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1511 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1512 const int min_size = std::min(values_x.size(), values_y.size());
1513 for (
int i = 0; i < min_size; ++i) {
1514 if (values_x[i] < values_y[i])
return true;
1515 if (values_x[i] > values_y[i])
return false;
1517 return values_y.size() >= values_x.size();
1522 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1523 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1524 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1525 const int min_size = std::min(values_x.size(), values_y.size());
1526 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1528 const bool expected_status = [&]() {
1529 for (
int i = 0; i < min_size; ++i) {
1530 if (values_x[i] < values_y[i])
return true;
1531 if (values_x[i] > values_y[i])
return false;
1533 return values_y.size() >= values_x.size();
1536 return expected_status == status;
1541 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1542 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1543 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1544 const int min_size = std::min(values_x.size(), values_y.size());
1545 for (
int i = 0; i < min_size; ++i) {
1546 if (values_x[i] < values_y[i])
return true;
1547 if (values_x[i] > values_y[i])
return false;
1549 return values_y.size() > values_x.size();
1554 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1555 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1556 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1557 const int min_size = std::min(values_x.size(), values_y.size());
1558 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1560 const bool expected_status = [&]() {
1561 for (
int i = 0; i < min_size; ++i) {
1562 if (values_x[i] < values_y[i])
return true;
1563 if (values_x[i] > values_y[i])
return false;
1565 return values_y.size() > values_x.size();
1568 return expected_status == status;
1573 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1574 const std::vector<int64_t> values_x = SetEval(ct.
arguments[0], set_evaluator);
1575 const std::vector<int64_t> values_y = SetEval(ct.
arguments[1], set_evaluator);
1576 const bool status = Eval(ct.
arguments[2], evaluator) != 0;
1577 return (values_x != values_y) == status;
1580bool CheckSlidingSum(
1582 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1583 const int64_t low = Eval(ct.
arguments[0], evaluator);
1584 const int64_t up = Eval(ct.
arguments[1], evaluator);
1585 const int64_t length = Eval(ct.
arguments[2], evaluator);
1587 int64_t sliding_sum = 0;
1588 for (
int i = 0; i < std::min<int64_t>(length, Length(ct.
arguments[3])); ++i) {
1589 sliding_sum += EvalAt(ct.
arguments[3], i, evaluator);
1591 if (sliding_sum < low || sliding_sum > up) {
1594 for (
int i = length; i < Length(ct.
arguments[3]); ++i) {
1595 sliding_sum += EvalAt(ct.
arguments[3], i, evaluator) -
1596 EvalAt(ct.
arguments[3], i - length, evaluator);
1597 if (sliding_sum < low || sliding_sum > up) {
1606 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1608 absl::flat_hash_map<int64_t, int> init_count;
1609 absl::flat_hash_map<int64_t, int> sorted_count;
1610 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
1611 init_count[EvalAt(ct.
arguments[0], i, evaluator)]++;
1612 sorted_count[EvalAt(ct.
arguments[1], i, evaluator)]++;
1614 if (init_count != sorted_count) {
1617 for (
int i = 0; i < Length(ct.
arguments[1]) - 1; ++i) {
1618 if (EvalAt(ct.
arguments[1], i, evaluator) >
1619 EvalAt(ct.
arguments[1], i, evaluator)) {
1626bool CheckOrToolsSubCircuit(
1628 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1629 absl::flat_hash_set<int64_t> visited;
1632 int64_t current = -1;
1633 for (
int i = 0; i < Length(ct.
arguments[0]); ++i) {
1634 const int64_t next = EvalAt(ct.
arguments[0], i, evaluator) -
base;
1635 if (next != i && current == -1) {
1637 }
else if (next == i) {
1638 visited.insert(next);
1643 const int residual_size = Length(ct.
arguments[0]) - visited.size();
1644 for (
int i = 0; i < residual_size; ++i) {
1645 const int64_t next = EvalAt(ct.
arguments[0], current, evaluator) -
base;
1646 visited.insert(next);
1647 if (next == current) {
1654 return visited.size() == Length(ct.
arguments[0]);
1657bool CheckOrToolsTableInt(
1659 const std::function<int64_t(
Variable*)>& ,
1660 const std::function<std::vector<int64_t>(
Variable*)>& ) {
1664bool CheckSymmetricAllDifferent(
1666 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1667 const int size = Length(ct.
arguments[0]);
1668 for (
int i = 0; i < size; ++i) {
1669 const int64_t value = EvalAt(ct.
arguments[0], i, evaluator) - 1;
1670 if (value < 0 || value >= size) {
1673 const int64_t reverse_value = EvalAt(ct.
arguments[0], value, evaluator) - 1;
1674 if (reverse_value != i) {
1681bool CheckValuePrecedeInt(
1683 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1684 const int64_t before = ct.
arguments[0].Value();
1685 const int64_t after = ct.
arguments[1].Value();
1686 const int64_t length = Length(ct.
arguments[2]);
1687 bool before_found =
false;
1688 for (
int i = 0; i < length; ++i) {
1689 const int64_t current = EvalAt(ct.
arguments[2], i, evaluator);
1690 if (current == before) before_found =
true;
1691 if (current == after && !before_found)
return false;
1696bool CheckOrToolsPrecedeChainInt(
1698 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator) {
1699 absl::flat_hash_map<int64_t, int> value_to_index;
1703 value_to_index[v] = value_to_index.size();
1707 for (int64_t v : ct.
arguments[0].values) {
1708 value_to_index[v] = value_to_index.size();
1711 LOG(FATAL) <<
"Unsupported argument type: " << ct.
arguments[0].type;
1714 int max_visited_index = -1;
1715 const int64_t length = Length(ct.
arguments[1]);
1716 for (
int i = 0; i < length; ++i) {
1717 const int64_t current = EvalAt(ct.
arguments[1], i, evaluator);
1718 const auto it = value_to_index.find(current);
1719 if (it == value_to_index.end())
continue;
1720 if (it->second > max_visited_index + 1)
return false;
1721 if (it->second == max_visited_index + 1) ++max_visited_index;
1726using CallMap = absl::flat_hash_map<
1729 const std::function<std::vector<int64_t>(
Variable*)>&)>>;
1738CallMap CreateCallMap() {
1740 m[
"alldifferent_except_0"] = CheckAlldifferentExcept0;
1741 m[
"among"] = CheckAmong;
1742 m[
"array_bool_and"] = CheckArrayBoolAnd;
1743 m[
"array_bool_element"] = CheckArrayIntElement;
1744 m[
"array_bool_or"] = CheckArrayBoolOr;
1745 m[
"array_bool_xor"] = CheckArrayBoolXor;
1746 m[
"array_int_element"] = CheckArrayIntElement;
1747 m[
"array_int_element_nonshifted"] = CheckArrayIntElementNonShifted;
1748 m[
"array_int_maximum"] = CheckMaximumInt;
1749 m[
"array_int_minimum"] = CheckMinimumInt;
1750 m[
"array_set_element"] = CheckArraySetElement;
1751 m[
"array_var_bool_element"] = CheckArrayVarIntElement;
1752 m[
"array_var_int_element"] = CheckArrayVarIntElement;
1753 m[
"array_var_set_element"] = CheckArraySetElement;
1754 m[
"at_most_int"] = CheckAtMostInt;
1755 m[
"bool_and"] = CheckBoolAnd;
1756 m[
"bool_clause"] = CheckBoolClause;
1757 m[
"bool_eq_imp"] = CheckIntEqImp;
1758 m[
"bool_eq_reif"] = CheckIntEqReif;
1759 m[
"bool_eq"] = CheckIntEq;
1760 m[
"bool_ge_imp"] = CheckIntGeImp;
1761 m[
"bool_ge_reif"] = CheckIntGeReif;
1762 m[
"bool_ge"] = CheckIntGe;
1763 m[
"bool_gt_imp"] = CheckIntGtImp;
1764 m[
"bool_gt_reif"] = CheckIntGtReif;
1765 m[
"bool_gt"] = CheckIntGt;
1766 m[
"bool_le_imp"] = CheckIntLeImp;
1767 m[
"bool_le_reif"] = CheckIntLeReif;
1768 m[
"bool_le"] = CheckIntLe;
1769 m[
"bool_left_imp"] = CheckIntLe;
1770 m[
"bool_lin_eq"] = CheckIntLinEq;
1771 m[
"bool_lin_le"] = CheckIntLinLe;
1772 m[
"bool_lt_imp"] = CheckIntLtImp;
1773 m[
"bool_lt_reif"] = CheckIntLtReif;
1774 m[
"bool_lt"] = CheckIntLt;
1775 m[
"bool_ne_imp"] = CheckIntNeImp;
1776 m[
"bool_ne_reif"] = CheckIntNeReif;
1777 m[
"bool_ne"] = CheckIntNe;
1778 m[
"bool_not"] = CheckBoolNot;
1779 m[
"bool_or"] = CheckBoolOr;
1780 m[
"bool_right_imp"] = CheckIntGe;
1781 m[
"bool_xor"] = CheckBoolXor;
1782 m[
"bool2int"] = CheckIntEq;
1783 m[
"count_eq"] = CheckOrToolsCountEq;
1784 m[
"count_geq"] = CheckCountGeq;
1785 m[
"count_gt"] = CheckCountGt;
1786 m[
"count_leq"] = CheckCountLeq;
1787 m[
"count_lt"] = CheckCountLt;
1788 m[
"count_neq"] = CheckCountNeq;
1789 m[
"count_reif"] = CheckCountReif;
1790 m[
"count"] = CheckOrToolsCountEq;
1791 m[
"diffn_k_with_sizes"] = CheckDiffnK;
1792 m[
"diffn_nonstrict_k_with_sizes"] = CheckDiffnNonStrictK;
1793 m[
"false_constraint"] = CheckFalseConstraint;
1794 m[
"fixed_cumulative"] = CheckCumulative;
1795 m[
"fzn_all_different_int"] = CheckAllDifferentInt;
1796 m[
"fzn_all_different_set"] = CheckAllDifferentSet;
1797 m[
"fzn_all_disjoint"] = CheckAllDisjoint;
1798 m[
"fzn_cumulative"] = CheckCumulative;
1799 m[
"fzn_diffn_nonstrict"] = CheckDiffnNonStrict;
1800 m[
"fzn_diffn"] = CheckDiffn;
1801 m[
"fzn_disjoint"] = CheckDisjoint;
1802 m[
"fzn_disjunctive_strict"] = CheckDisjunctiveStrict;
1803 m[
"fzn_disjunctive"] = CheckDisjunctive;
1804 m[
"fzn_partition_set"] = CheckPartitionSet;
1805 m[
"fzn_value_precede_int"] = CheckValuePrecedeInt;
1806 m[
"int_abs"] = CheckIntAbs;
1807 m[
"int_div"] = CheckIntDiv;
1808 m[
"int_eq_imp"] = CheckIntEqImp;
1809 m[
"int_eq_reif"] = CheckIntEqReif;
1810 m[
"int_eq"] = CheckIntEq;
1811 m[
"int_ge_imp"] = CheckIntGeImp;
1812 m[
"int_ge_reif"] = CheckIntGeReif;
1813 m[
"int_ge"] = CheckIntGe;
1814 m[
"int_gt_imp"] = CheckIntGtImp;
1815 m[
"int_gt_reif"] = CheckIntGtReif;
1816 m[
"int_gt"] = CheckIntGt;
1817 m[
"int_in"] = CheckSetIn;
1818 m[
"int_le_imp"] = CheckIntLeImp;
1819 m[
"int_le_reif"] = CheckIntLeReif;
1820 m[
"int_le"] = CheckIntLe;
1821 m[
"int_lin_eq_imp"] = CheckIntLinEqImp;
1822 m[
"int_lin_eq_reif"] = CheckIntLinEqReif;
1823 m[
"int_lin_eq"] = CheckIntLinEq;
1824 m[
"int_lin_ge_imp"] = CheckIntLinGeImp;
1825 m[
"int_lin_ge_reif"] = CheckIntLinGeReif;
1826 m[
"int_lin_ge"] = CheckIntLinGe;
1827 m[
"int_lin_le_imp"] = CheckIntLinLeImp;
1828 m[
"int_lin_le_reif"] = CheckIntLinLeReif;
1829 m[
"int_lin_le"] = CheckIntLinLe;
1830 m[
"int_lin_ne_imp"] = CheckIntLinNeImp;
1831 m[
"int_lin_ne_reif"] = CheckIntLinNeReif;
1832 m[
"int_lin_ne"] = CheckIntLinNe;
1833 m[
"int_lt_imp"] = CheckIntLtImp;
1834 m[
"int_lt_reif"] = CheckIntLtReif;
1835 m[
"int_lt"] = CheckIntLt;
1836 m[
"int_max"] = CheckIntMax;
1837 m[
"int_min"] = CheckIntMin;
1838 m[
"int_minus"] = CheckIntMinus;
1839 m[
"int_mod"] = CheckIntMod;
1840 m[
"int_ne_imp"] = CheckIntNeImp;
1841 m[
"int_ne_reif"] = CheckIntNeReif;
1842 m[
"int_ne"] = CheckIntNe;
1843 m[
"int_negate"] = CheckIntNegate;
1844 m[
"int_not_in"] = CheckSetNotIn;
1845 m[
"int_plus"] = CheckIntPlus;
1846 m[
"int_times"] = CheckIntTimes;
1847 m[
"maximum_arg_int"] = CheckMaximumArgInt;
1848 m[
"maximum_int"] = CheckMaximumInt;
1849 m[
"minimum_arg_int"] = CheckMinimumArgInt;
1850 m[
"minimum_int"] = CheckMinimumInt;
1851 m[
"ortools_arg_max_bool"] = CheckOrToolsArgMaxInt;
1852 m[
"ortools_arg_max_int"] = CheckOrToolsArgMaxInt;
1853 m[
"ortools_array_bool_element"] = CheckOrToolsArrayIntElement;
1854 m[
"ortools_array_int_element"] = CheckOrToolsArrayIntElement;
1855 m[
"ortools_array_var_bool_element"] = CheckOrToolsArrayIntElement;
1856 m[
"ortools_array_var_int_element"] = CheckOrToolsArrayIntElement;
1857 m[
"ortools_bin_packing_capa"] = CheckOrToolsBinPackingCapa;
1858 m[
"ortools_bin_packing_load"] = CheckOrToolsBinPackingLoad;
1859 m[
"ortools_bin_packing"] = CheckOrToolsBinPacking;
1860 m[
"ortools_circuit"] = CheckOrToolsCircuit;
1861 m[
"ortools_count_eq_cst"] = CheckOrToolsCountEq;
1862 m[
"ortools_count_eq"] = CheckOrToolsCountEq;
1863 m[
"ortools_cumulative_opt"] = CheckOrToolsCumulativeOpt;
1864 m[
"ortools_disjunctive_strict_opt"] = CheckOrToolsDisjunctiveStrictOpt;
1865 m[
"ortools_global_cardinality_low_up"] = CheckOrToolsGlobalCardinalityLowUp;
1866 m[
"ortools_global_cardinality"] = CheckOrToolsGlobalCardinality;
1867 m[
"ortools_inverse"] = CheckOrToolsInverse;
1868 m[
"ortools_lex_less_bool"] = CheckOrToolsLexLessInt;
1869 m[
"ortools_lex_less_int"] = CheckOrToolsLexLessInt;
1870 m[
"ortools_lex_lesseq_bool"] = CheckOrToolsLexLesseqInt;
1871 m[
"ortools_lex_lesseq_int"] = CheckOrToolsLexLesseqInt;
1872 m[
"ortools_network_flow_cost"] = CheckOrToolsNetworkFlowCost;
1873 m[
"ortools_network_flow"] = CheckOrToolsNetworkFlow;
1874 m[
"ortools_nvalue"] = CheckOrToolsNValue;
1875 m[
"ortools_precede_chain_int"] = CheckOrToolsPrecedeChainInt;
1876 m[
"ortools_regular"] = CheckOrToolsRegular;
1877 m[
"ortools_subcircuit"] = CheckOrToolsSubCircuit;
1878 m[
"ortools_table_bool"] = CheckOrToolsTableInt;
1879 m[
"ortools_table_int"] = CheckOrToolsTableInt;
1880 m[
"regular_nfa"] = CheckRegularNfa;
1881 m[
"set_card"] = CheckSetCard;
1882 m[
"set_diff"] = CheckSetDiff;
1883 m[
"set_eq_reif"] = CheckSetEqReif;
1884 m[
"set_eq"] = CheckSetEq;
1885 m[
"set_in_reif"] = CheckSetInReif;
1886 m[
"set_in"] = CheckSetIn;
1887 m[
"set_intersect"] = CheckSetIntersect;
1888 m[
"set_le"] = CheckSetLe;
1889 m[
"set_lt"] = CheckSetLt;
1890 m[
"set_le_reif"] = CheckSetLeReif;
1891 m[
"set_lt_reif"] = CheckSetLtReif;
1892 m[
"set_ne_reif"] = CheckSetNeReif;
1893 m[
"set_ne"] = CheckSetNe;
1894 m[
"set_not_in"] = CheckSetNotIn;
1895 m[
"set_subset_reif"] = CheckSetSubsetReif;
1896 m[
"set_subset"] = CheckSetSubset;
1897 m[
"set_superset_reif"] = CheckSetSupersetReif;
1898 m[
"set_superset"] = CheckSetSuperset;
1899 m[
"set_symdiff"] = CheckSetSymDiff;
1900 m[
"set_union"] = CheckSetUnion;
1901 m[
"sliding_sum"] = CheckSlidingSum;
1902 m[
"sort"] = CheckSort;
1903 m[
"symmetric_all_different"] = CheckSymmetricAllDifferent;
1904 m[
"var_cumulative"] = CheckCumulative;
1905 m[
"variable_cumulative"] = CheckCumulative;
1912 const Model& model,
const std::function<int64_t(
Variable*)>& evaluator,
1913 const std::function<std::vector<int64_t>(
Variable*)>& set_evaluator,
1916 const CallMap call_map = CreateCallMap();
1918 if (!ct->active)
continue;
1919 DCHECK(call_map.contains(ct->type)) << ct->type;
1920 const auto& checker = call_map.at(ct->type);
1921 if (!checker(*ct, evaluator, set_evaluator)) {
1922 SOLVER_LOG(logger,
"Failing constraint ", ct->DebugString());