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