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