14 #ifndef OR_TOOLS_SAT_INTEGER_H_ 15 #define OR_TOOLS_SAT_INTEGER_H_ 27 #include "absl/container/flat_hash_map.h" 28 #include "absl/container/inlined_vector.h" 29 #include "absl/strings/str_cat.h" 30 #include "absl/types/span.h" 71 const double kInfinity = std::numeric_limits<double>::infinity();
74 return static_cast<double>(
value.value());
77 template <
class IntType>
79 return IntType(std::abs(t.value()));
82 inline IntegerValue
CeilRatio(IntegerValue dividend,
83 IntegerValue positive_divisor) {
85 const IntegerValue result = dividend / positive_divisor;
86 const IntegerValue adjust =
87 static_cast<IntegerValue>(result * positive_divisor < dividend);
88 return result + adjust;
92 IntegerValue positive_divisor) {
94 const IntegerValue result = dividend / positive_divisor;
95 const IntegerValue adjust =
96 static_cast<IntegerValue>(result * positive_divisor > dividend);
97 return result - adjust;
107 IntegerValue positive_divisor) {
109 const IntegerValue m = dividend % positive_divisor;
110 return m < 0 ? m + positive_divisor : m;
115 const int64_t prod =
CapProd(
a.value(),
b.value());
119 const int64_t add =
CapAdd(prod, result->value());
123 *result = IntegerValue(add);
135 return IntegerVariable(i.value() ^ 1);
139 return (i.value() & 1) == 0;
143 return IntegerVariable(i.value() & (~1));
149 return PositiveOnlyIndex(
var.value() / 2);
153 IntegerValue coeff) {
155 return absl::StrCat(coeff.value(),
"*X",
var.value() / 2);
160 const std::vector<IntegerVariable>& vars);
198 ? absl::StrCat(
"I",
var.value() / 2,
">=",
bound.value())
199 : absl::StrCat(
"I",
var.value() / 2,
"<=", -
bound.value());
204 IntegerValue
bound = IntegerValue(0);
262 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
")");
264 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
" + ",
271 IntegerValue
coeff = IntegerValue(0);
311 num_created_variables_(0) {}
314 VLOG(1) <<
"#variables created = " << num_created_variables_;
363 IntegerVariable
var)
const;
411 IntegerValue
value)
const;
425 if (lit.
Index() >= reverse_encoding_.
size()) {
426 return empty_integer_literal_vector_;
428 return reverse_encoding_[lit.
Index()];
435 if (lit.
Index() >= full_reverse_encoding_.
size()) {
436 return empty_integer_literal_vector_;
438 return full_reverse_encoding_[lit.
Index()];
444 return newly_fixed_integer_literals_;
447 newly_fixed_integer_literals_.clear();
456 return literal_view_[lit.
Index()];
475 IntegerValue*
bound)
const;
483 literal_index_true_ = literal_true.
Index();
486 return Literal(literal_index_true_);
494 IntegerVariable
var)
const {
495 if (
var >= encoding_by_var_.size()) {
496 return std::map<IntegerValue, Literal>();
498 return encoding_by_var_[
var];
514 void AddImplications(
const std::map<IntegerValue, Literal>& map,
515 std::map<IntegerValue, Literal>::const_iterator it,
521 bool add_implications_ =
true;
522 int64_t num_created_variables_ = 0;
538 full_reverse_encoding_;
539 std::vector<IntegerLiteral> newly_fixed_integer_literals_;
551 absl::flat_hash_map<std::pair<PositiveOnlyIndex, IntegerValue>,
Literal>
552 equality_to_associated_literal_;
566 std::vector<IntegerValue> tmp_values_;
591 void Untrail(const
Trail& trail,
int literal_trail_index) final;
593 int trail_index) const final;
600 return IntegerVariable(vars_.
size());
660 const LiteralIndex is_ignored_literal = is_ignored_literals_[i];
666 return Literal(is_ignored_literals_[i]);
675 is_ignored_literals_[i] == is_considered.
NegatedIndex());
681 IntegerValue
LowerBound(IntegerVariable i)
const;
682 IntegerValue
UpperBound(IntegerVariable i)
const;
685 bool IsFixed(IntegerVariable i)
const;
734 absl::Span<const IntegerValue> coeffs,
735 std::vector<IntegerLiteral>* reason)
const;
739 absl::Span<const IntegerValue> coeffs,
740 absl::Span<const IntegerVariable> vars,
741 std::vector<IntegerLiteral>* reason)
const;
745 absl::Span<const IntegerValue> coeffs,
746 std::vector<int>* trail_indices)
const;
769 ABSL_MUST_USE_RESULT
bool Enqueue(
771 absl::Span<const IntegerLiteral> integer_reason);
781 std::vector<IntegerLiteral>* integer_reason);
790 ABSL_MUST_USE_RESULT
bool Enqueue(
792 absl::Span<const IntegerLiteral> integer_reason,
793 int trail_index_with_same_reason);
808 std::vector<Literal>* literals, std::vector<int>* dependencies)>;
815 absl::Span<const IntegerLiteral> integer_reason);
825 std::vector<Literal>* output)
const;
834 int64_t
timestamp()
const {
return num_enqueues_ + num_untrails_; }
844 watchers_.push_back(p);
850 absl::Span<const IntegerLiteral> integer_reason) {
851 DCHECK(ReasonIsValid(literal_reason, integer_reason));
853 conflict->assign(literal_reason.begin(), literal_reason.end());
858 DCHECK(ReasonIsValid({}, integer_reason));
867 return vars_[
var].current_trail_index < vars_.
size();
873 reversible_classes_.push_back(rev);
876 int Index()
const {
return integer_trail_.size(); }
904 return !literal_to_fix_.empty() || !integer_literal_to_fix_.empty();
910 bool ReasonIsValid(absl::Span<const Literal> literal_reason,
911 absl::Span<const IntegerLiteral> integer_reason);
916 std::vector<Literal>* InitializeConflict(
918 absl::Span<const Literal> literals_reason,
919 absl::Span<const IntegerLiteral> bounds_reason);
922 ABSL_MUST_USE_RESULT
bool EnqueueInternal(
924 absl::Span<const Literal> literal_reason,
925 absl::Span<const IntegerLiteral> integer_reason,
926 int trail_index_with_same_reason);
930 absl::Span<const Literal> literal_reason,
931 absl::Span<const IntegerLiteral> integer_reason);
936 ABSL_MUST_USE_RESULT
bool EnqueueAssociatedIntegerLiteral(
940 void MergeReasonIntoInternal(std::vector<Literal>* output)
const;
945 int FindLowestTrailIndexThatExplainBound(
IntegerLiteral i_lit)
const;
950 void ComputeLazyReasonIfNeeded(
int trail_index)
const;
957 absl::Span<const int> Dependencies(
int trail_index)
const;
963 void AppendLiteralsReason(
int trail_index,
964 std::vector<Literal>* output)
const;
967 std::string DebugString();
972 IntegerValue current_bound;
975 int current_trail_index;
985 mutable int var_trail_index_cache_threshold_ = 0;
990 absl::flat_hash_map<IntegerValue, IntegerVariable> constant_map_;
997 int32_t prev_trail_index;
1002 int32_t reason_index;
1004 std::vector<TrailEntry> integer_trail_;
1005 std::vector<LazyReasonFunction> lazy_reasons_;
1009 std::vector<int> integer_search_levels_;
1016 std::vector<int> reason_decision_levels_;
1017 std::vector<int> literals_reason_starts_;
1018 std::vector<int> bounds_reason_starts_;
1019 std::vector<Literal> literals_reason_buffer_;
1024 std::vector<IntegerLiteral> bounds_reason_buffer_;
1025 mutable std::vector<int> trail_index_reason_buffer_;
1028 mutable std::vector<Literal> lazy_reason_literals_;
1029 mutable std::vector<int> lazy_reason_trail_indices_;
1040 RevMap<absl::flat_hash_map<IntegerVariable, int>>
1041 var_to_current_lb_interval_index_;
1044 mutable bool has_dependency_ =
false;
1045 mutable std::vector<int> tmp_queue_;
1046 mutable std::vector<IntegerVariable> tmp_to_clear_;
1048 tmp_var_to_trail_index_in_queue_;
1049 mutable SparseBitset<BooleanVariable> added_variables_;
1056 std::vector<Literal> literal_to_fix_;
1057 std::vector<IntegerLiteral> integer_literal_to_fix_;
1060 struct RelaxHeapEntry {
1064 bool operator<(
const RelaxHeapEntry& o)
const {
return index < o.index; }
1066 mutable std::vector<RelaxHeapEntry> relax_heap_;
1067 mutable std::vector<int> tmp_indices_;
1070 mutable SparseBitset<IntegerVariable> tmp_marked_;
1076 std::vector<int> boolean_trail_index_to_integer_one_;
1080 int first_level_without_full_propagation_ = -1;
1082 int64_t num_enqueues_ = 0;
1083 int64_t num_untrails_ = 0;
1084 int64_t num_level_zero_enqueues_ = 0;
1085 mutable int64_t num_decisions_to_break_loop_ = 0;
1087 std::vector<SparseBitset<IntegerVariable>*> watchers_;
1088 std::vector<ReversibleInterface*> reversible_classes_;
1090 IntegerDomains* domains_;
1091 IntegerEncoder* encoder_;
1093 const SatParameters& parameters_;
1098 absl::flat_hash_map<std::pair<LiteralIndex, IntegerVariable>, IntegerValue>
1162 void Untrail(
const Trail& trail,
int literal_trail_index)
final;
1248 const std::function<
void(
const std::vector<IntegerVariable>&)> cb) {
1249 level_zero_modified_variable_callback_.push_back(cb);
1260 void UpdateCallingNeeds(
Trail* trail);
1270 return id == o.id && watch_index == o.watch_index;
1275 std::vector<PropagatorInterface*> watchers_;
1276 SparseBitset<IntegerVariable> modified_vars_;
1280 std::vector<std::deque<int>> queue_by_priority_;
1281 std::vector<bool> in_queue_;
1284 DEFINE_INT_TYPE(IdType, int32_t);
1285 std::vector<int> id_to_level_at_last_call_;
1286 RevVector<IdType, int> id_to_greatest_common_level_since_last_call_;
1287 std::vector<std::vector<ReversibleInterface*>> id_to_reversible_classes_;
1288 std::vector<std::vector<int*>> id_to_reversible_ints_;
1289 std::vector<std::vector<int>> id_to_watch_indices_;
1290 std::vector<int> id_to_priority_;
1291 std::vector<int> id_to_idempotence_;
1294 std::vector<int> propagator_ids_to_call_at_level_zero_;
1299 std::vector<std::function<void(
const std::vector<IntegerVariable>&)>>
1300 level_zero_modified_variable_callback_;
1310 IntegerValue
bound) {
1316 IntegerValue
bound) {
1331 IntegerValue
bound)
const {
1346 return vars_[i].current_bound;
1354 return vars_[i].current_bound == -vars_[
NegationOf(i)].current_bound;
1363 Literal l, IntegerVariable i)
const {
1364 const auto it = conditional_lbs_.find({l.
Index(), i});
1365 if (it != conditional_lbs_.end()) {
1366 return std::max(vars_[i].current_bound, it->second);
1368 return vars_[i].current_bound;
1388 IntegerVariable i)
const {
1393 IntegerVariable i)
const {
1408 IntegerVariable
var)
const {
1409 return integer_trail_[
var.value()].bound;
1413 IntegerVariable
var)
const {
1418 return integer_trail_[
var.value()].bound ==
1424 if (l.
Index() >= literal_to_watcher_.
size()) {
1425 literal_to_watcher_.
resize(l.
Index().value() + 1);
1433 if (
var.value() >= var_to_watcher_.
size()) {
1434 var_to_watcher_.
resize(
var.value() + 1);
1441 const WatchData data = {id, watch_index};
1442 if (!var_to_watcher_[
var].empty() && var_to_watcher_[
var].
back() == data) {
1479 ->GetOrCreateConstantIntegerVariable(IntegerValue(
value));
1488 IntegerValue(lb), IntegerValue(ub));
1508 IntegerVariable
var;
1510 if (assignment.LiteralIsTrue(lit)) {
1512 }
else if (assignment.LiteralIsFalse(lit)) {
1518 encoder->AssociateToIntegerEqualValue(lit,
var, IntegerValue(1));
1544 inline std::function<int64_t(
const Model&)>
Value(IntegerVariable v) {
1557 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1559 VLOG(1) <<
"Model trivially infeasible, variable " << v
1561 <<
" and GreaterOrEqual() was called with a lower bound of " 1571 std::vector<Literal>(), std::vector<IntegerLiteral>())) {
1573 LOG(
WARNING) <<
"Model trivially infeasible, variable " << v
1575 <<
" and LowerOrEqual() was called with an upper bound of " 1596 const std::vector<Literal>& enforcement_literals,
IntegerLiteral i) {
1603 std::vector<Literal> clause;
1624 int64_t lb, int64_t ub) {
1630 v, IntegerValue(lb))));
1644 inline std::function<std::vector<IntegerEncoder::ValueLiteralPair>(Model*)>
1660 std::function<void(Model*)>
1666 #endif // OR_TOOLS_SAT_INTEGER_H_ bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const
virtual bool Propagate()=0
std::function< void(IntegerLiteral literal_to_explain, int trail_index_of_literal, std::vector< Literal > *literals, std::vector< int > *dependencies)> LazyReasonFunction
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
DEFINE_INT_TYPE(ClauseIndex, int)
bool HasPendingRootLevelDeduction() const
std::function< BooleanVariable(Model *)> NewBooleanVariable()
AffineExpression Negated() const
const InlinedIntegerLiteralVector & GetIntegerLiterals(Literal lit) const
bool operator==(const ValueLiteralPair &o) const
int NumPropagators() const
LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i, IntegerValue *bound) const
IntegerLiteral GreaterOrEqual(IntegerValue bound) const
void WatchLowerBound(IntegerValue i, int id)
bool operator==(IntegerLiteral o) const
LiteralIndex OptionalLiteralIndex(IntegerVariable i) const
void RegisterWatcher(SparseBitset< IntegerVariable > *p)
Class that owns everything related to a particular optimization model.
ValueLiteralPair(IntegerValue v, Literal l)
IntegerVariable NumIntegerVariables() const
bool IntegerLiteralIsFalse(IntegerLiteral l) const
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue)
void AppendRelaxedLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, absl::Span< const IntegerVariable > vars, std::vector< IntegerLiteral > *reason) const
AffineExpression(IntegerVariable v)
bool VariableIsFullyEncoded(IntegerVariable var) const
IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const
const Domain & InitialVariableDomain(IntegerVariable var) const
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
std::vector< Literal > * MutableConflict()
#define VLOG(verboselevel)
DebugSolution(Model *model)
AffineExpression(IntegerVariable v, IntegerValue c)
bool ReportConflict(absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
IntegerValue LowerBound(IntegerVariable i) const
bool LiteralIsTrue(Literal literal) const
LiteralIndex Index() const
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
double LpValue(const absl::StrongVector< IntegerVariable, double > &lp_values) const
int64_t CapProd(int64_t x, int64_t y)
std::function< IntegerVariable(Model *)> NewIntegerVariableFromLiteral(Literal lit)
int64_t num_enqueues() const
bool AddUnitClause(Literal true_literal)
#define DCHECK_GT(val1, val2)
AffineExpression(IntegerValue cst)
void RemoveLevelZeroBounds(std::vector< IntegerLiteral > *reason) const
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
std::vector< Literal > ReasonFor(IntegerLiteral literal) const
IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const
LinearRange operator==(const LinearExpr &lhs, const LinearExpr &rhs)
IntegerVariable NextVariableToBranchOnInPropagationLoop() const
bool operator==(AffineExpression o) const
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
const IntegerVariable GetLiteralView(Literal lit) const
absl::Span< const Literal > Reason(const Trail &trail, int trail_index) const final
std::function< int64_t(const Model &)> Value(IntegerVariable v)
bool CurrentBranchHadAnIncompletePropagation()
void AppendNewBounds(std::vector< IntegerLiteral > *output) const
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
double ToDouble(IntegerValue value)
IntegerVariable PositiveVariable(IntegerVariable i)
void MarkIntegerVariableAsOptional(IntegerVariable i, Literal is_considered)
std::function< IntegerVariable(Model *)> ConstantIntegerVariable(int64_t value)
std::function< IntegerVariable(Model *)> NewIntegerVariable(int64_t lb, int64_t ub)
Literal GetFalseLiteral()
std::function< void(Model *)> LowerOrEqual(IntegerVariable v, int64_t ub)
void AssociateToIntegerEqualValue(Literal literal, IntegerVariable var, IntegerValue value)
void RegisterLevelZeroModifiedVariablesCallback(const std::function< void(const std::vector< IntegerVariable > &)> cb)
void FullyEncodeVariable(IntegerVariable var)
bool operator<(const ValueLiteralPair &o) const
const std::string DebugString() const
void resize(size_type new_size)
void WatchLowerBound(IntegerVariable var, int id, int watch_index=-1)
LiteralIndex NegatedIndex() const
LiteralIndex GetAssociatedLiteral(IntegerLiteral i_lit) const
void WatchIntegerVariable(IntegerValue v, int id)
absl::InlinedVector< IntegerLiteral, 2 > InlinedIntegerLiteralVector
RevIntegerValueRepository(Model *model)
int64_t CapAdd(int64_t x, int64_t y)
void WatchAffineExpression(AffineExpression e, int id)
#define DCHECK_NE(val1, val2)
Literal GetOrCreateAssociatedLiteral(IntegerLiteral i_lit)
virtual bool IncrementalPropagate(const std::vector< int > &watch_indices)
IntegerValue ConditionalLowerBound(Literal l, IntegerVariable i) const
#define CHECK_LE(val1, val2)
Literal GetOrCreateLiteralAssociatedToEquality(IntegerVariable var, IntegerValue value)
std::function< void(Model *)> ImpliesInInterval(Literal in_interval, IntegerVariable v, int64_t lb, int64_t ub)
void RegisterReversibleClass(int id, ReversibleInterface *rev)
std::function< void(Model *)> GreaterOrEqual(IntegerVariable v, int64_t lb)
int NumConstantVariables() const
IntegerVariable AddIntegerVariable()
IntegerValue LevelZeroUpperBound(IntegerVariable var) const
std::function< bool(const Model &)> IsFixed(IntegerVariable v)
bool UpdateInitialDomain(IntegerVariable var, Domain domain)
void SetPropagatorPriority(int id, int priority)
int64_t num_level_zero_enqueues() const
void AlwaysCallAtLevelZero(int id)
void push_back(const value_type &x)
void EnqueueLiteral(Literal literal, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
bool IsFixedAtLevelZero(IntegerVariable var) const
std::function< std::vector< IntegerEncoder::ValueLiteralPair >Model *)> FullyEncodeVariable(IntegerVariable var)
bool IsFixed(IntegerTrail *integer_trail) const
const bool LiteralOrNegationHasView(Literal lit) const
An Assignment is a variable -> domains mapping, used to report solutions to the user.
IntegerDomains(Model *model)
bool VariableIsPositive(IntegerVariable i)
bool InPropagationLoop() const
void MergeReasonInto(absl::Span< const IntegerLiteral > literals, std::vector< Literal > *output) const
void RelaxLinearReason(IntegerValue slack, absl::Span< const IntegerValue > coeffs, std::vector< IntegerLiteral > *reason) const
#define DCHECK_GE(val1, val2)
void WatchLiteral(Literal l, int id, int watch_index=-1)
std::pair< IntegerLiteral, IntegerLiteral > Canonicalize(IntegerLiteral i_lit) const
bool IsOptional(IntegerVariable i) const
#define CHECK_EQ(val1, val2)
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
LiteralIndex GetAssociatedEqualityLiteral(IntegerVariable var, IntegerValue value) const
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
ABSL_MUST_USE_RESULT bool ConditionalEnqueue(Literal lit, IntegerLiteral i_lit, std::vector< Literal > *literal_reason, std::vector< IntegerLiteral > *integer_reason)
void ClearNewlyFixedIntegerLiterals()
bool Propagate(Trail *trail) final
void WatchLowerBound(AffineExpression e, int id)
BooleanVariable NewBooleanVariable()
IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value)
std::function< void(Model *)> ExcludeCurrentSolutionWithoutIgnoredVariableAndBacktrack()
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
#define DCHECK(condition)
std::function< void(Model *)> Implication(const std::vector< Literal > &enforcement_literals, IntegerLiteral i)
std::map< IntegerValue, Literal > PartialGreaterThanEncoding(IntegerVariable var) const
We call domain any subset of Int64 = [kint64min, kint64max].
IntegerLiteral(IntegerVariable v, IntegerValue b)
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
void RegisterReversibleClass(ReversibleInterface *rev)
IntegerTrail(Model *model)
std::string DebugString() const
#define DCHECK_EQ(val1, val2)
void ClearAndResize(IntegerType size)
bool IsCurrentlyIgnored(IntegerVariable i) const
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
IntegerEncoder(Model *model)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool LiteralIsAssociated(IntegerLiteral i_lit) const
void WatchIntegerVariable(IntegerVariable i, int id, int watch_index=-1)
#define DCHECK_LE(val1, val2)
int Register(PropagatorInterface *propagator)
void Untrail(const Trail &trail, int literal_trail_index) final
const InlinedIntegerLiteralVector & GetAllIntegerLiterals(Literal lit) const
IntegerValue UpperBound(IntegerVariable i) const
bool ReportConflict(absl::Span< const IntegerLiteral > integer_reason)
int CurrentDecisionLevel() const
~GenericLiteralWatcher() final
std::vector< ValueLiteralPair > RawDomainEncoding(IntegerVariable var) const
std::function< void(Model *)> Equality(IntegerVariable v, int64_t value)
Collection of objects used to extend the Constraint Solver library.
std::vector< ValueLiteralPair > PartialDomainEncoding(IntegerVariable var) const
void AddAllImplicationsBetweenAssociatedLiterals()
const IntegerVariable kNoIntegerVariable(-1)
IntegerLiteral LowerOrEqual(IntegerValue bound) const
Literal IsIgnoredLiteral(IntegerVariable i) const
void DisableImplicationBetweenLiteral()
AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
int FindTrailIndexOfVarBefore(IntegerVariable var, int threshold) const
bool IntegerLiteralIsTrue(IntegerLiteral l) const
void WatchUpperBound(IntegerVariable var, int id, int watch_index=-1)
std::vector< ValueLiteralPair > FullDomainEncoding(IntegerVariable var) const
void WatchUpperBound(IntegerValue i, int id)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
const LiteralIndex kNoLiteralIndex(-1)
const VariablesAssignment & Assignment() const
void ReserveSpaceForNumVariables(int num_vars)
int64_t timestamp() const
IntegerVariable FirstUnassignedVariable() const
void Untrail(const Trail &trail, int literal_trail_index) final
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
IntType IntTypeAbs(IntType t)
virtual ~PropagatorInterface()
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
IntegerValue Max(IntegerTrail *integer_trail) const
IntegerValue Min(IntegerTrail *integer_trail) const
RevIntRepository(Model *model)
IntegerValue LevelZeroLowerBound(IntegerVariable var) const
GenericLiteralWatcher(Model *model)
bool operator!=(IntegerLiteral o) const
bool Propagate(Trail *trail) final
void WatchUpperBound(AffineExpression e, int id)
const std::vector< IntegerLiteral > NewlyFixedIntegerLiterals() const
bool IsFixed(IntegerVariable i) const
void AssociateToIntegerLiteral(Literal literal, IntegerLiteral i_lit)
void RegisterReversibleInt(int id, int *rev)
IntegerLiteral Negated() const
void NotifyThatPropagatorMayNotReachFixedPointInOnePass(int id)