39 const std::function<int64_t(
Variable*)>& evaluator) {
45 return evaluator(arg.
Var());
48 LOG(FATAL) <<
"Cannot evaluate " << arg.
DebugString();
58int64_t EvalAt(
const Argument& arg,
int pos,
59 const std::function<int64_t(
Variable*)>& evaluator) {
65 return evaluator(arg.
VarAt(pos));
68 LOG(FATAL) <<
"Cannot evaluate " << arg.
DebugString();
77 const std::function<int64_t(
Variable*)>& evaluator) {
78 absl::flat_hash_set<int64_t> visited;
81 if (visited.contains(
value)) {
84 visited.insert(
value);
90bool CheckAlldifferentExcept0(
92 absl::flat_hash_set<int64_t> visited;
98 visited.insert(
value);
105 const std::function<int64_t(
Variable*)>& evaluator) {
106 const int64_t expected = Eval(
ct.
arguments[0], evaluator);
113 return count == expected;
117 const std::function<int64_t(
Variable*)>& evaluator) {
122 result = std::min(result,
value);
129 const std::function<int64_t(
Variable*)>& evaluator) {
134 result = std::max(result,
value);
141 const std::function<int64_t(
Variable*)>& evaluator) {
148 return result % 2 == 1;
152 const std::function<int64_t(
Variable*)>& evaluator) {
158 const int64_t shifted_index = Eval(
ct.
arguments[0], evaluator) - 1;
159 const int64_t element = EvalAt(
ct.
arguments[1], shifted_index, evaluator);
160 const int64_t target = Eval(
ct.
arguments[2], evaluator);
161 return element == target;
164bool CheckArrayIntElementNonShifted(
169 const int64_t target = Eval(
ct.
arguments[2], evaluator);
170 return element == target;
173bool CheckArrayVarIntElement(
180 const int64_t shifted_index = Eval(
ct.
arguments[0], evaluator) - 1;
181 const int64_t element = EvalAt(
ct.
arguments[1], shifted_index, evaluator);
182 const int64_t target = Eval(
ct.
arguments[2], evaluator);
183 return element == target;
187 const std::function<int64_t(
Variable*)>& evaluator) {
188 const int64_t expected = Eval(
ct.
arguments[0], evaluator);
195 return count <= expected;
199 const std::function<int64_t(
Variable*)>& evaluator) {
200 const int64_t left = Eval(
ct.
arguments[0], evaluator);
201 const int64_t right = Eval(
ct.
arguments[1], evaluator);
203 return status == std::min(left, right);
207 const std::function<int64_t(
Variable*)>& evaluator) {
213 result = std::max(result,
value);
218 result = std::max(result, 1 -
value);
225 const std::function<int64_t(
Variable*)>& evaluator) {
226 const int64_t left = Eval(
ct.
arguments[0], evaluator);
227 const int64_t right = Eval(
ct.
arguments[1], evaluator);
228 return left == 1 - right;
232 const std::function<int64_t(
Variable*)>& evaluator) {
233 const int64_t left = Eval(
ct.
arguments[0], evaluator);
234 const int64_t right = Eval(
ct.
arguments[1], evaluator);
236 return status == std::max(left, right);
240 const std::function<int64_t(
Variable*)>& evaluator) {
241 const int64_t left = Eval(
ct.
arguments[0], evaluator);
242 const int64_t right = Eval(
ct.
arguments[1], evaluator);
243 const int64_t target = Eval(
ct.
arguments[2], evaluator);
244 return target == (left + right == 1);
248 const std::function<int64_t(
Variable*)>& evaluator) {
252 absl::flat_hash_set<int64_t> visited;
254 for (
int i = 0; i <
size; ++i) {
255 const int64_t
next = EvalAt(
ct.
arguments[0], current, evaluator) - base;
256 visited.insert(
next);
259 return visited.size() ==
size;
263 const std::function<int64_t(
Variable*)>& evaluator) {
273 const std::function<int64_t(
Variable*)>& evaluator) {
274 const int64_t count = ComputeCount(
ct, evaluator);
275 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
276 return count == expected;
280 const std::function<int64_t(
Variable*)>& evaluator) {
281 const int64_t count = ComputeCount(
ct, evaluator);
282 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
283 return count >= expected;
287 const std::function<int64_t(
Variable*)>& evaluator) {
288 const int64_t count = ComputeCount(
ct, evaluator);
289 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
290 return count > expected;
294 const std::function<int64_t(
Variable*)>& evaluator) {
295 const int64_t count = ComputeCount(
ct, evaluator);
296 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
297 return count <= expected;
301 const std::function<int64_t(
Variable*)>& evaluator) {
302 const int64_t count = ComputeCount(
ct, evaluator);
303 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
304 return count < expected;
308 const std::function<int64_t(
Variable*)>& evaluator) {
309 const int64_t count = ComputeCount(
ct, evaluator);
310 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
311 return count != expected;
315 const std::function<int64_t(
Variable*)>& evaluator) {
316 const int64_t count = ComputeCount(
ct, evaluator);
317 const int64_t expected = Eval(
ct.
arguments[2], evaluator);
319 return status == (expected == count);
323 const std::function<int64_t(
Variable*)>& evaluator) {
325 const int64_t capacity = Eval(
ct.
arguments[3], evaluator);
329 absl::flat_hash_map<int64_t, int64_t> usage;
330 for (
int i = 0; i <
size; ++i) {
332 const int64_t duration = EvalAt(
ct.
arguments[1], i, evaluator);
333 const int64_t requirement = EvalAt(
ct.
arguments[2], i, evaluator);
334 for (int64_t t =
start; t <
start + duration; ++t) {
335 usage[t] += requirement;
336 if (usage[t] > capacity) {
345 const std::function<int64_t(
Variable*)>& evaluator) {
347 const int64_t capacity = Eval(
ct.
arguments[4], evaluator);
352 absl::flat_hash_map<int64_t, int64_t> usage;
353 for (
int i = 0; i <
size; ++i) {
354 if (EvalAt(
ct.
arguments[0], i, evaluator) == 0)
continue;
356 const int64_t duration = EvalAt(
ct.
arguments[2], i, evaluator);
357 const int64_t requirement = EvalAt(
ct.
arguments[3], i, evaluator);
358 for (int64_t t =
start; t <
start + duration; ++t) {
359 usage[t] += requirement;
360 if (usage[t] > capacity) {
369 const std::function<int64_t(
Variable*)>& ) {
374 const std::function<int64_t(
Variable*)>& ) {
378bool CheckDiffnNonStrict(
380 const std::function<int64_t(
Variable*)>& ) {
384bool CheckDiffnNonStrictK(
386 const std::function<int64_t(
Variable*)>& ) {
391 const std::function<int64_t(
Variable*)>& evaluator) {
394 std::vector<std::pair<int64_t, int64_t>> start_durations_pairs;
395 start_durations_pairs.reserve(
size);
396 for (
int i = 0; i + 1 <
size; ++i) {
397 const int64_t duration = EvalAt(
ct.
arguments[1], i, evaluator);
398 if (duration == 0)
continue;
400 start_durations_pairs.push_back({
start, duration});
402 std::sort(start_durations_pairs.begin(), start_durations_pairs.end());
403 int64_t previous_end = std::numeric_limits<int64_t>::min();
404 for (
const auto& pair : start_durations_pairs) {
405 if (pair.first < previous_end)
return false;
406 previous_end = pair.first + pair.second;
411bool CheckDisjunctiveStrict(
415 std::vector<std::pair<int64_t, int64_t>> start_durations_pairs;
416 start_durations_pairs.reserve(
size);
417 for (
int i = 0; i + 1 <
size; ++i) {
419 const int64_t duration = EvalAt(
ct.
arguments[1], i, evaluator);
420 start_durations_pairs.push_back({
start, duration});
422 std::sort(start_durations_pairs.begin(), start_durations_pairs.end());
423 int64_t previous_end = std::numeric_limits<int64_t>::min();
424 for (
const auto& pair : start_durations_pairs) {
425 if (pair.first < previous_end)
return false;
426 previous_end = pair.first + pair.second;
431bool CheckDisjunctiveStrictOpt(
436 std::vector<std::pair<int64_t, int64_t>> start_durations_pairs;
437 start_durations_pairs.reserve(
size);
438 for (
int i = 0; i + 1 <
size; ++i) {
439 if (EvalAt(
ct.
arguments[0], i, evaluator) == 0)
continue;
441 const int64_t duration = EvalAt(
ct.
arguments[2], i, evaluator);
442 start_durations_pairs.push_back({
start, duration});
444 std::sort(start_durations_pairs.begin(), start_durations_pairs.end());
445 int64_t previous_end = std::numeric_limits<int64_t>::min();
446 for (
const auto& pair : start_durations_pairs) {
447 if (pair.first < previous_end)
return false;
448 previous_end = pair.first + pair.second;
453bool CheckFalseConstraint(
455 const std::function<int64_t(
Variable*)>& ) {
459std::vector<int64_t> ComputeGlobalCardinalityCards(
461 std::vector<int64_t> cards(Size(
ct.
arguments[1]), 0);
462 absl::flat_hash_map<int64_t, int> positions;
463 for (
int i = 0; i <
ct.
arguments[1].values.size(); ++i) {
465 CHECK(!positions.contains(
value));
466 positions[
value] = i;
470 if (positions.contains(
value)) {
471 cards[positions[
value]]++;
477bool CheckGlobalCardinality(
479 const std::vector<int64_t> cards =
480 ComputeGlobalCardinalityCards(
ct, evaluator);
483 const int64_t card = EvalAt(
ct.
arguments[2], i, evaluator);
484 if (card != cards[i]) {
491bool CheckGlobalCardinalityClosed(
493 const std::vector<int64_t> cards =
494 ComputeGlobalCardinalityCards(
ct, evaluator);
497 const int64_t card = EvalAt(
ct.
arguments[2], i, evaluator);
498 if (card != cards[i]) {
502 int64_t sum_of_cards = 0;
503 for (int64_t card : cards) {
504 sum_of_cards += card;
509bool CheckGlobalCardinalityLowUp(
511 const std::vector<int64_t> cards =
512 ComputeGlobalCardinalityCards(
ct, evaluator);
513 CHECK_EQ(cards.size(),
ct.
arguments[2].values.size());
514 CHECK_EQ(cards.size(),
ct.
arguments[3].values.size());
515 for (
int i = 0; i < cards.size(); ++i) {
516 const int64_t card = cards[i];
524bool CheckGlobalCardinalityLowUpClosed(
526 const std::vector<int64_t> cards =
527 ComputeGlobalCardinalityCards(
ct, evaluator);
528 CHECK_EQ(cards.size(),
ct.
arguments[2].values.size());
529 CHECK_EQ(cards.size(),
ct.
arguments[3].values.size());
530 for (
int i = 0; i < cards.size(); ++i) {
531 const int64_t card = cards[i];
536 int64_t sum_of_cards = 0;
537 for (int64_t card : cards) {
538 sum_of_cards += card;
543bool CheckGlobalCardinalityOld(
546 std::vector<int64_t> cards(
size, 0);
553 for (
int i = 0; i <
size; ++i) {
554 const int64_t card = EvalAt(
ct.
arguments[1], i, evaluator);
555 if (card != cards[i]) {
563 const std::function<int64_t(
Variable*)>& evaluator) {
564 const int64_t left = Eval(
ct.
arguments[0], evaluator);
565 const int64_t right = Eval(
ct.
arguments[1], evaluator);
566 return std::abs(left) == right;
570 const std::function<int64_t(
Variable*)>& evaluator) {
571 const int64_t left = Eval(
ct.
arguments[0], evaluator);
572 const int64_t right = Eval(
ct.
arguments[1], evaluator);
573 const int64_t target = Eval(
ct.
arguments[2], evaluator);
574 return target == left / right;
578 const std::function<int64_t(
Variable*)>& evaluator) {
579 const int64_t left = Eval(
ct.
arguments[0], evaluator);
580 const int64_t right = Eval(
ct.
arguments[1], evaluator);
581 return left == right;
585 const std::function<int64_t(
Variable*)>& evaluator) {
586 const int64_t left = Eval(
ct.
arguments[0], evaluator);
587 const int64_t right = Eval(
ct.
arguments[1], evaluator);
593 const std::function<int64_t(
Variable*)>& evaluator) {
594 const int64_t left = Eval(
ct.
arguments[0], evaluator);
595 const int64_t right = Eval(
ct.
arguments[1], evaluator);
597 return status == (left == right);
601 const std::function<int64_t(
Variable*)>& evaluator) {
602 const int64_t left = Eval(
ct.
arguments[0], evaluator);
603 const int64_t right = Eval(
ct.
arguments[1], evaluator);
604 return left >= right;
608 const std::function<int64_t(
Variable*)>& evaluator) {
609 const int64_t left = Eval(
ct.
arguments[0], evaluator);
610 const int64_t right = Eval(
ct.
arguments[1], evaluator);
616 const std::function<int64_t(
Variable*)>& evaluator) {
617 const int64_t left = Eval(
ct.
arguments[0], evaluator);
618 const int64_t right = Eval(
ct.
arguments[1], evaluator);
620 return status == (left >= right);
624 const std::function<int64_t(
Variable*)>& evaluator) {
625 const int64_t left = Eval(
ct.
arguments[0], evaluator);
626 const int64_t right = Eval(
ct.
arguments[1], evaluator);
631 const std::function<int64_t(
Variable*)>& evaluator) {
632 const int64_t left = Eval(
ct.
arguments[0], evaluator);
633 const int64_t right = Eval(
ct.
arguments[1], evaluator);
639 const std::function<int64_t(
Variable*)>& evaluator) {
640 const int64_t left = Eval(
ct.
arguments[0], evaluator);
641 const int64_t right = Eval(
ct.
arguments[1], evaluator);
643 return status == (left > right);
647 const std::function<int64_t(
Variable*)>& evaluator) {
648 const int64_t left = Eval(
ct.
arguments[0], evaluator);
649 const int64_t right = Eval(
ct.
arguments[1], evaluator);
650 return left <= right;
654 const std::function<int64_t(
Variable*)>& evaluator) {
655 const int64_t left = Eval(
ct.
arguments[0], evaluator);
656 const int64_t right = Eval(
ct.
arguments[1], evaluator);
662 const std::function<int64_t(
Variable*)>& evaluator) {
663 const int64_t left = Eval(
ct.
arguments[0], evaluator);
664 const int64_t right = Eval(
ct.
arguments[1], evaluator);
666 return status == (left <= right);
670 const std::function<int64_t(
Variable*)>& evaluator) {
671 const int64_t left = Eval(
ct.
arguments[0], evaluator);
672 const int64_t right = Eval(
ct.
arguments[1], evaluator);
677 const std::function<int64_t(
Variable*)>& evaluator) {
678 const int64_t left = Eval(
ct.
arguments[0], evaluator);
679 const int64_t right = Eval(
ct.
arguments[1], evaluator);
685 const std::function<int64_t(
Variable*)>& evaluator) {
686 const int64_t left = Eval(
ct.
arguments[0], evaluator);
687 const int64_t right = Eval(
ct.
arguments[1], evaluator);
689 return status == (left < right);
693 const std::function<int64_t(
Variable*)>& evaluator) {
703 const std::function<int64_t(
Variable*)>& evaluator) {
704 const int64_t left = ComputeIntLin(
ct, evaluator);
705 const int64_t right = Eval(
ct.
arguments[2], evaluator);
706 return left == right;
710 const std::function<int64_t(
Variable*)>& evaluator) {
711 const int64_t left = ComputeIntLin(
ct, evaluator);
712 const int64_t right = Eval(
ct.
arguments[2], evaluator);
718 const std::function<int64_t(
Variable*)>& evaluator) {
719 const int64_t left = ComputeIntLin(
ct, evaluator);
720 const int64_t right = Eval(
ct.
arguments[2], evaluator);
722 return status == (left == right);
726 const std::function<int64_t(
Variable*)>& evaluator) {
727 const int64_t left = ComputeIntLin(
ct, evaluator);
728 const int64_t right = Eval(
ct.
arguments[2], evaluator);
729 return left >= right;
733 const std::function<int64_t(
Variable*)>& evaluator) {
734 const int64_t left = ComputeIntLin(
ct, evaluator);
735 const int64_t right = Eval(
ct.
arguments[2], evaluator);
741 const std::function<int64_t(
Variable*)>& evaluator) {
742 const int64_t left = ComputeIntLin(
ct, evaluator);
743 const int64_t right = Eval(
ct.
arguments[2], evaluator);
745 return status == (left >= right);
749 const std::function<int64_t(
Variable*)>& evaluator) {
750 const int64_t left = ComputeIntLin(
ct, evaluator);
751 const int64_t right = Eval(
ct.
arguments[2], evaluator);
752 return left <= right;
756 const std::function<int64_t(
Variable*)>& evaluator) {
757 const int64_t left = ComputeIntLin(
ct, evaluator);
758 const int64_t right = Eval(
ct.
arguments[2], evaluator);
764 const std::function<int64_t(
Variable*)>& evaluator) {
765 const int64_t left = ComputeIntLin(
ct, evaluator);
766 const int64_t right = Eval(
ct.
arguments[2], evaluator);
768 return status == (left <= right);
772 const std::function<int64_t(
Variable*)>& evaluator) {
773 const int64_t left = ComputeIntLin(
ct, evaluator);
774 const int64_t right = Eval(
ct.
arguments[2], evaluator);
775 return left != right;
779 const std::function<int64_t(
Variable*)>& evaluator) {
780 const int64_t left = ComputeIntLin(
ct, evaluator);
781 const int64_t right = Eval(
ct.
arguments[2], evaluator);
787 const std::function<int64_t(
Variable*)>& evaluator) {
788 const int64_t left = ComputeIntLin(
ct, evaluator);
789 const int64_t right = Eval(
ct.
arguments[2], evaluator);
791 return status == (left != right);
795 const std::function<int64_t(
Variable*)>& evaluator) {
796 const int64_t left = Eval(
ct.
arguments[0], evaluator);
797 const int64_t right = Eval(
ct.
arguments[1], evaluator);
799 return status == std::max(left, right);
803 const std::function<int64_t(
Variable*)>& evaluator) {
804 const int64_t left = Eval(
ct.
arguments[0], evaluator);
805 const int64_t right = Eval(
ct.
arguments[1], evaluator);
807 return status == std::min(left, right);
811 const std::function<int64_t(
Variable*)>& evaluator) {
812 const int64_t left = Eval(
ct.
arguments[0], evaluator);
813 const int64_t right = Eval(
ct.
arguments[1], evaluator);
814 const int64_t target = Eval(
ct.
arguments[2], evaluator);
815 return target == left - right;
819 const std::function<int64_t(
Variable*)>& evaluator) {
820 const int64_t left = Eval(
ct.
arguments[0], evaluator);
821 const int64_t right = Eval(
ct.
arguments[1], evaluator);
822 const int64_t target = Eval(
ct.
arguments[2], evaluator);
823 return target == left % right;
827 const std::function<int64_t(
Variable*)>& evaluator) {
828 const int64_t left = Eval(
ct.
arguments[0], evaluator);
829 const int64_t right = Eval(
ct.
arguments[1], evaluator);
830 return left != right;
834 const std::function<int64_t(
Variable*)>& evaluator) {
835 const int64_t left = Eval(
ct.
arguments[0], evaluator);
836 const int64_t right = Eval(
ct.
arguments[1], evaluator);
842 const std::function<int64_t(
Variable*)>& evaluator) {
843 const int64_t left = Eval(
ct.
arguments[0], evaluator);
844 const int64_t right = Eval(
ct.
arguments[1], evaluator);
846 return status == (left != right);
850 const std::function<int64_t(
Variable*)>& evaluator) {
851 const int64_t left = Eval(
ct.
arguments[0], evaluator);
852 const int64_t right = Eval(
ct.
arguments[1], evaluator);
853 return left == -right;
857 const std::function<int64_t(
Variable*)>& evaluator) {
858 const int64_t left = Eval(
ct.
arguments[0], evaluator);
859 const int64_t right = Eval(
ct.
arguments[1], evaluator);
860 const int64_t target = Eval(
ct.
arguments[2], evaluator);
861 return target == left + right;
865 const std::function<int64_t(
Variable*)>& evaluator) {
866 const int64_t left = Eval(
ct.
arguments[0], evaluator);
867 const int64_t right = Eval(
ct.
arguments[1], evaluator);
868 const int64_t target = Eval(
ct.
arguments[2], evaluator);
869 return target == left * right;
873 const std::function<int64_t(
Variable*)>& evaluator) {
879 for (
int i = 0; i <
size; ++i) {
880 const int64_t
x = EvalAt(
ct.
arguments[0], i, evaluator) - invf_base;
881 const int64_t
y = EvalAt(
ct.
arguments[1], i, evaluator) - f_base;
888 for (
int i = 0; i <
size; ++i) {
889 const int64_t fi = EvalAt(
ct.
arguments[0], i, evaluator) - invf_base;
890 const int64_t invf_fi = EvalAt(
ct.
arguments[1], fi, evaluator) - f_base;
900 const std::function<int64_t(
Variable*)>& evaluator) {
903 const int64_t
x = EvalAt(
ct.
arguments[0], i, evaluator);
904 const int64_t
y = EvalAt(
ct.
arguments[1], i, evaluator);
917 const std::function<int64_t(
Variable*)>& evaluator) {
920 const int64_t
x = EvalAt(
ct.
arguments[0], i, evaluator);
921 const int64_t
y = EvalAt(
ct.
arguments[1], i, evaluator);
934 const std::function<int64_t(
Variable*)>& evaluator) {
935 const int64_t max_index = Eval(
ct.
arguments[1], evaluator) - 1;
936 const int64_t max_value = EvalAt(
ct.
arguments[0], max_index, evaluator);
938 for (
int i = 0; i < max_index; ++i) {
939 if (EvalAt(
ct.
arguments[0], i, evaluator) >= max_value) {
944 for (
int i = max_index + 1; i < Size(
ct.
arguments[0]); i++) {
945 if (EvalAt(
ct.
arguments[0], i, evaluator) > max_value) {
954 const std::function<int64_t(
Variable*)>& evaluator) {
955 int64_t max_value = std::numeric_limits<int64_t>::min();
957 max_value = std::max(max_value, EvalAt(
ct.
arguments[1], i, evaluator));
959 return max_value == Eval(
ct.
arguments[0], evaluator);
963 const std::function<int64_t(
Variable*)>& evaluator) {
964 const int64_t min_index = Eval(
ct.
arguments[1], evaluator) - 1;
965 const int64_t min_value = EvalAt(
ct.
arguments[0], min_index, evaluator);
967 for (
int i = 0; i < min_index; ++i) {
968 if (EvalAt(
ct.
arguments[0], i, evaluator) <= min_value) {
973 for (
int i = min_index + 1; i < Size(
ct.
arguments[0]); i++) {
974 if (EvalAt(
ct.
arguments[0], i, evaluator) < min_value) {
983 const std::function<int64_t(
Variable*)>& evaluator) {
984 int64_t min_value = std::numeric_limits<int64_t>::max();
986 min_value = std::min(min_value, EvalAt(
ct.
arguments[1], i, evaluator));
988 return min_value == Eval(
ct.
arguments[0], evaluator);
991bool CheckNetworkFlowConservation(
994 const std::function<int64_t(
Variable*)>& evaluator) {
995 std::vector<int64_t> balance(balance_input.
values);
996 const int num_arcs = Size(arcs) / 2;
997 for (
int arc = 0;
arc < num_arcs;
arc++) {
1000 const int64_t flow = EvalAt(flow_vars,
arc, evaluator);
1001 balance[
tail] -= flow;
1002 balance[
head] += flow;
1005 for (
const int64_t
value : balance) {
1006 if (
value != 0)
return false;
1013 const std::function<int64_t(
Variable*)>& evaluator) {
1020 const std::function<int64_t(
Variable*)>& evaluator) {
1027 int64_t total_cost = 0;
1029 for (
int arc = 0;
arc < num_arcs;
arc++) {
1032 total_cost += flow * unit_cost;
1035 return total_cost == Eval(
ct.
arguments[5], evaluator);
1039 const std::function<int64_t(
Variable*)>& evaluator) {
1040 const int64_t count = Eval(
ct.
arguments[0], evaluator);
1041 absl::flat_hash_set<int64_t> all_values;
1043 all_values.insert(EvalAt(
ct.
arguments[1], i, evaluator));
1046 return count == all_values.size();
1050 const std::function<int64_t(
Variable*)>& ) {
1055 const std::function<int64_t(
Variable*)>& ) {
1060 const std::function<int64_t(
Variable*)>& evaluator) {
1066 const std::function<int64_t(
Variable*)>& evaluator) {
1072 const std::function<int64_t(
Variable*)>& evaluator) {
1079 const std::function<int64_t(
Variable*)>& evaluator) {
1080 const int64_t low = Eval(
ct.
arguments[0], evaluator);
1081 const int64_t up = Eval(
ct.
arguments[1], evaluator);
1082 const int64_t length = Eval(
ct.
arguments[2], evaluator);
1084 int64_t sliding_sum = 0;
1085 for (
int i = 0; i < std::min<int64_t>(length, Size(
ct.
arguments[3])); ++i) {
1086 sliding_sum += EvalAt(
ct.
arguments[3], i, evaluator);
1088 if (sliding_sum < low || sliding_sum > up) {
1091 for (
int i = length; i < Size(
ct.
arguments[3]); ++i) {
1092 sliding_sum += EvalAt(
ct.
arguments[3], i, evaluator) -
1094 if (sliding_sum < low || sliding_sum > up) {
1102 const std::function<int64_t(
Variable*)>& evaluator) {
1104 absl::flat_hash_map<int64_t, int> init_count;
1105 absl::flat_hash_map<int64_t, int> sorted_count;
1107 init_count[EvalAt(
ct.
arguments[0], i, evaluator)]++;
1108 sorted_count[EvalAt(
ct.
arguments[1], i, evaluator)]++;
1110 if (init_count != sorted_count) {
1113 for (
int i = 0; i < Size(
ct.
arguments[1]) - 1; ++i) {
1123 const std::function<int64_t(
Variable*)>& evaluator) {
1124 absl::flat_hash_set<int64_t> visited;
1127 int64_t current = -1;
1130 if (
next != i && current == -1) {
1132 }
else if (
next == i) {
1133 visited.insert(
next);
1138 const int residual_size = Size(
ct.
arguments[0]) - visited.size();
1139 for (
int i = 0; i < residual_size; ++i) {
1140 const int64_t
next = EvalAt(
ct.
arguments[0], current, evaluator) - base;
1141 visited.insert(
next);
1142 if (
next == current) {
1153 const std::function<int64_t(
Variable*)>& ) {
1157bool CheckSymmetricAllDifferent(
1160 for (
int i = 0; i <
size; ++i) {
1165 const int64_t reverse_value = EvalAt(
ct.
arguments[0],
value, evaluator) - 1;
1166 if (reverse_value != i) {
1174 absl::flat_hash_map<std::string,
1176 std::function<int64_t(
Variable*)>)>>;
1185CallMap CreateCallMap() {
1187 m[
"fzn_all_different_int"] = CheckAllDifferentInt;
1188 m[
"alldifferent_except_0"] = CheckAlldifferentExcept0;
1189 m[
"among"] = CheckAmong;
1190 m[
"array_bool_and"] = CheckArrayBoolAnd;
1191 m[
"array_bool_element"] = CheckArrayIntElement;
1192 m[
"array_bool_or"] = CheckArrayBoolOr;
1193 m[
"array_bool_xor"] = CheckArrayBoolXor;
1194 m[
"array_int_element"] = CheckArrayIntElement;
1195 m[
"array_int_element_nonshifted"] = CheckArrayIntElementNonShifted;
1196 m[
"array_var_bool_element"] = CheckArrayVarIntElement;
1197 m[
"array_var_int_element"] = CheckArrayVarIntElement;
1198 m[
"at_most_int"] = CheckAtMostInt;
1199 m[
"bool_and"] = CheckBoolAnd;
1200 m[
"bool_clause"] = CheckBoolClause;
1201 m[
"bool_eq"] = CheckIntEq;
1202 m[
"bool2int"] = CheckIntEq;
1203 m[
"bool_eq_imp"] = CheckIntEqImp;
1204 m[
"bool_eq_reif"] = CheckIntEqReif;
1205 m[
"bool_ge"] = CheckIntGe;
1206 m[
"bool_ge_imp"] = CheckIntGeImp;
1207 m[
"bool_ge_reif"] = CheckIntGeReif;
1208 m[
"bool_gt"] = CheckIntGt;
1209 m[
"bool_gt_imp"] = CheckIntGtImp;
1210 m[
"bool_gt_reif"] = CheckIntGtReif;
1211 m[
"bool_le"] = CheckIntLe;
1212 m[
"bool_le_imp"] = CheckIntLeImp;
1213 m[
"bool_le_reif"] = CheckIntLeReif;
1214 m[
"bool_left_imp"] = CheckIntLe;
1215 m[
"bool_lin_eq"] = CheckIntLinEq;
1216 m[
"bool_lin_le"] = CheckIntLinLe;
1217 m[
"bool_lt"] = CheckIntLt;
1218 m[
"bool_lt_imp"] = CheckIntLtImp;
1219 m[
"bool_lt_reif"] = CheckIntLtReif;
1220 m[
"bool_ne"] = CheckIntNe;
1221 m[
"bool_ne_imp"] = CheckIntNeImp;
1222 m[
"bool_ne_reif"] = CheckIntNeReif;
1223 m[
"bool_not"] = CheckBoolNot;
1224 m[
"bool_or"] = CheckBoolOr;
1225 m[
"bool_right_imp"] = CheckIntGe;
1226 m[
"bool_xor"] = CheckBoolXor;
1227 m[
"ortools_circuit"] = CheckCircuit;
1228 m[
"count_eq"] = CheckCountEq;
1229 m[
"count"] = CheckCountEq;
1230 m[
"count_geq"] = CheckCountGeq;
1231 m[
"count_gt"] = CheckCountGt;
1232 m[
"count_leq"] = CheckCountLeq;
1233 m[
"count_lt"] = CheckCountLt;
1234 m[
"count_neq"] = CheckCountNeq;
1235 m[
"count_reif"] = CheckCountReif;
1236 m[
"fzn_cumulative"] = CheckCumulative;
1237 m[
"var_cumulative"] = CheckCumulative;
1238 m[
"variable_cumulative"] = CheckCumulative;
1239 m[
"fixed_cumulative"] = CheckCumulative;
1240 m[
"ortools_cumulative_opt"] = CheckCumulativeOpt;
1241 m[
"fzn_diffn"] = CheckDiffn;
1242 m[
"diffn_k_with_sizes"] = CheckDiffnK;
1243 m[
"fzn_diffn_nonstrict"] = CheckDiffnNonStrict;
1244 m[
"diffn_nonstrict_k_with_sizes"] = CheckDiffnNonStrictK;
1245 m[
"fzn_disjunctive"] = CheckDisjunctive;
1246 m[
"fzn_disjunctive_strict"] = CheckDisjunctiveStrict;
1247 m[
"ortools_disjunctive_strict_opt"] = CheckDisjunctiveStrictOpt;
1248 m[
"false_constraint"] = CheckFalseConstraint;
1249 m[
"global_cardinality"] = CheckGlobalCardinality;
1250 m[
"global_cardinality_closed"] = CheckGlobalCardinalityClosed;
1251 m[
"global_cardinality_low_up"] = CheckGlobalCardinalityLowUp;
1252 m[
"global_cardinality_low_up_closed"] = CheckGlobalCardinalityLowUpClosed;
1253 m[
"global_cardinality_old"] = CheckGlobalCardinalityOld;
1254 m[
"int_abs"] = CheckIntAbs;
1255 m[
"int_div"] = CheckIntDiv;
1256 m[
"int_eq"] = CheckIntEq;
1257 m[
"int_eq_imp"] = CheckIntEqImp;
1258 m[
"int_eq_reif"] = CheckIntEqReif;
1259 m[
"int_ge"] = CheckIntGe;
1260 m[
"int_ge_imp"] = CheckIntGeImp;
1261 m[
"int_ge_reif"] = CheckIntGeReif;
1262 m[
"int_gt"] = CheckIntGt;
1263 m[
"int_gt_imp"] = CheckIntGtImp;
1264 m[
"int_gt_reif"] = CheckIntGtReif;
1265 m[
"int_le"] = CheckIntLe;
1266 m[
"int_le_imp"] = CheckIntLeImp;
1267 m[
"int_le_reif"] = CheckIntLeReif;
1268 m[
"int_lin_eq"] = CheckIntLinEq;
1269 m[
"int_lin_eq_imp"] = CheckIntLinEqImp;
1270 m[
"int_lin_eq_reif"] = CheckIntLinEqReif;
1271 m[
"int_lin_ge"] = CheckIntLinGe;
1272 m[
"int_lin_ge_imp"] = CheckIntLinGeImp;
1273 m[
"int_lin_ge_reif"] = CheckIntLinGeReif;
1274 m[
"int_lin_le"] = CheckIntLinLe;
1275 m[
"int_lin_le_imp"] = CheckIntLinLeImp;
1276 m[
"int_lin_le_reif"] = CheckIntLinLeReif;
1277 m[
"int_lin_ne"] = CheckIntLinNe;
1278 m[
"int_lin_ne_imp"] = CheckIntLinNeImp;
1279 m[
"int_lin_ne_reif"] = CheckIntLinNeReif;
1280 m[
"int_lt"] = CheckIntLt;
1281 m[
"int_lt_imp"] = CheckIntLtImp;
1282 m[
"int_lt_reif"] = CheckIntLtReif;
1283 m[
"int_max"] = CheckIntMax;
1284 m[
"int_min"] = CheckIntMin;
1285 m[
"int_minus"] = CheckIntMinus;
1286 m[
"int_mod"] = CheckIntMod;
1287 m[
"int_ne"] = CheckIntNe;
1288 m[
"int_ne_imp"] = CheckIntNeImp;
1289 m[
"int_ne_reif"] = CheckIntNeReif;
1290 m[
"int_negate"] = CheckIntNegate;
1291 m[
"int_plus"] = CheckIntPlus;
1292 m[
"int_times"] = CheckIntTimes;
1293 m[
"ortools_inverse"] = CheckInverse;
1294 m[
"lex_less_bool"] = CheckLexLessInt;
1295 m[
"lex_less_int"] = CheckLexLessInt;
1296 m[
"lex_lesseq_bool"] = CheckLexLesseqInt;
1297 m[
"lex_lesseq_int"] = CheckLexLesseqInt;
1298 m[
"maximum_arg_int"] = CheckMaximumArgInt;
1299 m[
"maximum_int"] = CheckMaximumInt;
1300 m[
"array_int_maximum"] = CheckMaximumInt;
1301 m[
"minimum_arg_int"] = CheckMinimumArgInt;
1302 m[
"minimum_int"] = CheckMinimumInt;
1303 m[
"array_int_minimum"] = CheckMinimumInt;
1304 m[
"ortools_network_flow"] = CheckNetworkFlow;
1305 m[
"ortools_network_flow_cost"] = CheckNetworkFlowCost;
1306 m[
"nvalue"] = CheckNvalue;
1307 m[
"ortools_regular"] = CheckRegular;
1308 m[
"regular_nfa"] = CheckRegularNfa;
1309 m[
"set_in"] = CheckSetIn;
1310 m[
"int_in"] = CheckSetIn;
1311 m[
"set_not_in"] = CheckSetNotIn;
1312 m[
"int_not_in"] = CheckSetNotIn;
1313 m[
"set_in_reif"] = CheckSetInReif;
1314 m[
"sliding_sum"] = CheckSlidingSum;
1315 m[
"sort"] = CheckSort;
1316 m[
"ortools_subcircuit"] = CheckSubCircuit;
1317 m[
"symmetric_all_different"] = CheckSymmetricAllDifferent;
1318 m[
"ortools_table_bool"] = CheckTableInt;
1319 m[
"ortools_table_int"] = CheckTableInt;
1326 const std::function<int64_t(
Variable*)>& evaluator,
1329 const CallMap call_map = CreateCallMap();
1332 const auto& checker = call_map.at(
ct->
type);
1333 if (!checker(*
ct, evaluator)) {