14#ifndef OR_TOOLS_SAT_INTEGER_H_
15#define OR_TOOLS_SAT_INTEGER_H_
27#include "absl/base/attributes.h"
28#include "absl/container/flat_hash_map.h"
29#include "absl/container/inlined_vector.h"
30#include "absl/strings/str_cat.h"
31#include "absl/types/span.h"
72 const double kInfinity = std::numeric_limits<double>::infinity();
75 return static_cast<double>(
value.value());
78template <
class IntType>
80 return IntType(std::abs(t.value()));
84 IntegerValue positive_divisor) {
86 const IntegerValue result = dividend / positive_divisor;
87 const IntegerValue adjust =
88 static_cast<IntegerValue
>(result * positive_divisor < dividend);
89 return result + adjust;
93 IntegerValue positive_divisor) {
95 const IntegerValue result = dividend / positive_divisor;
96 const IntegerValue adjust =
97 static_cast<IntegerValue
>(result * positive_divisor > dividend);
98 return result - adjust;
108 IntegerValue positive_divisor) {
110 const IntegerValue m = dividend % positive_divisor;
111 return m < 0 ? m + positive_divisor : m;
116 const int64_t prod =
CapProd(
a.value(),
b.value());
120 const int64_t add =
CapAdd(prod, result->value());
124 *result = IntegerValue(add);
136 return IntegerVariable(i.value() ^ 1);
140 return (i.value() & 1) == 0;
144 return IntegerVariable(i.value() & (~1));
150 return PositiveOnlyIndex(
var.value() / 2);
154 IntegerValue coeff) {
156 return absl::StrCat(coeff.value(),
"*X",
var.value() / 2);
161 const std::vector<IntegerVariable>& vars);
206 ? absl::StrCat(
"I",
var.value() / 2,
">=",
bound.value())
207 : absl::StrCat(
"I",
var.value() / 2,
"<=", -
bound.value());
212 IntegerValue
bound = IntegerValue(0);
267 IntegerValue
ValueAt(IntegerValue var_value)
const {
281 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
")");
283 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
" + ",
293 IntegerValue
coeff = IntegerValue(0);
315 return a.literal <
b.literal;
321 return (
a.value <
b.value) ||
322 (
a.value ==
b.value &&
a.literal <
b.literal);
332 IntegerValue
value = IntegerValue(0);
361 num_created_variables_(0) {}
364 VLOG(1) <<
"#variables created = " << num_created_variables_;
402 IntegerVariable
var)
const;
450 IntegerValue
value)
const;
464 if (lit.
Index() >= reverse_encoding_.
size()) {
465 return empty_integer_literal_vector_;
467 return reverse_encoding_[lit.
Index()];
474 if (lit.
Index() >= full_reverse_encoding_.
size()) {
475 return empty_integer_literal_vector_;
477 return full_reverse_encoding_[lit.
Index()];
483 return newly_fixed_integer_literals_;
486 newly_fixed_integer_literals_.clear();
495 return literal_view_[lit.
Index()];
514 IntegerValue*
bound)
const;
522 literal_index_true_ = literal_true.
Index();
525 return Literal(literal_index_true_);
533 IntegerVariable
var)
const {
534 if (
var >= encoding_by_var_.size()) {
535 return std::map<IntegerValue, Literal>();
537 return encoding_by_var_[
var];
553 void AddImplications(
const std::map<IntegerValue, Literal>& map,
554 std::map<IntegerValue, Literal>::const_iterator it,
560 bool add_implications_ =
true;
561 int64_t num_created_variables_ = 0;
577 full_reverse_encoding_;
578 std::vector<IntegerLiteral> newly_fixed_integer_literals_;
590 absl::flat_hash_map<std::pair<PositiveOnlyIndex, IntegerValue>,
Literal>
591 equality_to_associated_literal_;
605 std::vector<IntegerValue> tmp_values_;
630 void Untrail(const
Trail& trail,
int literal_trail_index) final;
632 int trail_index) const final;
639 return IntegerVariable(vars_.
size());
699 const LiteralIndex is_ignored_literal = is_ignored_literals_[i];
705 return Literal(is_ignored_literals_[i]);
714 is_ignored_literals_[i] == is_considered.
NegatedIndex());
720 IntegerValue
LowerBound(IntegerVariable i)
const;
721 IntegerValue
UpperBound(IntegerVariable i)
const;
724 bool IsFixed(IntegerVariable i)
const;
727 IntegerValue
FixedValue(IntegerVariable i)
const;
790 absl::Span<const IntegerValue> coeffs,
791 std::vector<IntegerLiteral>* reason)
const;
795 absl::Span<const IntegerValue> coeffs,
796 absl::Span<const IntegerVariable> vars,
797 std::vector<IntegerLiteral>* reason)
const;
801 absl::Span<const IntegerValue> coeffs,
802 std::vector<int>* trail_indices)
const;
825 ABSL_MUST_USE_RESULT
bool Enqueue(
827 absl::Span<const IntegerLiteral> integer_reason);
839 IntegerLiteral i_lit, absl::Span<const IntegerLiteral> integer_reason);
849 std::vector<IntegerLiteral>* integer_reason);
858 ABSL_MUST_USE_RESULT
bool Enqueue(
860 absl::Span<const IntegerLiteral> integer_reason,
861 int trail_index_with_same_reason);
876 std::vector<Literal>* literals, std::vector<int>* dependencies)>;
883 absl::Span<const IntegerLiteral> integer_reason);
893 std::vector<Literal>* output)
const;
902 int64_t
timestamp()
const {
return num_enqueues_ + num_untrails_; }
912 watchers_.push_back(p);
918 absl::Span<const IntegerLiteral> integer_reason) {
919 DCHECK(ReasonIsValid(literal_reason, integer_reason));
921 conflict->assign(literal_reason.begin(), literal_reason.end());
926 DCHECK(ReasonIsValid({}, integer_reason));
935 return vars_[
var].current_trail_index < vars_.
size();
941 reversible_classes_.push_back(rev);
944 int Index()
const {
return integer_trail_.size(); }
972 return !literal_to_fix_.empty() || !integer_literal_to_fix_.empty();
978 bool ReasonIsValid(absl::Span<const Literal> literal_reason,
979 absl::Span<const IntegerLiteral> integer_reason);
984 std::vector<Literal>* InitializeConflict(
986 absl::Span<const Literal> literals_reason,
987 absl::Span<const IntegerLiteral> bounds_reason);
990 ABSL_MUST_USE_RESULT
bool EnqueueInternal(
992 absl::Span<const Literal> literal_reason,
993 absl::Span<const IntegerLiteral> integer_reason,
994 int trail_index_with_same_reason);
998 absl::Span<const Literal> literal_reason,
999 absl::Span<const IntegerLiteral> integer_reason);
1004 ABSL_MUST_USE_RESULT
bool EnqueueAssociatedIntegerLiteral(
1008 void MergeReasonIntoInternal(std::vector<Literal>* output)
const;
1013 int FindLowestTrailIndexThatExplainBound(
IntegerLiteral i_lit)
const;
1018 void ComputeLazyReasonIfNeeded(
int trail_index)
const;
1025 absl::Span<const int> Dependencies(
int trail_index)
const;
1031 void AppendLiteralsReason(
int trail_index,
1032 std::vector<Literal>* output)
const;
1035 std::string DebugString();
1040 IntegerValue current_bound;
1043 int current_trail_index;
1053 mutable int var_trail_index_cache_threshold_ = 0;
1058 absl::flat_hash_map<IntegerValue, IntegerVariable> constant_map_;
1064 IntegerVariable
var;
1065 int32_t prev_trail_index;
1070 int32_t reason_index;
1072 std::vector<TrailEntry> integer_trail_;
1073 std::vector<LazyReasonFunction> lazy_reasons_;
1077 std::vector<int> integer_search_levels_;
1084 std::vector<int> reason_decision_levels_;
1085 std::vector<int> literals_reason_starts_;
1086 std::vector<int> bounds_reason_starts_;
1087 std::vector<Literal> literals_reason_buffer_;
1092 std::vector<IntegerLiteral> bounds_reason_buffer_;
1093 mutable std::vector<int> trail_index_reason_buffer_;
1096 mutable std::vector<Literal> lazy_reason_literals_;
1097 mutable std::vector<int> lazy_reason_trail_indices_;
1108 RevMap<absl::flat_hash_map<IntegerVariable, int>>
1109 var_to_current_lb_interval_index_;
1112 mutable bool has_dependency_ =
false;
1113 mutable std::vector<int> tmp_queue_;
1114 mutable std::vector<IntegerVariable> tmp_to_clear_;
1116 tmp_var_to_trail_index_in_queue_;
1117 mutable SparseBitset<BooleanVariable> added_variables_;
1124 std::vector<Literal> literal_to_fix_;
1125 std::vector<IntegerLiteral> integer_literal_to_fix_;
1128 struct RelaxHeapEntry {
1132 bool operator<(
const RelaxHeapEntry& o)
const {
return index < o.index; }
1134 mutable std::vector<RelaxHeapEntry> relax_heap_;
1135 mutable std::vector<int> tmp_indices_;
1138 mutable SparseBitset<IntegerVariable> tmp_marked_;
1144 std::vector<int> boolean_trail_index_to_integer_one_;
1148 int first_level_without_full_propagation_ = -1;
1150 int64_t num_enqueues_ = 0;
1151 int64_t num_untrails_ = 0;
1152 int64_t num_level_zero_enqueues_ = 0;
1153 mutable int64_t num_decisions_to_break_loop_ = 0;
1155 std::vector<SparseBitset<IntegerVariable>*> watchers_;
1156 std::vector<ReversibleInterface*> reversible_classes_;
1158 IntegerDomains* domains_;
1159 IntegerEncoder* encoder_;
1161 const SatParameters& parameters_;
1166 absl::flat_hash_map<std::pair<LiteralIndex, IntegerVariable>, IntegerValue>
1230 void Untrail(
const Trail& trail,
int literal_trail_index)
final;
1316 const std::function<
void(
const std::vector<IntegerVariable>&)> cb) {
1317 level_zero_modified_variable_callback_.push_back(cb);
1328 void UpdateCallingNeeds(
Trail* trail);
1338 return id == o.id && watch_index == o.watch_index;
1343 std::vector<PropagatorInterface*> watchers_;
1344 SparseBitset<IntegerVariable> modified_vars_;
1348 std::vector<std::deque<int>> queue_by_priority_;
1349 std::vector<bool> in_queue_;
1352 DEFINE_INT_TYPE(IdType, int32_t);
1353 std::vector<int> id_to_level_at_last_call_;
1354 RevVector<IdType, int> id_to_greatest_common_level_since_last_call_;
1355 std::vector<std::vector<ReversibleInterface*>> id_to_reversible_classes_;
1356 std::vector<std::vector<int*>> id_to_reversible_ints_;
1357 std::vector<std::vector<int>> id_to_watch_indices_;
1358 std::vector<int> id_to_priority_;
1359 std::vector<int> id_to_idempotence_;
1362 std::vector<int> propagator_ids_to_call_at_level_zero_;
1367 std::vector<std::function<void(
const std::vector<IntegerVariable>&)>>
1368 level_zero_modified_variable_callback_;
1378 IntegerValue
bound) {
1384 IntegerValue
bound) {
1407 IntegerValue
bound)
const {
1436 return vars_[i].current_bound;
1444 return vars_[i].current_bound == -vars_[
NegationOf(i)].current_bound;
1449 return vars_[i].current_bound;
1453 Literal l, IntegerVariable i)
const {
1454 const auto it = conditional_lbs_.find({l.
Index(), i});
1455 if (it != conditional_lbs_.end()) {
1456 return std::max(vars_[i].current_bound, it->second);
1458 return vars_[i].current_bound;
1468 IntegerVariable i)
const {
1473 IntegerVariable i)
const {
1520 IntegerVariable
var)
const {
1521 return integer_trail_[
var.value()].bound;
1525 IntegerVariable
var)
const {
1530 return integer_trail_[
var.value()].bound ==
1553 if (l.
Index() >= literal_to_watcher_.
size()) {
1554 literal_to_watcher_.
resize(l.
Index().value() + 1);
1562 if (
var.value() >= var_to_watcher_.
size()) {
1563 var_to_watcher_.
resize(
var.value() + 1);
1570 const WatchData data = {id, watch_index};
1571 if (!var_to_watcher_[
var].empty() && var_to_watcher_[
var].back() == data) {
1608 ->GetOrCreateConstantIntegerVariable(IntegerValue(
value));
1617 IntegerValue(lb), IntegerValue(ub));
1637 IntegerVariable
var;
1639 if (assignment.LiteralIsTrue(lit)) {
1641 }
else if (assignment.LiteralIsFalse(lit)) {
1647 encoder->AssociateToIntegerEqualValue(lit,
var, IntegerValue(1));
1673inline std::function<int64_t(
const Model&)>
Value(IntegerVariable v) {
1686 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1688 VLOG(1) <<
"Model trivially infeasible, variable " << v
1690 <<
" and GreaterOrEqual() was called with a lower bound of "
1700 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1702 LOG(
WARNING) <<
"Model trivially infeasible, variable " << v
1704 <<
" and LowerOrEqual() was called with an upper bound of "
1725 const std::vector<Literal>& enforcement_literals,
IntegerLiteral i) {
1732 std::vector<Literal> clause;
1753 int64_t lb, int64_t ub) {
1759 v, IntegerValue(lb))));
1774 IntegerVariable
var) {
1789std::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)
std::map< IntegerValue, Literal > PartialGreaterThanEncoding(IntegerVariable var) const
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()
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)
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)
const LiteralIndex kNoLiteralIndex(-1)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue)
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)
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)
DEFINE_INT_TYPE(ClauseIndex, int)
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