Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
integer.h
Go to the documentation of this file.
1// Copyright 2010-2024 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 <ostream>
26#include <string>
27#include <utility>
28#include <vector>
29
30#include "absl/base/attributes.h"
31#include "absl/container/btree_map.h"
32#include "absl/container/flat_hash_map.h"
33#include "absl/container/inlined_vector.h"
34#include "absl/log/check.h"
35#include "absl/strings/str_cat.h"
36#include "absl/types/span.h"
39#include "ortools/sat/model.h"
41#include "ortools/sat/sat_parameters.pb.h"
43#include "ortools/util/bitset.h"
44#include "ortools/util/rev.h"
49
50namespace operations_research {
51namespace sat {
52
53// Value type of an integer variable. An integer variable is always bounded
54// on both sides, and this type is also used to store the bounds [lb, ub] of the
55// range of each integer variable.
56//
57// Note that both bounds are inclusive, which allows to write many propagation
58// algorithms for just one of the bound and apply it to the negated variables to
59// get the symmetric algorithm for the other bound.
61
62// The max range of an integer variable is [kMinIntegerValue, kMaxIntegerValue].
63//
64// It is symmetric so the set of possible ranges stays the same when we take the
65// negation of a variable. Moreover, we need some IntegerValue that fall outside
66// this range on both side so that we can usually take care of integer overflow
67// by simply doing "saturated arithmetic" and if one of the bound overflow, the
68// two bounds will "cross" each others and we will get an empty range.
69constexpr IntegerValue kMaxIntegerValue(
70 std::numeric_limits<IntegerValue::ValueType>::max() - 1);
71constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value());
72
73inline double ToDouble(IntegerValue value) {
74 const double kInfinity = std::numeric_limits<double>::infinity();
75 if (value >= kMaxIntegerValue) return kInfinity;
76 if (value <= kMinIntegerValue) return -kInfinity;
77 return static_cast<double>(value.value());
78}
79
80template <class IntType>
81inline IntType IntTypeAbs(IntType t) {
82 return IntType(std::abs(t.value()));
83}
84
85inline IntegerValue CeilRatio(IntegerValue dividend,
86 IntegerValue positive_divisor) {
87 DCHECK_GT(positive_divisor, 0);
88 const IntegerValue result = dividend / positive_divisor;
89 const IntegerValue adjust =
90 static_cast<IntegerValue>(result * positive_divisor < dividend);
91 return result + adjust;
92}
93
94inline IntegerValue FloorRatio(IntegerValue dividend,
95 IntegerValue positive_divisor) {
96 DCHECK_GT(positive_divisor, 0);
97 const IntegerValue result = dividend / positive_divisor;
98 const IntegerValue adjust =
99 static_cast<IntegerValue>(result * positive_divisor > dividend);
100 return result - adjust;
101}
102
103// Overflows and saturated arithmetic.
104
105inline IntegerValue CapProdI(IntegerValue a, IntegerValue b) {
106 return IntegerValue(CapProd(a.value(), b.value()));
107}
108
109inline IntegerValue CapSubI(IntegerValue a, IntegerValue b) {
110 return IntegerValue(CapSub(a.value(), b.value()));
111}
112
113inline IntegerValue CapAddI(IntegerValue a, IntegerValue b) {
114 return IntegerValue(CapAdd(a.value(), b.value()));
115}
116
117inline bool ProdOverflow(IntegerValue t, IntegerValue value) {
118 return AtMinOrMaxInt64(CapProd(t.value(), value.value()));
119}
120
121inline bool AtMinOrMaxInt64I(IntegerValue t) {
122 return AtMinOrMaxInt64(t.value());
123}
124
125// Helper for dividing several small integers by the same value. Note that there
126// is no point using this class is the divisor is a compile-time constant, since
127// the compiler should be smart enough to do this automatically.
128// Building a `QuickSmallDivision` object costs an integer division, but each
129// call to `DivideByDivisor` will only do an integer multiplication and a shift.
130//
131// This class always return the exact value of the division for all possible
132// values of `dividend` and `divisor`.
134 public:
135 explicit QuickSmallDivision(uint16_t divisor)
136 : inverse_((1ull << 48) / divisor + 1) {}
137
138 uint16_t DivideByDivisor(uint16_t dividend) const {
139 return static_cast<uint16_t>((inverse_ * static_cast<uint64_t>(dividend)) >>
140 48);
141 }
142
143 private:
144 uint64_t inverse_;
145};
146
147// Returns dividend - FloorRatio(dividend, divisor) * divisor;
148//
149// This function is around the same speed than the computation above, but it
150// never causes integer overflow. Note also that when calling FloorRatio() then
151// PositiveRemainder(), the compiler should optimize the modulo away and just
152// reuse the one from the first integer division.
153inline IntegerValue PositiveRemainder(IntegerValue dividend,
154 IntegerValue positive_divisor) {
155 DCHECK_GT(positive_divisor, 0);
156 const IntegerValue m = dividend % positive_divisor;
157 return m < 0 ? m + positive_divisor : m;
158}
159
160inline bool AddTo(IntegerValue a, IntegerValue* result) {
161 if (AtMinOrMaxInt64I(a)) return false;
162 const IntegerValue add = CapAddI(a, *result);
163 if (AtMinOrMaxInt64I(add)) return false;
164 *result = add;
165 return true;
166}
167
168// Computes result += a * b, and return false iff there is an overflow.
169inline bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue* result) {
170 const IntegerValue prod = CapProdI(a, b);
171 if (AtMinOrMaxInt64I(prod)) return false;
172 const IntegerValue add = CapAddI(prod, *result);
173 if (AtMinOrMaxInt64I(add)) return false;
174 *result = add;
175 return true;
176}
177
178// Index of an IntegerVariable.
179//
180// Each time we create an IntegerVariable we also create its negation. This is
181// done like that so internally we only stores and deal with lower bound. The
182// upper bound being the lower bound of the negated variable.
184const IntegerVariable kNoIntegerVariable(-1);
185inline IntegerVariable NegationOf(IntegerVariable i) {
186 return IntegerVariable(i.value() ^ 1);
187}
188
189inline bool VariableIsPositive(IntegerVariable i) {
190 return (i.value() & 1) == 0;
191}
192
193inline IntegerVariable PositiveVariable(IntegerVariable i) {
194 return IntegerVariable(i.value() & (~1));
195}
196
197// Special type for storing only one thing for var and NegationOf(var).
198DEFINE_STRONG_INDEX_TYPE(PositiveOnlyIndex);
199inline PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var) {
200 return PositiveOnlyIndex(var.value() / 2);
201}
202
203inline std::string IntegerTermDebugString(IntegerVariable var,
204 IntegerValue coeff) {
205 coeff = VariableIsPositive(var) ? coeff : -coeff;
206 return absl::StrCat(coeff.value(), "*X", var.value() / 2);
207}
208
209// Returns the vector of the negated variables.
210std::vector<IntegerVariable> NegationOf(
211 const std::vector<IntegerVariable>& vars);
212
213// The integer equivalent of a literal.
214// It represents an IntegerVariable and an upper/lower bound on it.
215//
216// Overflow: all the bounds below kMinIntegerValue and kMaxIntegerValue are
217// treated as kMinIntegerValue - 1 and kMaxIntegerValue + 1.
219 // Because IntegerLiteral should never be created at a bound less constrained
220 // than an existing IntegerVariable bound, we don't allow GreaterOrEqual() to
221 // have a bound lower than kMinIntegerValue, and LowerOrEqual() to have a
222 // bound greater than kMaxIntegerValue. The other side is not constrained
223 // to allow for a computed bound to overflow. Note that both the full initial
224 // domain and the empty domain can always be represented.
225 static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound);
226 static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound);
227
228 // These two static integer literals represent an always true and an always
229 // false condition.
232
233 // Clients should prefer the static construction methods above.
235 IntegerLiteral(IntegerVariable v, IntegerValue b) : var(v), bound(b) {
236 DCHECK_GE(bound, kMinIntegerValue);
237 DCHECK_LE(bound, kMaxIntegerValue + 1);
238 }
239
240 bool IsValid() const { return var != kNoIntegerVariable; }
241 bool IsAlwaysTrue() const { return var == kNoIntegerVariable && bound <= 0; }
242 bool IsAlwaysFalse() const { return var == kNoIntegerVariable && bound > 0; }
243
244 // The negation of x >= bound is x <= bound - 1.
245 IntegerLiteral Negated() const;
246
248 return var == o.var && bound == o.bound;
249 }
251 return var != o.var || bound != o.bound;
252 }
253
254 std::string DebugString() const {
255 return VariableIsPositive(var)
256 ? absl::StrCat("I", var.value() / 2, ">=", bound.value())
257 : absl::StrCat("I", var.value() / 2, "<=", -bound.value());
258 }
259
260 // Note that bound should be in [kMinIntegerValue, kMaxIntegerValue + 1].
261 IntegerVariable var = kNoIntegerVariable;
262 IntegerValue bound = IntegerValue(0);
263};
264
265inline std::ostream& operator<<(std::ostream& os, IntegerLiteral i_lit) {
266 os << i_lit.DebugString();
267 return os;
268}
269
270inline std::ostream& operator<<(std::ostream& os,
271 absl::Span<const IntegerLiteral> literals) {
272 os << "[";
273 bool first = true;
274 for (const IntegerLiteral literal : literals) {
275 if (first) {
276 first = false;
277 } else {
278 os << ",";
279 }
280 os << literal.DebugString();
281 }
282 os << "]";
283 return os;
284}
285
286using InlinedIntegerLiteralVector = absl::InlinedVector<IntegerLiteral, 2>;
288 absl::InlinedVector<std::pair<IntegerVariable, IntegerValue>, 2>;
289
290// Represents [coeff * variable + constant] or just a [constant].
291//
292// In some places it is useful to manipulate such expression instead of having
293// to create an extra integer variable. This is mainly used for scheduling
294// related constraints.
296 // Helper to construct an AffineExpression.
297 AffineExpression() = default;
298 AffineExpression(IntegerValue cst) // NOLINT(runtime/explicit)
299 : constant(cst) {}
300 AffineExpression(IntegerVariable v) // NOLINT(runtime/explicit)
301 : var(v), coeff(1) {}
302 AffineExpression(IntegerVariable v, IntegerValue c)
303 : var(c >= 0 ? v : NegationOf(v)), coeff(IntTypeAbs(c)) {}
304 AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
305 : var(c >= 0 ? v : NegationOf(v)), coeff(IntTypeAbs(c)), constant(cst) {}
306
307 // Returns the integer literal corresponding to expression >= value or
308 // expression <= value.
309 //
310 // On constant expressions, they will return IntegerLiteral::TrueLiteral()
311 // or IntegerLiteral::FalseLiteral().
312 IntegerLiteral GreaterOrEqual(IntegerValue bound) const;
313 IntegerLiteral LowerOrEqual(IntegerValue bound) const;
314
319
320 AffineExpression MultipliedBy(IntegerValue multiplier) const {
321 // Note that this also works if multiplier is negative.
322 return AffineExpression(var, coeff * multiplier, constant * multiplier);
323 }
324
326 return var == o.var && coeff == o.coeff && constant == o.constant;
327 }
328
329 // Returns the value of this affine expression given its variable value.
330 IntegerValue ValueAt(IntegerValue var_value) const {
331 return coeff * var_value + constant;
332 }
333
334 // Returns the affine expression value under a given LP solution.
336 lp_values) const {
337 if (var == kNoIntegerVariable) return ToDouble(constant);
338 return ToDouble(coeff) * lp_values[var] + ToDouble(constant);
339 }
340
341 bool IsConstant() const { return var == kNoIntegerVariable; }
342
343 std::string DebugString() const {
344 if (var == kNoIntegerVariable) return absl::StrCat(constant.value());
345 if (constant == 0) {
346 return absl::StrCat("(", coeff.value(), " * X", var.value(), ")");
347 } else {
348 return absl::StrCat("(", coeff.value(), " * X", var.value(), " + ",
349 constant.value(), ")");
350 }
351 }
352
353 // The coefficient MUST be positive. Use NegationOf(var) if needed.
354 //
355 // TODO(user): Make this private to enforce the invariant that coeff cannot be
356 // negative.
357 IntegerVariable var = kNoIntegerVariable; // kNoIntegerVariable for constant.
358 IntegerValue coeff = IntegerValue(0); // Zero for constant.
359 IntegerValue constant = IntegerValue(0);
360};
361
362template <typename H>
364 if (e.var != kNoIntegerVariable) {
365 h = H::combine(std::move(h), e.var);
366 h = H::combine(std::move(h), e.coeff);
367 }
368 h = H::combine(std::move(h), e.constant);
369
370 return h;
371}
372
373// A model singleton that holds the root level integer variable domains.
374// we just store a single domain for both var and its negation.
376 : public util_intops::StrongVector<PositiveOnlyIndex, Domain> {};
377
378// A model singleton used for debugging. If this is set in the model, then we
379// can check that various derived constraint do not exclude this solution (if it
380// is a known optimal solution for instance).
382 // This is the value of all proto variables.
383 // It should be of the same size of the PRESOLVED model and should correspond
384 // to a solution to the presolved model.
385 std::vector<int64_t> proto_values;
386
387 // This is filled from proto_values at load-time, and using the
388 // cp_model_mapping, we cache the solution of the integer variables that are
389 // mapped. Note that it is possible that not all integer variable are mapped.
390 //
391 // TODO(user): When this happen we should be able to infer the value of these
392 // derived variable in the solution. For now, we only do that for the
393 // objective variable.
396};
397
398// A value and a literal.
402 const ValueLiteralPair& b) const {
403 return a.literal < b.literal;
404 }
405 };
408 const ValueLiteralPair& b) const {
409 return (a.value < b.value) ||
410 (a.value == b.value && a.literal < b.literal);
411 }
412 };
413
414 bool operator==(const ValueLiteralPair& o) const {
415 return value == o.value && literal == o.literal;
416 }
417
418 std::string DebugString() const;
419
420 IntegerValue value = IntegerValue(0);
422};
423
424std::ostream& operator<<(std::ostream& os, const ValueLiteralPair& p);
425
428 IntegerValue left_value;
429 IntegerValue right_value;
430
431 // Used for testing.
432 bool operator==(const LiteralValueValue& rhs) const {
433 return literal.Index() == rhs.literal.Index() &&
435 }
436
437 std::string DebugString() const {
438 return absl::StrCat("(lit(", literal.Index().value(), ") * ",
439 left_value.value(), " * ", right_value.value(), ")");
440 }
441};
442
443// Sometimes we propagate fact with no reason at a positive level, those
444// will automatically be fixed on the next restart.
445//
446// TODO(user): If we change the logic to not restart right away, we probably
447// need to remove duplicates bounds for the same variable.
449 std::vector<Literal> literal_to_fix;
450 std::vector<IntegerLiteral> integer_literal_to_fix;
451};
452
453// Each integer variable x will be associated with a set of literals encoding
454// (x >= v) for some values of v. This class maintains the relationship between
455// the integer variables and such literals which can be created by a call to
456// CreateAssociatedLiteral().
457//
458// The advantage of creating such Boolean variables is that the SatSolver which
459// is driving the search can then take this variable as a decision and maintain
460// these variables activity and so on. These variables can also be propagated
461// directly by the learned clauses.
462//
463// This class also support a non-lazy full domain encoding which will create one
464// literal per possible value in the domain. See FullyEncodeVariable(). This is
465// meant to be called by constraints that directly work on the variable values
466// like a table constraint or an all-diff constraint.
467//
468// TODO(user): We could also lazily create precedences Booleans between two
469// arbitrary IntegerVariable. This is better done in the PrecedencesPropagator
470// though.
472 public:
474 : sat_solver_(model->GetOrCreate<SatSolver>()),
475 trail_(model->GetOrCreate<Trail>()),
476 delayed_to_fix_(model->GetOrCreate<DelayedRootLevelDeduction>()),
477 domains_(*model->GetOrCreate<IntegerDomains>()),
478 num_created_variables_(0) {}
479
480 // This type is neither copyable nor movable.
483
485 VLOG(1) << "#variables created = " << num_created_variables_;
486 }
487
488 // Memory optimization: you can call this before encoding variables.
489 void ReserveSpaceForNumVariables(int num_vars);
490
491 // Fully encode a variable using its current initial domain.
492 // If the variable is already fully encoded, this does nothing.
493 //
494 // This creates new Booleans variables as needed:
495 // 1) num_values for the literals X == value. Except when there is just
496 // two value in which case only one variable is created.
497 // 2) num_values - 3 for the literals X >= value or X <= value (using their
498 // negation). The -3 comes from the fact that we can reuse the equality
499 // literals for the two extreme points.
500 //
501 // The encoding for NegationOf(var) is automatically created too. It reuses
502 // the same Boolean variable as the encoding of var.
503 //
504 // TODO(user): It is currently only possible to call that at the decision
505 // level zero because we cannot add ternary clause in the middle of the
506 // search (for now). This is Checked.
507 void FullyEncodeVariable(IntegerVariable var);
508
509 // Returns true if we know that PartialDomainEncoding(var) span the full
510 // domain of var. This is always true if FullyEncodeVariable(var) has been
511 // called.
512 bool VariableIsFullyEncoded(IntegerVariable var) const;
513
514 // Returns the list of literal <=> var == value currently associated to the
515 // given variable. The result is sorted by value. We filter literal at false,
516 // and if a literal is true, then you will get a singleton. To be sure to get
517 // the full set of encoded value, then you should call this at level zero.
518 //
519 // The FullDomainEncoding() just check VariableIsFullyEncoded() and returns
520 // the same result.
521 //
522 // WARNING: The reference returned is only valid until the next call to one
523 // of these functions.
524 const std::vector<ValueLiteralPair>& FullDomainEncoding(
525 IntegerVariable var) const;
526 const std::vector<ValueLiteralPair>& PartialDomainEncoding(
527 IntegerVariable var) const;
528
529 // Returns the "canonical" (i_lit, negation of i_lit) pair. This mainly
530 // deal with domain with initial hole like [1,2][5,6] so that if one ask
531 // for x <= 3, this get canonicalized in the pair (x <= 2, x >= 5).
532 //
533 // Note that it is an error to call this with a literal that is trivially true
534 // or trivially false according to the initial variable domain. This is
535 // CHECKed to make sure we don't create wasteful literal.
536 //
537 // TODO(user): This is linear in the domain "complexity", we can do better if
538 // needed.
539 std::pair<IntegerLiteral, IntegerLiteral> Canonicalize(
540 IntegerLiteral i_lit) const;
541
542 // Returns, after creating it if needed, a Boolean literal such that:
543 // - if true, then the IntegerLiteral is true.
544 // - if false, then the negated IntegerLiteral is true.
545 //
546 // Note that this "canonicalize" the given literal first.
547 //
548 // This add the proper implications with the two "neighbor" literals of this
549 // one if they exist. This is the "list encoding" in: Thibaut Feydy, Peter J.
550 // Stuckey, "Lazy Clause Generation Reengineered", CP 2009.
553 IntegerValue value);
554
555 // Associates the Boolean literal to (X >= bound) or (X == value). If a
556 // literal was already associated to this fact, this will add an equality
557 // constraints between both literals. If the fact is trivially true or false,
558 // this will fix the given literal.
560 void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var,
561 IntegerValue value);
562
563 // Returns kNoLiteralIndex if there is no associated or the associated literal
564 // otherwise.
565 //
566 // Tricky: for domain with hole, like [0,1][5,6], we assume some equivalence
567 // classes, like >=2, >=3, >=4 are all the same as >= 5.
569 LiteralIndex GetAssociatedLiteral(IntegerLiteral i_lit) const;
570 LiteralIndex GetAssociatedEqualityLiteral(IntegerVariable var,
571 IntegerValue value) const;
572
573 // Advanced usage. It is more efficient to create the associated literals in
574 // order, but it might be anoying to do so. Instead, you can first call
575 // DisableImplicationBetweenLiteral() and when you are done creating all the
576 // associated literals, you can call (only at level zero)
577 // AddAllImplicationsBetweenAssociatedLiterals() which will also turn back on
578 // the implications between literals for the one that will be added
579 // afterwards.
580 void DisableImplicationBetweenLiteral() { add_implications_ = false; }
582
583 // Returns the IntegerLiterals that were associated with the given Literal.
585 if (lit.Index() >= reverse_encoding_.size()) {
586 return empty_integer_literal_vector_;
587 }
588 return reverse_encoding_[lit];
589 }
590
591 // Returns the variable == value pairs that were associated with the given
592 // Literal. Note that only positive IntegerVariable appears here.
594 if (lit.Index() >= reverse_equality_encoding_.size()) {
595 return empty_integer_value_vector_;
596 }
597 return reverse_equality_encoding_[lit];
598 }
599
600 // Returns all the variables for which this literal is associated to either
601 // var >= value or var == value.
602 const std::vector<IntegerVariable>& GetAllAssociatedVariables(
603 Literal lit) const {
604 temp_associated_vars_.clear();
605 for (const IntegerLiteral l : GetIntegerLiterals(lit)) {
606 temp_associated_vars_.push_back(l.var);
607 }
608 for (const auto& [var, value] : GetEqualityLiterals(lit)) {
609 temp_associated_vars_.push_back(var);
610 }
611 return temp_associated_vars_;
612 }
613
614 // If it exists, returns a [0,1] integer variable which is equal to 1 iff the
615 // given literal is true. Returns kNoIntegerVariable if such variable does not
616 // exist. Note that one can create one by creating a new IntegerVariable and
617 // calling AssociateToIntegerEqualValue().
618 IntegerVariable GetLiteralView(Literal lit) const {
619 if (lit.Index() >= literal_view_.size()) return kNoIntegerVariable;
620 return literal_view_[lit];
621 }
622
623 // If this is true, then a literal can be linearized with an affine expression
624 // involving an integer variable.
625 ABSL_MUST_USE_RESULT bool LiteralOrNegationHasView(
626 Literal lit, IntegerVariable* view = nullptr,
627 bool* view_is_direct = nullptr) const;
628
629 // Returns a Boolean literal associated with a bound lower than or equal to
630 // the one of the given IntegerLiteral. If the given IntegerLiteral is true,
631 // then the returned literal should be true too. Returns kNoLiteralIndex if no
632 // such literal was created.
633 //
634 // Ex: if 'i' is (x >= 4) and we already created a literal associated to
635 // (x >= 2) but not to (x >= 3), we will return the literal associated with
636 // (x >= 2).
638 IntegerValue* bound) const;
639
640 // Gets the literal always set to true, make it if it does not exist.
642 if (literal_index_true_ == kNoLiteralIndex) {
643 DCHECK_EQ(0, sat_solver_->CurrentDecisionLevel());
644 const Literal literal_true =
645 Literal(sat_solver_->NewBooleanVariable(), true);
646 literal_index_true_ = literal_true.Index();
647
648 // This might return false if we are already UNSAT.
649 // TODO(user): Make sure we abort right away on unsat!
650 (void)sat_solver_->AddUnitClause(literal_true);
651 }
652 return Literal(literal_index_true_);
653 }
655
656 // Returns the set of Literal associated to IntegerLiteral of the form var >=
657 // value. We make a copy, because this can be easily invalidated when calling
658 // any function of this class. So it is less efficient but safer.
659 std::vector<ValueLiteralPair> PartialGreaterThanEncoding(
660 IntegerVariable var) const;
661
662 // Makes sure all element in the >= encoding are non-trivial and canonical.
663 // The input variable must be positive.
664 bool UpdateEncodingOnInitialDomainChange(IntegerVariable var, Domain domain);
665
666 private:
667 // Adds the implications:
668 // Literal(before) <= associated_lit <= Literal(after).
669 // Arguments:
670 // - map is just encoding_by_var_[associated_lit.var] and is passed as a
671 // slight optimization.
672 // - 'it' is the current position of associated_lit in map, i.e. we must have
673 // it->second == associated_lit.
674 void AddImplications(
675 const absl::btree_map<IntegerValue, Literal>& map,
676 absl::btree_map<IntegerValue, Literal>::const_iterator it,
677 Literal associated_lit);
678
679 SatSolver* sat_solver_;
680 Trail* trail_;
681 DelayedRootLevelDeduction* delayed_to_fix_;
682 const IntegerDomains& domains_;
683
684 bool add_implications_ = true;
685 int64_t num_created_variables_ = 0;
686
687 // We keep all the literals associated to an Integer variable in a map ordered
688 // by bound (so we can properly add implications between the literals
689 // corresponding to the same variable).
690 //
691 // Note that we only keep this for positive variable.
692 // The one for the negation can be infered by it.
693 //
694 // Like x >= 1 x >= 4 x >= 5
695 // Correspond to x <= 0 x <= 3 x <= 4
696 // That is -x >= 0 -x >= -2 -x >= -4
697 //
698 // With potentially stronger <= bound if we fall into domain holes.
699 //
700 // TODO(user): Remove the entry no longer needed because of level zero
701 // propagations.
702 util_intops::StrongVector<PositiveOnlyIndex,
703 absl::btree_map<IntegerValue, Literal>>
704 encoding_by_var_;
705
706 // Store for a given LiteralIndex the list of its associated IntegerLiterals.
707 const InlinedIntegerLiteralVector empty_integer_literal_vector_;
709 reverse_encoding_;
710 const InlinedIntegerValueVector empty_integer_value_vector_;
712 reverse_equality_encoding_;
713
714 // Used by GetAllAssociatedVariables().
715 mutable std::vector<IntegerVariable> temp_associated_vars_;
716
717 // Store for a given LiteralIndex its IntegerVariable view or kNoLiteralIndex
718 // if there is none.
720
721 // Mapping (variable == value) -> associated literal. Note that even if
722 // there is more than one literal associated to the same fact, we just keep
723 // the first one that was added.
724 //
725 // Note that we only keep positive IntegerVariable here to reduce memory
726 // usage.
727 absl::flat_hash_map<std::pair<PositiveOnlyIndex, IntegerValue>, Literal>
728 equality_to_associated_literal_;
729
730 // Mutable because this is lazily cleaned-up by PartialDomainEncoding().
731 mutable util_intops::StrongVector<PositiveOnlyIndex,
732 absl::InlinedVector<ValueLiteralPair, 2>>
733 equality_by_var_;
734
735 // Variables that are fully encoded.
737
738 // A literal that is always true, convenient to encode trivial domains.
739 // This will be lazily created when needed.
740 LiteralIndex literal_index_true_ = kNoLiteralIndex;
741
742 // Temporary memory used by FullyEncodeVariable().
743 std::vector<IntegerValue> tmp_values_;
744 std::vector<ValueLiteralPair> tmp_encoding_;
745
746 // Temporary memory for the result of PartialDomainEncoding().
747 mutable std::vector<ValueLiteralPair> partial_encoding_;
748};
749
751 public:
753 virtual ~LazyReasonInterface() = default;
754
755 // When called, this must fill the two vectors so that literals contains any
756 // Literal part of the reason and dependencies contains the trail index of any
757 // IntegerLiteral that is also part of the reason.
758 //
759 // Remark: integer_literal[trail_index] might not exist or has nothing to
760 // do with what was propagated.
761 //
762 // TODO(user): {id, propagation_slack, var_to_explain, trail_index} is just a
763 // generic "payload" and we should probably rename it as such so that each
764 // implementation can store different things.
765 virtual void Explain(int id, IntegerValue propagation_slack,
766 IntegerVariable var_to_explain, int trail_index,
767 std::vector<Literal>* literals_reason,
768 std::vector<int>* trail_indices_reason) = 0;
769};
770
771// This class maintains a set of integer variables with their current bounds.
772// Bounds can be propagated from an external "source" and this class helps
773// to maintain the reason for each propagation.
774class IntegerTrail final : public SatPropagator {
775 public:
777 : SatPropagator("IntegerTrail"),
778 delayed_to_fix_(model->GetOrCreate<DelayedRootLevelDeduction>()),
779 domains_(model->GetOrCreate<IntegerDomains>()),
780 encoder_(model->GetOrCreate<IntegerEncoder>()),
781 trail_(model->GetOrCreate<Trail>()),
782 sat_solver_(model->GetOrCreate<SatSolver>()),
783 time_limit_(model->GetOrCreate<TimeLimit>()),
784 parameters_(*model->GetOrCreate<SatParameters>()) {
785 model->GetOrCreate<SatSolver>()->AddPropagator(this);
786 }
787
788 // This type is neither copyable nor movable.
789 IntegerTrail(const IntegerTrail&) = delete;
791 ~IntegerTrail() final;
792
793 // SatPropagator interface. These functions make sure the current bounds
794 // information is in sync with the current solver literal trail. Any
795 // class/propagator using this class must make sure it is synced to the
796 // correct state before calling any of its functions.
797 bool Propagate(Trail* trail) final;
798 void Untrail(const Trail& trail, int literal_trail_index) final;
799 absl::Span<const Literal> Reason(const Trail& trail, int trail_index,
800 int64_t conflict_id) const final;
801
802 // Returns the number of created integer variables.
803 //
804 // Note that this is twice the number of call to AddIntegerVariable() since
805 // we automatically create the NegationOf() variable too.
806 IntegerVariable NumIntegerVariables() const {
807 return IntegerVariable(var_lbs_.size());
808 }
809
810 // Optimization: you can call this before calling AddIntegerVariable()
811 // num_vars time.
812 void ReserveSpaceForNumVariables(int num_vars);
813
814 // Adds a new integer variable. Adding integer variable can only be done when
815 // the decision level is zero (checked). The given bounds are INCLUSIVE and
816 // must not cross.
817 //
818 // Note on integer overflow: 'upper_bound - lower_bound' must fit on an
819 // int64_t, this is DCHECKed. More generally, depending on the constraints
820 // that are added, the bounds magnitude must be small enough to satisfy each
821 // constraint overflow precondition.
822 IntegerVariable AddIntegerVariable(IntegerValue lower_bound,
823 IntegerValue upper_bound);
824
825 // Same as above but for a more complex domain specified as a sorted list of
826 // disjoint intervals. See the Domain class.
827 IntegerVariable AddIntegerVariable(const Domain& domain);
828
829 // Returns the initial domain of the given variable. Note that the min/max
830 // are updated with level zero propagation, but not holes.
831 const Domain& InitialVariableDomain(IntegerVariable var) const;
832
833 // Takes the intersection with the current initial variable domain.
834 //
835 // TODO(user): There is some memory inefficiency if this is called many time
836 // because of the underlying data structure we use. In practice, when used
837 // with a presolve, this is not often used, so that is fine though.
838 bool UpdateInitialDomain(IntegerVariable var, Domain domain);
839
840 // Same as AddIntegerVariable(value, value), but this is a bit more efficient
841 // because it reuses another constant with the same value if its exist.
842 //
843 // Note(user): Creating constant integer variable is a bit wasteful, but not
844 // that much, and it allows to simplify a lot of constraints that do not need
845 // to handle this case any differently than the general one. Maybe there is a
846 // better solution, but this is not really high priority as of December 2016.
847 IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value);
848 int NumConstantVariables() const;
849
850 // Same as AddIntegerVariable() but uses the maximum possible range. Note
851 // that since we take negation of bounds in various places, we make sure that
852 // we don't have overflow when we take the negation of the lower bound or of
853 // the upper bound.
857
858 // Returns the current lower/upper bound of the given integer variable.
859 IntegerValue LowerBound(IntegerVariable i) const;
860 IntegerValue UpperBound(IntegerVariable i) const;
861
862 // If one needs to do a lot of LowerBound()/UpperBound() it will be faster
863 // to cache the current pointer to the underlying vector.
864 const IntegerValue* LowerBoundsData() const { return var_lbs_.data(); }
865
866 // Checks if the variable is fixed.
867 bool IsFixed(IntegerVariable i) const;
868
869 // Checks that the variable is fixed and returns its value.
870 IntegerValue FixedValue(IntegerVariable i) const;
871
872 // Same as above for an affine expression.
873 IntegerValue LowerBound(AffineExpression expr) const;
874 IntegerValue UpperBound(AffineExpression expr) const;
875 bool IsFixed(AffineExpression expr) const;
876 IntegerValue FixedValue(AffineExpression expr) const;
877
878 // Returns the integer literal that represent the current lower/upper bound of
879 // the given integer variable.
880 IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const;
881 IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const;
882
883 // Returns the integer literal that represent the current lower/upper bound of
884 // the given affine expression. In case the expression is constant, it returns
885 // IntegerLiteral::TrueLiteral().
888
889 // Returns the current value (if known) of an IntegerLiteral.
892
893 // Returns globally valid lower/upper bound on the given integer variable.
894 IntegerValue LevelZeroLowerBound(IntegerVariable var) const;
895 IntegerValue LevelZeroUpperBound(IntegerVariable var) const;
896
897 // Returns globally valid lower/upper bound on the given affine expression.
898 IntegerValue LevelZeroLowerBound(AffineExpression exp) const;
899 IntegerValue LevelZeroUpperBound(AffineExpression exp) const;
900
901 // Returns true if the variable is fixed at level 0.
902 bool IsFixedAtLevelZero(IntegerVariable var) const;
903
904 // Returns true if the affine expression is fixed at level 0.
905 bool IsFixedAtLevelZero(AffineExpression expr) const;
906
907 // Advanced usage.
908 // Returns the current lower bound assuming the literal is true.
909 IntegerValue ConditionalLowerBound(Literal l, IntegerVariable i) const;
910 IntegerValue ConditionalLowerBound(Literal l, AffineExpression expr) const;
911
912 // Returns the current upper bound assuming the literal is true.
913 IntegerValue ConditionalUpperBound(Literal l, IntegerVariable i) const;
914 IntegerValue ConditionalUpperBound(Literal l, AffineExpression expr) const;
915
916 // Advanced usage. Given the reason for
917 // (Sum_i coeffs[i] * reason[i].var >= current_lb) initially in reason,
918 // this function relaxes the reason given that we only need the explanation of
919 // (Sum_i coeffs[i] * reason[i].var >= current_lb - slack).
920 //
921 // Preconditions:
922 // - coeffs must be of same size as reason, and all entry must be positive.
923 // - *reason must initially contains the trivial initial reason, that is
924 // the current lower-bound of each variables.
925 //
926 // TODO(user): Requiring all initial literal to be at their current bound is
927 // not really clean. Maybe we can change the API to only take IntegerVariable
928 // and produce the reason directly.
929 //
930 // TODO(user): change API so that this work is performed during the conflict
931 // analysis where we can be smarter in how we relax the reason. Note however
932 // that this function is mainly used when we have a conflict, so this is not
933 // really high priority.
934 //
935 // TODO(user): Test that the code work in the presence of integer overflow.
936 void RelaxLinearReason(IntegerValue slack,
937 absl::Span<const IntegerValue> coeffs,
938 std::vector<IntegerLiteral>* reason) const;
939
940 // Same as above but take in IntegerVariables instead of IntegerLiterals.
941 void AppendRelaxedLinearReason(IntegerValue slack,
942 absl::Span<const IntegerValue> coeffs,
943 absl::Span<const IntegerVariable> vars,
944 std::vector<IntegerLiteral>* reason) const;
945
946 // Same as above but relax the given trail indices.
947 void RelaxLinearReason(IntegerValue slack,
948 absl::Span<const IntegerValue> coeffs,
949 std::vector<int>* trail_indices) const;
950
951 // Removes from the reasons the literal that are always true.
952 // This is mainly useful for experiments/testing.
953 void RemoveLevelZeroBounds(std::vector<IntegerLiteral>* reason) const;
954
955 // Enqueue new information about a variable bound. Calling this with a less
956 // restrictive bound than the current one will have no effect.
957 //
958 // The reason for this "assignment" must be provided as:
959 // - A set of Literal currently being all false.
960 // - A set of IntegerLiteral currently being all true.
961 //
962 // IMPORTANT: Notice the inversed sign in the literal reason. This is a bit
963 // confusing but internally SAT use this direction for efficiency.
964 //
965 // Note(user): Duplicates Literal/IntegerLiteral are supported because we call
966 // STLSortAndRemoveDuplicates() in MergeReasonInto(), but maybe they shouldn't
967 // for efficiency reason.
968 //
969 // TODO(user): If the given bound is equal to the current bound, maybe the new
970 // reason is better? how to decide and what to do in this case? to think about
971 // it. Currently we simply don't do anything.
972 ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit) {
973 return EnqueueInternal(i_lit, false, {}, {}, integer_trail_.size());
974 }
975 ABSL_MUST_USE_RESULT bool Enqueue(
976 IntegerLiteral i_lit, absl::Span<const Literal> literal_reason,
977 absl::Span<const IntegerLiteral> integer_reason) {
978 return EnqueueInternal(i_lit, false, literal_reason, integer_reason,
979 integer_trail_.size());
980 }
981
982 // Enqueue new information about a variable bound. It has the same behavior
983 // as the Enqueue() method, except that it accepts true and false integer
984 // literals, both for i_lit, and for the integer reason.
985 //
986 // This method will do nothing if i_lit is a true literal. It will report a
987 // conflict if i_lit is a false literal, and enqueue i_lit normally otherwise.
988 // Furthemore, it will check that the integer reason does not contain any
989 // false literals, and will remove true literals before calling
990 // ReportConflict() or Enqueue().
991 ABSL_MUST_USE_RESULT bool SafeEnqueue(
992 IntegerLiteral i_lit, absl::Span<const IntegerLiteral> integer_reason);
993
994 // Pushes the given integer literal assuming that the Boolean literal is true.
995 // This can do a few things:
996 // - If lit it true, add it to the reason and push the integer bound.
997 // - If the bound is infeasible, push lit to false.
998 // - If the underlying variable is optional and also controlled by lit, push
999 // the bound even if lit is not assigned.
1000 ABSL_MUST_USE_RESULT bool ConditionalEnqueue(
1001 Literal lit, IntegerLiteral i_lit, std::vector<Literal>* literal_reason,
1002 std::vector<IntegerLiteral>* integer_reason);
1003
1004 // Same as Enqueue(), but takes an extra argument which if smaller than
1005 // integer_trail_.size() is interpreted as the trail index of an old Enqueue()
1006 // that had the same reason as this one. Note that the given Span must still
1007 // be valid as they are used in case of conflict.
1008 //
1009 // TODO(user): This currently cannot refer to a trail_index with a lazy
1010 // reason. Fix or at least check that this is the case.
1011 ABSL_MUST_USE_RESULT bool Enqueue(
1012 IntegerLiteral i_lit, absl::Span<const Literal> literal_reason,
1013 absl::Span<const IntegerLiteral> integer_reason,
1014 int trail_index_with_same_reason) {
1015 return EnqueueInternal(i_lit, false, literal_reason, integer_reason,
1016 trail_index_with_same_reason);
1017 }
1018
1019 // Lazy reason API.
1020 ABSL_MUST_USE_RESULT bool EnqueueWithLazyReason(
1021 IntegerLiteral i_lit, int id, IntegerValue propagation_slack,
1022 LazyReasonInterface* explainer) {
1023 const int trail_index = integer_trail_.size();
1024 lazy_reasons_.push_back(LazyReasonEntry{explainer, propagation_slack,
1025 i_lit.var, id, trail_index});
1026 return EnqueueInternal(i_lit, true, {}, {}, 0);
1027 }
1028
1029 // Sometimes we infer some root level bounds but we are not at the root level.
1030 // In this case, we will update the level-zero bounds right away, but will
1031 // delay the current push until the next restart.
1032 //
1033 // Note that if you want to also push the literal at the current level, then
1034 // just calling Enqueue() is enough. Since there is no reason, the literal
1035 // will still be recorded properly.
1036 ABSL_MUST_USE_RESULT bool RootLevelEnqueue(IntegerLiteral i_lit);
1037
1038 // Enqueues the given literal on the trail.
1039 // See the comment of Enqueue() for the reason format.
1040 void EnqueueLiteral(Literal literal, absl::Span<const Literal> literal_reason,
1041 absl::Span<const IntegerLiteral> integer_reason);
1042
1043 // Returns the reason (as set of Literal currently false) for a given integer
1044 // literal. Note that the bound must be less restrictive than the current
1045 // bound (checked).
1046 std::vector<Literal> ReasonFor(IntegerLiteral literal) const;
1047
1048 // Appends the reason for the given integer literals to the output and call
1049 // STLSortAndRemoveDuplicates() on it. This function accept "constant"
1050 // literal.
1051 void MergeReasonInto(absl::Span<const IntegerLiteral> literals,
1052 std::vector<Literal>* output) const;
1053
1054 // Returns the number of enqueues that changed a variable bounds. We don't
1055 // count enqueues called with a less restrictive bound than the current one.
1056 //
1057 // Note(user): this can be used to see if any of the bounds changed. Just
1058 // looking at the integer trail index is not enough because at level zero it
1059 // doesn't change since we directly update the "fixed" bounds.
1060 int64_t num_enqueues() const { return num_enqueues_; }
1061 int64_t timestamp() const { return num_enqueues_ + num_untrails_; }
1062
1063 // Same as num_enqueues but only count the level zero changes.
1064 int64_t num_level_zero_enqueues() const { return num_level_zero_enqueues_; }
1065
1066 // All the registered bitsets will be set to one each time a LbVar is
1067 // modified. It is up to the client to clear it if it wants to be notified
1068 // with the newly modified variables.
1071 watchers_.push_back(p);
1072 }
1073
1074 // Helper functions to report a conflict. Always return false so a client can
1075 // simply do: return integer_trail_->ReportConflict(...);
1076 bool ReportConflict(absl::Span<const Literal> literal_reason,
1077 absl::Span<const IntegerLiteral> integer_reason) {
1078 DCHECK(ReasonIsValid(literal_reason, integer_reason));
1079 std::vector<Literal>* conflict = trail_->MutableConflict();
1080 conflict->assign(literal_reason.begin(), literal_reason.end());
1081 MergeReasonInto(integer_reason, conflict);
1082 return false;
1083 }
1084 bool ReportConflict(absl::Span<const IntegerLiteral> integer_reason) {
1085 DCHECK(ReasonIsValid({}, integer_reason));
1086 std::vector<Literal>* conflict = trail_->MutableConflict();
1087 conflict->clear();
1088 MergeReasonInto(integer_reason, conflict);
1089 return false;
1090 }
1091
1092 // Returns true if the variable lower bound is still the one from level zero.
1093 bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const {
1094 return var_trail_index_[var] < var_lbs_.size();
1095 }
1096
1097 // Registers a reversible class. This class will always be synced with the
1098 // correct decision level.
1100 reversible_classes_.push_back(rev);
1101 }
1102
1103 int Index() const { return integer_trail_.size(); }
1104
1105 // Inspects the trail and output all the non-level zero bounds (one per
1106 // variables) to the output. The algo is sparse if there is only a few
1107 // propagations on the trail.
1108 void AppendNewBounds(std::vector<IntegerLiteral>* output) const;
1109
1110 // Inspects the trail and output all the non-level zero bounds from the base
1111 // index (one per variables) to the output. The algo is sparse if there is
1112 // only a few propagations on the trail.
1113 void AppendNewBoundsFrom(int base_index,
1114 std::vector<IntegerLiteral>* output) const;
1115
1116 // Returns the trail index < threshold of a TrailEntry about var. Returns -1
1117 // if there is no such entry (at a positive decision level). This is basically
1118 // the trail index of the lower bound of var at the time.
1119 //
1120 // Important: We do some optimization internally, so this should only be
1121 // used from within a LazyReasonFunction().
1122 int FindTrailIndexOfVarBefore(IntegerVariable var, int threshold) const;
1123
1124 // Basic heuristic to detect when we are in a propagation loop, and suggest
1125 // a good variable to branch on (taking the middle value) to get out of it.
1126 bool InPropagationLoop() const;
1128 IntegerVariable NextVariableToBranchOnInPropagationLoop() const;
1129
1130 // If we had an incomplete propagation, it is important to fix all the
1131 // variables and not really on the propagation to do so. This is related to
1132 // the InPropagationLoop() code above.
1134 IntegerVariable FirstUnassignedVariable() const;
1135
1136 // Return true if we can fix new fact at level zero.
1138 return !delayed_to_fix_->literal_to_fix.empty() ||
1139 !delayed_to_fix_->integer_literal_to_fix.empty();
1140 }
1141
1142 // If this is set, and in debug mode, we will call this on all conflict to
1143 // be checked for potential issue. Usually against a known optimal solution.
1145 std::function<bool(absl::Span<const Literal> clause,
1146 absl::Span<const IntegerLiteral> integers)>
1147 checker) {
1148 debug_checker_ = std::move(checker);
1149 }
1150
1151 // This is used by the GreaterThanAtLeastOneOf() lazy reason.
1152 //
1153 // TODO(user): This might better lives together with the propagation code,
1154 // but it does need access to data about the reason/conflict being currently
1155 // computed. Also for speed we do need all the code here in on block. Given
1156 // than we have just a few "lazy integer reason", we might not really want a
1157 // generic code in any case.
1158 void AddAllGreaterThanConstantReason(absl::Span<AffineExpression> exprs,
1159 IntegerValue target_min,
1160 std::vector<int>* indices) const {
1161 for (const AffineExpression& expr : exprs) {
1162 if (expr.IsConstant()) {
1163 DCHECK_GE(expr.constant, target_min);
1164 continue;
1165 }
1166 DCHECK_NE(expr.var, kNoIntegerVariable);
1167
1168 // Skip if we already have an explanation for expr >= target_min. Note
1169 // that we already do that while processing the returned indices, so this
1170 // mainly save a FindLowestTrailIndexThatExplainBound() call per skipped
1171 // indices, which can still be costly.
1172 {
1173 const int index = tmp_var_to_trail_index_in_queue_[expr.var];
1174 if (index == std::numeric_limits<int>::max()) continue;
1175 if (index > 0 &&
1176 expr.ValueAt(integer_trail_[index].bound) >= target_min) {
1177 has_dependency_ = true;
1178 continue;
1179 }
1180 }
1181
1182 // We need to find the index that explain the bound.
1183 // Note that this will skip if the condition is true at level zero.
1184 const int index =
1185 FindLowestTrailIndexThatExplainBound(expr.GreaterOrEqual(target_min));
1186 if (index >= 0) {
1187 indices->push_back(index);
1188 }
1189 }
1190 }
1191
1192 private:
1193 // Used for DHECKs to validate the reason given to the public functions above.
1194 // Tests that all Literal are false. Tests that all IntegerLiteral are true.
1195 bool ReasonIsValid(absl::Span<const Literal> literal_reason,
1196 absl::Span<const IntegerLiteral> integer_reason);
1197
1198 // Same as above, but with the literal for which this is the reason for.
1199 bool ReasonIsValid(Literal lit, absl::Span<const Literal> literal_reason,
1200 absl::Span<const IntegerLiteral> integer_reason);
1201 bool ReasonIsValid(IntegerLiteral i_lit,
1202 absl::Span<const Literal> literal_reason,
1203 absl::Span<const IntegerLiteral> integer_reason);
1204
1205 // If the variable has holes in its domain, make sure the literal is
1206 // canonicalized.
1207 void CanonicalizeLiteralIfNeeded(IntegerLiteral* i_lit);
1208
1209 // Called by the Enqueue() functions that detected a conflict. This does some
1210 // common conflict initialization that must terminate by a call to
1211 // MergeReasonIntoInternal(conflict) where conflict is the returned vector.
1212 std::vector<Literal>* InitializeConflict(
1213 IntegerLiteral integer_literal, bool use_lazy_reason,
1214 absl::Span<const Literal> literals_reason,
1215 absl::Span<const IntegerLiteral> bounds_reason);
1216
1217 // Saves the given reason and return its index.
1218 int AppendReasonToInternalBuffers(
1219 absl::Span<const Literal> literal_reason,
1220 absl::Span<const IntegerLiteral> integer_reason);
1221
1222 // Internal implementation of the different public Enqueue() functions.
1223 ABSL_MUST_USE_RESULT bool EnqueueInternal(
1224 IntegerLiteral i_lit, bool use_lazy_reason,
1225 absl::Span<const Literal> literal_reason,
1226 absl::Span<const IntegerLiteral> integer_reason,
1227 int trail_index_with_same_reason);
1228
1229 // Internal implementation of the EnqueueLiteral() functions.
1230 void EnqueueLiteralInternal(Literal literal, bool use_lazy_reason,
1231 absl::Span<const Literal> literal_reason,
1232 absl::Span<const IntegerLiteral> integer_reason);
1233
1234 // Same as EnqueueInternal() but for the case where we push an IntegerLiteral
1235 // because an associated Literal is true (and we know it). In this case, we
1236 // have less work to do, so this has the same effect but is faster.
1237 ABSL_MUST_USE_RESULT bool EnqueueAssociatedIntegerLiteral(
1238 IntegerLiteral i_lit, Literal literal_reason);
1239
1240 // Does the work of MergeReasonInto() when queue_ is already initialized.
1241 void MergeReasonIntoInternal(std::vector<Literal>* output,
1242 int64_t conflict_id) const;
1243
1244 // Returns the lowest trail index of a TrailEntry that can be used to explain
1245 // the given IntegerLiteral. The literal must be currently true (CHECKed).
1246 // Returns -1 if the explanation is trivial.
1247 int FindLowestTrailIndexThatExplainBound(IntegerLiteral i_lit) const;
1248
1249 // This must be called before Dependencies() or AppendLiteralsReason().
1250 //
1251 // TODO(user): Not really robust, try to find a better way.
1252 void ComputeLazyReasonIfNeeded(int reason_index) const;
1253
1254 // Helper function to return the "dependencies" of a bound assignment.
1255 // All the TrailEntry at these indices are part of the reason for this
1256 // assignment.
1257 //
1258 // Important: The returned Span is only valid up to the next call.
1259 absl::Span<const int> Dependencies(int reason_index) const;
1260
1261 // Helper function to append the Literal part of the reason for this bound
1262 // assignment. We use added_variables_ to not add the same literal twice.
1263 // Note that looking at literal.Variable() is enough since all the literals
1264 // of a reason must be false.
1265 void AppendLiteralsReason(int reason_index,
1266 std::vector<Literal>* output) const;
1267
1268 // Returns some debugging info.
1269 std::string DebugString();
1270
1271 // Used internally to return the next conlict number.
1272 int64_t NextConflictId();
1273
1274 // Information for each integer variable about its current lower bound and
1275 // position of the last TrailEntry in the trail referring to this var.
1278
1279 // This is used by FindLowestTrailIndexThatExplainBound() and
1280 // FindTrailIndexOfVarBefore() to speed up the lookup. It keeps a trail index
1281 // for each variable that may or may not point to a TrailEntry regarding this
1282 // variable. The validity of the index is verified before being used.
1283 //
1284 // The cache will only be updated with trail_index >= threshold.
1285 mutable int var_trail_index_cache_threshold_ = 0;
1287 var_trail_index_cache_;
1288
1289 // Used by GetOrCreateConstantIntegerVariable() to return already created
1290 // constant variables that share the same value.
1291 absl::flat_hash_map<IntegerValue, IntegerVariable> constant_map_;
1292
1293 // The integer trail. It always start by num_vars sentinel values with the
1294 // level 0 bounds (in one to one correspondence with var_lbs_).
1295 struct TrailEntry {
1296 IntegerValue bound;
1297 IntegerVariable var;
1298 int32_t prev_trail_index;
1299
1300 // Index in literals_reason_start_/bounds_reason_starts_ If this is negative
1301 // then it is a lazy reason.
1302 int32_t reason_index;
1303 };
1304 std::vector<TrailEntry> integer_trail_;
1305
1306 struct LazyReasonEntry {
1307 LazyReasonInterface* explainer;
1308 IntegerValue propagation_slack;
1309 IntegerVariable var_to_explain;
1310 int id;
1311 int trail_index_at_propagation_time;
1312
1313 void Explain(std::vector<Literal>* literals,
1314 std::vector<int>* dependencies) const {
1315 explainer->Explain(id, propagation_slack, var_to_explain,
1316 trail_index_at_propagation_time, literals,
1317 dependencies);
1318 }
1319 };
1320 std::vector<int> lazy_reason_decision_levels_;
1321 std::vector<LazyReasonEntry> lazy_reasons_;
1322
1323 // Start of each decision levels in integer_trail_.
1324 // TODO(user): use more general reversible mechanism?
1325 std::vector<int> integer_search_levels_;
1326
1327 // Buffer to store the reason of each trail entry.
1328 std::vector<int> reason_decision_levels_;
1329 std::vector<int> literals_reason_starts_;
1330 std::vector<Literal> literals_reason_buffer_;
1331
1332 // The last two vectors are in one to one correspondence. Dependencies() will
1333 // "cache" the result of the conversion from IntegerLiteral to trail indices
1334 // in trail_index_reason_buffer_.
1335 std::vector<int> bounds_reason_starts_;
1336 mutable std::vector<int> cached_sizes_;
1337 std::vector<IntegerLiteral> bounds_reason_buffer_;
1338 mutable std::vector<int> trail_index_reason_buffer_;
1339
1340 // Temporary vector filled by calls to LazyReasonFunction().
1341 mutable std::vector<Literal> lazy_reason_literals_;
1342 mutable std::vector<int> lazy_reason_trail_indices_;
1343
1344 // Temporary data used by MergeReasonInto().
1345 mutable bool has_dependency_ = false;
1346 mutable std::vector<int> tmp_queue_;
1347 mutable std::vector<IntegerVariable> tmp_to_clear_;
1349 tmp_var_to_trail_index_in_queue_;
1350 mutable SparseBitset<BooleanVariable> added_variables_;
1351
1352 // Temporary heap used by RelaxLinearReason();
1353 struct RelaxHeapEntry {
1354 int index;
1355 IntegerValue coeff;
1356 int64_t diff;
1357 bool operator<(const RelaxHeapEntry& o) const { return index < o.index; }
1358 };
1359 mutable std::vector<RelaxHeapEntry> relax_heap_;
1360 mutable std::vector<int> tmp_indices_;
1361
1362 // Temporary data used by AppendNewBounds().
1363 mutable SparseBitset<IntegerVariable> tmp_marked_;
1364
1365 // Temporary data used by SafeEnqueue();
1366 std::vector<IntegerLiteral> tmp_cleaned_reason_;
1367
1368 // For EnqueueLiteral(), we store the reason index at its Boolean trail index.
1369 std::vector<int> boolean_trail_index_to_reason_index_;
1370
1371 // We need to know if we skipped some propagation in the current branch.
1372 // This is reverted as we backtrack over it.
1373 int first_level_without_full_propagation_ = -1;
1374
1375 // This is used to detect when MergeReasonIntoInternal() is called multiple
1376 // time while processing the same conflict. It allows to optimize the reason
1377 // and the time taken to compute it.
1378 mutable int64_t last_conflict_id_ = -1;
1379 mutable bool info_is_valid_on_subsequent_last_level_expansion_ = false;
1381 var_to_trail_index_at_lower_level_;
1382 mutable std::vector<int> tmp_seen_;
1383 mutable std::vector<IntegerVariable> to_clear_for_lower_level_;
1384
1385 int64_t num_enqueues_ = 0;
1386 int64_t num_untrails_ = 0;
1387 int64_t num_level_zero_enqueues_ = 0;
1388 mutable int64_t num_decisions_to_break_loop_ = 0;
1389
1390 std::vector<SparseBitset<IntegerVariable>*> watchers_;
1391 std::vector<ReversibleInterface*> reversible_classes_;
1392
1393 mutable Domain temp_domain_;
1394 DelayedRootLevelDeduction* delayed_to_fix_;
1395 IntegerDomains* domains_;
1396 IntegerEncoder* encoder_;
1397 Trail* trail_;
1398 SatSolver* sat_solver_;
1399 TimeLimit* time_limit_;
1400 const SatParameters& parameters_;
1401
1402 // Temporary "hash" to keep track of all the conditional enqueue that were
1403 // done. Note that we currently do not keep any reason for them, and as such,
1404 // we can only use this in heuristics. See ConditionalLowerBound().
1405 absl::flat_hash_map<std::pair<LiteralIndex, IntegerVariable>, IntegerValue>
1406 conditional_lbs_;
1407
1408 std::function<bool(absl::Span<const Literal> clause,
1409 absl::Span<const IntegerLiteral> integers)>
1410 debug_checker_ = nullptr;
1411};
1412
1413// Base class for CP like propagators.
1415 public:
1417 virtual ~PropagatorInterface() = default;
1418
1419 // This will be called after one or more literals that are watched by this
1420 // propagator changed. It will also always be called on the first propagation
1421 // cycle after registration.
1422 virtual bool Propagate() = 0;
1423
1424 // This will only be called on a non-empty vector, otherwise Propagate() will
1425 // be called. The passed vector will contain the "watch index" of all the
1426 // literals that were given one at registration and that changed since the
1427 // last call to Propagate(). This is only true when going down in the search
1428 // tree, on backjump this list will be cleared.
1429 //
1430 // Notes:
1431 // - The indices may contain duplicates if the same integer variable as been
1432 // updated many times or if different watched literals have the same
1433 // watch_index.
1434 // - At level zero, it will not contain any indices associated with literals
1435 // that were already fixed when the propagator was registered. Only the
1436 // indices of the literals modified after the registration will be present.
1437 virtual bool IncrementalPropagate(const std::vector<int>& /*watch_indices*/) {
1438 LOG(FATAL) << "Not implemented.";
1439 return false; // Remove warning in Windows
1440 }
1441};
1442
1443// Singleton for basic reversible types. We need the wrapper so that they can be
1444// accessed with model->GetOrCreate<>() and properly registered at creation.
1445class RevIntRepository : public RevRepository<int> {
1446 public:
1448 model->GetOrCreate<IntegerTrail>()->RegisterReversibleClass(this);
1449 }
1450};
1451class RevIntegerValueRepository : public RevRepository<IntegerValue> {
1452 public:
1454 model->GetOrCreate<IntegerTrail>()->RegisterReversibleClass(this);
1455 }
1456};
1457
1458// This class allows registering Propagator that will be called if a
1459// watched Literal or LbVar changes.
1460//
1461// TODO(user): Move this to its own file. Add unit tests!
1463 public:
1465
1466 // This type is neither copyable nor movable.
1469
1470 ~GenericLiteralWatcher() final = default;
1471
1472 // Memory optimization: you can call this before registering watchers.
1473 void ReserveSpaceForNumVariables(int num_vars);
1474
1475 // On propagate, the registered propagators will be called if they need to
1476 // until a fixed point is reached. Propagators with low ids will tend to be
1477 // called first, but it ultimately depends on their "waking" order.
1478 bool Propagate(Trail* trail) final;
1479 void Untrail(const Trail& trail, int literal_trail_index) final;
1480
1481 // Registers a propagator and returns its unique ids.
1482 int Register(PropagatorInterface* propagator);
1483
1484 // Changes the priority of the propagator with given id. The priority is a
1485 // non-negative integer. Propagators with a lower priority will always be
1486 // run before the ones with a higher one. The default priority is one.
1487 void SetPropagatorPriority(int id, int priority);
1488
1489 // The default behavior is to assume that a propagator does not need to be
1490 // called twice in a row. However, propagators on which this is called will be
1491 // called again if they change one of their own watched variables.
1493
1494 // Whether we call a propagator even if its watched variables didn't change.
1495 // This is only used when we are back to level zero. This was introduced for
1496 // the LP propagator where we might need to continue an interrupted solve or
1497 // add extra cuts at level zero.
1498 void AlwaysCallAtLevelZero(int id);
1499
1500 // Watches the corresponding quantity. The propagator with given id will be
1501 // called if it changes. Note that WatchLiteral() only trigger when the
1502 // literal becomes true.
1503 //
1504 // If watch_index is specified, it is associated with the watched literal.
1505 // Doing this will cause IncrementalPropagate() to be called (see the
1506 // documentation of this interface for more detail).
1507 void WatchLiteral(Literal l, int id, int watch_index = -1);
1508 void WatchLowerBound(IntegerVariable var, int id, int watch_index = -1);
1509 void WatchUpperBound(IntegerVariable var, int id, int watch_index = -1);
1510 void WatchIntegerVariable(IntegerVariable i, int id, int watch_index = -1);
1511
1512 // Because the coeff is always positive, watching an affine expression is
1513 // the same as watching its var.
1515 WatchLowerBound(e.var, id);
1516 }
1518 WatchUpperBound(e.var, id);
1519 }
1523
1524 // No-op overload for "constant" IntegerVariable that are sometimes templated
1525 // as an IntegerValue.
1526 void WatchLowerBound(IntegerValue /*i*/, int /*id*/) {}
1527 void WatchUpperBound(IntegerValue /*i*/, int /*id*/) {}
1528 void WatchIntegerVariable(IntegerValue /*v*/, int /*id*/) {}
1529
1530 // Registers a reversible class with a given propagator. This class will be
1531 // changed to the correct state just before the propagator is called.
1532 //
1533 // Doing it just before should minimize cache-misses and bundle as much as
1534 // possible the "backtracking" together. Many propagators only watches a
1535 // few variables and will not be called at each decision levels.
1537
1538 // Registers a reversible int with a given propagator. The int will be changed
1539 // to its correct value just before Propagate() is called.
1540 //
1541 // Note that this will work in O(num_rev_int_of_propagator_id) per call to
1542 // Propagate() and happens at most once per decision level. As such this is
1543 // meant for classes that have just a few reversible ints or that will have a
1544 // similar complexity anyway.
1545 //
1546 // Alternatively, one can directly get the underlying RevRepository<int> with
1547 // a call to model.Get<>(), and use SaveWithStamp() before each modification
1548 // to have just a slight overhead per int updates. This later option is what
1549 // is usually done in a CP solver at the cost of a slightly more complex API.
1550 void RegisterReversibleInt(int id, int* rev);
1551
1552 // A simple form of incremental update is to maintain state as we dive into
1553 // the search tree but forget everything on every backtrack. A propagator
1554 // can be called many times by decision, so this can make a large proportion
1555 // of the calls incremental.
1556 //
1557 // This allows to achieve this with a really low overhead.
1558 //
1559 // The propagator can define a bool rev_is_in_dive_ = false; and at the
1560 // beginning of each propagate do:
1561 // const bool no_backtrack_since_last_call = rev_is_in_dive_;
1562 // watcher_->SetUntilNextBacktrack(&rev_is_in_dive_);
1563 void SetUntilNextBacktrack(bool* is_in_dive) {
1564 if (!*is_in_dive) {
1565 *is_in_dive = true;
1566 bool_to_reset_on_backtrack_.push_back(is_in_dive);
1567 }
1568 }
1569
1570 // Returns the number of registered propagators.
1571 int NumPropagators() const { return in_queue_.size(); }
1572
1573 // Set a callback for new variable bounds at level 0.
1574 //
1575 // This will be called (only at level zero) with the list of IntegerVariable
1576 // with changed lower bounds. Note that it might be called more than once
1577 // during the same propagation cycle if we fix variables in "stages".
1578 //
1579 // Also note that this will be called if some BooleanVariable where fixed even
1580 // if no IntegerVariable are changed, so the passed vector to the function
1581 // might be empty.
1583 const std::function<void(const std::vector<IntegerVariable>&)> cb) {
1584 level_zero_modified_variable_callback_.push_back(cb);
1585 }
1586
1587 // This will be called not too often during propagation (when we finish
1588 // propagating one priority). If it returns true, we will stop propagation
1589 // there. It is used by LbTreeSearch as we can stop as soon as the objective
1590 // lower bound crossed a threshold and do not need to call expensive
1591 // propagator when this is the case.
1592 void SetStopPropagationCallback(std::function<bool()> callback) {
1593 stop_propagation_callback_ = callback;
1594 }
1595
1596 // Returns the id of the propagator we are currently calling. This is meant
1597 // to be used from inside Propagate() in case a propagator was registered
1598 // more than once at different priority for instance.
1599 int GetCurrentId() const { return current_id_; }
1600
1601 // Add the given propagator to its queue.
1602 void CallOnNextPropagate(int id);
1603
1604 private:
1605 // Updates queue_ and in_queue_ with the propagator ids that need to be
1606 // called.
1607 void UpdateCallingNeeds(Trail* trail);
1608
1609 TimeLimit* time_limit_;
1610 IntegerTrail* integer_trail_;
1611 RevIntRepository* rev_int_repository_;
1612
1613 struct WatchData {
1614 int id;
1615 int watch_index;
1616 bool operator==(const WatchData& o) const {
1617 return id == o.id && watch_index == o.watch_index;
1618 }
1619 };
1621 literal_to_watcher_;
1623 var_to_watcher_;
1624 std::vector<PropagatorInterface*> watchers_;
1625 SparseBitset<IntegerVariable> modified_vars_;
1626
1627 // For RegisterLevelZeroModifiedVariablesCallback().
1628 SparseBitset<IntegerVariable> modified_vars_for_callback_;
1629
1630 // Propagator ids that needs to be called. There is one queue per priority but
1631 // just one Boolean to indicate if a propagator is in one of them.
1632 std::vector<std::deque<int>> queue_by_priority_;
1633 std::vector<bool> in_queue_;
1634
1635 // Data for each propagator.
1637 std::vector<bool> id_need_reversible_support_;
1638 std::vector<int> id_to_level_at_last_call_;
1639 RevVector<IdType, int> id_to_greatest_common_level_since_last_call_;
1640 std::vector<std::vector<ReversibleInterface*>> id_to_reversible_classes_;
1641 std::vector<std::vector<int*>> id_to_reversible_ints_;
1642
1643 std::vector<std::vector<int>> id_to_watch_indices_;
1644 std::vector<int> id_to_priority_;
1645 std::vector<int> id_to_idempotence_;
1646
1647 // Special propagators that needs to always be called at level zero.
1648 std::vector<int> propagator_ids_to_call_at_level_zero_;
1649
1650 // The id of the propagator we just called.
1651 int current_id_;
1652
1653 std::vector<std::function<void(const std::vector<IntegerVariable>&)>>
1654 level_zero_modified_variable_callback_;
1655
1656 std::function<bool()> stop_propagation_callback_;
1657
1658 std::vector<bool*> bool_to_reset_on_backtrack_;
1659};
1660
1661// ============================================================================
1662// Implementation.
1663// ============================================================================
1664
1665inline IntegerLiteral IntegerLiteral::GreaterOrEqual(IntegerVariable i,
1666 IntegerValue bound) {
1669}
1670
1671inline IntegerLiteral IntegerLiteral::LowerOrEqual(IntegerVariable i,
1672 IntegerValue bound) {
1678 return IntegerLiteral(kNoIntegerVariable, IntegerValue(-1));
1682 return IntegerLiteral(kNoIntegerVariable, IntegerValue(1));
1684
1686 // Note that bound >= kMinIntegerValue, so -bound + 1 will have the correct
1687 // capped value.
1688 return IntegerLiteral(
1689 NegationOf(IntegerVariable(var)),
1691}
1692
1693// var * coeff + constant >= bound.
1695 IntegerValue bound) const {
1699 }
1700 DCHECK_GT(coeff, 0);
1703}
1704
1705// var * coeff + constant <= bound.
1706inline IntegerLiteral AffineExpression::LowerOrEqual(IntegerValue bound) const {
1707 if (var == kNoIntegerVariable) {
1709 : IntegerLiteral::FalseLiteral();
1710 }
1711 DCHECK_GT(coeff, 0);
1713}
1714
1715inline IntegerValue IntegerTrail::LowerBound(IntegerVariable i) const {
1716 return var_lbs_[i];
1718
1719inline IntegerValue IntegerTrail::UpperBound(IntegerVariable i) const {
1720 return -var_lbs_[NegationOf(i)];
1722
1723inline bool IntegerTrail::IsFixed(IntegerVariable i) const {
1724 return var_lbs_[i] == -var_lbs_[NegationOf(i)];
1726
1727inline IntegerValue IntegerTrail::FixedValue(IntegerVariable i) const {
1728 DCHECK(IsFixed(i));
1729 return var_lbs_[i];
1730}
1731
1732inline IntegerValue IntegerTrail::ConditionalLowerBound(
1733 Literal l, IntegerVariable i) const {
1734 const auto it = conditional_lbs_.find({l.Index(), i});
1735 if (it != conditional_lbs_.end()) {
1736 return std::max(var_lbs_[i], it->second);
1737 }
1738 return var_lbs_[i];
1739}
1740
1741inline IntegerValue IntegerTrail::ConditionalLowerBound(
1742 Literal l, AffineExpression expr) const {
1743 if (expr.var == kNoIntegerVariable) return expr.constant;
1744 return ConditionalLowerBound(l, expr.var) * expr.coeff + expr.constant;
1745}
1746
1747inline IntegerValue IntegerTrail::ConditionalUpperBound(
1748 Literal l, IntegerVariable i) const {
1750}
1751
1752inline IntegerValue IntegerTrail::ConditionalUpperBound(
1753 Literal l, AffineExpression expr) const {
1754 if (expr.var == kNoIntegerVariable) return expr.constant;
1755 return ConditionalUpperBound(l, expr.var) * expr.coeff + expr.constant;
1756}
1757
1759 IntegerVariable i) const {
1764 IntegerVariable i) const {
1766}
1767
1768inline IntegerValue IntegerTrail::LowerBound(AffineExpression expr) const {
1769 if (expr.var == kNoIntegerVariable) return expr.constant;
1770 return LowerBound(expr.var) * expr.coeff + expr.constant;
1771}
1772
1773inline IntegerValue IntegerTrail::UpperBound(AffineExpression expr) const {
1774 if (expr.var == kNoIntegerVariable) return expr.constant;
1775 return UpperBound(expr.var) * expr.coeff + expr.constant;
1776}
1777
1778inline bool IntegerTrail::IsFixed(AffineExpression expr) const {
1779 if (expr.var == kNoIntegerVariable) return true;
1780 return IsFixed(expr.var);
1781}
1782
1783inline IntegerValue IntegerTrail::FixedValue(AffineExpression expr) const {
1784 if (expr.var == kNoIntegerVariable) return expr.constant;
1785 return FixedValue(expr.var) * expr.coeff + expr.constant;
1786}
1787
1789 AffineExpression expr) const {
1795 AffineExpression expr) const {
1797 return IntegerLiteral::LowerOrEqual(expr.var, UpperBound(expr.var));
1798}
1799
1801 return l.bound <= LowerBound(l.var);
1803
1805 return l.bound > UpperBound(l.var);
1807
1808// The level zero bounds are stored at the beginning of the trail and they also
1809// serves as sentinels. Their index match the variables index.
1810inline IntegerValue IntegerTrail::LevelZeroLowerBound(
1811 IntegerVariable var) const {
1812 return integer_trail_[var.value()].bound;
1813}
1814
1815inline IntegerValue IntegerTrail::LevelZeroUpperBound(
1816 IntegerVariable var) const {
1817 return -integer_trail_[NegationOf(var).value()].bound;
1818}
1819
1820inline bool IntegerTrail::IsFixedAtLevelZero(IntegerVariable var) const {
1821 return integer_trail_[var.value()].bound ==
1822 -integer_trail_[NegationOf(var).value()].bound;
1823}
1824
1825inline IntegerValue IntegerTrail::LevelZeroLowerBound(
1826 AffineExpression expr) const {
1827 if (expr.var == kNoIntegerVariable) return expr.constant;
1828 return expr.ValueAt(LevelZeroLowerBound(expr.var));
1829}
1830
1831inline IntegerValue IntegerTrail::LevelZeroUpperBound(
1832 AffineExpression expr) const {
1833 if (expr.var == kNoIntegerVariable) return expr.constant;
1834 return expr.ValueAt(LevelZeroUpperBound(expr.var));
1835}
1836
1837inline bool IntegerTrail::IsFixedAtLevelZero(AffineExpression expr) const {
1838 if (expr.var == kNoIntegerVariable) return true;
1840}
1841
1842inline void GenericLiteralWatcher::WatchLiteral(Literal l, int id,
1843 int watch_index) {
1844 if (l.Index() >= literal_to_watcher_.size()) {
1845 literal_to_watcher_.resize(l.Index().value() + 1);
1846 }
1847 literal_to_watcher_[l].push_back({id, watch_index});
1848}
1849
1850inline void GenericLiteralWatcher::WatchLowerBound(IntegerVariable var, int id,
1851 int watch_index) {
1852 if (var == kNoIntegerVariable) return;
1853 if (var.value() >= var_to_watcher_.size()) {
1854 var_to_watcher_.resize(var.value() + 1);
1855 }
1856
1857 // Minor optim, so that we don't watch the same variable twice. Propagator
1858 // code is easier this way since for example when one wants to watch both
1859 // an interval start and interval end, both might have the same underlying
1860 // variable.
1861 const WatchData data = {id, watch_index};
1862 if (!var_to_watcher_[var].empty() && var_to_watcher_[var].back() == data) {
1863 return;
1864 }
1865 var_to_watcher_[var].push_back(data);
1866}
1867
1868inline void GenericLiteralWatcher::WatchUpperBound(IntegerVariable var, int id,
1869 int watch_index) {
1870 if (var == kNoIntegerVariable) return;
1871 WatchLowerBound(NegationOf(var), id, watch_index);
1872}
1873
1874inline void GenericLiteralWatcher::WatchIntegerVariable(IntegerVariable i,
1875 int id,
1876 int watch_index) {
1877 WatchLowerBound(i, id, watch_index);
1878 WatchUpperBound(i, id, watch_index);
1879}
1880
1881// ============================================================================
1882// Model based functions.
1883//
1884// Note that in the model API, we simply use int64_t for the integer values, so
1885// that it is nicer for the client. Internally these are converted to
1886// IntegerValue which is typechecked.
1887// ============================================================================
1888
1889inline std::function<BooleanVariable(Model*)> NewBooleanVariable() {
1890 return [=](Model* model) {
1891 return model->GetOrCreate<SatSolver>()->NewBooleanVariable();
1892 };
1894
1895inline std::function<IntegerVariable(Model*)> ConstantIntegerVariable(
1896 int64_t value) {
1897 return [=](Model* model) {
1898 return model->GetOrCreate<IntegerTrail>()
1899 ->GetOrCreateConstantIntegerVariable(IntegerValue(value));
1900 };
1901}
1902
1903inline std::function<IntegerVariable(Model*)> NewIntegerVariable(int64_t lb,
1904 int64_t ub) {
1905 return [=](Model* model) {
1906 CHECK_LE(lb, ub);
1907 return model->GetOrCreate<IntegerTrail>()->AddIntegerVariable(
1908 IntegerValue(lb), IntegerValue(ub));
1909 };
1910}
1911
1912inline std::function<IntegerVariable(Model*)> NewIntegerVariable(
1913 const Domain& domain) {
1914 return [=](Model* model) {
1915 return model->GetOrCreate<IntegerTrail>()->AddIntegerVariable(domain);
1917}
1918
1919// Creates a 0-1 integer variable "view" of the given literal. It will have a
1920// value of 1 when the literal is true, and 0 when the literal is false.
1921inline IntegerVariable CreateNewIntegerVariableFromLiteral(Literal lit,
1922 Model* model) {
1923 auto* encoder = model->GetOrCreate<IntegerEncoder>();
1924 const IntegerVariable candidate = encoder->GetLiteralView(lit);
1925 if (candidate != kNoIntegerVariable) return candidate;
1926
1927 IntegerVariable var;
1928 auto* integer_trail = model->GetOrCreate<IntegerTrail>();
1929 const auto& assignment = model->GetOrCreate<SatSolver>()->Assignment();
1930 if (assignment.LiteralIsTrue(lit)) {
1931 var = integer_trail->GetOrCreateConstantIntegerVariable(IntegerValue(1));
1932 } else if (assignment.LiteralIsFalse(lit)) {
1933 var = integer_trail->GetOrCreateConstantIntegerVariable(IntegerValue(0));
1934 } else {
1935 var = integer_trail->AddIntegerVariable(IntegerValue(0), IntegerValue(1));
1936 }
1937
1938 encoder->AssociateToIntegerEqualValue(lit, var, IntegerValue(1));
1939 DCHECK_NE(encoder->GetLiteralView(lit), kNoIntegerVariable);
1940 return var;
1941}
1942
1943// Deprecated.
1944inline std::function<IntegerVariable(Model*)> NewIntegerVariableFromLiteral(
1945 Literal lit) {
1946 return [=](Model* model) {
1949}
1950
1951inline std::function<int64_t(const Model&)> LowerBound(IntegerVariable v) {
1952 return [=](const Model& model) {
1953 return model.Get<IntegerTrail>()->LowerBound(v).value();
1954 };
1956
1957inline std::function<int64_t(const Model&)> UpperBound(IntegerVariable v) {
1958 return [=](const Model& model) {
1959 return model.Get<IntegerTrail>()->UpperBound(v).value();
1960 };
1962
1963inline std::function<bool(const Model&)> IsFixed(IntegerVariable v) {
1964 return [=](const Model& model) {
1965 const IntegerTrail* trail = model.Get<IntegerTrail>();
1966 return trail->LowerBound(v) == trail->UpperBound(v);
1968}
1969
1970// This checks that the variable is fixed.
1971inline std::function<int64_t(const Model&)> Value(IntegerVariable v) {
1972 return [=](const Model& model) {
1973 const IntegerTrail* trail = model.Get<IntegerTrail>();
1974 CHECK_EQ(trail->LowerBound(v), trail->UpperBound(v)) << v;
1975 return trail->LowerBound(v).value();
1976 };
1977}
1978
1979inline std::function<void(Model*)> GreaterOrEqual(IntegerVariable v,
1980 int64_t lb) {
1981 return [=](Model* model) {
1982 if (!model->GetOrCreate<IntegerTrail>()->Enqueue(
1984 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1985 model->GetOrCreate<SatSolver>()->NotifyThatModelIsUnsat();
1986 VLOG(1) << "Model trivially infeasible, variable " << v
1987 << " has upper bound " << model->Get(UpperBound(v))
1988 << " and GreaterOrEqual() was called with a lower bound of "
1989 << lb;
1990 }
1991 };
1992}
1993
1994inline std::function<void(Model*)> LowerOrEqual(IntegerVariable v, int64_t ub) {
1995 return [=](Model* model) {
1996 if (!model->GetOrCreate<IntegerTrail>()->Enqueue(
1997 IntegerLiteral::LowerOrEqual(v, IntegerValue(ub)),
1998 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1999 model->GetOrCreate<SatSolver>()->NotifyThatModelIsUnsat();
2000 VLOG(1) << "Model trivially infeasible, variable " << v
2001 << " has lower bound " << model->Get(LowerBound(v))
2002 << " and LowerOrEqual() was called with an upper bound of " << ub;
2003 }
2004 };
2005}
2006
2007// Fix v to a given value.
2008inline std::function<void(Model*)> Equality(IntegerVariable v, int64_t value) {
2009 return [=](Model* model) {
2010 model->Add(LowerOrEqual(v, value));
2011 model->Add(GreaterOrEqual(v, value));
2013}
2014
2015// TODO(user): This is one of the rare case where it is better to use Equality()
2016// rather than two Implications(). Maybe we should modify our internal
2017// implementation to use half-reified encoding? that is do not propagate the
2018// direction integer-bound => literal, but just literal => integer-bound? This
2019// is the same as using different underlying variable for an integer literal and
2020// its negation.
2021inline std::function<void(Model*)> Implication(
2022 absl::Span<const Literal> enforcement_literals, IntegerLiteral i) {
2023 return [=](Model* model) {
2024 IntegerTrail* integer_trail = model->GetOrCreate<IntegerTrail>();
2025 if (i.bound <= integer_trail->LowerBound(i.var)) {
2026 // Always true! nothing to do.
2027 } else if (i.bound > integer_trail->UpperBound(i.var)) {
2028 // Always false.
2029 std::vector<Literal> clause;
2030 for (const Literal literal : enforcement_literals) {
2031 clause.push_back(literal.Negated());
2032 }
2033 model->Add(ClauseConstraint(clause));
2034 } else {
2035 // TODO(user): Double check what happen when we associate a trivially
2036 // true or false literal.
2037 IntegerEncoder* encoder = model->GetOrCreate<IntegerEncoder>();
2038 std::vector<Literal> clause{encoder->GetOrCreateAssociatedLiteral(i)};
2039 for (const Literal literal : enforcement_literals) {
2040 clause.push_back(literal.Negated());
2041 }
2042 model->Add(ClauseConstraint(clause));
2043 }
2044 };
2045}
2046
2047// in_interval => v in [lb, ub].
2048inline std::function<void(Model*)> ImpliesInInterval(Literal in_interval,
2049 IntegerVariable v,
2050 int64_t lb, int64_t ub) {
2051 return [=](Model* model) {
2052 if (lb == ub) {
2053 IntegerEncoder* encoder = model->GetOrCreate<IntegerEncoder>();
2054 model->Add(Implication({in_interval},
2056 v, IntegerValue(lb))));
2057 return;
2058 }
2059 model->Add(Implication(
2060 {in_interval}, IntegerLiteral::GreaterOrEqual(v, IntegerValue(lb))));
2061 model->Add(Implication({in_interval},
2062 IntegerLiteral::LowerOrEqual(v, IntegerValue(ub))));
2063 };
2064}
2065
2066// Calling model.Add(FullyEncodeVariable(var)) will create one literal per value
2067// in the domain of var (if not already done), and wire everything correctly.
2068// This also returns the full encoding, see the FullDomainEncoding() method of
2069// the IntegerEncoder class.
2070inline std::function<std::vector<ValueLiteralPair>(Model*)> FullyEncodeVariable(
2071 IntegerVariable var) {
2072 return [=](Model* model) {
2073 IntegerEncoder* encoder = model->GetOrCreate<IntegerEncoder>();
2074 if (!encoder->VariableIsFullyEncoded(var)) {
2075 encoder->FullyEncodeVariable(var);
2076 }
2077 return encoder->FullDomainEncoding(var);
2078 };
2079}
2080
2081} // namespace sat
2082} // namespace operations_research
2083
2084#endif // OR_TOOLS_SAT_INTEGER_H_
void ClearAndResize(IntegerType size)
Definition bitset.h:839
int NumPropagators() const
Returns the number of registered propagators.
Definition integer.h:1571
void WatchUpperBound(AffineExpression e, int id)
Definition integer.h:1517
void WatchAffineExpression(AffineExpression e, int id)
Definition integer.h:1520
void WatchLiteral(Literal l, int id, int watch_index=-1)
Definition integer.h:1844
void WatchUpperBound(IntegerVariable var, int id, int watch_index=-1)
Definition integer.h:1870
void Untrail(const Trail &trail, int literal_trail_index) final
Definition integer.cc:2297
void WatchLowerBound(IntegerVariable var, int id, int watch_index=-1)
Definition integer.h:1852
void RegisterLevelZeroModifiedVariablesCallback(const std::function< void(const std::vector< IntegerVariable > &)> cb)
Definition integer.h:1582
void SetStopPropagationCallback(std::function< bool()> callback)
Definition integer.h:1592
void SetPropagatorPriority(int id, int priority)
Definition integer.cc:2358
void WatchIntegerVariable(IntegerVariable i, int id, int watch_index=-1)
Definition integer.h:1876
void RegisterReversibleClass(int id, ReversibleInterface *rev)
Definition integer.cc:2374
void ReserveSpaceForNumVariables(int num_vars)
Memory optimization: you can call this before registering watchers.
Definition integer.cc:2104
int Register(PropagatorInterface *propagator)
Registers a propagator and returns its unique ids.
Definition integer.cc:2332
GenericLiteralWatcher & operator=(const GenericLiteralWatcher &)=delete
void CallOnNextPropagate(int id)
Add the given propagator to its queue.
Definition integer.cc:2108
GenericLiteralWatcher(const GenericLiteralWatcher &)=delete
This type is neither copyable nor movable.
const std::vector< ValueLiteralPair > & FullDomainEncoding(IntegerVariable var) const
Definition integer.cc:145
IntegerEncoder & operator=(const IntegerEncoder &)=delete
std::pair< IntegerLiteral, IntegerLiteral > Canonicalize(IntegerLiteral i_lit) const
Definition integer.cc:246
void AssociateToIntegerLiteral(Literal literal, IntegerLiteral i_lit)
Definition integer.cc:364
const InlinedIntegerValueVector & GetEqualityLiterals(Literal lit) const
Definition integer.h:593
IntegerVariable GetLiteralView(Literal lit) const
Definition integer.h:618
void FullyEncodeVariable(IntegerVariable var)
Definition integer.cc:79
IntegerEncoder(const IntegerEncoder &)=delete
This type is neither copyable nor movable.
Literal GetTrueLiteral()
Gets the literal always set to true, make it if it does not exist.
Definition integer.h:641
bool VariableIsFullyEncoded(IntegerVariable var) const
Definition integer.cc:110
bool IsFixedOrHasAssociatedLiteral(IntegerLiteral i_lit) const
Definition integer.cc:531
const std::vector< ValueLiteralPair > & PartialDomainEncoding(IntegerVariable var) const
Definition integer.cc:151
LiteralIndex GetAssociatedEqualityLiteral(IntegerVariable var, IntegerValue value) const
Definition integer.cc:317
const InlinedIntegerLiteralVector & GetIntegerLiterals(Literal lit) const
Returns the IntegerLiterals that were associated with the given Literal.
Definition integer.h:584
LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i_lit, IntegerValue *bound) const
Definition integer.cc:554
void ReserveSpaceForNumVariables(int num_vars)
Memory optimization: you can call this before encoding variables.
Definition integer.cc:73
Literal GetOrCreateAssociatedLiteral(IntegerLiteral i_lit)
Definition integer.cc:273
void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var, IntegerValue value)
Definition integer.cc:434
ABSL_MUST_USE_RESULT bool LiteralOrNegationHasView(Literal lit, IntegerVariable *view=nullptr, bool *view_is_direct=nullptr) const
Definition integer.cc:582
const std::vector< IntegerVariable > & GetAllAssociatedVariables(Literal lit) const
Definition integer.h:602
std::vector< ValueLiteralPair > PartialGreaterThanEncoding(IntegerVariable var) const
Definition integer.cc:602
LiteralIndex GetAssociatedLiteral(IntegerLiteral i_lit) const
Definition integer.cc:540
bool UpdateEncodingOnInitialDomainChange(IntegerVariable var, Domain domain)
Definition integer.cc:638
Literal GetOrCreateLiteralAssociatedToEquality(IntegerVariable var, IntegerValue value)
Definition integer.cc:327
ABSL_MUST_USE_RESULT bool ConditionalEnqueue(Literal lit, IntegerLiteral i_lit, std::vector< Literal > *literal_reason, std::vector< IntegerLiteral > *integer_reason)
Definition integer.cc:1269
absl::Span< const Literal > Reason(const Trail &trail, int trail_index, int64_t conflict_id) const final
Definition integer.cc:2047
IntegerValue LowerBound(IntegerVariable i) const
Returns the current lower/upper bound of the given integer variable.
Definition integer.h:1717
void RemoveLevelZeroBounds(std::vector< IntegerLiteral > *reason) const
Definition integer.cc:1159
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
Definition integer.h:975
int FindTrailIndexOfVarBefore(IntegerVariable var, int threshold) const
Definition integer.cc:946
bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const
Returns true if the variable lower bound is still the one from level zero.
Definition integer.h:1093
IntegerTrail & operator=(const IntegerTrail &)=delete
void RegisterWatcher(SparseBitset< IntegerVariable > *p)
Definition integer.h:1069
IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const
Definition integer.h:1765
bool IsFixedAtLevelZero(IntegerVariable var) const
Returns true if the variable is fixed at level 0.
Definition integer.h:1822
ABSL_MUST_USE_RESULT bool SafeEnqueue(IntegerLiteral i_lit, absl::Span< const IntegerLiteral > integer_reason)
Definition integer.cc:1252
void RelaxLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, std::vector< IntegerLiteral > *reason) const
Definition integer.cc:1025
bool IntegerLiteralIsTrue(IntegerLiteral l) const
Returns the current value (if known) of an IntegerLiteral.
Definition integer.h:1802
IntegerValue UpperBound(IntegerVariable i) const
Definition integer.h:1721
void AppendNewBoundsFrom(int base_index, std::vector< IntegerLiteral > *output) const
Definition integer.cc:2071
IntegerValue FixedValue(IntegerVariable i) const
Checks that the variable is fixed and returns its value.
Definition integer.h:1729
bool IntegerLiteralIsFalse(IntegerLiteral l) const
Definition integer.h:1806
IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const
Definition integer.h:1760
bool HasPendingRootLevelDeduction() const
Return true if we can fix new fact at level zero.
Definition integer.h:1137
void AddAllGreaterThanConstantReason(absl::Span< AffineExpression > exprs, IntegerValue target_min, std::vector< int > *indices) const
Definition integer.h:1158
void RegisterReversibleClass(ReversibleInterface *rev)
Definition integer.h:1099
bool ReportConflict(absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
Definition integer.h:1076
void AppendRelaxedLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, absl::Span< const IntegerVariable > vars, std::vector< IntegerLiteral > *reason) const
Same as above but take in IntegerVariables instead of IntegerLiterals.
Definition integer.cc:1047
IntegerTrail(const IntegerTrail &)=delete
This type is neither copyable nor movable.
bool ReportConflict(absl::Span< const IntegerLiteral > integer_reason)
Definition integer.h:1084
ABSL_MUST_USE_RESULT bool EnqueueWithLazyReason(IntegerLiteral i_lit, int id, IntegerValue propagation_slack, LazyReasonInterface *explainer)
Lazy reason API.
Definition integer.h:1020
void AppendNewBounds(std::vector< IntegerLiteral > *output) const
Definition integer.cc:2065
bool UpdateInitialDomain(IntegerVariable var, Domain domain)
Definition integer.cc:886
bool IsFixed(IntegerVariable i) const
Checks if the variable is fixed.
Definition integer.h:1725
IntegerVariable NumIntegerVariables() const
Definition integer.h:806
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason, int trail_index_with_same_reason)
Definition integer.h:1011
IntegerValue ConditionalLowerBound(Literal l, IntegerVariable i) const
Definition integer.h:1734
IntegerVariable NextVariableToBranchOnInPropagationLoop() const
Definition integer.cc:1452
IntegerValue ConditionalUpperBound(Literal l, IntegerVariable i) const
Returns the current upper bound assuming the literal is true.
Definition integer.h:1749
const IntegerValue * LowerBoundsData() const
Definition integer.h:864
void RegisterDebugChecker(std::function< bool(absl::Span< const Literal > clause, absl::Span< const IntegerLiteral > integers)> checker)
Definition integer.h:1144
int64_t num_level_zero_enqueues() const
Same as num_enqueues but only count the level zero changes.
Definition integer.h:1064
ABSL_MUST_USE_RESULT bool RootLevelEnqueue(IntegerLiteral i_lit)
Definition integer.cc:1229
IntegerValue LevelZeroUpperBound(IntegerVariable var) const
Definition integer.h:1817
void MergeReasonInto(absl::Span< const IntegerLiteral > literals, std::vector< Literal > *output) const
Definition integer.cc:1825
void EnqueueLiteral(Literal literal, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
Definition integer.cc:1392
const Domain & InitialVariableDomain(IntegerVariable var) const
Definition integer.cc:876
IntegerValue LevelZeroLowerBound(IntegerVariable var) const
Returns globally valid lower/upper bound on the given integer variable.
Definition integer.h:1812
void Untrail(const Trail &trail, int literal_trail_index) final
Definition integer.cc:768
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit)
Definition integer.h:972
IntegerVariable FirstUnassignedVariable() const
Definition integer.cc:1485
void ReserveSpaceForNumVariables(int num_vars)
Definition integer.cc:821
bool Propagate(Trail *trail) final
Definition integer.cc:705
IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value)
Definition integer.cc:925
std::vector< Literal > ReasonFor(IntegerLiteral literal) const
Definition integer.cc:1819
virtual void Explain(int id, IntegerValue propagation_slack, IntegerVariable var_to_explain, int trail_index, std::vector< Literal > *literals_reason, std::vector< int > *trail_indices_reason)=0
LiteralIndex Index() const
Definition sat_base.h:91
Base class for CP like propagators.
Definition integer.h:1414
virtual bool IncrementalPropagate(const std::vector< int > &)
Definition integer.h:1437
uint16_t DivideByDivisor(uint16_t dividend) const
Definition integer.h:138
Base class for all the SAT constraints.
Definition sat_base.h:533
BooleanVariable NewBooleanVariable()
Definition sat_solver.h:94
ABSL_MUST_USE_RESULT bool AddUnitClause(Literal true_literal)
void AddPropagator(SatPropagator *propagator)
std::vector< Literal > * MutableConflict()
Definition sat_base.h:433
value_type * data()
– Pass-through methods to STL vector ----------------------------------—
void push_back(const value_type &val)
void resize(size_type new_size)
int64_t a
Definition table.cc:44
int64_t value
IntVar * var
double upper_bound
double lower_bound
GRBmodel * model
MPCallback * callback
int lit
int literal
int index
std::function< std::vector< ValueLiteralPair >(Model *)> FullyEncodeVariable(IntegerVariable var)
Definition integer.h:2074
std::function< IntegerVariable(Model *)> NewIntegerVariableFromLiteral(Literal lit)
Definition integer.h:1948
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
Definition integer.h:94
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
Computes result += a * b, and return false iff there is an overflow.
Definition integer.h:169
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
std::function< void(Model *)> Equality(IntegerVariable v, int64_t value)
Fix v to a given value.
Definition integer.h:2012
bool AddTo(IntegerValue a, IntegerValue *result)
Definition integer.h:160
IntType IntTypeAbs(IntType t)
Definition integer.h:81
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
Definition integer.h:85
bool ProdOverflow(IntegerValue t, IntegerValue value)
Definition integer.h:117
const LiteralIndex kNoLiteralIndex(-1)
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
Definition sat_solver.h:933
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
Definition integer.h:1955
std::function< BooleanVariable(Model *)> NewBooleanVariable()
Definition integer.h:1893
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
Returns the vector of the negated variables.
Definition integer.cc:51
std::function< void(Model *)> LowerOrEqual(IntegerVariable v, int64_t ub)
Definition integer.h:1998
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
Definition integer.h:203
std::function< bool(const Model &)> IsFixed(IntegerVariable v)
Definition integer.h:1967
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
absl::InlinedVector< std::pair< IntegerVariable, IntegerValue >, 2 > InlinedIntegerValueVector
Definition integer.h:287
std::function< void(Model *)> Implication(absl::Span< const Literal > enforcement_literals, IntegerLiteral i)
Definition integer.h:2025
std::function< IntegerVariable(Model *)> ConstantIntegerVariable(int64_t value)
Definition integer.h:1899
IntegerVariable PositiveVariable(IntegerVariable i)
Definition integer.h:193
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition cp_model.cc:89
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
Definition integer.h:153
IntegerValue CapAddI(IntegerValue a, IntegerValue b)
Definition integer.h:113
std::function< int64_t(const Model &)> Value(IntegerVariable v)
This checks that the variable is fixed.
Definition integer.h:1975
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
Definition integer.h:1961
H AbslHashValue(H h, const IntVar &i)
– ABSL HASHING SUPPORT --------------------------------------------------—
Definition cp_model.h:515
std::function< IntegerVariable(Model *)> NewIntegerVariable(int64_t lb, int64_t ub)
Definition integer.h:1907
std::function< void(Model *)> GreaterOrEqual(IntegerVariable v, int64_t lb)
Definition integer.h:1983
absl::InlinedVector< IntegerLiteral, 2 > InlinedIntegerLiteralVector
Definition integer.h:286
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
Definition integer.h:199
std::function< void(Model *)> ImpliesInInterval(Literal in_interval, IntegerVariable v, int64_t lb, int64_t ub)
in_interval => v in [lb, ub].
Definition integer.h:2052
bool VariableIsPositive(IntegerVariable i)
Definition integer.h:189
IntegerValue CapSubI(IntegerValue a, IntegerValue b)
Definition integer.h:109
bool AtMinOrMaxInt64I(IntegerValue t)
Definition integer.h:121
IntegerValue CapProdI(IntegerValue a, IntegerValue b)
Overflows and saturated arithmetic.
Definition integer.h:105
double ToDouble(IntegerValue value)
Definition integer.h:73
IntegerVariable CreateNewIntegerVariableFromLiteral(Literal lit, Model *model)
Definition integer.h:1925
In SWIG mode, we don't want anything besides these top-level includes.
bool AtMinOrMaxInt64(int64_t x)
Checks if x is equal to the min or the max value of an int64_t.
int64_t CapAdd(int64_t x, int64_t y)
static constexpr double kInfinity
int64_t CapSub(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
int64_t bound
#define DEFINE_STRONG_INT64_TYPE(integer_type_name)
#define DEFINE_STRONG_INDEX_TYPE(index_type_name)
IntegerLiteral GreaterOrEqual(IntegerValue bound) const
var * coeff + constant >= bound.
Definition integer.h:1696
bool operator==(AffineExpression o) const
Definition integer.h:325
AffineExpression MultipliedBy(IntegerValue multiplier) const
Definition integer.h:320
AffineExpression Negated() const
Definition integer.h:315
AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
Definition integer.h:304
AffineExpression()=default
Helper to construct an AffineExpression.
IntegerValue ValueAt(IntegerValue var_value) const
Returns the value of this affine expression given its variable value.
Definition integer.h:330
AffineExpression(IntegerVariable v, IntegerValue c)
Definition integer.h:302
double LpValue(const util_intops::StrongVector< IntegerVariable, double > &lp_values) const
Returns the affine expression value under a given LP solution.
Definition integer.h:335
IntegerLiteral LowerOrEqual(IntegerValue bound) const
var * coeff + constant <= bound.
Definition integer.h:1708
std::vector< int64_t > proto_values
Definition integer.h:385
util_intops::StrongVector< IntegerVariable, bool > ivar_has_value
Definition integer.h:394
util_intops::StrongVector< IntegerVariable, IntegerValue > ivar_values
Definition integer.h:395
std::vector< IntegerLiteral > integer_literal_to_fix
Definition integer.h:450
bool operator==(IntegerLiteral o) const
Definition integer.h:247
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
Definition integer.h:1667
static IntegerLiteral TrueLiteral()
Definition integer.h:1679
IntegerLiteral Negated() const
The negation of x >= bound is x <= bound - 1.
Definition integer.h:1687
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
Definition integer.h:1673
static IntegerLiteral FalseLiteral()
Definition integer.h:1683
IntegerLiteral(IntegerVariable v, IntegerValue b)
Definition integer.h:235
bool operator!=(IntegerLiteral o) const
Definition integer.h:250
IntegerLiteral()
Clients should prefer the static construction methods above.
Definition integer.h:234
bool operator==(const LiteralValueValue &rhs) const
Used for testing.
Definition integer.h:432
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
Definition integer.h:401
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
Definition integer.h:407
bool operator==(const ValueLiteralPair &o) const
Definition integer.h:414