14#ifndef OR_TOOLS_SAT_INTEGER_H_
15#define OR_TOOLS_SAT_INTEGER_H_
29#include "absl/base/attributes.h"
30#include "absl/container/btree_map.h"
31#include "absl/container/flat_hash_map.h"
32#include "absl/container/inlined_vector.h"
33#include "absl/strings/str_cat.h"
34#include "absl/strings/string_view.h"
35#include "absl/types/span.h"
45#include "ortools/sat/sat_parameters.pb.h"
78 const double kInfinity = std::numeric_limits<double>::infinity();
81 return static_cast<double>(
value.value());
84template <
class IntType>
86 return IntType(std::abs(t.value()));
90 IntegerValue positive_divisor) {
92 const IntegerValue result = dividend / positive_divisor;
93 const IntegerValue adjust =
94 static_cast<IntegerValue
>(result * positive_divisor < dividend);
95 return result + adjust;
99 IntegerValue positive_divisor) {
101 const IntegerValue result = dividend / positive_divisor;
102 const IntegerValue adjust =
103 static_cast<IntegerValue
>(result * positive_divisor > dividend);
104 return result - adjust;
114 IntegerValue positive_divisor) {
116 const IntegerValue m = dividend % positive_divisor;
117 return m < 0 ? m + positive_divisor : m;
122 const int64_t prod =
CapProd(
a.value(),
b.value());
126 const int64_t add =
CapAdd(prod, result->value());
130 *result = IntegerValue(add);
142 return IntegerVariable(i.value() ^ 1);
146 return (i.value() & 1) == 0;
150 return IntegerVariable(i.value() & (~1));
156 return PositiveOnlyIndex(
var.value() / 2);
160 IntegerValue
coeff) {
162 return absl::StrCat(
coeff.value(),
"*X",
var.value() / 2);
167 const std::vector<IntegerVariable>& vars);
212 ? absl::StrCat(
"I",
var.value() / 2,
">=",
bound.value())
213 : absl::StrCat(
"I",
var.value() / 2,
"<=", -
bound.value());
218 IntegerValue
bound = IntegerValue(0);
273 IntegerValue
ValueAt(IntegerValue var_value)
const {
287 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
")");
289 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
" + ",
299 IntegerValue
coeff = IntegerValue(0);
321 return a.literal <
b.literal;
327 return (
a.value <
b.value) ||
328 (
a.value ==
b.value &&
a.literal <
b.literal);
338 IntegerValue
value = IntegerValue(0);
367 num_created_variables_(0) {}
370 VLOG(1) <<
"#variables created = " << num_created_variables_;
408 IntegerVariable
var)
const;
456 IntegerValue
value)
const;
470 if (lit.
Index() >= reverse_encoding_.
size()) {
471 return empty_integer_literal_vector_;
473 return reverse_encoding_[lit.
Index()];
480 if (lit.
Index() >= full_reverse_encoding_.
size()) {
481 return empty_integer_literal_vector_;
483 return full_reverse_encoding_[lit.
Index()];
489 return newly_fixed_integer_literals_;
492 newly_fixed_integer_literals_.clear();
501 return literal_view_[lit.
Index()];
520 IntegerValue*
bound)
const;
528 literal_index_true_ = literal_true.
Index();
531 return Literal(literal_index_true_);
539 IntegerVariable
var)
const {
540 if (
var >= encoding_by_var_.size()) {
541 return absl::btree_map<IntegerValue, Literal>();
543 return encoding_by_var_[
var];
559 void AddImplications(
560 const absl::btree_map<IntegerValue, Literal>& map,
561 absl::btree_map<IntegerValue, Literal>::const_iterator it,
567 bool add_implications_ =
true;
568 int64_t num_created_variables_ = 0;
584 full_reverse_encoding_;
585 std::vector<IntegerLiteral> newly_fixed_integer_literals_;
597 absl::flat_hash_map<std::pair<PositiveOnlyIndex, IntegerValue>,
Literal>
598 equality_to_associated_literal_;
612 std::vector<IntegerValue> tmp_values_;
627 parameters_(*
model->GetOrCreate<SatParameters>()) {
637 void Untrail(const
Trail& trail,
int literal_trail_index) final;
639 int trail_index) const final;
646 return IntegerVariable(vars_.
size());
706 const LiteralIndex is_ignored_literal = is_ignored_literals_[i];
712 return Literal(is_ignored_literals_[i]);
721 is_ignored_literals_[i] == is_considered.
NegatedIndex());
727 IntegerValue
LowerBound(IntegerVariable i)
const;
728 IntegerValue
UpperBound(IntegerVariable i)
const;
731 bool IsFixed(IntegerVariable i)
const;
734 IntegerValue
FixedValue(IntegerVariable i)
const;
797 absl::Span<const IntegerValue> coeffs,
798 std::vector<IntegerLiteral>* reason)
const;
802 absl::Span<const IntegerValue> coeffs,
803 absl::Span<const IntegerVariable> vars,
804 std::vector<IntegerLiteral>* reason)
const;
808 absl::Span<const IntegerValue> coeffs,
809 std::vector<int>* trail_indices)
const;
832 ABSL_MUST_USE_RESULT
bool Enqueue(
834 absl::Span<const IntegerLiteral> integer_reason);
846 IntegerLiteral i_lit, absl::Span<const IntegerLiteral> integer_reason);
856 std::vector<IntegerLiteral>* integer_reason);
865 ABSL_MUST_USE_RESULT
bool Enqueue(
867 absl::Span<const IntegerLiteral> integer_reason,
868 int trail_index_with_same_reason);
883 std::vector<Literal>* literals, std::vector<int>* dependencies)>;
890 absl::Span<const IntegerLiteral> integer_reason);
900 std::vector<Literal>* output)
const;
909 int64_t
timestamp()
const {
return num_enqueues_ + num_untrails_; }
919 watchers_.push_back(p);
925 absl::Span<const IntegerLiteral> integer_reason) {
926 DCHECK(ReasonIsValid(literal_reason, integer_reason));
928 conflict->assign(literal_reason.begin(), literal_reason.end());
933 DCHECK(ReasonIsValid({}, integer_reason));
942 return vars_[
var].current_trail_index < vars_.
size();
948 reversible_classes_.push_back(rev);
951 int Index()
const {
return integer_trail_.size(); }
979 return !literal_to_fix_.empty() || !integer_literal_to_fix_.empty();
985 bool ReasonIsValid(absl::Span<const Literal> literal_reason,
986 absl::Span<const IntegerLiteral> integer_reason);
991 std::vector<Literal>* InitializeConflict(
993 absl::Span<const Literal> literals_reason,
994 absl::Span<const IntegerLiteral> bounds_reason);
997 ABSL_MUST_USE_RESULT
bool EnqueueInternal(
999 absl::Span<const Literal> literal_reason,
1000 absl::Span<const IntegerLiteral> integer_reason,
1001 int trail_index_with_same_reason);
1005 absl::Span<const Literal> literal_reason,
1006 absl::Span<const IntegerLiteral> integer_reason);
1011 ABSL_MUST_USE_RESULT
bool EnqueueAssociatedIntegerLiteral(
1015 void MergeReasonIntoInternal(std::vector<Literal>* output)
const;
1020 int FindLowestTrailIndexThatExplainBound(
IntegerLiteral i_lit)
const;
1025 void ComputeLazyReasonIfNeeded(
int trail_index)
const;
1032 absl::Span<const int> Dependencies(
int trail_index)
const;
1038 void AppendLiteralsReason(
int trail_index,
1039 std::vector<Literal>* output)
const;
1042 std::string DebugString();
1047 IntegerValue current_bound;
1050 int current_trail_index;
1060 mutable int var_trail_index_cache_threshold_ = 0;
1065 absl::flat_hash_map<IntegerValue, IntegerVariable> constant_map_;
1071 IntegerVariable
var;
1072 int32_t prev_trail_index;
1077 int32_t reason_index;
1079 std::vector<TrailEntry> integer_trail_;
1080 std::vector<LazyReasonFunction> lazy_reasons_;
1084 std::vector<int> integer_search_levels_;
1091 std::vector<int> reason_decision_levels_;
1092 std::vector<int> literals_reason_starts_;
1093 std::vector<int> bounds_reason_starts_;
1094 std::vector<Literal> literals_reason_buffer_;
1099 std::vector<IntegerLiteral> bounds_reason_buffer_;
1100 mutable std::vector<int> trail_index_reason_buffer_;
1103 mutable std::vector<Literal> lazy_reason_literals_;
1104 mutable std::vector<int> lazy_reason_trail_indices_;
1115 RevMap<absl::flat_hash_map<IntegerVariable, int>>
1116 var_to_current_lb_interval_index_;
1119 mutable bool has_dependency_ =
false;
1120 mutable std::vector<int> tmp_queue_;
1121 mutable std::vector<IntegerVariable> tmp_to_clear_;
1123 tmp_var_to_trail_index_in_queue_;
1124 mutable SparseBitset<BooleanVariable> added_variables_;
1131 std::vector<Literal> literal_to_fix_;
1132 std::vector<IntegerLiteral> integer_literal_to_fix_;
1135 struct RelaxHeapEntry {
1139 bool operator<(
const RelaxHeapEntry& o)
const {
return index < o.index; }
1141 mutable std::vector<RelaxHeapEntry> relax_heap_;
1142 mutable std::vector<int> tmp_indices_;
1145 mutable SparseBitset<IntegerVariable> tmp_marked_;
1151 std::vector<int> boolean_trail_index_to_integer_one_;
1155 int first_level_without_full_propagation_ = -1;
1157 int64_t num_enqueues_ = 0;
1158 int64_t num_untrails_ = 0;
1159 int64_t num_level_zero_enqueues_ = 0;
1160 mutable int64_t num_decisions_to_break_loop_ = 0;
1162 std::vector<SparseBitset<IntegerVariable>*> watchers_;
1163 std::vector<ReversibleInterface*> reversible_classes_;
1165 IntegerDomains* domains_;
1166 IntegerEncoder* encoder_;
1168 const SatParameters& parameters_;
1173 absl::flat_hash_map<std::pair<LiteralIndex, IntegerVariable>, IntegerValue>
1237 void Untrail(
const Trail& trail,
int literal_trail_index)
final;
1323 const std::function<
void(
const std::vector<IntegerVariable>&)> cb) {
1324 level_zero_modified_variable_callback_.push_back(cb);
1335 void UpdateCallingNeeds(
Trail* trail);
1345 return id == o.id && watch_index == o.watch_index;
1350 std::vector<PropagatorInterface*> watchers_;
1351 SparseBitset<IntegerVariable> modified_vars_;
1354 SparseBitset<IntegerVariable> modified_vars_for_callback_;
1358 std::vector<std::deque<int>> queue_by_priority_;
1359 std::vector<bool> in_queue_;
1362 DEFINE_STRONG_INDEX_TYPE(IdType);
1363 std::vector<int> id_to_level_at_last_call_;
1364 RevVector<IdType, int> id_to_greatest_common_level_since_last_call_;
1365 std::vector<std::vector<ReversibleInterface*>> id_to_reversible_classes_;
1366 std::vector<std::vector<int*>> id_to_reversible_ints_;
1367 std::vector<std::vector<int>> id_to_watch_indices_;
1368 std::vector<int> id_to_priority_;
1369 std::vector<int> id_to_idempotence_;
1372 std::vector<int> propagator_ids_to_call_at_level_zero_;
1377 std::vector<std::function<void(
const std::vector<IntegerVariable>&)>>
1378 level_zero_modified_variable_callback_;
1388 IntegerValue
bound) {
1394 IntegerValue
bound) {
1417 IntegerValue
bound)
const {
1446 return vars_[i].current_bound;
1454 return vars_[i].current_bound == -vars_[
NegationOf(i)].current_bound;
1459 return vars_[i].current_bound;
1463 Literal l, IntegerVariable i)
const {
1464 const auto it = conditional_lbs_.find({l.
Index(), i});
1465 if (it != conditional_lbs_.end()) {
1466 return std::max(vars_[i].current_bound, it->second);
1468 return vars_[i].current_bound;
1478 IntegerVariable i)
const {
1483 IntegerVariable i)
const {
1530 IntegerVariable
var)
const {
1531 return integer_trail_[
var.value()].bound;
1535 IntegerVariable
var)
const {
1540 return integer_trail_[
var.value()].bound ==
1563 if (l.
Index() >= literal_to_watcher_.
size()) {
1564 literal_to_watcher_.
resize(l.
Index().value() + 1);
1572 if (
var.value() >= var_to_watcher_.
size()) {
1573 var_to_watcher_.
resize(
var.value() + 1);
1580 const WatchData data = {id, watch_index};
1581 if (!var_to_watcher_[
var].empty() && var_to_watcher_[
var].back() == data) {
1618 ->GetOrCreateConstantIntegerVariable(IntegerValue(
value));
1627 IntegerValue(lb), IntegerValue(ub));
1647 IntegerVariable
var;
1649 if (assignment.LiteralIsTrue(lit)) {
1651 }
else if (assignment.LiteralIsFalse(lit)) {
1657 encoder->AssociateToIntegerEqualValue(lit,
var, IntegerValue(1));
1683inline std::function<int64_t(
const Model&)>
Value(IntegerVariable v) {
1696 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1698 VLOG(1) <<
"Model trivially infeasible, variable " << v
1700 <<
" and GreaterOrEqual() was called with a lower bound of "
1710 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1712 LOG(
WARNING) <<
"Model trivially infeasible, variable " << v
1714 <<
" and LowerOrEqual() was called with an upper bound of "
1735 const std::vector<Literal>& enforcement_literals,
IntegerLiteral i) {
1742 std::vector<Literal> clause;
1763 int64_t lb, int64_t ub) {
1769 v, IntegerValue(lb))));
1784 IntegerVariable
var) {
1799std::function<void(Model*)>
#define DCHECK_LE(val1, val2)
#define DCHECK_NE(val1, val2)
#define CHECK_EQ(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2)
#define DCHECK(condition)
#define CHECK_LE(val1, val2)
#define DCHECK_EQ(val1, val2)
#define VLOG(verboselevel)
void resize(size_type new_size)
void push_back(const value_type &x)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
We call domain any subset of Int64 = [kint64min, kint64max].
void ClearAndResize(IntegerType size)
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
bool Propagate(Trail *trail) final
void WatchLowerBound(IntegerValue i, int id)
void AlwaysCallAtLevelZero(int id)
void RegisterLevelZeroModifiedVariablesCallback(const std::function< void(const std::vector< IntegerVariable > &)> cb)
void WatchIntegerVariable(IntegerValue v, int id)
int NumPropagators() const
void WatchLowerBound(AffineExpression e, int id)
void WatchUpperBound(AffineExpression e, int id)
void RegisterReversibleInt(int id, int *rev)
void RegisterReversibleClass(int id, ReversibleInterface *rev)
void WatchLiteral(Literal l, int id, int watch_index=-1)
void WatchUpperBound(IntegerValue i, int id)
void WatchLowerBound(IntegerVariable var, int id, int watch_index=-1)
GenericLiteralWatcher(Model *model)
void WatchIntegerVariable(IntegerVariable i, int id, int watch_index=-1)
void WatchAffineExpression(AffineExpression e, int id)
~GenericLiteralWatcher() final
void WatchUpperBound(IntegerVariable var, int id, int watch_index=-1)
void SetPropagatorPriority(int id, int priority)
int Register(PropagatorInterface *propagator)
void NotifyThatPropagatorMayNotReachFixedPointInOnePass(int id)
void Untrail(const Trail &trail, int literal_trail_index) final
Literal GetOrCreateLiteralAssociatedToEquality(IntegerVariable var, IntegerValue value)
LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i, IntegerValue *bound) const
const std::vector< IntegerLiteral > NewlyFixedIntegerLiterals() const
LiteralIndex GetAssociatedLiteral(IntegerLiteral i_lit) const
void FullyEncodeVariable(IntegerVariable var)
Literal GetFalseLiteral()
const IntegerVariable GetLiteralView(Literal lit) const
const InlinedIntegerLiteralVector & GetAllIntegerLiterals(Literal lit) const
std::pair< IntegerLiteral, IntegerLiteral > Canonicalize(IntegerLiteral i_lit) const
void DisableImplicationBetweenLiteral()
void ClearNewlyFixedIntegerLiterals()
void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var, IntegerValue value)
std::vector< ValueLiteralPair > PartialDomainEncoding(IntegerVariable var) const
bool LiteralIsAssociated(IntegerLiteral i_lit) const
std::vector< ValueLiteralPair > FullDomainEncoding(IntegerVariable var) const
const bool LiteralOrNegationHasView(Literal lit) const
void AddAllImplicationsBetweenAssociatedLiterals()
absl::btree_map< IntegerValue, Literal > PartialGreaterThanEncoding(IntegerVariable var) const
bool VariableIsFullyEncoded(IntegerVariable var) const
const InlinedIntegerLiteralVector & GetIntegerLiterals(Literal lit) const
IntegerEncoder(Model *model)
std::vector< ValueLiteralPair > RawDomainEncoding(IntegerVariable var) const
LiteralIndex GetAssociatedEqualityLiteral(IntegerVariable var, IntegerValue value) const
void AssociateToIntegerLiteral(Literal literal, IntegerLiteral i_lit)
Literal GetOrCreateAssociatedLiteral(IntegerLiteral i_lit)
IntegerVariable FirstUnassignedVariable() const
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value)
int64_t num_enqueues() const
void RegisterWatcher(SparseBitset< IntegerVariable > *p)
bool Propagate(Trail *trail) final
void ReserveSpaceForNumVariables(int num_vars)
int FindTrailIndexOfVarBefore(IntegerVariable var, int threshold) const
bool IsCurrentlyIgnored(IntegerVariable i) const
std::vector< Literal > ReasonFor(IntegerLiteral literal) const
bool ReportConflict(absl::Span< const IntegerLiteral > integer_reason)
std::function< void(IntegerLiteral literal_to_explain, int trail_index_of_literal, std::vector< Literal > *literals, std::vector< int > *dependencies)> LazyReasonFunction
int64_t num_level_zero_enqueues() const
bool IsFixed(IntegerVariable i) const
LiteralIndex OptionalLiteralIndex(IntegerVariable i) const
absl::Span< const Literal > Reason(const Trail &trail, int trail_index) const final
IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const
bool CurrentBranchHadAnIncompletePropagation()
bool InPropagationLoop() const
bool ReportConflict(absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
void EnqueueLiteral(Literal literal, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
IntegerVariable NextVariableToBranchOnInPropagationLoop() const
IntegerValue UpperBound(IntegerVariable i) const
void MarkIntegerVariableAsOptional(IntegerVariable i, Literal is_considered)
ABSL_MUST_USE_RESULT bool SafeEnqueue(IntegerLiteral i_lit, absl::Span< const IntegerLiteral > integer_reason)
IntegerValue LevelZeroUpperBound(IntegerVariable var) const
IntegerValue ConditionalLowerBound(Literal l, IntegerVariable i) const
IntegerValue FixedValue(IntegerVariable i) const
bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const
void AppendRelaxedLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, absl::Span< const IntegerVariable > vars, std::vector< IntegerLiteral > *reason) const
IntegerValue LevelZeroLowerBound(IntegerVariable var) const
void RelaxLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, std::vector< IntegerLiteral > *reason) const
void AppendNewBounds(std::vector< IntegerLiteral > *output) const
bool IntegerLiteralIsTrue(IntegerLiteral l) const
IntegerValue LowerBound(IntegerVariable i) const
IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const
bool HasPendingRootLevelDeduction() const
int NumConstantVariables() const
bool IsFixedAtLevelZero(IntegerVariable var) const
void MergeReasonInto(absl::Span< const IntegerLiteral > literals, std::vector< Literal > *output) const
Literal IsIgnoredLiteral(IntegerVariable i) const
bool IsOptional(IntegerVariable i) const
ABSL_MUST_USE_RESULT bool ConditionalEnqueue(Literal lit, IntegerLiteral i_lit, std::vector< Literal > *literal_reason, std::vector< IntegerLiteral > *integer_reason)
int64_t timestamp() const
bool IntegerLiteralIsFalse(IntegerLiteral l) const
void RemoveLevelZeroBounds(std::vector< IntegerLiteral > *reason) const
IntegerVariable AddIntegerVariable()
void RegisterReversibleClass(ReversibleInterface *rev)
const Domain & InitialVariableDomain(IntegerVariable var) const
void Untrail(const Trail &trail, int literal_trail_index) final
IntegerVariable NumIntegerVariables() const
bool UpdateInitialDomain(IntegerVariable var, Domain domain)
IntegerTrail(Model *model)
LiteralIndex NegatedIndex() const
LiteralIndex Index() const
Class that owns everything related to a particular optimization model.
virtual ~PropagatorInterface()
virtual bool Propagate()=0
virtual bool IncrementalPropagate(const std::vector< int > &watch_indices)
RevIntRepository(Model *model)
RevIntegerValueRepository(Model *model)
BooleanVariable NewBooleanVariable()
int CurrentDecisionLevel() const
bool AddUnitClause(Literal true_literal)
const VariablesAssignment & Assignment() const
std::vector< Literal > * MutableConflict()
bool LiteralIsTrue(Literal literal) const
absl::InlinedVector< IntegerLiteral, 2 > InlinedIntegerLiteralVector
std::function< std::vector< ValueLiteralPair >(Model *)> FullyEncodeVariable(IntegerVariable var)
std::function< IntegerVariable(Model *)> NewIntegerVariableFromLiteral(Literal lit)
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
DEFINE_STRONG_INDEX_TYPE(ClauseIndex)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
std::function< void(Model *)> Equality(IntegerVariable v, int64_t value)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
IntType IntTypeAbs(IntType t)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
DEFINE_STRONG_INT64_TYPE(IntegerValue)
const LiteralIndex kNoLiteralIndex(-1)
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
std::function< BooleanVariable(Model *)> NewBooleanVariable()
std::function< void(Model *)> LowerOrEqual(IntegerVariable v, int64_t ub)
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
std::function< bool(const Model &)> IsFixed(IntegerVariable v)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
std::function< IntegerVariable(Model *)> ConstantIntegerVariable(int64_t value)
std::function< void(Model *)> Implication(const std::vector< Literal > &enforcement_literals, IntegerLiteral i)
IntegerVariable PositiveVariable(IntegerVariable i)
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
std::function< void(Model *)> ExcludeCurrentSolutionWithoutIgnoredVariableAndBacktrack()
std::function< IntegerVariable(Model *)> NewIntegerVariable(int64_t lb, int64_t ub)
std::function< void(Model *)> GreaterOrEqual(IntegerVariable v, int64_t lb)
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
std::function< void(Model *)> ImpliesInInterval(Literal in_interval, IntegerVariable v, int64_t lb, int64_t ub)
bool VariableIsPositive(IntegerVariable i)
double ToDouble(IntegerValue value)
Collection of objects used to extend the Constraint Solver library.
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
LinearRange operator==(const LinearExpr &lhs, const LinearExpr &rhs)
AffineExpression Negated() const
AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
AffineExpression(IntegerValue cst)
IntegerLiteral GreaterOrEqual(IntegerValue bound) const
IntegerValue ValueAt(IntegerValue var_value) const
IntegerLiteral LowerOrEqual(IntegerValue bound) const
double LpValue(const absl::StrongVector< IntegerVariable, double > &lp_values) const
AffineExpression(IntegerVariable v, IntegerValue c)
const std::string DebugString() const
bool operator==(AffineExpression o) const
AffineExpression MultipliedBy(IntegerValue multiplier) const
AffineExpression(IntegerVariable v)
DebugSolution(Model *model)
IntegerDomains(Model *model)
bool operator==(IntegerLiteral o) const
IntegerLiteral(IntegerVariable v, IntegerValue b)
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
static IntegerLiteral TrueLiteral()
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
std::string DebugString() const
bool IsTrueLiteral() const
bool IsFalseLiteral() const
IntegerLiteral Negated() const
bool operator!=(IntegerLiteral o) const
static IntegerLiteral FalseLiteral()
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
bool operator==(const ValueLiteralPair &o) const
std::string DebugString() const