24 #include "absl/strings/str_format.h" 25 #include "absl/strings/str_join.h" 36 "Initial size of the array of the hash " 37 "table of caches for objects of type Var(x == 3)");
45 class EqualityExprCst :
public Constraint {
47 EqualityExprCst(Solver*
const s, IntExpr*
const e, int64_t v);
48 ~EqualityExprCst()
override {}
50 void InitialPropagate()
override;
51 IntVar* Var()
override {
52 return solver()->MakeIsEqualCstVar(
expr_->Var(), value_);
54 std::string DebugString()
const override;
56 void Accept(ModelVisitor*
const visitor)
const override {
69 EqualityExprCst::EqualityExprCst(Solver*
const s, IntExpr*
const e, int64_t v)
70 : Constraint(s),
expr_(e), value_(v) {}
72 void EqualityExprCst::Post() {
74 Demon* d = solver()->MakeConstraintInitialPropagateCallback(
this);
79 void EqualityExprCst::InitialPropagate() {
expr_->
SetValue(value_); }
81 std::string EqualityExprCst::DebugString()
const {
90 if (IsADifference(e, &left, &right)) {
94 }
else if (e->
Min() == e->
Max() && e->
Min() == v) {
97 return RevAlloc(
new EqualityExprCst(
this, e, v));
105 if (IsADifference(e, &left, &right)) {
109 }
else if (e->
Min() == e->
Max() && e->
Min() == v) {
112 return RevAlloc(
new EqualityExprCst(
this, e, v));
122 GreaterEqExprCst(
Solver*
const s,
IntExpr*
const e, int64_t v);
123 ~GreaterEqExprCst()
override {}
124 void Post()
override;
125 void InitialPropagate()
override;
126 std::string DebugString()
const override;
127 IntVar* Var()
override {
128 return solver()->MakeIsGreaterOrEqualCstVar(
expr_->Var(), value_);
131 void Accept(ModelVisitor*
const visitor)
const override {
140 IntExpr*
const expr_;
145 GreaterEqExprCst::GreaterEqExprCst(Solver*
const s, IntExpr*
const e, int64_t v)
146 : Constraint(s),
expr_(e), value_(v), demon_(nullptr) {}
148 void GreaterEqExprCst::Post() {
150 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
158 void GreaterEqExprCst::InitialPropagate() {
160 if (demon_ !=
nullptr &&
expr_->
Min() >= value_) {
165 std::string GreaterEqExprCst::DebugString()
const {
174 }
else if (e->
Max() < v) {
177 return RevAlloc(
new GreaterEqExprCst(
this, e, v));
185 }
else if (e->
Max() < v) {
188 return RevAlloc(
new GreaterEqExprCst(
this, e, v));
196 }
else if (e->
Max() <= v) {
199 return RevAlloc(
new GreaterEqExprCst(
this, e, v + 1));
207 }
else if (e->
Max() <= v) {
210 return RevAlloc(
new GreaterEqExprCst(
this, e, v + 1));
221 ~LessEqExprCst()
override {}
222 void Post()
override;
223 void InitialPropagate()
override;
224 std::string DebugString()
const override;
225 IntVar* Var()
override {
226 return solver()->MakeIsLessOrEqualCstVar(
expr_->Var(), value_);
228 void Accept(ModelVisitor*
const visitor)
const override {
237 IntExpr*
const expr_;
242 LessEqExprCst::LessEqExprCst(Solver*
const s, IntExpr*
const e, int64_t v)
243 : Constraint(s),
expr_(e), value_(v), demon_(nullptr) {}
245 void LessEqExprCst::Post() {
247 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
255 void LessEqExprCst::InitialPropagate() {
257 if (demon_ !=
nullptr &&
expr_->
Max() <= value_) {
262 std::string LessEqExprCst::DebugString()
const {
271 }
else if (e->
Min() > v) {
274 return RevAlloc(
new LessEqExprCst(
this, e, v));
282 }
else if (e->
Min() > v) {
285 return RevAlloc(
new LessEqExprCst(
this, e, v));
293 }
else if (e->
Min() >= v) {
296 return RevAlloc(
new LessEqExprCst(
this, e, v - 1));
304 }
else if (e->
Min() >= v) {
307 return RevAlloc(
new LessEqExprCst(
this, e, v - 1));
318 ~DiffCst()
override {}
319 void Post()
override {}
320 void InitialPropagate()
override;
321 void BoundPropagate();
322 std::string DebugString()
const override;
323 IntVar* Var()
override {
324 return solver()->MakeIsDifferentCstVar(var_, value_);
326 void Accept(ModelVisitor*
const visitor)
const override {
335 bool HasLargeDomain(IntVar*
var);
342 DiffCst::DiffCst(Solver*
const s, IntVar*
const var, int64_t
value)
343 : Constraint(s), var_(
var), value_(
value), demon_(nullptr) {}
345 void DiffCst::InitialPropagate() {
346 if (HasLargeDomain(var_)) {
355 void DiffCst::BoundPropagate() {
356 const int64_t var_min = var_->
Min();
357 const int64_t var_max = var_->
Max();
358 if (var_min > value_ || var_max < value_) {
360 }
else if (var_min == value_) {
362 }
else if (var_max == value_) {
364 }
else if (!HasLargeDomain(var_)) {
370 std::string DiffCst::DebugString()
const {
371 return absl::StrFormat(
"(%s != %d)", var_->
DebugString(), value_);
374 bool DiffCst::HasLargeDomain(IntVar*
var) {
383 if (IsADifference(e, &left, &right)) {
387 }
else if (e->
Bound() && e->
Min() == v) {
398 if (IsADifference(e, &left, &right)) {
402 }
else if (e->
Bound() && e->
Min() == v) {
415 void Post()
override {
416 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
417 var_->WhenDomain(demon_);
420 void InitialPropagate()
override {
421 bool inhibit = var_->Bound();
422 int64_t u = var_->Contains(
cst_);
423 int64_t l = inhibit ? u : 0;
427 if (var_->Size() <= 0xFFFFFF) {
428 var_->RemoveValue(
cst_);
432 var_->SetValue(
cst_);
437 demon_->inhibit(solver());
440 std::string DebugString()
const override {
441 return absl::StrFormat(
"IsEqualCstCt(%s, %d, %s)", var_->DebugString(),
445 void Accept(ModelVisitor*
const visitor)
const override {
465 if (IsADifference(
var, &left, &right)) {
503 if (boolvar->
Bound()) {
504 if (boolvar->
Min() == 0) {
512 model_cache_->InsertExprConstantExpression(
516 if (IsADifference(
var, &left, &right)) {
531 void Post()
override {
532 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
533 var_->WhenDomain(demon_);
537 void InitialPropagate()
override {
538 bool inhibit = var_->Bound();
539 int64_t l = 1 - var_->Contains(
cst_);
540 int64_t u = inhibit ? l : 1;
544 if (var_->Size() <= 0xFFFFFF) {
545 var_->RemoveValue(
cst_);
549 var_->SetValue(
cst_);
554 demon_->inhibit(solver());
558 std::string DebugString()
const override {
559 return absl::StrFormat(
"IsDiffCstCt(%s, %d, %s)", var_->DebugString(),
cst_,
563 void Accept(ModelVisitor*
const visitor)
const override {
583 if (IsADifference(
var, &left, &right)) {
586 return var->Var()->IsDifferent(
value);
599 if (
var->IsVar() && !
var->Var()->Contains(
value)) {
605 if (boolvar->
Bound()) {
606 if (boolvar->
Min() == 0) {
612 model_cache_->InsertExprConstantExpression(
616 if (IsADifference(
var, &left, &right)) {
628 IsGreaterEqualCstCt(
Solver*
const s,
IntExpr*
const v, int64_t c,
631 void Post()
override {
632 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
633 expr_->WhenRange(demon_);
636 void InitialPropagate()
override {
637 bool inhibit =
false;
653 demon_->inhibit(solver());
656 std::string DebugString()
const override {
657 return absl::StrFormat(
"IsGreaterEqualCstCt(%s, %d, %s)",
662 void Accept(ModelVisitor*
const visitor)
const override {
673 IntExpr*
const expr_;
687 return var->Var()->IsGreaterOrEqual(
value);
702 if (boolvar->
Bound()) {
703 if (boolvar->
Min() == 0) {
711 model_cache_->InsertExprConstantExpression(
726 IsLessEqualCstCt(
Solver*
const s,
IntExpr*
const v, int64_t c,
730 void Post()
override {
731 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
732 expr_->WhenRange(demon_);
736 void InitialPropagate()
override {
737 bool inhibit =
false;
753 demon_->inhibit(solver());
757 std::string DebugString()
const override {
758 return absl::StrFormat(
"IsLessEqualCstCt(%s, %d, %s)",
expr_->DebugString(),
762 void Accept(ModelVisitor*
const visitor)
const override {
773 IntExpr*
const expr_;
787 return var->Var()->IsLessOrEqual(
value);
802 if (boolvar->
Bound()) {
803 if (boolvar->
Min() == 0) {
811 model_cache_->InsertExprConstantExpression(
826 BetweenCt(
Solver*
const s,
IntExpr*
const v, int64_t l, int64_t u)
829 void Post()
override {
830 if (!
expr_->IsVar()) {
831 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
832 expr_->WhenRange(demon_);
836 void InitialPropagate()
override {
837 expr_->SetRange(min_, max_);
840 expr_->Range(&emin, &emax);
841 if (demon_ !=
nullptr && emin >= min_ && emax <= max_) {
842 demon_->inhibit(solver());
846 std::string DebugString()
const override {
847 return absl::StrFormat(
"BetweenCt(%s, %d, %d)",
expr_->DebugString(), min_,
851 void Accept(ModelVisitor*
const visitor)
const override {
861 IntExpr*
const expr_;
869 class NotBetweenCt :
public Constraint {
871 NotBetweenCt(Solver*
const s, IntExpr*
const v, int64_t l, int64_t u)
872 : Constraint(s),
expr_(v), min_(l), max_(u), demon_(nullptr) {}
874 void Post()
override {
875 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
876 expr_->WhenRange(demon_);
879 void InitialPropagate()
override {
882 expr_->Range(&emin, &emax);
884 expr_->SetMin(max_ + 1);
885 }
else if (emax <= max_) {
886 expr_->SetMax(min_ - 1);
889 if (!
expr_->IsVar() && (emax < min_ || emin > max_)) {
890 demon_->inhibit(solver());
894 std::string DebugString()
const override {
895 return absl::StrFormat(
"NotBetweenCt(%s, %d, %d)",
expr_->DebugString(),
899 void Accept(ModelVisitor*
const visitor)
const override {
909 IntExpr*
const expr_;
915 int64_t ExtractExprProductCoeff(IntExpr** expr) {
918 while ((*expr)->solver()->IsProduct(*expr, expr, &coeff)) prod *= coeff;
932 expr->
Range(&emin, &emax);
940 int64_t coeff = ExtractExprProductCoeff(&expr);
952 return RevAlloc(
new BetweenCt(
this, expr, l, u));
965 expr->
Range(&emin, &emax);
971 if (emax <= u)
return MakeLess(expr, l);
974 return RevAlloc(
new NotBetweenCt(
this, expr, l, u));
982 IsBetweenCt(
Solver*
const s,
IntExpr*
const e, int64_t l, int64_t u,
991 void Post()
override {
992 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
993 expr_->WhenRange(demon_);
994 boolvar_->WhenBound(demon_);
997 void InitialPropagate()
override {
998 bool inhibit =
false;
1001 expr_->Range(&emin, &emax);
1002 int64_t u = 1 - (emin > max_ || emax < min_);
1003 int64_t l = emax <= max_ && emin >= min_;
1004 boolvar_->SetRange(l, u);
1005 if (boolvar_->Bound()) {
1007 if (boolvar_->Min() == 0) {
1008 if (
expr_->IsVar()) {
1009 expr_->Var()->RemoveInterval(min_, max_);
1011 }
else if (emin > min_) {
1012 expr_->SetMin(max_ + 1);
1013 }
else if (emax < max_) {
1014 expr_->SetMax(min_ - 1);
1017 expr_->SetRange(min_, max_);
1020 if (inhibit &&
expr_->IsVar()) {
1021 demon_->inhibit(solver());
1026 std::string DebugString()
const override {
1027 return absl::StrFormat(
"IsBetweenCt(%s, %d, %d, %s)",
expr_->DebugString(),
1028 min_, max_, boolvar_->DebugString());
1031 void Accept(ModelVisitor*
const visitor)
const override {
1043 IntExpr*
const expr_;
1046 IntVar*
const boolvar_;
1062 expr->
Range(&emin, &emax);
1070 int64_t coeff = ExtractExprProductCoeff(&expr);
1083 return RevAlloc(
new IsBetweenCt(
this, expr, l, u,
b));
1103 const std::vector<int64_t>& sorted_values)
1104 :
Constraint(s), var_(v), values_(sorted_values) {
1109 void Post()
override {}
1111 void InitialPropagate()
override { var_->SetValues(values_); }
1113 std::string DebugString()
const override {
1114 return absl::StrFormat(
"Member(%s, %s)", var_->DebugString(),
1115 absl::StrJoin(values_,
", "));
1118 void Accept(ModelVisitor*
const visitor)
const override {
1128 const std::vector<int64_t> values_;
1131 class NotMemberCt :
public Constraint {
1133 NotMemberCt(Solver*
const s, IntVar*
const v,
1134 const std::vector<int64_t>& sorted_values)
1135 : Constraint(s), var_(v), values_(sorted_values) {
1140 void Post()
override {}
1142 void InitialPropagate()
override { var_->RemoveValues(values_); }
1144 std::string DebugString()
const override {
1145 return absl::StrFormat(
"NotMember(%s, %s)", var_->DebugString(),
1146 absl::StrJoin(values_,
", "));
1149 void Accept(ModelVisitor*
const visitor)
const override {
1159 const std::vector<int64_t> values_;
1164 const std::vector<int64_t>& values) {
1165 const int64_t coeff = ExtractExprProductCoeff(&expr);
1167 return std::find(values.begin(), values.end(), 0) == values.end()
1171 std::vector<int64_t> copied_values = values;
1176 for (
const int64_t v : copied_values) {
1177 if (v % coeff == 0) copied_values[num_kept++] = v / coeff;
1179 copied_values.resize(num_kept);
1185 expr->
Range(&emin, &emax);
1186 for (
const int64_t v : copied_values) {
1187 if (v >= emin && v <= emax) copied_values[num_kept++] = v;
1189 copied_values.resize(num_kept);
1195 if (copied_values.size() == 1)
return MakeEquality(expr, copied_values[0]);
1197 if (copied_values.size() ==
1198 copied_values.back() - copied_values.front() + 1) {
1200 return MakeBetweenCt(expr, copied_values.front(), copied_values.back());
1205 if (emax - emin < 2 * copied_values.size()) {
1207 std::vector<bool> is_among_input_values(emax - emin + 1,
false);
1208 for (
const int64_t v : copied_values)
1209 is_among_input_values[v - emin] =
true;
1212 copied_values.clear();
1213 for (int64_t v_off = 0; v_off < is_among_input_values.size(); ++v_off) {
1214 if (!is_among_input_values[v_off]) copied_values.push_back(v_off + emin);
1219 if (copied_values.size() == 1) {
1222 return RevAlloc(
new NotMemberCt(
this, expr->
Var(), copied_values));
1225 return RevAlloc(
new MemberCt(
this, expr->
Var(), copied_values));
1229 const std::vector<int>& values) {
1234 const std::vector<int64_t>& values) {
1235 const int64_t coeff = ExtractExprProductCoeff(&expr);
1237 return std::find(values.begin(), values.end(), 0) == values.end()
1241 std::vector<int64_t> copied_values = values;
1246 for (
const int64_t v : copied_values) {
1247 if (v % coeff == 0) copied_values[num_kept++] = v / coeff;
1249 copied_values.resize(num_kept);
1255 expr->
Range(&emin, &emax);
1256 for (
const int64_t v : copied_values) {
1257 if (v >= emin && v <= emax) copied_values[num_kept++] = v;
1259 copied_values.resize(num_kept);
1265 if (copied_values.size() == 1)
return MakeNonEquality(expr, copied_values[0]);
1267 if (copied_values.size() ==
1268 copied_values.back() - copied_values.front() + 1) {
1269 return MakeNotBetweenCt(expr, copied_values.front(), copied_values.back());
1274 if (emax - emin < 2 * copied_values.size()) {
1276 std::vector<bool> is_among_input_values(emax - emin + 1,
false);
1277 for (
const int64_t v : copied_values)
1278 is_among_input_values[v - emin] =
true;
1281 copied_values.clear();
1282 for (int64_t v_off = 0; v_off < is_among_input_values.size(); ++v_off) {
1283 if (!is_among_input_values[v_off]) copied_values.push_back(v_off + emin);
1288 if (copied_values.size() == 1) {
1291 return RevAlloc(
new MemberCt(
this, expr->
Var(), copied_values));
1294 return RevAlloc(
new NotMemberCt(
this, expr->
Var(), copied_values));
1298 const std::vector<int>& values) {
1308 const std::vector<int64_t>& sorted_values,
IntVar*
const b)
1311 values_as_set_(sorted_values.begin(), sorted_values.end()),
1312 values_(sorted_values),
1316 domain_(var_->MakeDomainIterator(true)),
1317 neg_support_(std::numeric_limits<int64_t>::
min()) {
1326 void Post()
override {
1329 if (!var_->Bound()) {
1330 var_->WhenDomain(demon_);
1332 if (!boolvar_->Bound()) {
1334 solver(),
this, &IsMemberCt::TargetBound,
"TargetBound");
1335 boolvar_->WhenBound(bdemon);
1339 void InitialPropagate()
override {
1340 boolvar_->SetRange(0, 1);
1341 if (boolvar_->Bound()) {
1348 std::string DebugString()
const override {
1349 return absl::StrFormat(
"IsMemberCt(%s, %s, %s)", var_->DebugString(),
1350 absl::StrJoin(values_,
", "),
1351 boolvar_->DebugString());
1354 void Accept(ModelVisitor*
const visitor)
const override {
1366 if (boolvar_->Bound()) {
1369 for (
int offset = 0; offset < values_.size(); ++offset) {
1370 const int candidate = (support_ + offset) % values_.size();
1371 if (var_->Contains(values_[candidate])) {
1372 support_ = candidate;
1373 if (var_->Bound()) {
1374 demon_->inhibit(solver());
1375 boolvar_->SetValue(1);
1380 if (var_->Contains(neg_support_)) {
1384 for (
const int64_t
value : InitAndGetValues(domain_)) {
1386 neg_support_ =
value;
1392 demon_->inhibit(solver());
1393 boolvar_->SetValue(1);
1398 demon_->inhibit(solver());
1399 boolvar_->SetValue(0);
1403 void TargetBound() {
1404 DCHECK(boolvar_->Bound());
1405 if (boolvar_->Min() == 1LL) {
1406 demon_->inhibit(solver());
1407 var_->SetValues(values_);
1409 demon_->inhibit(solver());
1410 var_->RemoveValues(values_);
1415 absl::flat_hash_set<int64_t> values_as_set_;
1416 std::vector<int64_t> values_;
1417 IntVar*
const boolvar_;
1420 IntVarIterator*
const domain_;
1421 int64_t neg_support_;
1425 Constraint* BuildIsMemberCt(Solver*
const solver, IntExpr*
const expr,
1426 const std::vector<T>& values,
1427 IntVar*
const boolvar) {
1430 IntExpr* sub =
nullptr;
1432 if (solver->IsProduct(expr, &sub, &
coef) &&
coef != 0 &&
coef != 1) {
1433 std::vector<int64_t> new_values;
1434 new_values.reserve(values.size());
1435 for (
const int64_t
value : values) {
1440 return BuildIsMemberCt(solver, sub, new_values, boolvar);
1443 std::set<T> set_of_values(values.begin(), values.end());
1444 std::vector<int64_t> filtered_values;
1445 bool all_values =
false;
1446 if (expr->IsVar()) {
1447 IntVar*
const var = expr->
Var();
1448 for (
const T
value : set_of_values) {
1450 filtered_values.push_back(
value);
1453 all_values = (filtered_values.size() ==
var->
Size());
1457 expr->Range(&emin, &emax);
1458 for (
const T
value : set_of_values) {
1460 filtered_values.push_back(
value);
1463 all_values = (filtered_values.size() == emax - emin + 1);
1465 if (filtered_values.empty()) {
1466 return solver->MakeEquality(boolvar,
Zero());
1467 }
else if (all_values) {
1468 return solver->MakeEquality(boolvar, 1);
1469 }
else if (filtered_values.size() == 1) {
1470 return solver->MakeIsEqualCstCt(expr, filtered_values.back(), boolvar);
1471 }
else if (filtered_values.back() ==
1472 filtered_values.front() + filtered_values.size() - 1) {
1474 return solver->MakeIsBetweenCt(expr, filtered_values.front(),
1475 filtered_values.back(), boolvar);
1477 return solver->RevAlloc(
1478 new IsMemberCt(solver, expr->Var(), filtered_values, boolvar));
1484 const std::vector<int64_t>& values,
1486 return BuildIsMemberCt(
this, expr, values, boolvar);
1490 const std::vector<int>& values,
1492 return BuildIsMemberCt(
this, expr, values, boolvar);
1496 const std::vector<int64_t>& values) {
1503 const std::vector<int>& values) {
1510 class SortedDisjointForbiddenIntervalsConstraint :
public Constraint {
1512 SortedDisjointForbiddenIntervalsConstraint(
1515 :
Constraint(solver), var_(
var), intervals_(std::move(intervals)) {}
1517 ~SortedDisjointForbiddenIntervalsConstraint()
override {}
1519 void Post()
override {
1520 Demon*
const demon = solver()->MakeConstraintInitialPropagateCallback(
this);
1521 var_->WhenRange(demon);
1524 void InitialPropagate()
override {
1525 const int64_t vmin = var_->Min();
1526 const int64_t vmax = var_->Max();
1527 const auto first_interval_it = intervals_.FirstIntervalGreaterOrEqual(vmin);
1528 if (first_interval_it == intervals_.end()) {
1532 const auto last_interval_it = intervals_.LastIntervalLessOrEqual(vmax);
1533 if (last_interval_it == intervals_.end()) {
1539 if (vmin >= first_interval_it->start) {
1542 var_->SetMin(
CapAdd(first_interval_it->end, 1));
1544 if (vmax <= last_interval_it->end) {
1546 var_->SetMax(
CapSub(last_interval_it->start, 1));
1550 std::string DebugString()
const override {
1551 return absl::StrFormat(
"ForbiddenIntervalCt(%s, %s)", var_->DebugString(),
1552 intervals_.DebugString());
1555 void Accept(ModelVisitor*
const visitor)
const override {
1559 std::vector<int64_t> starts;
1560 std::vector<int64_t> ends;
1561 for (
auto&
interval : intervals_) {
1572 const SortedDisjointIntervalList intervals_;
1577 std::vector<int64_t> starts,
1578 std::vector<int64_t> ends) {
1579 return RevAlloc(
new SortedDisjointForbiddenIntervalsConstraint(
1580 this, expr->
Var(), {starts, ends}));
1584 std::vector<int> starts,
1585 std::vector<int> ends) {
1586 return RevAlloc(
new SortedDisjointForbiddenIntervalsConstraint(
1587 this, expr->
Var(), {starts, ends}));
1592 return RevAlloc(
new SortedDisjointForbiddenIntervalsConstraint(
1593 this, expr->
Var(), std::move(intervals)));
Constraint * MakeFalseConstraint()
This constraint always fails.
Cast constraints are special channeling constraints designed to keep a variable in sync with an expre...
Constraint * MakeGreater(IntExpr *const left, IntExpr *const right)
left > right
IntVar * MakeIsGreaterOrEqualCstVar(IntExpr *const var, int64_t value)
status var of (var >= value)
IntVar * MakeIsEqualCstVar(IntExpr *const var, int64_t value)
status var of (var == value)
int64_t CapSub(int64_t x, int64_t y)
Constraint * MakeIsDifferentCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var != value)
Constraint * MakeNotMemberCt(IntExpr *const expr, const std::vector< int64_t > &values)
expr not in set.
int64_t PosIntDivDown(int64_t e, int64_t v)
IntVar * Var() override
Creates a variable from the expression.
virtual void RemoveValue(int64_t v)=0
This method removes the value 'v' from the domain of the variable.
IntVar * MakeIsLessCstVar(IntExpr *const var, int64_t value)
status var of (var < value)
int64_t PosIntDivUp(int64_t e, int64_t v)
static const char kMember[]
IntVar * MakeIsGreaterCstVar(IntExpr *const var, int64_t value)
status var of (var > value)
static const char kMaxArgument[]
static const char kEquality[]
virtual bool Contains(int64_t v) const =0
This method returns whether the value 'v' is in the domain of the variable.
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
static const char kEndsArgument[]
Constraint * MakeMemberCt(IntExpr *const expr, const std::vector< int64_t > &values)
expr in set.
virtual int64_t Min() const =0
IntVar * MakeIsEqualVar(IntExpr *const v1, IntExpr *v2)
status var of (v1 == v2)
A constraint is the main modeling object.
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
void AddConstraint(Constraint *const c)
Adds the constraint 'c' to the model.
bool IsVar() const override
Returns true if the expression is indeed a variable.
static const char kStartsArgument[]
static const char kIsLessOrEqual[]
IntervalVar *const target_var_
Constraint * MakeIsDifferentCt(IntExpr *const v1, IntExpr *const v2, IntVar *const b)
b == (v1 != v2)
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual IntVar * Var()=0
Creates a variable from the expression.
static const char kIsEqual[]
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
virtual void SetMax(int64_t m)=0
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
Constraint * MakeIsLessOrEqualCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var <= value)
static const char kMinArgument[]
int64_t CapAdd(int64_t x, int64_t y)
static const char kGreaterOrEqual[]
Constraint * MakeIsGreaterOrEqualCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var >= value)
Constraint * MakeIsLessCstCt(IntExpr *const v, int64_t c, IntVar *const b)
b == (v < c)
Constraint * MakeIsEqualCt(IntExpr *const v1, IntExpr *v2, IntVar *const b)
b == (v1 == v2)
static const char kLessOrEqual[]
This class represents a sorted list of disjoint, closed intervals.
virtual void SetMin(int64_t m)=0
IntExpr * MakeDifference(IntExpr *const left, IntExpr *const right)
left - right
bool ContainsKey(const Collection &collection, const Key &key)
static const char kIsBetween[]
IntVar * MakeIsMemberVar(IntExpr *const expr, const std::vector< int64_t > &values)
Constraint * MakeIsEqualCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var == value)
Constraint * MakeLess(IntExpr *const left, IntExpr *const right)
left < right
virtual uint64_t Size() const =0
This method returns the number of values in the domain of the variable.
The class IntVar is a subset of IntExpr.
#define DCHECK_GE(val1, val2)
The class IntExpr is the base of all integer expressions in constraint programming.
Constraint * MakeIsBetweenCt(IntExpr *const expr, int64_t l, int64_t u, IntVar *const b)
b == (l <= expr <= u)
static const char kBetween[]
Constraint * MakeLessOrEqual(IntExpr *const left, IntExpr *const right)
left <= right
#define CHECK_EQ(val1, val2)
virtual void SetValue(int64_t v)
This method sets the value of the expression.
Constraint * MakeIsMemberCt(IntExpr *const expr, const std::vector< int64_t > &values, IntVar *const boolvar)
boolvar == (expr in set)
std::string DebugString() const override
T * RevAlloc(T *object)
Registers the given object as being reversible.
IntVar * MakeIsBetweenVar(IntExpr *const v, int64_t l, int64_t u)
static const char kValuesArgument[]
ABSL_FLAG(int, cache_initial_size, 1024, "Initial size of the array of the hash " "table of caches for objects of type Var(x == 3)")
#define DCHECK(condition)
Constraint * MakeBetweenCt(IntExpr *const expr, int64_t l, int64_t u)
(l <= expr <= u)
Constraint * MakeGreaterOrEqual(IntExpr *const left, IntExpr *const right)
left >= right
IntVar * MakeIntConst(int64_t val, const std::string &name)
IntConst will create a constant expression.
#define DCHECK_EQ(val1, val2)
static const char kNotBetween[]
Constraint * MakeNotBetweenCt(IntExpr *const expr, int64_t l, int64_t u)
(expr < l || expr > u) This constraint is lazy as it will not make holes in the domain of variables.
static const char kIsDifferent[]
Constraint * MakeTrueConstraint()
This constraint always succeeds.
IntVar * MakeIsDifferentCstVar(IntExpr *const var, int64_t value)
status var of (var != value)
Collection of objects used to extend the Constraint Solver library.
Constraint * MakeEquality(IntExpr *const left, IntExpr *const right)
left == right
static const char kExpressionArgument[]
virtual void Range(int64_t *l, int64_t *u)
By default calls Min() and Max(), but can be redefined when Min and Max code can be factorized.
IntVar * MakeIsDifferentVar(IntExpr *const v1, IntExpr *const v2)
status var of (v1 != v2)
static const char kIsGreaterOrEqual[]
static const char kValueArgument[]
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
Constraint * MakeIsGreaterCstCt(IntExpr *const v, int64_t c, IntVar *const b)
b == (v > c)
void inhibit(Solver *const s)
This method inhibits the demon in the search tree below the current position.
IntVar * MakeIsLessOrEqualCstVar(IntExpr *const var, int64_t value)
status var of (var <= value)
Constraint * MakeNonEquality(IntExpr *const left, IntExpr *const right)
left != right
static const char kTargetArgument[]
static const char kNonEqual[]
static const char kIsMember[]
static const char kNotMember[]
IntExpr * MakeSum(IntExpr *const left, IntExpr *const right)
left + right.
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
#define CHECK_NE(val1, val2)
virtual int64_t Max() const =0
IntVar * MakeBoolVar()
MakeBoolVar will create a variable with a {0, 1} domain.