23#include "absl/container/flat_hash_map.h"
24#include "absl/strings/str_cat.h"
25#include "absl/strings/str_format.h"
38ABSL_FLAG(
bool, cp_disable_expression_optimization,
false,
39 "Disable special optimization when creating expressions.");
41 "Share IntConst's with the same value.");
44#pragma warning(disable : 4351 4355)
62 :
IntExpr(s), index_(s->GetNewIntVarIndex()) {
83 if (mi > 1 || ma < 0 || mi > ma) {
107 if (l <= 0 && u >= 1) {
131 return ((v == 0 &&
value_ != 1) || (v == 1 &&
value_ != 0));
135 if (constant > 1 || constant < 0) {
146 if (constant > 1 || constant < 0) {
159 }
else if (constant <= 0) {
169 }
else if (constant >= 1) {
178 const std::string& var_name =
name();
179 if (!var_name.empty()) {
180 out = var_name +
"(";
204class DomainIntVar :
public IntVar {
209 BitSetIterator(uint64_t*
const bitset, int64_t omin)
212 max_(
std::numeric_limits<int64_t>::
min()),
215 ~BitSetIterator()
override {}
217 void Init(int64_t
min, int64_t
max) {
222 bool Ok()
const {
return current_ <= max_; }
229 bitset_,
current_ - omin_, max_ - omin_) +
234 std::string DebugString()
const override {
return "BitSetIterator"; }
237 uint64_t*
const bitset_;
243 class BitSet :
public BaseObject {
245 explicit BitSet(Solver*
const s) :
solver_(s), holes_stamp_(0) {}
246 ~BitSet()
override {}
248 virtual int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax) = 0;
249 virtual int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax) = 0;
250 virtual bool Contains(int64_t val)
const = 0;
251 virtual bool SetValue(int64_t val) = 0;
252 virtual bool RemoveValue(int64_t val) = 0;
253 virtual uint64_t Size()
const = 0;
254 virtual void DelayRemoveValue(int64_t val) = 0;
255 virtual void ApplyRemovedValues(DomainIntVar*
var) = 0;
256 virtual void ClearRemovedValues() = 0;
257 virtual std::string pretty_DebugString(int64_t
min, int64_t
max)
const = 0;
258 virtual BitSetIterator* MakeIterator() = 0;
261 const uint64_t current_stamp =
solver_->stamp();
262 if (holes_stamp_ < current_stamp) {
264 holes_stamp_ = current_stamp;
268 virtual void ClearHoles() {
holes_.clear(); }
270 const std::vector<int64_t>& Holes() {
return holes_; }
274 int NumHoles()
const {
282 std::vector<int64_t>
holes_;
283 uint64_t holes_stamp_;
286 class QueueHandler :
public Demon {
288 explicit QueueHandler(DomainIntVar*
const var) : var_(
var) {}
289 ~QueueHandler()
override {}
290 void Run(Solver*
const s)
override {
291 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
293 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
298 std::string DebugString()
const override {
299 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
303 DomainIntVar*
const var_;
314 RevIntPtrMap(Solver*
const solver, int64_t rmin, int64_t rmax)
315 :
solver_(solver), range_min_(rmin), start_(0) {}
319 bool Empty()
const {
return start_.Value() == elements_.size(); }
321 void SortActive() { std::sort(elements_.begin(), elements_.end()); }
326 void UnsafeRevInsert(int64_t
value, T* elem) {
327 elements_.push_back(std::make_pair(
value, elem));
330 [
this,
value](Solver* s) { Uninsert(
value); },
false);
335 for (
int pos = start_.Value(); pos < elements_.size(); ++pos) {
336 if (elements_[pos].first ==
value) {
337 if (position !=
nullptr) *position = pos;
338 return At(pos).second;
346 const int start = start_.Value();
349 if (position > start) {
352 const std::pair<int64_t, T*> copy = elements_[start];
353 elements_[start] = elements_[position];
354 elements_[position] = copy;
359 const std::pair<int64_t, T*>& At(
int position)
const {
362 return elements_[position];
365 void RemoveAll() { start_.SetValue(
solver_, elements_.size()); }
367 int start()
const {
return start_.Value(); }
368 int end()
const {
return elements_.size(); }
370 int Size()
const {
return elements_.size() - start_.Value(); }
373 void Uninsert(int64_t
value) {
374 for (
int pos = 0; pos < elements_.size(); ++pos) {
375 if (elements_[pos].first ==
value) {
377 const int last = elements_.size() - 1;
379 elements_[pos] = elements_.back();
381 elements_.pop_back();
385 LOG(
FATAL) <<
"The element should have been removed";
390 const int64_t range_min_;
391 NumericalRev<int> start_;
392 std::vector<std::pair<int64_t, T*>> elements_;
396 class BaseValueWatcher :
public Constraint {
398 explicit BaseValueWatcher(Solver*
const solver) : Constraint(solver) {}
400 ~BaseValueWatcher()
override {}
402 virtual IntVar* GetOrMakeValueWatcher(int64_t
value) = 0;
404 virtual void SetValueWatcher(IntVar*
const boolvar, int64_t
value) = 0;
409 class ValueWatcher :
public BaseValueWatcher {
411 class WatchDemon :
public Demon {
413 WatchDemon(ValueWatcher*
const watcher, int64_t
value, IntVar*
var)
414 : value_watcher_(watcher), value_(
value), var_(
var) {}
415 ~WatchDemon()
override {}
417 void Run(Solver*
const solver)
override {
418 value_watcher_->ProcessValueWatcher(value_, var_);
422 ValueWatcher*
const value_watcher_;
423 const int64_t value_;
427 class VarDemon :
public Demon {
429 explicit VarDemon(ValueWatcher*
const watcher)
430 : value_watcher_(watcher) {}
432 ~VarDemon()
override {}
434 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
437 ValueWatcher*
const value_watcher_;
440 ValueWatcher(Solver*
const solver, DomainIntVar*
const variable)
441 : BaseValueWatcher(solver),
443 hole_iterator_(variable_->MakeHoleIterator(true)),
445 watchers_(solver, variable->Min(), variable->Max()) {}
447 ~ValueWatcher()
override {}
449 IntVar* GetOrMakeValueWatcher(int64_t
value)
override {
450 IntVar*
const watcher = watchers_.FindPtrOrNull(
value,
nullptr);
451 if (watcher !=
nullptr)
return watcher;
452 if (variable_->Contains(
value)) {
453 if (variable_->Bound()) {
454 return solver()->MakeIntConst(1);
456 const std::string vname = variable_->HasName()
458 : variable_->DebugString();
459 const std::string bname =
460 absl::StrFormat(
"Watch<%s == %d>", vname,
value);
461 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
462 watchers_.UnsafeRevInsert(
value, boolvar);
463 if (posted_.Switched()) {
465 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
466 var_demon_->desinhibit(solver());
471 return variable_->solver()->MakeIntConst(0);
475 void SetValueWatcher(IntVar*
const boolvar, int64_t
value)
override {
476 CHECK(watchers_.FindPtrOrNull(
value,
nullptr) ==
nullptr);
477 if (!boolvar->Bound()) {
478 watchers_.UnsafeRevInsert(
value, boolvar);
479 if (posted_.Switched() && !boolvar->Bound()) {
481 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
482 var_demon_->desinhibit(solver());
487 void Post()
override {
488 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
489 variable_->WhenDomain(var_demon_);
490 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
491 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
492 const int64_t
value = w.first;
493 IntVar*
const boolvar = w.second;
494 if (!boolvar->Bound() && variable_->Contains(
value)) {
496 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
499 posted_.Switch(solver());
502 void InitialPropagate()
override {
503 if (variable_->Bound()) {
506 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
507 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
508 const int64_t
value = w.first;
509 IntVar*
const boolvar = w.second;
510 if (!variable_->Contains(
value)) {
511 boolvar->SetValue(0);
512 watchers_.RemoveAt(pos);
514 if (boolvar->Bound()) {
515 ProcessValueWatcher(
value, boolvar);
516 watchers_.RemoveAt(pos);
524 void ProcessValueWatcher(int64_t
value, IntVar* boolvar) {
525 if (boolvar->Min() == 0) {
526 if (variable_->Size() < 0xFFFFFF) {
527 variable_->RemoveValue(
value);
530 solver()->AddConstraint(solver()->MakeNonEquality(variable_,
value));
533 variable_->SetValue(
value);
538 const int kSmallList = 16;
539 if (variable_->Bound()) {
541 }
else if (watchers_.Size() <= kSmallList ||
542 variable_->Min() != variable_->OldMin() ||
543 variable_->Max() != variable_->OldMax()) {
553 BitSet*
const bitset = variable_->bitset();
554 if (bitset !=
nullptr && !watchers_.Empty()) {
555 if (bitset->NumHoles() * 2 < watchers_.Size()) {
556 for (
const int64_t hole : InitAndGetValues(hole_iterator_)) {
558 IntVar*
const boolvar = watchers_.FindPtrOrNull(hole, &pos);
559 if (boolvar !=
nullptr) {
560 boolvar->SetValue(0);
561 watchers_.RemoveAt(pos);
573 void VariableBound() {
574 DCHECK(variable_->Bound());
575 const int64_t
value = variable_->Min();
576 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
577 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
578 w.second->SetValue(w.first ==
value);
580 watchers_.RemoveAll();
581 var_demon_->inhibit(solver());
585 void ScanWatchers() {
586 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
587 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
588 if (!variable_->Contains(w.first)) {
589 IntVar*
const boolvar = w.second;
590 boolvar->SetValue(0);
591 watchers_.RemoveAt(pos);
598 void CheckInhibit() {
599 if (watchers_.Empty()) {
600 var_demon_->inhibit(solver());
604 void Accept(ModelVisitor*
const visitor)
const override {
608 std::vector<int64_t> all_coefficients;
609 std::vector<IntVar*> all_bool_vars;
610 for (
int position = watchers_.start(); position < watchers_.end();
612 const std::pair<int64_t, IntVar*>& w = watchers_.At(position);
613 all_coefficients.push_back(w.first);
614 all_bool_vars.push_back(w.second);
623 std::string DebugString()
const override {
624 return absl::StrFormat(
"ValueWatcher(%s)", variable_->DebugString());
628 DomainIntVar*
const variable_;
629 IntVarIterator*
const hole_iterator_;
632 RevIntPtrMap<IntVar> watchers_;
636 class DenseValueWatcher :
public BaseValueWatcher {
638 class WatchDemon :
public Demon {
640 WatchDemon(DenseValueWatcher*
const watcher, int64_t
value, IntVar*
var)
641 : value_watcher_(watcher), value_(
value), var_(
var) {}
642 ~WatchDemon()
override {}
644 void Run(Solver*
const solver)
override {
645 value_watcher_->ProcessValueWatcher(value_, var_);
649 DenseValueWatcher*
const value_watcher_;
650 const int64_t value_;
654 class VarDemon :
public Demon {
656 explicit VarDemon(DenseValueWatcher*
const watcher)
657 : value_watcher_(watcher) {}
659 ~VarDemon()
override {}
661 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
664 DenseValueWatcher*
const value_watcher_;
667 DenseValueWatcher(Solver*
const solver, DomainIntVar*
const variable)
668 : BaseValueWatcher(solver),
670 hole_iterator_(variable_->MakeHoleIterator(true)),
673 watchers_(variable->Max() - variable->Min() + 1, nullptr),
674 active_watchers_(0) {}
676 ~DenseValueWatcher()
override {}
678 IntVar* GetOrMakeValueWatcher(int64_t
value)
override {
679 const int64_t var_max =
offset_ + watchers_.size() - 1;
680 if (value < offset_ || value > var_max) {
681 return solver()->MakeIntConst(0);
684 IntVar*
const watcher = watchers_[
index];
685 if (watcher !=
nullptr)
return watcher;
686 if (variable_->Contains(
value)) {
687 if (variable_->Bound()) {
688 return solver()->MakeIntConst(1);
690 const std::string vname = variable_->HasName()
692 : variable_->DebugString();
693 const std::string bname =
694 absl::StrFormat(
"Watch<%s == %d>", vname,
value);
695 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
696 RevInsert(
index, boolvar);
697 if (posted_.Switched()) {
699 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
700 var_demon_->desinhibit(solver());
705 return variable_->solver()->MakeIntConst(0);
709 void SetValueWatcher(IntVar*
const boolvar, int64_t
value)
override {
712 if (!boolvar->Bound()) {
713 RevInsert(
index, boolvar);
714 if (posted_.Switched() && !boolvar->Bound()) {
716 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
717 var_demon_->desinhibit(solver());
722 void Post()
override {
723 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
724 variable_->WhenDomain(var_demon_);
725 for (
int pos = 0; pos < watchers_.size(); ++pos) {
727 IntVar*
const boolvar = watchers_[pos];
728 if (boolvar !=
nullptr && !boolvar->Bound() &&
729 variable_->Contains(
value)) {
731 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
734 posted_.Switch(solver());
737 void InitialPropagate()
override {
738 if (variable_->Bound()) {
741 for (
int pos = 0; pos < watchers_.size(); ++pos) {
742 IntVar*
const boolvar = watchers_[pos];
743 if (boolvar ==
nullptr)
continue;
745 if (!variable_->Contains(
value)) {
746 boolvar->SetValue(0);
748 }
else if (boolvar->Bound()) {
749 ProcessValueWatcher(
value, boolvar);
753 if (active_watchers_.Value() == 0) {
754 var_demon_->inhibit(solver());
759 void ProcessValueWatcher(int64_t
value, IntVar* boolvar) {
760 if (boolvar->Min() == 0) {
761 variable_->RemoveValue(
value);
763 variable_->SetValue(
value);
768 if (variable_->Bound()) {
773 if (active_watchers_.Value() == 0) {
774 var_demon_->inhibit(solver());
780 void VariableBound() {
781 DCHECK(variable_->Bound());
782 const int64_t
value = variable_->Min();
783 for (
int pos = 0; pos < watchers_.size(); ++pos) {
784 IntVar*
const boolvar = watchers_[pos];
785 if (boolvar !=
nullptr) {
790 var_demon_->inhibit(solver());
794 void ScanWatchers() {
795 const int64_t old_min_index = variable_->OldMin() -
offset_;
796 const int64_t old_max_index = variable_->OldMax() -
offset_;
797 const int64_t min_index = variable_->Min() -
offset_;
798 const int64_t max_index = variable_->Max() -
offset_;
799 for (
int pos = old_min_index; pos < min_index; ++pos) {
800 IntVar*
const boolvar = watchers_[pos];
801 if (boolvar !=
nullptr) {
802 boolvar->SetValue(0);
806 for (
int pos = max_index + 1; pos <= old_max_index; ++pos) {
807 IntVar*
const boolvar = watchers_[pos];
808 if (boolvar !=
nullptr) {
809 boolvar->SetValue(0);
813 BitSet*
const bitset = variable_->bitset();
814 if (bitset !=
nullptr) {
815 if (bitset->NumHoles() * 2 < active_watchers_.Value()) {
816 for (
const int64_t hole : InitAndGetValues(hole_iterator_)) {
817 IntVar*
const boolvar = watchers_[hole -
offset_];
818 if (boolvar !=
nullptr) {
819 boolvar->SetValue(0);
824 for (
int pos = min_index + 1; pos < max_index; ++pos) {
825 IntVar*
const boolvar = watchers_[pos];
826 if (boolvar !=
nullptr && !variable_->Contains(
offset_ + pos)) {
827 boolvar->SetValue(0);
835 void RevRemove(
int pos) {
836 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
837 watchers_[pos] =
nullptr;
838 active_watchers_.Decr(solver());
841 void RevInsert(
int pos, IntVar* boolvar) {
842 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
843 watchers_[pos] = boolvar;
844 active_watchers_.Incr(solver());
847 void Accept(ModelVisitor*
const visitor)
const override {
851 std::vector<int64_t> all_coefficients;
852 std::vector<IntVar*> all_bool_vars;
853 for (
int position = 0; position < watchers_.size(); ++position) {
854 if (watchers_[position] !=
nullptr) {
855 all_coefficients.push_back(position +
offset_);
856 all_bool_vars.push_back(watchers_[position]);
866 std::string DebugString()
const override {
867 return absl::StrFormat(
"DenseValueWatcher(%s)", variable_->DebugString());
871 DomainIntVar*
const variable_;
872 IntVarIterator*
const hole_iterator_;
876 std::vector<IntVar*> watchers_;
877 NumericalRev<int> active_watchers_;
880 class BaseUpperBoundWatcher :
public Constraint {
882 explicit BaseUpperBoundWatcher(Solver*
const solver) : Constraint(solver) {}
884 ~BaseUpperBoundWatcher()
override {}
886 virtual IntVar* GetOrMakeUpperBoundWatcher(int64_t
value) = 0;
888 virtual void SetUpperBoundWatcher(IntVar*
const boolvar, int64_t
value) = 0;
894 class UpperBoundWatcher :
public BaseUpperBoundWatcher {
896 class WatchDemon :
public Demon {
898 WatchDemon(UpperBoundWatcher*
const watcher, int64_t
index,
900 : value_watcher_(watcher), index_(
index), var_(
var) {}
901 ~WatchDemon()
override {}
903 void Run(Solver*
const solver)
override {
904 value_watcher_->ProcessUpperBoundWatcher(index_, var_);
908 UpperBoundWatcher*
const value_watcher_;
909 const int64_t index_;
913 class VarDemon :
public Demon {
915 explicit VarDemon(UpperBoundWatcher*
const watcher)
916 : value_watcher_(watcher) {}
917 ~VarDemon()
override {}
919 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
922 UpperBoundWatcher*
const value_watcher_;
925 UpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
926 : BaseUpperBoundWatcher(solver),
929 watchers_(solver, variable->Min(), variable->Max()),
934 ~UpperBoundWatcher()
override {}
936 IntVar* GetOrMakeUpperBoundWatcher(int64_t
value)
override {
937 IntVar*
const watcher = watchers_.FindPtrOrNull(
value,
nullptr);
938 if (watcher !=
nullptr) {
941 if (variable_->Max() >=
value) {
942 if (variable_->Min() >=
value) {
943 return solver()->MakeIntConst(1);
945 const std::string vname = variable_->HasName()
947 : variable_->DebugString();
948 const std::string bname =
949 absl::StrFormat(
"Watch<%s >= %d>", vname,
value);
950 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
951 watchers_.UnsafeRevInsert(
value, boolvar);
952 if (posted_.Switched()) {
954 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
955 var_demon_->desinhibit(solver());
961 return variable_->solver()->MakeIntConst(0);
965 void SetUpperBoundWatcher(IntVar*
const boolvar, int64_t
value)
override {
966 CHECK(watchers_.FindPtrOrNull(
value,
nullptr) ==
nullptr);
967 watchers_.UnsafeRevInsert(
value, boolvar);
968 if (posted_.Switched() && !boolvar->Bound()) {
970 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
971 var_demon_->desinhibit(solver());
976 void Post()
override {
977 const int kTooSmallToSort = 8;
978 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
979 variable_->WhenRange(var_demon_);
981 if (watchers_.Size() > kTooSmallToSort) {
982 watchers_.SortActive();
984 start_.SetValue(solver(), watchers_.start());
985 end_.SetValue(solver(), watchers_.end() - 1);
988 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
989 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
990 IntVar*
const boolvar = w.second;
991 const int64_t
value = w.first;
992 if (!boolvar->Bound() &&
value > variable_->Min() &&
993 value <= variable_->Max()) {
995 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
998 posted_.Switch(solver());
1001 void InitialPropagate()
override {
1002 const int64_t var_min = variable_->Min();
1003 const int64_t var_max = variable_->Max();
1005 while (start_.Value() <= end_.Value()) {
1006 const std::pair<int64_t, IntVar*>& w = watchers_.At(start_.Value());
1007 if (w.first <= var_min) {
1008 w.second->SetValue(1);
1009 start_.Incr(solver());
1014 while (end_.Value() >= start_.Value()) {
1015 const std::pair<int64_t, IntVar*>& w = watchers_.At(end_.Value());
1016 if (w.first > var_max) {
1017 w.second->SetValue(0);
1018 end_.Decr(solver());
1023 for (
int i = start_.Value(); i <= end_.Value(); ++i) {
1024 const std::pair<int64_t, IntVar*>& w = watchers_.At(i);
1025 if (w.second->Bound()) {
1026 ProcessUpperBoundWatcher(w.first, w.second);
1029 if (start_.Value() > end_.Value()) {
1030 var_demon_->inhibit(solver());
1033 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1034 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
1035 const int64_t
value = w.first;
1036 IntVar*
const boolvar = w.second;
1038 if (
value <= var_min) {
1039 boolvar->SetValue(1);
1040 watchers_.RemoveAt(pos);
1041 }
else if (
value > var_max) {
1042 boolvar->SetValue(0);
1043 watchers_.RemoveAt(pos);
1044 }
else if (boolvar->Bound()) {
1045 ProcessUpperBoundWatcher(
value, boolvar);
1046 watchers_.RemoveAt(pos);
1052 void Accept(ModelVisitor*
const visitor)
const override {
1056 std::vector<int64_t> all_coefficients;
1057 std::vector<IntVar*> all_bool_vars;
1058 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1059 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
1060 all_coefficients.push_back(w.first);
1061 all_bool_vars.push_back(w.second);
1070 std::string DebugString()
const override {
1071 return absl::StrFormat(
"UpperBoundWatcher(%s)", variable_->DebugString());
1075 void ProcessUpperBoundWatcher(int64_t
value, IntVar*
const boolvar) {
1076 if (boolvar->Min() == 0) {
1077 variable_->SetMax(
value - 1);
1079 variable_->SetMin(
value);
1084 const int64_t var_min = variable_->Min();
1085 const int64_t var_max = variable_->Max();
1087 while (start_.Value() <= end_.Value()) {
1088 const std::pair<int64_t, IntVar*>& w = watchers_.At(start_.Value());
1089 if (w.first <= var_min) {
1090 w.second->SetValue(1);
1091 start_.Incr(solver());
1096 while (end_.Value() >= start_.Value()) {
1097 const std::pair<int64_t, IntVar*>& w = watchers_.At(end_.Value());
1098 if (w.first > var_max) {
1099 w.second->SetValue(0);
1100 end_.Decr(solver());
1105 if (start_.Value() > end_.Value()) {
1106 var_demon_->inhibit(solver());
1109 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1110 const std::pair<int64_t, IntVar*>& w = watchers_.At(pos);
1111 const int64_t
value = w.first;
1112 IntVar*
const boolvar = w.second;
1114 if (
value <= var_min) {
1115 boolvar->SetValue(1);
1116 watchers_.RemoveAt(pos);
1117 }
else if (
value > var_max) {
1118 boolvar->SetValue(0);
1119 watchers_.RemoveAt(pos);
1122 if (watchers_.Empty()) {
1123 var_demon_->inhibit(solver());
1128 DomainIntVar*
const variable_;
1131 RevIntPtrMap<IntVar> watchers_;
1132 NumericalRev<int> start_;
1133 NumericalRev<int> end_;
1138 class DenseUpperBoundWatcher :
public BaseUpperBoundWatcher {
1140 class WatchDemon :
public Demon {
1142 WatchDemon(DenseUpperBoundWatcher*
const watcher, int64_t
value,
1144 : value_watcher_(watcher), value_(
value), var_(
var) {}
1145 ~WatchDemon()
override {}
1147 void Run(Solver*
const solver)
override {
1148 value_watcher_->ProcessUpperBoundWatcher(value_, var_);
1152 DenseUpperBoundWatcher*
const value_watcher_;
1153 const int64_t value_;
1157 class VarDemon :
public Demon {
1159 explicit VarDemon(DenseUpperBoundWatcher*
const watcher)
1160 : value_watcher_(watcher) {}
1162 ~VarDemon()
override {}
1164 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
1167 DenseUpperBoundWatcher*
const value_watcher_;
1170 DenseUpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
1171 : BaseUpperBoundWatcher(solver),
1172 variable_(variable),
1173 var_demon_(nullptr),
1175 watchers_(variable->Max() - variable->Min() + 1, nullptr),
1176 active_watchers_(0) {}
1178 ~DenseUpperBoundWatcher()
override {}
1180 IntVar* GetOrMakeUpperBoundWatcher(int64_t
value)
override {
1181 if (variable_->Max() >=
value) {
1182 if (variable_->Min() >=
value) {
1183 return solver()->MakeIntConst(1);
1185 const std::string vname = variable_->HasName()
1187 : variable_->DebugString();
1188 const std::string bname =
1189 absl::StrFormat(
"Watch<%s >= %d>", vname,
value);
1190 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
1192 if (posted_.Switched()) {
1194 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
1195 var_demon_->desinhibit(solver());
1200 return variable_->solver()->MakeIntConst(0);
1204 void SetUpperBoundWatcher(IntVar*
const boolvar, int64_t
value)
override {
1207 if (!boolvar->Bound()) {
1208 RevInsert(
index, boolvar);
1209 if (posted_.Switched() && !boolvar->Bound()) {
1211 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
1212 var_demon_->desinhibit(solver());
1217 void Post()
override {
1218 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
1219 variable_->WhenRange(var_demon_);
1220 for (
int pos = 0; pos < watchers_.size(); ++pos) {
1222 IntVar*
const boolvar = watchers_[pos];
1223 if (boolvar !=
nullptr && !boolvar->Bound() &&
1224 value > variable_->Min() && value <= variable_->Max()) {
1226 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
1229 posted_.Switch(solver());
1232 void InitialPropagate()
override {
1233 for (
int pos = 0; pos < watchers_.size(); ++pos) {
1234 IntVar*
const boolvar = watchers_[pos];
1235 if (boolvar ==
nullptr)
continue;
1237 if (value <= variable_->Min()) {
1238 boolvar->SetValue(1);
1240 }
else if (
value > variable_->Max()) {
1241 boolvar->SetValue(0);
1243 }
else if (boolvar->Bound()) {
1244 ProcessUpperBoundWatcher(
value, boolvar);
1248 if (active_watchers_.Value() == 0) {
1249 var_demon_->inhibit(solver());
1253 void ProcessUpperBoundWatcher(int64_t
value, IntVar* boolvar) {
1254 if (boolvar->Min() == 0) {
1255 variable_->SetMax(
value - 1);
1257 variable_->SetMin(
value);
1262 const int64_t old_min_index = variable_->OldMin() -
offset_;
1263 const int64_t old_max_index = variable_->OldMax() -
offset_;
1264 const int64_t min_index = variable_->Min() -
offset_;
1265 const int64_t max_index = variable_->Max() -
offset_;
1266 for (
int pos = old_min_index; pos <= min_index; ++pos) {
1267 IntVar*
const boolvar = watchers_[pos];
1268 if (boolvar !=
nullptr) {
1269 boolvar->SetValue(1);
1274 for (
int pos = max_index + 1; pos <= old_max_index; ++pos) {
1275 IntVar*
const boolvar = watchers_[pos];
1276 if (boolvar !=
nullptr) {
1277 boolvar->SetValue(0);
1281 if (active_watchers_.Value() == 0) {
1282 var_demon_->inhibit(solver());
1286 void RevRemove(
int pos) {
1287 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
1288 watchers_[pos] =
nullptr;
1289 active_watchers_.Decr(solver());
1292 void RevInsert(
int pos, IntVar* boolvar) {
1293 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
1294 watchers_[pos] = boolvar;
1295 active_watchers_.Incr(solver());
1298 void Accept(ModelVisitor*
const visitor)
const override {
1302 std::vector<int64_t> all_coefficients;
1303 std::vector<IntVar*> all_bool_vars;
1304 for (
int position = 0; position < watchers_.size(); ++position) {
1305 if (watchers_[position] !=
nullptr) {
1306 all_coefficients.push_back(position +
offset_);
1307 all_bool_vars.push_back(watchers_[position]);
1317 std::string DebugString()
const override {
1318 return absl::StrFormat(
"DenseUpperBoundWatcher(%s)",
1319 variable_->DebugString());
1323 DomainIntVar*
const variable_;
1327 std::vector<IntVar*> watchers_;
1328 NumericalRev<int> active_watchers_;
1332 DomainIntVar(Solver*
const s, int64_t vmin, int64_t vmax,
1333 const std::string&
name);
1334 DomainIntVar(Solver*
const s,
const std::vector<int64_t>& sorted_values,
1335 const std::string&
name);
1336 ~DomainIntVar()
override;
1338 int64_t Min()
const override {
return min_.Value(); }
1339 void SetMin(int64_t m)
override;
1340 int64_t Max()
const override {
return max_.Value(); }
1341 void SetMax(int64_t m)
override;
1342 void SetRange(int64_t mi, int64_t ma)
override;
1343 void SetValue(int64_t v)
override;
1344 bool Bound()
const override {
return (min_.Value() == max_.Value()); }
1345 int64_t
Value()
const override {
1346 CHECK_EQ(min_.Value(), max_.Value())
1347 <<
" variable " << DebugString() <<
" is not bound.";
1348 return min_.Value();
1350 void RemoveValue(int64_t v)
override;
1351 void RemoveInterval(int64_t l, int64_t u)
override;
1353 void WhenBound(Demon* d)
override {
1354 if (min_.Value() != max_.Value()) {
1356 delayed_bound_demons_.PushIfNotTop(solver(),
1359 bound_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1363 void WhenRange(Demon* d)
override {
1364 if (min_.Value() != max_.Value()) {
1366 delayed_range_demons_.PushIfNotTop(solver(),
1369 range_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1373 void WhenDomain(Demon* d)
override {
1374 if (min_.Value() != max_.Value()) {
1376 delayed_domain_demons_.PushIfNotTop(solver(),
1379 domain_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1384 IntVar* IsEqual(int64_t constant)
override {
1385 Solver*
const s = solver();
1386 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1387 return s->MakeIsLessOrEqualCstVar(
this, constant);
1389 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1390 return s->MakeIsGreaterOrEqualCstVar(
this, constant);
1392 if (!Contains(constant)) {
1393 return s->MakeIntConst(int64_t{0});
1395 if (Bound() && min_.Value() == constant) {
1396 return s->MakeIntConst(int64_t{1});
1398 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1400 if (cache !=
nullptr) {
1401 return cache->Var();
1403 if (value_watcher_ ==
nullptr) {
1404 if (
CapSub(Max(), Min()) <= 256) {
1405 solver()->SaveAndSetValue(
1406 reinterpret_cast<void**
>(&value_watcher_),
1407 reinterpret_cast<void*
>(
1408 solver()->RevAlloc(
new DenseValueWatcher(solver(),
this))));
1411 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1412 reinterpret_cast<void*
>(solver()->RevAlloc(
1413 new ValueWatcher(solver(),
this))));
1415 solver()->AddConstraint(value_watcher_);
1417 IntVar*
const boolvar = value_watcher_->GetOrMakeValueWatcher(constant);
1418 s->Cache()->InsertExprConstantExpression(
1424 Constraint*
SetIsEqual(
const std::vector<int64_t>& values,
1425 const std::vector<IntVar*>& vars) {
1426 if (value_watcher_ ==
nullptr) {
1427 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1428 reinterpret_cast<void*
>(solver()->RevAlloc(
1429 new ValueWatcher(solver(),
this))));
1430 for (
int i = 0; i < vars.size(); ++i) {
1431 value_watcher_->SetValueWatcher(vars[i], values[i]);
1434 return value_watcher_;
1437 IntVar* IsDifferent(int64_t constant)
override {
1438 Solver*
const s = solver();
1439 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1440 return s->MakeIsGreaterOrEqualCstVar(
this, constant + 1);
1442 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1443 return s->MakeIsLessOrEqualCstVar(
this, constant - 1);
1445 if (!Contains(constant)) {
1446 return s->MakeIntConst(int64_t{1});
1448 if (Bound() && min_.Value() == constant) {
1449 return s->MakeIntConst(int64_t{0});
1451 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1453 if (cache !=
nullptr) {
1454 return cache->Var();
1456 IntVar*
const boolvar = s->MakeDifference(1, IsEqual(constant))->Var();
1457 s->Cache()->InsertExprConstantExpression(
1463 IntVar* IsGreaterOrEqual(int64_t constant)
override {
1464 Solver*
const s = solver();
1465 if (max_.Value() < constant) {
1466 return s->MakeIntConst(int64_t{0});
1468 if (min_.Value() >= constant) {
1469 return s->MakeIntConst(int64_t{1});
1471 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1473 if (cache !=
nullptr) {
1474 return cache->Var();
1476 if (bound_watcher_ ==
nullptr) {
1477 if (
CapSub(Max(), Min()) <= 256) {
1478 solver()->SaveAndSetValue(
1479 reinterpret_cast<void**
>(&bound_watcher_),
1480 reinterpret_cast<void*
>(solver()->RevAlloc(
1481 new DenseUpperBoundWatcher(solver(),
this))));
1482 solver()->AddConstraint(bound_watcher_);
1484 solver()->SaveAndSetValue(
1485 reinterpret_cast<void**
>(&bound_watcher_),
1486 reinterpret_cast<void*
>(
1487 solver()->RevAlloc(
new UpperBoundWatcher(solver(),
this))));
1488 solver()->AddConstraint(bound_watcher_);
1491 IntVar*
const boolvar =
1492 bound_watcher_->GetOrMakeUpperBoundWatcher(constant);
1493 s->Cache()->InsertExprConstantExpression(
1494 boolvar,
this, constant,
1501 const std::vector<IntVar*>& vars) {
1502 if (bound_watcher_ ==
nullptr) {
1503 if (
CapSub(Max(), Min()) <= 256) {
1504 solver()->SaveAndSetValue(
1505 reinterpret_cast<void**
>(&bound_watcher_),
1506 reinterpret_cast<void*
>(solver()->RevAlloc(
1507 new DenseUpperBoundWatcher(solver(),
this))));
1508 solver()->AddConstraint(bound_watcher_);
1510 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&bound_watcher_),
1511 reinterpret_cast<void*
>(solver()->RevAlloc(
1512 new UpperBoundWatcher(solver(),
this))));
1513 solver()->AddConstraint(bound_watcher_);
1515 for (
int i = 0; i < values.size(); ++i) {
1516 bound_watcher_->SetUpperBoundWatcher(vars[i], values[i]);
1519 return bound_watcher_;
1522 IntVar* IsLessOrEqual(int64_t constant)
override {
1523 Solver*
const s = solver();
1524 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1526 if (cache !=
nullptr) {
1527 return cache->Var();
1529 IntVar*
const boolvar =
1530 s->MakeDifference(1, IsGreaterOrEqual(constant + 1))->Var();
1531 s->Cache()->InsertExprConstantExpression(
1539 void CleanInProcess();
1540 uint64_t Size()
const override {
1541 if (bits_ !=
nullptr)
return bits_->Size();
1542 return (
static_cast<uint64_t
>(max_.Value()) -
1543 static_cast<uint64_t
>(min_.Value()) + 1);
1545 bool Contains(int64_t v)
const override {
1546 if (v < min_.Value() || v > max_.Value())
return false;
1547 return (bits_ ==
nullptr ?
true : bits_->Contains(v));
1549 IntVarIterator* MakeHoleIterator(
bool reversible)
const override;
1550 IntVarIterator* MakeDomainIterator(
bool reversible)
const override;
1551 int64_t OldMin()
const override {
return std::min(old_min_, min_.Value()); }
1552 int64_t OldMax()
const override {
return std::max(old_max_, max_.Value()); }
1554 std::string DebugString()
const override;
1555 BitSet* bitset()
const {
return bits_; }
1557 std::string BaseName()
const override {
return "IntegerVar"; }
1559 friend class PlusCstDomainIntVar;
1560 friend class LinkExprAndDomainIntVar;
1563 void CheckOldMin() {
1564 if (old_min_ > min_.Value()) {
1565 old_min_ = min_.Value();
1568 void CheckOldMax() {
1569 if (old_max_ < max_.Value()) {
1570 old_max_ = max_.Value();
1579 SimpleRevFIFO<Demon*> bound_demons_;
1580 SimpleRevFIFO<Demon*> range_demons_;
1581 SimpleRevFIFO<Demon*> domain_demons_;
1582 SimpleRevFIFO<Demon*> delayed_bound_demons_;
1583 SimpleRevFIFO<Demon*> delayed_range_demons_;
1584 SimpleRevFIFO<Demon*> delayed_domain_demons_;
1588 BaseValueWatcher* value_watcher_;
1589 BaseUpperBoundWatcher* bound_watcher_;
1598inline bool ClosedIntervalNoLargerThan(int64_t
a, int64_t
b, int64_t K) {
1608class SimpleBitSet :
public DomainIntVar::BitSet {
1610 SimpleBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1616 size_(vmax - vmin + 1),
1618 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1619 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1620 bits_ =
new uint64_t[bsize_];
1621 stamps_ =
new uint64_t[bsize_];
1622 for (
int i = 0; i < bsize_; ++i) {
1624 (i == size_.Value() - 1) ? 63 -
BitPos64(size_.Value()) : 0;
1626 stamps_[i] = s->stamp() - 1;
1630 SimpleBitSet(Solver*
const s,
const std::vector<int64_t>& sorted_values,
1631 int64_t vmin, int64_t vmax)
1637 size_(sorted_values.size()),
1639 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1640 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1641 bits_ =
new uint64_t[bsize_];
1642 stamps_ =
new uint64_t[bsize_];
1643 for (
int i = 0; i < bsize_; ++i) {
1644 bits_[i] = uint64_t{0};
1645 stamps_[i] = s->stamp() - 1;
1647 for (
int i = 0; i < sorted_values.size(); ++i) {
1648 const int64_t val = sorted_values[i];
1651 const int pos =
BitPos64(val - omin_);
1656 ~SimpleBitSet()
override {
1661 bool bit(int64_t val)
const {
return IsBitSet64(bits_, val - omin_); }
1663 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1669 const int64_t new_min =
1672 const uint64_t removed_bits =
1674 size_.Add(
solver_, -removed_bits);
1678 int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax)
override {
1684 const int64_t new_max =
1687 const uint64_t removed_bits =
1689 size_.Add(
solver_, -removed_bits);
1693 bool SetValue(int64_t val)
override {
1703 bool Contains(int64_t val)
const override {
1709 bool RemoveValue(int64_t val)
override {
1710 if (val < omin_ || val > omax_ || !bit(val)) {
1714 const int64_t val_offset = val - omin_;
1716 const uint64_t current_stamp =
solver_->stamp();
1717 if (stamps_[offset] < current_stamp) {
1718 stamps_[offset] = current_stamp;
1719 solver_->SaveValue(&bits_[offset]);
1721 const int pos =
BitPos64(val_offset);
1722 bits_[offset] &= ~OneBit64(pos);
1730 uint64_t Size()
const override {
return size_.Value(); }
1732 std::string DebugString()
const override {
1734 absl::StrAppendFormat(&out,
"SimpleBitSet(%d..%d : ", omin_, omax_);
1735 for (
int i = 0; i < bsize_; ++i) {
1736 absl::StrAppendFormat(&out,
"%x", bits_[i]);
1742 void DelayRemoveValue(int64_t val)
override { removed_.push_back(val); }
1744 void ApplyRemovedValues(DomainIntVar*
var)
override {
1745 std::sort(removed_.begin(), removed_.end());
1746 for (std::vector<int64_t>::iterator it = removed_.begin();
1747 it != removed_.end(); ++it) {
1748 var->RemoveValue(*it);
1752 void ClearRemovedValues()
override { removed_.clear(); }
1754 std::string pretty_DebugString(int64_t
min, int64_t
max)
const override {
1760 int64_t start_cumul =
min;
1761 for (int64_t v =
min + 1; v <
max; ++v) {
1769 if (v == start_cumul + 1) {
1770 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1771 }
else if (v == start_cumul + 2) {
1772 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1774 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1781 if (
max == start_cumul + 1) {
1782 absl::StrAppendFormat(&out,
"%d %d", start_cumul,
max);
1784 absl::StrAppendFormat(&out,
"%d..%d", start_cumul,
max);
1787 absl::StrAppendFormat(&out,
"%d",
max);
1790 absl::StrAppendFormat(&out,
"%d",
min);
1795 DomainIntVar::BitSetIterator* MakeIterator()
override {
1796 return new DomainIntVar::BitSetIterator(bits_, omin_);
1802 const int64_t omin_;
1803 const int64_t omax_;
1804 NumericalRev<int64_t> size_;
1806 std::vector<int64_t> removed_;
1812class SmallBitSet :
public DomainIntVar::BitSet {
1814 SmallBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1820 size_(vmax - vmin + 1) {
1821 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1825 SmallBitSet(Solver*
const s,
const std::vector<int64_t>& sorted_values,
1826 int64_t vmin, int64_t vmax)
1832 size_(sorted_values.size()) {
1833 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1835 for (
int i = 0; i < sorted_values.size(); ++i) {
1836 const int64_t val = sorted_values[i];
1844 ~SmallBitSet()
override {}
1846 bool bit(int64_t val)
const {
1849 return (bits_ &
OneBit64(val - omin_)) != 0;
1852 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1862 const uint64_t new_bits = bits_ &
OneRange64(nmin - omin_, cmax - omin_);
1863 if (new_bits != uint64_t{0}) {
1876 int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax)
override {
1886 const uint64_t new_bits = bits_ &
OneRange64(cmin - omin_, nmax - omin_);
1887 if (new_bits != uint64_t{0}) {
1900 bool SetValue(int64_t val)
override {
1912 bool Contains(int64_t val)
const override {
1918 bool RemoveValue(int64_t val)
override {
1923 const uint64_t current_stamp =
solver_->stamp();
1924 if (
stamp_ < current_stamp) {
1928 bits_ &= ~OneBit64(val - omin_);
1941 uint64_t Size()
const override {
return size_.Value(); }
1943 std::string DebugString()
const override {
1944 return absl::StrFormat(
"SmallBitSet(%d..%d : %llx)", omin_, omax_, bits_);
1947 void DelayRemoveValue(int64_t val)
override {
1950 removed_.push_back(val);
1953 void ApplyRemovedValues(DomainIntVar*
var)
override {
1954 std::sort(removed_.begin(), removed_.end());
1955 for (std::vector<int64_t>::iterator it = removed_.begin();
1956 it != removed_.end(); ++it) {
1957 var->RemoveValue(*it);
1961 void ClearRemovedValues()
override { removed_.clear(); }
1963 std::string pretty_DebugString(int64_t
min, int64_t
max)
const override {
1969 int64_t start_cumul =
min;
1970 for (int64_t v =
min + 1; v <
max; ++v) {
1978 if (v == start_cumul + 1) {
1979 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1980 }
else if (v == start_cumul + 2) {
1981 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1983 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1990 if (
max == start_cumul + 1) {
1991 absl::StrAppendFormat(&out,
"%d %d", start_cumul,
max);
1993 absl::StrAppendFormat(&out,
"%d..%d", start_cumul,
max);
1996 absl::StrAppendFormat(&out,
"%d",
max);
1999 absl::StrAppendFormat(&out,
"%d",
min);
2004 DomainIntVar::BitSetIterator* MakeIterator()
override {
2005 return new DomainIntVar::BitSetIterator(&bits_, omin_);
2011 const int64_t omin_;
2012 const int64_t omax_;
2013 NumericalRev<int64_t> size_;
2014 std::vector<int64_t> removed_;
2017class EmptyIterator :
public IntVarIterator {
2019 ~EmptyIterator()
override {}
2020 void Init()
override {}
2021 bool Ok()
const override {
return false; }
2022 int64_t
Value()
const override {
2023 LOG(
FATAL) <<
"Should not be called";
2026 void Next()
override {}
2029class RangeIterator :
public IntVarIterator {
2031 explicit RangeIterator(
const IntVar*
const var)
2033 min_(
std::numeric_limits<int64_t>::
max()),
2034 max_(
std::numeric_limits<int64_t>::
min()),
2037 ~RangeIterator()
override {}
2039 void Init()
override {
2045 bool Ok()
const override {
return current_ <= max_; }
2049 void Next()
override {
current_++; }
2052 const IntVar*
const var_;
2058class DomainIntVarHoleIterator :
public IntVarIterator {
2060 explicit DomainIntVarHoleIterator(
const DomainIntVar*
const v)
2061 : var_(v), bits_(nullptr), values_(nullptr), size_(0), index_(0) {}
2063 ~DomainIntVarHoleIterator()
override {}
2065 void Init()
override {
2066 bits_ = var_->bitset();
2067 if (bits_ !=
nullptr) {
2069 values_ = bits_->Holes().data();
2070 size_ = bits_->Holes().size();
2078 bool Ok()
const override {
return index_ < size_; }
2080 int64_t
Value()
const override {
2081 DCHECK(bits_ !=
nullptr);
2083 return values_[index_];
2086 void Next()
override { index_++; }
2089 const DomainIntVar*
const var_;
2090 DomainIntVar::BitSet* bits_;
2091 const int64_t* values_;
2096class DomainIntVarDomainIterator :
public IntVarIterator {
2098 explicit DomainIntVarDomainIterator(
const DomainIntVar*
const v,
2101 bitset_iterator_(nullptr),
2102 min_(
std::numeric_limits<int64_t>::
max()),
2103 max_(
std::numeric_limits<int64_t>::
min()),
2105 reversible_(reversible) {}
2107 ~DomainIntVarDomainIterator()
override {
2108 if (!reversible_ && bitset_iterator_) {
2109 delete bitset_iterator_;
2113 void Init()
override {
2114 if (var_->bitset() !=
nullptr && !var_->Bound()) {
2116 if (!bitset_iterator_) {
2117 Solver*
const solver = var_->solver();
2118 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2119 bitset_iterator_ = solver->RevAlloc(var_->bitset()->MakeIterator());
2122 if (bitset_iterator_) {
2123 delete bitset_iterator_;
2125 bitset_iterator_ = var_->bitset()->MakeIterator();
2127 bitset_iterator_->Init(var_->Min(), var_->Max());
2129 if (bitset_iterator_) {
2131 Solver*
const solver = var_->solver();
2132 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2134 delete bitset_iterator_;
2136 bitset_iterator_ =
nullptr;
2144 bool Ok()
const override {
2145 return bitset_iterator_ ? bitset_iterator_->Ok() : (
current_ <= max_);
2148 int64_t
Value()
const override {
2149 return bitset_iterator_ ? bitset_iterator_->Value() :
current_;
2152 void Next()
override {
2153 if (bitset_iterator_) {
2154 bitset_iterator_->Next();
2161 const DomainIntVar*
const var_;
2162 DomainIntVar::BitSetIterator* bitset_iterator_;
2166 const bool reversible_;
2169class UnaryIterator :
public IntVarIterator {
2171 UnaryIterator(
const IntVar*
const v,
bool hole,
bool reversible)
2172 :
iterator_(hole ? v->MakeHoleIterator(reversible)
2173 : v->MakeDomainIterator(reversible)),
2174 reversible_(reversible) {}
2176 ~UnaryIterator()
override {
2182 void Init()
override {
iterator_->Init(); }
2184 bool Ok()
const override {
return iterator_->Ok(); }
2186 void Next()
override {
iterator_->Next(); }
2190 const bool reversible_;
2193DomainIntVar::DomainIntVar(Solver*
const s, int64_t vmin, int64_t vmax,
2194 const std::string&
name)
2205 value_watcher_(nullptr),
2206 bound_watcher_(nullptr) {}
2208DomainIntVar::DomainIntVar(Solver*
const s,
2209 const std::vector<int64_t>& sorted_values,
2210 const std::string&
name)
2212 min_(
std::numeric_limits<int64_t>::
max()),
2213 max_(
std::numeric_limits<int64_t>::
min()),
2214 old_min_(
std::numeric_limits<int64_t>::
max()),
2215 old_max_(
std::numeric_limits<int64_t>::
min()),
2216 new_min_(
std::numeric_limits<int64_t>::
max()),
2217 new_max_(
std::numeric_limits<int64_t>::
min()),
2221 value_watcher_(nullptr),
2222 bound_watcher_(nullptr) {
2225 const int64_t vmin = sorted_values.front();
2226 const int64_t vmax = sorted_values.back();
2227 const bool contiguous = vmax - vmin + 1 == sorted_values.size();
2229 min_.SetValue(solver(), vmin);
2232 max_.SetValue(solver(), vmax);
2237 if (vmax - vmin + 1 < 65) {
2238 bits_ = solver()->RevAlloc(
2239 new SmallBitSet(solver(), sorted_values, vmin, vmax));
2241 bits_ = solver()->RevAlloc(
2242 new SimpleBitSet(solver(), sorted_values, vmin, vmax));
2247DomainIntVar::~DomainIntVar() {}
2249void DomainIntVar::SetMin(int64_t m) {
2250 if (m <= min_.Value())
return;
2251 if (m > max_.Value()) solver()->Fail();
2255 if (new_min_ > new_max_) {
2261 const int64_t new_min =
2264 : bits_->ComputeNewMin(m, min_.Value(), max_.Value()));
2265 min_.SetValue(solver(), new_min);
2266 if (min_.Value() > max_.Value()) {
2273void DomainIntVar::SetMax(int64_t m) {
2274 if (m >= max_.Value())
return;
2275 if (m < min_.Value()) solver()->Fail();
2279 if (new_max_ < new_min_) {
2285 const int64_t new_max =
2288 : bits_->ComputeNewMax(m, min_.Value(), max_.Value()));
2289 max_.SetValue(solver(), new_max);
2290 if (min_.Value() > max_.Value()) {
2297void DomainIntVar::SetRange(int64_t mi, int64_t ma) {
2301 if (mi > ma || mi > max_.Value() || ma < min_.Value()) solver()->Fail();
2302 if (mi <= min_.Value() && ma >= max_.Value())
return;
2304 if (ma < new_max_) {
2307 if (mi > new_min_) {
2310 if (new_min_ > new_max_) {
2314 if (mi > min_.Value()) {
2316 const int64_t new_min =
2319 : bits_->ComputeNewMin(mi, min_.Value(), max_.Value()));
2320 min_.SetValue(solver(), new_min);
2322 if (min_.Value() > ma) {
2325 if (ma < max_.Value()) {
2327 const int64_t new_max =
2330 : bits_->ComputeNewMax(ma, min_.Value(), max_.Value()));
2331 max_.SetValue(solver(), new_max);
2333 if (min_.Value() > max_.Value()) {
2341void DomainIntVar::SetValue(int64_t v) {
2342 if (v != min_.Value() || v != max_.Value()) {
2343 if (v < min_.Value() || v > max_.Value()) {
2347 if (v > new_max_ || v < new_min_) {
2353 if (bits_ && !bits_->SetValue(v)) {
2358 min_.SetValue(solver(), v);
2359 max_.SetValue(solver(), v);
2365void DomainIntVar::RemoveValue(int64_t v) {
2366 if (v < min_.Value() || v > max_.Value())
return;
2367 if (v == min_.Value()) {
2369 }
else if (v == max_.Value()) {
2372 if (bits_ ==
nullptr) {
2376 if (v >= new_min_ && v <= new_max_ && bits_->Contains(v)) {
2377 bits_->DelayRemoveValue(v);
2380 if (bits_->RemoveValue(v)) {
2387void DomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2388 if (l <= min_.Value()) {
2390 }
else if (u >= max_.Value()) {
2393 for (int64_t v = l; v <= u; ++v) {
2399void DomainIntVar::CreateBits() {
2400 solver()->SaveValue(
reinterpret_cast<void**
>(&bits_));
2401 if (max_.Value() - min_.Value() < 64) {
2402 bits_ = solver()->RevAlloc(
2403 new SmallBitSet(solver(), min_.Value(), max_.Value()));
2405 bits_ = solver()->RevAlloc(
2406 new SimpleBitSet(solver(), min_.Value(), max_.Value()));
2410void DomainIntVar::CleanInProcess() {
2412 if (bits_ !=
nullptr) {
2413 bits_->ClearHoles();
2417void DomainIntVar::Push() {
2423void DomainIntVar::Process() {
2426 if (bits_ !=
nullptr) {
2427 bits_->ClearRemovedValues();
2429 set_variable_to_clean_on_fail(
this);
2430 new_min_ = min_.Value();
2431 new_max_ = max_.Value();
2432 const bool is_bound = min_.Value() == max_.Value();
2433 const bool range_changed =
2434 min_.Value() != OldMin() || max_.Value() != OldMax();
2437 ExecuteAll(bound_demons_);
2439 if (range_changed) {
2440 ExecuteAll(range_demons_);
2442 ExecuteAll(domain_demons_);
2446 EnqueueAll(delayed_bound_demons_);
2448 if (range_changed) {
2449 EnqueueAll(delayed_range_demons_);
2451 EnqueueAll(delayed_domain_demons_);
2454 set_variable_to_clean_on_fail(
nullptr);
2456 old_min_ = min_.Value();
2457 old_max_ = max_.Value();
2458 if (min_.Value() < new_min_) {
2461 if (max_.Value() > new_max_) {
2464 if (bits_ !=
nullptr) {
2465 bits_->ApplyRemovedValues(
this);
2469#define COND_REV_ALLOC(rev, alloc) rev ? solver()->RevAlloc(alloc) : alloc;
2471IntVarIterator* DomainIntVar::MakeHoleIterator(
bool reversible)
const {
2472 return COND_REV_ALLOC(reversible,
new DomainIntVarHoleIterator(
this));
2475IntVarIterator* DomainIntVar::MakeDomainIterator(
bool reversible)
const {
2477 new DomainIntVarDomainIterator(
this, reversible));
2480std::string DomainIntVar::DebugString()
const {
2482 const std::string& var_name =
name();
2483 if (!var_name.empty()) {
2484 out = var_name +
"(";
2486 out =
"DomainIntVar(";
2488 if (min_.Value() == max_.Value()) {
2489 absl::StrAppendFormat(&out,
"%d", min_.Value());
2490 }
else if (bits_ !=
nullptr) {
2491 out.append(bits_->pretty_DebugString(min_.Value(), max_.Value()));
2493 absl::StrAppendFormat(&out,
"%d..%d", min_.Value(), max_.Value());
2501class ConcreteBooleanVar :
public BooleanVar {
2504 class Handler :
public Demon {
2506 explicit Handler(ConcreteBooleanVar*
const var) : Demon(), var_(
var) {}
2507 ~Handler()
override {}
2508 void Run(Solver*
const s)
override {
2509 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
2511 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
2513 Solver::DemonPriority priority()
const override {
2514 return Solver::VAR_PRIORITY;
2516 std::string DebugString()
const override {
2517 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
2521 ConcreteBooleanVar*
const var_;
2524 ConcreteBooleanVar(Solver*
const s,
const std::string&
name)
2527 ~ConcreteBooleanVar()
override {}
2529 void SetValue(int64_t v)
override {
2530 if (value_ == kUnboundBooleanVarValue) {
2531 if ((v & 0xfffffffffffffffe) == 0) {
2533 value_ =
static_cast<int>(v);
2537 }
else if (v == value_) {
2544 DCHECK_NE(value_, kUnboundBooleanVarValue);
2545 ExecuteAll(bound_demons_);
2546 for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_); it.ok();
2548 EnqueueDelayedDemon(*it);
2552 int64_t OldMin()
const override {
return 0LL; }
2553 int64_t OldMax()
const override {
return 1LL; }
2554 void RestoreValue()
override { value_ = kUnboundBooleanVarValue; }
2562class IntConst :
public IntVar {
2564 IntConst(Solver*
const s, int64_t
value,
const std::string&
name =
"")
2566 ~IntConst()
override {}
2568 int64_t Min()
const override {
return value_; }
2569 void SetMin(int64_t m)
override {
2574 int64_t Max()
const override {
return value_; }
2575 void SetMax(int64_t m)
override {
2580 void SetRange(int64_t l, int64_t u)
override {
2581 if (l > value_ || u < value_) {
2585 void SetValue(int64_t v)
override {
2590 bool Bound()
const override {
return true; }
2591 int64_t
Value()
const override {
return value_; }
2592 void RemoveValue(int64_t v)
override {
2597 void RemoveInterval(int64_t l, int64_t u)
override {
2598 if (l <= value_ && value_ <= u) {
2602 void WhenBound(Demon* d)
override {}
2603 void WhenRange(Demon* d)
override {}
2604 void WhenDomain(Demon* d)
override {}
2605 uint64_t Size()
const override {
return 1; }
2606 bool Contains(int64_t v)
const override {
return (v == value_); }
2607 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2610 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2613 int64_t OldMin()
const override {
return value_; }
2614 int64_t OldMax()
const override {
return value_; }
2615 std::string DebugString()
const override {
2617 if (solver()->HasName(
this)) {
2618 const std::string& var_name =
name();
2619 absl::StrAppendFormat(&out,
"%s(%d)", var_name, value_);
2621 absl::StrAppendFormat(&out,
"IntConst(%d)", value_);
2626 int VarType()
const override {
return CONST_VAR; }
2628 IntVar* IsEqual(int64_t constant)
override {
2629 if (constant == value_) {
2630 return solver()->MakeIntConst(1);
2632 return solver()->MakeIntConst(0);
2636 IntVar* IsDifferent(int64_t constant)
override {
2637 if (constant == value_) {
2638 return solver()->MakeIntConst(0);
2640 return solver()->MakeIntConst(1);
2644 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2645 return solver()->MakeIntConst(value_ >= constant);
2648 IntVar* IsLessOrEqual(int64_t constant)
override {
2649 return solver()->MakeIntConst(value_ <= constant);
2652 std::string
name()
const override {
2653 if (solver()->HasName(
this)) {
2656 return absl::StrCat(value_);
2666class PlusCstVar :
public IntVar {
2668 PlusCstVar(Solver*
const s, IntVar* v, int64_t c)
2669 : IntVar(s), var_(v),
cst_(c) {}
2671 ~PlusCstVar()
override {}
2673 void WhenRange(Demon* d)
override { var_->WhenRange(d); }
2675 void WhenBound(Demon* d)
override { var_->WhenBound(d); }
2677 void WhenDomain(Demon* d)
override { var_->WhenDomain(d); }
2679 int64_t OldMin()
const override {
return CapAdd(var_->OldMin(),
cst_); }
2681 int64_t OldMax()
const override {
return CapAdd(var_->OldMax(),
cst_); }
2683 std::string DebugString()
const override {
2685 return absl::StrFormat(
"%s(%s + %d)",
name(), var_->DebugString(),
cst_);
2687 return absl::StrFormat(
"(%s + %d)", var_->DebugString(),
cst_);
2691 int VarType()
const override {
return VAR_ADD_CST; }
2693 void Accept(ModelVisitor*
const visitor)
const override {
2694 visitor->VisitIntegerVariable(
this, ModelVisitor::kSumOperation,
cst_,
2698 IntVar* IsEqual(int64_t constant)
override {
2699 return var_->IsEqual(constant -
cst_);
2702 IntVar* IsDifferent(int64_t constant)
override {
2703 return var_->IsDifferent(constant -
cst_);
2706 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2707 return var_->IsGreaterOrEqual(constant -
cst_);
2710 IntVar* IsLessOrEqual(int64_t constant)
override {
2711 return var_->IsLessOrEqual(constant -
cst_);
2714 IntVar* SubVar()
const {
return var_; }
2716 int64_t Constant()
const {
return cst_; }
2723class PlusCstIntVar :
public PlusCstVar {
2725 class PlusCstIntVarIterator :
public UnaryIterator {
2727 PlusCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2728 : UnaryIterator(v, hole, rev),
cst_(c) {}
2730 ~PlusCstIntVarIterator()
override {}
2738 PlusCstIntVar(Solver*
const s, IntVar* v, int64_t c) : PlusCstVar(s, v, c) {}
2740 ~PlusCstIntVar()
override {}
2742 int64_t Min()
const override {
return var_->Min() +
cst_; }
2744 void SetMin(int64_t m)
override { var_->SetMin(
CapSub(m,
cst_)); }
2746 int64_t Max()
const override {
return var_->Max() +
cst_; }
2748 void SetMax(int64_t m)
override { var_->SetMax(
CapSub(m,
cst_)); }
2750 void SetRange(int64_t l, int64_t u)
override {
2754 void SetValue(int64_t v)
override { var_->SetValue(v -
cst_); }
2756 int64_t
Value()
const override {
return var_->Value() +
cst_; }
2758 bool Bound()
const override {
return var_->Bound(); }
2760 void RemoveValue(int64_t v)
override { var_->RemoveValue(v -
cst_); }
2762 void RemoveInterval(int64_t l, int64_t u)
override {
2763 var_->RemoveInterval(l -
cst_, u -
cst_);
2766 uint64_t Size()
const override {
return var_->Size(); }
2768 bool Contains(int64_t v)
const override {
return var_->Contains(v -
cst_); }
2770 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2772 reversible,
new PlusCstIntVarIterator(var_,
cst_,
true, reversible));
2774 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2776 reversible,
new PlusCstIntVarIterator(var_,
cst_,
false, reversible));
2780class PlusCstDomainIntVar :
public PlusCstVar {
2782 class PlusCstDomainIntVarIterator :
public UnaryIterator {
2784 PlusCstDomainIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
2786 : UnaryIterator(v, hole, reversible),
cst_(c) {}
2788 ~PlusCstDomainIntVarIterator()
override {}
2796 PlusCstDomainIntVar(Solver*
const s, DomainIntVar* v, int64_t c)
2797 : PlusCstVar(s, v, c) {}
2799 ~PlusCstDomainIntVar()
override {}
2801 int64_t Min()
const override;
2802 void SetMin(int64_t m)
override;
2803 int64_t Max()
const override;
2804 void SetMax(int64_t m)
override;
2805 void SetRange(int64_t l, int64_t u)
override;
2806 void SetValue(int64_t v)
override;
2807 bool Bound()
const override;
2808 int64_t
Value()
const override;
2809 void RemoveValue(int64_t v)
override;
2810 void RemoveInterval(int64_t l, int64_t u)
override;
2811 uint64_t Size()
const override;
2812 bool Contains(int64_t v)
const override;
2814 DomainIntVar* domain_int_var()
const {
2815 return reinterpret_cast<DomainIntVar*
>(var_);
2818 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2819 return COND_REV_ALLOC(reversible,
new PlusCstDomainIntVarIterator(
2820 var_,
cst_,
true, reversible));
2822 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2823 return COND_REV_ALLOC(reversible,
new PlusCstDomainIntVarIterator(
2824 var_,
cst_,
false, reversible));
2828int64_t PlusCstDomainIntVar::Min()
const {
2829 return domain_int_var()->min_.Value() +
cst_;
2832void PlusCstDomainIntVar::SetMin(int64_t m) {
2833 domain_int_var()->DomainIntVar::SetMin(m -
cst_);
2836int64_t PlusCstDomainIntVar::Max()
const {
2837 return domain_int_var()->max_.Value() +
cst_;
2840void PlusCstDomainIntVar::SetMax(int64_t m) {
2841 domain_int_var()->DomainIntVar::SetMax(m -
cst_);
2844void PlusCstDomainIntVar::SetRange(int64_t l, int64_t u) {
2845 domain_int_var()->DomainIntVar::SetRange(l -
cst_, u -
cst_);
2848void PlusCstDomainIntVar::SetValue(int64_t v) {
2849 domain_int_var()->DomainIntVar::SetValue(v -
cst_);
2852bool PlusCstDomainIntVar::Bound()
const {
2853 return domain_int_var()->min_.Value() == domain_int_var()->max_.Value();
2857 CHECK_EQ(domain_int_var()->min_.Value(), domain_int_var()->max_.Value())
2858 <<
" variable is not bound";
2859 return domain_int_var()->min_.Value() +
cst_;
2862void PlusCstDomainIntVar::RemoveValue(int64_t v) {
2863 domain_int_var()->DomainIntVar::RemoveValue(v -
cst_);
2866void PlusCstDomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2867 domain_int_var()->DomainIntVar::RemoveInterval(l -
cst_, u -
cst_);
2870uint64_t PlusCstDomainIntVar::Size()
const {
2871 return domain_int_var()->DomainIntVar::Size();
2874bool PlusCstDomainIntVar::Contains(int64_t v)
const {
2875 return domain_int_var()->DomainIntVar::Contains(v -
cst_);
2880class SubCstIntVar :
public IntVar {
2882 class SubCstIntVarIterator :
public UnaryIterator {
2884 SubCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2885 : UnaryIterator(v, hole, rev),
cst_(c) {}
2886 ~SubCstIntVarIterator()
override {}
2894 SubCstIntVar(Solver*
const s, IntVar* v, int64_t c);
2895 ~SubCstIntVar()
override;
2897 int64_t Min()
const override;
2898 void SetMin(int64_t m)
override;
2899 int64_t Max()
const override;
2900 void SetMax(int64_t m)
override;
2901 void SetRange(int64_t l, int64_t u)
override;
2902 void SetValue(int64_t v)
override;
2903 bool Bound()
const override;
2904 int64_t
Value()
const override;
2905 void RemoveValue(int64_t v)
override;
2906 void RemoveInterval(int64_t l, int64_t u)
override;
2907 uint64_t Size()
const override;
2908 bool Contains(int64_t v)
const override;
2909 void WhenRange(Demon* d)
override;
2910 void WhenBound(Demon* d)
override;
2911 void WhenDomain(Demon* d)
override;
2912 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2914 reversible,
new SubCstIntVarIterator(var_,
cst_,
true, reversible));
2916 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2918 reversible,
new SubCstIntVarIterator(var_,
cst_,
false, reversible));
2920 int64_t OldMin()
const override {
return CapSub(
cst_, var_->OldMax()); }
2921 int64_t OldMax()
const override {
return CapSub(
cst_, var_->OldMin()); }
2922 std::string DebugString()
const override;
2923 std::string
name()
const override;
2924 int VarType()
const override {
return CST_SUB_VAR; }
2926 void Accept(ModelVisitor*
const visitor)
const override {
2927 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation,
2931 IntVar* IsEqual(int64_t constant)
override {
2932 return var_->IsEqual(
cst_ - constant);
2935 IntVar* IsDifferent(int64_t constant)
override {
2936 return var_->IsDifferent(
cst_ - constant);
2939 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2940 return var_->IsLessOrEqual(
cst_ - constant);
2943 IntVar* IsLessOrEqual(int64_t constant)
override {
2944 return var_->IsGreaterOrEqual(
cst_ - constant);
2947 IntVar* SubVar()
const {
return var_; }
2948 int64_t Constant()
const {
return cst_; }
2955SubCstIntVar::SubCstIntVar(Solver*
const s, IntVar* v, int64_t c)
2956 : IntVar(s), var_(v),
cst_(c) {}
2958SubCstIntVar::~SubCstIntVar() {}
2960int64_t SubCstIntVar::Min()
const {
return cst_ - var_->Max(); }
2962void SubCstIntVar::SetMin(int64_t m) { var_->SetMax(
CapSub(
cst_, m)); }
2964int64_t SubCstIntVar::Max()
const {
return cst_ - var_->Min(); }
2966void SubCstIntVar::SetMax(int64_t m) { var_->SetMin(
CapSub(
cst_, m)); }
2968void SubCstIntVar::SetRange(int64_t l, int64_t u) {
2972void SubCstIntVar::SetValue(int64_t v) { var_->SetValue(
cst_ - v); }
2974bool SubCstIntVar::Bound()
const {
return var_->Bound(); }
2976void SubCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
2980void SubCstIntVar::RemoveValue(int64_t v) { var_->RemoveValue(
cst_ - v); }
2982void SubCstIntVar::RemoveInterval(int64_t l, int64_t u) {
2983 var_->RemoveInterval(
cst_ - u,
cst_ - l);
2986void SubCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
2988void SubCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
2990uint64_t SubCstIntVar::Size()
const {
return var_->Size(); }
2992bool SubCstIntVar::Contains(int64_t v)
const {
2993 return var_->Contains(
cst_ - v);
2996std::string SubCstIntVar::DebugString()
const {
2998 return absl::StrFormat(
"Not(%s)", var_->DebugString());
3000 return absl::StrFormat(
"(%d - %s)",
cst_, var_->DebugString());
3005 if (solver()->HasName(
this)) {
3008 return absl::StrFormat(
"Not(%s)", var_->name());
3010 return absl::StrFormat(
"(%d - %s)",
cst_, var_->name());
3016class OppIntVar :
public IntVar {
3018 class OppIntVarIterator :
public UnaryIterator {
3020 OppIntVarIterator(
const IntVar*
const v,
bool hole,
bool reversible)
3021 : UnaryIterator(v, hole, reversible) {}
3022 ~OppIntVarIterator()
override {}
3027 OppIntVar(Solver*
const s, IntVar* v);
3028 ~OppIntVar()
override;
3030 int64_t Min()
const override;
3031 void SetMin(int64_t m)
override;
3032 int64_t Max()
const override;
3033 void SetMax(int64_t m)
override;
3034 void SetRange(int64_t l, int64_t u)
override;
3035 void SetValue(int64_t v)
override;
3036 bool Bound()
const override;
3037 int64_t
Value()
const override;
3038 void RemoveValue(int64_t v)
override;
3039 void RemoveInterval(int64_t l, int64_t u)
override;
3040 uint64_t Size()
const override;
3041 bool Contains(int64_t v)
const override;
3042 void WhenRange(Demon* d)
override;
3043 void WhenBound(Demon* d)
override;
3044 void WhenDomain(Demon* d)
override;
3045 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3047 new OppIntVarIterator(var_,
true, reversible));
3049 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3051 new OppIntVarIterator(var_,
false, reversible));
3053 int64_t OldMin()
const override {
return CapOpp(var_->OldMax()); }
3054 int64_t OldMax()
const override {
return CapOpp(var_->OldMin()); }
3055 std::string DebugString()
const override;
3056 int VarType()
const override {
return OPP_VAR; }
3058 void Accept(ModelVisitor*
const visitor)
const override {
3059 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation, 0,
3063 IntVar* IsEqual(int64_t constant)
override {
3064 return var_->IsEqual(-constant);
3067 IntVar* IsDifferent(int64_t constant)
override {
3068 return var_->IsDifferent(-constant);
3071 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3072 return var_->IsLessOrEqual(-constant);
3075 IntVar* IsLessOrEqual(int64_t constant)
override {
3076 return var_->IsGreaterOrEqual(-constant);
3079 IntVar* SubVar()
const {
return var_; }
3085OppIntVar::OppIntVar(Solver*
const s, IntVar* v) : IntVar(s), var_(v) {}
3087OppIntVar::~OppIntVar() {}
3089int64_t OppIntVar::Min()
const {
return -var_->Max(); }
3091void OppIntVar::SetMin(int64_t m) { var_->SetMax(
CapOpp(m)); }
3093int64_t OppIntVar::Max()
const {
return -var_->Min(); }
3095void OppIntVar::SetMax(int64_t m) { var_->SetMin(
CapOpp(m)); }
3097void OppIntVar::SetRange(int64_t l, int64_t u) {
3101void OppIntVar::SetValue(int64_t v) { var_->SetValue(
CapOpp(v)); }
3103bool OppIntVar::Bound()
const {
return var_->Bound(); }
3105void OppIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3109void OppIntVar::RemoveValue(int64_t v) { var_->RemoveValue(-v); }
3111void OppIntVar::RemoveInterval(int64_t l, int64_t u) {
3112 var_->RemoveInterval(-u, -l);
3115void OppIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3117void OppIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3119uint64_t OppIntVar::Size()
const {
return var_->Size(); }
3121bool OppIntVar::Contains(int64_t v)
const {
return var_->Contains(-v); }
3123std::string OppIntVar::DebugString()
const {
3124 return absl::StrFormat(
"-(%s)", var_->DebugString());
3131class TimesCstIntVar :
public IntVar {
3133 TimesCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3134 : IntVar(s), var_(v),
cst_(c) {}
3135 ~TimesCstIntVar()
override {}
3137 IntVar* SubVar()
const {
return var_; }
3138 int64_t Constant()
const {
return cst_; }
3140 void Accept(ModelVisitor*
const visitor)
const override {
3141 visitor->VisitIntegerVariable(
this, ModelVisitor::kProductOperation,
cst_,
3145 IntVar* IsEqual(int64_t constant)
override {
3146 if (constant %
cst_ == 0) {
3147 return var_->IsEqual(constant /
cst_);
3149 return solver()->MakeIntConst(0);
3153 IntVar* IsDifferent(int64_t constant)
override {
3154 if (constant %
cst_ == 0) {
3155 return var_->IsDifferent(constant /
cst_);
3157 return solver()->MakeIntConst(1);
3161 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3169 IntVar* IsLessOrEqual(int64_t constant)
override {
3177 std::string DebugString()
const override {
3178 return absl::StrFormat(
"(%s * %d)", var_->DebugString(),
cst_);
3188class TimesPosCstIntVar :
public TimesCstIntVar {
3190 class TimesPosCstIntVarIterator :
public UnaryIterator {
3192 TimesPosCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3194 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3195 ~TimesPosCstIntVarIterator()
override {}
3203 TimesPosCstIntVar(Solver*
const s, IntVar* v, int64_t c);
3204 ~TimesPosCstIntVar()
override;
3206 int64_t Min()
const override;
3207 void SetMin(int64_t m)
override;
3208 int64_t Max()
const override;
3209 void SetMax(int64_t m)
override;
3210 void SetRange(int64_t l, int64_t u)
override;
3211 void SetValue(int64_t v)
override;
3212 bool Bound()
const override;
3213 int64_t
Value()
const override;
3214 void RemoveValue(int64_t v)
override;
3215 void RemoveInterval(int64_t l, int64_t u)
override;
3216 uint64_t Size()
const override;
3217 bool Contains(int64_t v)
const override;
3218 void WhenRange(Demon* d)
override;
3219 void WhenBound(Demon* d)
override;
3220 void WhenDomain(Demon* d)
override;
3221 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3223 var_,
cst_,
true, reversible));
3225 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3227 var_,
cst_,
false, reversible));
3229 int64_t OldMin()
const override {
return CapProd(var_->OldMin(),
cst_); }
3230 int64_t OldMax()
const override {
return CapProd(var_->OldMax(),
cst_); }
3235TimesPosCstIntVar::TimesPosCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3236 : TimesCstIntVar(s, v, c) {}
3238TimesPosCstIntVar::~TimesPosCstIntVar() {}
3240int64_t TimesPosCstIntVar::Min()
const {
return CapProd(var_->Min(),
cst_); }
3242void TimesPosCstIntVar::SetMin(int64_t m) {
3248int64_t TimesPosCstIntVar::Max()
const {
return CapProd(var_->Max(),
cst_); }
3250void TimesPosCstIntVar::SetMax(int64_t m) {
3256void TimesPosCstIntVar::SetRange(int64_t l, int64_t u) {
3260void TimesPosCstIntVar::SetValue(int64_t v) {
3261 if (v %
cst_ != 0) {
3264 var_->SetValue(v /
cst_);
3267bool TimesPosCstIntVar::Bound()
const {
return var_->Bound(); }
3269void TimesPosCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3275void TimesPosCstIntVar::RemoveValue(int64_t v) {
3276 if (v %
cst_ == 0) {
3277 var_->RemoveValue(v /
cst_);
3281void TimesPosCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3282 for (int64_t v = l; v <= u; ++v) {
3288void TimesPosCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3290void TimesPosCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3292uint64_t TimesPosCstIntVar::Size()
const {
return var_->Size(); }
3294bool TimesPosCstIntVar::Contains(int64_t v)
const {
3295 return (v %
cst_ == 0 && var_->Contains(v /
cst_));
3300class TimesPosCstBoolVar :
public TimesCstIntVar {
3302 class TimesPosCstBoolVarIterator :
public UnaryIterator {
3305 TimesPosCstBoolVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3307 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3308 ~TimesPosCstBoolVarIterator()
override {}
3316 TimesPosCstBoolVar(Solver*
const s, BooleanVar* v, int64_t c);
3317 ~TimesPosCstBoolVar()
override;
3319 int64_t Min()
const override;
3320 void SetMin(int64_t m)
override;
3321 int64_t Max()
const override;
3322 void SetMax(int64_t m)
override;
3323 void SetRange(int64_t l, int64_t u)
override;
3324 void SetValue(int64_t v)
override;
3325 bool Bound()
const override;
3326 int64_t
Value()
const override;
3327 void RemoveValue(int64_t v)
override;
3328 void RemoveInterval(int64_t l, int64_t u)
override;
3329 uint64_t Size()
const override;
3330 bool Contains(int64_t v)
const override;
3331 void WhenRange(Demon* d)
override;
3332 void WhenBound(Demon* d)
override;
3333 void WhenDomain(Demon* d)
override;
3334 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3337 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3340 new TimesPosCstBoolVarIterator(boolean_var(),
cst_,
false, reversible));
3342 int64_t OldMin()
const override {
return 0; }
3343 int64_t OldMax()
const override {
return cst_; }
3345 BooleanVar* boolean_var()
const {
3346 return reinterpret_cast<BooleanVar*
>(var_);
3352TimesPosCstBoolVar::TimesPosCstBoolVar(Solver*
const s, BooleanVar* v,
3354 : TimesCstIntVar(s, v, c) {}
3356TimesPosCstBoolVar::~TimesPosCstBoolVar() {}
3358int64_t TimesPosCstBoolVar::Min()
const {
3359 return (boolean_var()->RawValue() == 1) *
cst_;
3362void TimesPosCstBoolVar::SetMin(int64_t m) {
3366 boolean_var()->SetMin(1);
3370int64_t TimesPosCstBoolVar::Max()
const {
3371 return (boolean_var()->RawValue() != 0) *
cst_;
3374void TimesPosCstBoolVar::SetMax(int64_t m) {
3377 }
else if (m <
cst_) {
3378 boolean_var()->SetMax(0);
3382void TimesPosCstBoolVar::SetRange(int64_t l, int64_t u) {
3383 if (u < 0 || l >
cst_ || l > u) {
3387 boolean_var()->SetMin(1);
3388 }
else if (u <
cst_) {
3389 boolean_var()->SetMax(0);
3393void TimesPosCstBoolVar::SetValue(int64_t v) {
3395 boolean_var()->SetValue(0);
3396 }
else if (v ==
cst_) {
3397 boolean_var()->SetValue(1);
3403bool TimesPosCstBoolVar::Bound()
const {
3404 return boolean_var()->RawValue() != BooleanVar::kUnboundBooleanVarValue;
3407void TimesPosCstBoolVar::WhenRange(Demon* d) { boolean_var()->WhenRange(d); }
3410 CHECK_NE(boolean_var()->RawValue(), BooleanVar::kUnboundBooleanVarValue)
3411 <<
" variable is not bound";
3412 return boolean_var()->RawValue() *
cst_;
3415void TimesPosCstBoolVar::RemoveValue(int64_t v) {
3417 boolean_var()->RemoveValue(0);
3418 }
else if (v ==
cst_) {
3419 boolean_var()->RemoveValue(1);
3423void TimesPosCstBoolVar::RemoveInterval(int64_t l, int64_t u) {
3424 if (l <= 0 && u >= 0) {
3425 boolean_var()->RemoveValue(0);
3427 if (l <= cst_ && u >=
cst_) {
3428 boolean_var()->RemoveValue(1);
3432void TimesPosCstBoolVar::WhenBound(Demon* d) { boolean_var()->WhenBound(d); }
3434void TimesPosCstBoolVar::WhenDomain(Demon* d) { boolean_var()->WhenDomain(d); }
3436uint64_t TimesPosCstBoolVar::Size()
const {
3438 (boolean_var()->RawValue() == BooleanVar::kUnboundBooleanVarValue));
3441bool TimesPosCstBoolVar::Contains(int64_t v)
const {
3443 return boolean_var()->RawValue() != 1;
3444 }
else if (v ==
cst_) {
3445 return boolean_var()->RawValue() != 0;
3452class TimesNegCstIntVar :
public TimesCstIntVar {
3454 class TimesNegCstIntVarIterator :
public UnaryIterator {
3456 TimesNegCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3458 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3459 ~TimesNegCstIntVarIterator()
override {}
3467 TimesNegCstIntVar(Solver*
const s, IntVar* v, int64_t c);
3468 ~TimesNegCstIntVar()
override;
3470 int64_t Min()
const override;
3471 void SetMin(int64_t m)
override;
3472 int64_t Max()
const override;
3473 void SetMax(int64_t m)
override;
3474 void SetRange(int64_t l, int64_t u)
override;
3475 void SetValue(int64_t v)
override;
3476 bool Bound()
const override;
3477 int64_t
Value()
const override;
3478 void RemoveValue(int64_t v)
override;
3479 void RemoveInterval(int64_t l, int64_t u)
override;
3480 uint64_t Size()
const override;
3481 bool Contains(int64_t v)
const override;
3482 void WhenRange(Demon* d)
override;
3483 void WhenBound(Demon* d)
override;
3484 void WhenDomain(Demon* d)
override;
3485 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3487 var_,
cst_,
true, reversible));
3489 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3491 var_,
cst_,
false, reversible));
3493 int64_t OldMin()
const override {
return CapProd(var_->OldMax(),
cst_); }
3494 int64_t OldMax()
const override {
return CapProd(var_->OldMin(),
cst_); }
3499TimesNegCstIntVar::TimesNegCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3500 : TimesCstIntVar(s, v, c) {}
3502TimesNegCstIntVar::~TimesNegCstIntVar() {}
3504int64_t TimesNegCstIntVar::Min()
const {
return CapProd(var_->Max(),
cst_); }
3506void TimesNegCstIntVar::SetMin(int64_t m) {
3512int64_t TimesNegCstIntVar::Max()
const {
return CapProd(var_->Min(),
cst_); }
3514void TimesNegCstIntVar::SetMax(int64_t m) {
3520void TimesNegCstIntVar::SetRange(int64_t l, int64_t u) {
3524void TimesNegCstIntVar::SetValue(int64_t v) {
3525 if (v %
cst_ != 0) {
3528 var_->SetValue(v /
cst_);
3531bool TimesNegCstIntVar::Bound()
const {
return var_->Bound(); }
3533void TimesNegCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3539void TimesNegCstIntVar::RemoveValue(int64_t v) {
3540 if (v %
cst_ == 0) {
3541 var_->RemoveValue(v /
cst_);
3545void TimesNegCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3546 for (int64_t v = l; v <= u; ++v) {
3552void TimesNegCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3554void TimesNegCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3556uint64_t TimesNegCstIntVar::Size()
const {
return var_->Size(); }
3558bool TimesNegCstIntVar::Contains(int64_t v)
const {
3559 return (v %
cst_ == 0 && var_->Contains(v /
cst_));
3566class PlusIntExpr :
public BaseIntExpr {
3568 PlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3569 : BaseIntExpr(s), left_(l), right_(r) {}
3571 ~PlusIntExpr()
override {}
3573 int64_t Min()
const override {
return left_->Min() + right_->Min(); }
3575 void SetMin(int64_t m)
override {
3576 if (m > left_->Min() + right_->Min()) {
3577 left_->SetMin(m - right_->Max());
3578 right_->SetMin(m - left_->Max());
3582 void SetRange(int64_t l, int64_t u)
override {
3583 const int64_t left_min = left_->Min();
3584 const int64_t right_min = right_->Min();
3585 const int64_t left_max = left_->Max();
3586 const int64_t right_max = right_->Max();
3587 if (l > left_min + right_min) {
3588 left_->SetMin(l - right_max);
3589 right_->SetMin(l - left_max);
3591 if (u < left_max + right_max) {
3592 left_->SetMax(u - right_min);
3593 right_->SetMax(u - left_min);
3597 int64_t Max()
const override {
return left_->Max() + right_->Max(); }
3599 void SetMax(int64_t m)
override {
3600 if (m < left_->Max() + right_->Max()) {
3601 left_->SetMax(m - right_->Min());
3602 right_->SetMax(m - left_->Min());
3606 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3608 void Range(int64_t*
const mi, int64_t*
const ma)
override {
3609 *mi = left_->Min() + right_->Min();
3610 *ma = left_->Max() + right_->Max();
3613 std::string
name()
const override {
3614 return absl::StrFormat(
"(%s + %s)", left_->name(), right_->name());
3617 std::string DebugString()
const override {
3618 return absl::StrFormat(
"(%s + %s)", left_->DebugString(),
3619 right_->DebugString());
3622 void WhenRange(Demon* d)
override {
3623 left_->WhenRange(d);
3624 right_->WhenRange(d);
3627 void ExpandPlusIntExpr(IntExpr*
const expr, std::vector<IntExpr*>* subs) {
3628 PlusIntExpr*
const casted =
dynamic_cast<PlusIntExpr*
>(expr);
3629 if (casted !=
nullptr) {
3630 ExpandPlusIntExpr(casted->left_, subs);
3631 ExpandPlusIntExpr(casted->right_, subs);
3633 subs->push_back(expr);
3637 IntVar* CastToVar()
override {
3638 if (
dynamic_cast<PlusIntExpr*
>(left_) !=
nullptr ||
3639 dynamic_cast<PlusIntExpr*
>(right_) !=
nullptr) {
3640 std::vector<IntExpr*> sub_exprs;
3641 ExpandPlusIntExpr(left_, &sub_exprs);
3642 ExpandPlusIntExpr(right_, &sub_exprs);
3643 if (sub_exprs.size() >= 3) {
3644 std::vector<IntVar*> sub_vars(sub_exprs.size());
3645 for (
int i = 0; i < sub_exprs.size(); ++i) {
3646 sub_vars[i] = sub_exprs[i]->Var();
3648 return solver()->MakeSum(sub_vars)->Var();
3651 return BaseIntExpr::CastToVar();
3654 void Accept(ModelVisitor*
const visitor)
const override {
3655 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3656 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3657 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3659 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3663 IntExpr*
const left_;
3664 IntExpr*
const right_;
3667class SafePlusIntExpr :
public BaseIntExpr {
3669 SafePlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3670 : BaseIntExpr(s), left_(l), right_(r) {}
3672 ~SafePlusIntExpr()
override {}
3674 int64_t Min()
const override {
return CapAdd(left_->Min(), right_->Min()); }
3676 void SetMin(int64_t m)
override {
3677 left_->SetMin(
CapSub(m, right_->Max()));
3678 right_->SetMin(
CapSub(m, left_->Max()));
3681 void SetRange(int64_t l, int64_t u)
override {
3682 const int64_t left_min = left_->Min();
3683 const int64_t right_min = right_->Min();
3684 const int64_t left_max = left_->Max();
3685 const int64_t right_max = right_->Max();
3686 if (l >
CapAdd(left_min, right_min)) {
3687 left_->SetMin(
CapSub(l, right_max));
3688 right_->SetMin(
CapSub(l, left_max));
3690 if (u <
CapAdd(left_max, right_max)) {
3691 left_->SetMax(
CapSub(u, right_min));
3692 right_->SetMax(
CapSub(u, left_min));
3696 int64_t Max()
const override {
return CapAdd(left_->Max(), right_->Max()); }
3698 void SetMax(int64_t m)
override {
3699 left_->SetMax(
CapSub(m, right_->Min()));
3700 right_->SetMax(
CapSub(m, left_->Min()));
3703 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3705 std::string
name()
const override {
3706 return absl::StrFormat(
"(%s + %s)", left_->name(), right_->name());
3709 std::string DebugString()
const override {
3710 return absl::StrFormat(
"(%s + %s)", left_->DebugString(),
3711 right_->DebugString());
3714 void WhenRange(Demon* d)
override {
3715 left_->WhenRange(d);
3716 right_->WhenRange(d);
3719 void Accept(ModelVisitor*
const visitor)
const override {
3720 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3721 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3722 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3724 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3728 IntExpr*
const left_;
3729 IntExpr*
const right_;
3734class PlusIntCstExpr :
public BaseIntExpr {
3736 PlusIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3737 : BaseIntExpr(s),
expr_(e), value_(v) {}
3738 ~PlusIntCstExpr()
override {}
3739 int64_t Min()
const override {
return CapAdd(
expr_->Min(), value_); }
3740 void SetMin(int64_t m)
override {
expr_->SetMin(
CapSub(m, value_)); }
3741 int64_t Max()
const override {
return CapAdd(
expr_->Max(), value_); }
3742 void SetMax(int64_t m)
override {
expr_->SetMax(
CapSub(m, value_)); }
3743 bool Bound()
const override {
return (
expr_->Bound()); }
3744 std::string
name()
const override {
3745 return absl::StrFormat(
"(%s + %d)",
expr_->name(), value_);
3747 std::string DebugString()
const override {
3748 return absl::StrFormat(
"(%s + %d)",
expr_->DebugString(), value_);
3750 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3751 IntVar* CastToVar()
override;
3752 void Accept(ModelVisitor*
const visitor)
const override {
3753 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3754 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3756 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3757 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3761 IntExpr*
const expr_;
3762 const int64_t value_;
3765IntVar* PlusIntCstExpr::CastToVar() {
3766 Solver*
const s = solver();
3768 IntVar* cast =
nullptr;
3771 return BaseIntExpr::CastToVar();
3773 switch (
var->VarType()) {
3775 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstDomainIntVar(
3776 s,
reinterpret_cast<DomainIntVar*
>(
var), value_)));
3780 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstIntVar(s,
var, value_)));
3788class SubIntExpr :
public BaseIntExpr {
3790 SubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3791 : BaseIntExpr(s), left_(l), right_(r) {}
3793 ~SubIntExpr()
override {}
3795 int64_t Min()
const override {
return left_->Min() - right_->Max(); }
3797 void SetMin(int64_t m)
override {
3798 left_->SetMin(
CapAdd(m, right_->Min()));
3799 right_->SetMax(
CapSub(left_->Max(), m));
3802 int64_t Max()
const override {
return left_->Max() - right_->Min(); }
3804 void SetMax(int64_t m)
override {
3805 left_->SetMax(
CapAdd(m, right_->Max()));
3806 right_->SetMin(
CapSub(left_->Min(), m));
3809 void Range(int64_t* mi, int64_t* ma)
override {
3810 *mi = left_->Min() - right_->Max();
3811 *ma = left_->Max() - right_->Min();
3814 void SetRange(int64_t l, int64_t u)
override {
3815 const int64_t left_min = left_->Min();
3816 const int64_t right_min = right_->Min();
3817 const int64_t left_max = left_->Max();
3818 const int64_t right_max = right_->Max();
3819 if (l > left_min - right_max) {
3820 left_->SetMin(
CapAdd(l, right_min));
3821 right_->SetMax(
CapSub(left_max, l));
3823 if (u < left_max - right_min) {
3824 left_->SetMax(
CapAdd(u, right_max));
3825 right_->SetMin(
CapSub(left_min, u));
3829 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3831 std::string
name()
const override {
3832 return absl::StrFormat(
"(%s - %s)", left_->name(), right_->name());
3835 std::string DebugString()
const override {
3836 return absl::StrFormat(
"(%s - %s)", left_->DebugString(),
3837 right_->DebugString());
3840 void WhenRange(Demon* d)
override {
3841 left_->WhenRange(d);
3842 right_->WhenRange(d);
3845 void Accept(ModelVisitor*
const visitor)
const override {
3846 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3847 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3848 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3850 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3853 IntExpr* left()
const {
return left_; }
3854 IntExpr* right()
const {
return right_; }
3857 IntExpr*
const left_;
3858 IntExpr*
const right_;
3861class SafeSubIntExpr :
public SubIntExpr {
3863 SafeSubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3864 : SubIntExpr(s, l, r) {}
3866 ~SafeSubIntExpr()
override {}
3868 int64_t Min()
const override {
return CapSub(left_->Min(), right_->Max()); }
3870 void SetMin(int64_t m)
override {
3871 left_->SetMin(
CapAdd(m, right_->Min()));
3872 right_->SetMax(
CapSub(left_->Max(), m));
3875 void SetRange(int64_t l, int64_t u)
override {
3876 const int64_t left_min = left_->Min();
3877 const int64_t right_min = right_->Min();
3878 const int64_t left_max = left_->Max();
3879 const int64_t right_max = right_->Max();
3880 if (l >
CapSub(left_min, right_max)) {
3881 left_->SetMin(
CapAdd(l, right_min));
3882 right_->SetMax(
CapSub(left_max, l));
3884 if (u <
CapSub(left_max, right_min)) {
3885 left_->SetMax(
CapAdd(u, right_max));
3886 right_->SetMin(
CapSub(left_min, u));
3890 void Range(int64_t* mi, int64_t* ma)
override {
3891 *mi =
CapSub(left_->Min(), right_->Max());
3892 *ma =
CapSub(left_->Max(), right_->Min());
3895 int64_t Max()
const override {
return CapSub(left_->Max(), right_->Min()); }
3897 void SetMax(int64_t m)
override {
3898 left_->SetMax(
CapAdd(m, right_->Max()));
3899 right_->SetMin(
CapSub(left_->Min(), m));
3907class SubIntCstExpr :
public BaseIntExpr {
3909 SubIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3910 : BaseIntExpr(s),
expr_(e), value_(v) {}
3911 ~SubIntCstExpr()
override {}
3912 int64_t Min()
const override {
return CapSub(value_,
expr_->Max()); }
3913 void SetMin(int64_t m)
override {
expr_->SetMax(
CapSub(value_, m)); }
3914 int64_t Max()
const override {
return CapSub(value_,
expr_->Min()); }
3915 void SetMax(int64_t m)
override {
expr_->SetMin(
CapSub(value_, m)); }
3916 bool Bound()
const override {
return (
expr_->Bound()); }
3917 std::string
name()
const override {
3918 return absl::StrFormat(
"(%d - %s)", value_,
expr_->name());
3920 std::string DebugString()
const override {
3921 return absl::StrFormat(
"(%d - %s)", value_,
expr_->DebugString());
3923 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3924 IntVar* CastToVar()
override;
3926 void Accept(ModelVisitor*
const visitor)
const override {
3927 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3928 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3929 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3931 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3935 IntExpr*
const expr_;
3936 const int64_t value_;
3939IntVar* SubIntCstExpr::CastToVar() {
3942 return BaseIntExpr::CastToVar();
3944 Solver*
const s = solver();
3946 s->RegisterIntVar(s->RevAlloc(
new SubCstIntVar(s,
expr_->Var(), value_)));
3952class OppIntExpr :
public BaseIntExpr {
3954 OppIntExpr(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
3955 ~OppIntExpr()
override {}
3956 int64_t Min()
const override {
return (-
expr_->Max()); }
3957 void SetMin(int64_t m)
override {
expr_->SetMax(-m); }
3958 int64_t Max()
const override {
return (-
expr_->Min()); }
3959 void SetMax(int64_t m)
override {
expr_->SetMin(-m); }
3960 bool Bound()
const override {
return (
expr_->Bound()); }
3961 std::string
name()
const override {
3962 return absl::StrFormat(
"(-%s)",
expr_->name());
3964 std::string DebugString()
const override {
3965 return absl::StrFormat(
"(-%s)",
expr_->DebugString());
3967 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3968 IntVar* CastToVar()
override;
3970 void Accept(ModelVisitor*
const visitor)
const override {
3971 visitor->BeginVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3972 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3974 visitor->EndVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3978 IntExpr*
const expr_;
3981IntVar* OppIntExpr::CastToVar() {
3982 Solver*
const s = solver();
3984 s->RegisterIntVar(s->RevAlloc(
new OppIntVar(s,
expr_->Var())));
3990class TimesIntCstExpr :
public BaseIntExpr {
3992 TimesIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3993 : BaseIntExpr(s),
expr_(e), value_(v) {}
3995 ~TimesIntCstExpr()
override {}
3997 bool Bound()
const override {
return (
expr_->Bound()); }
3999 std::string
name()
const override {
4000 return absl::StrFormat(
"(%s * %d)",
expr_->name(), value_);
4003 std::string DebugString()
const override {
4004 return absl::StrFormat(
"(%s * %d)",
expr_->DebugString(), value_);
4007 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
4009 IntExpr* Expr()
const {
return expr_; }
4011 int64_t Constant()
const {
return value_; }
4013 void Accept(ModelVisitor*
const visitor)
const override {
4014 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4015 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4017 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4018 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4022 IntExpr*
const expr_;
4023 const int64_t value_;
4028class TimesPosIntCstExpr :
public TimesIntCstExpr {
4030 TimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4031 : TimesIntCstExpr(s, e, v) {
4035 ~TimesPosIntCstExpr()
override {}
4037 int64_t Min()
const override {
return expr_->Min() * value_; }
4041 int64_t Max()
const override {
return expr_->Max() * value_; }
4045 IntVar* CastToVar()
override {
4046 Solver*
const s = solver();
4047 IntVar*
var =
nullptr;
4048 if (
expr_->IsVar() &&
4050 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4051 s,
reinterpret_cast<BooleanVar*
>(
expr_), value_)));
4053 var = s->RegisterIntVar(
4054 s->RevAlloc(
new TimesPosCstIntVar(s,
expr_->Var(), value_)));
4062class SafeTimesPosIntCstExpr :
public TimesIntCstExpr {
4064 SafeTimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4065 : TimesIntCstExpr(s, e, v) {
4069 ~SafeTimesPosIntCstExpr()
override {}
4071 int64_t Min()
const override {
return CapProd(
expr_->Min(), value_); }
4073 void SetMin(int64_t m)
override {
4079 int64_t Max()
const override {
return CapProd(
expr_->Max(), value_); }
4081 void SetMax(int64_t m)
override {
4087 IntVar* CastToVar()
override {
4088 Solver*
const s = solver();
4089 IntVar*
var =
nullptr;
4090 if (
expr_->IsVar() &&
4092 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4093 s,
reinterpret_cast<BooleanVar*
>(
expr_), value_)));
4096 var = s->RegisterIntVar(
4097 s->RevAlloc(
new TimesPosCstIntVar(s,
expr_->Var(), value_)));
4105class TimesIntNegCstExpr :
public TimesIntCstExpr {
4107 TimesIntNegCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4108 : TimesIntCstExpr(s, e, v) {
4112 ~TimesIntNegCstExpr()
override {}
4114 int64_t Min()
const override {
return CapProd(
expr_->Max(), value_); }
4116 void SetMin(int64_t m)
override {
4122 int64_t Max()
const override {
return CapProd(
expr_->Min(), value_); }
4124 void SetMax(int64_t m)
override {
4130 IntVar* CastToVar()
override {
4131 Solver*
const s = solver();
4132 IntVar*
var =
nullptr;
4133 var = s->RegisterIntVar(
4134 s->RevAlloc(
new TimesNegCstIntVar(s,
expr_->Var(), value_)));
4142void SetPosPosMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4145 const int64_t lmax = left->Max();
4146 const int64_t rmax = right->Max();
4147 if (m >
CapProd(lmax, rmax)) {
4148 left->solver()->Fail();
4150 if (m >
CapProd(left->Min(), right->Min())) {
4162void SetPosPosMaxExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4165 const int64_t lmin = left->Min();
4166 const int64_t rmin = right->Min();
4167 if (m <
CapProd(lmin, rmin)) {
4168 left->solver()->Fail();
4170 if (m <
CapProd(left->Max(), right->Max())) {
4182void SetPosGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4186 const int64_t lmax = left->Max();
4187 const int64_t rmax = right->Max();
4188 if (m >
CapProd(lmax, rmax)) {
4189 left->solver()->Fail();
4191 if (left->Max() == 0) {
4198 }
else if (m == 0) {
4199 const int64_t lmin = left->Min();
4204 const int64_t lmin = left->Min();
4213void SetGenGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4218 const int64_t lmin = left->Min();
4219 const int64_t lmax = left->Max();
4220 const int64_t rmin = right->Min();
4221 const int64_t rmax = right->Max();
4223 left->solver()->Fail();
4225 if (m > lmin * rmin) {
4228 }
else if (m >
CapProd(lmax, rmax)) {
4234void TimesSetMin(IntExpr*
const left, IntExpr*
const right,
4235 IntExpr*
const minus_left, IntExpr*
const minus_right,
4237 if (left->Min() >= 0) {
4238 if (right->Min() >= 0) {
4239 SetPosPosMinExpr(left, right, m);
4240 }
else if (right->Max() <= 0) {
4241 SetPosPosMaxExpr(left, minus_right, -m);
4243 SetPosGenMinExpr(left, right, m);
4245 }
else if (left->Max() <= 0) {
4246 if (right->Min() >= 0) {
4247 SetPosPosMaxExpr(right, minus_left, -m);
4248 }
else if (right->Max() <= 0) {
4249 SetPosPosMinExpr(minus_left, minus_right, m);
4251 SetPosGenMinExpr(minus_left, minus_right, m);
4253 }
else if (right->Min() >= 0) {
4254 SetPosGenMinExpr(right, left, m);
4255 }
else if (right->Max() <= 0) {
4256 SetPosGenMinExpr(minus_right, minus_left, m);
4259 SetGenGenMinExpr(left, right, m);
4263class TimesIntExpr :
public BaseIntExpr {
4265 TimesIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4269 minus_left_(s->MakeOpposite(left_)),
4270 minus_right_(s->MakeOpposite(right_)) {}
4271 ~TimesIntExpr()
override {}
4272 int64_t Min()
const override {
4273 const int64_t lmin = left_->Min();
4274 const int64_t lmax = left_->Max();
4275 const int64_t rmin = right_->Min();
4276 const int64_t rmax = right_->Max();
4280 void SetMin(int64_t m)
override;
4281 int64_t Max()
const override {
4282 const int64_t lmin = left_->Min();
4283 const int64_t lmax = left_->Max();
4284 const int64_t rmin = right_->Min();
4285 const int64_t rmax = right_->Max();
4289 void SetMax(int64_t m)
override;
4290 bool Bound()
const override;
4291 std::string
name()
const override {
4292 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4294 std::string DebugString()
const override {
4295 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4296 right_->DebugString());
4298 void WhenRange(Demon* d)
override {
4299 left_->WhenRange(d);
4300 right_->WhenRange(d);
4303 void Accept(ModelVisitor*
const visitor)
const override {
4304 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4305 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4306 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4308 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4312 IntExpr*
const left_;
4313 IntExpr*
const right_;
4314 IntExpr*
const minus_left_;
4315 IntExpr*
const minus_right_;
4318void TimesIntExpr::SetMin(int64_t m) {
4320 TimesSetMin(left_, right_, minus_left_, minus_right_, m);
4324void TimesIntExpr::SetMax(int64_t m) {
4326 TimesSetMin(left_, minus_right_, minus_left_, right_, -m);
4330bool TimesIntExpr::Bound()
const {
4331 const bool left_bound = left_->Bound();
4332 const bool right_bound = right_->Bound();
4333 return ((left_bound && left_->Max() == 0) ||
4334 (right_bound && right_->Max() == 0) || (left_bound && right_bound));
4339class TimesPosIntExpr :
public BaseIntExpr {
4341 TimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4342 : BaseIntExpr(s), left_(l), right_(r) {}
4343 ~TimesPosIntExpr()
override {}
4344 int64_t Min()
const override {
return (left_->Min() * right_->Min()); }
4345 void SetMin(int64_t m)
override;
4346 int64_t Max()
const override {
return (left_->Max() * right_->Max()); }
4347 void SetMax(int64_t m)
override;
4348 bool Bound()
const override;
4349 std::string
name()
const override {
4350 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4352 std::string DebugString()
const override {
4353 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4354 right_->DebugString());
4356 void WhenRange(Demon* d)
override {
4357 left_->WhenRange(d);
4358 right_->WhenRange(d);
4361 void Accept(ModelVisitor*
const visitor)
const override {
4362 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4363 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4364 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4366 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4370 IntExpr*
const left_;
4371 IntExpr*
const right_;
4374void TimesPosIntExpr::SetMin(int64_t m) { SetPosPosMinExpr(left_, right_, m); }
4376void TimesPosIntExpr::SetMax(int64_t m) { SetPosPosMaxExpr(left_, right_, m); }
4378bool TimesPosIntExpr::Bound()
const {
4379 return (left_->Max() == 0 || right_->Max() == 0 ||
4380 (left_->Bound() && right_->Bound()));
4385class SafeTimesPosIntExpr :
public BaseIntExpr {
4387 SafeTimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4388 : BaseIntExpr(s), left_(l), right_(r) {}
4389 ~SafeTimesPosIntExpr()
override {}
4390 int64_t Min()
const override {
return CapProd(left_->Min(), right_->Min()); }
4391 void SetMin(int64_t m)
override {
4393 SetPosPosMinExpr(left_, right_, m);
4396 int64_t Max()
const override {
return CapProd(left_->Max(), right_->Max()); }
4397 void SetMax(int64_t m)
override {
4399 SetPosPosMaxExpr(left_, right_, m);
4402 bool Bound()
const override {
4403 return (left_->Max() == 0 || right_->Max() == 0 ||
4404 (left_->Bound() && right_->Bound()));
4406 std::string
name()
const override {
4407 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4409 std::string DebugString()
const override {
4410 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4411 right_->DebugString());
4413 void WhenRange(Demon* d)
override {
4414 left_->WhenRange(d);
4415 right_->WhenRange(d);
4418 void Accept(ModelVisitor*
const visitor)
const override {
4419 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4420 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4421 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4423 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4427 IntExpr*
const left_;
4428 IntExpr*
const right_;
4433class TimesBooleanPosIntExpr :
public BaseIntExpr {
4435 TimesBooleanPosIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4436 : BaseIntExpr(s), boolvar_(
b),
expr_(e) {}
4437 ~TimesBooleanPosIntExpr()
override {}
4438 int64_t Min()
const override {
4439 return (boolvar_->RawValue() == 1 ?
expr_->Min() : 0);
4441 void SetMin(int64_t m)
override;
4442 int64_t Max()
const override {
4443 return (boolvar_->RawValue() == 0 ? 0 :
expr_->Max());
4445 void SetMax(int64_t m)
override;
4446 void Range(int64_t* mi, int64_t* ma)
override;
4447 void SetRange(int64_t mi, int64_t ma)
override;
4448 bool Bound()
const override;
4449 std::string
name()
const override {
4450 return absl::StrFormat(
"(%s * %s)", boolvar_->name(),
expr_->name());
4452 std::string DebugString()
const override {
4453 return absl::StrFormat(
"(%s * %s)", boolvar_->DebugString(),
4454 expr_->DebugString());
4456 void WhenRange(Demon* d)
override {
4457 boolvar_->WhenRange(d);
4458 expr_->WhenRange(d);
4461 void Accept(ModelVisitor*
const visitor)
const override {
4462 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4463 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4465 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4467 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4471 BooleanVar*
const boolvar_;
4472 IntExpr*
const expr_;
4475void TimesBooleanPosIntExpr::SetMin(int64_t m) {
4477 boolvar_->SetValue(1);
4482void TimesBooleanPosIntExpr::SetMax(int64_t m) {
4486 if (m < expr_->Min()) {
4487 boolvar_->SetValue(0);
4489 if (boolvar_->RawValue() == 1) {
4494void TimesBooleanPosIntExpr::Range(int64_t* mi, int64_t* ma) {
4495 const int value = boolvar_->RawValue();
4499 }
else if (
value == 1) {
4500 expr_->Range(mi, ma);
4507void TimesBooleanPosIntExpr::SetRange(int64_t mi, int64_t ma) {
4508 if (ma < 0 || mi > ma) {
4512 boolvar_->SetValue(1);
4515 if (ma < expr_->Min()) {
4516 boolvar_->SetValue(0);
4518 if (boolvar_->RawValue() == 1) {
4523bool TimesBooleanPosIntExpr::Bound()
const {
4524 return (boolvar_->RawValue() == 0 ||
expr_->Max() == 0 ||
4525 (boolvar_->RawValue() != BooleanVar::kUnboundBooleanVarValue &&
4531class TimesBooleanIntExpr :
public BaseIntExpr {
4533 TimesBooleanIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4534 : BaseIntExpr(s), boolvar_(
b),
expr_(e) {}
4535 ~TimesBooleanIntExpr()
override {}
4536 int64_t Min()
const override {
4537 switch (boolvar_->RawValue()) {
4542 return expr_->Min();
4545 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4550 void SetMin(int64_t m)
override;
4551 int64_t Max()
const override {
4552 switch (boolvar_->RawValue()) {
4557 return expr_->Max();
4560 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4565 void SetMax(int64_t m)
override;
4566 void Range(int64_t* mi, int64_t* ma)
override;
4567 void SetRange(int64_t mi, int64_t ma)
override;
4568 bool Bound()
const override;
4569 std::string
name()
const override {
4570 return absl::StrFormat(
"(%s * %s)", boolvar_->name(),
expr_->name());
4572 std::string DebugString()
const override {
4573 return absl::StrFormat(
"(%s * %s)", boolvar_->DebugString(),
4574 expr_->DebugString());
4576 void WhenRange(Demon* d)
override {
4577 boolvar_->WhenRange(d);
4578 expr_->WhenRange(d);
4581 void Accept(ModelVisitor*
const visitor)
const override {
4582 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4583 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4585 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4587 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4591 BooleanVar*
const boolvar_;
4592 IntExpr*
const expr_;
4595void TimesBooleanIntExpr::SetMin(int64_t m) {
4596 switch (boolvar_->RawValue()) {
4608 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4610 boolvar_->SetValue(1);
4612 }
else if (m <= 0 && expr_->Max() < m) {
4613 boolvar_->SetValue(0);
4619void TimesBooleanIntExpr::SetMax(int64_t m) {
4620 switch (boolvar_->RawValue()) {
4632 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4634 boolvar_->SetValue(1);
4636 }
else if (m >= 0 &&
expr_->Min() > m) {
4637 boolvar_->SetValue(0);
4643void TimesBooleanIntExpr::Range(int64_t* mi, int64_t* ma) {
4644 switch (boolvar_->RawValue()) {
4656 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4664void TimesBooleanIntExpr::SetRange(int64_t mi, int64_t ma) {
4668 switch (boolvar_->RawValue()) {
4670 if (mi > 0 || ma < 0) {
4676 expr_->SetRange(mi, ma);
4680 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4682 boolvar_->SetValue(1);
4684 }
else if (mi == 0 &&
expr_->Max() < 0) {
4685 boolvar_->SetValue(0);
4688 boolvar_->SetValue(1);
4690 }
else if (ma == 0 &&
expr_->Min() > 0) {
4691 boolvar_->SetValue(0);
4698bool TimesBooleanIntExpr::Bound()
const {
4699 return (boolvar_->RawValue() == 0 ||
4701 (boolvar_->RawValue() != BooleanVar::kUnboundBooleanVarValue ||
4702 expr_->Max() == 0)));
4707class DivPosIntCstExpr :
public BaseIntExpr {
4709 DivPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4710 : BaseIntExpr(s),
expr_(e), value_(v) {
4713 ~DivPosIntCstExpr()
override {}
4715 int64_t Min()
const override {
return expr_->Min() / value_; }
4717 void SetMin(int64_t m)
override {
4719 expr_->SetMin(m * value_);
4721 expr_->SetMin((m - 1) * value_ + 1);
4724 int64_t Max()
const override {
return expr_->Max() / value_; }
4726 void SetMax(int64_t m)
override {
4728 expr_->SetMax((m + 1) * value_ - 1);
4730 expr_->SetMax(m * value_);
4734 std::string
name()
const override {
4735 return absl::StrFormat(
"(%s div %d)",
expr_->name(), value_);
4738 std::string DebugString()
const override {
4739 return absl::StrFormat(
"(%s div %d)",
expr_->DebugString(), value_);
4742 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
4744 void Accept(ModelVisitor*
const visitor)
const override {
4745 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4746 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4748 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4749 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4753 IntExpr*
const expr_;
4754 const int64_t value_;
4759class DivPosIntExpr :
public BaseIntExpr {
4761 DivPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4765 opp_num_(s->MakeOpposite(num)) {}
4767 ~DivPosIntExpr()
override {}
4769 int64_t Min()
const override {
4770 return num_->Min() >= 0
4771 ? num_->Min() / denom_->Max()
4772 : (denom_->Min() == 0 ? num_->Min()
4773 : num_->Min() / denom_->Min());
4776 int64_t Max()
const override {
4777 return num_->Max() >= 0 ? (denom_->Min() == 0 ? num_->Max()
4778 : num_->Max() / denom_->Min())
4779 : num_->Max() / denom_->Max();
4782 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4783 num->SetMin(m * denom->Min());
4784 denom->SetMax(num->Max() / m);
4787 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4788 num->SetMax((m + 1) * denom->Max() - 1);
4789 denom->SetMin(num->Min() / (m + 1) + 1);
4792 void SetMin(int64_t m)
override {
4794 SetPosMin(num_, denom_, m);
4796 SetPosMax(opp_num_, denom_, -m);
4800 void SetMax(int64_t m)
override {
4802 SetPosMax(num_, denom_, m);
4804 SetPosMin(opp_num_, denom_, -m);
4808 std::string
name()
const override {
4809 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
4811 std::string DebugString()
const override {
4812 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
4813 denom_->DebugString());
4815 void WhenRange(Demon* d)
override {
4817 denom_->WhenRange(d);
4820 void Accept(ModelVisitor*
const visitor)
const override {
4821 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4822 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4823 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4825 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4829 IntExpr*
const num_;
4830 IntExpr*
const denom_;
4831 IntExpr*
const opp_num_;
4834class DivPosPosIntExpr :
public BaseIntExpr {
4836 DivPosPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4837 : BaseIntExpr(s), num_(num), denom_(denom) {}
4839 ~DivPosPosIntExpr()
override {}
4841 int64_t Min()
const override {
4842 if (denom_->Max() == 0) {
4845 return num_->Min() / denom_->Max();
4848 int64_t Max()
const override {
4849 if (denom_->Min() == 0) {
4852 return num_->Max() / denom_->Min();
4856 void SetMin(int64_t m)
override {
4858 num_->SetMin(m * denom_->Min());
4859 denom_->SetMax(num_->Max() / m);
4863 void SetMax(int64_t m)
override {
4865 num_->SetMax((m + 1) * denom_->Max() - 1);
4866 denom_->SetMin(num_->Min() / (m + 1) + 1);
4872 std::string
name()
const override {
4873 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
4876 std::string DebugString()
const override {
4877 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
4878 denom_->DebugString());
4881 void WhenRange(Demon* d)
override {
4883 denom_->WhenRange(d);
4886 void Accept(ModelVisitor*
const visitor)
const override {
4887 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4888 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4889 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4891 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4895 IntExpr*
const num_;
4896 IntExpr*
const denom_;
4901class DivIntExpr :
public BaseIntExpr {
4903 DivIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4907 opp_num_(s->MakeOpposite(num)) {}
4909 ~DivIntExpr()
override {}
4911 int64_t Min()
const override {
4912 const int64_t num_min = num_->Min();
4913 const int64_t num_max = num_->Max();
4914 const int64_t denom_min = denom_->Min();
4915 const int64_t denom_max = denom_->Max();
4917 if (denom_min == 0 && denom_max == 0) {
4922 if (denom_min >= 0) {
4924 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4925 return num_min >= 0 ? num_min / denom_max : num_min / adjusted_denom_min;
4926 }
else if (denom_max <= 0) {
4928 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4929 return num_max >= 0 ? num_max / adjusted_denom_max : num_max / denom_min;
4931 return std::min(num_min, -num_max);
4935 int64_t Max()
const override {
4936 const int64_t num_min = num_->Min();
4937 const int64_t num_max = num_->Max();
4938 const int64_t denom_min = denom_->Min();
4939 const int64_t denom_max = denom_->Max();
4941 if (denom_min == 0 && denom_max == 0) {
4946 if (denom_min >= 0) {
4948 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4949 return num_max >= 0 ? num_max / adjusted_denom_min : num_max / denom_max;
4950 }
else if (denom_max <= 0) {
4952 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4953 return num_min >= 0 ? num_min / denom_min
4954 : -num_min / -adjusted_denom_max;
4956 return std::max(num_max, -num_min);
4960 void AdjustDenominator() {
4961 if (denom_->Min() == 0) {
4963 }
else if (denom_->Max() == 0) {
4969 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4971 const int64_t num_min = num->Min();
4972 const int64_t num_max = num->Max();
4973 const int64_t denom_min = denom->Min();
4974 const int64_t denom_max = denom->Max();
4977 if (denom_min > 0) {
4978 num->SetMin(m * denom_min);
4979 denom->SetMax(num_max / m);
4980 }
else if (denom_max < 0) {
4981 num->SetMax(m * denom_max);
4982 denom->SetMin(num_min / m);
4986 denom->SetRange(1, num_max / m);
4987 }
else if (num_max <= 0) {
4989 denom->SetRange(num_min / m, -1);
4993 denom->SetRange(1, num_max / m);
4994 }
else if (m > num_max) {
4996 denom->SetRange(num_min / m, -1);
4998 denom->SetRange(num_min / m, num_max / m);
5005 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
5007 const int64_t num_min = num->Min();
5008 const int64_t num_max = num->Max();
5009 const int64_t denom_min = denom->Min();
5010 const int64_t denom_max = denom->Max();
5013 if (denom_min > 0) {
5014 num->SetMax((m + 1) * denom_max - 1);
5015 denom->SetMin((num_min / (m + 1)) + 1);
5016 }
else if (denom_max < 0) {
5017 num->SetMin((m + 1) * denom_min + 1);
5018 denom->SetMax(num_max / (m + 1) - 1);
5019 }
else if (num_min > (m + 1) * denom_max - 1) {
5021 }
else if (num_max < (m + 1) * denom_min + 1) {
5026 void SetMin(int64_t m)
override {
5027 AdjustDenominator();
5029 SetPosMin(num_, denom_, m);
5031 SetPosMax(opp_num_, denom_, -m);
5035 void SetMax(int64_t m)
override {
5036 AdjustDenominator();
5038 SetPosMax(num_, denom_, m);
5040 SetPosMin(opp_num_, denom_, -m);
5044 std::string
name()
const override {
5045 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
5047 std::string DebugString()
const override {
5048 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
5049 denom_->DebugString());
5051 void WhenRange(Demon* d)
override {
5053 denom_->WhenRange(d);
5056 void Accept(ModelVisitor*
const visitor)
const override {
5057 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
5058 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
5059 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5061 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
5065 IntExpr*
const num_;
5066 IntExpr*
const denom_;
5067 IntExpr*
const opp_num_;
5072class IntAbsConstraint :
public CastConstraint {
5074 IntAbsConstraint(Solver*
const s, IntVar*
const sub, IntVar*
const target)
5075 : CastConstraint(s, target), sub_(sub) {}
5077 ~IntAbsConstraint()
override {}
5079 void Post()
override {
5081 solver(),
this, &IntAbsConstraint::PropagateSub,
"PropagateSub");
5082 sub_->WhenRange(sub_demon);
5084 solver(),
this, &IntAbsConstraint::PropagateTarget,
"PropagateTarget");
5088 void InitialPropagate()
override {
5093 void PropagateSub() {
5094 const int64_t smin = sub_->Min();
5095 const int64_t smax = sub_->Max();
5098 }
else if (smin >= 0) {
5105 void PropagateTarget() {
5107 sub_->SetRange(-target_max, target_max);
5109 if (target_min > 0) {
5110 if (sub_->Min() > -target_min) {
5111 sub_->SetMin(target_min);
5112 }
else if (sub_->Max() < target_min) {
5113 sub_->SetMax(-target_min);
5118 std::string DebugString()
const override {
5119 return absl::StrFormat(
"IntAbsConstraint(%s, %s)", sub_->DebugString(),
5123 void Accept(ModelVisitor*
const visitor)
const override {
5124 visitor->BeginVisitConstraint(ModelVisitor::kAbsEqual,
this);
5125 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5127 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
5129 visitor->EndVisitConstraint(ModelVisitor::kAbsEqual,
this);
5136class IntAbs :
public BaseIntExpr {
5138 IntAbs(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
5140 ~IntAbs()
override {}
5142 int64_t Min()
const override {
5145 expr_->Range(&emin, &emax);
5155 void SetMin(int64_t m)
override {
5159 expr_->Range(&emin, &emax);
5162 }
else if (emax < m) {
5168 int64_t Max()
const override {
5171 expr_->Range(&emin, &emax);
5175 void SetMax(int64_t m)
override {
expr_->SetRange(-m, m); }
5177 void SetRange(int64_t mi, int64_t ma)
override {
5178 expr_->SetRange(-ma, ma);
5182 expr_->Range(&emin, &emax);
5185 }
else if (emax < mi) {
5191 void Range(int64_t* mi, int64_t* ma)
override {
5194 expr_->Range(&emin, &emax);
5198 }
else if (emax <= 0) {
5207 bool Bound()
const override {
return expr_->Bound(); }
5209 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5211 std::string
name()
const override {
5212 return absl::StrFormat(
"IntAbs(%s)",
expr_->name());
5215 std::string DebugString()
const override {
5216 return absl::StrFormat(
"IntAbs(%s)",
expr_->DebugString());
5219 void Accept(ModelVisitor*
const visitor)
const override {
5220 visitor->BeginVisitIntegerExpression(ModelVisitor::kAbs,
this);
5221 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5223 visitor->EndVisitIntegerExpression(ModelVisitor::kAbs,
this);
5226 IntVar* CastToVar()
override {
5227 int64_t min_value = 0;
5228 int64_t max_value = 0;
5229 Range(&min_value, &max_value);
5230 Solver*
const s = solver();
5231 const std::string
name = absl::StrFormat(
"AbsVar(%s)",
expr_->name());
5232 IntVar*
const target = s->MakeIntVar(min_value, max_value,
name);
5233 CastConstraint*
const ct =
5234 s->RevAlloc(
new IntAbsConstraint(s,
expr_->Var(), target));
5235 s->AddCastConstraint(
ct, target,
this);
5240 IntExpr*
const expr_;
5246class IntSquare :
public BaseIntExpr {
5248 IntSquare(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
5249 ~IntSquare()
override {}
5251 int64_t Min()
const override {
5252 const int64_t emin =
expr_->Min();
5258 const int64_t emax =
expr_->Max();
5266 void SetMin(int64_t m)
override {
5271 const int64_t emin =
expr_->Min();
5272 const int64_t emax =
expr_->Max();
5273 const int64_t root =
5274 static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5276 expr_->SetMin(root);
5277 }
else if (emax <= 0) {
5278 expr_->SetMax(-root);
5279 }
else if (
expr_->IsVar()) {
5280 reinterpret_cast<IntVar*
>(
expr_)->RemoveInterval(-root + 1, root - 1);
5283 int64_t Max()
const override {
5284 const int64_t emax =
expr_->Max();
5285 const int64_t emin =
expr_->Min();
5290 return std::max(emin * emin, emax * emax);
5292 void SetMax(int64_t m)
override {
5299 const int64_t root =
5300 static_cast<int64_t
>(floor(sqrt(
static_cast<double>(m))));
5301 expr_->SetRange(-root, root);
5303 bool Bound()
const override {
return expr_->Bound(); }
5304 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5305 std::string
name()
const override {
5306 return absl::StrFormat(
"IntSquare(%s)",
expr_->name());
5308 std::string DebugString()
const override {
5309 return absl::StrFormat(
"IntSquare(%s)",
expr_->DebugString());
5312 void Accept(ModelVisitor*
const visitor)
const override {
5313 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare,
this);
5314 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5316 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare,
this);
5319 IntExpr* expr()
const {
return expr_; }
5322 IntExpr*
const expr_;
5325class PosIntSquare :
public IntSquare {
5327 PosIntSquare(Solver*
const s, IntExpr*
const e) : IntSquare(s, e) {}
5328 ~PosIntSquare()
override {}
5330 int64_t Min()
const override {
5331 const int64_t emin =
expr_->Min();
5336 void SetMin(int64_t m)
override {
5340 const int64_t root =
5341 static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5342 expr_->SetMin(root);
5344 int64_t Max()
const override {
5345 const int64_t emax =
expr_->Max();
5350 void SetMax(int64_t m)
override {
5357 const int64_t root =
5358 static_cast<int64_t
>(floor(sqrt(
static_cast<double>(m))));
5359 expr_->SetMax(root);
5365int64_t IntPower(int64_t
value, int64_t power) {
5366 int64_t result =
value;
5368 for (
int i = 1; i < power; ++i) {
5374int64_t OverflowLimit(int64_t power) {
5375 return static_cast<int64_t
>(floor(exp(
5379class BasePower :
public BaseIntExpr {
5381 BasePower(Solver*
const s, IntExpr*
const e, int64_t n)
5386 ~BasePower()
override {}
5388 bool Bound()
const override {
return expr_->Bound(); }
5390 IntExpr* expr()
const {
return expr_; }
5392 int64_t exponant()
const {
return pow_; }
5394 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5396 std::string
name()
const override {
5397 return absl::StrFormat(
"IntPower(%s, %d)",
expr_->name(),
pow_);
5400 std::string DebugString()
const override {
5401 return absl::StrFormat(
"IntPower(%s, %d)",
expr_->DebugString(),
pow_);
5404 void Accept(ModelVisitor*
const visitor)
const override {
5405 visitor->BeginVisitIntegerExpression(ModelVisitor::kPower,
this);
5406 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5408 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
pow_);
5409 visitor->EndVisitIntegerExpression(ModelVisitor::kPower,
this);
5413 int64_t Pown(int64_t
value)
const {
5418 if (
pow_ % 2 == 0) {
5427 int64_t SqrnDown(int64_t
value)
const {
5435 const double d_value =
static_cast<double>(
value);
5437 const double sq = exp(log(d_value) /
pow_);
5438 res =
static_cast<int64_t
>(floor(sq));
5441 const double sq = exp(log(-d_value) /
pow_);
5442 res = -
static_cast<int64_t
>(ceil(sq));
5444 const int64_t pow_res = Pown(res + 1);
5445 if (pow_res <=
value) {
5452 int64_t SqrnUp(int64_t
value)
const {
5460 const double d_value =
static_cast<double>(
value);
5462 const double sq = exp(log(d_value) /
pow_);
5463 res =
static_cast<int64_t
>(ceil(sq));
5466 const double sq = exp(log(-d_value) /
pow_);
5467 res = -
static_cast<int64_t
>(floor(sq));
5469 const int64_t pow_res = Pown(res - 1);
5470 if (pow_res >=
value) {
5477 IntExpr*
const expr_;
5482class IntEvenPower :
public BasePower {
5484 IntEvenPower(Solver*
const s, IntExpr*
const e, int64_t n)
5485 : BasePower(s, e, n) {
5489 ~IntEvenPower()
override {}
5491 int64_t Min()
const override {
5494 expr_->Range(&emin, &emax);
5503 void SetMin(int64_t m)
override {
5509 expr_->Range(&emin, &emax);
5510 const int64_t root = SqrnUp(m);
5512 expr_->SetMin(root);
5513 }
else if (emax < root) {
5514 expr_->SetMax(-root);
5515 }
else if (
expr_->IsVar()) {
5516 reinterpret_cast<IntVar*
>(
expr_)->RemoveInterval(-root + 1, root - 1);
5520 int64_t Max()
const override {
5524 void SetMax(int64_t m)
override {
5531 const int64_t root = SqrnDown(m);
5532 expr_->SetRange(-root, root);
5536class PosIntEvenPower :
public BasePower {
5538 PosIntEvenPower(Solver*
const s, IntExpr*
const e, int64_t pow)
5539 : BasePower(s, e, pow) {
5543 ~PosIntEvenPower()
override {}
5545 int64_t Min()
const override {
return Pown(
expr_->Min()); }
5547 void SetMin(int64_t m)
override {
5551 expr_->SetMin(SqrnUp(m));
5553 int64_t Max()
const override {
return Pown(
expr_->Max()); }
5555 void SetMax(int64_t m)
override {
5562 expr_->SetMax(SqrnDown(m));
5566class IntOddPower :
public BasePower {
5568 IntOddPower(Solver*
const s, IntExpr*
const e, int64_t n)
5569 : BasePower(s, e, n) {
5573 ~IntOddPower()
override {}
5575 int64_t Min()
const override {
return Pown(
expr_->Min()); }
5577 void SetMin(int64_t m)
override {
expr_->SetMin(SqrnUp(m)); }
5579 int64_t Max()
const override {
return Pown(
expr_->Max()); }
5581 void SetMax(int64_t m)
override {
expr_->SetMax(SqrnDown(m)); }
5586class MinIntExpr :
public BaseIntExpr {
5588 MinIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5589 : BaseIntExpr(s), left_(l), right_(r) {}
5590 ~MinIntExpr()
override {}
5591 int64_t Min()
const override {
5592 const int64_t lmin = left_->Min();
5593 const int64_t rmin = right_->Min();
5596 void SetMin(int64_t m)
override {
5600 int64_t Max()
const override {
5601 const int64_t lmax = left_->Max();
5602 const int64_t rmax = right_->Max();
5605 void SetMax(int64_t m)
override {
5606 if (left_->Min() > m) {
5609 if (right_->Min() > m) {
5613 std::string
name()
const override {
5614 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->name(), right_->name());
5616 std::string DebugString()
const override {
5617 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->DebugString(),
5618 right_->DebugString());
5620 void WhenRange(Demon* d)
override {
5621 left_->WhenRange(d);
5622 right_->WhenRange(d);
5625 void Accept(ModelVisitor*
const visitor)
const override {
5626 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5627 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5628 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5630 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5634 IntExpr*
const left_;
5635 IntExpr*
const right_;
5640class MinCstIntExpr :
public BaseIntExpr {
5642 MinCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5643 : BaseIntExpr(s),
expr_(e), value_(v) {}
5645 ~MinCstIntExpr()
override {}
5647 int64_t Min()
const override {
return std::min(
expr_->Min(), value_); }
5649 void SetMin(int64_t m)
override {
5656 int64_t Max()
const override {
return std::min(
expr_->Max(), value_); }
5658 void SetMax(int64_t m)
override {
5664 bool Bound()
const override {
5665 return (
expr_->Bound() ||
expr_->Min() >= value_);
5668 std::string
name()
const override {
5669 return absl::StrFormat(
"MinCstIntExpr(%s, %d)",
expr_->name(), value_);
5672 std::string DebugString()
const override {
5673 return absl::StrFormat(
"MinCstIntExpr(%s, %d)",
expr_->DebugString(),
5677 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5679 void Accept(ModelVisitor*
const visitor)
const override {
5680 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5681 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5683 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5684 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5688 IntExpr*
const expr_;
5689 const int64_t value_;
5694class MaxIntExpr :
public BaseIntExpr {
5696 MaxIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5697 : BaseIntExpr(s), left_(l), right_(r) {}
5699 ~MaxIntExpr()
override {}
5701 int64_t Min()
const override {
return std::max(left_->Min(), right_->Min()); }
5703 void SetMin(int64_t m)
override {
5704 if (left_->Max() < m) {
5707 if (right_->Max() < m) {
5713 int64_t Max()
const override {
return std::max(left_->Max(), right_->Max()); }
5715 void SetMax(int64_t m)
override {
5720 std::string
name()
const override {
5721 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->name(), right_->name());
5724 std::string DebugString()
const override {
5725 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->DebugString(),
5726 right_->DebugString());
5729 void WhenRange(Demon* d)
override {
5730 left_->WhenRange(d);
5731 right_->WhenRange(d);
5734 void Accept(ModelVisitor*
const visitor)
const override {
5735 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5736 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5737 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5739 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5743 IntExpr*
const left_;
5744 IntExpr*
const right_;
5749class MaxCstIntExpr :
public BaseIntExpr {
5751 MaxCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5752 : BaseIntExpr(s),
expr_(e), value_(v) {}
5754 ~MaxCstIntExpr()
override {}
5756 int64_t Min()
const override {
return std::max(
expr_->Min(), value_); }
5758 void SetMin(int64_t m)
override {
5764 int64_t Max()
const override {
return std::max(
expr_->Max(), value_); }
5766 void SetMax(int64_t m)
override {
5773 bool Bound()
const override {
5774 return (
expr_->Bound() ||
expr_->Max() <= value_);
5777 std::string
name()
const override {
5778 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)",
expr_->name(), value_);
5781 std::string DebugString()
const override {
5782 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)",
expr_->DebugString(),
5786 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5788 void Accept(ModelVisitor*
const visitor)
const override {
5789 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5790 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5792 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5793 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5797 IntExpr*
const expr_;
5798 const int64_t value_;
5809class SimpleConvexPiecewiseExpr :
public BaseIntExpr {
5811 SimpleConvexPiecewiseExpr(Solver*
const s, IntExpr*
const e, int64_t ec,
5812 int64_t ed, int64_t ld, int64_t lc)
5816 early_date_(ec == 0 ?
std::numeric_limits<int64_t>::
min() : ed),
5817 late_date_(lc == 0 ?
std::numeric_limits<int64_t>::
max() : ld),
5827 ~SimpleConvexPiecewiseExpr()
override {}
5829 int64_t Min()
const override {
5830 const int64_t vmin =
expr_->Min();
5831 const int64_t vmax =
expr_->Max();
5832 if (vmin >= late_date_) {
5833 return (vmin - late_date_) * late_cost_;
5834 }
else if (vmax <= early_date_) {
5835 return (early_date_ - vmax) * early_cost_;
5841 void SetMin(int64_t m)
override {
5847 expr_->Range(&vmin, &vmax);
5850 (late_cost_ == 0 ? vmax : late_date_ +
PosIntDivUp(m, late_cost_) - 1);
5852 (early_cost_ == 0 ? vmin
5855 if (
expr_->IsVar()) {
5856 expr_->Var()->RemoveInterval(lb, rb);
5860 int64_t Max()
const override {
5861 const int64_t vmin =
expr_->Min();
5862 const int64_t vmax =
expr_->Max();
5863 const int64_t mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0;
5865 vmin < early_date_ ? (early_date_ - vmin) * early_cost_ : 0;
5869 void SetMax(int64_t m)
override {
5873 if (late_cost_ != 0LL) {
5874 const int64_t rb = late_date_ +
PosIntDivDown(m, late_cost_);
5875 if (early_cost_ != 0LL) {
5876 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5877 expr_->SetRange(lb, rb);
5882 if (early_cost_ != 0LL) {
5883 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5889 std::string
name()
const override {
5890 return absl::StrFormat(
5891 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5892 expr_->name(), early_cost_, early_date_, late_date_, late_cost_);
5895 std::string DebugString()
const override {
5896 return absl::StrFormat(
5897 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5898 expr_->DebugString(), early_cost_, early_date_, late_date_, late_cost_);
5901 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5903 void Accept(ModelVisitor*
const visitor)
const override {
5904 visitor->BeginVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5905 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5907 visitor->VisitIntegerArgument(ModelVisitor::kEarlyCostArgument,
5909 visitor->VisitIntegerArgument(ModelVisitor::kEarlyDateArgument,
5911 visitor->VisitIntegerArgument(ModelVisitor::kLateCostArgument, late_cost_);
5912 visitor->VisitIntegerArgument(ModelVisitor::kLateDateArgument, late_date_);
5913 visitor->EndVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5917 IntExpr*
const expr_;
5918 const int64_t early_cost_;
5919 const int64_t early_date_;
5920 const int64_t late_date_;
5921 const int64_t late_cost_;
5926class SemiContinuousExpr :
public BaseIntExpr {
5928 SemiContinuousExpr(Solver*
const s, IntExpr*
const e, int64_t fixed_charge,
5930 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge),
step_(step) {
5935 ~SemiContinuousExpr()
override {}
5937 int64_t
Value(int64_t x)
const {
5945 int64_t Min()
const override {
return Value(
expr_->Min()); }
5947 void SetMin(int64_t m)
override {
5956 int64_t Max()
const override {
return Value(
expr_->Max()); }
5958 void SetMax(int64_t m)
override {
5973 std::string
name()
const override {
5974 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
5978 std::string DebugString()
const override {
5979 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
5983 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5985 void Accept(ModelVisitor*
const visitor)
const override {
5986 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
5987 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5989 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
5991 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument,
step_);
5992 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
5996 IntExpr*
const expr_;
5997 const int64_t fixed_charge_;
5998 const int64_t
step_;
6001class SemiContinuousStepOneExpr :
public BaseIntExpr {
6003 SemiContinuousStepOneExpr(Solver*
const s, IntExpr*
const e,
6004 int64_t fixed_charge)
6005 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge) {
6009 ~SemiContinuousStepOneExpr()
override {}
6011 int64_t
Value(int64_t x)
const {
6015 return fixed_charge_ + x;
6019 int64_t Min()
const override {
return Value(
expr_->Min()); }
6021 void SetMin(int64_t m)
override {
6022 if (m >= fixed_charge_ + 1) {
6023 expr_->SetMin(m - fixed_charge_);
6029 int64_t Max()
const override {
return Value(
expr_->Max()); }
6031 void SetMax(int64_t m)
override {
6035 if (m < fixed_charge_ + 1) {
6038 expr_->SetMax(m - fixed_charge_);
6042 std::string
name()
const override {
6043 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6044 expr_->name(), fixed_charge_);
6047 std::string DebugString()
const override {
6048 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6049 expr_->DebugString(), fixed_charge_);
6052 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6054 void Accept(ModelVisitor*
const visitor)
const override {
6055 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6056 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6058 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6060 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 1);
6061 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6065 IntExpr*
const expr_;
6066 const int64_t fixed_charge_;
6069class SemiContinuousStepZeroExpr :
public BaseIntExpr {
6071 SemiContinuousStepZeroExpr(Solver*
const s, IntExpr*
const e,
6072 int64_t fixed_charge)
6073 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge) {
6077 ~SemiContinuousStepZeroExpr()
override {}
6079 int64_t
Value(int64_t x)
const {
6083 return fixed_charge_;
6087 int64_t Min()
const override {
return Value(
expr_->Min()); }
6089 void SetMin(int64_t m)
override {
6090 if (m >= fixed_charge_) {
6097 int64_t Max()
const override {
return Value(
expr_->Max()); }
6099 void SetMax(int64_t m)
override {
6103 if (m < fixed_charge_) {
6108 std::string
name()
const override {
6109 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6110 expr_->name(), fixed_charge_);
6113 std::string DebugString()
const override {
6114 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6115 expr_->DebugString(), fixed_charge_);
6118 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6120 void Accept(ModelVisitor*
const visitor)
const override {
6121 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6122 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6124 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6126 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 0);
6127 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6131 IntExpr*
const expr_;
6132 const int64_t fixed_charge_;
6136class LinkExprAndVar :
public CastConstraint {
6138 LinkExprAndVar(Solver*
const s, IntExpr*
const expr, IntVar*
const var)
6139 : CastConstraint(s,
var),
expr_(expr) {}
6141 ~LinkExprAndVar()
override {}
6143 void Post()
override {
6144 Solver*
const s = solver();
6145 Demon* d = s->MakeConstraintInitialPropagateCallback(
this);
6146 expr_->WhenRange(d);
6150 void InitialPropagate()
override {
6153 expr_->Range(&l, &u);
6157 std::string DebugString()
const override {
6158 return absl::StrFormat(
"cast(%s, %s)",
expr_->DebugString(),
6162 void Accept(ModelVisitor*
const visitor)
const override {
6163 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6164 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6166 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6168 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6172 IntExpr*
const expr_;
6177class ExprWithEscapeValue :
public BaseIntExpr {
6179 ExprWithEscapeValue(Solver*
const s, IntVar*
const c, IntExpr*
const e,
6180 int64_t unperformed_value)
6184 unperformed_value_(unperformed_value) {}
6186 ~ExprWithEscapeValue()
override {}
6188 int64_t Min()
const override {
6189 if (condition_->Min() == 1) {
6190 return expression_->Min();
6191 }
else if (condition_->Max() == 1) {
6192 return std::min(unperformed_value_, expression_->Min());
6194 return unperformed_value_;
6198 void SetMin(int64_t m)
override {
6199 if (m > unperformed_value_) {
6200 condition_->SetValue(1);
6201 expression_->SetMin(m);
6202 }
else if (condition_->Min() == 1) {
6203 expression_->SetMin(m);
6204 }
else if (m > expression_->Max()) {
6205 condition_->SetValue(0);
6209 int64_t Max()
const override {
6210 if (condition_->Min() == 1) {
6211 return expression_->Max();
6212 }
else if (condition_->Max() == 1) {
6213 return std::max(unperformed_value_, expression_->Max());
6215 return unperformed_value_;
6219 void SetMax(int64_t m)
override {
6220 if (m < unperformed_value_) {
6221 condition_->SetValue(1);
6222 expression_->SetMax(m);
6223 }
else if (condition_->Min() == 1) {
6224 expression_->SetMax(m);
6225 }
else if (m < expression_->Min()) {
6226 condition_->SetValue(0);
6230 void SetRange(int64_t mi, int64_t ma)
override {
6231 if (ma < unperformed_value_ || mi > unperformed_value_) {
6232 condition_->SetValue(1);
6233 expression_->SetRange(mi, ma);
6234 }
else if (condition_->Min() == 1) {
6235 expression_->SetRange(mi, ma);
6236 }
else if (ma < expression_->Min() || mi > expression_->Max()) {
6237 condition_->SetValue(0);
6241 void SetValue(int64_t v)
override {
6242 if (v != unperformed_value_) {
6243 condition_->SetValue(1);
6244 expression_->SetValue(v);
6245 }
else if (condition_->Min() == 1) {
6246 expression_->SetValue(v);
6247 }
else if (v < expression_->Min() || v > expression_->Max()) {
6248 condition_->SetValue(0);
6252 bool Bound()
const override {
6253 return condition_->Max() == 0 || expression_->Bound();
6256 void WhenRange(Demon* d)
override {
6257 expression_->WhenRange(d);
6258 condition_->WhenBound(d);
6261 std::string DebugString()
const override {
6262 return absl::StrFormat(
"ConditionExpr(%s, %s, %d)",
6263 condition_->DebugString(),
6264 expression_->DebugString(), unperformed_value_);
6267 void Accept(ModelVisitor*
const visitor)
const override {
6268 visitor->BeginVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6269 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
6271 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6273 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
6274 unperformed_value_);
6275 visitor->EndVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6279 IntVar*
const condition_;
6280 IntExpr*
const expression_;
6281 const int64_t unperformed_value_;
6286class LinkExprAndDomainIntVar :
public CastConstraint {
6288 LinkExprAndDomainIntVar(Solver*
const s, IntExpr*
const expr,
6289 DomainIntVar*
const var)
6290 : CastConstraint(s,
var),
6292 cached_min_(
std::numeric_limits<int64_t>::
min()),
6293 cached_max_(
std::numeric_limits<int64_t>::
max()),
6294 fail_stamp_(uint64_t{0}) {}
6296 ~LinkExprAndDomainIntVar()
override {}
6298 DomainIntVar*
var()
const {
6299 return reinterpret_cast<DomainIntVar*
>(
target_var_);
6302 void Post()
override {
6303 Solver*
const s = solver();
6304 Demon*
const d = s->MakeConstraintInitialPropagateCallback(
this);
6305 expr_->WhenRange(d);
6307 solver(),
this, &LinkExprAndDomainIntVar::Propagate,
"Propagate");
6311 void InitialPropagate()
override {
6312 expr_->SetRange(
var()->min_.Value(),
var()->max_.Value());
6313 expr_->Range(&cached_min_, &cached_max_);
6314 var()->DomainIntVar::SetRange(cached_min_, cached_max_);
6318 if (
var()->min_.Value() > cached_min_ ||
6319 var()->max_.Value() < cached_max_ ||
6320 solver()->fail_stamp() != fail_stamp_) {
6322 fail_stamp_ = solver()->fail_stamp();
6326 std::string DebugString()
const override {
6327 return absl::StrFormat(
"cast(%s, %s)",
expr_->DebugString(),
6331 void Accept(ModelVisitor*
const visitor)
const override {
6332 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6333 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6335 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6337 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6341 IntExpr*
const expr_;
6342 int64_t cached_min_;
6343 int64_t cached_max_;
6344 uint64_t fail_stamp_;
6361 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6362 dvar->CleanInProcess();
6366 const std::vector<IntVar*>& vars) {
6367 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6368 CHECK(dvar !=
nullptr);
6369 return dvar->SetIsEqual(values, vars);
6373 const std::vector<int64_t>& values,
6374 const std::vector<IntVar*>& vars) {
6375 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6376 CHECK(dvar !=
nullptr);
6377 return dvar->SetIsGreaterOrEqual(values, vars);
6390 return MakeIntConst(
min,
name);
6392 if (
min == 0 &&
max == 1) {
6393 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
name)));
6395 const std::string inner_name =
"inner_" +
name;
6396 return RegisterIntVar(
6397 MakeSum(RevAlloc(
new ConcreteBooleanVar(
this, inner_name)),
min)
6398 ->VarWithName(
name));
6400 return RegisterIntVar(RevAlloc(
new DomainIntVar(
this,
min,
max,
name)));
6405 return MakeIntVar(
min,
max,
"");
6409 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
name)));
6413 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
"")));
6416IntVar* Solver::MakeIntVar(
const std::vector<int64_t>& values,
6417 const std::string&
name) {
6420 if (values.size() == 1)
return MakeIntConst(values[0],
name);
6422 std::vector<int64_t> unique_sorted_values = values;
6425 if (unique_sorted_values.size() == 1)
return MakeIntConst(values[0],
name);
6427 if (unique_sorted_values.size() ==
6428 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6429 return MakeIntVar(unique_sorted_values.front(), unique_sorted_values.back(),
6435 for (
const int64_t v : unique_sorted_values) {
6439 gcd = MathUtil::GCD64(gcd, std::abs(v));
6444 return RegisterIntVar(
6445 RevAlloc(
new DomainIntVar(
this, unique_sorted_values,
name)));
6449 for (int64_t& v : unique_sorted_values) {
6453 const std::string new_name =
name.empty() ?
"" :
"inner_" +
name;
6455 IntVar* inner_intvar =
nullptr;
6456 if (unique_sorted_values.size() ==
6457 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6458 inner_intvar = MakeIntVar(unique_sorted_values.front(),
6459 unique_sorted_values.back(), new_name);
6461 inner_intvar = RegisterIntVar(
6462 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, new_name)));
6464 return MakeProd(inner_intvar, gcd)->Var();
6467IntVar* Solver::MakeIntVar(
const std::vector<int64_t>& values) {
6468 return MakeIntVar(values,
"");
6471IntVar* Solver::MakeIntVar(
const std::vector<int>& values,
6472 const std::string&
name) {
6476IntVar* Solver::MakeIntVar(
const std::vector<int>& values) {
6477 return MakeIntVar(values,
"");
6480IntVar* Solver::MakeIntConst(int64_t val,
const std::string&
name) {
6484 if (absl::GetFlag(FLAGS_cp_share_int_consts) &&
name.empty() &&
6485 val >= MIN_CACHED_INT_CONST && val <= MAX_CACHED_INT_CONST) {
6486 return cached_constants_[val - MIN_CACHED_INT_CONST];
6488 return RevAlloc(
new IntConst(
this, val,
name));
6491IntVar* Solver::MakeIntConst(int64_t val) {
return MakeIntConst(val,
""); }
6496std::string IndexedName(
const std::string& prefix,
int index,
int max_index) {
6498#if defined(_MSC_VER)
6499 const int digits = max_index > 0 ?
6500 static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
6503 const int digits = max_index > 0 ?
static_cast<int>(log10(max_index)) + 1: 1;
6505 return absl::StrFormat(
"%s%0*d", prefix, digits,
index);
6507 return absl::StrCat(prefix,
index);
6512void Solver::MakeIntVarArray(
int var_count, int64_t vmin, int64_t vmax,
6513 const std::string&
name,
6514 std::vector<IntVar*>* vars) {
6515 for (
int i = 0; i < var_count; ++i) {
6516 vars->push_back(MakeIntVar(vmin, vmax, IndexedName(
name, i, var_count)));
6520void Solver::MakeIntVarArray(
int var_count, int64_t vmin, int64_t vmax,
6521 std::vector<IntVar*>* vars) {
6522 for (
int i = 0; i < var_count; ++i) {
6523 vars->push_back(MakeIntVar(vmin, vmax));
6527IntVar** Solver::MakeIntVarArray(
int var_count, int64_t vmin, int64_t vmax,
6528 const std::string&
name) {
6530 for (
int i = 0; i < var_count; ++i) {
6531 vars[i] = MakeIntVar(vmin, vmax, IndexedName(
name, i, var_count));
6536void Solver::MakeBoolVarArray(
int var_count,
const std::string&
name,
6537 std::vector<IntVar*>* vars) {
6538 for (
int i = 0; i < var_count; ++i) {
6539 vars->push_back(MakeBoolVar(IndexedName(
name, i, var_count)));
6543void Solver::MakeBoolVarArray(
int var_count, std::vector<IntVar*>* vars) {
6544 for (
int i = 0; i < var_count; ++i) {
6545 vars->push_back(MakeBoolVar());
6549IntVar** Solver::MakeBoolVarArray(
int var_count,
const std::string&
name) {
6551 for (
int i = 0; i < var_count; ++i) {
6552 vars[i] = MakeBoolVar(IndexedName(
name, i, var_count));
6557void Solver::InitCachedIntConstants() {
6558 for (
int i = MIN_CACHED_INT_CONST; i <= MAX_CACHED_INT_CONST; ++i) {
6559 cached_constants_[i - MIN_CACHED_INT_CONST] =
6560 RevAlloc(
new IntConst(
this, i,
""));
6567 if (right->
Bound()) {
6568 return MakeSum(left, right->
Min());
6570 if (left->
Bound()) {
6571 return MakeSum(right, left->
Min());
6573 if (left == right) {
6574 return MakeProd(left, 2);
6576 IntExpr* cache = model_cache_->FindExprExprExpression(
6577 left, right, ModelCache::EXPR_EXPR_SUM);
6578 if (cache ==
nullptr) {
6579 cache = model_cache_->FindExprExprExpression(right, left,
6580 ModelCache::EXPR_EXPR_SUM);
6582 if (cache !=
nullptr) {
6588 ? RegisterIntExpr(RevAlloc(
new SafePlusIntExpr(
this, left, right)))
6589 : RegisterIntExpr(RevAlloc(
new PlusIntExpr(
this, left, right)));
6590 model_cache_->InsertExprExprExpression(result, left, right,
6591 ModelCache::EXPR_EXPR_SUM);
6598 if (expr->
Bound()) {
6599 return MakeIntConst(expr->
Min() +
value);
6604 IntExpr* result = Cache()->FindExprConstantExpression(
6605 expr,
value, ModelCache::EXPR_CONSTANT_SUM);
6606 if (result ==
nullptr) {
6610 switch (
var->VarType()) {
6612 result = RegisterIntExpr(RevAlloc(
new PlusCstDomainIntVar(
6613 this,
reinterpret_cast<DomainIntVar*
>(
var),
value)));
6617 result = RegisterIntExpr(MakeIntConst(
var->Min() +
value));
6621 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(
var);
6622 IntVar*
const sub_var = add_var->SubVar();
6623 const int64_t new_constant =
value + add_var->Constant();
6624 if (new_constant == 0) {
6628 DomainIntVar*
const dvar =
6629 reinterpret_cast<DomainIntVar*
>(sub_var);
6630 result = RegisterIntExpr(
6631 RevAlloc(
new PlusCstDomainIntVar(
this, dvar, new_constant)));
6633 result = RegisterIntExpr(
6634 RevAlloc(
new PlusCstIntVar(
this, sub_var, new_constant)));
6640 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(
var);
6641 IntVar*
const sub_var = add_var->SubVar();
6642 const int64_t new_constant =
value + add_var->Constant();
6643 result = RegisterIntExpr(
6644 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6648 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(
var);
6649 IntVar*
const sub_var = add_var->SubVar();
6651 RegisterIntExpr(RevAlloc(
new SubCstIntVar(
this, sub_var,
value)));
6656 RegisterIntExpr(RevAlloc(
new PlusCstIntVar(
this,
var,
value)));
6659 result = RegisterIntExpr(RevAlloc(
new PlusIntCstExpr(
this, expr,
value)));
6661 Cache()->InsertExprConstantExpression(result, expr,
value,
6662 ModelCache::EXPR_CONSTANT_SUM);
6670 if (left->
Bound()) {
6671 return MakeDifference(left->
Min(), right);
6673 if (right->
Bound()) {
6674 return MakeSum(left, -right->
Min());
6678 int64_t left_coef = 1;
6679 int64_t right_coef = 1;
6680 if (IsProduct(left, &sub_left, &left_coef) &&
6681 IsProduct(right, &sub_right, &right_coef)) {
6682 const int64_t abs_gcd =
6683 MathUtil::GCD64(std::abs(left_coef), std::abs(right_coef));
6684 if (abs_gcd != 0 && abs_gcd != 1) {
6685 return MakeProd(MakeDifference(MakeProd(sub_left, left_coef / abs_gcd),
6686 MakeProd(sub_right, right_coef / abs_gcd)),
6691 IntExpr* result = Cache()->FindExprExprExpression(
6692 left, right, ModelCache::EXPR_EXPR_DIFFERENCE);
6693 if (result ==
nullptr) {
6696 result = RegisterIntExpr(RevAlloc(
new SubIntExpr(
this, left, right)));
6698 result = RegisterIntExpr(RevAlloc(
new SafeSubIntExpr(
this, left, right)));
6700 Cache()->InsertExprExprExpression(result, left, right,
6701 ModelCache::EXPR_EXPR_DIFFERENCE);
6709 if (expr->
Bound()) {
6710 return MakeIntConst(
value - expr->
Min());
6713 return MakeOpposite(expr);
6715 IntExpr* result = Cache()->FindExprConstantExpression(
6716 expr,
value, ModelCache::EXPR_CONSTANT_DIFFERENCE);
6717 if (result ==
nullptr) {
6722 switch (
var->VarType()) {
6724 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(
var);
6725 IntVar*
const sub_var = add_var->SubVar();
6726 const int64_t new_constant =
value - add_var->Constant();
6727 if (new_constant == 0) {
6730 result = RegisterIntExpr(
6731 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6736 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(
var);
6737 IntVar*
const sub_var = add_var->SubVar();
6738 const int64_t new_constant =
value - add_var->Constant();
6739 result = MakeSum(sub_var, new_constant);
6743 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(
var);
6744 IntVar*
const sub_var = add_var->SubVar();
6745 result = MakeSum(sub_var,
value);
6750 RegisterIntExpr(RevAlloc(
new SubCstIntVar(
this,
var,
value)));
6753 result = RegisterIntExpr(RevAlloc(
new SubIntCstExpr(
this, expr,
value)));
6755 Cache()->InsertExprConstantExpression(result, expr,
value,
6756 ModelCache::EXPR_CONSTANT_DIFFERENCE);
6763 if (expr->
Bound()) {
6764 return MakeIntConst(-expr->
Min());
6767 Cache()->FindExprExpression(expr, ModelCache::EXPR_OPPOSITE);
6768 if (result ==
nullptr) {
6769 if (expr->
IsVar()) {
6770 result = RegisterIntVar(RevAlloc(
new OppIntExpr(
this, expr))->Var());
6772 result = RegisterIntExpr(RevAlloc(
new OppIntExpr(
this, expr)));
6774 Cache()->InsertExprExpression(result, expr, ModelCache::EXPR_OPPOSITE);
6781 IntExpr* result = Cache()->FindExprConstantExpression(
6782 expr,
value, ModelCache::EXPR_CONSTANT_PROD);
6783 if (result !=
nullptr) {
6794 if (m_expr->
Bound()) {
6799 return MakeOpposite(m_expr);
6803 result = RegisterIntExpr(
6804 RevAlloc(
new SafeTimesPosIntCstExpr(
this, m_expr,
coefficient)));
6806 result = RegisterIntExpr(
6807 RevAlloc(
new TimesPosIntCstExpr(
this, m_expr,
coefficient)));
6810 result = MakeIntConst(0);
6812 result = RegisterIntExpr(
6813 RevAlloc(
new TimesIntNegCstExpr(
this, m_expr,
coefficient)));
6815 if (m_expr->
IsVar() &&
6816 !absl::GetFlag(FLAGS_cp_disable_expression_optimization)) {
6817 result = result->
Var();
6819 Cache()->InsertExprConstantExpression(result, expr,
value,
6820 ModelCache::EXPR_CONSTANT_PROD);
6826void ExtractPower(
IntExpr**
const expr, int64_t*
const exponant) {
6827 if (
dynamic_cast<BasePower*
>(*expr) !=
nullptr) {
6828 BasePower*
const power =
dynamic_cast<BasePower*
>(*expr);
6829 *expr = power->expr();
6830 *exponant = power->exponant();
6832 if (
dynamic_cast<IntSquare*
>(*expr) !=
nullptr) {
6833 IntSquare*
const power =
dynamic_cast<IntSquare*
>(*expr);
6834 *expr = power->expr();
6837 if ((*expr)->IsVar()) {
6838 IntVar*
const var = (*expr)->Var();
6839 IntExpr*
const sub =
var->solver()->CastExpression(
var);
6840 if (sub !=
nullptr &&
dynamic_cast<BasePower*
>(sub) !=
nullptr) {
6841 BasePower*
const power =
dynamic_cast<BasePower*
>(sub);
6842 *expr = power->expr();
6843 *exponant = power->exponant();
6845 if (sub !=
nullptr &&
dynamic_cast<IntSquare*
>(sub) !=
nullptr) {
6846 IntSquare*
const power =
dynamic_cast<IntSquare*
>(sub);
6847 *expr = power->expr();
6853void ExtractProduct(IntExpr**
const expr, int64_t*
const coefficient,
6855 if (
dynamic_cast<TimesCstIntVar*
>(*expr) !=
nullptr) {
6856 TimesCstIntVar*
const left_prod =
dynamic_cast<TimesCstIntVar*
>(*expr);
6858 *expr = left_prod->SubVar();
6860 }
else if (
dynamic_cast<TimesIntCstExpr*
>(*expr) !=
nullptr) {
6861 TimesIntCstExpr*
const left_prod =
dynamic_cast<TimesIntCstExpr*
>(*expr);
6863 *expr = left_prod->Expr();
6870 if (left->
Bound()) {
6871 return MakeProd(right, left->
Min());
6874 if (right->
Bound()) {
6875 return MakeProd(left, right->
Min());
6882 int64_t left_exponant = 1;
6883 int64_t right_exponant = 1;
6884 ExtractPower(&m_left, &left_exponant);
6885 ExtractPower(&m_right, &right_exponant);
6887 if (m_left == m_right) {
6888 return MakePower(m_left, left_exponant + right_exponant);
6896 bool modified =
false;
6899 ExtractProduct(&m_right, &
coefficient, &modified);
6901 return MakeProd(MakeProd(m_left, m_right),
coefficient);
6908 IntExpr* result = model_cache_->FindExprExprExpression(
6909 left, right, ModelCache::EXPR_EXPR_PROD);
6910 if (result ==
nullptr) {
6911 result = model_cache_->FindExprExprExpression(right, left,
6912 ModelCache::EXPR_EXPR_PROD);
6914 if (result !=
nullptr) {
6918 if (right->
Min() >= 0) {
6919 result = RegisterIntExpr(RevAlloc(
new TimesBooleanPosIntExpr(
6920 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6922 result = RegisterIntExpr(RevAlloc(
new TimesBooleanIntExpr(
6923 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6925 }
else if (right->
IsVar() &&
6927 if (left->
Min() >= 0) {
6928 result = RegisterIntExpr(RevAlloc(
new TimesBooleanPosIntExpr(
6929 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6931 result = RegisterIntExpr(RevAlloc(
new TimesBooleanIntExpr(
6932 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6934 }
else if (left->
Min() >= 0 && right->
Min() >= 0) {
6938 RegisterIntExpr(RevAlloc(
new SafeTimesPosIntExpr(
this, left, right)));
6941 RegisterIntExpr(RevAlloc(
new TimesPosIntExpr(
this, left, right)));
6944 result = RegisterIntExpr(RevAlloc(
new TimesIntExpr(
this, left, right)));
6946 model_cache_->InsertExprExprExpression(result, left, right,
6947 ModelCache::EXPR_EXPR_PROD);
6952 CHECK(numerator !=
nullptr);
6953 CHECK(denominator !=
nullptr);
6954 if (denominator->
Bound()) {
6955 return MakeDiv(numerator, denominator->
Min());
6957 IntExpr* result = model_cache_->FindExprExprExpression(
6958 numerator, denominator, ModelCache::EXPR_EXPR_DIV);
6959 if (result !=
nullptr) {
6963 if (denominator->
Min() <= 0 && denominator->
Max() >= 0) {
6964 AddConstraint(MakeNonEquality(denominator, 0));
6967 if (denominator->
Min() >= 0) {
6968 if (numerator->
Min() >= 0) {
6969 result = RevAlloc(
new DivPosPosIntExpr(
this, numerator, denominator));
6971 result = RevAlloc(
new DivPosIntExpr(
this, numerator, denominator));
6973 }
else if (denominator->
Max() <= 0) {
6974 if (numerator->
Max() <= 0) {
6975 result = RevAlloc(
new DivPosPosIntExpr(
this, MakeOpposite(numerator),
6976 MakeOpposite(denominator)));
6978 result = MakeOpposite(RevAlloc(
6979 new DivPosIntExpr(
this, numerator, MakeOpposite(denominator))));
6982 result = RevAlloc(
new DivIntExpr(
this, numerator, denominator));
6984 model_cache_->InsertExprExprExpression(result, numerator, denominator,
6985 ModelCache::EXPR_EXPR_DIV);
6990 CHECK(expr !=
nullptr);
6992 if (expr->
Bound()) {
6993 return MakeIntConst(expr->
Min() /
value);
6994 }
else if (
value == 1) {
6996 }
else if (
value == -1) {
6997 return MakeOpposite(expr);
6998 }
else if (
value > 0) {
6999 return RegisterIntExpr(RevAlloc(
new DivPosIntCstExpr(
this, expr,
value)));
7000 }
else if (
value == 0) {
7001 LOG(
FATAL) <<
"Cannot divide by 0";
7004 return RegisterIntExpr(
7005 MakeOpposite(RevAlloc(
new DivPosIntCstExpr(
this, expr, -
value))));
7011 if (Cache()->FindExprExpression(
var, ModelCache::EXPR_ABS) ==
nullptr) {
7012 Cache()->InsertExprExpression(abs_var,
var, ModelCache::EXPR_ABS);
7014 return RevAlloc(
new IntAbsConstraint(
this,
var, abs_var));
7019 if (e->
Min() >= 0) {
7021 }
else if (e->
Max() <= 0) {
7022 return MakeOpposite(e);
7024 IntExpr* result = Cache()->FindExprExpression(e, ModelCache::EXPR_ABS);
7025 if (result ==
nullptr) {
7029 result = MakeProd(MakeAbs(expr), std::abs(
coefficient));
7031 result = RegisterIntExpr(RevAlloc(
new IntAbs(
this, e)));
7033 Cache()->InsertExprExpression(result, e, ModelCache::EXPR_ABS);
7040 if (expr->
Bound()) {
7041 const int64_t v = expr->
Min();
7042 return MakeIntConst(v * v);
7044 IntExpr* result = Cache()->FindExprExpression(expr, ModelCache::EXPR_SQUARE);
7045 if (result ==
nullptr) {
7046 if (expr->
Min() >= 0) {
7047 result = RegisterIntExpr(RevAlloc(
new PosIntSquare(
this, expr)));
7049 result = RegisterIntExpr(RevAlloc(
new IntSquare(
this, expr)));
7051 Cache()->InsertExprExpression(result, expr, ModelCache::EXPR_SQUARE);
7059 if (expr->
Bound()) {
7060 const int64_t v = expr->
Min();
7061 if (v >= OverflowLimit(n)) {
7064 return MakeIntConst(IntPower(v, n));
7068 return MakeIntConst(1);
7072 return MakeSquare(expr);
7076 if (expr->
Min() >= 0) {
7078 RegisterIntExpr(RevAlloc(
new PosIntEvenPower(
this, expr, n)));
7080 result = RegisterIntExpr(RevAlloc(
new IntEvenPower(
this, expr, n)));
7083 result = RegisterIntExpr(RevAlloc(
new IntOddPower(
this, expr, n)));
7093 if (left->
Bound()) {
7094 return MakeMin(right, left->
Min());
7096 if (right->
Bound()) {
7097 return MakeMin(left, right->
Min());
7099 if (left->
Min() >= right->
Max()) {
7102 if (right->
Min() >= left->
Max()) {
7105 return RegisterIntExpr(RevAlloc(
new MinIntExpr(
this, left, right)));
7110 if (value <= expr->Min()) {
7111 return MakeIntConst(
value);
7113 if (expr->
Bound()) {
7119 return RegisterIntExpr(RevAlloc(
new MinCstIntExpr(
this, expr,
value)));
7123 return MakeMin(expr,
static_cast<int64_t
>(
value));
7129 if (left->
Bound()) {
7130 return MakeMax(right, left->
Min());
7132 if (right->
Bound()) {
7133 return MakeMax(left, right->
Min());
7135 if (left->
Min() >= right->
Max()) {
7138 if (right->
Min() >= left->
Max()) {
7141 return RegisterIntExpr(RevAlloc(
new MaxIntExpr(
this, left, right)));
7146 if (expr->
Bound()) {
7149 if (value <= expr->Min()) {
7153 return MakeIntConst(
value);
7155 return RegisterIntExpr(RevAlloc(
new MaxCstIntExpr(
this, expr,
value)));
7159 return MakeMax(expr,
static_cast<int64_t
>(
value));
7163 int64_t early_date, int64_t late_date,
7164 int64_t late_cost) {
7165 return RegisterIntExpr(RevAlloc(
new SimpleConvexPiecewiseExpr(
7166 this, expr, early_cost, early_date, late_date, late_cost)));
7170 int64_t fixed_charge, int64_t step) {
7172 if (fixed_charge == 0) {
7173 return MakeIntConst(int64_t{0});
7175 return RegisterIntExpr(
7176 RevAlloc(
new SemiContinuousStepZeroExpr(
this, expr, fixed_charge)));
7178 }
else if (step == 1) {
7179 return RegisterIntExpr(
7180 RevAlloc(
new SemiContinuousStepOneExpr(
this, expr, fixed_charge)));
7182 return RegisterIntExpr(
7183 RevAlloc(
new SemiContinuousExpr(
this, expr, fixed_charge, step)));
7197 int64_t
Min()
const override {
7198 return f_.GetMinimum(
expr_->Min(),
expr_->Max());
7202 f_.GetSmallestRangeGreaterThanValue(
expr_->Min(),
expr_->Max(), m);
7203 expr_->SetRange(range.first, range.second);
7206 int64_t
Max()
const override {
7207 return f_.GetMaximum(
expr_->Min(),
expr_->Max());
7212 f_.GetSmallestRangeLessThanValue(
expr_->Min(),
expr_->Max(), m);
7213 expr_->SetRange(range.first, range.second);
7218 f_.GetSmallestRangeInValueRange(
expr_->Min(),
expr_->Max(), l, u);
7219 expr_->SetRange(range.first, range.second);
7221 std::string
name()
const override {
7222 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)",
expr_->name(),
7227 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)",
expr_->DebugString(),
7251 int64_t unperformed_value) {
7252 if (condition->
Min() == 1) {
7254 }
else if (condition->
Max() == 0) {
7255 return MakeIntConst(unperformed_value);
7257 IntExpr* cache = Cache()->FindExprExprConstantExpression(
7258 condition, expr, unperformed_value,
7259 ModelCache::EXPR_EXPR_CONSTANT_CONDITIONAL);
7260 if (cache ==
nullptr) {
7262 new ExprWithEscapeValue(
this, condition, expr, unperformed_value));
7263 Cache()->InsertExprExprConstantExpression(
7264 cache, condition, expr, unperformed_value,
7265 ModelCache::EXPR_EXPR_CONSTANT_CONDITIONAL);
7275 MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->
Var();
7277 AddConstraint(MakeBetweenCt(result, 0, mod - 1));
7279 AddConstraint(MakeBetweenCt(result, mod + 1, 0));
7286 return MakeModulo(x, mod->
Min());
7289 MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->
Var();
7290 AddConstraint(MakeLess(result, MakeAbs(mod)));
7291 AddConstraint(MakeGreater(result, MakeOpposite(MakeAbs(mod))));
7299void IntVar::RemoveValues(
const std::vector<int64_t>& values) {
7301 const int size = values.size();
7308 RemoveValue(values[0]);
7312 RemoveValue(values[0]);
7313 RemoveValue(values[1]);
7317 RemoveValue(values[0]);
7318 RemoveValue(values[1]);
7319 RemoveValue(values[2]);
7325 int start_index = 0;
7326 int64_t new_min = Min();
7327 if (values[start_index] <= new_min) {
7328 while (start_index < size - 1 &&
7329 values[start_index + 1] == values[start_index] + 1) {
7330 new_min = values[start_index + 1] + 1;
7334 int end_index = size - 1;
7335 int64_t new_max = Max();
7336 if (values[end_index] >= new_max) {
7337 while (end_index > start_index + 1 &&
7338 values[end_index - 1] == values[end_index] - 1) {
7339 new_max = values[end_index - 1] - 1;
7343 SetRange(new_min, new_max);
7344 for (
int i = start_index; i <= end_index; ++i) {
7345 RemoveValue(values[i]);
7352 IntExpr*
const casted = solver()->CastExpression(
this);
7356void IntVar::SetValues(
const std::vector<int64_t>& values) {
7357 switch (values.size()) {
7363 SetValue(values.back());
7367 if (Contains(values[0])) {
7368 if (Contains(values[1])) {
7369 const int64_t l =
std::min(values[0], values[1]);
7370 const int64_t u =
std::max(values[0], values[1]);
7373 RemoveInterval(l + 1, u - 1);
7376 SetValue(values[0]);
7379 SetValue(values[1]);
7390 std::vector<int64_t>& tmp = solver()->tmp_vector_;
7392 tmp.insert(tmp.end(), values.begin(), values.end());
7393 std::sort(tmp.begin(), tmp.end());
7394 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
7395 const int size = tmp.size();
7396 const int64_t vmin = Min();
7397 const int64_t vmax = Max();
7399 int last = size - 1;
7400 if (tmp.front() > vmax || tmp.back() < vmin) {
7404 while (tmp[first] < vmin || !Contains(tmp[first])) {
7406 if (first > last || tmp[first] > vmax) {
7410 while (last > first && (tmp[last] > vmax || !Contains(tmp[last]))) {
7415 SetRange(tmp[first], tmp[last]);
7416 while (first < last) {
7417 const int64_t start = tmp[first] + 1;
7418 const int64_t end = tmp[first + 1] - 1;
7420 RemoveInterval(start, end);
7430 if (!
var->Bound()) {
7432 DomainIntVar* dvar =
reinterpret_cast<DomainIntVar*
>(
var);
7434 s->
RevAlloc(
new LinkExprAndDomainIntVar(s, expr, dvar)), dvar, expr);
7443 if (var_ ==
nullptr) {
7444 solver()->SaveValue(
reinterpret_cast<void**
>(&var_));
7452 Range(&vmin, &vmax);
7453 IntVar*
const var = solver()->MakeIntVar(vmin, vmax);
7461 if (expr->
IsVar()) {
7463 expr = CastExpression(expr_var);
7467 SubIntExpr*
const sub_expr =
dynamic_cast<SubIntExpr*
>(expr);
7468 if (sub_expr !=
nullptr) {
7469 *left = sub_expr->left();
7470 *right = sub_expr->right();
7477 bool* is_negated)
const {
7479 *inner_var = expr->
Var();
7480 *is_negated =
false;
7483 SubCstIntVar*
const sub_var =
reinterpret_cast<SubCstIntVar*
>(expr);
7484 if (sub_var !=
nullptr && sub_var->Constant() == 1 &&
7487 *inner_var = sub_var->SubVar();
7496 if (
dynamic_cast<TimesCstIntVar*
>(expr) !=
nullptr) {
7497 TimesCstIntVar*
const var =
dynamic_cast<TimesCstIntVar*
>(expr);
7499 *inner_expr =
var->SubVar();
7501 }
else if (
dynamic_cast<TimesIntCstExpr*
>(expr) !=
nullptr) {
7502 TimesIntCstExpr*
const prod =
dynamic_cast<TimesIntCstExpr*
>(expr);
7504 *inner_expr = prod->Expr();
7512#undef COND_REV_ALLOC
#define DCHECK_LE(val1, val2)
#define DCHECK_NE(val1, val2)
#define CHECK_LT(val1, val2)
#define CHECK_EQ(val1, val2)
#define CHECK_GE(val1, val2)
#define CHECK_GT(val1, val2)
#define DCHECK_GE(val1, val2)
#define CHECK_NE(val1, val2)
#define DCHECK_GT(val1, val2)
#define DCHECK_LT(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
A BaseObject is the root of all reversibly allocated objects.
virtual void RestoreValue()=0
void WhenBound(Demon *d) override
This method attaches a demon that will be awakened when the variable is bound.
IntVar * IsLessOrEqual(int64_t constant) override
uint64_t Size() const override
This method returns the number of values in the domain of the variable.
void SetRange(int64_t mi, int64_t ma) override
This method sets both the min and the max of the expression.
SimpleRevFIFO< Demon * > delayed_bound_demons_
bool Contains(int64_t v) const override
This method returns whether the value 'v' is in the domain of the variable.
void RemoveValue(int64_t v) override
This method removes the value 'v' from the domain of the variable.
static const int kUnboundBooleanVarValue
IntVar * IsEqual(int64_t constant) override
IsEqual.
IntVar * IsGreaterOrEqual(int64_t constant) override
void SetMax(int64_t m) override
SimpleRevFIFO< Demon * > bound_demons_
void RemoveInterval(int64_t l, int64_t u) override
This method removes the interval 'l' .
void SetMin(int64_t m) override
IntVar * IsDifferent(int64_t constant) override
std::string DebugString() const override
A constraint is the main modeling object.
A Demon is the base element of a propagation queue.
virtual Solver::DemonPriority priority() const
This method returns the priority of the demon.
The class IntExpr is the base of all integer expressions in constraint programming.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
virtual int64_t Min() const =0
virtual IntVar * Var()=0
Creates a variable from the expression.
IntVar * VarWithName(const std::string &name)
Creates a variable from the expression and set the name of the resulting var.
virtual int64_t Max() const =0
The class IntVar is a subset of IntExpr.
IntVar * Var() override
Creates a variable from the expression.
virtual int VarType() const
The class Iterator has two direct subclasses.
@ EXPR_CONSTANT_IS_GREATER_OR_EQUAL
@ EXPR_CONSTANT_IS_NOT_EQUAL
@ EXPR_CONSTANT_IS_LESS_OR_EQUAL
virtual void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate)
static const char kVarValueWatcher[]
static const char kVarsArgument[]
static const char kVarBoundWatcher[]
static const char kVariableArgument[]
static const char kValuesArgument[]
PiecewiseLinearExpr(Solver *solver, IntExpr *expr, const PiecewiseLinearFunction &f)
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
int64_t Min() const override
void SetRange(int64_t l, int64_t u) override
This method sets both the min and the max of the expression.
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
std::string name() const override
Object naming.
int64_t Max() const override
void SetMax(int64_t m) override
~PiecewiseLinearExpr() override
void SetMin(int64_t m) override
std::string DebugString() const override
virtual std::string name() const
Object naming.
void set_name(const std::string &name)
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
@ DELAYED_PRIORITY
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
@ OUTSIDE_SEARCH
Before search, after search.
IntExpr * MakeDifference(IntExpr *const left, IntExpr *const right)
left - right
void AddCastConstraint(CastConstraint *const constraint, IntVar *const target_var, IntExpr *const expr)
Adds 'constraint' to the solver and marks it as a cast constraint, that is, a constraint created call...
IntVar * MakeIntConst(int64_t val, const std::string &name)
IntConst will create a constant expression.
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
T * RevAlloc(T *object)
Registers the given object as being reversible.
std::vector< IntVarIterator * > holes_
#define COND_REV_ALLOC(rev, alloc)
ABSL_FLAG(bool, cp_disable_expression_optimization, false, "Disable special optimization when creating expressions.")
IntVarIterator *const iterator_
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
int RemoveAt(RepeatedType *array, const IndexContainer &indices)
const Collection::value_type::second_type FindPtrOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Collection of objects used to extend the Constraint Solver library.
int64_t SubOverflows(int64_t x, int64_t y)
static const uint64_t kAllBits64
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
int64_t CapAdd(int64_t x, int64_t y)
void CleanVariableOnFail(IntVar *const var)
int64_t CapSub(int64_t x, int64_t y)
int64_t UnsafeMostSignificantBitPosition64(const uint64_t *const bitset, uint64_t start, uint64_t end)
uint64_t BitCountRange64(const uint64_t *const bitset, uint64_t start, uint64_t end)
Constraint * SetIsEqual(IntVar *const var, const std::vector< int64_t > &values, const std::vector< IntVar * > &vars)
int64_t UnsafeLeastSignificantBitPosition64(const uint64_t *const bitset, uint64_t start, uint64_t end)
bool AddOverflows(int64_t x, int64_t y)
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
void RestoreBoolValue(IntVar *const var)
Constraint * SetIsGreaterOrEqual(IntVar *const var, const std::vector< int64_t > &values, const std::vector< IntVar * > &vars)
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
int64_t CapProd(int64_t x, int64_t y)
uint64_t OneRange64(uint64_t s, uint64_t e)
uint32_t BitPos64(uint64_t pos)
uint64_t BitCount64(uint64_t n)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
void LinkVarExpr(Solver *const s, IntExpr *const expr, IntVar *const var)
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
uint64_t OneBit64(int pos)
uint64_t BitOffset64(uint64_t pos)
int64_t PosIntDivDown(int64_t e, int64_t v)
uint64_t BitLength64(uint64_t size)
int LeastSignificantBitPosition64(uint64_t n)
int64_t CapOpp(int64_t v)
int MostSignificantBitPosition64(uint64_t n)
int64_t PosIntDivUp(int64_t e, int64_t v)
IntervalVar *const target_var_