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