23 #include "absl/container/flat_hash_map.h"
24 #include "absl/strings/str_cat.h"
25 #include "absl/strings/str_format.h"
38 ABSL_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 +
"(";
204 class 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;
347 DCHECK_GE(position,
start);
348 DCHECK_LT(position, elements_.size());
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 {
360 DCHECK_GE(position, start_.
Value());
361 DCHECK_LT(position, elements_.size());
362 return elements_[position];
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) {
376 DCHECK_GE(pos, start_.
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 {
711 CHECK(watchers_[
index] ==
nullptr);
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();
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());
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);
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();
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());
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());
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 {
1206 CHECK(watchers_[
index] ==
nullptr);
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_;
1598 inline bool ClosedIntervalNoLargerThan(int64_t
a, int64_t
b, int64_t K) {
1608 class 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 {
1664 DCHECK_GE(nmin, cmin);
1665 DCHECK_LE(nmin, cmax);
1666 DCHECK_LE(cmin, cmax);
1667 DCHECK_GE(cmin, omin_);
1668 DCHECK_LE(cmax, omax_);
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 {
1679 DCHECK_GE(nmax, cmin);
1680 DCHECK_LE(nmax, cmax);
1681 DCHECK_LE(cmin, cmax);
1682 DCHECK_GE(cmin, omin_);
1683 DCHECK_LE(cmax, omax_);
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 {
1694 DCHECK_GE(val, omin_);
1695 DCHECK_LE(val, omax_);
1703 bool Contains(int64_t val)
const override {
1704 DCHECK_GE(val, omin_);
1705 DCHECK_LE(val, omax_);
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);
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_;
1812 class SmallBitSet :
public DomainIntVar::BitSet {
1814 SmallBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1817 stamp_(s->
stamp() - 1),
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)
1829 stamp_(s->
stamp() - 1),
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];
1837 DCHECK_GE(val, vmin);
1838 DCHECK_LE(val, vmax);
1844 ~SmallBitSet()
override {}
1846 bool bit(int64_t val)
const {
1847 DCHECK_GE(val, omin_);
1848 DCHECK_LE(val, omax_);
1849 return (bits_ &
OneBit64(val - omin_)) != 0;
1852 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1853 DCHECK_GE(nmin, cmin);
1854 DCHECK_LE(nmin, cmax);
1855 DCHECK_LE(cmin, cmax);
1856 DCHECK_GE(cmin, omin_);
1857 DCHECK_LE(cmax, omax_);
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 {
1877 DCHECK_GE(nmax, cmin);
1878 DCHECK_LE(nmax, cmax);
1879 DCHECK_LE(cmin, cmax);
1880 DCHECK_GE(cmin, omin_);
1881 DCHECK_LE(cmax, omax_);
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 {
1901 DCHECK_GE(val, omin_);
1902 DCHECK_LE(val, omax_);
1912 bool Contains(int64_t val)
const override {
1913 DCHECK_GE(val, omin_);
1914 DCHECK_LE(val, omax_);
1918 bool RemoveValue(int64_t val)
override {
1919 DCHECK_GE(val, omin_);
1920 DCHECK_LE(val, omax_);
1923 const uint64_t current_stamp =
solver_->stamp();
1924 if (stamp_ < current_stamp) {
1925 stamp_ = current_stamp;
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 {
1948 DCHECK_GE(val, omin_);
1949 DCHECK_LE(val, omax_);
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_;
2017 class 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 {}
2029 class 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_;
2058 class 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);
2082 DCHECK(index_ < size_);
2083 return values_[index_];
2086 void Next()
override { index_++; }
2089 const DomainIntVar*
const var_;
2090 DomainIntVar::BitSet* bits_;
2091 const int64_t* values_;
2096 class 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_;
2169 class 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_;
2193 DomainIntVar::DomainIntVar(Solver*
const s, int64_t vmin, int64_t vmax,
2194 const std::string&
name)
2205 value_watcher_(nullptr),
2206 bound_watcher_(nullptr) {}
2208 DomainIntVar::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) {
2223 CHECK_GE(sorted_values.size(), 1);
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));
2247 DomainIntVar::~DomainIntVar() {}
2249 void 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()) {
2273 void 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()) {
2297 void 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()) {
2341 void 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);
2365 void 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)) {
2387 void 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) {
2399 void 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()));
2410 void DomainIntVar::CleanInProcess() {
2412 if (bits_ !=
nullptr) {
2413 bits_->ClearHoles();
2417 void DomainIntVar::Push() {
2423 void 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 template <
typename T>
2470 T* CondRevAlloc(Solver* solver,
bool reversible, T*
object) {
2471 return reversible ? solver->RevAlloc(
object) : object;
2474 IntVarIterator* DomainIntVar::MakeHoleIterator(
bool reversible)
const {
2475 return CondRevAlloc(solver(), reversible,
new DomainIntVarHoleIterator(
this));
2478 IntVarIterator* DomainIntVar::MakeDomainIterator(
bool reversible)
const {
2479 return CondRevAlloc(solver(), reversible,
2480 new DomainIntVarDomainIterator(
this, reversible));
2483 std::string DomainIntVar::DebugString()
const {
2485 const std::string& var_name =
name();
2486 if (!var_name.empty()) {
2487 out = var_name +
"(";
2489 out =
"DomainIntVar(";
2491 if (min_.Value() == max_.Value()) {
2492 absl::StrAppendFormat(&out,
"%d", min_.Value());
2493 }
else if (bits_ !=
nullptr) {
2494 out.append(bits_->pretty_DebugString(min_.Value(), max_.Value()));
2496 absl::StrAppendFormat(&out,
"%d..%d", min_.Value(), max_.Value());
2504 class ConcreteBooleanVar :
public BooleanVar {
2507 class Handler :
public Demon {
2509 explicit Handler(ConcreteBooleanVar*
const var) : Demon(), var_(
var) {}
2510 ~Handler()
override {}
2511 void Run(Solver*
const s)
override {
2512 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
2514 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
2516 Solver::DemonPriority priority()
const override {
2517 return Solver::VAR_PRIORITY;
2519 std::string DebugString()
const override {
2520 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
2524 ConcreteBooleanVar*
const var_;
2527 ConcreteBooleanVar(Solver*
const s,
const std::string&
name)
2530 ~ConcreteBooleanVar()
override {}
2532 void SetValue(int64_t v)
override {
2533 if (value_ == kUnboundBooleanVarValue) {
2534 if ((v & 0xfffffffffffffffe) == 0) {
2536 value_ =
static_cast<int>(v);
2540 }
else if (v == value_) {
2547 DCHECK_NE(value_, kUnboundBooleanVarValue);
2548 ExecuteAll(bound_demons_);
2549 for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_); it.ok();
2551 EnqueueDelayedDemon(*it);
2555 int64_t OldMin()
const override {
return 0LL; }
2556 int64_t OldMax()
const override {
return 1LL; }
2557 void RestoreValue()
override { value_ = kUnboundBooleanVarValue; }
2565 class IntConst :
public IntVar {
2567 IntConst(Solver*
const s, int64_t
value,
const std::string&
name =
"")
2569 ~IntConst()
override {}
2571 int64_t Min()
const override {
return value_; }
2572 void SetMin(int64_t m)
override {
2577 int64_t Max()
const override {
return value_; }
2578 void SetMax(int64_t m)
override {
2583 void SetRange(int64_t l, int64_t u)
override {
2584 if (l > value_ || u < value_) {
2588 void SetValue(int64_t v)
override {
2593 bool Bound()
const override {
return true; }
2594 int64_t
Value()
const override {
return value_; }
2595 void RemoveValue(int64_t v)
override {
2600 void RemoveInterval(int64_t l, int64_t u)
override {
2601 if (l <= value_ && value_ <= u) {
2605 void WhenBound(Demon* d)
override {}
2606 void WhenRange(Demon* d)
override {}
2607 void WhenDomain(Demon* d)
override {}
2608 uint64_t Size()
const override {
return 1; }
2609 bool Contains(int64_t v)
const override {
return (v == value_); }
2610 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2611 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
2613 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2614 return CondRevAlloc(solver(), reversible,
new RangeIterator(
this));
2616 int64_t OldMin()
const override {
return value_; }
2617 int64_t OldMax()
const override {
return value_; }
2618 std::string DebugString()
const override {
2620 if (solver()->HasName(
this)) {
2621 const std::string& var_name =
name();
2622 absl::StrAppendFormat(&out,
"%s(%d)", var_name, value_);
2624 absl::StrAppendFormat(&out,
"IntConst(%d)", value_);
2629 int VarType()
const override {
return CONST_VAR; }
2631 IntVar* IsEqual(int64_t constant)
override {
2632 if (constant == value_) {
2633 return solver()->MakeIntConst(1);
2635 return solver()->MakeIntConst(0);
2639 IntVar* IsDifferent(int64_t constant)
override {
2640 if (constant == value_) {
2641 return solver()->MakeIntConst(0);
2643 return solver()->MakeIntConst(1);
2647 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2648 return solver()->MakeIntConst(value_ >= constant);
2651 IntVar* IsLessOrEqual(int64_t constant)
override {
2652 return solver()->MakeIntConst(value_ <= constant);
2655 std::string
name()
const override {
2656 if (solver()->HasName(
this)) {
2659 return absl::StrCat(value_);
2669 class PlusCstVar :
public IntVar {
2671 PlusCstVar(Solver*
const s, IntVar* v, int64_t c)
2672 : IntVar(s), var_(v),
cst_(c) {}
2674 ~PlusCstVar()
override {}
2676 void WhenRange(Demon* d)
override { var_->WhenRange(d); }
2678 void WhenBound(Demon* d)
override { var_->WhenBound(d); }
2680 void WhenDomain(Demon* d)
override { var_->WhenDomain(d); }
2682 int64_t OldMin()
const override {
return CapAdd(var_->OldMin(),
cst_); }
2684 int64_t OldMax()
const override {
return CapAdd(var_->OldMax(),
cst_); }
2686 std::string DebugString()
const override {
2688 return absl::StrFormat(
"%s(%s + %d)",
name(), var_->DebugString(),
cst_);
2690 return absl::StrFormat(
"(%s + %d)", var_->DebugString(),
cst_);
2694 int VarType()
const override {
return VAR_ADD_CST; }
2696 void Accept(ModelVisitor*
const visitor)
const override {
2697 visitor->VisitIntegerVariable(
this, ModelVisitor::kSumOperation,
cst_,
2701 IntVar* IsEqual(int64_t constant)
override {
2702 return var_->IsEqual(constant -
cst_);
2705 IntVar* IsDifferent(int64_t constant)
override {
2706 return var_->IsDifferent(constant -
cst_);
2709 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2710 return var_->IsGreaterOrEqual(constant -
cst_);
2713 IntVar* IsLessOrEqual(int64_t constant)
override {
2714 return var_->IsLessOrEqual(constant -
cst_);
2717 IntVar* SubVar()
const {
return var_; }
2719 int64_t Constant()
const {
return cst_; }
2726 class PlusCstIntVar :
public PlusCstVar {
2728 class PlusCstIntVarIterator :
public UnaryIterator {
2730 PlusCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2731 : UnaryIterator(v, hole, rev),
cst_(c) {}
2733 ~PlusCstIntVarIterator()
override {}
2741 PlusCstIntVar(Solver*
const s, IntVar* v, int64_t c) : PlusCstVar(s, v, c) {}
2743 ~PlusCstIntVar()
override {}
2745 int64_t Min()
const override {
return var_->Min() +
cst_; }
2747 void SetMin(int64_t m)
override { var_->SetMin(
CapSub(m,
cst_)); }
2749 int64_t Max()
const override {
return var_->Max() +
cst_; }
2751 void SetMax(int64_t m)
override { var_->SetMax(
CapSub(m,
cst_)); }
2753 void SetRange(int64_t l, int64_t u)
override {
2757 void SetValue(int64_t v)
override { var_->SetValue(v -
cst_); }
2759 int64_t
Value()
const override {
return var_->Value() +
cst_; }
2761 bool Bound()
const override {
return var_->Bound(); }
2763 void RemoveValue(int64_t v)
override { var_->RemoveValue(v -
cst_); }
2765 void RemoveInterval(int64_t l, int64_t u)
override {
2766 var_->RemoveInterval(l -
cst_, u -
cst_);
2769 uint64_t Size()
const override {
return var_->Size(); }
2771 bool Contains(int64_t v)
const override {
return var_->Contains(v -
cst_); }
2773 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2774 return CondRevAlloc(
2775 solver(), reversible,
2776 new PlusCstIntVarIterator(var_,
cst_,
true, reversible));
2778 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2779 return CondRevAlloc(
2780 solver(), reversible,
2781 new PlusCstIntVarIterator(var_,
cst_,
false, reversible));
2785 class PlusCstDomainIntVar :
public PlusCstVar {
2787 class PlusCstDomainIntVarIterator :
public UnaryIterator {
2789 PlusCstDomainIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
2791 : UnaryIterator(v, hole, reversible),
cst_(c) {}
2793 ~PlusCstDomainIntVarIterator()
override {}
2801 PlusCstDomainIntVar(Solver*
const s, DomainIntVar* v, int64_t c)
2802 : PlusCstVar(s, v, c) {}
2804 ~PlusCstDomainIntVar()
override {}
2806 int64_t Min()
const override;
2807 void SetMin(int64_t m)
override;
2808 int64_t Max()
const override;
2809 void SetMax(int64_t m)
override;
2810 void SetRange(int64_t l, int64_t u)
override;
2811 void SetValue(int64_t v)
override;
2812 bool Bound()
const override;
2813 int64_t
Value()
const override;
2814 void RemoveValue(int64_t v)
override;
2815 void RemoveInterval(int64_t l, int64_t u)
override;
2816 uint64_t Size()
const override;
2817 bool Contains(int64_t v)
const override;
2819 DomainIntVar* domain_int_var()
const {
2820 return reinterpret_cast<DomainIntVar*
>(var_);
2823 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2824 return CondRevAlloc(
2825 solver(), reversible,
2826 new PlusCstDomainIntVarIterator(var_,
cst_,
true, reversible));
2828 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2829 return CondRevAlloc(
2830 solver(), reversible,
2831 new PlusCstDomainIntVarIterator(var_,
cst_,
false, reversible));
2835 int64_t PlusCstDomainIntVar::Min()
const {
2836 return domain_int_var()->min_.Value() +
cst_;
2839 void PlusCstDomainIntVar::SetMin(int64_t m) {
2840 domain_int_var()->DomainIntVar::SetMin(
CapSub(m,
cst_));
2843 int64_t PlusCstDomainIntVar::Max()
const {
2844 return domain_int_var()->max_.Value() +
cst_;
2847 void PlusCstDomainIntVar::SetMax(int64_t m) {
2848 domain_int_var()->DomainIntVar::SetMax(
CapSub(m,
cst_));
2851 void PlusCstDomainIntVar::SetRange(int64_t l, int64_t u) {
2852 domain_int_var()->DomainIntVar::SetRange(l -
cst_, u -
cst_);
2855 void PlusCstDomainIntVar::SetValue(int64_t v) {
2856 domain_int_var()->DomainIntVar::SetValue(v -
cst_);
2859 bool PlusCstDomainIntVar::Bound()
const {
2860 return domain_int_var()->min_.Value() == domain_int_var()->max_.Value();
2864 CHECK_EQ(domain_int_var()->min_.Value(), domain_int_var()->max_.Value())
2865 <<
" variable is not bound";
2866 return domain_int_var()->min_.Value() +
cst_;
2869 void PlusCstDomainIntVar::RemoveValue(int64_t v) {
2870 domain_int_var()->DomainIntVar::RemoveValue(v -
cst_);
2873 void PlusCstDomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2874 domain_int_var()->DomainIntVar::RemoveInterval(l -
cst_, u -
cst_);
2877 uint64_t PlusCstDomainIntVar::Size()
const {
2878 return domain_int_var()->DomainIntVar::Size();
2881 bool PlusCstDomainIntVar::Contains(int64_t v)
const {
2882 return domain_int_var()->DomainIntVar::Contains(v -
cst_);
2887 class SubCstIntVar :
public IntVar {
2889 class SubCstIntVarIterator :
public UnaryIterator {
2891 SubCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2892 : UnaryIterator(v, hole, rev),
cst_(c) {}
2893 ~SubCstIntVarIterator()
override {}
2901 SubCstIntVar(Solver*
const s, IntVar* v, int64_t c);
2902 ~SubCstIntVar()
override;
2904 int64_t Min()
const override;
2905 void SetMin(int64_t m)
override;
2906 int64_t Max()
const override;
2907 void SetMax(int64_t m)
override;
2908 void SetRange(int64_t l, int64_t u)
override;
2909 void SetValue(int64_t v)
override;
2910 bool Bound()
const override;
2911 int64_t
Value()
const override;
2912 void RemoveValue(int64_t v)
override;
2913 void RemoveInterval(int64_t l, int64_t u)
override;
2914 uint64_t Size()
const override;
2915 bool Contains(int64_t v)
const override;
2916 void WhenRange(Demon* d)
override;
2917 void WhenBound(Demon* d)
override;
2918 void WhenDomain(Demon* d)
override;
2919 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2920 return CondRevAlloc(solver(), reversible,
2921 new SubCstIntVarIterator(var_,
cst_,
true, reversible));
2923 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2924 return CondRevAlloc(
2925 solver(), reversible,
2926 new SubCstIntVarIterator(var_,
cst_,
false, reversible));
2928 int64_t OldMin()
const override {
return CapSub(
cst_, var_->OldMax()); }
2929 int64_t OldMax()
const override {
return CapSub(
cst_, var_->OldMin()); }
2930 std::string DebugString()
const override;
2931 std::string
name()
const override;
2932 int VarType()
const override {
return CST_SUB_VAR; }
2934 void Accept(ModelVisitor*
const visitor)
const override {
2935 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation,
2939 IntVar* IsEqual(int64_t constant)
override {
2940 return var_->IsEqual(
cst_ - constant);
2943 IntVar* IsDifferent(int64_t constant)
override {
2944 return var_->IsDifferent(
cst_ - constant);
2947 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2948 return var_->IsLessOrEqual(
cst_ - constant);
2951 IntVar* IsLessOrEqual(int64_t constant)
override {
2952 return var_->IsGreaterOrEqual(
cst_ - constant);
2955 IntVar* SubVar()
const {
return var_; }
2956 int64_t Constant()
const {
return cst_; }
2963 SubCstIntVar::SubCstIntVar(Solver*
const s, IntVar* v, int64_t c)
2964 : IntVar(s), var_(v),
cst_(c) {}
2966 SubCstIntVar::~SubCstIntVar() {}
2968 int64_t SubCstIntVar::Min()
const {
return cst_ - var_->Max(); }
2970 void SubCstIntVar::SetMin(int64_t m) { var_->SetMax(
CapSub(
cst_, m)); }
2972 int64_t SubCstIntVar::Max()
const {
return cst_ - var_->Min(); }
2974 void SubCstIntVar::SetMax(int64_t m) { var_->SetMin(
CapSub(
cst_, m)); }
2976 void SubCstIntVar::SetRange(int64_t l, int64_t u) {
2980 void SubCstIntVar::SetValue(int64_t v) { var_->SetValue(
cst_ - v); }
2982 bool SubCstIntVar::Bound()
const {
return var_->Bound(); }
2984 void SubCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
2988 void SubCstIntVar::RemoveValue(int64_t v) { var_->RemoveValue(
cst_ - v); }
2990 void SubCstIntVar::RemoveInterval(int64_t l, int64_t u) {
2991 var_->RemoveInterval(
cst_ - u,
cst_ - l);
2994 void SubCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
2996 void SubCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
2998 uint64_t SubCstIntVar::Size()
const {
return var_->Size(); }
3000 bool SubCstIntVar::Contains(int64_t v)
const {
3001 return var_->Contains(
cst_ - v);
3004 std::string SubCstIntVar::DebugString()
const {
3006 return absl::StrFormat(
"Not(%s)", var_->DebugString());
3008 return absl::StrFormat(
"(%d - %s)",
cst_, var_->DebugString());
3013 if (solver()->HasName(
this)) {
3016 return absl::StrFormat(
"Not(%s)", var_->name());
3018 return absl::StrFormat(
"(%d - %s)",
cst_, var_->name());
3024 class OppIntVar :
public IntVar {
3026 class OppIntVarIterator :
public UnaryIterator {
3028 OppIntVarIterator(
const IntVar*
const v,
bool hole,
bool reversible)
3029 : UnaryIterator(v, hole, reversible) {}
3030 ~OppIntVarIterator()
override {}
3035 OppIntVar(Solver*
const s, IntVar* v);
3036 ~OppIntVar()
override;
3038 int64_t Min()
const override;
3039 void SetMin(int64_t m)
override;
3040 int64_t Max()
const override;
3041 void SetMax(int64_t m)
override;
3042 void SetRange(int64_t l, int64_t u)
override;
3043 void SetValue(int64_t v)
override;
3044 bool Bound()
const override;
3045 int64_t
Value()
const override;
3046 void RemoveValue(int64_t v)
override;
3047 void RemoveInterval(int64_t l, int64_t u)
override;
3048 uint64_t Size()
const override;
3049 bool Contains(int64_t v)
const override;
3050 void WhenRange(Demon* d)
override;
3051 void WhenBound(Demon* d)
override;
3052 void WhenDomain(Demon* d)
override;
3053 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3054 return CondRevAlloc(solver(), reversible,
3055 new OppIntVarIterator(var_,
true, reversible));
3057 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3058 return CondRevAlloc(solver(), reversible,
3059 new OppIntVarIterator(var_,
false, reversible));
3061 int64_t OldMin()
const override {
return CapOpp(var_->OldMax()); }
3062 int64_t OldMax()
const override {
return CapOpp(var_->OldMin()); }
3063 std::string DebugString()
const override;
3064 int VarType()
const override {
return OPP_VAR; }
3066 void Accept(ModelVisitor*
const visitor)
const override {
3067 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation, 0,
3071 IntVar* IsEqual(int64_t constant)
override {
3072 return var_->IsEqual(-constant);
3075 IntVar* IsDifferent(int64_t constant)
override {
3076 return var_->IsDifferent(-constant);
3079 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3080 return var_->IsLessOrEqual(-constant);
3083 IntVar* IsLessOrEqual(int64_t constant)
override {
3084 return var_->IsGreaterOrEqual(-constant);
3087 IntVar* SubVar()
const {
return var_; }
3093 OppIntVar::OppIntVar(Solver*
const s, IntVar* v) : IntVar(s), var_(v) {}
3095 OppIntVar::~OppIntVar() {}
3097 int64_t OppIntVar::Min()
const {
return -var_->Max(); }
3099 void OppIntVar::SetMin(int64_t m) { var_->SetMax(
CapOpp(m)); }
3101 int64_t OppIntVar::Max()
const {
return -var_->Min(); }
3103 void OppIntVar::SetMax(int64_t m) { var_->SetMin(
CapOpp(m)); }
3105 void OppIntVar::SetRange(int64_t l, int64_t u) {
3109 void OppIntVar::SetValue(int64_t v) { var_->SetValue(
CapOpp(v)); }
3111 bool OppIntVar::Bound()
const {
return var_->Bound(); }
3113 void OppIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3117 void OppIntVar::RemoveValue(int64_t v) { var_->RemoveValue(-v); }
3119 void OppIntVar::RemoveInterval(int64_t l, int64_t u) {
3120 var_->RemoveInterval(-u, -l);
3123 void OppIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3125 void OppIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3127 uint64_t OppIntVar::Size()
const {
return var_->Size(); }
3129 bool OppIntVar::Contains(int64_t v)
const {
return var_->Contains(-v); }
3131 std::string OppIntVar::DebugString()
const {
3132 return absl::StrFormat(
"-(%s)", var_->DebugString());
3139 class TimesCstIntVar :
public IntVar {
3141 TimesCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3142 : IntVar(s), var_(v),
cst_(c) {}
3143 ~TimesCstIntVar()
override {}
3145 IntVar* SubVar()
const {
return var_; }
3146 int64_t Constant()
const {
return cst_; }
3148 void Accept(ModelVisitor*
const visitor)
const override {
3149 visitor->VisitIntegerVariable(
this, ModelVisitor::kProductOperation,
cst_,
3153 IntVar* IsEqual(int64_t constant)
override {
3154 if (constant %
cst_ == 0) {
3155 return var_->IsEqual(constant /
cst_);
3157 return solver()->MakeIntConst(0);
3161 IntVar* IsDifferent(int64_t constant)
override {
3162 if (constant %
cst_ == 0) {
3163 return var_->IsDifferent(constant /
cst_);
3165 return solver()->MakeIntConst(1);
3169 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3177 IntVar* IsLessOrEqual(int64_t constant)
override {
3185 std::string DebugString()
const override {
3186 return absl::StrFormat(
"(%s * %d)", var_->DebugString(),
cst_);
3196 class TimesPosCstIntVar :
public TimesCstIntVar {
3198 class TimesPosCstIntVarIterator :
public UnaryIterator {
3200 TimesPosCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3202 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3203 ~TimesPosCstIntVarIterator()
override {}
3211 TimesPosCstIntVar(Solver*
const s, IntVar* v, int64_t c);
3212 ~TimesPosCstIntVar()
override;
3214 int64_t Min()
const override;
3215 void SetMin(int64_t m)
override;
3216 int64_t Max()
const override;
3217 void SetMax(int64_t m)
override;
3218 void SetRange(int64_t l, int64_t u)
override;
3219 void SetValue(int64_t v)
override;
3220 bool Bound()
const override;
3221 int64_t
Value()
const override;
3222 void RemoveValue(int64_t v)
override;
3223 void RemoveInterval(int64_t l, int64_t u)
override;
3224 uint64_t Size()
const override;
3225 bool Contains(int64_t v)
const override;
3226 void WhenRange(Demon* d)
override;
3227 void WhenBound(Demon* d)
override;
3228 void WhenDomain(Demon* d)
override;
3229 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3230 return CondRevAlloc(
3231 solver(), reversible,
3232 new TimesPosCstIntVarIterator(var_,
cst_,
true, reversible));
3234 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3235 return CondRevAlloc(
3236 solver(), reversible,
3237 new TimesPosCstIntVarIterator(var_,
cst_,
false, reversible));
3239 int64_t OldMin()
const override {
return CapProd(var_->OldMin(),
cst_); }
3240 int64_t OldMax()
const override {
return CapProd(var_->OldMax(),
cst_); }
3245 TimesPosCstIntVar::TimesPosCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3246 : TimesCstIntVar(s, v, c) {}
3248 TimesPosCstIntVar::~TimesPosCstIntVar() {}
3250 int64_t TimesPosCstIntVar::Min()
const {
return CapProd(var_->Min(),
cst_); }
3252 void TimesPosCstIntVar::SetMin(int64_t m) {
3258 int64_t TimesPosCstIntVar::Max()
const {
return CapProd(var_->Max(),
cst_); }
3260 void TimesPosCstIntVar::SetMax(int64_t m) {
3266 void TimesPosCstIntVar::SetRange(int64_t l, int64_t u) {
3270 void TimesPosCstIntVar::SetValue(int64_t v) {
3271 if (v %
cst_ != 0) {
3274 var_->SetValue(v /
cst_);
3277 bool TimesPosCstIntVar::Bound()
const {
return var_->Bound(); }
3279 void TimesPosCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3285 void TimesPosCstIntVar::RemoveValue(int64_t v) {
3286 if (v %
cst_ == 0) {
3287 var_->RemoveValue(v /
cst_);
3291 void TimesPosCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3292 for (int64_t v = l; v <= u; ++v) {
3298 void TimesPosCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3300 void TimesPosCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3302 uint64_t TimesPosCstIntVar::Size()
const {
return var_->Size(); }
3304 bool TimesPosCstIntVar::Contains(int64_t v)
const {
3305 return (v %
cst_ == 0 && var_->Contains(v /
cst_));
3310 class TimesPosCstBoolVar :
public TimesCstIntVar {
3312 class TimesPosCstBoolVarIterator :
public UnaryIterator {
3315 TimesPosCstBoolVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3317 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3318 ~TimesPosCstBoolVarIterator()
override {}
3326 TimesPosCstBoolVar(Solver*
const s, BooleanVar* v, int64_t c);
3327 ~TimesPosCstBoolVar()
override;
3329 int64_t Min()
const override;
3330 void SetMin(int64_t m)
override;
3331 int64_t Max()
const override;
3332 void SetMax(int64_t m)
override;
3333 void SetRange(int64_t l, int64_t u)
override;
3334 void SetValue(int64_t v)
override;
3335 bool Bound()
const override;
3336 int64_t
Value()
const override;
3337 void RemoveValue(int64_t v)
override;
3338 void RemoveInterval(int64_t l, int64_t u)
override;
3339 uint64_t Size()
const override;
3340 bool Contains(int64_t v)
const override;
3341 void WhenRange(Demon* d)
override;
3342 void WhenBound(Demon* d)
override;
3343 void WhenDomain(Demon* d)
override;
3344 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3345 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
3347 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3348 return CondRevAlloc(
3349 solver(), reversible,
3350 new TimesPosCstBoolVarIterator(boolean_var(),
cst_,
false, reversible));
3352 int64_t OldMin()
const override {
return 0; }
3353 int64_t OldMax()
const override {
return cst_; }
3355 BooleanVar* boolean_var()
const {
3356 return reinterpret_cast<BooleanVar*
>(var_);
3362 TimesPosCstBoolVar::TimesPosCstBoolVar(Solver*
const s, BooleanVar* v,
3364 : TimesCstIntVar(s, v, c) {}
3366 TimesPosCstBoolVar::~TimesPosCstBoolVar() {}
3368 int64_t TimesPosCstBoolVar::Min()
const {
3369 return (boolean_var()->RawValue() == 1) *
cst_;
3372 void TimesPosCstBoolVar::SetMin(int64_t m) {
3376 boolean_var()->SetMin(1);
3380 int64_t TimesPosCstBoolVar::Max()
const {
3381 return (boolean_var()->RawValue() != 0) *
cst_;
3384 void TimesPosCstBoolVar::SetMax(int64_t m) {
3387 }
else if (m <
cst_) {
3388 boolean_var()->SetMax(0);
3392 void TimesPosCstBoolVar::SetRange(int64_t l, int64_t u) {
3393 if (u < 0 || l >
cst_ || l > u) {
3397 boolean_var()->SetMin(1);
3398 }
else if (u <
cst_) {
3399 boolean_var()->SetMax(0);
3403 void TimesPosCstBoolVar::SetValue(int64_t v) {
3405 boolean_var()->SetValue(0);
3406 }
else if (v ==
cst_) {
3407 boolean_var()->SetValue(1);
3413 bool TimesPosCstBoolVar::Bound()
const {
3414 return boolean_var()->RawValue() != BooleanVar::kUnboundBooleanVarValue;
3417 void TimesPosCstBoolVar::WhenRange(Demon* d) { boolean_var()->WhenRange(d); }
3420 CHECK_NE(boolean_var()->RawValue(), BooleanVar::kUnboundBooleanVarValue)
3421 <<
" variable is not bound";
3422 return boolean_var()->RawValue() *
cst_;
3425 void TimesPosCstBoolVar::RemoveValue(int64_t v) {
3427 boolean_var()->RemoveValue(0);
3428 }
else if (v ==
cst_) {
3429 boolean_var()->RemoveValue(1);
3433 void TimesPosCstBoolVar::RemoveInterval(int64_t l, int64_t u) {
3434 if (l <= 0 && u >= 0) {
3435 boolean_var()->RemoveValue(0);
3437 if (l <= cst_ && u >=
cst_) {
3438 boolean_var()->RemoveValue(1);
3442 void TimesPosCstBoolVar::WhenBound(Demon* d) { boolean_var()->WhenBound(d); }
3444 void TimesPosCstBoolVar::WhenDomain(Demon* d) { boolean_var()->WhenDomain(d); }
3446 uint64_t TimesPosCstBoolVar::Size()
const {
3448 (boolean_var()->RawValue() == BooleanVar::kUnboundBooleanVarValue));
3451 bool TimesPosCstBoolVar::Contains(int64_t v)
const {
3453 return boolean_var()->RawValue() != 1;
3454 }
else if (v ==
cst_) {
3455 return boolean_var()->RawValue() != 0;
3462 class TimesNegCstIntVar :
public TimesCstIntVar {
3464 class TimesNegCstIntVarIterator :
public UnaryIterator {
3466 TimesNegCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3468 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3469 ~TimesNegCstIntVarIterator()
override {}
3477 TimesNegCstIntVar(Solver*
const s, IntVar* v, int64_t c);
3478 ~TimesNegCstIntVar()
override;
3480 int64_t Min()
const override;
3481 void SetMin(int64_t m)
override;
3482 int64_t Max()
const override;
3483 void SetMax(int64_t m)
override;
3484 void SetRange(int64_t l, int64_t u)
override;
3485 void SetValue(int64_t v)
override;
3486 bool Bound()
const override;
3487 int64_t
Value()
const override;
3488 void RemoveValue(int64_t v)
override;
3489 void RemoveInterval(int64_t l, int64_t u)
override;
3490 uint64_t Size()
const override;
3491 bool Contains(int64_t v)
const override;
3492 void WhenRange(Demon* d)
override;
3493 void WhenBound(Demon* d)
override;
3494 void WhenDomain(Demon* d)
override;
3495 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3496 return CondRevAlloc(
3497 solver(), reversible,
3498 new TimesNegCstIntVarIterator(var_,
cst_,
true, reversible));
3500 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3501 return CondRevAlloc(
3502 solver(), reversible,
3503 new TimesNegCstIntVarIterator(var_,
cst_,
false, reversible));
3505 int64_t OldMin()
const override {
return CapProd(var_->OldMax(),
cst_); }
3506 int64_t OldMax()
const override {
return CapProd(var_->OldMin(),
cst_); }
3511 TimesNegCstIntVar::TimesNegCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3512 : TimesCstIntVar(s, v, c) {}
3514 TimesNegCstIntVar::~TimesNegCstIntVar() {}
3516 int64_t TimesNegCstIntVar::Min()
const {
return CapProd(var_->Max(),
cst_); }
3518 void TimesNegCstIntVar::SetMin(int64_t m) {
3524 int64_t TimesNegCstIntVar::Max()
const {
return CapProd(var_->Min(),
cst_); }
3526 void TimesNegCstIntVar::SetMax(int64_t m) {
3532 void TimesNegCstIntVar::SetRange(int64_t l, int64_t u) {
3537 void TimesNegCstIntVar::SetValue(int64_t v) {
3538 if (v %
cst_ != 0) {
3541 var_->SetValue(v /
cst_);
3544 bool TimesNegCstIntVar::Bound()
const {
return var_->Bound(); }
3546 void TimesNegCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3552 void TimesNegCstIntVar::RemoveValue(int64_t v) {
3553 if (v %
cst_ == 0) {
3554 var_->RemoveValue(v /
cst_);
3558 void TimesNegCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3559 for (int64_t v = l; v <= u; ++v) {
3565 void TimesNegCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3567 void TimesNegCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3569 uint64_t TimesNegCstIntVar::Size()
const {
return var_->Size(); }
3571 bool TimesNegCstIntVar::Contains(int64_t v)
const {
3572 return (v %
cst_ == 0 && var_->Contains(v /
cst_));
3579 class PlusIntExpr :
public BaseIntExpr {
3581 PlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3582 : BaseIntExpr(s), left_(l), right_(r) {}
3584 ~PlusIntExpr()
override {}
3586 int64_t Min()
const override {
return left_->Min() + right_->Min(); }
3588 void SetMin(int64_t m)
override {
3589 if (m > left_->Min() + right_->Min()) {
3591 if (m > right_->Max() + left_->Max()) solver()->Fail();
3592 left_->SetMin(m - right_->Max());
3593 right_->SetMin(m - left_->Max());
3597 void SetRange(int64_t l, int64_t u)
override {
3598 const int64_t left_min = left_->Min();
3599 const int64_t right_min = right_->Min();
3600 const int64_t left_max = left_->Max();
3601 const int64_t right_max = right_->Max();
3602 if (l > left_min + right_min) {
3604 if (l > right_max + left_max) solver()->Fail();
3605 left_->SetMin(l - right_max);
3606 right_->SetMin(l - left_max);
3608 if (u < left_max + right_max) {
3610 if (u < right_min + left_min) solver()->Fail();
3611 left_->SetMax(u - right_min);
3612 right_->SetMax(u - left_min);
3616 int64_t Max()
const override {
return left_->Max() + right_->Max(); }
3618 void SetMax(int64_t m)
override {
3619 if (m < left_->Max() + right_->Max()) {
3621 if (m < right_->Min() + left_->Min()) solver()->Fail();
3622 left_->SetMax(m - right_->Min());
3623 right_->SetMax(m - left_->Min());
3627 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3629 void Range(int64_t*
const mi, int64_t*
const ma)
override {
3630 *mi = left_->Min() + right_->Min();
3631 *ma = left_->Max() + right_->Max();
3634 std::string
name()
const override {
3635 return absl::StrFormat(
"(%s + %s)", left_->name(), right_->name());
3638 std::string DebugString()
const override {
3639 return absl::StrFormat(
"(%s + %s)", left_->DebugString(),
3640 right_->DebugString());
3643 void WhenRange(Demon* d)
override {
3644 left_->WhenRange(d);
3645 right_->WhenRange(d);
3648 void ExpandPlusIntExpr(IntExpr*
const expr, std::vector<IntExpr*>* subs) {
3649 PlusIntExpr*
const casted =
dynamic_cast<PlusIntExpr*
>(expr);
3650 if (casted !=
nullptr) {
3651 ExpandPlusIntExpr(casted->left_, subs);
3652 ExpandPlusIntExpr(casted->right_, subs);
3654 subs->push_back(expr);
3658 IntVar* CastToVar()
override {
3659 if (
dynamic_cast<PlusIntExpr*
>(left_) !=
nullptr ||
3660 dynamic_cast<PlusIntExpr*
>(right_) !=
nullptr) {
3661 std::vector<IntExpr*> sub_exprs;
3662 ExpandPlusIntExpr(left_, &sub_exprs);
3663 ExpandPlusIntExpr(right_, &sub_exprs);
3664 if (sub_exprs.size() >= 3) {
3665 std::vector<IntVar*> sub_vars(sub_exprs.size());
3666 for (
int i = 0; i < sub_exprs.size(); ++i) {
3667 sub_vars[i] = sub_exprs[i]->Var();
3669 return solver()->MakeSum(sub_vars)->Var();
3672 return BaseIntExpr::CastToVar();
3675 void Accept(ModelVisitor*
const visitor)
const override {
3676 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3677 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3678 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3680 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3684 IntExpr*
const left_;
3685 IntExpr*
const right_;
3688 class SafePlusIntExpr :
public BaseIntExpr {
3690 SafePlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3691 : BaseIntExpr(s), left_(l), right_(r) {}
3693 ~SafePlusIntExpr()
override {}
3695 int64_t Min()
const override {
return CapAdd(left_->Min(), right_->Min()); }
3697 void SetMin(int64_t m)
override {
3698 left_->SetMin(
CapSub(m, right_->Max()));
3699 right_->SetMin(
CapSub(m, left_->Max()));
3702 void SetRange(int64_t l, int64_t u)
override {
3703 const int64_t left_min = left_->Min();
3704 const int64_t right_min = right_->Min();
3705 const int64_t left_max = left_->Max();
3706 const int64_t right_max = right_->Max();
3707 if (l >
CapAdd(left_min, right_min)) {
3708 left_->SetMin(
CapSub(l, right_max));
3709 right_->SetMin(
CapSub(l, left_max));
3711 if (u <
CapAdd(left_max, right_max)) {
3712 left_->SetMax(
CapSub(u, right_min));
3713 right_->SetMax(
CapSub(u, left_min));
3717 int64_t Max()
const override {
return CapAdd(left_->Max(), right_->Max()); }
3719 void SetMax(int64_t m)
override {
3720 left_->SetMax(
CapSub(m, right_->Min()));
3721 right_->SetMax(
CapSub(m, left_->Min()));
3724 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3726 std::string
name()
const override {
3727 return absl::StrFormat(
"(%s + %s)", left_->name(), right_->name());
3730 std::string DebugString()
const override {
3731 return absl::StrFormat(
"(%s + %s)", left_->DebugString(),
3732 right_->DebugString());
3735 void WhenRange(Demon* d)
override {
3736 left_->WhenRange(d);
3737 right_->WhenRange(d);
3740 void Accept(ModelVisitor*
const visitor)
const override {
3741 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3742 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3743 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3745 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3749 IntExpr*
const left_;
3750 IntExpr*
const right_;
3755 class PlusIntCstExpr :
public BaseIntExpr {
3757 PlusIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3758 : BaseIntExpr(s),
expr_(e), value_(v) {}
3759 ~PlusIntCstExpr()
override {}
3760 int64_t Min()
const override {
return CapAdd(
expr_->Min(), value_); }
3761 void SetMin(int64_t m)
override {
expr_->SetMin(
CapSub(m, value_)); }
3762 int64_t Max()
const override {
return CapAdd(
expr_->Max(), value_); }
3763 void SetMax(int64_t m)
override {
expr_->SetMax(
CapSub(m, value_)); }
3764 bool Bound()
const override {
return (
expr_->Bound()); }
3765 std::string
name()
const override {
3766 return absl::StrFormat(
"(%s + %d)",
expr_->name(), value_);
3768 std::string DebugString()
const override {
3769 return absl::StrFormat(
"(%s + %d)",
expr_->DebugString(), value_);
3771 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3772 IntVar* CastToVar()
override;
3773 void Accept(ModelVisitor*
const visitor)
const override {
3774 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3775 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3777 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3778 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3782 IntExpr*
const expr_;
3783 const int64_t value_;
3786 IntVar* PlusIntCstExpr::CastToVar() {
3787 Solver*
const s = solver();
3789 IntVar* cast =
nullptr;
3792 return BaseIntExpr::CastToVar();
3794 switch (
var->VarType()) {
3796 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstDomainIntVar(
3797 s,
reinterpret_cast<DomainIntVar*
>(
var), value_)));
3801 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstIntVar(s,
var, value_)));
3809 class SubIntExpr :
public BaseIntExpr {
3811 SubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3812 : BaseIntExpr(s), left_(l), right_(r) {}
3814 ~SubIntExpr()
override {}
3816 int64_t Min()
const override {
return left_->Min() - right_->Max(); }
3818 void SetMin(int64_t m)
override {
3819 left_->SetMin(
CapAdd(m, right_->Min()));
3820 right_->SetMax(
CapSub(left_->Max(), m));
3823 int64_t Max()
const override {
return left_->Max() - right_->Min(); }
3825 void SetMax(int64_t m)
override {
3826 left_->SetMax(
CapAdd(m, right_->Max()));
3827 right_->SetMin(
CapSub(left_->Min(), m));
3830 void Range(int64_t* mi, int64_t* ma)
override {
3831 *mi = left_->Min() - right_->Max();
3832 *ma = left_->Max() - right_->Min();
3835 void SetRange(int64_t l, int64_t u)
override {
3836 const int64_t left_min = left_->Min();
3837 const int64_t right_min = right_->Min();
3838 const int64_t left_max = left_->Max();
3839 const int64_t right_max = right_->Max();
3840 if (l > left_min - right_max) {
3841 left_->SetMin(
CapAdd(l, right_min));
3842 right_->SetMax(
CapSub(left_max, l));
3844 if (u < left_max - right_min) {
3845 left_->SetMax(
CapAdd(u, right_max));
3846 right_->SetMin(
CapSub(left_min, u));
3850 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3852 std::string
name()
const override {
3853 return absl::StrFormat(
"(%s - %s)", left_->name(), right_->name());
3856 std::string DebugString()
const override {
3857 return absl::StrFormat(
"(%s - %s)", left_->DebugString(),
3858 right_->DebugString());
3861 void WhenRange(Demon* d)
override {
3862 left_->WhenRange(d);
3863 right_->WhenRange(d);
3866 void Accept(ModelVisitor*
const visitor)
const override {
3867 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3868 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3869 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3871 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3874 IntExpr* left()
const {
return left_; }
3875 IntExpr* right()
const {
return right_; }
3878 IntExpr*
const left_;
3879 IntExpr*
const right_;
3882 class SafeSubIntExpr :
public SubIntExpr {
3884 SafeSubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3885 : SubIntExpr(s, l, r) {}
3887 ~SafeSubIntExpr()
override {}
3889 int64_t Min()
const override {
return CapSub(left_->Min(), right_->Max()); }
3891 void SetMin(int64_t m)
override {
3892 left_->SetMin(
CapAdd(m, right_->Min()));
3893 right_->SetMax(
CapSub(left_->Max(), m));
3896 void SetRange(int64_t l, int64_t u)
override {
3897 const int64_t left_min = left_->Min();
3898 const int64_t right_min = right_->Min();
3899 const int64_t left_max = left_->Max();
3900 const int64_t right_max = right_->Max();
3901 if (l >
CapSub(left_min, right_max)) {
3902 left_->SetMin(
CapAdd(l, right_min));
3903 right_->SetMax(
CapSub(left_max, l));
3905 if (u <
CapSub(left_max, right_min)) {
3906 left_->SetMax(
CapAdd(u, right_max));
3907 right_->SetMin(
CapSub(left_min, u));
3911 void Range(int64_t* mi, int64_t* ma)
override {
3912 *mi =
CapSub(left_->Min(), right_->Max());
3913 *ma =
CapSub(left_->Max(), right_->Min());
3916 int64_t Max()
const override {
return CapSub(left_->Max(), right_->Min()); }
3918 void SetMax(int64_t m)
override {
3919 left_->SetMax(
CapAdd(m, right_->Max()));
3920 right_->SetMin(
CapSub(left_->Min(), m));
3928 class SubIntCstExpr :
public BaseIntExpr {
3930 SubIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3931 : BaseIntExpr(s),
expr_(e), value_(v) {}
3932 ~SubIntCstExpr()
override {}
3933 int64_t Min()
const override {
return CapSub(value_,
expr_->Max()); }
3934 void SetMin(int64_t m)
override {
expr_->SetMax(
CapSub(value_, m)); }
3935 int64_t Max()
const override {
return CapSub(value_,
expr_->Min()); }
3936 void SetMax(int64_t m)
override {
expr_->SetMin(
CapSub(value_, m)); }
3937 bool Bound()
const override {
return (
expr_->Bound()); }
3938 std::string
name()
const override {
3939 return absl::StrFormat(
"(%d - %s)", value_,
expr_->name());
3941 std::string DebugString()
const override {
3942 return absl::StrFormat(
"(%d - %s)", value_,
expr_->DebugString());
3944 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3945 IntVar* CastToVar()
override;
3947 void Accept(ModelVisitor*
const visitor)
const override {
3948 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3949 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3950 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3952 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3956 IntExpr*
const expr_;
3957 const int64_t value_;
3960 IntVar* SubIntCstExpr::CastToVar() {
3963 return BaseIntExpr::CastToVar();
3965 Solver*
const s = solver();
3967 s->RegisterIntVar(s->RevAlloc(
new SubCstIntVar(s,
expr_->Var(), value_)));
3973 class OppIntExpr :
public BaseIntExpr {
3975 OppIntExpr(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
3976 ~OppIntExpr()
override {}
3977 int64_t Min()
const override {
return (
CapOpp(
expr_->Max())); }
3978 void SetMin(int64_t m)
override {
expr_->SetMax(
CapOpp(m)); }
3979 int64_t Max()
const override {
return (
CapOpp(
expr_->Min())); }
3980 void SetMax(int64_t m)
override {
expr_->SetMin(
CapOpp(m)); }
3981 bool Bound()
const override {
return (
expr_->Bound()); }
3982 std::string
name()
const override {
3983 return absl::StrFormat(
"(-%s)",
expr_->name());
3985 std::string DebugString()
const override {
3986 return absl::StrFormat(
"(-%s)",
expr_->DebugString());
3988 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3989 IntVar* CastToVar()
override;
3991 void Accept(ModelVisitor*
const visitor)
const override {
3992 visitor->BeginVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3993 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3995 visitor->EndVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3999 IntExpr*
const expr_;
4002 IntVar* OppIntExpr::CastToVar() {
4003 Solver*
const s = solver();
4005 s->RegisterIntVar(s->RevAlloc(
new OppIntVar(s,
expr_->Var())));
4011 class TimesIntCstExpr :
public BaseIntExpr {
4013 TimesIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4014 : BaseIntExpr(s),
expr_(e), value_(v) {}
4016 ~TimesIntCstExpr()
override {}
4018 bool Bound()
const override {
return (
expr_->Bound()); }
4020 std::string
name()
const override {
4021 return absl::StrFormat(
"(%s * %d)",
expr_->name(), value_);
4024 std::string DebugString()
const override {
4025 return absl::StrFormat(
"(%s * %d)",
expr_->DebugString(), value_);
4028 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
4030 IntExpr* Expr()
const {
return expr_; }
4032 int64_t Constant()
const {
return value_; }
4034 void Accept(ModelVisitor*
const visitor)
const override {
4035 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4036 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4038 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4039 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4043 IntExpr*
const expr_;
4044 const int64_t value_;
4049 class TimesPosIntCstExpr :
public TimesIntCstExpr {
4051 TimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4052 : TimesIntCstExpr(s, e, v) {
4056 ~TimesPosIntCstExpr()
override {}
4058 int64_t Min()
const override {
return expr_->Min() * value_; }
4062 int64_t Max()
const override {
return expr_->Max() * value_; }
4066 IntVar* CastToVar()
override {
4067 Solver*
const s = solver();
4068 IntVar*
var =
nullptr;
4069 if (
expr_->IsVar() &&
4071 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4072 s,
reinterpret_cast<BooleanVar*
>(
expr_), value_)));
4074 var = s->RegisterIntVar(
4075 s->RevAlloc(
new TimesPosCstIntVar(s,
expr_->Var(), value_)));
4083 class SafeTimesPosIntCstExpr :
public TimesIntCstExpr {
4085 SafeTimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4086 : TimesIntCstExpr(s, e, v) {
4090 ~SafeTimesPosIntCstExpr()
override {}
4092 int64_t Min()
const override {
return CapProd(
expr_->Min(), value_); }
4094 void SetMin(int64_t m)
override {
4100 int64_t Max()
const override {
return CapProd(
expr_->Max(), value_); }
4102 void SetMax(int64_t m)
override {
4108 IntVar* CastToVar()
override {
4109 Solver*
const s = solver();
4110 IntVar*
var =
nullptr;
4111 if (
expr_->IsVar() &&
4113 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4114 s,
reinterpret_cast<BooleanVar*
>(
expr_), value_)));
4117 var = s->RegisterIntVar(
4118 s->RevAlloc(
new TimesPosCstIntVar(s,
expr_->Var(), value_)));
4126 class TimesIntNegCstExpr :
public TimesIntCstExpr {
4128 TimesIntNegCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4129 : TimesIntCstExpr(s, e, v) {
4133 ~TimesIntNegCstExpr()
override {}
4135 int64_t Min()
const override {
return CapProd(
expr_->Max(), value_); }
4137 void SetMin(int64_t m)
override {
4143 int64_t Max()
const override {
return CapProd(
expr_->Min(), value_); }
4145 void SetMax(int64_t m)
override {
4151 IntVar* CastToVar()
override {
4152 Solver*
const s = solver();
4153 IntVar*
var =
nullptr;
4154 var = s->RegisterIntVar(
4155 s->RevAlloc(
new TimesNegCstIntVar(s,
expr_->Var(), value_)));
4163 void SetPosPosMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4164 DCHECK_GE(left->Min(), 0);
4165 DCHECK_GE(right->Min(), 0);
4166 const int64_t lmax = left->Max();
4167 const int64_t rmax = right->Max();
4168 if (m >
CapProd(lmax, rmax)) {
4169 left->solver()->Fail();
4171 if (m >
CapProd(left->Min(), right->Min())) {
4183 void SetPosPosMaxExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4184 DCHECK_GE(left->Min(), 0);
4185 DCHECK_GE(right->Min(), 0);
4186 const int64_t lmin = left->Min();
4187 const int64_t rmin = right->Min();
4188 if (m <
CapProd(lmin, rmin)) {
4189 left->solver()->Fail();
4191 if (m <
CapProd(left->Max(), right->Max())) {
4203 void SetPosGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4204 DCHECK_GE(left->Min(), 0);
4205 DCHECK_GT(right->Max(), 0);
4206 DCHECK_LT(right->Min(), 0);
4207 const int64_t lmax = left->Max();
4208 const int64_t rmax = right->Max();
4209 if (m >
CapProd(lmax, rmax)) {
4210 left->solver()->Fail();
4212 if (left->Max() == 0) {
4213 DCHECK_EQ(0, left->Min());
4219 }
else if (m == 0) {
4220 const int64_t lmin = left->Min();
4225 const int64_t lmin = left->Min();
4234 void SetGenGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4235 DCHECK_LT(left->Min(), 0);
4236 DCHECK_GT(left->Max(), 0);
4237 DCHECK_GT(right->Max(), 0);
4238 DCHECK_LT(right->Min(), 0);
4239 const int64_t lmin = left->Min();
4240 const int64_t lmax = left->Max();
4241 const int64_t rmin = right->Min();
4242 const int64_t rmax = right->Max();
4244 left->solver()->Fail();
4250 }
else if (m >
CapProd(lmax, rmax)) {
4256 void TimesSetMin(IntExpr*
const left, IntExpr*
const right,
4257 IntExpr*
const minus_left, IntExpr*
const minus_right,
4259 if (left->Min() >= 0) {
4260 if (right->Min() >= 0) {
4261 SetPosPosMinExpr(left, right, m);
4262 }
else if (right->Max() <= 0) {
4263 SetPosPosMaxExpr(left, minus_right, -m);
4265 SetPosGenMinExpr(left, right, m);
4267 }
else if (left->Max() <= 0) {
4268 if (right->Min() >= 0) {
4269 SetPosPosMaxExpr(right, minus_left, -m);
4270 }
else if (right->Max() <= 0) {
4271 SetPosPosMinExpr(minus_left, minus_right, m);
4273 SetPosGenMinExpr(minus_left, minus_right, m);
4275 }
else if (right->Min() >= 0) {
4276 SetPosGenMinExpr(right, left, m);
4277 }
else if (right->Max() <= 0) {
4278 SetPosGenMinExpr(minus_right, minus_left, m);
4281 SetGenGenMinExpr(left, right, m);
4285 class TimesIntExpr :
public BaseIntExpr {
4287 TimesIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4291 minus_left_(s->MakeOpposite(left_)),
4292 minus_right_(s->MakeOpposite(right_)) {}
4293 ~TimesIntExpr()
override {}
4294 int64_t Min()
const override {
4295 const int64_t lmin = left_->Min();
4296 const int64_t lmax = left_->Max();
4297 const int64_t rmin = right_->Min();
4298 const int64_t rmax = right_->Max();
4302 void SetMin(int64_t m)
override;
4303 int64_t Max()
const override {
4304 const int64_t lmin = left_->Min();
4305 const int64_t lmax = left_->Max();
4306 const int64_t rmin = right_->Min();
4307 const int64_t rmax = right_->Max();
4311 void SetMax(int64_t m)
override;
4312 bool Bound()
const override;
4313 std::string
name()
const override {
4314 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4316 std::string DebugString()
const override {
4317 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4318 right_->DebugString());
4320 void WhenRange(Demon* d)
override {
4321 left_->WhenRange(d);
4322 right_->WhenRange(d);
4325 void Accept(ModelVisitor*
const visitor)
const override {
4326 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4327 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4328 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4330 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4334 IntExpr*
const left_;
4335 IntExpr*
const right_;
4336 IntExpr*
const minus_left_;
4337 IntExpr*
const minus_right_;
4340 void TimesIntExpr::SetMin(int64_t m) {
4342 TimesSetMin(left_, right_, minus_left_, minus_right_, m);
4346 void TimesIntExpr::SetMax(int64_t m) {
4348 TimesSetMin(left_, minus_right_, minus_left_, right_,
CapOpp(m));
4352 bool TimesIntExpr::Bound()
const {
4353 const bool left_bound = left_->Bound();
4354 const bool right_bound = right_->Bound();
4355 return ((left_bound && left_->Max() == 0) ||
4356 (right_bound && right_->Max() == 0) || (left_bound && right_bound));
4361 class TimesPosIntExpr :
public BaseIntExpr {
4363 TimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4364 : BaseIntExpr(s), left_(l), right_(r) {}
4365 ~TimesPosIntExpr()
override {}
4366 int64_t Min()
const override {
return (left_->Min() * right_->Min()); }
4367 void SetMin(int64_t m)
override;
4368 int64_t Max()
const override {
return (left_->Max() * right_->Max()); }
4369 void SetMax(int64_t m)
override;
4370 bool Bound()
const override;
4371 std::string
name()
const override {
4372 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4374 std::string DebugString()
const override {
4375 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4376 right_->DebugString());
4378 void WhenRange(Demon* d)
override {
4379 left_->WhenRange(d);
4380 right_->WhenRange(d);
4383 void Accept(ModelVisitor*
const visitor)
const override {
4384 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4385 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4386 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4388 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4392 IntExpr*
const left_;
4393 IntExpr*
const right_;
4396 void TimesPosIntExpr::SetMin(int64_t m) { SetPosPosMinExpr(left_, right_, m); }
4398 void TimesPosIntExpr::SetMax(int64_t m) { SetPosPosMaxExpr(left_, right_, m); }
4400 bool TimesPosIntExpr::Bound()
const {
4401 return (left_->Max() == 0 || right_->Max() == 0 ||
4402 (left_->Bound() && right_->Bound()));
4407 class SafeTimesPosIntExpr :
public BaseIntExpr {
4409 SafeTimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4410 : BaseIntExpr(s), left_(l), right_(r) {}
4411 ~SafeTimesPosIntExpr()
override {}
4412 int64_t Min()
const override {
return CapProd(left_->Min(), right_->Min()); }
4413 void SetMin(int64_t m)
override {
4415 SetPosPosMinExpr(left_, right_, m);
4418 int64_t Max()
const override {
return CapProd(left_->Max(), right_->Max()); }
4419 void SetMax(int64_t m)
override {
4421 SetPosPosMaxExpr(left_, right_, m);
4424 bool Bound()
const override {
4425 return (left_->Max() == 0 || right_->Max() == 0 ||
4426 (left_->Bound() && right_->Bound()));
4428 std::string
name()
const override {
4429 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4431 std::string DebugString()
const override {
4432 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4433 right_->DebugString());
4435 void WhenRange(Demon* d)
override {
4436 left_->WhenRange(d);
4437 right_->WhenRange(d);
4440 void Accept(ModelVisitor*
const visitor)
const override {
4441 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4442 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4443 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4445 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4449 IntExpr*
const left_;
4450 IntExpr*
const right_;
4455 class TimesBooleanPosIntExpr :
public BaseIntExpr {
4457 TimesBooleanPosIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4458 : BaseIntExpr(s), boolvar_(
b),
expr_(e) {}
4459 ~TimesBooleanPosIntExpr()
override {}
4460 int64_t Min()
const override {
4461 return (boolvar_->RawValue() == 1 ?
expr_->Min() : 0);
4463 void SetMin(int64_t m)
override;
4464 int64_t Max()
const override {
4465 return (boolvar_->RawValue() == 0 ? 0 :
expr_->Max());
4467 void SetMax(int64_t m)
override;
4468 void Range(int64_t* mi, int64_t* ma)
override;
4469 void SetRange(int64_t mi, int64_t ma)
override;
4470 bool Bound()
const override;
4471 std::string
name()
const override {
4472 return absl::StrFormat(
"(%s * %s)", boolvar_->name(),
expr_->name());
4474 std::string DebugString()
const override {
4475 return absl::StrFormat(
"(%s * %s)", boolvar_->DebugString(),
4476 expr_->DebugString());
4478 void WhenRange(Demon* d)
override {
4479 boolvar_->WhenRange(d);
4480 expr_->WhenRange(d);
4483 void Accept(ModelVisitor*
const visitor)
const override {
4484 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4485 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4487 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4489 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4493 BooleanVar*
const boolvar_;
4494 IntExpr*
const expr_;
4497 void TimesBooleanPosIntExpr::SetMin(int64_t m) {
4499 boolvar_->SetValue(1);
4504 void TimesBooleanPosIntExpr::SetMax(int64_t m) {
4508 if (m < expr_->Min()) {
4509 boolvar_->SetValue(0);
4511 if (boolvar_->RawValue() == 1) {
4517 const int value = boolvar_->RawValue();
4521 }
else if (
value == 1) {
4522 expr_->Range(mi, ma);
4529 void TimesBooleanPosIntExpr::SetRange(int64_t mi, int64_t ma) {
4530 if (ma < 0 || mi > ma) {
4534 boolvar_->SetValue(1);
4537 if (ma < expr_->Min()) {
4538 boolvar_->SetValue(0);
4540 if (boolvar_->RawValue() == 1) {
4545 bool TimesBooleanPosIntExpr::Bound()
const {
4546 return (boolvar_->RawValue() == 0 ||
expr_->Max() == 0 ||
4547 (boolvar_->RawValue() != BooleanVar::kUnboundBooleanVarValue &&
4553 class TimesBooleanIntExpr :
public BaseIntExpr {
4555 TimesBooleanIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4556 : BaseIntExpr(s), boolvar_(
b),
expr_(e) {}
4557 ~TimesBooleanIntExpr()
override {}
4558 int64_t Min()
const override {
4559 switch (boolvar_->RawValue()) {
4564 return expr_->Min();
4567 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4572 void SetMin(int64_t m)
override;
4573 int64_t Max()
const override {
4574 switch (boolvar_->RawValue()) {
4579 return expr_->Max();
4582 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4587 void SetMax(int64_t m)
override;
4588 void Range(int64_t* mi, int64_t* ma)
override;
4589 void SetRange(int64_t mi, int64_t ma)
override;
4590 bool Bound()
const override;
4591 std::string
name()
const override {
4592 return absl::StrFormat(
"(%s * %s)", boolvar_->name(),
expr_->name());
4594 std::string DebugString()
const override {
4595 return absl::StrFormat(
"(%s * %s)", boolvar_->DebugString(),
4596 expr_->DebugString());
4598 void WhenRange(Demon* d)
override {
4599 boolvar_->WhenRange(d);
4600 expr_->WhenRange(d);
4603 void Accept(ModelVisitor*
const visitor)
const override {
4604 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4605 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4607 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4609 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4613 BooleanVar*
const boolvar_;
4614 IntExpr*
const expr_;
4617 void TimesBooleanIntExpr::SetMin(int64_t m) {
4618 switch (boolvar_->RawValue()) {
4630 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4632 boolvar_->SetValue(1);
4634 }
else if (m <= 0 && expr_->Max() < m) {
4635 boolvar_->SetValue(0);
4641 void TimesBooleanIntExpr::SetMax(int64_t m) {
4642 switch (boolvar_->RawValue()) {
4654 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4656 boolvar_->SetValue(1);
4658 }
else if (m >= 0 &&
expr_->Min() > m) {
4659 boolvar_->SetValue(0);
4666 switch (boolvar_->RawValue()) {
4678 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4686 void TimesBooleanIntExpr::SetRange(int64_t mi, int64_t ma) {
4690 switch (boolvar_->RawValue()) {
4692 if (mi > 0 || ma < 0) {
4698 expr_->SetRange(mi, ma);
4702 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4704 boolvar_->SetValue(1);
4706 }
else if (mi == 0 &&
expr_->Max() < 0) {
4707 boolvar_->SetValue(0);
4710 boolvar_->SetValue(1);
4712 }
else if (ma == 0 &&
expr_->Min() > 0) {
4713 boolvar_->SetValue(0);
4720 bool TimesBooleanIntExpr::Bound()
const {
4721 return (boolvar_->RawValue() == 0 ||
4723 (boolvar_->RawValue() != BooleanVar::kUnboundBooleanVarValue ||
4724 expr_->Max() == 0)));
4729 class DivPosIntCstExpr :
public BaseIntExpr {
4731 DivPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4732 : BaseIntExpr(s),
expr_(e), value_(v) {
4735 ~DivPosIntCstExpr()
override {}
4737 int64_t Min()
const override {
return expr_->Min() / value_; }
4739 void SetMin(int64_t m)
override {
4741 expr_->SetMin(m * value_);
4743 expr_->SetMin((m - 1) * value_ + 1);
4746 int64_t Max()
const override {
return expr_->Max() / value_; }
4748 void SetMax(int64_t m)
override {
4750 expr_->SetMax((m + 1) * value_ - 1);
4752 expr_->SetMax(m * value_);
4756 std::string
name()
const override {
4757 return absl::StrFormat(
"(%s div %d)",
expr_->name(), value_);
4760 std::string DebugString()
const override {
4761 return absl::StrFormat(
"(%s div %d)",
expr_->DebugString(), value_);
4764 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
4766 void Accept(ModelVisitor*
const visitor)
const override {
4767 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4768 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4770 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4771 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4775 IntExpr*
const expr_;
4776 const int64_t value_;
4781 class DivPosIntExpr :
public BaseIntExpr {
4783 DivPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4787 opp_num_(s->MakeOpposite(num)) {}
4789 ~DivPosIntExpr()
override {}
4791 int64_t Min()
const override {
4792 return num_->Min() >= 0
4793 ? num_->Min() / denom_->Max()
4794 : (denom_->Min() == 0 ? num_->Min()
4795 : num_->Min() / denom_->Min());
4798 int64_t Max()
const override {
4799 return num_->Max() >= 0 ? (denom_->Min() == 0 ? num_->Max()
4800 : num_->Max() / denom_->Min())
4801 : num_->Max() / denom_->Max();
4804 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4805 num->SetMin(m * denom->Min());
4806 denom->SetMax(num->Max() / m);
4809 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4810 num->SetMax((m + 1) * denom->Max() - 1);
4811 denom->SetMin(num->Min() / (m + 1) + 1);
4814 void SetMin(int64_t m)
override {
4816 SetPosMin(num_, denom_, m);
4818 SetPosMax(opp_num_, denom_, -m);
4822 void SetMax(int64_t m)
override {
4824 SetPosMax(num_, denom_, m);
4826 SetPosMin(opp_num_, denom_, -m);
4830 std::string
name()
const override {
4831 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
4833 std::string DebugString()
const override {
4834 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
4835 denom_->DebugString());
4837 void WhenRange(Demon* d)
override {
4839 denom_->WhenRange(d);
4842 void Accept(ModelVisitor*
const visitor)
const override {
4843 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4844 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4845 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4847 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4851 IntExpr*
const num_;
4852 IntExpr*
const denom_;
4853 IntExpr*
const opp_num_;
4856 class DivPosPosIntExpr :
public BaseIntExpr {
4858 DivPosPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4859 : BaseIntExpr(s), num_(num), denom_(denom) {}
4861 ~DivPosPosIntExpr()
override {}
4863 int64_t Min()
const override {
4864 if (denom_->Max() == 0) {
4867 return num_->Min() / denom_->Max();
4870 int64_t Max()
const override {
4871 if (denom_->Min() == 0) {
4874 return num_->Max() / denom_->Min();
4878 void SetMin(int64_t m)
override {
4880 num_->SetMin(m * denom_->Min());
4881 denom_->SetMax(num_->Max() / m);
4885 void SetMax(int64_t m)
override {
4887 num_->SetMax((m + 1) * denom_->Max() - 1);
4888 denom_->SetMin(num_->Min() / (m + 1) + 1);
4894 std::string
name()
const override {
4895 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
4898 std::string DebugString()
const override {
4899 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
4900 denom_->DebugString());
4903 void WhenRange(Demon* d)
override {
4905 denom_->WhenRange(d);
4908 void Accept(ModelVisitor*
const visitor)
const override {
4909 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4910 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4911 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4913 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4917 IntExpr*
const num_;
4918 IntExpr*
const denom_;
4923 class DivIntExpr :
public BaseIntExpr {
4925 DivIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4929 opp_num_(s->MakeOpposite(num)) {}
4931 ~DivIntExpr()
override {}
4933 int64_t Min()
const override {
4934 const int64_t num_min = num_->Min();
4935 const int64_t num_max = num_->Max();
4936 const int64_t denom_min = denom_->Min();
4937 const int64_t denom_max = denom_->Max();
4939 if (denom_min == 0 && denom_max == 0) {
4944 if (denom_min >= 0) {
4945 DCHECK_GT(denom_max, 0);
4946 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4947 return num_min >= 0 ? num_min / denom_max : num_min / adjusted_denom_min;
4948 }
else if (denom_max <= 0) {
4949 DCHECK_LT(denom_min, 0);
4950 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4951 return num_max >= 0 ? num_max / adjusted_denom_max : num_max / denom_min;
4953 return std::min(num_min, -num_max);
4957 int64_t Max()
const override {
4958 const int64_t num_min = num_->Min();
4959 const int64_t num_max = num_->Max();
4960 const int64_t denom_min = denom_->Min();
4961 const int64_t denom_max = denom_->Max();
4963 if (denom_min == 0 && denom_max == 0) {
4968 if (denom_min >= 0) {
4969 DCHECK_GT(denom_max, 0);
4970 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4971 return num_max >= 0 ? num_max / adjusted_denom_min : num_max / denom_max;
4972 }
else if (denom_max <= 0) {
4973 DCHECK_LT(denom_min, 0);
4974 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4975 return num_min >= 0 ? num_min / denom_min
4976 : -num_min / -adjusted_denom_max;
4978 return std::max(num_max, -num_min);
4982 void AdjustDenominator() {
4983 if (denom_->Min() == 0) {
4985 }
else if (denom_->Max() == 0) {
4991 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4993 const int64_t num_min = num->Min();
4994 const int64_t num_max = num->Max();
4995 const int64_t denom_min = denom->Min();
4996 const int64_t denom_max = denom->Max();
4997 DCHECK_NE(denom_min, 0);
4998 DCHECK_NE(denom_max, 0);
4999 if (denom_min > 0) {
5000 num->SetMin(m * denom_min);
5001 denom->SetMax(num_max / m);
5002 }
else if (denom_max < 0) {
5003 num->SetMax(m * denom_max);
5004 denom->SetMin(num_min / m);
5008 denom->SetRange(1, num_max / m);
5009 }
else if (num_max <= 0) {
5011 denom->SetRange(num_min / m, -1);
5015 denom->SetRange(1, num_max / m);
5016 }
else if (m > num_max) {
5018 denom->SetRange(num_min / m, -1);
5020 denom->SetRange(num_min / m, num_max / m);
5027 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
5029 const int64_t num_min = num->Min();
5030 const int64_t num_max = num->Max();
5031 const int64_t denom_min = denom->Min();
5032 const int64_t denom_max = denom->Max();
5033 DCHECK_NE(denom_min, 0);
5034 DCHECK_NE(denom_max, 0);
5035 if (denom_min > 0) {
5036 num->SetMax((m + 1) * denom_max - 1);
5037 denom->SetMin((num_min / (m + 1)) + 1);
5038 }
else if (denom_max < 0) {
5039 num->SetMin((m + 1) * denom_min + 1);
5040 denom->SetMax(num_max / (m + 1) - 1);
5041 }
else if (num_min > (m + 1) * denom_max - 1) {
5043 }
else if (num_max < (m + 1) * denom_min + 1) {
5048 void SetMin(int64_t m)
override {
5049 AdjustDenominator();
5051 SetPosMin(num_, denom_, m);
5053 SetPosMax(opp_num_, denom_, -m);
5057 void SetMax(int64_t m)
override {
5058 AdjustDenominator();
5060 SetPosMax(num_, denom_, m);
5062 SetPosMin(opp_num_, denom_, -m);
5066 std::string
name()
const override {
5067 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
5069 std::string DebugString()
const override {
5070 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
5071 denom_->DebugString());
5073 void WhenRange(Demon* d)
override {
5075 denom_->WhenRange(d);
5078 void Accept(ModelVisitor*
const visitor)
const override {
5079 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
5080 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
5081 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5083 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
5087 IntExpr*
const num_;
5088 IntExpr*
const denom_;
5089 IntExpr*
const opp_num_;
5094 class IntAbsConstraint :
public CastConstraint {
5096 IntAbsConstraint(Solver*
const s, IntVar*
const sub, IntVar*
const target)
5097 : CastConstraint(s, target), sub_(sub) {}
5099 ~IntAbsConstraint()
override {}
5101 void Post()
override {
5103 solver(),
this, &IntAbsConstraint::PropagateSub,
"PropagateSub");
5104 sub_->WhenRange(sub_demon);
5106 solver(),
this, &IntAbsConstraint::PropagateTarget,
"PropagateTarget");
5110 void InitialPropagate()
override {
5115 void PropagateSub() {
5116 const int64_t smin = sub_->Min();
5117 const int64_t smax = sub_->Max();
5120 }
else if (smin >= 0) {
5127 void PropagateTarget() {
5129 sub_->SetRange(-target_max, target_max);
5131 if (target_min > 0) {
5132 if (sub_->Min() > -target_min) {
5133 sub_->SetMin(target_min);
5134 }
else if (sub_->Max() < target_min) {
5135 sub_->SetMax(-target_min);
5140 std::string DebugString()
const override {
5141 return absl::StrFormat(
"IntAbsConstraint(%s, %s)", sub_->DebugString(),
5145 void Accept(ModelVisitor*
const visitor)
const override {
5146 visitor->BeginVisitConstraint(ModelVisitor::kAbsEqual,
this);
5147 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5149 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
5151 visitor->EndVisitConstraint(ModelVisitor::kAbsEqual,
this);
5158 class IntAbs :
public BaseIntExpr {
5160 IntAbs(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
5162 ~IntAbs()
override {}
5164 int64_t Min()
const override {
5167 expr_->Range(&emin, &emax);
5177 void SetMin(int64_t m)
override {
5181 expr_->Range(&emin, &emax);
5184 }
else if (emax < m) {
5190 int64_t Max()
const override {
5193 expr_->Range(&emin, &emax);
5197 void SetMax(int64_t m)
override {
expr_->SetRange(-m, m); }
5199 void SetRange(int64_t mi, int64_t ma)
override {
5200 expr_->SetRange(-ma, ma);
5204 expr_->Range(&emin, &emax);
5207 }
else if (emax < mi) {
5213 void Range(int64_t* mi, int64_t* ma)
override {
5216 expr_->Range(&emin, &emax);
5220 }
else if (emax <= 0) {
5229 bool Bound()
const override {
return expr_->Bound(); }
5231 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5233 std::string
name()
const override {
5234 return absl::StrFormat(
"IntAbs(%s)",
expr_->name());
5237 std::string DebugString()
const override {
5238 return absl::StrFormat(
"IntAbs(%s)",
expr_->DebugString());
5241 void Accept(ModelVisitor*
const visitor)
const override {
5242 visitor->BeginVisitIntegerExpression(ModelVisitor::kAbs,
this);
5243 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5245 visitor->EndVisitIntegerExpression(ModelVisitor::kAbs,
this);
5248 IntVar* CastToVar()
override {
5249 int64_t min_value = 0;
5250 int64_t max_value = 0;
5251 Range(&min_value, &max_value);
5252 Solver*
const s = solver();
5253 const std::string
name = absl::StrFormat(
"AbsVar(%s)",
expr_->name());
5254 IntVar*
const target = s->MakeIntVar(min_value, max_value,
name);
5255 CastConstraint*
const ct =
5256 s->RevAlloc(
new IntAbsConstraint(s,
expr_->Var(), target));
5257 s->AddCastConstraint(
ct, target,
this);
5262 IntExpr*
const expr_;
5268 class IntSquare :
public BaseIntExpr {
5270 IntSquare(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
5271 ~IntSquare()
override {}
5273 int64_t Min()
const override {
5274 const int64_t emin =
expr_->Min();
5280 const int64_t emax =
expr_->Max();
5288 void SetMin(int64_t m)
override {
5293 const int64_t emin =
expr_->Min();
5294 const int64_t emax =
expr_->Max();
5295 const int64_t root =
5296 static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5298 expr_->SetMin(root);
5299 }
else if (emax <= 0) {
5300 expr_->SetMax(-root);
5301 }
else if (
expr_->IsVar()) {
5302 reinterpret_cast<IntVar*
>(
expr_)->RemoveInterval(-root + 1, root - 1);
5305 int64_t Max()
const override {
5306 const int64_t emax =
expr_->Max();
5307 const int64_t emin =
expr_->Min();
5312 return std::max(emin * emin, emax * emax);
5314 void SetMax(int64_t m)
override {
5321 const int64_t root =
5322 static_cast<int64_t
>(floor(sqrt(
static_cast<double>(m))));
5323 expr_->SetRange(-root, root);
5325 bool Bound()
const override {
return expr_->Bound(); }
5326 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5327 std::string
name()
const override {
5328 return absl::StrFormat(
"IntSquare(%s)",
expr_->name());
5330 std::string DebugString()
const override {
5331 return absl::StrFormat(
"IntSquare(%s)",
expr_->DebugString());
5334 void Accept(ModelVisitor*
const visitor)
const override {
5335 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare,
this);
5336 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5338 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare,
this);
5341 IntExpr* expr()
const {
return expr_; }
5344 IntExpr*
const expr_;
5347 class PosIntSquare :
public IntSquare {
5349 PosIntSquare(Solver*
const s, IntExpr*
const e) : IntSquare(s, e) {}
5350 ~PosIntSquare()
override {}
5352 int64_t Min()
const override {
5353 const int64_t emin =
expr_->Min();
5358 void SetMin(int64_t m)
override {
5362 const int64_t root =
5363 static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5364 expr_->SetMin(root);
5366 int64_t Max()
const override {
5367 const int64_t emax =
expr_->Max();
5372 void SetMax(int64_t m)
override {
5379 const int64_t root =
5380 static_cast<int64_t
>(floor(sqrt(
static_cast<double>(m))));
5381 expr_->SetMax(root);
5387 int64_t IntPower(int64_t
value, int64_t power) {
5388 int64_t result =
value;
5390 for (
int i = 1; i < power; ++i) {
5396 int64_t OverflowLimit(int64_t power) {
5397 return static_cast<int64_t
>(floor(exp(
5401 class BasePower :
public BaseIntExpr {
5403 BasePower(Solver*
const s, IntExpr*
const e, int64_t n)
5408 ~BasePower()
override {}
5410 bool Bound()
const override {
return expr_->Bound(); }
5412 IntExpr* expr()
const {
return expr_; }
5414 int64_t exponant()
const {
return pow_; }
5416 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5418 std::string
name()
const override {
5419 return absl::StrFormat(
"IntPower(%s, %d)",
expr_->name(),
pow_);
5422 std::string DebugString()
const override {
5423 return absl::StrFormat(
"IntPower(%s, %d)",
expr_->DebugString(),
pow_);
5426 void Accept(ModelVisitor*
const visitor)
const override {
5427 visitor->BeginVisitIntegerExpression(ModelVisitor::kPower,
this);
5428 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5430 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
pow_);
5431 visitor->EndVisitIntegerExpression(ModelVisitor::kPower,
this);
5435 int64_t Pown(int64_t
value)
const {
5440 if (
pow_ % 2 == 0) {
5449 int64_t SqrnDown(int64_t
value)
const {
5457 const double d_value =
static_cast<double>(
value);
5459 const double sq = exp(log(d_value) /
pow_);
5460 res =
static_cast<int64_t
>(floor(sq));
5462 CHECK_EQ(1,
pow_ % 2);
5463 const double sq = exp(log(-d_value) /
pow_);
5464 res = -
static_cast<int64_t
>(ceil(sq));
5466 const int64_t pow_res = Pown(res + 1);
5467 if (pow_res <=
value) {
5474 int64_t SqrnUp(int64_t
value)
const {
5482 const double d_value =
static_cast<double>(
value);
5484 const double sq = exp(log(d_value) /
pow_);
5485 res =
static_cast<int64_t
>(ceil(sq));
5487 CHECK_EQ(1,
pow_ % 2);
5488 const double sq = exp(log(-d_value) /
pow_);
5489 res = -
static_cast<int64_t
>(floor(sq));
5491 const int64_t pow_res = Pown(res - 1);
5492 if (pow_res >=
value) {
5499 IntExpr*
const expr_;
5504 class IntEvenPower :
public BasePower {
5506 IntEvenPower(Solver*
const s, IntExpr*
const e, int64_t n)
5507 : BasePower(s, e, n) {
5511 ~IntEvenPower()
override {}
5513 int64_t Min()
const override {
5516 expr_->Range(&emin, &emax);
5525 void SetMin(int64_t m)
override {
5531 expr_->Range(&emin, &emax);
5532 const int64_t root = SqrnUp(m);
5534 expr_->SetMin(root);
5535 }
else if (emax < root) {
5536 expr_->SetMax(-root);
5537 }
else if (
expr_->IsVar()) {
5538 reinterpret_cast<IntVar*
>(
expr_)->RemoveInterval(-root + 1, root - 1);
5542 int64_t Max()
const override {
5546 void SetMax(int64_t m)
override {
5553 const int64_t root = SqrnDown(m);
5554 expr_->SetRange(-root, root);
5558 class PosIntEvenPower :
public BasePower {
5560 PosIntEvenPower(Solver*
const s, IntExpr*
const e, int64_t pow)
5561 : BasePower(s, e, pow) {
5562 CHECK_EQ(0, pow % 2);
5565 ~PosIntEvenPower()
override {}
5567 int64_t Min()
const override {
return Pown(
expr_->Min()); }
5569 void SetMin(int64_t m)
override {
5573 expr_->SetMin(SqrnUp(m));
5575 int64_t Max()
const override {
return Pown(
expr_->Max()); }
5577 void SetMax(int64_t m)
override {
5584 expr_->SetMax(SqrnDown(m));
5588 class IntOddPower :
public BasePower {
5590 IntOddPower(Solver*
const s, IntExpr*
const e, int64_t n)
5591 : BasePower(s, e, n) {
5595 ~IntOddPower()
override {}
5597 int64_t Min()
const override {
return Pown(
expr_->Min()); }
5599 void SetMin(int64_t m)
override {
expr_->SetMin(SqrnUp(m)); }
5601 int64_t Max()
const override {
return Pown(
expr_->Max()); }
5603 void SetMax(int64_t m)
override {
expr_->SetMax(SqrnDown(m)); }
5608 class MinIntExpr :
public BaseIntExpr {
5610 MinIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5611 : BaseIntExpr(s), left_(l), right_(r) {}
5612 ~MinIntExpr()
override {}
5613 int64_t Min()
const override {
5614 const int64_t lmin = left_->Min();
5615 const int64_t rmin = right_->Min();
5618 void SetMin(int64_t m)
override {
5622 int64_t Max()
const override {
5623 const int64_t lmax = left_->Max();
5624 const int64_t rmax = right_->Max();
5627 void SetMax(int64_t m)
override {
5628 if (left_->Min() > m) {
5631 if (right_->Min() > m) {
5635 std::string
name()
const override {
5636 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->name(), right_->name());
5638 std::string DebugString()
const override {
5639 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->DebugString(),
5640 right_->DebugString());
5642 void WhenRange(Demon* d)
override {
5643 left_->WhenRange(d);
5644 right_->WhenRange(d);
5647 void Accept(ModelVisitor*
const visitor)
const override {
5648 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5649 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5650 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5652 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5656 IntExpr*
const left_;
5657 IntExpr*
const right_;
5662 class MinCstIntExpr :
public BaseIntExpr {
5664 MinCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5665 : BaseIntExpr(s),
expr_(e), value_(v) {}
5667 ~MinCstIntExpr()
override {}
5669 int64_t Min()
const override {
return std::min(
expr_->Min(), value_); }
5671 void SetMin(int64_t m)
override {
5678 int64_t Max()
const override {
return std::min(
expr_->Max(), value_); }
5680 void SetMax(int64_t m)
override {
5686 bool Bound()
const override {
5687 return (
expr_->Bound() ||
expr_->Min() >= value_);
5690 std::string
name()
const override {
5691 return absl::StrFormat(
"MinCstIntExpr(%s, %d)",
expr_->name(), value_);
5694 std::string DebugString()
const override {
5695 return absl::StrFormat(
"MinCstIntExpr(%s, %d)",
expr_->DebugString(),
5699 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5701 void Accept(ModelVisitor*
const visitor)
const override {
5702 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5703 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5705 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5706 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5710 IntExpr*
const expr_;
5711 const int64_t value_;
5716 class MaxIntExpr :
public BaseIntExpr {
5718 MaxIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5719 : BaseIntExpr(s), left_(l), right_(r) {}
5721 ~MaxIntExpr()
override {}
5723 int64_t Min()
const override {
return std::max(left_->Min(), right_->Min()); }
5725 void SetMin(int64_t m)
override {
5726 if (left_->Max() < m) {
5729 if (right_->Max() < m) {
5735 int64_t Max()
const override {
return std::max(left_->Max(), right_->Max()); }
5737 void SetMax(int64_t m)
override {
5742 std::string
name()
const override {
5743 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->name(), right_->name());
5746 std::string DebugString()
const override {
5747 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->DebugString(),
5748 right_->DebugString());
5751 void WhenRange(Demon* d)
override {
5752 left_->WhenRange(d);
5753 right_->WhenRange(d);
5756 void Accept(ModelVisitor*
const visitor)
const override {
5757 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5758 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5759 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5761 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5765 IntExpr*
const left_;
5766 IntExpr*
const right_;
5771 class MaxCstIntExpr :
public BaseIntExpr {
5773 MaxCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5774 : BaseIntExpr(s),
expr_(e), value_(v) {}
5776 ~MaxCstIntExpr()
override {}
5778 int64_t Min()
const override {
return std::max(
expr_->Min(), value_); }
5780 void SetMin(int64_t m)
override {
5786 int64_t Max()
const override {
return std::max(
expr_->Max(), value_); }
5788 void SetMax(int64_t m)
override {
5795 bool Bound()
const override {
5796 return (
expr_->Bound() ||
expr_->Max() <= value_);
5799 std::string
name()
const override {
5800 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)",
expr_->name(), value_);
5803 std::string DebugString()
const override {
5804 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)",
expr_->DebugString(),
5808 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5810 void Accept(ModelVisitor*
const visitor)
const override {
5811 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5812 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5814 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5815 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5819 IntExpr*
const expr_;
5820 const int64_t value_;
5831 class SimpleConvexPiecewiseExpr :
public BaseIntExpr {
5833 SimpleConvexPiecewiseExpr(Solver*
const s, IntExpr*
const e, int64_t ec,
5834 int64_t ed, int64_t ld, int64_t lc)
5838 early_date_(ec == 0 ? std::numeric_limits<int64_t>::
min() : ed),
5839 late_date_(lc == 0 ? std::numeric_limits<int64_t>::
max() : ld),
5841 DCHECK_GE(ec, int64_t{0});
5842 DCHECK_GE(lc, int64_t{0});
5849 ~SimpleConvexPiecewiseExpr()
override {}
5851 int64_t Min()
const override {
5852 const int64_t vmin =
expr_->Min();
5853 const int64_t vmax =
expr_->Max();
5854 if (vmin >= late_date_) {
5855 return (vmin - late_date_) * late_cost_;
5856 }
else if (vmax <= early_date_) {
5857 return (early_date_ - vmax) * early_cost_;
5863 void SetMin(int64_t m)
override {
5869 expr_->Range(&vmin, &vmax);
5872 (late_cost_ == 0 ? vmax : late_date_ +
PosIntDivUp(m, late_cost_) - 1);
5874 (early_cost_ == 0 ? vmin
5877 if (
expr_->IsVar()) {
5878 expr_->Var()->RemoveInterval(lb, rb);
5882 int64_t Max()
const override {
5883 const int64_t vmin =
expr_->Min();
5884 const int64_t vmax =
expr_->Max();
5885 const int64_t mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0;
5887 vmin < early_date_ ? (early_date_ - vmin) * early_cost_ : 0;
5891 void SetMax(int64_t m)
override {
5895 if (late_cost_ != 0LL) {
5896 const int64_t rb = late_date_ +
PosIntDivDown(m, late_cost_);
5897 if (early_cost_ != 0LL) {
5898 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5899 expr_->SetRange(lb, rb);
5904 if (early_cost_ != 0LL) {
5905 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5911 std::string
name()
const override {
5912 return absl::StrFormat(
5913 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5914 expr_->name(), early_cost_, early_date_, late_date_, late_cost_);
5917 std::string DebugString()
const override {
5918 return absl::StrFormat(
5919 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5920 expr_->DebugString(), early_cost_, early_date_, late_date_, late_cost_);
5923 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5925 void Accept(ModelVisitor*
const visitor)
const override {
5926 visitor->BeginVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5927 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5929 visitor->VisitIntegerArgument(ModelVisitor::kEarlyCostArgument,
5931 visitor->VisitIntegerArgument(ModelVisitor::kEarlyDateArgument,
5933 visitor->VisitIntegerArgument(ModelVisitor::kLateCostArgument, late_cost_);
5934 visitor->VisitIntegerArgument(ModelVisitor::kLateDateArgument, late_date_);
5935 visitor->EndVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5939 IntExpr*
const expr_;
5940 const int64_t early_cost_;
5941 const int64_t early_date_;
5942 const int64_t late_date_;
5943 const int64_t late_cost_;
5948 class SemiContinuousExpr :
public BaseIntExpr {
5950 SemiContinuousExpr(Solver*
const s, IntExpr*
const e, int64_t fixed_charge,
5952 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge),
step_(step) {
5953 DCHECK_GE(fixed_charge, int64_t{0});
5954 DCHECK_GT(step, int64_t{0});
5957 ~SemiContinuousExpr()
override {}
5959 int64_t
Value(int64_t x)
const {
5967 int64_t Min()
const override {
return Value(
expr_->Min()); }
5969 void SetMin(int64_t m)
override {
5978 int64_t Max()
const override {
return Value(
expr_->Max()); }
5980 void SetMax(int64_t m)
override {
5995 std::string
name()
const override {
5996 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
6000 std::string DebugString()
const override {
6001 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
6005 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6007 void Accept(ModelVisitor*
const visitor)
const override {
6008 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6009 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6011 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6013 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument,
step_);
6014 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6018 IntExpr*
const expr_;
6019 const int64_t fixed_charge_;
6020 const int64_t
step_;
6023 class SemiContinuousStepOneExpr :
public BaseIntExpr {
6025 SemiContinuousStepOneExpr(Solver*
const s, IntExpr*
const e,
6026 int64_t fixed_charge)
6027 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge) {
6028 DCHECK_GE(fixed_charge, int64_t{0});
6031 ~SemiContinuousStepOneExpr()
override {}
6033 int64_t
Value(int64_t x)
const {
6037 return fixed_charge_ + x;
6041 int64_t Min()
const override {
return Value(
expr_->Min()); }
6043 void SetMin(int64_t m)
override {
6044 if (m >= fixed_charge_ + 1) {
6045 expr_->SetMin(m - fixed_charge_);
6051 int64_t Max()
const override {
return Value(
expr_->Max()); }
6053 void SetMax(int64_t m)
override {
6057 if (m < fixed_charge_ + 1) {
6060 expr_->SetMax(m - fixed_charge_);
6064 std::string
name()
const override {
6065 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6066 expr_->name(), fixed_charge_);
6069 std::string DebugString()
const override {
6070 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6071 expr_->DebugString(), fixed_charge_);
6074 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6076 void Accept(ModelVisitor*
const visitor)
const override {
6077 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6078 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6080 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6082 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 1);
6083 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6087 IntExpr*
const expr_;
6088 const int64_t fixed_charge_;
6091 class SemiContinuousStepZeroExpr :
public BaseIntExpr {
6093 SemiContinuousStepZeroExpr(Solver*
const s, IntExpr*
const e,
6094 int64_t fixed_charge)
6095 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge) {
6096 DCHECK_GT(fixed_charge, int64_t{0});
6099 ~SemiContinuousStepZeroExpr()
override {}
6101 int64_t
Value(int64_t x)
const {
6105 return fixed_charge_;
6109 int64_t Min()
const override {
return Value(
expr_->Min()); }
6111 void SetMin(int64_t m)
override {
6112 if (m >= fixed_charge_) {
6119 int64_t Max()
const override {
return Value(
expr_->Max()); }
6121 void SetMax(int64_t m)
override {
6125 if (m < fixed_charge_) {
6130 std::string
name()
const override {
6131 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6132 expr_->name(), fixed_charge_);
6135 std::string DebugString()
const override {
6136 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6137 expr_->DebugString(), fixed_charge_);
6140 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6142 void Accept(ModelVisitor*
const visitor)
const override {
6143 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6144 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6146 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6148 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 0);
6149 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6153 IntExpr*
const expr_;
6154 const int64_t fixed_charge_;
6158 class LinkExprAndVar :
public CastConstraint {
6160 LinkExprAndVar(Solver*
const s, IntExpr*
const expr, IntVar*
const var)
6161 : CastConstraint(s,
var),
expr_(expr) {}
6163 ~LinkExprAndVar()
override {}
6165 void Post()
override {
6166 Solver*
const s = solver();
6167 Demon* d = s->MakeConstraintInitialPropagateCallback(
this);
6168 expr_->WhenRange(d);
6172 void InitialPropagate()
override {
6175 expr_->Range(&l, &u);
6179 std::string DebugString()
const override {
6180 return absl::StrFormat(
"cast(%s, %s)",
expr_->DebugString(),
6184 void Accept(ModelVisitor*
const visitor)
const override {
6185 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6186 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6188 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6190 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6194 IntExpr*
const expr_;
6199 class ExprWithEscapeValue :
public BaseIntExpr {
6201 ExprWithEscapeValue(Solver*
const s, IntVar*
const c, IntExpr*
const e,
6202 int64_t unperformed_value)
6206 unperformed_value_(unperformed_value) {}
6208 ~ExprWithEscapeValue()
override {}
6210 int64_t Min()
const override {
6211 if (condition_->Min() == 1) {
6212 return expression_->Min();
6213 }
else if (condition_->Max() == 1) {
6214 return std::min(unperformed_value_, expression_->Min());
6216 return unperformed_value_;
6220 void SetMin(int64_t m)
override {
6221 if (m > unperformed_value_) {
6222 condition_->SetValue(1);
6223 expression_->SetMin(m);
6224 }
else if (condition_->Min() == 1) {
6225 expression_->SetMin(m);
6226 }
else if (m > expression_->Max()) {
6227 condition_->SetValue(0);
6231 int64_t Max()
const override {
6232 if (condition_->Min() == 1) {
6233 return expression_->Max();
6234 }
else if (condition_->Max() == 1) {
6235 return std::max(unperformed_value_, expression_->Max());
6237 return unperformed_value_;
6241 void SetMax(int64_t m)
override {
6242 if (m < unperformed_value_) {
6243 condition_->SetValue(1);
6244 expression_->SetMax(m);
6245 }
else if (condition_->Min() == 1) {
6246 expression_->SetMax(m);
6247 }
else if (m < expression_->Min()) {
6248 condition_->SetValue(0);
6252 void SetRange(int64_t mi, int64_t ma)
override {
6253 if (ma < unperformed_value_ || mi > unperformed_value_) {
6254 condition_->SetValue(1);
6255 expression_->SetRange(mi, ma);
6256 }
else if (condition_->Min() == 1) {
6257 expression_->SetRange(mi, ma);
6258 }
else if (ma < expression_->Min() || mi > expression_->Max()) {
6259 condition_->SetValue(0);
6263 void SetValue(int64_t v)
override {
6264 if (v != unperformed_value_) {
6265 condition_->SetValue(1);
6266 expression_->SetValue(v);
6267 }
else if (condition_->Min() == 1) {
6268 expression_->SetValue(v);
6269 }
else if (v < expression_->Min() || v > expression_->Max()) {
6270 condition_->SetValue(0);
6274 bool Bound()
const override {
6275 return condition_->Max() == 0 || expression_->Bound();
6278 void WhenRange(Demon* d)
override {
6279 expression_->WhenRange(d);
6280 condition_->WhenBound(d);
6283 std::string DebugString()
const override {
6284 return absl::StrFormat(
"ConditionExpr(%s, %s, %d)",
6285 condition_->DebugString(),
6286 expression_->DebugString(), unperformed_value_);
6289 void Accept(ModelVisitor*
const visitor)
const override {
6290 visitor->BeginVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6291 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
6293 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6295 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
6296 unperformed_value_);
6297 visitor->EndVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6301 IntVar*
const condition_;
6302 IntExpr*
const expression_;
6303 const int64_t unperformed_value_;
6308 class LinkExprAndDomainIntVar :
public CastConstraint {
6310 LinkExprAndDomainIntVar(Solver*
const s, IntExpr*
const expr,
6311 DomainIntVar*
const var)
6312 : CastConstraint(s,
var),
6314 cached_min_(std::numeric_limits<int64_t>::
min()),
6315 cached_max_(std::numeric_limits<int64_t>::
max()),
6316 fail_stamp_(uint64_t{0}) {}
6318 ~LinkExprAndDomainIntVar()
override {}
6320 DomainIntVar*
var()
const {
6321 return reinterpret_cast<DomainIntVar*
>(
target_var_);
6324 void Post()
override {
6325 Solver*
const s = solver();
6326 Demon*
const d = s->MakeConstraintInitialPropagateCallback(
this);
6327 expr_->WhenRange(d);
6329 solver(),
this, &LinkExprAndDomainIntVar::Propagate,
"Propagate");
6333 void InitialPropagate()
override {
6334 expr_->SetRange(
var()->min_.Value(),
var()->max_.Value());
6335 expr_->Range(&cached_min_, &cached_max_);
6336 var()->DomainIntVar::SetRange(cached_min_, cached_max_);
6340 if (
var()->min_.Value() > cached_min_ ||
6341 var()->max_.Value() < cached_max_ ||
6342 solver()->fail_stamp() != fail_stamp_) {
6344 fail_stamp_ = solver()->fail_stamp();
6348 std::string DebugString()
const override {
6349 return absl::StrFormat(
"cast(%s, %s)",
expr_->DebugString(),
6353 void Accept(ModelVisitor*
const visitor)
const override {
6354 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6355 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6357 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6359 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6363 IntExpr*
const expr_;
6364 int64_t cached_min_;
6365 int64_t cached_max_;
6366 uint64_t fail_stamp_;
6373 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
6376 return CondRevAlloc(solver(), reversible,
new RangeIterator(
this));
6383 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6384 dvar->CleanInProcess();
6388 const std::vector<IntVar*>& vars) {
6389 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6390 CHECK(dvar !=
nullptr);
6391 return dvar->SetIsEqual(values, vars);
6395 const std::vector<int64_t>& values,
6396 const std::vector<IntVar*>& vars) {
6397 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6398 CHECK(dvar !=
nullptr);
6399 return dvar->SetIsGreaterOrEqual(values, vars);
6412 return MakeIntConst(
min,
name);
6414 if (
min == 0 &&
max == 1) {
6415 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
name)));
6417 const std::string inner_name =
"inner_" +
name;
6418 return RegisterIntVar(
6419 MakeSum(RevAlloc(
new ConcreteBooleanVar(
this, inner_name)),
min)
6420 ->VarWithName(
name));
6422 return RegisterIntVar(RevAlloc(
new DomainIntVar(
this,
min,
max,
name)));
6427 return MakeIntVar(
min,
max,
"");
6431 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
name)));
6435 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
"")));
6438 IntVar* Solver::MakeIntVar(
const std::vector<int64_t>& values,
6439 const std::string&
name) {
6440 DCHECK(!values.empty());
6442 if (values.size() == 1)
return MakeIntConst(values[0],
name);
6444 std::vector<int64_t> unique_sorted_values = values;
6447 if (unique_sorted_values.size() == 1)
return MakeIntConst(values[0],
name);
6449 if (unique_sorted_values.size() ==
6450 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6451 return MakeIntVar(unique_sorted_values.front(), unique_sorted_values.back(),
6457 for (
const int64_t v : unique_sorted_values) {
6461 gcd = MathUtil::GCD64(gcd, std::abs(v));
6466 return RegisterIntVar(
6467 RevAlloc(
new DomainIntVar(
this, unique_sorted_values,
name)));
6471 for (int64_t& v : unique_sorted_values) {
6472 DCHECK_EQ(0, v % gcd);
6475 const std::string new_name =
name.empty() ?
"" :
"inner_" +
name;
6477 IntVar* inner_intvar =
nullptr;
6478 if (unique_sorted_values.size() ==
6479 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6480 inner_intvar = MakeIntVar(unique_sorted_values.front(),
6481 unique_sorted_values.back(), new_name);
6483 inner_intvar = RegisterIntVar(
6484 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, new_name)));
6486 return MakeProd(inner_intvar, gcd)->Var();
6489 IntVar* Solver::MakeIntVar(
const std::vector<int64_t>& values) {
6490 return MakeIntVar(values,
"");
6493 IntVar* Solver::MakeIntVar(
const std::vector<int>& values,
6494 const std::string&
name) {
6498 IntVar* Solver::MakeIntVar(
const std::vector<int>& values) {
6499 return MakeIntVar(values,
"");
6502 IntVar* Solver::MakeIntConst(int64_t val,
const std::string&
name) {
6506 if (absl::GetFlag(FLAGS_cp_share_int_consts) &&
name.empty() &&
6507 val >= MIN_CACHED_INT_CONST && val <= MAX_CACHED_INT_CONST) {
6508 return cached_constants_[val - MIN_CACHED_INT_CONST];
6510 return RevAlloc(
new IntConst(
this, val,
name));
6513 IntVar* Solver::MakeIntConst(int64_t val) {
return MakeIntConst(val,
""); }
6518 std::string IndexedName(
const std::string& prefix,
int index,
int max_index) {
6520 #if defined(_MSC_VER)
6521 const int digits = max_index > 0 ?
6522 static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
6525 const int digits = max_index > 0 ?
static_cast<int>(log10(max_index)) + 1: 1;
6527 return absl::StrFormat(
"%s%0*d", prefix, digits,
index);
6529 return absl::StrCat(prefix,
index);
6534 void Solver::MakeIntVarArray(
int var_count, int64_t vmin, int64_t vmax,
6535 const std::string&
name,
6536 std::vector<IntVar*>* vars) {
6537 for (
int i = 0; i < var_count; ++i) {
6538 vars->push_back(MakeIntVar(vmin, vmax, IndexedName(
name, i, var_count)));
6542 void Solver::MakeIntVarArray(
int var_count, int64_t vmin, int64_t vmax,
6543 std::vector<IntVar*>* vars) {
6544 for (
int i = 0; i < var_count; ++i) {
6545 vars->push_back(MakeIntVar(vmin, vmax));
6549 IntVar** Solver::MakeIntVarArray(
int var_count, int64_t vmin, int64_t vmax,
6550 const std::string&
name) {
6552 for (
int i = 0; i < var_count; ++i) {
6553 vars[i] = MakeIntVar(vmin, vmax, IndexedName(
name, i, var_count));
6558 void Solver::MakeBoolVarArray(
int var_count,
const std::string&
name,
6559 std::vector<IntVar*>* vars) {
6560 for (
int i = 0; i < var_count; ++i) {
6561 vars->push_back(MakeBoolVar(IndexedName(
name, i, var_count)));
6565 void Solver::MakeBoolVarArray(
int var_count, std::vector<IntVar*>* vars) {
6566 for (
int i = 0; i < var_count; ++i) {
6567 vars->push_back(MakeBoolVar());
6571 IntVar** Solver::MakeBoolVarArray(
int var_count,
const std::string&
name) {
6573 for (
int i = 0; i < var_count; ++i) {
6574 vars[i] = MakeBoolVar(IndexedName(
name, i, var_count));
6579 void Solver::InitCachedIntConstants() {
6580 for (
int i = MIN_CACHED_INT_CONST; i <= MAX_CACHED_INT_CONST; ++i) {
6581 cached_constants_[i - MIN_CACHED_INT_CONST] =
6582 RevAlloc(
new IntConst(
this, i,
""));
6587 CHECK_EQ(
this, left->
solver());
6588 CHECK_EQ(
this, right->
solver());
6589 if (right->
Bound()) {
6590 return MakeSum(left, right->
Min());
6592 if (left->
Bound()) {
6593 return MakeSum(right, left->
Min());
6595 if (left == right) {
6596 return MakeProd(left, 2);
6598 IntExpr* cache = model_cache_->FindExprExprExpression(
6599 left, right, ModelCache::EXPR_EXPR_SUM);
6600 if (cache ==
nullptr) {
6601 cache = model_cache_->FindExprExprExpression(right, left,
6602 ModelCache::EXPR_EXPR_SUM);
6604 if (cache !=
nullptr) {
6610 ? RegisterIntExpr(RevAlloc(
new SafePlusIntExpr(
this, left, right)))
6611 : RegisterIntExpr(RevAlloc(
new PlusIntExpr(
this, left, right)));
6612 model_cache_->InsertExprExprExpression(result, left, right,
6613 ModelCache::EXPR_EXPR_SUM);
6619 CHECK_EQ(
this, expr->
solver());
6620 if (expr->
Bound()) {
6626 IntExpr* result = Cache()->FindExprConstantExpression(
6627 expr,
value, ModelCache::EXPR_CONSTANT_SUM);
6628 if (result ==
nullptr) {
6632 switch (
var->VarType()) {
6634 result = RegisterIntExpr(RevAlloc(
new PlusCstDomainIntVar(
6635 this,
reinterpret_cast<DomainIntVar*
>(
var),
value)));
6639 result = RegisterIntExpr(MakeIntConst(
var->Min() +
value));
6643 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(
var);
6644 IntVar*
const sub_var = add_var->SubVar();
6645 const int64_t new_constant =
value + add_var->Constant();
6646 if (new_constant == 0) {
6650 DomainIntVar*
const dvar =
6651 reinterpret_cast<DomainIntVar*
>(sub_var);
6652 result = RegisterIntExpr(
6653 RevAlloc(
new PlusCstDomainIntVar(
this, dvar, new_constant)));
6655 result = RegisterIntExpr(
6656 RevAlloc(
new PlusCstIntVar(
this, sub_var, new_constant)));
6662 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(
var);
6663 IntVar*
const sub_var = add_var->SubVar();
6664 const int64_t new_constant =
value + add_var->Constant();
6665 result = RegisterIntExpr(
6666 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6670 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(
var);
6671 IntVar*
const sub_var = add_var->SubVar();
6673 RegisterIntExpr(RevAlloc(
new SubCstIntVar(
this, sub_var,
value)));
6678 RegisterIntExpr(RevAlloc(
new PlusCstIntVar(
this,
var,
value)));
6681 result = RegisterIntExpr(RevAlloc(
new PlusIntCstExpr(
this, expr,
value)));
6683 Cache()->InsertExprConstantExpression(result, expr,
value,
6684 ModelCache::EXPR_CONSTANT_SUM);
6690 CHECK_EQ(
this, left->
solver());
6691 CHECK_EQ(
this, right->
solver());
6692 if (left->
Bound()) {
6693 return MakeDifference(left->
Min(), right);
6695 if (right->
Bound()) {
6696 return MakeSum(left, -right->
Min());
6700 int64_t left_coef = 1;
6701 int64_t right_coef = 1;
6702 if (IsProduct(left, &sub_left, &left_coef) &&
6703 IsProduct(right, &sub_right, &right_coef)) {
6704 const int64_t abs_gcd =
6705 MathUtil::GCD64(std::abs(left_coef), std::abs(right_coef));
6706 if (abs_gcd != 0 && abs_gcd != 1) {
6707 return MakeProd(MakeDifference(MakeProd(sub_left, left_coef / abs_gcd),
6708 MakeProd(sub_right, right_coef / abs_gcd)),
6713 IntExpr* result = Cache()->FindExprExprExpression(
6714 left, right, ModelCache::EXPR_EXPR_DIFFERENCE);
6715 if (result ==
nullptr) {
6718 result = RegisterIntExpr(RevAlloc(
new SubIntExpr(
this, left, right)));
6720 result = RegisterIntExpr(RevAlloc(
new SafeSubIntExpr(
this, left, right)));
6722 Cache()->InsertExprExprExpression(result, left, right,
6723 ModelCache::EXPR_EXPR_DIFFERENCE);
6730 CHECK_EQ(
this, expr->
solver());
6731 if (expr->
Bound()) {
6732 return MakeIntConst(
value - expr->
Min());
6735 return MakeOpposite(expr);
6737 IntExpr* result = Cache()->FindExprConstantExpression(
6738 expr,
value, ModelCache::EXPR_CONSTANT_DIFFERENCE);
6739 if (result ==
nullptr) {
6744 switch (
var->VarType()) {
6746 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(
var);
6747 IntVar*
const sub_var = add_var->SubVar();
6748 const int64_t new_constant =
value - add_var->Constant();
6749 if (new_constant == 0) {
6752 result = RegisterIntExpr(
6753 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6758 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(
var);
6759 IntVar*
const sub_var = add_var->SubVar();
6760 const int64_t new_constant =
value - add_var->Constant();
6761 result = MakeSum(sub_var, new_constant);
6765 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(
var);
6766 IntVar*
const sub_var = add_var->SubVar();
6767 result = MakeSum(sub_var,
value);
6772 RegisterIntExpr(RevAlloc(
new SubCstIntVar(
this,
var,
value)));
6775 result = RegisterIntExpr(RevAlloc(
new SubIntCstExpr(
this, expr,
value)));
6777 Cache()->InsertExprConstantExpression(result, expr,
value,
6778 ModelCache::EXPR_CONSTANT_DIFFERENCE);
6784 CHECK_EQ(
this, expr->
solver());
6785 if (expr->
Bound()) {
6786 return MakeIntConst(-expr->
Min());
6789 Cache()->FindExprExpression(expr, ModelCache::EXPR_OPPOSITE);
6790 if (result ==
nullptr) {
6791 if (expr->
IsVar()) {
6792 result = RegisterIntVar(RevAlloc(
new OppIntExpr(
this, expr))->Var());
6794 result = RegisterIntExpr(RevAlloc(
new OppIntExpr(
this, expr)));
6796 Cache()->InsertExprExpression(result, expr, ModelCache::EXPR_OPPOSITE);
6802 CHECK_EQ(
this, expr->
solver());
6803 IntExpr* result = Cache()->FindExprConstantExpression(
6804 expr,
value, ModelCache::EXPR_CONSTANT_PROD);
6805 if (result !=
nullptr) {
6816 if (m_expr->
Bound()) {
6821 return MakeOpposite(m_expr);
6825 result = RegisterIntExpr(
6826 RevAlloc(
new SafeTimesPosIntCstExpr(
this, m_expr,
coefficient)));
6828 result = RegisterIntExpr(
6829 RevAlloc(
new TimesPosIntCstExpr(
this, m_expr,
coefficient)));
6832 result = MakeIntConst(0);
6834 result = RegisterIntExpr(
6835 RevAlloc(
new TimesIntNegCstExpr(
this, m_expr,
coefficient)));
6837 if (m_expr->
IsVar() &&
6838 !absl::GetFlag(FLAGS_cp_disable_expression_optimization)) {
6839 result = result->
Var();
6841 Cache()->InsertExprConstantExpression(result, expr,
value,
6842 ModelCache::EXPR_CONSTANT_PROD);
6848 void ExtractPower(
IntExpr**
const expr, int64_t*
const exponant) {
6849 if (
dynamic_cast<BasePower*
>(*expr) !=
nullptr) {
6850 BasePower*
const power =
dynamic_cast<BasePower*
>(*expr);
6851 *expr = power->expr();
6852 *exponant = power->exponant();
6854 if (
dynamic_cast<IntSquare*
>(*expr) !=
nullptr) {
6855 IntSquare*
const power =
dynamic_cast<IntSquare*
>(*expr);
6856 *expr = power->expr();
6859 if ((*expr)->IsVar()) {
6860 IntVar*
const var = (*expr)->Var();
6861 IntExpr*
const sub =
var->solver()->CastExpression(
var);
6862 if (sub !=
nullptr &&
dynamic_cast<BasePower*
>(sub) !=
nullptr) {
6863 BasePower*
const power =
dynamic_cast<BasePower*
>(sub);
6864 *expr = power->expr();
6865 *exponant = power->exponant();
6867 if (sub !=
nullptr &&
dynamic_cast<IntSquare*
>(sub) !=
nullptr) {
6868 IntSquare*
const power =
dynamic_cast<IntSquare*
>(sub);
6869 *expr = power->expr();
6875 void ExtractProduct(IntExpr**
const expr, int64_t*
const coefficient,
6877 if (
dynamic_cast<TimesCstIntVar*
>(*expr) !=
nullptr) {
6878 TimesCstIntVar*
const left_prod =
dynamic_cast<TimesCstIntVar*
>(*expr);
6880 *expr = left_prod->SubVar();
6882 }
else if (
dynamic_cast<TimesIntCstExpr*
>(*expr) !=
nullptr) {
6883 TimesIntCstExpr*
const left_prod =
dynamic_cast<TimesIntCstExpr*
>(*expr);
6885 *expr = left_prod->Expr();
6892 if (left->
Bound()) {
6893 return MakeProd(right, left->
Min());
6896 if (right->
Bound()) {
6897 return MakeProd(left, right->
Min());
6904 int64_t left_exponant = 1;
6905 int64_t right_exponant = 1;
6906 ExtractPower(&m_left, &left_exponant);
6907 ExtractPower(&m_right, &right_exponant);
6909 if (m_left == m_right) {
6910 return MakePower(m_left, left_exponant + right_exponant);
6918 bool modified =
false;
6921 ExtractProduct(&m_right, &
coefficient, &modified);
6923 return MakeProd(MakeProd(m_left, m_right),
coefficient);
6928 CHECK_EQ(
this, left->
solver());
6929 CHECK_EQ(
this, right->
solver());
6930 IntExpr* result = model_cache_->FindExprExprExpression(
6931 left, right, ModelCache::EXPR_EXPR_PROD);
6932 if (result ==
nullptr) {
6933 result = model_cache_->FindExprExprExpression(right, left,
6934 ModelCache::EXPR_EXPR_PROD);
6936 if (result !=
nullptr) {
6940 if (right->
Min() >= 0) {
6941 result = RegisterIntExpr(RevAlloc(
new TimesBooleanPosIntExpr(
6942 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6944 result = RegisterIntExpr(RevAlloc(
new TimesBooleanIntExpr(
6945 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6947 }
else if (right->
IsVar() &&
6949 if (left->
Min() >= 0) {
6950 result = RegisterIntExpr(RevAlloc(
new TimesBooleanPosIntExpr(
6951 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6953 result = RegisterIntExpr(RevAlloc(
new TimesBooleanIntExpr(
6954 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6956 }
else if (left->
Min() >= 0 && right->
Min() >= 0) {
6960 RegisterIntExpr(RevAlloc(
new SafeTimesPosIntExpr(
this, left, right)));
6963 RegisterIntExpr(RevAlloc(
new TimesPosIntExpr(
this, left, right)));
6966 result = RegisterIntExpr(RevAlloc(
new TimesIntExpr(
this, left, right)));
6968 model_cache_->InsertExprExprExpression(result, left, right,
6969 ModelCache::EXPR_EXPR_PROD);
6974 CHECK(numerator !=
nullptr);
6975 CHECK(denominator !=
nullptr);
6976 if (denominator->
Bound()) {
6977 return MakeDiv(numerator, denominator->
Min());
6979 IntExpr* result = model_cache_->FindExprExprExpression(
6980 numerator, denominator, ModelCache::EXPR_EXPR_DIV);
6981 if (result !=
nullptr) {
6985 if (denominator->
Min() <= 0 && denominator->
Max() >= 0) {
6986 AddConstraint(MakeNonEquality(denominator, 0));
6989 if (denominator->
Min() >= 0) {
6990 if (numerator->
Min() >= 0) {
6991 result = RevAlloc(
new DivPosPosIntExpr(
this, numerator, denominator));
6993 result = RevAlloc(
new DivPosIntExpr(
this, numerator, denominator));
6995 }
else if (denominator->
Max() <= 0) {
6996 if (numerator->
Max() <= 0) {
6997 result = RevAlloc(
new DivPosPosIntExpr(
this, MakeOpposite(numerator),
6998 MakeOpposite(denominator)));
7000 result = MakeOpposite(RevAlloc(
7001 new DivPosIntExpr(
this, numerator, MakeOpposite(denominator))));
7004 result = RevAlloc(
new DivIntExpr(
this, numerator, denominator));
7006 model_cache_->InsertExprExprExpression(result, numerator, denominator,
7007 ModelCache::EXPR_EXPR_DIV);
7012 CHECK(expr !=
nullptr);
7013 CHECK_EQ(
this, expr->
solver());
7014 if (expr->
Bound()) {
7015 return MakeIntConst(expr->
Min() /
value);
7016 }
else if (
value == 1) {
7018 }
else if (
value == -1) {
7019 return MakeOpposite(expr);
7020 }
else if (
value > 0) {
7021 return RegisterIntExpr(RevAlloc(
new DivPosIntCstExpr(
this, expr,
value)));
7022 }
else if (
value == 0) {
7023 LOG(FATAL) <<
"Cannot divide by 0";
7026 return RegisterIntExpr(
7027 MakeOpposite(RevAlloc(
new DivPosIntCstExpr(
this, expr, -
value))));
7033 if (Cache()->FindExprExpression(
var, ModelCache::EXPR_ABS) ==
nullptr) {
7034 Cache()->InsertExprExpression(abs_var,
var, ModelCache::EXPR_ABS);
7036 return RevAlloc(
new IntAbsConstraint(
this,
var, abs_var));
7040 CHECK_EQ(
this, e->
solver());
7041 if (e->
Min() >= 0) {
7043 }
else if (e->
Max() <= 0) {
7044 return MakeOpposite(e);
7046 IntExpr* result = Cache()->FindExprExpression(e, ModelCache::EXPR_ABS);
7047 if (result ==
nullptr) {
7051 result = MakeProd(MakeAbs(expr), std::abs(
coefficient));
7053 result = RegisterIntExpr(RevAlloc(
new IntAbs(
this, e)));
7055 Cache()->InsertExprExpression(result, e, ModelCache::EXPR_ABS);
7061 CHECK_EQ(
this, expr->
solver());
7062 if (expr->
Bound()) {
7063 const int64_t v = expr->
Min();
7064 return MakeIntConst(v * v);
7066 IntExpr* result = Cache()->FindExprExpression(expr, ModelCache::EXPR_SQUARE);
7067 if (result ==
nullptr) {
7068 if (expr->
Min() >= 0) {
7069 result = RegisterIntExpr(RevAlloc(
new PosIntSquare(
this, expr)));
7071 result = RegisterIntExpr(RevAlloc(
new IntSquare(
this, expr)));
7073 Cache()->InsertExprExpression(result, expr, ModelCache::EXPR_SQUARE);
7079 CHECK_EQ(
this, expr->
solver());
7081 if (expr->
Bound()) {
7082 const int64_t v = expr->
Min();
7083 if (v >= OverflowLimit(n)) {
7086 return MakeIntConst(IntPower(v, n));
7090 return MakeIntConst(1);
7094 return MakeSquare(expr);
7098 if (expr->
Min() >= 0) {
7100 RegisterIntExpr(RevAlloc(
new PosIntEvenPower(
this, expr, n)));
7102 result = RegisterIntExpr(RevAlloc(
new IntEvenPower(
this, expr, n)));
7105 result = RegisterIntExpr(RevAlloc(
new IntOddPower(
this, expr, n)));
7113 CHECK_EQ(
this, left->
solver());
7114 CHECK_EQ(
this, right->
solver());
7115 if (left->
Bound()) {
7116 return MakeMin(right, left->
Min());
7118 if (right->
Bound()) {
7119 return MakeMin(left, right->
Min());
7121 if (left->
Min() >= right->
Max()) {
7124 if (right->
Min() >= left->
Max()) {
7127 return RegisterIntExpr(RevAlloc(
new MinIntExpr(
this, left, right)));
7131 CHECK_EQ(
this, expr->
solver());
7132 if (value <= expr->Min()) {
7133 return MakeIntConst(
value);
7135 if (expr->
Bound()) {
7141 return RegisterIntExpr(RevAlloc(
new MinCstIntExpr(
this, expr,
value)));
7145 return MakeMin(expr,
static_cast<int64_t
>(
value));
7149 CHECK_EQ(
this, left->
solver());
7150 CHECK_EQ(
this, right->
solver());
7151 if (left->
Bound()) {
7152 return MakeMax(right, left->
Min());
7154 if (right->
Bound()) {
7155 return MakeMax(left, right->
Min());
7157 if (left->
Min() >= right->
Max()) {
7160 if (right->
Min() >= left->
Max()) {
7163 return RegisterIntExpr(RevAlloc(
new MaxIntExpr(
this, left, right)));
7167 CHECK_EQ(
this, expr->
solver());
7168 if (expr->
Bound()) {
7171 if (value <= expr->Min()) {
7175 return MakeIntConst(
value);
7177 return RegisterIntExpr(RevAlloc(
new MaxCstIntExpr(
this, expr,
value)));
7181 return MakeMax(expr,
static_cast<int64_t
>(
value));
7185 int64_t early_date, int64_t late_date,
7186 int64_t late_cost) {
7187 return RegisterIntExpr(RevAlloc(
new SimpleConvexPiecewiseExpr(
7188 this, expr, early_cost, early_date, late_date, late_cost)));
7192 int64_t fixed_charge, int64_t step) {
7194 if (fixed_charge == 0) {
7195 return MakeIntConst(int64_t{0});
7197 return RegisterIntExpr(
7198 RevAlloc(
new SemiContinuousStepZeroExpr(
this, expr, fixed_charge)));
7200 }
else if (step == 1) {
7201 return RegisterIntExpr(
7202 RevAlloc(
new SemiContinuousStepOneExpr(
this, expr, fixed_charge)));
7204 return RegisterIntExpr(
7205 RevAlloc(
new SemiContinuousExpr(
this, expr, fixed_charge, step)));
7219 int64_t
Min()
const override {
7220 return f_.GetMinimum(
expr_->Min(),
expr_->Max());
7224 f_.GetSmallestRangeGreaterThanValue(
expr_->Min(),
expr_->Max(), m);
7228 int64_t
Max()
const override {
7229 return f_.GetMaximum(
expr_->Min(),
expr_->Max());
7234 f_.GetSmallestRangeLessThanValue(
expr_->Min(),
expr_->Max(), m);
7240 f_.GetSmallestRangeInValueRange(
expr_->Min(),
expr_->Max(), l, u);
7243 std::string
name()
const override {
7244 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)",
expr_->name(),
7249 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)",
expr_->DebugString(),
7273 int64_t unperformed_value) {
7274 if (condition->
Min() == 1) {
7276 }
else if (condition->
Max() == 0) {
7277 return MakeIntConst(unperformed_value);
7279 IntExpr* cache = Cache()->FindExprExprConstantExpression(
7280 condition, expr, unperformed_value,
7281 ModelCache::EXPR_EXPR_CONSTANT_CONDITIONAL);
7282 if (cache ==
nullptr) {
7284 new ExprWithEscapeValue(
this, condition, expr, unperformed_value));
7285 Cache()->InsertExprExprConstantExpression(
7286 cache, condition, expr, unperformed_value,
7287 ModelCache::EXPR_EXPR_CONSTANT_CONDITIONAL);
7297 MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->
Var();
7299 AddConstraint(MakeBetweenCt(result, 0, mod - 1));
7301 AddConstraint(MakeBetweenCt(result, mod + 1, 0));
7308 return MakeModulo(x, mod->
Min());
7311 MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->
Var();
7312 AddConstraint(MakeLess(result, MakeAbs(mod)));
7313 AddConstraint(MakeGreater(result, MakeOpposite(MakeAbs(mod))));
7321 void IntVar::RemoveValues(
const std::vector<int64_t>& values) {
7323 const int size = values.size();
7330 RemoveValue(values[0]);
7334 RemoveValue(values[0]);
7335 RemoveValue(values[1]);
7339 RemoveValue(values[0]);
7340 RemoveValue(values[1]);
7341 RemoveValue(values[2]);
7347 int start_index = 0;
7348 int64_t new_min = Min();
7349 if (values[start_index] <= new_min) {
7350 while (start_index < size - 1 &&
7351 values[start_index + 1] == values[start_index] + 1) {
7352 new_min = values[start_index + 1] + 1;
7356 int end_index = size - 1;
7357 int64_t new_max = Max();
7358 if (values[end_index] >= new_max) {
7359 while (end_index > start_index + 1 &&
7360 values[end_index - 1] == values[end_index] - 1) {
7361 new_max = values[end_index - 1] - 1;
7365 SetRange(new_min, new_max);
7366 for (
int i = start_index; i <= end_index; ++i) {
7367 RemoveValue(values[i]);
7374 IntExpr*
const casted = solver()->CastExpression(
this);
7378 void IntVar::SetValues(
const std::vector<int64_t>& values) {
7379 switch (values.size()) {
7385 SetValue(values.back());
7389 if (Contains(values[0])) {
7390 if (Contains(values[1])) {
7391 const int64_t l =
std::min(values[0], values[1]);
7392 const int64_t u =
std::max(values[0], values[1]);
7395 RemoveInterval(l + 1, u - 1);
7398 SetValue(values[0]);
7401 SetValue(values[1]);
7412 std::vector<int64_t>& tmp = solver()->tmp_vector_;
7414 tmp.insert(tmp.end(), values.begin(), values.end());
7415 std::sort(tmp.begin(), tmp.end());
7416 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
7417 const int size = tmp.size();
7418 const int64_t vmin = Min();
7419 const int64_t vmax = Max();
7421 int last = size - 1;
7422 if (tmp.front() > vmax || tmp.back() < vmin) {
7426 while (tmp[first] < vmin || !Contains(tmp[first])) {
7428 if (first > last || tmp[first] > vmax) {
7432 while (last > first && (tmp[last] > vmax || !Contains(tmp[last]))) {
7436 DCHECK_GE(last, first);
7437 SetRange(tmp[first], tmp[last]);
7438 while (first < last) {
7439 const int64_t
start = tmp[first] + 1;
7440 const int64_t
end = tmp[first + 1] - 1;
7452 if (!
var->Bound()) {
7454 DomainIntVar* dvar =
reinterpret_cast<DomainIntVar*
>(
var);
7456 s->
RevAlloc(
new LinkExprAndDomainIntVar(s, expr, dvar)), dvar, expr);
7465 if (var_ ==
nullptr) {
7466 solver()->SaveValue(
reinterpret_cast<void**
>(&var_));
7474 Range(&vmin, &vmax);
7475 IntVar*
const var = solver()->MakeIntVar(vmin, vmax);
7483 if (expr->
IsVar()) {
7485 expr = CastExpression(expr_var);
7489 SubIntExpr*
const sub_expr =
dynamic_cast<SubIntExpr*
>(expr);
7490 if (sub_expr !=
nullptr) {
7491 *left = sub_expr->left();
7492 *right = sub_expr->right();
7499 bool* is_negated)
const {
7501 *inner_var = expr->
Var();
7502 *is_negated =
false;
7505 SubCstIntVar*
const sub_var =
reinterpret_cast<SubCstIntVar*
>(expr);
7506 if (sub_var !=
nullptr && sub_var->Constant() == 1 &&
7509 *inner_var = sub_var->SubVar();
7518 if (
dynamic_cast<TimesCstIntVar*
>(expr) !=
nullptr) {
7519 TimesCstIntVar*
const var =
dynamic_cast<TimesCstIntVar*
>(expr);
7521 *inner_expr =
var->SubVar();
7523 }
else if (
dynamic_cast<TimesIntCstExpr*
>(expr) !=
nullptr) {
7524 TimesIntCstExpr*
const prod =
dynamic_cast<TimesIntCstExpr*
>(expr);
7526 *inner_expr = prod->Expr();
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 IntVar * Var()=0
Creates a variable from the expression.
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
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[]
void Decr(Solver *const s)
void Incr(Solver *const s)
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)
void SetValue(Solver *const s, const T &val)
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
T * RevAlloc(T *object)
Registers the given object as being reversible.
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.
std::vector< IntVarIterator * > holes_
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::pair< double, double > Range
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)
Constraint * SetIsEqual(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 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)
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)
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)
Constraint * SetIsGreaterOrEqual(IntVar *const var, const std::vector< int64_t > &values, const std::vector< IntVar * > &vars)
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_
std::optional< int64_t > end
const std::optional< Range > & range