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