OR-Tools  9.1
checker.cc
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
15 
16 #include <algorithm>
17 #include <cstdint>
18 #include <limits>
19 
20 #include "absl/container/flat_hash_map.h"
21 #include "absl/container/flat_hash_set.h"
22 #include "ortools/base/map_util.h"
23 #include "ortools/flatzinc/model.h"
24 #include "ortools/util/logging.h"
25 
26 namespace operations_research {
27 namespace fz {
28 namespace {
29 
30 // Helpers
31 
32 int64_t Eval(const Argument& arg,
33  const std::function<int64_t(Variable*)>& evaluator) {
34  switch (arg.type) {
35  case Argument::INT_VALUE: {
36  return arg.Value();
37  }
38  case Argument::VAR_REF: {
39  return evaluator(arg.Var());
40  }
41  default: {
42  LOG(FATAL) << "Cannot evaluate " << arg.DebugString();
43  return 0;
44  }
45  }
46 }
47 
48 int Size(const Argument& arg) {
49  return std::max(arg.values.size(), arg.variables.size());
50 }
51 
52 int64_t EvalAt(const Argument& arg, int pos,
53  const std::function<int64_t(Variable*)>& evaluator) {
54  switch (arg.type) {
55  case Argument::INT_LIST: {
56  return arg.ValueAt(pos);
57  }
59  return evaluator(arg.VarAt(pos));
60  }
61  default: {
62  LOG(FATAL) << "Cannot evaluate " << arg.DebugString();
63  return 0;
64  }
65  }
66 }
67 
68 // Checkers
69 
70 bool CheckAllDifferentInt(const Constraint& ct,
71  const std::function<int64_t(Variable*)>& evaluator) {
72  absl::flat_hash_set<int64_t> visited;
73  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
74  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
75  if (gtl::ContainsKey(visited, value)) {
76  return false;
77  }
78  visited.insert(value);
79  }
80 
81  return true;
82 }
83 
84 bool CheckAlldifferentExcept0(
85  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
86  absl::flat_hash_set<int64_t> visited;
87  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
88  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
89  if (value != 0 && gtl::ContainsKey(visited, value)) {
90  return false;
91  }
92  visited.insert(value);
93  }
94 
95  return true;
96 }
97 
98 bool CheckAmong(const Constraint& ct,
99  const std::function<int64_t(Variable*)>& evaluator) {
100  const int64_t expected = Eval(ct.arguments[0], evaluator);
101  int64_t count = 0;
102  for (int i = 0; i < Size(ct.arguments[1]); ++i) {
103  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
104  count += ct.arguments[2].Contains(value);
105  }
106 
107  return count == expected;
108 }
109 
110 bool CheckArrayBoolAnd(const Constraint& ct,
111  const std::function<int64_t(Variable*)>& evaluator) {
112  int64_t result = 1;
113 
114  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
115  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
116  result = std::min(result, value);
117  }
118 
119  return result == Eval(ct.arguments[1], evaluator);
120 }
121 
122 bool CheckArrayBoolOr(const Constraint& ct,
123  const std::function<int64_t(Variable*)>& evaluator) {
124  int64_t result = 0;
125 
126  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
127  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
128  result = std::max(result, value);
129  }
130 
131  return result == Eval(ct.arguments[1], evaluator);
132 }
133 
134 bool CheckArrayBoolXor(const Constraint& ct,
135  const std::function<int64_t(Variable*)>& evaluator) {
136  int64_t result = 0;
137 
138  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
139  result += EvalAt(ct.arguments[0], i, evaluator);
140  }
141 
142  return result % 2 == 1;
143 }
144 
145 bool CheckArrayIntElement(const Constraint& ct,
146  const std::function<int64_t(Variable*)>& evaluator) {
147  if (ct.arguments[0].variables.size() == 2) {
148  // TODO(user): Check 2D element.
149  return true;
150  }
151  // Flatzinc arrays are 1 based.
152  const int64_t shifted_index = Eval(ct.arguments[0], evaluator) - 1;
153  const int64_t element = EvalAt(ct.arguments[1], shifted_index, evaluator);
154  const int64_t target = Eval(ct.arguments[2], evaluator);
155  return element == target;
156 }
157 
158 bool CheckArrayIntElementNonShifted(
159  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
160  CHECK_EQ(ct.arguments[0].variables.size(), 1);
161  const int64_t index = Eval(ct.arguments[0], evaluator);
162  const int64_t element = EvalAt(ct.arguments[1], index, evaluator);
163  const int64_t target = Eval(ct.arguments[2], evaluator);
164  return element == target;
165 }
166 
167 bool CheckArrayVarIntElement(
168  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
169  if (ct.arguments[0].variables.size() == 2) {
170  // TODO(user): Check 2D element.
171  return true;
172  }
173  // Flatzinc arrays are 1 based.
174  const int64_t shifted_index = Eval(ct.arguments[0], evaluator) - 1;
175  const int64_t element = EvalAt(ct.arguments[1], shifted_index, evaluator);
176  const int64_t target = Eval(ct.arguments[2], evaluator);
177  return element == target;
178 }
179 
180 bool CheckAtMostInt(const Constraint& ct,
181  const std::function<int64_t(Variable*)>& evaluator) {
182  const int64_t expected = Eval(ct.arguments[0], evaluator);
183  const int64_t value = Eval(ct.arguments[2], evaluator);
184 
185  int64_t count = 0;
186  for (int i = 0; i < Size(ct.arguments[1]); ++i) {
187  count += EvalAt(ct.arguments[1], i, evaluator) == value;
188  }
189  return count <= expected;
190 }
191 
192 bool CheckBoolAnd(const Constraint& ct,
193  const std::function<int64_t(Variable*)>& evaluator) {
194  const int64_t left = Eval(ct.arguments[0], evaluator);
195  const int64_t right = Eval(ct.arguments[1], evaluator);
196  const int64_t status = Eval(ct.arguments[2], evaluator);
197  return status == std::min(left, right);
198 }
199 
200 bool CheckBoolClause(const Constraint& ct,
201  const std::function<int64_t(Variable*)>& evaluator) {
202  int64_t result = 0;
203 
204  // Positive variables.
205  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
206  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
207  result = std::max(result, value);
208  }
209  // Negative variables.
210  for (int i = 0; i < Size(ct.arguments[1]); ++i) {
211  const int64_t value = EvalAt(ct.arguments[1], i, evaluator);
212  result = std::max(result, 1 - value);
213  }
214 
215  return result;
216 }
217 
218 bool CheckBoolNot(const Constraint& ct,
219  const std::function<int64_t(Variable*)>& evaluator) {
220  const int64_t left = Eval(ct.arguments[0], evaluator);
221  const int64_t right = Eval(ct.arguments[1], evaluator);
222  return left == 1 - right;
223 }
224 
225 bool CheckBoolOr(const Constraint& ct,
226  const std::function<int64_t(Variable*)>& evaluator) {
227  const int64_t left = Eval(ct.arguments[0], evaluator);
228  const int64_t right = Eval(ct.arguments[1], evaluator);
229  const int64_t status = Eval(ct.arguments[2], evaluator);
230  return status == std::max(left, right);
231 }
232 
233 bool CheckBoolXor(const Constraint& ct,
234  const std::function<int64_t(Variable*)>& evaluator) {
235  const int64_t left = Eval(ct.arguments[0], evaluator);
236  const int64_t right = Eval(ct.arguments[1], evaluator);
237  const int64_t target = Eval(ct.arguments[2], evaluator);
238  return target == (left + right == 1);
239 }
240 
241 bool CheckCircuit(const Constraint& ct,
242  const std::function<int64_t(Variable*)>& evaluator) {
243  const int size = Size(ct.arguments[0]);
244  const int base = ct.arguments[1].Value();
245 
246  absl::flat_hash_set<int64_t> visited;
247  int64_t current = 0;
248  for (int i = 0; i < size; ++i) {
249  const int64_t next = EvalAt(ct.arguments[0], current, evaluator) - base;
250  visited.insert(next);
251  current = next;
252  }
253  return visited.size() == size;
254 }
255 
256 int64_t ComputeCount(const Constraint& ct,
257  const std::function<int64_t(Variable*)>& evaluator) {
258  int64_t result = 0;
259  const int64_t value = Eval(ct.arguments[1], evaluator);
260  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
261  result += EvalAt(ct.arguments[0], i, evaluator) == value;
262  }
263  return result;
264 }
265 
266 bool CheckCountEq(const Constraint& ct,
267  const std::function<int64_t(Variable*)>& evaluator) {
268  const int64_t count = ComputeCount(ct, evaluator);
269  const int64_t expected = Eval(ct.arguments[2], evaluator);
270  return count == expected;
271 }
272 
273 bool CheckCountGeq(const Constraint& ct,
274  const std::function<int64_t(Variable*)>& evaluator) {
275  const int64_t count = ComputeCount(ct, evaluator);
276  const int64_t expected = Eval(ct.arguments[2], evaluator);
277  return count >= expected;
278 }
279 
280 bool CheckCountGt(const Constraint& ct,
281  const std::function<int64_t(Variable*)>& evaluator) {
282  const int64_t count = ComputeCount(ct, evaluator);
283  const int64_t expected = Eval(ct.arguments[2], evaluator);
284  return count > expected;
285 }
286 
287 bool CheckCountLeq(const Constraint& ct,
288  const std::function<int64_t(Variable*)>& evaluator) {
289  const int64_t count = ComputeCount(ct, evaluator);
290  const int64_t expected = Eval(ct.arguments[2], evaluator);
291  return count <= expected;
292 }
293 
294 bool CheckCountLt(const Constraint& ct,
295  const std::function<int64_t(Variable*)>& evaluator) {
296  const int64_t count = ComputeCount(ct, evaluator);
297  const int64_t expected = Eval(ct.arguments[2], evaluator);
298  return count < expected;
299 }
300 
301 bool CheckCountNeq(const Constraint& ct,
302  const std::function<int64_t(Variable*)>& evaluator) {
303  const int64_t count = ComputeCount(ct, evaluator);
304  const int64_t expected = Eval(ct.arguments[2], evaluator);
305  return count != expected;
306 }
307 
308 bool CheckCountReif(const Constraint& ct,
309  const std::function<int64_t(Variable*)>& evaluator) {
310  const int64_t count = ComputeCount(ct, evaluator);
311  const int64_t expected = Eval(ct.arguments[2], evaluator);
312  const int64_t status = Eval(ct.arguments[3], evaluator);
313  return status == (expected == count);
314 }
315 
316 bool CheckCumulative(const Constraint& ct,
317  const std::function<int64_t(Variable*)>& evaluator) {
318  // TODO(user): Improve complexity for large durations.
319  const int64_t capacity = Eval(ct.arguments[3], evaluator);
320  const int size = Size(ct.arguments[0]);
321  CHECK_EQ(size, Size(ct.arguments[1]));
322  CHECK_EQ(size, Size(ct.arguments[2]));
323  absl::flat_hash_map<int64_t, int64_t> usage;
324  for (int i = 0; i < size; ++i) {
325  const int64_t start = EvalAt(ct.arguments[0], i, evaluator);
326  const int64_t duration = EvalAt(ct.arguments[1], i, evaluator);
327  const int64_t requirement = EvalAt(ct.arguments[2], i, evaluator);
328  for (int64_t t = start; t < start + duration; ++t) {
329  usage[t] += requirement;
330  if (usage[t] > capacity) {
331  return false;
332  }
333  }
334  }
335  return true;
336 }
337 
338 bool CheckDiffn(const Constraint& ct,
339  const std::function<int64_t(Variable*)>& evaluator) {
340  return true;
341 }
342 
343 bool CheckDiffnK(const Constraint& ct,
344  const std::function<int64_t(Variable*)>& evaluator) {
345  return true;
346 }
347 
348 bool CheckDiffnNonStrict(const Constraint& ct,
349  const std::function<int64_t(Variable*)>& evaluator) {
350  return true;
351 }
352 
353 bool CheckDiffnNonStrictK(const Constraint& ct,
354  const std::function<int64_t(Variable*)>& evaluator) {
355  return true;
356 }
357 
358 bool CheckDisjunctive(const Constraint& ct,
359  const std::function<int64_t(Variable*)>& evaluator) {
360  return true;
361 }
362 
363 bool CheckDisjunctiveStrict(
364  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
365  return true;
366 }
367 
368 bool CheckFalseConstraint(const Constraint& ct,
369  const std::function<int64_t(Variable*)>& evaluator) {
370  return false;
371 }
372 
373 std::vector<int64_t> ComputeGlobalCardinalityCards(
374  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
375  std::vector<int64_t> cards(Size(ct.arguments[1]), 0);
376  absl::flat_hash_map<int64_t, int> positions;
377  for (int i = 0; i < ct.arguments[1].values.size(); ++i) {
378  const int64_t value = ct.arguments[1].values[i];
379  CHECK(!gtl::ContainsKey(positions, value));
380  positions[value] = i;
381  }
382  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
383  const int value = EvalAt(ct.arguments[0], i, evaluator);
384  if (gtl::ContainsKey(positions, value)) {
385  cards[positions[value]]++;
386  }
387  }
388  return cards;
389 }
390 
391 bool CheckGlobalCardinality(
392  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
393  const std::vector<int64_t> cards =
394  ComputeGlobalCardinalityCards(ct, evaluator);
395  CHECK_EQ(cards.size(), Size(ct.arguments[2]));
396  for (int i = 0; i < Size(ct.arguments[2]); ++i) {
397  const int64_t card = EvalAt(ct.arguments[2], i, evaluator);
398  if (card != cards[i]) {
399  return false;
400  }
401  }
402  return true;
403 }
404 
405 bool CheckGlobalCardinalityClosed(
406  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
407  const std::vector<int64_t> cards =
408  ComputeGlobalCardinalityCards(ct, evaluator);
409  CHECK_EQ(cards.size(), Size(ct.arguments[2]));
410  for (int i = 0; i < Size(ct.arguments[2]); ++i) {
411  const int64_t card = EvalAt(ct.arguments[2], i, evaluator);
412  if (card != cards[i]) {
413  return false;
414  }
415  }
416  int64_t sum_of_cards = 0;
417  for (int64_t card : cards) {
418  sum_of_cards += card;
419  }
420  return sum_of_cards == Size(ct.arguments[0]);
421 }
422 
423 bool CheckGlobalCardinalityLowUp(
424  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
425  const std::vector<int64_t> cards =
426  ComputeGlobalCardinalityCards(ct, evaluator);
427  CHECK_EQ(cards.size(), ct.arguments[2].values.size());
428  CHECK_EQ(cards.size(), ct.arguments[3].values.size());
429  for (int i = 0; i < cards.size(); ++i) {
430  const int64_t card = cards[i];
431  if (card < ct.arguments[2].values[i] || card > ct.arguments[3].values[i]) {
432  return false;
433  }
434  }
435  return true;
436 }
437 
438 bool CheckGlobalCardinalityLowUpClosed(
439  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
440  const std::vector<int64_t> cards =
441  ComputeGlobalCardinalityCards(ct, evaluator);
442  CHECK_EQ(cards.size(), ct.arguments[2].values.size());
443  CHECK_EQ(cards.size(), ct.arguments[3].values.size());
444  for (int i = 0; i < cards.size(); ++i) {
445  const int64_t card = cards[i];
446  if (card < ct.arguments[2].values[i] || card > ct.arguments[3].values[i]) {
447  return false;
448  }
449  }
450  int64_t sum_of_cards = 0;
451  for (int64_t card : cards) {
452  sum_of_cards += card;
453  }
454  return sum_of_cards == Size(ct.arguments[0]);
455 }
456 
457 bool CheckGlobalCardinalityOld(
458  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
459  const int size = Size(ct.arguments[1]);
460  std::vector<int64_t> cards(size, 0);
461  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
462  const int64_t value = EvalAt(ct.arguments[0], i, evaluator);
463  if (value >= 0 && value < size) {
464  cards[value]++;
465  }
466  }
467  for (int i = 0; i < size; ++i) {
468  const int64_t card = EvalAt(ct.arguments[1], i, evaluator);
469  if (card != cards[i]) {
470  return false;
471  }
472  }
473  return true;
474 }
475 
476 bool CheckIntAbs(const Constraint& ct,
477  const std::function<int64_t(Variable*)>& evaluator) {
478  const int64_t left = Eval(ct.arguments[0], evaluator);
479  const int64_t right = Eval(ct.arguments[1], evaluator);
480  return std::abs(left) == right;
481 }
482 
483 bool CheckIntDiv(const Constraint& ct,
484  const std::function<int64_t(Variable*)>& evaluator) {
485  const int64_t left = Eval(ct.arguments[0], evaluator);
486  const int64_t right = Eval(ct.arguments[1], evaluator);
487  const int64_t target = Eval(ct.arguments[2], evaluator);
488  return target == left / right;
489 }
490 
491 bool CheckIntEq(const Constraint& ct,
492  const std::function<int64_t(Variable*)>& evaluator) {
493  const int64_t left = Eval(ct.arguments[0], evaluator);
494  const int64_t right = Eval(ct.arguments[1], evaluator);
495  return left == right;
496 }
497 
498 bool CheckIntEqImp(const Constraint& ct,
499  const std::function<int64_t(Variable*)>& evaluator) {
500  const int64_t left = Eval(ct.arguments[0], evaluator);
501  const int64_t right = Eval(ct.arguments[1], evaluator);
502  const bool status = Eval(ct.arguments[2], evaluator) != 0;
503  return (status && (left == right)) || !status;
504 }
505 
506 bool CheckIntEqReif(const Constraint& ct,
507  const std::function<int64_t(Variable*)>& evaluator) {
508  const int64_t left = Eval(ct.arguments[0], evaluator);
509  const int64_t right = Eval(ct.arguments[1], evaluator);
510  const bool status = Eval(ct.arguments[2], evaluator) != 0;
511  return status == (left == right);
512 }
513 
514 bool CheckIntGe(const Constraint& ct,
515  const std::function<int64_t(Variable*)>& evaluator) {
516  const int64_t left = Eval(ct.arguments[0], evaluator);
517  const int64_t right = Eval(ct.arguments[1], evaluator);
518  return left >= right;
519 }
520 
521 bool CheckIntGeImp(const Constraint& ct,
522  const std::function<int64_t(Variable*)>& evaluator) {
523  const int64_t left = Eval(ct.arguments[0], evaluator);
524  const int64_t right = Eval(ct.arguments[1], evaluator);
525  const bool status = Eval(ct.arguments[2], evaluator) != 0;
526  return (status && (left >= right)) || !status;
527 }
528 
529 bool CheckIntGeReif(const Constraint& ct,
530  const std::function<int64_t(Variable*)>& evaluator) {
531  const int64_t left = Eval(ct.arguments[0], evaluator);
532  const int64_t right = Eval(ct.arguments[1], evaluator);
533  const bool status = Eval(ct.arguments[2], evaluator) != 0;
534  return status == (left >= right);
535 }
536 
537 bool CheckIntGt(const Constraint& ct,
538  const std::function<int64_t(Variable*)>& evaluator) {
539  const int64_t left = Eval(ct.arguments[0], evaluator);
540  const int64_t right = Eval(ct.arguments[1], evaluator);
541  return left > right;
542 }
543 
544 bool CheckIntGtImp(const Constraint& ct,
545  const std::function<int64_t(Variable*)>& evaluator) {
546  const int64_t left = Eval(ct.arguments[0], evaluator);
547  const int64_t right = Eval(ct.arguments[1], evaluator);
548  const bool status = Eval(ct.arguments[2], evaluator) != 0;
549  return (status && (left > right)) || !status;
550 }
551 
552 bool CheckIntGtReif(const Constraint& ct,
553  const std::function<int64_t(Variable*)>& evaluator) {
554  const int64_t left = Eval(ct.arguments[0], evaluator);
555  const int64_t right = Eval(ct.arguments[1], evaluator);
556  const bool status = Eval(ct.arguments[2], evaluator) != 0;
557  return status == (left > right);
558 }
559 
560 bool CheckIntLe(const Constraint& ct,
561  const std::function<int64_t(Variable*)>& evaluator) {
562  const int64_t left = Eval(ct.arguments[0], evaluator);
563  const int64_t right = Eval(ct.arguments[1], evaluator);
564  return left <= right;
565 }
566 
567 bool CheckIntLeImp(const Constraint& ct,
568  const std::function<int64_t(Variable*)>& evaluator) {
569  const int64_t left = Eval(ct.arguments[0], evaluator);
570  const int64_t right = Eval(ct.arguments[1], evaluator);
571  const bool status = Eval(ct.arguments[2], evaluator) != 0;
572  return (status && (left <= right)) || !status;
573 }
574 
575 bool CheckIntLeReif(const Constraint& ct,
576  const std::function<int64_t(Variable*)>& evaluator) {
577  const int64_t left = Eval(ct.arguments[0], evaluator);
578  const int64_t right = Eval(ct.arguments[1], evaluator);
579  const bool status = Eval(ct.arguments[2], evaluator) != 0;
580  return status == (left <= right);
581 }
582 
583 bool CheckIntLt(const Constraint& ct,
584  const std::function<int64_t(Variable*)>& evaluator) {
585  const int64_t left = Eval(ct.arguments[0], evaluator);
586  const int64_t right = Eval(ct.arguments[1], evaluator);
587  return left < right;
588 }
589 
590 bool CheckIntLtImp(const Constraint& ct,
591  const std::function<int64_t(Variable*)>& evaluator) {
592  const int64_t left = Eval(ct.arguments[0], evaluator);
593  const int64_t right = Eval(ct.arguments[1], evaluator);
594  const bool status = Eval(ct.arguments[2], evaluator) != 0;
595  return (status && (left < right)) || !status;
596 }
597 
598 bool CheckIntLtReif(const Constraint& ct,
599  const std::function<int64_t(Variable*)>& evaluator) {
600  const int64_t left = Eval(ct.arguments[0], evaluator);
601  const int64_t right = Eval(ct.arguments[1], evaluator);
602  const bool status = Eval(ct.arguments[2], evaluator) != 0;
603  return status == (left < right);
604 }
605 
606 int64_t ComputeIntLin(const Constraint& ct,
607  const std::function<int64_t(Variable*)>& evaluator) {
608  int64_t result = 0;
609  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
610  result += EvalAt(ct.arguments[0], i, evaluator) *
611  EvalAt(ct.arguments[1], i, evaluator);
612  }
613  return result;
614 }
615 
616 bool CheckIntLinEq(const Constraint& ct,
617  const std::function<int64_t(Variable*)>& evaluator) {
618  const int64_t left = ComputeIntLin(ct, evaluator);
619  const int64_t right = Eval(ct.arguments[2], evaluator);
620  return left == right;
621 }
622 
623 bool CheckIntLinEqImp(const Constraint& ct,
624  const std::function<int64_t(Variable*)>& evaluator) {
625  const int64_t left = ComputeIntLin(ct, evaluator);
626  const int64_t right = Eval(ct.arguments[2], evaluator);
627  const bool status = Eval(ct.arguments[3], evaluator) != 0;
628  return (status && (left == right)) || !status;
629 }
630 
631 bool CheckIntLinEqReif(const Constraint& ct,
632  const std::function<int64_t(Variable*)>& evaluator) {
633  const int64_t left = ComputeIntLin(ct, evaluator);
634  const int64_t right = Eval(ct.arguments[2], evaluator);
635  const bool status = Eval(ct.arguments[3], evaluator) != 0;
636  return status == (left == right);
637 }
638 
639 bool CheckIntLinGe(const Constraint& ct,
640  const std::function<int64_t(Variable*)>& evaluator) {
641  const int64_t left = ComputeIntLin(ct, evaluator);
642  const int64_t right = Eval(ct.arguments[2], evaluator);
643  return left >= right;
644 }
645 
646 bool CheckIntLinGeImp(const Constraint& ct,
647  const std::function<int64_t(Variable*)>& evaluator) {
648  const int64_t left = ComputeIntLin(ct, evaluator);
649  const int64_t right = Eval(ct.arguments[2], evaluator);
650  const bool status = Eval(ct.arguments[3], evaluator) != 0;
651  return (status && (left >= right)) || !status;
652 }
653 
654 bool CheckIntLinGeReif(const Constraint& ct,
655  const std::function<int64_t(Variable*)>& evaluator) {
656  const int64_t left = ComputeIntLin(ct, evaluator);
657  const int64_t right = Eval(ct.arguments[2], evaluator);
658  const bool status = Eval(ct.arguments[3], evaluator) != 0;
659  return status == (left >= right);
660 }
661 
662 bool CheckIntLinLe(const Constraint& ct,
663  const std::function<int64_t(Variable*)>& evaluator) {
664  const int64_t left = ComputeIntLin(ct, evaluator);
665  const int64_t right = Eval(ct.arguments[2], evaluator);
666  return left <= right;
667 }
668 
669 bool CheckIntLinLeImp(const Constraint& ct,
670  const std::function<int64_t(Variable*)>& evaluator) {
671  const int64_t left = ComputeIntLin(ct, evaluator);
672  const int64_t right = Eval(ct.arguments[2], evaluator);
673  const bool status = Eval(ct.arguments[3], evaluator) != 0;
674  return (status && (left <= right)) || !status;
675 }
676 
677 bool CheckIntLinLeReif(const Constraint& ct,
678  const std::function<int64_t(Variable*)>& evaluator) {
679  const int64_t left = ComputeIntLin(ct, evaluator);
680  const int64_t right = Eval(ct.arguments[2], evaluator);
681  const bool status = Eval(ct.arguments[3], evaluator) != 0;
682  return status == (left <= right);
683 }
684 
685 bool CheckIntLinNe(const Constraint& ct,
686  const std::function<int64_t(Variable*)>& evaluator) {
687  const int64_t left = ComputeIntLin(ct, evaluator);
688  const int64_t right = Eval(ct.arguments[2], evaluator);
689  return left != right;
690 }
691 
692 bool CheckIntLinNeImp(const Constraint& ct,
693  const std::function<int64_t(Variable*)>& evaluator) {
694  const int64_t left = ComputeIntLin(ct, evaluator);
695  const int64_t right = Eval(ct.arguments[2], evaluator);
696  const bool status = Eval(ct.arguments[3], evaluator) != 0;
697  return (status && (left != right)) || !status;
698 }
699 
700 bool CheckIntLinNeReif(const Constraint& ct,
701  const std::function<int64_t(Variable*)>& evaluator) {
702  const int64_t left = ComputeIntLin(ct, evaluator);
703  const int64_t right = Eval(ct.arguments[2], evaluator);
704  const bool status = Eval(ct.arguments[3], evaluator) != 0;
705  return status == (left != right);
706 }
707 
708 bool CheckIntMax(const Constraint& ct,
709  const std::function<int64_t(Variable*)>& evaluator) {
710  const int64_t left = Eval(ct.arguments[0], evaluator);
711  const int64_t right = Eval(ct.arguments[1], evaluator);
712  const int64_t status = Eval(ct.arguments[2], evaluator);
713  return status == std::max(left, right);
714 }
715 
716 bool CheckIntMin(const Constraint& ct,
717  const std::function<int64_t(Variable*)>& evaluator) {
718  const int64_t left = Eval(ct.arguments[0], evaluator);
719  const int64_t right = Eval(ct.arguments[1], evaluator);
720  const int64_t status = Eval(ct.arguments[2], evaluator);
721  return status == std::min(left, right);
722 }
723 
724 bool CheckIntMinus(const Constraint& ct,
725  const std::function<int64_t(Variable*)>& evaluator) {
726  const int64_t left = Eval(ct.arguments[0], evaluator);
727  const int64_t right = Eval(ct.arguments[1], evaluator);
728  const int64_t target = Eval(ct.arguments[2], evaluator);
729  return target == left - right;
730 }
731 
732 bool CheckIntMod(const Constraint& ct,
733  const std::function<int64_t(Variable*)>& evaluator) {
734  const int64_t left = Eval(ct.arguments[0], evaluator);
735  const int64_t right = Eval(ct.arguments[1], evaluator);
736  const int64_t target = Eval(ct.arguments[2], evaluator);
737  return target == left % right;
738 }
739 
740 bool CheckIntNe(const Constraint& ct,
741  const std::function<int64_t(Variable*)>& evaluator) {
742  const int64_t left = Eval(ct.arguments[0], evaluator);
743  const int64_t right = Eval(ct.arguments[1], evaluator);
744  return left != right;
745 }
746 
747 bool CheckIntNeImp(const Constraint& ct,
748  const std::function<int64_t(Variable*)>& evaluator) {
749  const int64_t left = Eval(ct.arguments[0], evaluator);
750  const int64_t right = Eval(ct.arguments[1], evaluator);
751  const bool status = Eval(ct.arguments[2], evaluator) != 0;
752  return (status && (left != right)) || !status;
753 }
754 
755 bool CheckIntNeReif(const Constraint& ct,
756  const std::function<int64_t(Variable*)>& evaluator) {
757  const int64_t left = Eval(ct.arguments[0], evaluator);
758  const int64_t right = Eval(ct.arguments[1], evaluator);
759  const bool status = Eval(ct.arguments[2], evaluator) != 0;
760  return status == (left != right);
761 }
762 
763 bool CheckIntNegate(const Constraint& ct,
764  const std::function<int64_t(Variable*)>& evaluator) {
765  const int64_t left = Eval(ct.arguments[0], evaluator);
766  const int64_t right = Eval(ct.arguments[1], evaluator);
767  return left == -right;
768 }
769 
770 bool CheckIntPlus(const Constraint& ct,
771  const std::function<int64_t(Variable*)>& evaluator) {
772  const int64_t left = Eval(ct.arguments[0], evaluator);
773  const int64_t right = Eval(ct.arguments[1], evaluator);
774  const int64_t target = Eval(ct.arguments[2], evaluator);
775  return target == left + right;
776 }
777 
778 bool CheckIntTimes(const Constraint& ct,
779  const std::function<int64_t(Variable*)>& evaluator) {
780  const int64_t left = Eval(ct.arguments[0], evaluator);
781  const int64_t right = Eval(ct.arguments[1], evaluator);
782  const int64_t target = Eval(ct.arguments[2], evaluator);
783  return target == left * right;
784 }
785 
786 bool CheckInverse(const Constraint& ct,
787  const std::function<int64_t(Variable*)>& evaluator) {
788  CHECK_EQ(Size(ct.arguments[0]), Size(ct.arguments[1]));
789  const int size = Size(ct.arguments[0]);
790  const int f_base = ct.arguments[2].Value();
791  const int invf_base = ct.arguments[3].Value();
792  // Check all bounds.
793  for (int i = 0; i < size; ++i) {
794  const int64_t x = EvalAt(ct.arguments[0], i, evaluator) - invf_base;
795  const int64_t y = EvalAt(ct.arguments[1], i, evaluator) - f_base;
796  if (x < 0 || x >= size || y < 0 || y >= size) {
797  return false;
798  }
799  }
800 
801  // Check f-1(f(i)) = i.
802  for (int i = 0; i < size; ++i) {
803  const int64_t fi = EvalAt(ct.arguments[0], i, evaluator) - invf_base;
804  const int64_t invf_fi = EvalAt(ct.arguments[1], fi, evaluator) - f_base;
805  if (invf_fi != i) {
806  return false;
807  }
808  }
809 
810  return true;
811 }
812 
813 bool CheckLexLessInt(const Constraint& ct,
814  const std::function<int64_t(Variable*)>& evaluator) {
815  CHECK_EQ(Size(ct.arguments[0]), Size(ct.arguments[1]));
816  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
817  const int64_t x = EvalAt(ct.arguments[0], i, evaluator);
818  const int64_t y = EvalAt(ct.arguments[1], i, evaluator);
819  if (x < y) {
820  return true;
821  }
822  if (x > y) {
823  return false;
824  }
825  }
826  // We are at the end of the list. The two chains are equals.
827  return false;
828 }
829 
830 bool CheckLexLesseqInt(const Constraint& ct,
831  const std::function<int64_t(Variable*)>& evaluator) {
832  CHECK_EQ(Size(ct.arguments[0]), Size(ct.arguments[1]));
833  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
834  const int64_t x = EvalAt(ct.arguments[0], i, evaluator);
835  const int64_t y = EvalAt(ct.arguments[1], i, evaluator);
836  if (x < y) {
837  return true;
838  }
839  if (x > y) {
840  return false;
841  }
842  }
843  // We are at the end of the list. The two chains are equals.
844  return true;
845 }
846 
847 bool CheckMaximumArgInt(const Constraint& ct,
848  const std::function<int64_t(Variable*)>& evaluator) {
849  const int64_t max_index = Eval(ct.arguments[1], evaluator) - 1;
850  const int64_t max_value = EvalAt(ct.arguments[0], max_index, evaluator);
851  // Checks that all value before max_index are < max_value.
852  for (int i = 0; i < max_index; ++i) {
853  if (EvalAt(ct.arguments[0], i, evaluator) >= max_value) {
854  return false;
855  }
856  }
857  // Checks that all value after max_index are <= max_value.
858  for (int i = max_index + 1; i < Size(ct.arguments[0]); i++) {
859  if (EvalAt(ct.arguments[0], i, evaluator) > max_value) {
860  return false;
861  }
862  }
863 
864  return true;
865 }
866 
867 bool CheckMaximumInt(const Constraint& ct,
868  const std::function<int64_t(Variable*)>& evaluator) {
869  int64_t max_value = std::numeric_limits<int64_t>::min();
870  for (int i = 0; i < Size(ct.arguments[1]); ++i) {
871  max_value = std::max(max_value, EvalAt(ct.arguments[1], i, evaluator));
872  }
873  return max_value == Eval(ct.arguments[0], evaluator);
874 }
875 
876 bool CheckMinimumArgInt(const Constraint& ct,
877  const std::function<int64_t(Variable*)>& evaluator) {
878  const int64_t min_index = Eval(ct.arguments[1], evaluator) - 1;
879  const int64_t min_value = EvalAt(ct.arguments[0], min_index, evaluator);
880  // Checks that all value before min_index are > min_value.
881  for (int i = 0; i < min_index; ++i) {
882  if (EvalAt(ct.arguments[0], i, evaluator) <= min_value) {
883  return false;
884  }
885  }
886  // Checks that all value after min_index are >= min_value.
887  for (int i = min_index + 1; i < Size(ct.arguments[0]); i++) {
888  if (EvalAt(ct.arguments[0], i, evaluator) < min_value) {
889  return false;
890  }
891  }
892 
893  return true;
894 }
895 
896 bool CheckMinimumInt(const Constraint& ct,
897  const std::function<int64_t(Variable*)>& evaluator) {
898  int64_t min_value = std::numeric_limits<int64_t>::max();
899  for (int i = 0; i < Size(ct.arguments[1]); ++i) {
900  min_value = std::min(min_value, EvalAt(ct.arguments[1], i, evaluator));
901  }
902  return min_value == Eval(ct.arguments[0], evaluator);
903 }
904 
905 bool CheckNetworkFlowConservation(
906  const Argument& arcs, const Argument& balance_input,
907  const Argument& flow_vars,
908  const std::function<int64_t(Variable*)>& evaluator) {
909  std::vector<int64_t> balance(balance_input.values);
910 
911  const int num_arcs = Size(arcs) / 2;
912  for (int arc = 0; arc < num_arcs; arc++) {
913  const int tail = arcs.values[arc * 2] - 1;
914  const int head = arcs.values[arc * 2 + 1] - 1;
915  const int64_t flow = EvalAt(flow_vars, arc, evaluator);
916  balance[tail] -= flow;
917  balance[head] += flow;
918  }
919 
920  for (const int64_t value : balance) {
921  if (value != 0) return false;
922  }
923 
924  return true;
925 }
926 
927 bool CheckNetworkFlow(const Constraint& ct,
928  const std::function<int64_t(Variable*)>& evaluator) {
929  return CheckNetworkFlowConservation(ct.arguments[0], ct.arguments[1],
930  ct.arguments[2], evaluator);
931 }
932 
933 bool CheckNetworkFlowCost(const Constraint& ct,
934  const std::function<int64_t(Variable*)>& evaluator) {
935  if (!CheckNetworkFlowConservation(ct.arguments[0], ct.arguments[1],
936  ct.arguments[3], evaluator)) {
937  return false;
938  }
939 
940  int64_t total_cost = 0;
941  const int num_arcs = Size(ct.arguments[3]);
942  for (int arc = 0; arc < num_arcs; arc++) {
943  const int64_t flow = EvalAt(ct.arguments[3], arc, evaluator);
944  const int64_t cost = EvalAt(ct.arguments[2], arc, evaluator);
945  total_cost += flow * cost;
946  }
947 
948  return total_cost == Eval(ct.arguments[4], evaluator);
949 }
950 
951 bool CheckNvalue(const Constraint& ct,
952  const std::function<int64_t(Variable*)>& evaluator) {
953  const int64_t count = Eval(ct.arguments[0], evaluator);
954  absl::flat_hash_set<int64_t> all_values;
955  for (int i = 0; i < Size(ct.arguments[1]); ++i) {
956  all_values.insert(EvalAt(ct.arguments[1], i, evaluator));
957  }
958 
959  return count == all_values.size();
960 }
961 
962 bool CheckRegular(const Constraint& ct,
963  const std::function<int64_t(Variable*)>& evaluator) {
964  return true;
965 }
966 
967 bool CheckRegularNfa(const Constraint& ct,
968  const std::function<int64_t(Variable*)>& evaluator) {
969  return true;
970 }
971 
972 bool CheckSetIn(const Constraint& ct,
973  const std::function<int64_t(Variable*)>& evaluator) {
974  const int64_t value = Eval(ct.arguments[0], evaluator);
975  return ct.arguments[1].Contains(value);
976 }
977 
978 bool CheckSetNotIn(const Constraint& ct,
979  const std::function<int64_t(Variable*)>& evaluator) {
980  const int64_t value = Eval(ct.arguments[0], evaluator);
981  return !ct.arguments[1].Contains(value);
982 }
983 
984 bool CheckSetInReif(const Constraint& ct,
985  const std::function<int64_t(Variable*)>& evaluator) {
986  const int64_t value = Eval(ct.arguments[0], evaluator);
987  const int64_t status = Eval(ct.arguments[2], evaluator);
988  return status == ct.arguments[1].Contains(value);
989 }
990 
991 bool CheckSlidingSum(const Constraint& ct,
992  const std::function<int64_t(Variable*)>& evaluator) {
993  const int64_t low = Eval(ct.arguments[0], evaluator);
994  const int64_t up = Eval(ct.arguments[1], evaluator);
995  const int64_t length = Eval(ct.arguments[2], evaluator);
996  // Compute initial sum.
997  int64_t sliding_sum = 0;
998  for (int i = 0; i < std::min<int64_t>(length, Size(ct.arguments[3])); ++i) {
999  sliding_sum += EvalAt(ct.arguments[3], i, evaluator);
1000  }
1001  if (sliding_sum < low || sliding_sum > up) {
1002  return false;
1003  }
1004  for (int i = length; i < Size(ct.arguments[3]); ++i) {
1005  sliding_sum += EvalAt(ct.arguments[3], i, evaluator) -
1006  EvalAt(ct.arguments[3], i - length, evaluator);
1007  if (sliding_sum < low || sliding_sum > up) {
1008  return false;
1009  }
1010  }
1011  return true;
1012 }
1013 
1014 bool CheckSort(const Constraint& ct,
1015  const std::function<int64_t(Variable*)>& evaluator) {
1016  CHECK_EQ(Size(ct.arguments[0]), Size(ct.arguments[1]));
1017  absl::flat_hash_map<int64_t, int> init_count;
1018  absl::flat_hash_map<int64_t, int> sorted_count;
1019  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
1020  init_count[EvalAt(ct.arguments[0], i, evaluator)]++;
1021  sorted_count[EvalAt(ct.arguments[1], i, evaluator)]++;
1022  }
1023  if (init_count != sorted_count) {
1024  return false;
1025  }
1026  for (int i = 0; i < Size(ct.arguments[1]) - 1; ++i) {
1027  if (EvalAt(ct.arguments[1], i, evaluator) >
1028  EvalAt(ct.arguments[1], i, evaluator)) {
1029  return false;
1030  }
1031  }
1032  return true;
1033 }
1034 
1035 bool CheckSubCircuit(const Constraint& ct,
1036  const std::function<int64_t(Variable*)>& evaluator) {
1037  absl::flat_hash_set<int64_t> visited;
1038  const int base = ct.arguments[1].Value();
1039  // Find inactive nodes (pointing to themselves).
1040  int64_t current = -1;
1041  for (int i = 0; i < Size(ct.arguments[0]); ++i) {
1042  const int64_t next = EvalAt(ct.arguments[0], i, evaluator) - base;
1043  if (next != i && current == -1) {
1044  current = next;
1045  } else if (next == i) {
1046  visited.insert(next);
1047  }
1048  }
1049 
1050  // Try to find a path of length 'residual_size'.
1051  const int residual_size = Size(ct.arguments[0]) - visited.size();
1052  for (int i = 0; i < residual_size; ++i) {
1053  const int64_t next = EvalAt(ct.arguments[0], current, evaluator) - base;
1054  visited.insert(next);
1055  if (next == current) {
1056  return false;
1057  }
1058  current = next;
1059  }
1060 
1061  // Have we visited all nodes?
1062  return visited.size() == Size(ct.arguments[0]);
1063 }
1064 
1065 bool CheckTableInt(const Constraint& ct,
1066  const std::function<int64_t(Variable*)>& evaluator) {
1067  return true;
1068 }
1069 
1070 bool CheckSymmetricAllDifferent(
1071  const Constraint& ct, const std::function<int64_t(Variable*)>& evaluator) {
1072  const int size = Size(ct.arguments[0]);
1073  for (int i = 0; i < size; ++i) {
1074  const int64_t value = EvalAt(ct.arguments[0], i, evaluator) - 1;
1075  if (value < 0 || value >= size) {
1076  return false;
1077  }
1078  const int64_t reverse_value = EvalAt(ct.arguments[0], value, evaluator) - 1;
1079  if (reverse_value != i) {
1080  return false;
1081  }
1082  }
1083  return true;
1084 }
1085 
1086 using CallMap =
1087  absl::flat_hash_map<std::string,
1088  std::function<bool(const Constraint& ct,
1089  std::function<int64_t(Variable*)>)>>;
1090 
1091 // Creates a map between flatzinc predicates and CP-SAT builders.
1092 //
1093 // Predicates starting with fzn_ are predicates with the same name in flatzinc
1094 // and in minizinc. The fzn_ prefix is added to differentiate them.
1095 //
1096 // Predicates starting with ortools_ are predicates defined only in or-tools.
1097 // They are created at compilation time when using the or-tools mzn library.
1098 CallMap CreateCallMap() {
1099  CallMap m;
1100  m["fzn_all_different_int"] = CheckAllDifferentInt;
1101  m["alldifferent_except_0"] = CheckAlldifferentExcept0;
1102  m["among"] = CheckAmong;
1103  m["array_bool_and"] = CheckArrayBoolAnd;
1104  m["array_bool_element"] = CheckArrayIntElement;
1105  m["array_bool_or"] = CheckArrayBoolOr;
1106  m["array_bool_xor"] = CheckArrayBoolXor;
1107  m["array_int_element"] = CheckArrayIntElement;
1108  m["array_int_element_nonshifted"] = CheckArrayIntElementNonShifted;
1109  m["array_var_bool_element"] = CheckArrayVarIntElement;
1110  m["array_var_int_element"] = CheckArrayVarIntElement;
1111  m["at_most_int"] = CheckAtMostInt;
1112  m["bool_and"] = CheckBoolAnd;
1113  m["bool_clause"] = CheckBoolClause;
1114  m["bool_eq"] = CheckIntEq;
1115  m["bool2int"] = CheckIntEq;
1116  m["bool_eq_imp"] = CheckIntEqImp;
1117  m["bool_eq_reif"] = CheckIntEqReif;
1118  m["bool_ge"] = CheckIntGe;
1119  m["bool_ge_imp"] = CheckIntGeImp;
1120  m["bool_ge_reif"] = CheckIntGeReif;
1121  m["bool_gt"] = CheckIntGt;
1122  m["bool_gt_imp"] = CheckIntGtImp;
1123  m["bool_gt_reif"] = CheckIntGtReif;
1124  m["bool_le"] = CheckIntLe;
1125  m["bool_le_imp"] = CheckIntLeImp;
1126  m["bool_le_reif"] = CheckIntLeReif;
1127  m["bool_left_imp"] = CheckIntLe;
1128  m["bool_lin_eq"] = CheckIntLinEq;
1129  m["bool_lin_le"] = CheckIntLinLe;
1130  m["bool_lt"] = CheckIntLt;
1131  m["bool_lt_imp"] = CheckIntLtImp;
1132  m["bool_lt_reif"] = CheckIntLtReif;
1133  m["bool_ne"] = CheckIntNe;
1134  m["bool_ne_imp"] = CheckIntNeImp;
1135  m["bool_ne_reif"] = CheckIntNeReif;
1136  m["bool_not"] = CheckBoolNot;
1137  m["bool_or"] = CheckBoolOr;
1138  m["bool_right_imp"] = CheckIntGe;
1139  m["bool_xor"] = CheckBoolXor;
1140  m["ortools_circuit"] = CheckCircuit;
1141  m["count_eq"] = CheckCountEq;
1142  m["count"] = CheckCountEq;
1143  m["count_geq"] = CheckCountGeq;
1144  m["count_gt"] = CheckCountGt;
1145  m["count_leq"] = CheckCountLeq;
1146  m["count_lt"] = CheckCountLt;
1147  m["count_neq"] = CheckCountNeq;
1148  m["count_reif"] = CheckCountReif;
1149  m["fzn_cumulative"] = CheckCumulative;
1150  m["var_cumulative"] = CheckCumulative;
1151  m["variable_cumulative"] = CheckCumulative;
1152  m["fixed_cumulative"] = CheckCumulative;
1153  m["fzn_diffn"] = CheckDiffn;
1154  m["diffn_k_with_sizes"] = CheckDiffnK;
1155  m["fzn_diffn_nonstrict"] = CheckDiffnNonStrict;
1156  m["diffn_nonstrict_k_with_sizes"] = CheckDiffnNonStrictK;
1157  m["disjunctive"] = CheckDisjunctive;
1158  m["disjunctive_strict"] = CheckDisjunctiveStrict;
1159  m["false_constraint"] = CheckFalseConstraint;
1160  m["global_cardinality"] = CheckGlobalCardinality;
1161  m["global_cardinality_closed"] = CheckGlobalCardinalityClosed;
1162  m["global_cardinality_low_up"] = CheckGlobalCardinalityLowUp;
1163  m["global_cardinality_low_up_closed"] = CheckGlobalCardinalityLowUpClosed;
1164  m["global_cardinality_old"] = CheckGlobalCardinalityOld;
1165  m["int_abs"] = CheckIntAbs;
1166  m["int_div"] = CheckIntDiv;
1167  m["int_eq"] = CheckIntEq;
1168  m["int_eq_imp"] = CheckIntEqImp;
1169  m["int_eq_reif"] = CheckIntEqReif;
1170  m["int_ge"] = CheckIntGe;
1171  m["int_ge_imp"] = CheckIntGeImp;
1172  m["int_ge_reif"] = CheckIntGeReif;
1173  m["int_gt"] = CheckIntGt;
1174  m["int_gt_imp"] = CheckIntGtImp;
1175  m["int_gt_reif"] = CheckIntGtReif;
1176  m["int_le"] = CheckIntLe;
1177  m["int_le_imp"] = CheckIntLeImp;
1178  m["int_le_reif"] = CheckIntLeReif;
1179  m["int_lin_eq"] = CheckIntLinEq;
1180  m["int_lin_eq_imp"] = CheckIntLinEqImp;
1181  m["int_lin_eq_reif"] = CheckIntLinEqReif;
1182  m["int_lin_ge"] = CheckIntLinGe;
1183  m["int_lin_ge_imp"] = CheckIntLinGeImp;
1184  m["int_lin_ge_reif"] = CheckIntLinGeReif;
1185  m["int_lin_le"] = CheckIntLinLe;
1186  m["int_lin_le_imp"] = CheckIntLinLeImp;
1187  m["int_lin_le_reif"] = CheckIntLinLeReif;
1188  m["int_lin_ne"] = CheckIntLinNe;
1189  m["int_lin_ne_imp"] = CheckIntLinNeImp;
1190  m["int_lin_ne_reif"] = CheckIntLinNeReif;
1191  m["int_lt"] = CheckIntLt;
1192  m["int_lt_imp"] = CheckIntLtImp;
1193  m["int_lt_reif"] = CheckIntLtReif;
1194  m["int_max"] = CheckIntMax;
1195  m["int_min"] = CheckIntMin;
1196  m["int_minus"] = CheckIntMinus;
1197  m["int_mod"] = CheckIntMod;
1198  m["int_ne"] = CheckIntNe;
1199  m["int_ne_imp"] = CheckIntNeImp;
1200  m["int_ne_reif"] = CheckIntNeReif;
1201  m["int_negate"] = CheckIntNegate;
1202  m["int_plus"] = CheckIntPlus;
1203  m["int_times"] = CheckIntTimes;
1204  m["ortools_inverse"] = CheckInverse;
1205  m["lex_less_bool"] = CheckLexLessInt;
1206  m["lex_less_int"] = CheckLexLessInt;
1207  m["lex_lesseq_bool"] = CheckLexLesseqInt;
1208  m["lex_lesseq_int"] = CheckLexLesseqInt;
1209  m["maximum_arg_int"] = CheckMaximumArgInt;
1210  m["maximum_int"] = CheckMaximumInt;
1211  m["array_int_maximum"] = CheckMaximumInt;
1212  m["minimum_arg_int"] = CheckMinimumArgInt;
1213  m["minimum_int"] = CheckMinimumInt;
1214  m["array_int_minimum"] = CheckMinimumInt;
1215  m["ortools_network_flow"] = CheckNetworkFlow;
1216  m["ortools_network_flow_cost"] = CheckNetworkFlowCost;
1217  m["nvalue"] = CheckNvalue;
1218  m["ortools_regular"] = CheckRegular;
1219  m["regular_nfa"] = CheckRegularNfa;
1220  m["set_in"] = CheckSetIn;
1221  m["int_in"] = CheckSetIn;
1222  m["set_not_in"] = CheckSetNotIn;
1223  m["int_not_in"] = CheckSetNotIn;
1224  m["set_in_reif"] = CheckSetInReif;
1225  m["sliding_sum"] = CheckSlidingSum;
1226  m["sort"] = CheckSort;
1227  m["ortools_subcircuit"] = CheckSubCircuit;
1228  m["symmetric_all_different"] = CheckSymmetricAllDifferent;
1229  m["ortools_table_bool"] = CheckTableInt;
1230  m["ortools_table_int"] = CheckTableInt;
1231  return m;
1232 }
1233 
1234 } // namespace
1235 
1237  const std::function<int64_t(Variable*)>& evaluator,
1238  SolverLogger* logger) {
1239  bool ok = true;
1240  const CallMap call_map = CreateCallMap();
1241  for (Constraint* ct : model.constraints()) {
1242  if (!ct->active) continue;
1243  const auto& checker = gtl::FindOrDie(call_map, ct->type);
1244  if (!checker(*ct, evaluator)) {
1245  SOLVER_LOG(logger, "Failing constraint ", ct->DebugString());
1246  ok = false;
1247  }
1248  }
1249  return ok;
1250 }
1251 
1252 } // namespace fz
1253 } // namespace operations_research
int64_t head
#define CHECK(condition)
Definition: base/logging.h:491
int64_t min
Definition: alldiff_cst.cc:139
std::string DebugString() const
Definition: model.cc:753
#define SOLVER_LOG(logger,...)
Definition: util/logging.h:63
const int FATAL
Definition: log_severity.h:32
int64_t ValueAt(int pos) const
Definition: model.cc:688
#define LOG(severity)
Definition: base/logging.h:416
GRBmodel * model
int64_t tail
std::string DebugString() const
Definition: model.cc:574
int64_t max
Definition: alldiff_cst.cc:140
Block * next
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:200
const Collection::value_type::second_type & FindOrDie(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:206
int64_t capacity
std::vector< Variable * > variables
int index
Definition: pack.cc:509
Variable * VarAt(int pos) const
Definition: model.cc:717
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:698
int64_t cost
bool CheckSolution(const Model &model, const std::function< int64_t(Variable *)> &evaluator, SolverLogger *logger)
Definition: checker.cc:1236
Collection of objects used to extend the Constraint Solver library.
std::vector< Argument > arguments
int64_t value
std::vector< int64_t > values
const Constraint * ct
Variable * Var() const
Definition: model.cc:713