OR-Tools  9.6
integer.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 
14 #ifndef OR_TOOLS_SAT_INTEGER_H_
15 #define OR_TOOLS_SAT_INTEGER_H_
16 
17 #include <stdlib.h>
18 
19 #include <algorithm>
20 #include <cstdint>
21 #include <deque>
22 #include <functional>
23 #include <limits>
24 #include <memory>
25 #include <ostream>
26 #include <string>
27 #include <utility>
28 #include <vector>
29 
30 #include "absl/base/attributes.h"
31 #include "absl/container/btree_map.h"
32 #include "absl/container/flat_hash_map.h"
33 #include "absl/container/inlined_vector.h"
34 #include "absl/strings/str_cat.h"
35 #include "absl/strings/string_view.h"
36 #include "absl/types/span.h"
37 #include "ortools/base/hash.h"
39 #include "ortools/base/logging.h"
40 #include "ortools/base/macros.h"
43 #include "ortools/sat/model.h"
44 #include "ortools/sat/sat_base.h"
45 #include "ortools/sat/sat_parameters.pb.h"
46 #include "ortools/sat/sat_solver.h"
47 #include "ortools/util/bitset.h"
48 #include "ortools/util/rev.h"
53 
54 namespace operations_research {
55 namespace sat {
56 
57 // Value type of an integer variable. An integer variable is always bounded
58 // on both sides, and this type is also used to store the bounds [lb, ub] of the
59 // range of each integer variable.
60 //
61 // Note that both bounds are inclusive, which allows to write many propagation
62 // algorithms for just one of the bound and apply it to the negated variables to
63 // get the symmetric algorithm for the other bound.
65 
66 // The max range of an integer variable is [kMinIntegerValue, kMaxIntegerValue].
67 //
68 // It is symmetric so the set of possible ranges stays the same when we take the
69 // negation of a variable. Moreover, we need some IntegerValue that fall outside
70 // this range on both side so that we can usually take care of integer overflow
71 // by simply doing "saturated arithmetic" and if one of the bound overflow, the
72 // two bounds will "cross" each others and we will get an empty range.
73 constexpr IntegerValue kMaxIntegerValue(
75 constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value());
76 
77 inline double ToDouble(IntegerValue value) {
78  const double kInfinity = std::numeric_limits<double>::infinity();
79  if (value >= kMaxIntegerValue) return kInfinity;
80  if (value <= kMinIntegerValue) return -kInfinity;
81  return static_cast<double>(value.value());
82 }
83 
84 template <class IntType>
85 inline IntType IntTypeAbs(IntType t) {
86  return IntType(std::abs(t.value()));
87 }
88 
89 inline IntegerValue CeilRatio(IntegerValue dividend,
90  IntegerValue positive_divisor) {
91  DCHECK_GT(positive_divisor, 0);
92  const IntegerValue result = dividend / positive_divisor;
93  const IntegerValue adjust =
94  static_cast<IntegerValue>(result * positive_divisor < dividend);
95  return result + adjust;
96 }
97 
98 inline IntegerValue FloorRatio(IntegerValue dividend,
99  IntegerValue positive_divisor) {
100  DCHECK_GT(positive_divisor, 0);
101  const IntegerValue result = dividend / positive_divisor;
102  const IntegerValue adjust =
103  static_cast<IntegerValue>(result * positive_divisor > dividend);
104  return result - adjust;
105 }
106 
107 // Returns dividend - FloorRatio(dividend, divisor) * divisor;
108 //
109 // This function is around the same speed than the computation above, but it
110 // never causes integer overflow. Note also that when calling FloorRatio() then
111 // PositiveRemainder(), the compiler should optimize the modulo away and just
112 // reuse the one from the first integer division.
113 inline IntegerValue PositiveRemainder(IntegerValue dividend,
114  IntegerValue positive_divisor) {
115  DCHECK_GT(positive_divisor, 0);
116  const IntegerValue m = dividend % positive_divisor;
117  return m < 0 ? m + positive_divisor : m;
118 }
119 
120 // Computes result += a * b, and return false iff there is an overflow.
121 inline bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue* result) {
122  const int64_t prod = CapProd(a.value(), b.value());
123  if (prod == std::numeric_limits<int64_t>::min() ||
125  return false;
126  const int64_t add = CapAdd(prod, result->value());
127  if (add == std::numeric_limits<int64_t>::min() ||
129  return false;
130  *result = IntegerValue(add);
131  return true;
132 }
133 
134 // Index of an IntegerVariable.
135 //
136 // Each time we create an IntegerVariable we also create its negation. This is
137 // done like that so internally we only stores and deal with lower bound. The
138 // upper bound beeing the lower bound of the negated variable.
139 DEFINE_STRONG_INDEX_TYPE(IntegerVariable);
140 const IntegerVariable kNoIntegerVariable(-1);
141 inline IntegerVariable NegationOf(IntegerVariable i) {
142  return IntegerVariable(i.value() ^ 1);
143 }
144 
145 inline bool VariableIsPositive(IntegerVariable i) {
146  return (i.value() & 1) == 0;
147 }
148 
149 inline IntegerVariable PositiveVariable(IntegerVariable i) {
150  return IntegerVariable(i.value() & (~1));
151 }
152 
153 // Special type for storing only one thing for var and NegationOf(var).
154 DEFINE_STRONG_INDEX_TYPE(PositiveOnlyIndex);
155 inline PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var) {
156  return PositiveOnlyIndex(var.value() / 2);
157 }
158 
159 inline std::string IntegerTermDebugString(IntegerVariable var,
160  IntegerValue coeff) {
161  coeff = VariableIsPositive(var) ? coeff : -coeff;
162  return absl::StrCat(coeff.value(), "*X", var.value() / 2);
163 }
164 
165 // Returns the vector of the negated variables.
166 std::vector<IntegerVariable> NegationOf(
167  const std::vector<IntegerVariable>& vars);
168 
169 // The integer equivalent of a literal.
170 // It represents an IntegerVariable and an upper/lower bound on it.
171 //
172 // Overflow: all the bounds below kMinIntegerValue and kMaxIntegerValue are
173 // treated as kMinIntegerValue - 1 and kMaxIntegerValue + 1.
175  // Because IntegerLiteral should never be created at a bound less constrained
176  // than an existing IntegerVariable bound, we don't allow GreaterOrEqual() to
177  // have a bound lower than kMinIntegerValue, and LowerOrEqual() to have a
178  // bound greater than kMaxIntegerValue. The other side is not constrained
179  // to allow for a computed bound to overflow. Note that both the full initial
180  // domain and the empty domain can always be represented.
181  static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound);
182  static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound);
183 
184  // These two static integer literals represent an always true and an always
185  // false condition.
186  static IntegerLiteral TrueLiteral();
187  static IntegerLiteral FalseLiteral();
188 
189  // Clients should prefer the static construction methods above.
191  IntegerLiteral(IntegerVariable v, IntegerValue b) : var(v), bound(b) {
192  DCHECK_GE(bound, kMinIntegerValue);
193  DCHECK_LE(bound, kMaxIntegerValue + 1);
194  }
195 
196  bool IsValid() const { return var != kNoIntegerVariable; }
197  bool IsAlwaysTrue() const { return var == kNoIntegerVariable && bound <= 0; }
198  bool IsAlwaysFalse() const { return var == kNoIntegerVariable && bound > 0; }
199 
200  // The negation of x >= bound is x <= bound - 1.
201  IntegerLiteral Negated() const;
202 
203  bool operator==(IntegerLiteral o) const {
204  return var == o.var && bound == o.bound;
205  }
206  bool operator!=(IntegerLiteral o) const {
207  return var != o.var || bound != o.bound;
208  }
209 
210  std::string DebugString() const {
211  return VariableIsPositive(var)
212  ? absl::StrCat("I", var.value() / 2, ">=", bound.value())
213  : absl::StrCat("I", var.value() / 2, "<=", -bound.value());
214  }
215 
216  // Note that bound should be in [kMinIntegerValue, kMaxIntegerValue + 1].
217  IntegerVariable var = kNoIntegerVariable;
218  IntegerValue bound = IntegerValue(0);
219 };
220 
221 inline std::ostream& operator<<(std::ostream& os, IntegerLiteral i_lit) {
222  os << i_lit.DebugString();
223  return os;
224 }
225 
226 inline std::ostream& operator<<(std::ostream& os,
227  absl::Span<const IntegerLiteral> literals) {
228  os << "[";
229  bool first = true;
230  for (const IntegerLiteral literal : literals) {
231  if (first) {
232  first = false;
233  } else {
234  os << ",";
235  }
236  os << literal.DebugString();
237  }
238  os << "]";
239  return os;
240 }
241 
242 using InlinedIntegerLiteralVector = absl::InlinedVector<IntegerLiteral, 2>;
244  absl::InlinedVector<std::pair<IntegerVariable, IntegerValue>, 2>;
245 
246 // Represents [coeff * variable + constant] or just a [constant].
247 //
248 // In some places it is useful to manipulate such expression instead of having
249 // to create an extra integer variable. This is mainly used for scheduling
250 // related constraints.
252  // Helper to construct an AffineExpression.
254  AffineExpression(IntegerValue cst) // NOLINT(runtime/explicit)
255  : constant(cst) {}
256  AffineExpression(IntegerVariable v) // NOLINT(runtime/explicit)
257  : var(v), coeff(1) {}
258  AffineExpression(IntegerVariable v, IntegerValue c)
259  : var(c > 0 ? v : NegationOf(v)), coeff(IntTypeAbs(c)) {}
260  AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
261  : var(c > 0 ? v : NegationOf(v)), coeff(IntTypeAbs(c)), constant(cst) {}
262 
263  // Returns the integer literal corresponding to expression >= value or
264  // expression <= value.
265  //
266  // On constant expressions, they will return IntegerLiteral::TrueLiteral()
267  // or IntegerLiteral::FalseLiteral().
268  IntegerLiteral GreaterOrEqual(IntegerValue bound) const;
269  IntegerLiteral LowerOrEqual(IntegerValue bound) const;
270 
271  // It is safe to call these with non-typed constants.
272  // This simplify the code when we need GreaterOrEqual(0) for instance.
273  IntegerLiteral GreaterOrEqual(int64_t bound) const;
274  IntegerLiteral LowerOrEqual(int64_t bound) const;
275 
279  }
280 
281  AffineExpression MultipliedBy(IntegerValue multiplier) const {
282  // Note that this also works if multiplier is negative.
283  return AffineExpression(var, coeff * multiplier, constant * multiplier);
284  }
285 
286  bool operator==(AffineExpression o) const {
287  return var == o.var && coeff == o.coeff && constant == o.constant;
288  }
289 
290  // Returns the value of this affine expression given its variable value.
291  IntegerValue ValueAt(IntegerValue var_value) const {
292  return coeff * var_value + constant;
293  }
294 
295  // Returns the affine expression value under a given LP solution.
296  double LpValue(
297  const absl::StrongVector<IntegerVariable, double>& lp_values) const {
298  if (var == kNoIntegerVariable) return ToDouble(constant);
299  return ToDouble(coeff) * lp_values[var] + ToDouble(constant);
300  }
301 
302  bool IsConstant() const { return var == kNoIntegerVariable; }
303 
304  const std::string DebugString() const {
305  if (var == kNoIntegerVariable) return absl::StrCat(constant.value());
306  if (constant == 0) {
307  return absl::StrCat("(", coeff.value(), " * X", var.value(), ")");
308  } else {
309  return absl::StrCat("(", coeff.value(), " * X", var.value(), " + ",
310  constant.value(), ")");
311  }
312  }
313 
314  // The coefficient MUST be positive. Use NegationOf(var) if needed.
315  //
316  // TODO(user): Make this private to enforce the invariant that coeff cannot be
317  // negative.
318  IntegerVariable var = kNoIntegerVariable; // kNoIntegerVariable for constant.
319  IntegerValue coeff = IntegerValue(0); // Zero for constant.
320  IntegerValue constant = IntegerValue(0);
321 };
322 
323 // A model singleton that holds the root level integer variable domains.
324 // we just store a single domain for both var and its negation.
325 struct IntegerDomains : public absl::StrongVector<PositiveOnlyIndex, Domain> {};
326 
327 // A model singleton used for debugging. If this is set in the model, then we
328 // can check that various derived constraint do not exclude this solution (if it
329 // is a known optimal solution for instance).
331  // This is the value of all proto variables.
332  // It should be of the same size of the PRESOLVED model and should correspond
333  // to a solution to the presolved model.
334  std::vector<int64_t> proto_values;
335 
336  // This is filled from proto_values at load-time, and using the
337  // cp_model_mapping, we cache the solution of the integer-variabls that are
338  // mapped. Note that it is possible that not all integer variable are mapped.
339  //
340  // TODO(user): When this happen we should be able to infer the value of these
341  // derived variable in the solution. For now, we only do that for the
342  // objective variable.
345 };
346 
347 // A value and a literal.
351  const ValueLiteralPair& b) const {
352  return a.literal < b.literal;
353  }
354  };
355  struct CompareByValue {
357  const ValueLiteralPair& b) const {
358  return (a.value < b.value) ||
359  (a.value == b.value && a.literal < b.literal);
360  }
361  };
362 
363  bool operator==(const ValueLiteralPair& o) const {
364  return value == o.value && literal == o.literal;
365  }
366 
367  std::string DebugString() const;
368 
369  IntegerValue value = IntegerValue(0);
371 };
372 
373 std::ostream& operator<<(std::ostream& os, const ValueLiteralPair& p);
374 
377  IntegerValue left_value;
378  IntegerValue right_value;
379 
380  // Used for testing.
381  bool operator==(const LiteralValueValue& rhs) const {
382  return literal.Index() == rhs.literal.Index() &&
383  left_value == rhs.left_value && right_value == rhs.right_value;
384  }
385 
386  std::string DebugString() const {
387  return absl::StrCat("(lit(", literal.Index().value(), ") * ",
388  left_value.value(), " * ", right_value.value(), ")");
389  }
390 };
391 
392 // Sometimes we propagate fact with no reason at a positive level, those
393 // will automatically be fixed on the next restart.
394 //
395 // TODO(user): If we change the logic to not restart right away, we probably
396 // need to remove duplicates bounds for the same variable.
398  std::vector<Literal> literal_to_fix;
399  std::vector<IntegerLiteral> integer_literal_to_fix;
400 };
401 
402 // Each integer variable x will be associated with a set of literals encoding
403 // (x >= v) for some values of v. This class maintains the relationship between
404 // the integer variables and such literals which can be created by a call to
405 // CreateAssociatedLiteral().
406 //
407 // The advantage of creating such Boolean variables is that the SatSolver which
408 // is driving the search can then take this variable as a decision and maintain
409 // these variables activity and so on. These variables can also be propagated
410 // directly by the learned clauses.
411 //
412 // This class also support a non-lazy full domain encoding which will create one
413 // literal per possible value in the domain. See FullyEncodeVariable(). This is
414 // meant to be called by constraints that directly work on the variable values
415 // like a table constraint or an all-diff constraint.
416 //
417 // TODO(user): We could also lazily create precedences Booleans between two
418 // arbitrary IntegerVariable. This is better done in the PrecedencesPropagator
419 // though.
421  public:
423  : sat_solver_(model->GetOrCreate<SatSolver>()),
424  trail_(model->GetOrCreate<Trail>()),
425  delayed_to_fix_(model->GetOrCreate<DelayedRootLevelDeduction>()),
426  domains_(*model->GetOrCreate<IntegerDomains>()),
427  num_created_variables_(0) {}
428 
430  VLOG(1) << "#variables created = " << num_created_variables_;
431  }
432 
433  // Memory optimization: you can call this before encoding variables.
434  void ReserveSpaceForNumVariables(int num_vars);
435 
436  // Fully encode a variable using its current initial domain.
437  // If the variable is already fully encoded, this does nothing.
438  //
439  // This creates new Booleans variables as needed:
440  // 1) num_values for the literals X == value. Except when there is just
441  // two value in which case only one variable is created.
442  // 2) num_values - 3 for the literals X >= value or X <= value (using their
443  // negation). The -3 comes from the fact that we can reuse the equality
444  // literals for the two extreme points.
445  //
446  // The encoding for NegationOf(var) is automatically created too. It reuses
447  // the same Boolean variable as the encoding of var.
448  //
449  // TODO(user): It is currently only possible to call that at the decision
450  // level zero because we cannot add ternary clause in the middle of the
451  // search (for now). This is Checked.
452  void FullyEncodeVariable(IntegerVariable var);
453 
454  // Returns true if we know that PartialDomainEncoding(var) span the full
455  // domain of var. This is always true if FullyEncodeVariable(var) has been
456  // called.
457  bool VariableIsFullyEncoded(IntegerVariable var) const;
458 
459  // Returns the list of literal <=> var == value currently associated to the
460  // given variable. The result is sorted by value. We filter literal at false,
461  // and if a literal is true, then you will get a singleton. To be sure to get
462  // the full set of encoded value, then you should call this at level zero.
463  //
464  // The FullDomainEncoding() just check VariableIsFullyEncoded() and returns
465  // the same result.
466  std::vector<ValueLiteralPair> FullDomainEncoding(IntegerVariable var) const;
467  std::vector<ValueLiteralPair> PartialDomainEncoding(
468  IntegerVariable var) const;
469 
470  // Returns the "canonical" (i_lit, negation of i_lit) pair. This mainly
471  // deal with domain with initial hole like [1,2][5,6] so that if one ask
472  // for x <= 3, this get canonicalized in the pair (x <= 2, x >= 5).
473  //
474  // Note that it is an error to call this with a literal that is trivially true
475  // or trivially false according to the initial variable domain. This is
476  // CHECKed to make sure we don't create wasteful literal.
477  //
478  // TODO(user): This is linear in the domain "complexity", we can do better if
479  // needed.
480  std::pair<IntegerLiteral, IntegerLiteral> Canonicalize(
481  IntegerLiteral i_lit) const;
482 
483  // Returns, after creating it if needed, a Boolean literal such that:
484  // - if true, then the IntegerLiteral is true.
485  // - if false, then the negated IntegerLiteral is true.
486  //
487  // Note that this "canonicalize" the given literal first.
488  //
489  // This add the proper implications with the two "neighbor" literals of this
490  // one if they exist. This is the "list encoding" in: Thibaut Feydy, Peter J.
491  // Stuckey, "Lazy Clause Generation Reengineered", CP 2009.
494  IntegerValue value);
495 
496  // Associates the Boolean literal to (X >= bound) or (X == value). If a
497  // literal was already associated to this fact, this will add an equality
498  // constraints between both literals. If the fact is trivially true or false,
499  // this will fix the given literal.
501  void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var,
502  IntegerValue value);
503 
504  // Returns kNoLiteralIndex if there is no associated or the associated literal
505  // otherwise.
506  //
507  // Tricky: for domain with hole, like [0,1][5,6], we assume some equivalence
508  // classes, like >=2, >=3, >=4 are all the same as >= 5.
509  LiteralIndex GetAssociatedLiteral(IntegerLiteral i_lit) const;
510  LiteralIndex GetAssociatedEqualityLiteral(IntegerVariable var,
511  IntegerValue value) const;
512 
513  // Advanced usage. It is more efficient to create the associated literals in
514  // order, but it might be anoying to do so. Instead, you can first call
515  // DisableImplicationBetweenLiteral() and when you are done creating all the
516  // associated literals, you can call (only at level zero)
517  // AddAllImplicationsBetweenAssociatedLiterals() which will also turn back on
518  // the implications between literals for the one that will be added
519  // afterwards.
520  void DisableImplicationBetweenLiteral() { add_implications_ = false; }
522 
523  // Returns the IntegerLiterals that were associated with the given Literal.
525  if (lit.Index() >= reverse_encoding_.size()) {
526  return empty_integer_literal_vector_;
527  }
528  return reverse_encoding_[lit.Index()];
529  }
530 
531  // Returns the variable == value pairs that were associated with the given
532  // Literal. Note that only positive IntegerVariable appears here.
534  if (lit.Index() >= reverse_equality_encoding_.size()) {
535  return empty_integer_value_vector_;
536  }
537  return reverse_equality_encoding_[lit.Index()];
538  }
539 
540  // Returns all the variables for which this literal is associated to either
541  // var >= value or var == value.
542  const std::vector<IntegerVariable>& GetAllAssociatedVariables(
543  Literal lit) const {
544  temp_associated_vars_.clear();
545  for (const IntegerLiteral l : GetIntegerLiterals(lit)) {
546  temp_associated_vars_.push_back(l.var);
547  }
548  for (const auto [var, value] : GetEqualityLiterals(lit)) {
549  temp_associated_vars_.push_back(var);
550  }
551  return temp_associated_vars_;
552  }
553 
554  // If it exists, returns a [0,1] integer variable which is equal to 1 iff the
555  // given literal is true. Returns kNoIntegerVariable if such variable does not
556  // exist. Note that one can create one by creating a new IntegerVariable and
557  // calling AssociateToIntegerEqualValue().
558  const IntegerVariable GetLiteralView(Literal lit) const {
559  if (lit.Index() >= literal_view_.size()) return kNoIntegerVariable;
560  return literal_view_[lit.Index()];
561  }
562 
563  // If this is true, then a literal can be linearized with an affine expression
564  // involving an integer variable.
565  ABSL_MUST_USE_RESULT bool LiteralOrNegationHasView(
566  Literal lit, IntegerVariable* view = nullptr,
567  bool* view_is_direct = nullptr) const;
568 
569  // Returns a Boolean literal associated with a bound lower than or equal to
570  // the one of the given IntegerLiteral. If the given IntegerLiteral is true,
571  // then the returned literal should be true too. Returns kNoLiteralIndex if no
572  // such literal was created.
573  //
574  // Ex: if 'i' is (x >= 4) and we already created a literal associated to
575  // (x >= 2) but not to (x >= 3), we will return the literal associated with
576  // (x >= 2).
577  LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i_lit,
578  IntegerValue* bound) const;
579 
580  // Gets the literal always set to true, make it if it does not exist.
582  DCHECK_EQ(0, sat_solver_->CurrentDecisionLevel());
583  if (literal_index_true_ == kNoLiteralIndex) {
584  const Literal literal_true =
585  Literal(sat_solver_->NewBooleanVariable(), true);
586  literal_index_true_ = literal_true.Index();
587  sat_solver_->AddUnitClause(literal_true);
588  }
589  return Literal(literal_index_true_);
590  }
592 
593  // Returns the set of Literal associated to IntegerLiteral of the form var >=
594  // value. We make a copy, because this can be easily invalidated when calling
595  // any function of this class. So it is less efficient but safer.
596  std::vector<ValueLiteralPair> PartialGreaterThanEncoding(
597  IntegerVariable var) const;
598 
599  // Makes sure all element in the >= encoding are non-trivial and canonical.
600  // The input variable must be positive.
601  bool UpdateEncodingOnInitialDomainChange(IntegerVariable var, Domain domain);
602 
603  private:
604  // Adds the implications:
605  // Literal(before) <= associated_lit <= Literal(after).
606  // Arguments:
607  // - map is just encoding_by_var_[associated_lit.var] and is passed as a
608  // slight optimization.
609  // - 'it' is the current position of associated_lit in map, i.e. we must have
610  // it->second == associated_lit.
611  void AddImplications(
612  const absl::btree_map<IntegerValue, Literal>& map,
613  absl::btree_map<IntegerValue, Literal>::const_iterator it,
614  Literal associated_lit);
615 
616  SatSolver* sat_solver_;
617  Trail* trail_;
618  DelayedRootLevelDeduction* delayed_to_fix_;
619  const IntegerDomains& domains_;
620 
621  bool add_implications_ = true;
622  int64_t num_created_variables_ = 0;
623 
624  // We keep all the literals associated to an Integer variable in a map ordered
625  // by bound (so we can properly add implications between the literals
626  // corresponding to the same variable).
627  //
628  // Note that we only keep this for positive variable.
629  // The one for the negation can be infered by it.
630  //
631  // Like x >= 1 x >= 4 x >= 5
632  // Correspond to x <= 0 x <= 3 x <= 4
633  // That is -x >= 0 -x >= -2 -x >= -4
634  //
635  // With potentially stronger <= bound if we fall into domain holes.
636  //
637  // TODO(user): Remove the entry no longer needed because of level zero
638  // propagations.
640  encoding_by_var_;
641 
642  // Store for a given LiteralIndex the list of its associated IntegerLiterals.
643  const InlinedIntegerLiteralVector empty_integer_literal_vector_;
645  reverse_encoding_;
646  const InlinedIntegerValueVector empty_integer_value_vector_;
648  reverse_equality_encoding_;
649 
650  // Used by GetAllAssociatedVariables().
651  mutable std::vector<IntegerVariable> temp_associated_vars_;
652 
653  // Store for a given LiteralIndex its IntegerVariable view or kNoLiteralIndex
654  // if there is none.
656 
657  // Mapping (variable == value) -> associated literal. Note that even if
658  // there is more than one literal associated to the same fact, we just keep
659  // the first one that was added.
660  //
661  // Note that we only keep positive IntegerVariable here to reduce memory
662  // usage.
663  absl::flat_hash_map<std::pair<PositiveOnlyIndex, IntegerValue>, Literal>
664  equality_to_associated_literal_;
665 
666  // Mutable because this is lazily cleaned-up by PartialDomainEncoding().
667  mutable absl::StrongVector<PositiveOnlyIndex,
668  absl::InlinedVector<ValueLiteralPair, 2>>
669  equality_by_var_;
670 
671  // Variables that are fully encoded.
672  mutable absl::StrongVector<PositiveOnlyIndex, bool> is_fully_encoded_;
673 
674  // A literal that is always true, convenient to encode trivial domains.
675  // This will be lazily created when needed.
676  LiteralIndex literal_index_true_ = kNoLiteralIndex;
677 
678  // Temporary memory used by FullyEncodeVariable().
679  std::vector<IntegerValue> tmp_values_;
680  std::vector<ValueLiteralPair> tmp_encoding_;
681 
682  DISALLOW_COPY_AND_ASSIGN(IntegerEncoder);
683 };
684 
685 // This class maintains a set of integer variables with their current bounds.
686 // Bounds can be propagated from an external "source" and this class helps
687 // to maintain the reason for each propagation.
688 class IntegerTrail : public SatPropagator {
689  public:
691  : SatPropagator("IntegerTrail"),
692  delayed_to_fix_(model->GetOrCreate<DelayedRootLevelDeduction>()),
693  domains_(model->GetOrCreate<IntegerDomains>()),
694  encoder_(model->GetOrCreate<IntegerEncoder>()),
695  trail_(model->GetOrCreate<Trail>()),
696  sat_solver_(model->GetOrCreate<SatSolver>()),
697  parameters_(*model->GetOrCreate<SatParameters>()) {
698  model->GetOrCreate<SatSolver>()->AddPropagator(this);
699  }
700  ~IntegerTrail() final;
701 
702  // SatPropagator interface. These functions make sure the current bounds
703  // information is in sync with the current solver literal trail. Any
704  // class/propagator using this class must make sure it is synced to the
705  // correct state before calling any of its functions.
706  bool Propagate(Trail* trail) final;
707  void Untrail(const Trail& trail, int literal_trail_index) final;
708  absl::Span<const Literal> Reason(const Trail& trail,
709  int trail_index) const final;
710 
711  // Returns the number of created integer variables.
712  //
713  // Note that this is twice the number of call to AddIntegerVariable() since
714  // we automatically create the NegationOf() variable too.
715  IntegerVariable NumIntegerVariables() const {
716  return IntegerVariable(vars_.size());
717  }
718 
719  // Optimization: you can call this before calling AddIntegerVariable()
720  // num_vars time.
721  void ReserveSpaceForNumVariables(int num_vars);
722 
723  // Adds a new integer variable. Adding integer variable can only be done when
724  // the decision level is zero (checked). The given bounds are INCLUSIVE and
725  // must not cross.
726  //
727  // Note on integer overflow: 'upper_bound - lower_bound' must fit on an
728  // int64_t, this is DCHECKed. More generally, depending on the constraints
729  // that are added, the bounds magnitude must be small enough to satisfy each
730  // constraint overflow precondition.
731  IntegerVariable AddIntegerVariable(IntegerValue lower_bound,
732  IntegerValue upper_bound);
733 
734  // Same as above but for a more complex domain specified as a sorted list of
735  // disjoint intervals. See the Domain class.
736  IntegerVariable AddIntegerVariable(const Domain& domain);
737 
738  // Returns the initial domain of the given variable. Note that the min/max
739  // are updated with level zero propagation, but not holes.
740  const Domain& InitialVariableDomain(IntegerVariable var) const;
741 
742  // Takes the intersection with the current initial variable domain.
743  //
744  // TODO(user): There is some memory inefficiency if this is called many time
745  // because of the underlying data structure we use. In practice, when used
746  // with a presolve, this is not often used, so that is fine though.
747  bool UpdateInitialDomain(IntegerVariable var, Domain domain);
748 
749  // Same as AddIntegerVariable(value, value), but this is a bit more efficient
750  // because it reuses another constant with the same value if its exist.
751  //
752  // Note(user): Creating constant integer variable is a bit wasteful, but not
753  // that much, and it allows to simplify a lot of constraints that do not need
754  // to handle this case any differently than the general one. Maybe there is a
755  // better solution, but this is not really high priority as of December 2016.
756  IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value);
757  int NumConstantVariables() const;
758 
759  // Same as AddIntegerVariable() but uses the maximum possible range. Note
760  // that since we take negation of bounds in various places, we make sure that
761  // we don't have overflow when we take the negation of the lower bound or of
762  // the upper bound.
763  IntegerVariable AddIntegerVariable() {
765  }
766 
767  // For an optional variable, both its lb and ub must be valid bound assuming
768  // the fact that the variable is "present". However, the domain [lb, ub] is
769  // allowed to be empty (i.e. ub < lb) if the given is_ignored literal is true.
770  // Moreover, if is_ignored is true, then the bound of such variable should NOT
771  // impact any non-ignored variable in any way (but the reverse is not true).
772  bool IsOptional(IntegerVariable i) const {
773  return is_ignored_literals_[i] != kNoLiteralIndex;
774  }
775  bool IsCurrentlyIgnored(IntegerVariable i) const {
776  const LiteralIndex is_ignored_literal = is_ignored_literals_[i];
777  return is_ignored_literal != kNoLiteralIndex &&
778  trail_->Assignment().LiteralIsTrue(Literal(is_ignored_literal));
779  }
780  Literal IsIgnoredLiteral(IntegerVariable i) const {
781  DCHECK(IsOptional(i));
782  return Literal(is_ignored_literals_[i]);
783  }
784  LiteralIndex OptionalLiteralIndex(IntegerVariable i) const {
785  return is_ignored_literals_[i] == kNoLiteralIndex
787  : Literal(is_ignored_literals_[i]).NegatedIndex();
788  }
789  void MarkIntegerVariableAsOptional(IntegerVariable i, Literal is_considered) {
790  DCHECK(is_ignored_literals_[i] == kNoLiteralIndex ||
791  is_ignored_literals_[i] == is_considered.NegatedIndex());
792  is_ignored_literals_[i] = is_considered.NegatedIndex();
793  is_ignored_literals_[NegationOf(i)] = is_considered.NegatedIndex();
794  }
795 
796  // Returns the current lower/upper bound of the given integer variable.
797  IntegerValue LowerBound(IntegerVariable i) const;
798  IntegerValue UpperBound(IntegerVariable i) const;
799 
800  // Checks if the variable is fixed.
801  bool IsFixed(IntegerVariable i) const;
802 
803  // Checks that the variable is fixed and returns its value.
804  IntegerValue FixedValue(IntegerVariable i) const;
805 
806  // Same as above for an affine expression.
807  IntegerValue LowerBound(AffineExpression expr) const;
808  IntegerValue UpperBound(AffineExpression expr) const;
809  bool IsFixed(AffineExpression expr) const;
810  IntegerValue FixedValue(AffineExpression expr) const;
811 
812  // Returns the integer literal that represent the current lower/upper bound of
813  // the given integer variable.
814  IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const;
815  IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const;
816 
817  // Returns the integer literal that represent the current lower/upper bound of
818  // the given affine expression. In case the expression is constant, it returns
819  // IntegerLiteral::TrueLiteral().
822 
823  // Returns the current value (if known) of an IntegerLiteral.
824  bool IntegerLiteralIsTrue(IntegerLiteral l) const;
826 
827  // Returns globally valid lower/upper bound on the given integer variable.
828  IntegerValue LevelZeroLowerBound(IntegerVariable var) const;
829  IntegerValue LevelZeroUpperBound(IntegerVariable var) const;
830 
831  // Returns globally valid lower/upper bound on the given affine expression.
832  IntegerValue LevelZeroLowerBound(AffineExpression exp) const;
833  IntegerValue LevelZeroUpperBound(AffineExpression exp) const;
834 
835  // Returns true if the variable is fixed at level 0.
836  bool IsFixedAtLevelZero(IntegerVariable var) const;
837 
838  // Returns true if the affine expression is fixed at level 0.
839  bool IsFixedAtLevelZero(AffineExpression expr) const;
840 
841  // Advanced usage.
842  // Returns the current lower bound assuming the literal is true.
843  IntegerValue ConditionalLowerBound(Literal l, IntegerVariable i) const;
844  IntegerValue ConditionalLowerBound(Literal l, AffineExpression expr) const;
845 
846  // Advanced usage. Given the reason for
847  // (Sum_i coeffs[i] * reason[i].var >= current_lb) initially in reason,
848  // this function relaxes the reason given that we only need the explanation of
849  // (Sum_i coeffs[i] * reason[i].var >= current_lb - slack).
850  //
851  // Preconditions:
852  // - coeffs must be of same size as reason, and all entry must be positive.
853  // - *reason must initially contains the trivial initial reason, that is
854  // the current lower-bound of each variables.
855  //
856  // TODO(user): Requiring all initial literal to be at their current bound is
857  // not really clean. Maybe we can change the API to only take IntegerVariable
858  // and produce the reason directly.
859  //
860  // TODO(user): change API so that this work is performed during the conflict
861  // analysis where we can be smarter in how we relax the reason. Note however
862  // that this function is mainly used when we have a conflict, so this is not
863  // really high priority.
864  //
865  // TODO(user): Test that the code work in the presence of integer overflow.
866  void RelaxLinearReason(IntegerValue slack,
867  absl::Span<const IntegerValue> coeffs,
868  std::vector<IntegerLiteral>* reason) const;
869 
870  // Same as above but take in IntegerVariables instead of IntegerLiterals.
871  void AppendRelaxedLinearReason(IntegerValue slack,
872  absl::Span<const IntegerValue> coeffs,
873  absl::Span<const IntegerVariable> vars,
874  std::vector<IntegerLiteral>* reason) const;
875 
876  // Same as above but relax the given trail indices.
877  void RelaxLinearReason(IntegerValue slack,
878  absl::Span<const IntegerValue> coeffs,
879  std::vector<int>* trail_indices) const;
880 
881  // Removes from the reasons the literal that are always true.
882  // This is mainly useful for experiments/testing.
883  void RemoveLevelZeroBounds(std::vector<IntegerLiteral>* reason) const;
884 
885  // Enqueue new information about a variable bound. Calling this with a less
886  // restrictive bound than the current one will have no effect.
887  //
888  // The reason for this "assignment" must be provided as:
889  // - A set of Literal currently beeing all false.
890  // - A set of IntegerLiteral currently beeing all true.
891  //
892  // IMPORTANT: Notice the inversed sign in the literal reason. This is a bit
893  // confusing but internally SAT use this direction for efficiency.
894  //
895  // Note(user): Duplicates Literal/IntegerLiteral are supported because we call
896  // STLSortAndRemoveDuplicates() in MergeReasonInto(), but maybe they shouldn't
897  // for efficiency reason.
898  //
899  // TODO(user): If the given bound is equal to the current bound, maybe the new
900  // reason is better? how to decide and what to do in this case? to think about
901  // it. Currently we simply don't do anything.
902  ABSL_MUST_USE_RESULT bool Enqueue(
903  IntegerLiteral i_lit, absl::Span<const Literal> literal_reason,
904  absl::Span<const IntegerLiteral> integer_reason);
905 
906  // Enqueue new information about a variable bound. It has the same behavior
907  // as the Enqueue() method, except that it accepts true and false integer
908  // literals, both for i_lit, and for the integer reason.
909  //
910  // This method will do nothing if i_lit is a true literal. It will report a
911  // conflict if i_lit is a false literal, and enqueue i_lit normally otherwise.
912  // Furthemore, it will check that the integer reason does not contain any
913  // false literals, and will remove true literals before calling
914  // ReportConflict() or Enqueue().
915  ABSL_MUST_USE_RESULT bool SafeEnqueue(
916  IntegerLiteral i_lit, absl::Span<const IntegerLiteral> integer_reason);
917 
918  // Pushes the given integer literal assuming that the Boolean literal is true.
919  // This can do a few things:
920  // - If lit it true, add it to the reason and push the integer bound.
921  // - If the bound is infeasible, push lit to false.
922  // - If the underlying variable is optional and also controlled by lit, push
923  // the bound even if lit is not assigned.
924  ABSL_MUST_USE_RESULT bool ConditionalEnqueue(
925  Literal lit, IntegerLiteral i_lit, std::vector<Literal>* literal_reason,
926  std::vector<IntegerLiteral>* integer_reason);
927 
928  // Same as Enqueue(), but takes an extra argument which if smaller than
929  // integer_trail_.size() is interpreted as the trail index of an old Enqueue()
930  // that had the same reason as this one. Note that the given Span must still
931  // be valid as they are used in case of conflict.
932  //
933  // TODO(user): This currently cannot refer to a trail_index with a lazy
934  // reason. Fix or at least check that this is the case.
935  ABSL_MUST_USE_RESULT bool Enqueue(
936  IntegerLiteral i_lit, absl::Span<const Literal> literal_reason,
937  absl::Span<const IntegerLiteral> integer_reason,
938  int trail_index_with_same_reason);
939 
940  // Lazy reason API.
941  //
942  // The function is provided with the IntegerLiteral to explain and its index
943  // in the integer trail. It must fill the two vectors so that literals
944  // contains any Literal part of the reason and dependencies contains the trail
945  // index of any IntegerLiteral that is also part of the reason.
946  //
947  // Remark: sometimes this is called to fill the conflict while the literal
948  // to explain is propagated. In this case, trail_index_of_literal will be
949  // the current trail index, and we cannot assume that there is anything filled
950  // yet in integer_literal[trail_index_of_literal].
951  using LazyReasonFunction = std::function<void(
952  IntegerLiteral literal_to_explain, int trail_index_of_literal,
953  std::vector<Literal>* literals, std::vector<int>* dependencies)>;
954  ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit,
955  LazyReasonFunction lazy_reason);
956 
957  // Sometimes we infer some root level bounds but we are not at the root level.
958  // In this case, we will update the level-zero bounds right away, but will
959  // delay the current push until the next restart.
960  //
961  // Note that if you want to also push the literal at the current level, then
962  // just calling Enqueue() is enough. Since there is no reason, the literal
963  // will still be recorded properly.
964  ABSL_MUST_USE_RESULT bool RootLevelEnqueue(IntegerLiteral i_lit);
965 
966  // Enqueues the given literal on the trail.
967  // See the comment of Enqueue() for the reason format.
968  void EnqueueLiteral(Literal literal, absl::Span<const Literal> literal_reason,
969  absl::Span<const IntegerLiteral> integer_reason);
970 
971  // Returns the reason (as set of Literal currently false) for a given integer
972  // literal. Note that the bound must be less restrictive than the current
973  // bound (checked).
974  std::vector<Literal> ReasonFor(IntegerLiteral literal) const;
975 
976  // Appends the reason for the given integer literals to the output and call
977  // STLSortAndRemoveDuplicates() on it. This function accept "constant"
978  // literal.
979  void MergeReasonInto(absl::Span<const IntegerLiteral> literals,
980  std::vector<Literal>* output) const;
981 
982  // Returns the number of enqueues that changed a variable bounds. We don't
983  // count enqueues called with a less restrictive bound than the current one.
984  //
985  // Note(user): this can be used to see if any of the bounds changed. Just
986  // looking at the integer trail index is not enough because at level zero it
987  // doesn't change since we directly update the "fixed" bounds.
988  int64_t num_enqueues() const { return num_enqueues_; }
989  int64_t timestamp() const { return num_enqueues_ + num_untrails_; }
990 
991  // Same as num_enqueues but only count the level zero changes.
992  int64_t num_level_zero_enqueues() const { return num_level_zero_enqueues_; }
993 
994  // All the registered bitsets will be set to one each time a LbVar is
995  // modified. It is up to the client to clear it if it wants to be notified
996  // with the newly modified variables.
999  watchers_.push_back(p);
1000  }
1001 
1002  // Helper functions to report a conflict. Always return false so a client can
1003  // simply do: return integer_trail_->ReportConflict(...);
1004  bool ReportConflict(absl::Span<const Literal> literal_reason,
1005  absl::Span<const IntegerLiteral> integer_reason) {
1006  DCHECK(ReasonIsValid(literal_reason, integer_reason));
1007  std::vector<Literal>* conflict = trail_->MutableConflict();
1008  conflict->assign(literal_reason.begin(), literal_reason.end());
1009  MergeReasonInto(integer_reason, conflict);
1010  return false;
1011  }
1012  bool ReportConflict(absl::Span<const IntegerLiteral> integer_reason) {
1013  DCHECK(ReasonIsValid({}, integer_reason));
1014  std::vector<Literal>* conflict = trail_->MutableConflict();
1015  conflict->clear();
1016  MergeReasonInto(integer_reason, conflict);
1017  return false;
1018  }
1019 
1020  // Returns true if the variable lower bound is still the one from level zero.
1021  bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const {
1022  return vars_[var].current_trail_index < vars_.size();
1023  }
1024 
1025  // Registers a reversible class. This class will always be synced with the
1026  // correct decision level.
1028  reversible_classes_.push_back(rev);
1029  }
1030 
1031  int Index() const { return integer_trail_.size(); }
1032 
1033  // Inspects the trail and output all the non-level zero bounds (one per
1034  // variables) to the output. The algo is sparse if there is only a few
1035  // propagations on the trail.
1036  void AppendNewBounds(std::vector<IntegerLiteral>* output) const;
1037 
1038  // Returns the trail index < threshold of a TrailEntry about var. Returns -1
1039  // if there is no such entry (at a positive decision level). This is basically
1040  // the trail index of the lower bound of var at the time.
1041  //
1042  // Important: We do some optimization internally, so this should only be
1043  // used from within a LazyReasonFunction().
1044  int FindTrailIndexOfVarBefore(IntegerVariable var, int threshold) const;
1045 
1046  // Basic heuristic to detect when we are in a propagation loop, and suggest
1047  // a good variable to branch on (taking the middle value) to get out of it.
1048  bool InPropagationLoop() const;
1050  IntegerVariable NextVariableToBranchOnInPropagationLoop() const;
1051 
1052  // If we had an incomplete propagation, it is important to fix all the
1053  // variables and not relly on the propagation to do so. This is related to the
1054  // InPropagationLoop() code above.
1056  IntegerVariable FirstUnassignedVariable() const;
1057 
1058  // Return true if we can fix new fact at level zero.
1060  return !delayed_to_fix_->literal_to_fix.empty() ||
1061  !delayed_to_fix_->integer_literal_to_fix.empty();
1062  }
1063 
1064  // If this is set, and in debug mode, we will call this on all conflict to
1065  // be checked for potential issue. Usually against a known optimal solution.
1067  std::function<bool(absl::Span<const Literal> clause,
1068  absl::Span<const IntegerLiteral> integers)>
1069  checker) {
1070  debug_checker_ = std::move(checker);
1071  }
1072 
1073  private:
1074  // Used for DHECKs to validate the reason given to the public functions above.
1075  // Tests that all Literal are false. Tests that all IntegerLiteral are true.
1076  bool ReasonIsValid(absl::Span<const Literal> literal_reason,
1077  absl::Span<const IntegerLiteral> integer_reason);
1078 
1079  // Same as above, but with the literal for which this is the reason for.
1080  bool ReasonIsValid(Literal lit, absl::Span<const Literal> literal_reason,
1081  absl::Span<const IntegerLiteral> integer_reason);
1082  bool ReasonIsValid(IntegerLiteral i_lit,
1083  absl::Span<const Literal> literal_reason,
1084  absl::Span<const IntegerLiteral> integer_reason);
1085 
1086  // If the variable has holes in its domain, make sure the literal is
1087  // canonicalized.
1088  void CanonicalizeLiteralIfNeeded(IntegerLiteral* i_lit);
1089 
1090  // Called by the Enqueue() functions that detected a conflict. This does some
1091  // common conflict initialization that must terminate by a call to
1092  // MergeReasonIntoInternal(conflict) where conflict is the returned vector.
1093  std::vector<Literal>* InitializeConflict(
1094  IntegerLiteral integer_literal, const LazyReasonFunction& lazy_reason,
1095  absl::Span<const Literal> literals_reason,
1096  absl::Span<const IntegerLiteral> bounds_reason);
1097 
1098  // Internal implementation of the different public Enqueue() functions.
1099  ABSL_MUST_USE_RESULT bool EnqueueInternal(
1100  IntegerLiteral i_lit, LazyReasonFunction lazy_reason,
1101  absl::Span<const Literal> literal_reason,
1102  absl::Span<const IntegerLiteral> integer_reason,
1103  int trail_index_with_same_reason);
1104 
1105  // Internal implementation of the EnqueueLiteral() functions.
1106  void EnqueueLiteralInternal(Literal literal, LazyReasonFunction lazy_reason,
1107  absl::Span<const Literal> literal_reason,
1108  absl::Span<const IntegerLiteral> integer_reason);
1109 
1110  // Same as EnqueueInternal() but for the case where we push an IntegerLiteral
1111  // because an associated Literal is true (and we know it). In this case, we
1112  // have less work to do, so this has the same effect but is faster.
1113  ABSL_MUST_USE_RESULT bool EnqueueAssociatedIntegerLiteral(
1114  IntegerLiteral i_lit, Literal literal_reason);
1115 
1116  // Does the work of MergeReasonInto() when queue_ is already initialized.
1117  void MergeReasonIntoInternal(std::vector<Literal>* output) const;
1118 
1119  // Returns the lowest trail index of a TrailEntry that can be used to explain
1120  // the given IntegerLiteral. The literal must be currently true (CHECKed).
1121  // Returns -1 if the explanation is trivial.
1122  int FindLowestTrailIndexThatExplainBound(IntegerLiteral i_lit) const;
1123 
1124  // This must be called before Dependencies() or AppendLiteralsReason().
1125  //
1126  // TODO(user): Not really robust, try to find a better way.
1127  void ComputeLazyReasonIfNeeded(int trail_index) const;
1128 
1129  // Helper function to return the "dependencies" of a bound assignment.
1130  // All the TrailEntry at these indices are part of the reason for this
1131  // assignment.
1132  //
1133  // Important: The returned Span is only valid up to the next call.
1134  absl::Span<const int> Dependencies(int trail_index) const;
1135 
1136  // Helper function to append the Literal part of the reason for this bound
1137  // assignment. We use added_variables_ to not add the same literal twice.
1138  // Note that looking at literal.Variable() is enough since all the literals
1139  // of a reason must be false.
1140  void AppendLiteralsReason(int trail_index,
1141  std::vector<Literal>* output) const;
1142 
1143  // Returns some debugging info.
1144  std::string DebugString();
1145 
1146  // Information for each internal variable about its current bound.
1147  struct VarInfo {
1148  // The current bound on this variable.
1149  IntegerValue current_bound;
1150 
1151  // Trail index of the last TrailEntry in the trail referring to this var.
1152  int current_trail_index;
1153  };
1155 
1156  // This is used by FindLowestTrailIndexThatExplainBound() and
1157  // FindTrailIndexOfVarBefore() to speed up the lookup. It keeps a trail index
1158  // for each variable that may or may not point to a TrailEntry regarding this
1159  // variable. The validity of the index is verified before beeing used.
1160  //
1161  // The cache will only be updated with trail_index >= threshold.
1162  mutable int var_trail_index_cache_threshold_ = 0;
1163  mutable absl::StrongVector<IntegerVariable, int> var_trail_index_cache_;
1164 
1165  // Used by GetOrCreateConstantIntegerVariable() to return already created
1166  // constant variables that share the same value.
1167  absl::flat_hash_map<IntegerValue, IntegerVariable> constant_map_;
1168 
1169  // The integer trail. It always start by num_vars sentinel values with the
1170  // level 0 bounds (in one to one correspondence with vars_).
1171  struct TrailEntry {
1172  IntegerValue bound;
1173  IntegerVariable var;
1174  int32_t prev_trail_index;
1175 
1176  // Index in literals_reason_start_/bounds_reason_starts_ If this is -1, then
1177  // this was a propagation with a lazy reason, and the reason can be
1178  // re-created by calling the function lazy_reasons_[trail_index].
1179  int32_t reason_index;
1180  };
1181  std::vector<TrailEntry> integer_trail_;
1182  std::vector<LazyReasonFunction> lazy_reasons_;
1183 
1184  // Start of each decision levels in integer_trail_.
1185  // TODO(user): use more general reversible mechanism?
1186  std::vector<int> integer_search_levels_;
1187 
1188  // Buffer to store the reason of each trail entry.
1189  // Note that bounds_reason_buffer_ is an "union". It initially contains the
1190  // IntegerLiteral, and is lazily replaced by the result of
1191  // FindLowestTrailIndexThatExplainBound() applied to these literals. The
1192  // encoding is a bit hacky, see Dependencies().
1193  std::vector<int> reason_decision_levels_;
1194  std::vector<int> literals_reason_starts_;
1195  std::vector<int> bounds_reason_starts_;
1196  std::vector<Literal> literals_reason_buffer_;
1197 
1198  // These two vectors are in one to one correspondence. Dependencies() will
1199  // "cache" the result of the conversion from IntegerLiteral to trail indices
1200  // in trail_index_reason_buffer_.
1201  std::vector<IntegerLiteral> bounds_reason_buffer_;
1202  mutable std::vector<int> trail_index_reason_buffer_;
1203 
1204  // Temporary vector filled by calls to LazyReasonFunction().
1205  mutable std::vector<Literal> lazy_reason_literals_;
1206  mutable std::vector<int> lazy_reason_trail_indices_;
1207 
1208  // The "is_ignored" literal of the optional variables or kNoLiteralIndex.
1210 
1211  // Temporary data used by MergeReasonInto().
1212  mutable bool has_dependency_ = false;
1213  mutable std::vector<int> tmp_queue_;
1214  mutable std::vector<IntegerVariable> tmp_to_clear_;
1216  tmp_var_to_trail_index_in_queue_;
1217  mutable SparseBitset<BooleanVariable> added_variables_;
1218 
1219  // Temporary heap used by RelaxLinearReason();
1220  struct RelaxHeapEntry {
1221  int index;
1222  IntegerValue coeff;
1223  int64_t diff;
1224  bool operator<(const RelaxHeapEntry& o) const { return index < o.index; }
1225  };
1226  mutable std::vector<RelaxHeapEntry> relax_heap_;
1227  mutable std::vector<int> tmp_indices_;
1228 
1229  // Temporary data used by AppendNewBounds().
1230  mutable SparseBitset<IntegerVariable> tmp_marked_;
1231 
1232  // Temporary data used by SafeEnqueue();
1233  std::vector<IntegerLiteral> tmp_cleaned_reason_;
1234 
1235  // For EnqueueLiteral(), we store a special TrailEntry to recover the reason
1236  // lazily. This vector indicates the correspondence between a literal that
1237  // was pushed by this class at a given trail index, and the index of its
1238  // TrailEntry in integer_trail_.
1239  std::vector<int> boolean_trail_index_to_integer_one_;
1240 
1241  // We need to know if we skipped some propagation in the current branch.
1242  // This is reverted as we backtrack over it.
1243  int first_level_without_full_propagation_ = -1;
1244 
1245  int64_t num_enqueues_ = 0;
1246  int64_t num_untrails_ = 0;
1247  int64_t num_level_zero_enqueues_ = 0;
1248  mutable int64_t num_decisions_to_break_loop_ = 0;
1249 
1250  std::vector<SparseBitset<IntegerVariable>*> watchers_;
1251  std::vector<ReversibleInterface*> reversible_classes_;
1252 
1253  mutable Domain temp_domain_;
1254  DelayedRootLevelDeduction* delayed_to_fix_;
1255  IntegerDomains* domains_;
1256  IntegerEncoder* encoder_;
1257  Trail* trail_;
1258  SatSolver* sat_solver_;
1259  const SatParameters& parameters_;
1260 
1261  // Temporary "hash" to keep track of all the conditional enqueue that were
1262  // done. Note that we currently do not keep any reason for them, and as such,
1263  // we can only use this in heuristics. See ConditionalLowerBound().
1264  absl::flat_hash_map<std::pair<LiteralIndex, IntegerVariable>, IntegerValue>
1265  conditional_lbs_;
1266 
1267  std::function<bool(absl::Span<const Literal> clause,
1268  absl::Span<const IntegerLiteral> integers)>
1269  debug_checker_ = nullptr;
1270 
1271  DISALLOW_COPY_AND_ASSIGN(IntegerTrail);
1272 };
1273 
1274 // Base class for CP like propagators.
1276  public:
1279 
1280  // This will be called after one or more literals that are watched by this
1281  // propagator changed. It will also always be called on the first propagation
1282  // cycle after registration.
1283  virtual bool Propagate() = 0;
1284 
1285  // This will only be called on a non-empty vector, otherwise Propagate() will
1286  // be called. The passed vector will contain the "watch index" of all the
1287  // literals that were given one at registration and that changed since the
1288  // last call to Propagate(). This is only true when going down in the search
1289  // tree, on backjump this list will be cleared.
1290  //
1291  // Notes:
1292  // - The indices may contain duplicates if the same integer variable as been
1293  // updated many times or if different watched literals have the same
1294  // watch_index.
1295  // - At level zero, it will not contain any indices associated with literals
1296  // that were already fixed when the propagator was registered. Only the
1297  // indices of the literals modified after the registration will be present.
1298  virtual bool IncrementalPropagate(const std::vector<int>& watch_indices) {
1299  LOG(FATAL) << "Not implemented.";
1300  return false; // Remove warning in Windows
1301  }
1302 };
1303 
1304 // Singleton for basic reversible types. We need the wrapper so that they can be
1305 // accessed with model->GetOrCreate<>() and properly registered at creation.
1306 class RevIntRepository : public RevRepository<int> {
1307  public:
1309  model->GetOrCreate<IntegerTrail>()->RegisterReversibleClass(this);
1310  }
1311 };
1312 class RevIntegerValueRepository : public RevRepository<IntegerValue> {
1313  public:
1315  model->GetOrCreate<IntegerTrail>()->RegisterReversibleClass(this);
1316  }
1317 };
1318 
1319 // This class allows registering Propagator that will be called if a
1320 // watched Literal or LbVar changes.
1321 //
1322 // TODO(user): Move this to its own file. Add unit tests!
1324  public:
1325  explicit GenericLiteralWatcher(Model* model);
1327 
1328  // Memory optimization: you can call this before registering watchers.
1329  void ReserveSpaceForNumVariables(int num_vars);
1330 
1331  // On propagate, the registered propagators will be called if they need to
1332  // until a fixed point is reached. Propagators with low ids will tend to be
1333  // called first, but it ultimately depends on their "waking" order.
1334  bool Propagate(Trail* trail) final;
1335  void Untrail(const Trail& trail, int literal_trail_index) final;
1336 
1337  // Registers a propagator and returns its unique ids.
1338  int Register(PropagatorInterface* propagator);
1339 
1340  // Changes the priority of the propagator with given id. The priority is a
1341  // non-negative integer. Propagators with a lower priority will always be
1342  // run before the ones with a higher one. The default priority is one.
1343  void SetPropagatorPriority(int id, int priority);
1344 
1345  // The default behavior is to assume that a propagator does not need to be
1346  // called twice in a row. However, propagators on which this is called will be
1347  // called again if they change one of their own watched variables.
1349 
1350  // Whether we call a propagator even if its watched variables didn't change.
1351  // This is only used when we are back to level zero. This was introduced for
1352  // the LP propagator where we might need to continue an interrupted solve or
1353  // add extra cuts at level zero.
1354  void AlwaysCallAtLevelZero(int id);
1355 
1356  // Watches the corresponding quantity. The propagator with given id will be
1357  // called if it changes. Note that WatchLiteral() only trigger when the
1358  // literal becomes true.
1359  //
1360  // If watch_index is specified, it is associated with the watched literal.
1361  // Doing this will cause IncrementalPropagate() to be called (see the
1362  // documentation of this interface for more detail).
1363  void WatchLiteral(Literal l, int id, int watch_index = -1);
1364  void WatchLowerBound(IntegerVariable var, int id, int watch_index = -1);
1365  void WatchUpperBound(IntegerVariable var, int id, int watch_index = -1);
1366  void WatchIntegerVariable(IntegerVariable i, int id, int watch_index = -1);
1367 
1368  // Because the coeff is always positive, whatching an affine expression is
1369  // the same as watching its var.
1371  WatchLowerBound(e.var, id);
1372  }
1374  WatchUpperBound(e.var, id);
1375  }
1377  WatchIntegerVariable(e.var, id);
1378  }
1379 
1380  // No-op overload for "constant" IntegerVariable that are sometimes templated
1381  // as an IntegerValue.
1382  void WatchLowerBound(IntegerValue i, int id) {}
1383  void WatchUpperBound(IntegerValue i, int id) {}
1384  void WatchIntegerVariable(IntegerValue v, int id) {}
1385 
1386  // Registers a reversible class with a given propagator. This class will be
1387  // changed to the correct state just before the propagator is called.
1388  //
1389  // Doing it just before should minimize cache-misses and bundle as much as
1390  // possible the "backtracking" together. Many propagators only watches a
1391  // few variables and will not be called at each decision levels.
1392  void RegisterReversibleClass(int id, ReversibleInterface* rev);
1393 
1394  // Registers a reversible int with a given propagator. The int will be changed
1395  // to its correct value just before Propagate() is called.
1396  //
1397  // Note that this will work in O(num_rev_int_of_propagator_id) per call to
1398  // Propagate() and happens at most once per decision level. As such this is
1399  // meant for classes that have just a few reversible ints or that will have a
1400  // similar complexity anyway.
1401  //
1402  // Alternatively, one can directly get the underlying RevRepository<int> with
1403  // a call to model.Get<>(), and use SaveWithStamp() before each modification
1404  // to have just a slight overhead per int updates. This later option is what
1405  // is usually done in a CP solver at the cost of a sligthly more complex API.
1406  void RegisterReversibleInt(int id, int* rev);
1407 
1408  // Returns the number of registered propagators.
1409  int NumPropagators() const { return in_queue_.size(); }
1410 
1411  // Set a callback for new variable bounds at level 0.
1412  //
1413  // This will be called (only at level zero) with the list of IntegerVariable
1414  // with changed lower bounds. Note that it might be called more than once
1415  // during the same propagation cycle if we fix variables in "stages".
1416  //
1417  // Also note that this will be called if some BooleanVariable where fixed even
1418  // if no IntegerVariable are changed, so the passed vector to the function
1419  // might be empty.
1421  const std::function<void(const std::vector<IntegerVariable>&)> cb) {
1422  level_zero_modified_variable_callback_.push_back(cb);
1423  }
1424 
1425  // This will be called not too often during propagation (when we finish
1426  // propagating one priority). If it returns true, we will stop propagation
1427  // there. It is used by LbTreeSearch as we can stop as soon as the objective
1428  // lower bound crossed a threshold and do not need to call expensive
1429  // propagator when this is the case.
1430  void SetStopPropagationCallback(std::function<bool()> callback) {
1431  stop_propagation_callback_ = callback;
1432  }
1433 
1434  // Returns the id of the propagator we are currently calling. This is meant
1435  // to be used from inside Propagate() in case a propagator was registered
1436  // more than once at different priority for instance.
1437  int GetCurrentId() const { return current_id_; }
1438 
1439  // Add the given propagator to its queue.
1440  void CallOnNextPropagate(int id);
1441 
1442  private:
1443  // Updates queue_ and in_queue_ with the propagator ids that need to be
1444  // called.
1445  void UpdateCallingNeeds(Trail* trail);
1446 
1447  TimeLimit* time_limit_;
1448  IntegerTrail* integer_trail_;
1449  RevIntRepository* rev_int_repository_;
1450 
1451  struct WatchData {
1452  int id;
1453  int watch_index;
1454  bool operator==(const WatchData& o) const {
1455  return id == o.id && watch_index == o.watch_index;
1456  }
1457  };
1460  std::vector<PropagatorInterface*> watchers_;
1461  SparseBitset<IntegerVariable> modified_vars_;
1462 
1463  // For RegisterLevelZeroModifiedVariablesCallback().
1464  SparseBitset<IntegerVariable> modified_vars_for_callback_;
1465 
1466  // Propagator ids that needs to be called. There is one queue per priority but
1467  // just one Boolean to indicate if a propagator is in one of them.
1468  std::vector<std::deque<int>> queue_by_priority_;
1469  std::vector<bool> in_queue_;
1470 
1471  // Data for each propagator.
1472  DEFINE_STRONG_INDEX_TYPE(IdType);
1473  std::vector<int> id_to_level_at_last_call_;
1474  RevVector<IdType, int> id_to_greatest_common_level_since_last_call_;
1475  std::vector<std::vector<ReversibleInterface*>> id_to_reversible_classes_;
1476  std::vector<std::vector<int*>> id_to_reversible_ints_;
1477  std::vector<std::vector<int>> id_to_watch_indices_;
1478  std::vector<int> id_to_priority_;
1479  std::vector<int> id_to_idempotence_;
1480 
1481  // Special propagators that needs to always be called at level zero.
1482  std::vector<int> propagator_ids_to_call_at_level_zero_;
1483 
1484  // The id of the propagator we just called.
1485  int current_id_;
1486 
1487  std::vector<std::function<void(const std::vector<IntegerVariable>&)>>
1488  level_zero_modified_variable_callback_;
1489 
1490  std::function<bool()> stop_propagation_callback_;
1491 
1492  DISALLOW_COPY_AND_ASSIGN(GenericLiteralWatcher);
1493 };
1494 
1495 // ============================================================================
1496 // Implementation.
1497 // ============================================================================
1498 
1500  IntegerValue bound) {
1501  return IntegerLiteral(
1503 }
1504 
1506  IntegerValue bound) {
1507  return IntegerLiteral(
1509 }
1510 
1512  return IntegerLiteral(kNoIntegerVariable, IntegerValue(-1));
1513 }
1514 
1516  return IntegerLiteral(kNoIntegerVariable, IntegerValue(1));
1517 }
1518 
1520  // Note that bound >= kMinIntegerValue, so -bound + 1 will have the correct
1521  // capped value.
1522  return IntegerLiteral(
1523  NegationOf(IntegerVariable(var)),
1525 }
1526 
1527 // var * coeff + constant >= bound.
1529  IntegerValue bound) const {
1530  if (var == kNoIntegerVariable) {
1533  }
1534  DCHECK_GT(coeff, 0);
1537 }
1538 
1540  return GreaterOrEqual(IntegerValue(bound));
1541 }
1542 
1543 // var * coeff + constant <= bound.
1545  if (var == kNoIntegerVariable) {
1548  }
1549  DCHECK_GT(coeff, 0);
1551 }
1552 
1554  return LowerOrEqual(IntegerValue(bound));
1555 }
1556 
1557 inline IntegerValue IntegerTrail::LowerBound(IntegerVariable i) const {
1558  return vars_[i].current_bound;
1559 }
1560 
1561 inline IntegerValue IntegerTrail::UpperBound(IntegerVariable i) const {
1562  return -vars_[NegationOf(i)].current_bound;
1563 }
1564 
1565 inline bool IntegerTrail::IsFixed(IntegerVariable i) const {
1566  return vars_[i].current_bound == -vars_[NegationOf(i)].current_bound;
1567 }
1568 
1569 inline IntegerValue IntegerTrail::FixedValue(IntegerVariable i) const {
1570  DCHECK(IsFixed(i));
1571  return vars_[i].current_bound;
1572 }
1573 
1575  Literal l, IntegerVariable i) const {
1576  const auto it = conditional_lbs_.find({l.Index(), i});
1577  if (it != conditional_lbs_.end()) {
1578  return std::max(vars_[i].current_bound, it->second);
1579  }
1580  return vars_[i].current_bound;
1581 }
1582 
1584  Literal l, AffineExpression expr) const {
1585  if (expr.var == kNoIntegerVariable) return expr.constant;
1586  return ConditionalLowerBound(l, expr.var) * expr.coeff + expr.constant;
1587 }
1588 
1590  IntegerVariable i) const {
1592 }
1593 
1595  IntegerVariable i) const {
1597 }
1598 
1599 inline IntegerValue IntegerTrail::LowerBound(AffineExpression expr) const {
1600  if (expr.var == kNoIntegerVariable) return expr.constant;
1601  return LowerBound(expr.var) * expr.coeff + expr.constant;
1602 }
1603 
1604 inline IntegerValue IntegerTrail::UpperBound(AffineExpression expr) const {
1605  if (expr.var == kNoIntegerVariable) return expr.constant;
1606  return UpperBound(expr.var) * expr.coeff + expr.constant;
1607 }
1608 
1609 inline bool IntegerTrail::IsFixed(AffineExpression expr) const {
1610  if (expr.var == kNoIntegerVariable) return true;
1611  return IsFixed(expr.var);
1612 }
1613 
1614 inline IntegerValue IntegerTrail::FixedValue(AffineExpression expr) const {
1615  if (expr.var == kNoIntegerVariable) return expr.constant;
1616  return FixedValue(expr.var) * expr.coeff + expr.constant;
1617 }
1618 
1620  AffineExpression expr) const {
1621  if (expr.var == kNoIntegerVariable) return IntegerLiteral::TrueLiteral();
1622  return IntegerLiteral::GreaterOrEqual(expr.var, LowerBound(expr.var));
1623 }
1624 
1626  AffineExpression expr) const {
1627  if (expr.var == kNoIntegerVariable) return IntegerLiteral::TrueLiteral();
1628  return IntegerLiteral::LowerOrEqual(expr.var, UpperBound(expr.var));
1629 }
1630 
1632  return l.bound <= LowerBound(l.var);
1633 }
1634 
1636  return l.bound > UpperBound(l.var);
1637 }
1638 
1639 // The level zero bounds are stored at the beginning of the trail and they also
1640 // serves as sentinels. Their index match the variables index.
1642  IntegerVariable var) const {
1643  return integer_trail_[var.value()].bound;
1644 }
1645 
1647  IntegerVariable var) const {
1648  return -integer_trail_[NegationOf(var).value()].bound;
1649 }
1650 
1651 inline bool IntegerTrail::IsFixedAtLevelZero(IntegerVariable var) const {
1652  return integer_trail_[var.value()].bound ==
1653  -integer_trail_[NegationOf(var).value()].bound;
1654 }
1655 
1657  AffineExpression expr) const {
1658  if (expr.var == kNoIntegerVariable) return expr.constant;
1659  return expr.ValueAt(LevelZeroLowerBound(expr.var));
1660 }
1661 
1663  AffineExpression expr) const {
1664  if (expr.var == kNoIntegerVariable) return expr.constant;
1665  return expr.ValueAt(LevelZeroUpperBound(expr.var));
1666 }
1667 
1669  if (expr.var == kNoIntegerVariable) return true;
1670  return IsFixedAtLevelZero(expr.var);
1671 }
1672 
1674  int watch_index) {
1675  if (l.Index() >= literal_to_watcher_.size()) {
1676  literal_to_watcher_.resize(l.Index().value() + 1);
1677  }
1678  literal_to_watcher_[l.Index()].push_back({id, watch_index});
1679 }
1680 
1681 inline void GenericLiteralWatcher::WatchLowerBound(IntegerVariable var, int id,
1682  int watch_index) {
1683  if (var == kNoIntegerVariable) return;
1684  if (var.value() >= var_to_watcher_.size()) {
1685  var_to_watcher_.resize(var.value() + 1);
1686  }
1687 
1688  // Minor optim, so that we don't watch the same variable twice. Propagator
1689  // code is easier this way since for example when one wants to watch both
1690  // an interval start and interval end, both might have the same underlying
1691  // variable.
1692  const WatchData data = {id, watch_index};
1693  if (!var_to_watcher_[var].empty() && var_to_watcher_[var].back() == data) {
1694  return;
1695  }
1696  var_to_watcher_[var].push_back(data);
1697 }
1698 
1699 inline void GenericLiteralWatcher::WatchUpperBound(IntegerVariable var, int id,
1700  int watch_index) {
1701  if (var == kNoIntegerVariable) return;
1702  WatchLowerBound(NegationOf(var), id, watch_index);
1703 }
1704 
1705 inline void GenericLiteralWatcher::WatchIntegerVariable(IntegerVariable i,
1706  int id,
1707  int watch_index) {
1708  WatchLowerBound(i, id, watch_index);
1709  WatchUpperBound(i, id, watch_index);
1710 }
1711 
1712 // ============================================================================
1713 // Model based functions.
1714 //
1715 // Note that in the model API, we simply use int64_t for the integer values, so
1716 // that it is nicer for the client. Internally these are converted to
1717 // IntegerValue which is typechecked.
1718 // ============================================================================
1719 
1720 inline std::function<BooleanVariable(Model*)> NewBooleanVariable() {
1721  return [=](Model* model) {
1722  return model->GetOrCreate<SatSolver>()->NewBooleanVariable();
1723  };
1724 }
1725 
1726 inline std::function<IntegerVariable(Model*)> ConstantIntegerVariable(
1727  int64_t value) {
1728  return [=](Model* model) {
1729  return model->GetOrCreate<IntegerTrail>()
1730  ->GetOrCreateConstantIntegerVariable(IntegerValue(value));
1731  };
1732 }
1733 
1734 inline std::function<IntegerVariable(Model*)> NewIntegerVariable(int64_t lb,
1735  int64_t ub) {
1736  return [=](Model* model) {
1737  CHECK_LE(lb, ub);
1738  return model->GetOrCreate<IntegerTrail>()->AddIntegerVariable(
1739  IntegerValue(lb), IntegerValue(ub));
1740  };
1741 }
1742 
1743 inline std::function<IntegerVariable(Model*)> NewIntegerVariable(
1744  const Domain& domain) {
1745  return [=](Model* model) {
1746  return model->GetOrCreate<IntegerTrail>()->AddIntegerVariable(domain);
1747  };
1748 }
1749 
1750 // Creates a 0-1 integer variable "view" of the given literal. It will have a
1751 // value of 1 when the literal is true, and 0 when the literal is false.
1752 inline std::function<IntegerVariable(Model*)> NewIntegerVariableFromLiteral(
1753  Literal lit) {
1754  return [=](Model* model) {
1755  auto* encoder = model->GetOrCreate<IntegerEncoder>();
1756  const IntegerVariable candidate = encoder->GetLiteralView(lit);
1757  if (candidate != kNoIntegerVariable) return candidate;
1758 
1759  IntegerVariable var;
1760  const auto& assignment = model->GetOrCreate<SatSolver>()->Assignment();
1761  if (assignment.LiteralIsTrue(lit)) {
1762  var = model->Add(ConstantIntegerVariable(1));
1763  } else if (assignment.LiteralIsFalse(lit)) {
1764  var = model->Add(ConstantIntegerVariable(0));
1765  } else {
1766  var = model->Add(NewIntegerVariable(0, 1));
1767  }
1768 
1769  encoder->AssociateToIntegerEqualValue(lit, var, IntegerValue(1));
1770  DCHECK_NE(encoder->GetLiteralView(lit), kNoIntegerVariable);
1771  return var;
1772  };
1773 }
1774 
1775 inline std::function<int64_t(const Model&)> LowerBound(IntegerVariable v) {
1776  return [=](const Model& model) {
1777  return model.Get<IntegerTrail>()->LowerBound(v).value();
1778  };
1779 }
1780 
1781 inline std::function<int64_t(const Model&)> UpperBound(IntegerVariable v) {
1782  return [=](const Model& model) {
1783  return model.Get<IntegerTrail>()->UpperBound(v).value();
1784  };
1785 }
1786 
1787 inline std::function<bool(const Model&)> IsFixed(IntegerVariable v) {
1788  return [=](const Model& model) {
1789  const IntegerTrail* trail = model.Get<IntegerTrail>();
1790  return trail->LowerBound(v) == trail->UpperBound(v);
1791  };
1792 }
1793 
1794 // This checks that the variable is fixed.
1795 inline std::function<int64_t(const Model&)> Value(IntegerVariable v) {
1796  return [=](const Model& model) {
1797  const IntegerTrail* trail = model.Get<IntegerTrail>();
1798  CHECK_EQ(trail->LowerBound(v), trail->UpperBound(v)) << v;
1799  return trail->LowerBound(v).value();
1800  };
1801 }
1802 
1803 inline std::function<void(Model*)> GreaterOrEqual(IntegerVariable v,
1804  int64_t lb) {
1805  return [=](Model* model) {
1806  if (!model->GetOrCreate<IntegerTrail>()->Enqueue(
1807  IntegerLiteral::GreaterOrEqual(v, IntegerValue(lb)),
1808  std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1809  model->GetOrCreate<SatSolver>()->NotifyThatModelIsUnsat();
1810  VLOG(1) << "Model trivially infeasible, variable " << v
1811  << " has upper bound " << model->Get(UpperBound(v))
1812  << " and GreaterOrEqual() was called with a lower bound of "
1813  << lb;
1814  }
1815  };
1816 }
1817 
1818 inline std::function<void(Model*)> LowerOrEqual(IntegerVariable v, int64_t ub) {
1819  return [=](Model* model) {
1820  if (!model->GetOrCreate<IntegerTrail>()->Enqueue(
1821  IntegerLiteral::LowerOrEqual(v, IntegerValue(ub)),
1822  std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1823  model->GetOrCreate<SatSolver>()->NotifyThatModelIsUnsat();
1824  VLOG(1) << "Model trivially infeasible, variable " << v
1825  << " has lower bound " << model->Get(LowerBound(v))
1826  << " and LowerOrEqual() was called with an upper bound of " << ub;
1827  }
1828  };
1829 }
1830 
1831 // Fix v to a given value.
1832 inline std::function<void(Model*)> Equality(IntegerVariable v, int64_t value) {
1833  return [=](Model* model) {
1834  model->Add(LowerOrEqual(v, value));
1835  model->Add(GreaterOrEqual(v, value));
1836  };
1837 }
1838 
1839 // TODO(user): This is one of the rare case where it is better to use Equality()
1840 // rather than two Implications(). Maybe we should modify our internal
1841 // implementation to use half-reified encoding? that is do not propagate the
1842 // direction integer-bound => literal, but just literal => integer-bound? This
1843 // is the same as using different underlying variable for an integer literal and
1844 // its negation.
1845 inline std::function<void(Model*)> Implication(
1846  const std::vector<Literal>& enforcement_literals, IntegerLiteral i) {
1847  return [=](Model* model) {
1848  IntegerTrail* integer_trail = model->GetOrCreate<IntegerTrail>();
1849  if (i.bound <= integer_trail->LowerBound(i.var)) {
1850  // Always true! nothing to do.
1851  } else if (i.bound > integer_trail->UpperBound(i.var)) {
1852  // Always false.
1853  std::vector<Literal> clause;
1854  for (const Literal literal : enforcement_literals) {
1855  clause.push_back(literal.Negated());
1856  }
1857  model->Add(ClauseConstraint(clause));
1858  } else {
1859  // TODO(user): Double check what happen when we associate a trivially
1860  // true or false literal.
1861  IntegerEncoder* encoder = model->GetOrCreate<IntegerEncoder>();
1862  std::vector<Literal> clause{encoder->GetOrCreateAssociatedLiteral(i)};
1863  for (const Literal literal : enforcement_literals) {
1864  clause.push_back(literal.Negated());
1865  }
1866  model->Add(ClauseConstraint(clause));
1867  }
1868  };
1869 }
1870 
1871 // in_interval => v in [lb, ub].
1872 inline std::function<void(Model*)> ImpliesInInterval(Literal in_interval,
1873  IntegerVariable v,
1874  int64_t lb, int64_t ub) {
1875  return [=](Model* model) {
1876  if (lb == ub) {
1877  IntegerEncoder* encoder = model->GetOrCreate<IntegerEncoder>();
1878  model->Add(Implication({in_interval},
1880  v, IntegerValue(lb))));
1881  return;
1882  }
1883  model->Add(Implication(
1884  {in_interval}, IntegerLiteral::GreaterOrEqual(v, IntegerValue(lb))));
1885  model->Add(Implication({in_interval},
1886  IntegerLiteral::LowerOrEqual(v, IntegerValue(ub))));
1887  };
1888 }
1889 
1890 // Calling model.Add(FullyEncodeVariable(var)) will create one literal per value
1891 // in the domain of var (if not already done), and wire everything correctly.
1892 // This also returns the full encoding, see the FullDomainEncoding() method of
1893 // the IntegerEncoder class.
1894 inline std::function<std::vector<ValueLiteralPair>(Model*)> FullyEncodeVariable(
1895  IntegerVariable var) {
1896  return [=](Model* model) {
1897  IntegerEncoder* encoder = model->GetOrCreate<IntegerEncoder>();
1898  if (!encoder->VariableIsFullyEncoded(var)) {
1899  encoder->FullyEncodeVariable(var);
1900  }
1901  return encoder->FullDomainEncoding(var);
1902  };
1903 }
1904 
1905 // Same as ExcludeCurrentSolutionAndBacktrack() but this version works for an
1906 // integer problem with optional variables. The issue is that an optional
1907 // variable that is ignored can basically take any value, and we don't really
1908 // want to enumerate them. This function should exclude all solutions where
1909 // only the ignored variable values change.
1910 std::function<void(Model*)>
1912 
1913 } // namespace sat
1914 } // namespace operations_research
1915 
1916 #endif // OR_TOOLS_SAT_INTEGER_H_
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
void resize(size_type new_size)
size_type size() const
void push_back(const value_type &x)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
We call domain any subset of Int64 = [kint64min, kint64max].
void ClearAndResize(IntegerType size)
Definition: bitset.h:767
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:106
void WatchLowerBound(IntegerValue i, int id)
Definition: integer.h:1382
void RegisterLevelZeroModifiedVariablesCallback(const std::function< void(const std::vector< IntegerVariable > &)> cb)
Definition: integer.h:1420
void WatchIntegerVariable(IntegerValue v, int id)
Definition: integer.h:1384
void WatchLowerBound(AffineExpression e, int id)
Definition: integer.h:1370
void WatchUpperBound(AffineExpression e, int id)
Definition: integer.h:1373
void RegisterReversibleClass(int id, ReversibleInterface *rev)
Definition: integer.cc:2325
void WatchLiteral(Literal l, int id, int watch_index=-1)
Definition: integer.h:1673
void WatchUpperBound(IntegerValue i, int id)
Definition: integer.h:1383
void WatchLowerBound(IntegerVariable var, int id, int watch_index=-1)
Definition: integer.h:1681
void WatchIntegerVariable(IntegerVariable i, int id, int watch_index=-1)
Definition: integer.h:1705
void WatchAffineExpression(AffineExpression e, int id)
Definition: integer.h:1376
void WatchUpperBound(IntegerVariable var, int id, int watch_index=-1)
Definition: integer.h:1699
void SetStopPropagationCallback(std::function< bool()> callback)
Definition: integer.h:1430
void SetPropagatorPriority(int id, int priority)
Definition: integer.cc:2309
int Register(PropagatorInterface *propagator)
Definition: integer.cc:2286
void Untrail(const Trail &trail, int literal_trail_index) final
Definition: integer.cc:2262
Literal GetOrCreateLiteralAssociatedToEquality(IntegerVariable var, IntegerValue value)
Definition: integer.cc:308
LiteralIndex GetAssociatedLiteral(IntegerLiteral i_lit) const
Definition: integer.cc:517
void FullyEncodeVariable(IntegerVariable var)
Definition: integer.cc:74
bool UpdateEncodingOnInitialDomainChange(IntegerVariable var, Domain domain)
Definition: integer.cc:615
void ReserveSpaceForNumVariables(int num_vars)
Definition: integer.cc:68
const IntegerVariable GetLiteralView(Literal lit) const
Definition: integer.h:558
std::pair< IntegerLiteral, IntegerLiteral > Canonicalize(IntegerLiteral i_lit) const
Definition: integer.cc:227
LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i_lit, IntegerValue *bound) const
Definition: integer.cc:531
void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var, IntegerValue value)
Definition: integer.cc:417
std::vector< ValueLiteralPair > PartialDomainEncoding(IntegerVariable var) const
Definition: integer.cc:146
const std::vector< IntegerVariable > & GetAllAssociatedVariables(Literal lit) const
Definition: integer.h:542
const InlinedIntegerLiteralVector & GetIntegerLiterals(Literal lit) const
Definition: integer.h:524
ABSL_MUST_USE_RESULT bool LiteralOrNegationHasView(Literal lit, IntegerVariable *view=nullptr, bool *view_is_direct=nullptr) const
Definition: integer.cc:559
std::vector< ValueLiteralPair > FullDomainEncoding(IntegerVariable var) const
Definition: integer.cc:140
const InlinedIntegerValueVector & GetEqualityLiterals(Literal lit) const
Definition: integer.h:533
bool VariableIsFullyEncoded(IntegerVariable var) const
Definition: integer.cc:105
std::vector< ValueLiteralPair > PartialGreaterThanEncoding(IntegerVariable var) const
Definition: integer.cc:579
LiteralIndex GetAssociatedEqualityLiteral(IntegerVariable var, IntegerValue value) const
Definition: integer.cc:298
void AssociateToIntegerLiteral(Literal literal, IntegerLiteral i_lit)
Definition: integer.cc:345
Literal GetOrCreateAssociatedLiteral(IntegerLiteral i_lit)
Definition: integer.cc:254
IntegerVariable FirstUnassignedVariable() const
Definition: integer.cc:1498
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
Definition: integer.cc:1228
IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value)
Definition: integer.cc:893
void RegisterWatcher(SparseBitset< IntegerVariable > *p)
Definition: integer.h:997
bool Propagate(Trail *trail) final
Definition: integer.cc:682
void ReserveSpaceForNumVariables(int num_vars)
Definition: integer.cc:797
int FindTrailIndexOfVarBefore(IntegerVariable var, int threshold) const
Definition: integer.cc:914
bool IsCurrentlyIgnored(IntegerVariable i) const
Definition: integer.h:775
std::vector< Literal > ReasonFor(IntegerLiteral literal) const
Definition: integer.cc:1873
bool ReportConflict(absl::Span< const IntegerLiteral > integer_reason)
Definition: integer.h:1012
std::function< void(IntegerLiteral literal_to_explain, int trail_index_of_literal, std::vector< Literal > *literals, std::vector< int > *dependencies)> LazyReasonFunction
Definition: integer.h:953
int64_t num_level_zero_enqueues() const
Definition: integer.h:992
bool IsFixed(IntegerVariable i) const
Definition: integer.h:1565
LiteralIndex OptionalLiteralIndex(IntegerVariable i) const
Definition: integer.h:784
absl::Span< const Literal > Reason(const Trail &trail, int trail_index) const final
Definition: integer.cc:2029
IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const
Definition: integer.h:1589
bool ReportConflict(absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
Definition: integer.h:1004
void EnqueueLiteral(Literal literal, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
Definition: integer.cc:1387
ABSL_MUST_USE_RESULT bool RootLevelEnqueue(IntegerLiteral i_lit)
Definition: integer.cc:1188
IntegerVariable NextVariableToBranchOnInPropagationLoop() const
Definition: integer.cc:1465
IntegerValue UpperBound(IntegerVariable i) const
Definition: integer.h:1561
void MarkIntegerVariableAsOptional(IntegerVariable i, Literal is_considered)
Definition: integer.h:789
ABSL_MUST_USE_RESULT bool SafeEnqueue(IntegerLiteral i_lit, absl::Span< const IntegerLiteral > integer_reason)
Definition: integer.cc:1211
IntegerValue LevelZeroUpperBound(IntegerVariable var) const
Definition: integer.h:1646
IntegerValue ConditionalLowerBound(Literal l, IntegerVariable i) const
Definition: integer.h:1574
IntegerValue FixedValue(IntegerVariable i) const
Definition: integer.h:1569
bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const
Definition: integer.h:1021
void AppendRelaxedLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, absl::Span< const IntegerVariable > vars, std::vector< IntegerLiteral > *reason) const
Definition: integer.cc:1006
IntegerValue LevelZeroLowerBound(IntegerVariable var) const
Definition: integer.h:1641
void RelaxLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, std::vector< IntegerLiteral > *reason) const
Definition: integer.cc:984
void AppendNewBounds(std::vector< IntegerLiteral > *output) const
Definition: integer.cc:2049
bool IntegerLiteralIsTrue(IntegerLiteral l) const
Definition: integer.h:1631
IntegerValue LowerBound(IntegerVariable i) const
Definition: integer.h:1557
IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const
Definition: integer.h:1594
bool IsFixedAtLevelZero(IntegerVariable var) const
Definition: integer.h:1651
void MergeReasonInto(absl::Span< const IntegerLiteral > literals, std::vector< Literal > *output) const
Definition: integer.cc:1879
Literal IsIgnoredLiteral(IntegerVariable i) const
Definition: integer.h:780
bool IsOptional(IntegerVariable i) const
Definition: integer.h:772
ABSL_MUST_USE_RESULT bool ConditionalEnqueue(Literal lit, IntegerLiteral i_lit, std::vector< Literal > *literal_reason, std::vector< IntegerLiteral > *integer_reason)
Definition: integer.cc:1235
bool IntegerLiteralIsFalse(IntegerLiteral l) const
Definition: integer.h:1635
void RemoveLevelZeroBounds(std::vector< IntegerLiteral > *reason) const
Definition: integer.cc:1118
IntegerVariable AddIntegerVariable()
Definition: integer.h:763
void RegisterReversibleClass(ReversibleInterface *rev)
Definition: integer.h:1027
const Domain & InitialVariableDomain(IntegerVariable var) const
Definition: integer.cc:852
void Untrail(const Trail &trail, int literal_trail_index) final
Definition: integer.cc:748
IntegerVariable NumIntegerVariables() const
Definition: integer.h:715
bool UpdateInitialDomain(IntegerVariable var, Domain domain)
Definition: integer.cc:862
void RegisterDebugChecker(std::function< bool(absl::Span< const Literal > clause, absl::Span< const IntegerLiteral > integers)> checker)
Definition: integer.h:1066
LiteralIndex NegatedIndex() const
Definition: sat_base.h:91
LiteralIndex Index() const
Definition: sat_base.h:90
std::string DebugString() const
Definition: sat_base.h:99
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:42
virtual bool IncrementalPropagate(const std::vector< int > &watch_indices)
Definition: integer.h:1298
BooleanVariable NewBooleanVariable()
Definition: sat_solver.h:88
bool AddUnitClause(Literal true_literal)
Definition: sat_solver.cc:186
std::vector< Literal > * MutableConflict()
Definition: sat_base.h:373
const VariablesAssignment & Assignment() const
Definition: sat_base.h:402
bool LiteralIsTrue(Literal literal) const
Definition: sat_base.h:164
int64_t b
int64_t a
int64_t value
IntVar * var
Definition: expr_array.cc:1874
GRBmodel * model
MPCallback * callback
int index
Definition: cleanup.h:22
absl::InlinedVector< IntegerLiteral, 2 > InlinedIntegerLiteralVector
Definition: integer.h:242
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
Definition: integer.h:98
absl::InlinedVector< std::pair< IntegerVariable, IntegerValue >, 2 > InlinedIntegerValueVector
Definition: integer.h:244
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
Definition: integer.h:121
std::function< void(Model *)> GreaterOrEqual(IntegerVariable v, int64_t lb)
Definition: integer.h:1803
DEFINE_STRONG_INDEX_TYPE(ClauseIndex)
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
Definition: integer.h:1781
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:88
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
Definition: sat_solver.h:946
IntType IntTypeAbs(IntType t)
Definition: integer.h:85
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
Definition: integer.h:89
DEFINE_STRONG_INT64_TYPE(IntegerValue)
const LiteralIndex kNoLiteralIndex(-1)
std::function< BooleanVariable(Model *)> NewBooleanVariable()
Definition: integer.h:1720
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1795
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
Definition: integer.h:159
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
std::function< IntegerVariable(Model *)> NewIntegerVariableFromLiteral(Literal lit)
Definition: integer.h:1752
IntegerVariable PositiveVariable(IntegerVariable i)
Definition: integer.h:149
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
Definition: integer.h:113
std::function< void(Model *)> Implication(const std::vector< Literal > &enforcement_literals, IntegerLiteral i)
Definition: integer.h:1845
std::function< void(Model *)> LowerOrEqual(IntegerVariable v, int64_t ub)
Definition: integer.h:1818
std::function< IntegerVariable(Model *)> NewIntegerVariable(int64_t lb, int64_t ub)
Definition: integer.h:1734
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
Definition: integer.cc:46
std::function< void(Model *)> ExcludeCurrentSolutionWithoutIgnoredVariableAndBacktrack()
Definition: integer.cc:2336
std::function< void(Model *)> ImpliesInInterval(Literal in_interval, IntegerVariable v, int64_t lb, int64_t ub)
Definition: integer.h:1872
std::function< void(Model *)> Equality(IntegerVariable v, int64_t value)
Definition: integer.h:1832
std::function< bool(const Model &)> IsFixed(IntegerVariable v)
Definition: integer.h:1787
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
Definition: integer.h:155
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
Definition: integer.h:1775
bool VariableIsPositive(IntegerVariable i)
Definition: integer.h:145
std::function< std::vector< ValueLiteralPair >Model *)> FullyEncodeVariable(IntegerVariable var)
Definition: integer.h:1894
std::function< IntegerVariable(Model *)> ConstantIntegerVariable(int64_t value)
Definition: integer.h:1726
double ToDouble(IntegerValue value)
Definition: integer.h:77
Collection of objects used to extend the Constraint Solver library.
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
LinearRange operator==(const LinearExpr &lhs, const LinearExpr &rhs)
Definition: linear_expr.cc:184
Literal literal
Definition: optimization.cc:88
IntVar * upper_bound
Definition: routing.cc:1087
IntVar * lower_bound
Definition: routing.cc:1086
int64_t bound
constexpr double kInfinity
AffineExpression Negated() const
Definition: integer.h:276
AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
Definition: integer.h:260
IntegerLiteral GreaterOrEqual(IntegerValue bound) const
Definition: integer.h:1528
IntegerValue ValueAt(IntegerValue var_value) const
Definition: integer.h:291
IntegerLiteral LowerOrEqual(IntegerValue bound) const
Definition: integer.h:1544
double LpValue(const absl::StrongVector< IntegerVariable, double > &lp_values) const
Definition: integer.h:296
AffineExpression(IntegerVariable v, IntegerValue c)
Definition: integer.h:258
const std::string DebugString() const
Definition: integer.h:304
bool operator==(AffineExpression o) const
Definition: integer.h:286
AffineExpression MultipliedBy(IntegerValue multiplier) const
Definition: integer.h:281
absl::StrongVector< IntegerVariable, IntegerValue > ivar_values
Definition: integer.h:344
std::vector< int64_t > proto_values
Definition: integer.h:334
absl::StrongVector< IntegerVariable, bool > ivar_has_value
Definition: integer.h:343
std::vector< IntegerLiteral > integer_literal_to_fix
Definition: integer.h:399
bool operator==(IntegerLiteral o) const
Definition: integer.h:203
IntegerLiteral(IntegerVariable v, IntegerValue b)
Definition: integer.h:191
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
Definition: integer.h:1505
static IntegerLiteral TrueLiteral()
Definition: integer.h:1511
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
Definition: integer.h:1499
IntegerLiteral Negated() const
Definition: integer.h:1519
bool operator!=(IntegerLiteral o) const
Definition: integer.h:206
static IntegerLiteral FalseLiteral()
Definition: integer.h:1515
bool operator==(const LiteralValueValue &rhs) const
Definition: integer.h:381
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
Definition: integer.h:350
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
Definition: integer.h:356
bool operator==(const ValueLiteralPair &o) const
Definition: integer.h:363
#define VLOG(verboselevel)
Definition: vlog.h:39