14 #ifndef OR_TOOLS_SAT_INTEGER_H_
15 #define OR_TOOLS_SAT_INTEGER_H_
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/strings/str_cat.h"
35 #include "absl/strings/string_view.h"
36 #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());
84 template <
class IntType>
86 return IntType(std::abs(t.value()));
89 inline IntegerValue
CeilRatio(IntegerValue dividend,
90 IntegerValue positive_divisor) {
91 DCHECK_GT(positive_divisor, 0);
92 const IntegerValue result = dividend / positive_divisor;
93 const IntegerValue adjust =
94 static_cast<IntegerValue
>(result * positive_divisor < dividend);
95 return result + adjust;
99 IntegerValue positive_divisor) {
100 DCHECK_GT(positive_divisor, 0);
101 const IntegerValue result = dividend / positive_divisor;
102 const IntegerValue adjust =
103 static_cast<IntegerValue
>(result * positive_divisor > dividend);
104 return result - adjust;
114 IntegerValue positive_divisor) {
115 DCHECK_GT(positive_divisor, 0);
116 const IntegerValue m = dividend % positive_divisor;
117 return m < 0 ? m + positive_divisor : m;
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);
227 absl::Span<const IntegerLiteral> literals) {
244 absl::InlinedVector<std::pair<IntegerVariable, IntegerValue>, 2>;
291 IntegerValue
ValueAt(IntegerValue var_value)
const {
307 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
")");
309 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
" + ",
319 IntegerValue
coeff = IntegerValue(0);
352 return a.literal <
b.literal;
358 return (
a.value <
b.value) ||
359 (
a.value ==
b.value &&
a.literal <
b.literal);
369 IntegerValue
value = IntegerValue(0);
387 return absl::StrCat(
"(lit(",
literal.
Index().value(),
") * ",
427 num_created_variables_(0) {}
430 VLOG(1) <<
"#variables created = " << num_created_variables_;
468 IntegerVariable
var)
const;
511 IntegerValue
value)
const;
525 if (lit.
Index() >= reverse_encoding_.
size()) {
526 return empty_integer_literal_vector_;
528 return reverse_encoding_[lit.
Index()];
534 if (lit.
Index() >= reverse_equality_encoding_.
size()) {
535 return empty_integer_value_vector_;
537 return reverse_equality_encoding_[lit.
Index()];
544 temp_associated_vars_.clear();
546 temp_associated_vars_.push_back(l.var);
549 temp_associated_vars_.push_back(
var);
551 return temp_associated_vars_;
560 return literal_view_[lit.
Index()];
566 Literal lit, IntegerVariable* view =
nullptr,
567 bool* view_is_direct =
nullptr)
const;
578 IntegerValue*
bound)
const;
586 literal_index_true_ = literal_true.
Index();
589 return Literal(literal_index_true_);
597 IntegerVariable
var)
const;
611 void AddImplications(
612 const absl::btree_map<IntegerValue, Literal>& map,
613 absl::btree_map<IntegerValue, Literal>::const_iterator it,
621 bool add_implications_ =
true;
622 int64_t num_created_variables_ = 0;
648 reverse_equality_encoding_;
651 mutable std::vector<IntegerVariable> temp_associated_vars_;
663 absl::flat_hash_map<std::pair<PositiveOnlyIndex, IntegerValue>,
Literal>
664 equality_to_associated_literal_;
668 absl::InlinedVector<ValueLiteralPair, 2>>
679 std::vector<IntegerValue> tmp_values_;
680 std::vector<ValueLiteralPair> tmp_encoding_;
697 parameters_(*
model->GetOrCreate<SatParameters>()) {
707 void Untrail(const
Trail& trail,
int literal_trail_index) final;
709 int trail_index) const final;
716 return IntegerVariable(vars_.
size());
776 const LiteralIndex is_ignored_literal = is_ignored_literals_[i];
782 return Literal(is_ignored_literals_[i]);
791 is_ignored_literals_[i] == is_considered.
NegatedIndex());
797 IntegerValue
LowerBound(IntegerVariable i)
const;
798 IntegerValue
UpperBound(IntegerVariable i)
const;
801 bool IsFixed(IntegerVariable i)
const;
804 IntegerValue
FixedValue(IntegerVariable i)
const;
867 absl::Span<const IntegerValue> coeffs,
868 std::vector<IntegerLiteral>* reason)
const;
872 absl::Span<const IntegerValue> coeffs,
873 absl::Span<const IntegerVariable> vars,
874 std::vector<IntegerLiteral>* reason)
const;
878 absl::Span<const IntegerValue> coeffs,
879 std::vector<int>* trail_indices)
const;
902 ABSL_MUST_USE_RESULT
bool Enqueue(
904 absl::Span<const IntegerLiteral> integer_reason);
916 IntegerLiteral i_lit, absl::Span<const IntegerLiteral> integer_reason);
926 std::vector<IntegerLiteral>* integer_reason);
935 ABSL_MUST_USE_RESULT
bool Enqueue(
937 absl::Span<const IntegerLiteral> integer_reason,
938 int trail_index_with_same_reason);
953 std::vector<Literal>* literals, std::vector<int>* dependencies)>;
969 absl::Span<const IntegerLiteral> integer_reason);
980 std::vector<Literal>* output)
const;
989 int64_t
timestamp()
const {
return num_enqueues_ + num_untrails_; }
999 watchers_.push_back(p);
1005 absl::Span<const IntegerLiteral> integer_reason) {
1006 DCHECK(ReasonIsValid(literal_reason, integer_reason));
1008 conflict->assign(literal_reason.begin(), literal_reason.end());
1013 DCHECK(ReasonIsValid({}, integer_reason));
1022 return vars_[
var].current_trail_index < vars_.
size();
1028 reversible_classes_.push_back(rev);
1031 int Index()
const {
return integer_trail_.size(); }
1067 std::function<
bool(absl::Span<const Literal> clause,
1068 absl::Span<const IntegerLiteral> integers)>
1070 debug_checker_ = std::move(checker);
1076 bool ReasonIsValid(absl::Span<const Literal> literal_reason,
1077 absl::Span<const IntegerLiteral> integer_reason);
1080 bool ReasonIsValid(
Literal lit, absl::Span<const Literal> literal_reason,
1081 absl::Span<const IntegerLiteral> integer_reason);
1083 absl::Span<const Literal> literal_reason,
1084 absl::Span<const IntegerLiteral> integer_reason);
1093 std::vector<Literal>* InitializeConflict(
1095 absl::Span<const Literal> literals_reason,
1096 absl::Span<const IntegerLiteral> bounds_reason);
1099 ABSL_MUST_USE_RESULT
bool EnqueueInternal(
1101 absl::Span<const Literal> literal_reason,
1102 absl::Span<const IntegerLiteral> integer_reason,
1103 int trail_index_with_same_reason);
1107 absl::Span<const Literal> literal_reason,
1108 absl::Span<const IntegerLiteral> integer_reason);
1113 ABSL_MUST_USE_RESULT
bool EnqueueAssociatedIntegerLiteral(
1117 void MergeReasonIntoInternal(std::vector<Literal>* output)
const;
1122 int FindLowestTrailIndexThatExplainBound(
IntegerLiteral i_lit)
const;
1127 void ComputeLazyReasonIfNeeded(
int trail_index)
const;
1134 absl::Span<const int> Dependencies(
int trail_index)
const;
1140 void AppendLiteralsReason(
int trail_index,
1141 std::vector<Literal>* output)
const;
1144 std::string DebugString();
1149 IntegerValue current_bound;
1152 int current_trail_index;
1162 mutable int var_trail_index_cache_threshold_ = 0;
1167 absl::flat_hash_map<IntegerValue, IntegerVariable> constant_map_;
1173 IntegerVariable
var;
1174 int32_t prev_trail_index;
1179 int32_t reason_index;
1181 std::vector<TrailEntry> integer_trail_;
1182 std::vector<LazyReasonFunction> lazy_reasons_;
1186 std::vector<int> integer_search_levels_;
1193 std::vector<int> reason_decision_levels_;
1194 std::vector<int> literals_reason_starts_;
1195 std::vector<int> bounds_reason_starts_;
1196 std::vector<Literal> literals_reason_buffer_;
1201 std::vector<IntegerLiteral> bounds_reason_buffer_;
1202 mutable std::vector<int> trail_index_reason_buffer_;
1205 mutable std::vector<Literal> lazy_reason_literals_;
1206 mutable std::vector<int> lazy_reason_trail_indices_;
1212 mutable bool has_dependency_ =
false;
1213 mutable std::vector<int> tmp_queue_;
1214 mutable std::vector<IntegerVariable> tmp_to_clear_;
1216 tmp_var_to_trail_index_in_queue_;
1217 mutable SparseBitset<BooleanVariable> added_variables_;
1220 struct RelaxHeapEntry {
1224 bool operator<(
const RelaxHeapEntry& o)
const {
return index < o.index; }
1226 mutable std::vector<RelaxHeapEntry> relax_heap_;
1227 mutable std::vector<int> tmp_indices_;
1230 mutable SparseBitset<IntegerVariable> tmp_marked_;
1233 std::vector<IntegerLiteral> tmp_cleaned_reason_;
1239 std::vector<int> boolean_trail_index_to_integer_one_;
1243 int first_level_without_full_propagation_ = -1;
1245 int64_t num_enqueues_ = 0;
1246 int64_t num_untrails_ = 0;
1247 int64_t num_level_zero_enqueues_ = 0;
1248 mutable int64_t num_decisions_to_break_loop_ = 0;
1250 std::vector<SparseBitset<IntegerVariable>*> watchers_;
1251 std::vector<ReversibleInterface*> reversible_classes_;
1253 mutable Domain temp_domain_;
1254 DelayedRootLevelDeduction* delayed_to_fix_;
1255 IntegerDomains* domains_;
1256 IntegerEncoder* encoder_;
1258 SatSolver* sat_solver_;
1259 const SatParameters& parameters_;
1264 absl::flat_hash_map<std::pair<LiteralIndex, IntegerVariable>, IntegerValue>
1267 std::function<bool(absl::Span<const Literal> clause,
1268 absl::Span<const IntegerLiteral> integers)>
1269 debug_checker_ =
nullptr;
1299 LOG(FATAL) <<
"Not implemented.";
1335 void Untrail(
const Trail& trail,
int literal_trail_index)
final;
1421 const std::function<
void(
const std::vector<IntegerVariable>&)> cb) {
1422 level_zero_modified_variable_callback_.push_back(cb);
1431 stop_propagation_callback_ =
callback;
1445 void UpdateCallingNeeds(
Trail* trail);
1455 return id == o.id && watch_index == o.watch_index;
1460 std::vector<PropagatorInterface*> watchers_;
1461 SparseBitset<IntegerVariable> modified_vars_;
1464 SparseBitset<IntegerVariable> modified_vars_for_callback_;
1468 std::vector<std::deque<int>> queue_by_priority_;
1469 std::vector<bool> in_queue_;
1472 DEFINE_STRONG_INDEX_TYPE(IdType);
1473 std::vector<int> id_to_level_at_last_call_;
1474 RevVector<IdType, int> id_to_greatest_common_level_since_last_call_;
1475 std::vector<std::vector<ReversibleInterface*>> id_to_reversible_classes_;
1476 std::vector<std::vector<int*>> id_to_reversible_ints_;
1477 std::vector<std::vector<int>> id_to_watch_indices_;
1478 std::vector<int> id_to_priority_;
1479 std::vector<int> id_to_idempotence_;
1482 std::vector<int> propagator_ids_to_call_at_level_zero_;
1487 std::vector<std::function<void(
const std::vector<IntegerVariable>&)>>
1488 level_zero_modified_variable_callback_;
1490 std::function<bool()> stop_propagation_callback_;
1500 IntegerValue
bound) {
1506 IntegerValue
bound) {
1529 IntegerValue
bound)
const {
1534 DCHECK_GT(
coeff, 0);
1549 DCHECK_GT(
coeff, 0);
1558 return vars_[i].current_bound;
1566 return vars_[i].current_bound == -vars_[
NegationOf(i)].current_bound;
1571 return vars_[i].current_bound;
1575 Literal l, IntegerVariable i)
const {
1576 const auto it = conditional_lbs_.find({l.
Index(), i});
1577 if (it != conditional_lbs_.end()) {
1578 return std::max(vars_[i].current_bound, it->second);
1580 return vars_[i].current_bound;
1590 IntegerVariable i)
const {
1595 IntegerVariable i)
const {
1642 IntegerVariable
var)
const {
1643 return integer_trail_[
var.value()].bound;
1647 IntegerVariable
var)
const {
1652 return integer_trail_[
var.value()].bound ==
1675 if (l.
Index() >= literal_to_watcher_.
size()) {
1676 literal_to_watcher_.
resize(l.
Index().value() + 1);
1684 if (
var.value() >= var_to_watcher_.
size()) {
1685 var_to_watcher_.
resize(
var.value() + 1);
1692 const WatchData data = {id, watch_index};
1693 if (!var_to_watcher_[
var].empty() && var_to_watcher_[
var].back() == data) {
1730 ->GetOrCreateConstantIntegerVariable(IntegerValue(
value));
1739 IntegerValue(lb), IntegerValue(ub));
1759 IntegerVariable
var;
1761 if (assignment.LiteralIsTrue(lit)) {
1763 }
else if (assignment.LiteralIsFalse(lit)) {
1769 encoder->AssociateToIntegerEqualValue(lit,
var, IntegerValue(1));
1795 inline std::function<int64_t(
const Model&)>
Value(IntegerVariable v) {
1808 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1810 VLOG(1) <<
"Model trivially infeasible, variable " << v
1812 <<
" and GreaterOrEqual() was called with a lower bound of "
1822 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1824 VLOG(1) <<
"Model trivially infeasible, variable " << v
1826 <<
" and LowerOrEqual() was called with an upper bound of " << ub;
1846 const std::vector<Literal>& enforcement_literals,
IntegerLiteral i) {
1853 std::vector<Literal> clause;
1874 int64_t lb, int64_t ub) {
1880 v, IntegerValue(lb))));
1895 IntegerVariable
var) {
1910 std::function<void(Model*)>
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 ReserveSpaceForNumVariables(int num_vars)
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)
void CallOnNextPropagate(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 SetStopPropagationCallback(std::function< bool()> callback)
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 GetAssociatedLiteral(IntegerLiteral i_lit) const
void FullyEncodeVariable(IntegerVariable var)
bool UpdateEncodingOnInitialDomainChange(IntegerVariable var, Domain domain)
void ReserveSpaceForNumVariables(int num_vars)
Literal GetFalseLiteral()
const IntegerVariable GetLiteralView(Literal lit) const
std::pair< IntegerLiteral, IntegerLiteral > Canonicalize(IntegerLiteral i_lit) const
LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i_lit, IntegerValue *bound) const
void DisableImplicationBetweenLiteral()
void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var, IntegerValue value)
std::vector< ValueLiteralPair > PartialDomainEncoding(IntegerVariable var) const
const std::vector< IntegerVariable > & GetAllAssociatedVariables(Literal lit) const
const InlinedIntegerLiteralVector & GetIntegerLiterals(Literal lit) const
ABSL_MUST_USE_RESULT bool LiteralOrNegationHasView(Literal lit, IntegerVariable *view=nullptr, bool *view_is_direct=nullptr) const
std::vector< ValueLiteralPair > FullDomainEncoding(IntegerVariable var) const
const InlinedIntegerValueVector & GetEqualityLiterals(Literal lit) const
void AddAllImplicationsBetweenAssociatedLiterals()
bool VariableIsFullyEncoded(IntegerVariable var) const
std::vector< ValueLiteralPair > PartialGreaterThanEncoding(IntegerVariable var) const
IntegerEncoder(Model *model)
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)
void NotifyThatPropagationWasAborted()
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)
ABSL_MUST_USE_RESULT bool RootLevelEnqueue(IntegerLiteral i_lit)
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)
void RegisterDebugChecker(std::function< bool(absl::Span< const Literal > clause, absl::Span< const IntegerLiteral > integers)> checker)
LiteralIndex NegatedIndex() const
LiteralIndex Index() const
std::string DebugString() 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)
std::vector< Literal > * MutableConflict()
const VariablesAssignment & Assignment() const
bool LiteralIsTrue(Literal literal) const
absl::InlinedVector< IntegerLiteral, 2 > InlinedIntegerLiteralVector
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
absl::InlinedVector< std::pair< IntegerVariable, IntegerValue >, 2 > InlinedIntegerValueVector
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
std::function< void(Model *)> GreaterOrEqual(IntegerVariable v, int64_t lb)
DEFINE_STRONG_INDEX_TYPE(ClauseIndex)
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
IntType IntTypeAbs(IntType t)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
DEFINE_STRONG_INT64_TYPE(IntegerValue)
const LiteralIndex kNoLiteralIndex(-1)
std::function< BooleanVariable(Model *)> NewBooleanVariable()
std::function< int64_t(const Model &)> Value(IntegerVariable v)
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
std::function< IntegerVariable(Model *)> NewIntegerVariableFromLiteral(Literal lit)
IntegerVariable PositiveVariable(IntegerVariable i)
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
std::function< void(Model *)> Implication(const std::vector< Literal > &enforcement_literals, IntegerLiteral i)
std::function< void(Model *)> LowerOrEqual(IntegerVariable v, int64_t ub)
std::function< IntegerVariable(Model *)> NewIntegerVariable(int64_t lb, int64_t ub)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
std::function< void(Model *)> ExcludeCurrentSolutionWithoutIgnoredVariableAndBacktrack()
std::function< void(Model *)> ImpliesInInterval(Literal in_interval, IntegerVariable v, int64_t lb, int64_t ub)
std::function< void(Model *)> Equality(IntegerVariable v, int64_t value)
std::function< bool(const Model &)> IsFixed(IntegerVariable v)
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
bool VariableIsPositive(IntegerVariable i)
std::function< std::vector< ValueLiteralPair >Model *)> FullyEncodeVariable(IntegerVariable var)
std::function< IntegerVariable(Model *)> ConstantIntegerVariable(int64_t value)
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)
constexpr double kInfinity
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)
absl::StrongVector< IntegerVariable, IntegerValue > ivar_values
std::vector< int64_t > proto_values
absl::StrongVector< IntegerVariable, bool > ivar_has_value
std::vector< IntegerLiteral > integer_literal_to_fix
std::vector< Literal > literal_to_fix
bool operator==(IntegerLiteral o) const
bool IsAlwaysFalse() 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 IsAlwaysTrue() const
IntegerLiteral Negated() const
bool operator!=(IntegerLiteral o) const
static IntegerLiteral FalseLiteral()
bool operator==(const LiteralValueValue &rhs) const
std::string DebugString() const
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
#define VLOG(verboselevel)