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