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