24#include "absl/flags/flag.h"
25#include "absl/strings/str_cat.h"
26#include "absl/strings/str_format.h"
27#include "absl/strings/string_view.h"
28#include "absl/types/span.h"
38ABSL_FLAG(
bool, cp_disable_expression_optimization,
false,
39 "Disable special optimization when creating expressions.");
41 "Share IntConst's with the same value.");
44#pragma warning(disable : 4351 4355)
62 :
IntExpr(s), index_(s->GetNewIntVarIndex()) {
83 if (mi > 1 || ma < 0 || mi > ma) {
107 if (l <= 0 && u >= 1) {
131 return ((v == 0 &&
value_ != 1) || (v == 1 &&
value_ != 0));
135 if (constant > 1 || constant < 0) {
146 if (constant > 1 || constant < 0) {
159 }
else if (constant <= 0) {
169 }
else if (constant >= 1) {
178 const std::string& var_name =
name();
179 if (!var_name.empty()) {
180 out = var_name +
"(";
204class DomainIntVar :
public IntVar {
209 BitSetIterator(uint64_t*
const bitset, int64_t omin)
212 max_(
std::numeric_limits<int64_t>::min()),
213 current_(
std::numeric_limits<int64_t>::max()) {}
215 ~BitSetIterator()
override {}
217 void Init(int64_t min, int64_t max) {
222 bool Ok()
const {
return current_ <= max_; }
224 int64_t
Value()
const {
return current_; }
227 if (++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_; }
272 void AddHole(int64_t value) { holes_.push_back(value); }
274 int NumHoles()
const {
275 return holes_stamp_ < solver_->stamp() ? 0 : holes_.size();
279 Solver*
const solver_;
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));
329 solver_->AddBacktrackAction(
330 [
this, value](Solver* s) { Uninsert(value); },
false);
335 for (
int pos = start_.Value(); pos < elements_.size(); ++pos) {
336 if (elements_[pos].first == value) {
337 if (position !=
nullptr) *position = pos;
338 return At(pos).second;
346 const int start = start_.Value();
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;
356 start_.Incr(solver_);
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];
365 void RemoveAll() { start_.SetValue(solver_, elements_.size()); }
367 int start()
const {
return start_.Value(); }
368 int end()
const {
return elements_.size(); }
370 int Size()
const {
return elements_.size() - start_.Value(); }
373 void Uninsert(int64_t value) {
374 for (
int pos = 0; pos < elements_.size(); ++pos) {
375 if (elements_[pos].first == value) {
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";
389 Solver*
const solver_;
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* 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)),
672 offset_(variable->Min()),
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);
683 const int index = value - offset_;
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 {
710 const int index = value - offset_;
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) {
726 const int64_t value = pos + offset_;
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;
744 const int64_t value = pos + offset_;
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) {
786 boolvar->SetValue(pos + offset_ == value);
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);
820 RevRemove(hole - offset_);
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_;
875 const int64_t offset_;
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* boolvar, int64_t value) = 0;
894 class UpperBoundWatcher :
public BaseUpperBoundWatcher {
896 class WatchDemon :
public Demon {
898 WatchDemon(UpperBoundWatcher*
const watcher, int64_t index,
900 : value_watcher_(watcher), index_(index), var_(var) {}
901 ~WatchDemon()
override {}
903 void Run(Solver*
const solver)
override {
904 value_watcher_->ProcessUpperBoundWatcher(index_, var_);
908 UpperBoundWatcher*
const value_watcher_;
909 const int64_t index_;
913 class VarDemon :
public Demon {
915 explicit VarDemon(UpperBoundWatcher*
const watcher)
916 : value_watcher_(watcher) {}
917 ~VarDemon()
override {}
919 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
922 UpperBoundWatcher*
const value_watcher_;
925 UpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
926 : BaseUpperBoundWatcher(solver),
929 watchers_(solver, variable->Min(), variable->Max()),
934 ~UpperBoundWatcher()
override {}
936 IntVar* GetOrMakeUpperBoundWatcher(int64_t value)
override {
937 IntVar*
const watcher = watchers_.FindPtrOrNull(value,
nullptr);
938 if (watcher !=
nullptr) {
941 if (variable_->Max() >= value) {
942 if (variable_->Min() >= value) {
943 return solver()->MakeIntConst(1);
945 const std::string vname = variable_->HasName()
947 : variable_->DebugString();
948 const std::string bname =
949 absl::StrFormat(
"Watch<%s >= %d>", vname, value);
950 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
951 watchers_.UnsafeRevInsert(value, boolvar);
952 if (posted_.Switched()) {
954 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
955 var_demon_->desinhibit(solver());
961 return variable_->solver()->MakeIntConst(0);
965 void SetUpperBoundWatcher(IntVar*
const boolvar, int64_t value)
override {
966 CHECK(watchers_.FindPtrOrNull(value,
nullptr) ==
nullptr);
967 watchers_.UnsafeRevInsert(value, boolvar);
968 if (posted_.Switched() && !boolvar->Bound()) {
970 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
971 var_demon_->desinhibit(solver());
976 void Post()
override {
977 const int kTooSmallToSort = 8;
978 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
979 variable_->WhenRange(var_demon_);
981 if (watchers_.Size() > kTooSmallToSort) {
982 watchers_.SortActive();
984 start_.SetValue(solver(), watchers_.start());
985 end_.SetValue(solver(), watchers_.end() - 1);
988 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
989 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
990 IntVar*
const boolvar =
w.second;
991 const int64_t value =
w.first;
992 if (!boolvar->Bound() && value > variable_->Min() &&
993 value <= variable_->Max()) {
995 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
998 posted_.Switch(solver());
1001 void InitialPropagate()
override {
1002 const int64_t var_min = variable_->Min();
1003 const int64_t var_max = variable_->Max();
1005 while (start_.Value() <= end_.Value()) {
1006 const std::pair<int64_t, IntVar*>&
w = watchers_.At(start_.Value());
1007 if (
w.first <= var_min) {
1008 w.second->SetValue(1);
1009 start_.Incr(solver());
1014 while (end_.Value() >= start_.Value()) {
1015 const std::pair<int64_t, IntVar*>&
w = watchers_.At(end_.Value());
1016 if (
w.first > var_max) {
1017 w.second->SetValue(0);
1018 end_.Decr(solver());
1023 for (
int i = start_.Value(); i <= end_.Value(); ++i) {
1024 const std::pair<int64_t, IntVar*>&
w = watchers_.At(i);
1025 if (
w.second->Bound()) {
1026 ProcessUpperBoundWatcher(
w.first,
w.second);
1029 if (start_.Value() > end_.Value()) {
1030 var_demon_->inhibit(solver());
1033 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1034 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
1035 const int64_t value =
w.first;
1036 IntVar*
const boolvar =
w.second;
1038 if (value <= var_min) {
1039 boolvar->SetValue(1);
1040 watchers_.RemoveAt(pos);
1041 }
else if (value > var_max) {
1042 boolvar->SetValue(0);
1043 watchers_.RemoveAt(pos);
1044 }
else if (boolvar->Bound()) {
1045 ProcessUpperBoundWatcher(value, boolvar);
1046 watchers_.RemoveAt(pos);
1052 void Accept(ModelVisitor*
const visitor)
const override {
1056 std::vector<int64_t> all_coefficients;
1057 std::vector<IntVar*> all_bool_vars;
1058 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1059 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
1060 all_coefficients.push_back(
w.first);
1061 all_bool_vars.push_back(
w.second);
1070 std::string DebugString()
const override {
1071 return absl::StrFormat(
"UpperBoundWatcher(%s)", variable_->DebugString());
1075 void ProcessUpperBoundWatcher(int64_t value, IntVar*
const boolvar) {
1076 if (boolvar->Min() == 0) {
1077 variable_->SetMax(value - 1);
1079 variable_->SetMin(value);
1084 const int64_t var_min = variable_->Min();
1085 const int64_t var_max = variable_->Max();
1087 while (start_.Value() <= end_.Value()) {
1088 const std::pair<int64_t, IntVar*>&
w = watchers_.At(start_.Value());
1089 if (
w.first <= var_min) {
1090 w.second->SetValue(1);
1091 start_.Incr(solver());
1096 while (end_.Value() >= start_.Value()) {
1097 const std::pair<int64_t, IntVar*>&
w = watchers_.At(end_.Value());
1098 if (
w.first > var_max) {
1099 w.second->SetValue(0);
1100 end_.Decr(solver());
1105 if (start_.Value() > end_.Value()) {
1106 var_demon_->inhibit(solver());
1109 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1110 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
1111 const int64_t value =
w.first;
1112 IntVar*
const boolvar =
w.second;
1114 if (value <= var_min) {
1115 boolvar->SetValue(1);
1116 watchers_.RemoveAt(pos);
1117 }
else if (value > var_max) {
1118 boolvar->SetValue(0);
1119 watchers_.RemoveAt(pos);
1122 if (watchers_.Empty()) {
1123 var_demon_->inhibit(solver());
1128 DomainIntVar*
const variable_;
1131 RevIntPtrMap<IntVar> watchers_;
1132 NumericalRev<int> start_;
1133 NumericalRev<int> end_;
1138 class DenseUpperBoundWatcher :
public BaseUpperBoundWatcher {
1140 class WatchDemon :
public Demon {
1142 WatchDemon(DenseUpperBoundWatcher*
const watcher, int64_t value,
1144 : value_watcher_(watcher), value_(value), var_(var) {}
1145 ~WatchDemon()
override {}
1147 void Run(Solver*
const solver)
override {
1148 value_watcher_->ProcessUpperBoundWatcher(value_, var_);
1152 DenseUpperBoundWatcher*
const value_watcher_;
1153 const int64_t value_;
1157 class VarDemon :
public Demon {
1159 explicit VarDemon(DenseUpperBoundWatcher*
const watcher)
1160 : value_watcher_(watcher) {}
1162 ~VarDemon()
override {}
1164 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
1167 DenseUpperBoundWatcher*
const value_watcher_;
1170 DenseUpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
1171 : BaseUpperBoundWatcher(solver),
1172 variable_(variable),
1173 var_demon_(nullptr),
1174 offset_(variable->Min()),
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);
1191 RevInsert(value - offset_, boolvar);
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 {
1205 const int index = value - offset_;
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) {
1221 const int64_t value = pos + offset_;
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;
1236 const int64_t value = pos + offset_;
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_;
1326 const int64_t offset_;
1327 std::vector<IntVar*> watchers_;
1328 NumericalRev<int> active_watchers_;
1332 DomainIntVar(Solver* s, int64_t vmin, int64_t vmax,
const std::string& name);
1333 DomainIntVar(Solver* s, absl::Span<const int64_t> sorted_values,
1334 const std::string& name);
1335 ~DomainIntVar()
override;
1337 int64_t Min()
const override {
return min_.Value(); }
1338 void SetMin(int64_t m)
override;
1339 int64_t Max()
const override {
return max_.Value(); }
1340 void SetMax(int64_t m)
override;
1341 void SetRange(int64_t mi, int64_t ma)
override;
1342 void SetValue(int64_t v)
override;
1343 bool Bound()
const override {
return (min_.Value() == max_.Value()); }
1344 int64_t
Value()
const override {
1345 CHECK_EQ(min_.Value(), max_.Value())
1346 <<
" variable " << DebugString() <<
" is not bound.";
1347 return min_.Value();
1349 void RemoveValue(int64_t v)
override;
1350 void RemoveInterval(int64_t l, int64_t u)
override;
1352 void WhenBound(Demon* d)
override {
1353 if (min_.Value() != max_.Value()) {
1355 delayed_bound_demons_.PushIfNotTop(solver(),
1358 bound_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1362 void WhenRange(Demon* d)
override {
1363 if (min_.Value() != max_.Value()) {
1365 delayed_range_demons_.PushIfNotTop(solver(),
1368 range_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1372 void WhenDomain(Demon* d)
override {
1373 if (min_.Value() != max_.Value()) {
1375 delayed_domain_demons_.PushIfNotTop(solver(),
1378 domain_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1383 IntVar* IsEqual(int64_t constant)
override {
1384 Solver*
const s = solver();
1385 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1386 return s->MakeIsLessOrEqualCstVar(
this, constant);
1388 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1389 return s->MakeIsGreaterOrEqualCstVar(
this, constant);
1391 if (!Contains(constant)) {
1392 return s->MakeIntConst(int64_t{0});
1394 if (Bound() && min_.Value() == constant) {
1395 return s->MakeIntConst(int64_t{1});
1397 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1399 if (cache !=
nullptr) {
1400 return cache->Var();
1402 if (value_watcher_ ==
nullptr) {
1403 if (
CapSub(Max(), Min()) <= 256) {
1404 solver()->SaveAndSetValue(
1405 reinterpret_cast<void**
>(&value_watcher_),
1406 reinterpret_cast<void*
>(
1407 solver()->RevAlloc(
new DenseValueWatcher(solver(),
this))));
1410 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1411 reinterpret_cast<void*
>(solver()->RevAlloc(
1412 new ValueWatcher(solver(),
this))));
1414 solver()->AddConstraint(value_watcher_);
1416 IntVar*
const boolvar = value_watcher_->GetOrMakeValueWatcher(constant);
1417 s->Cache()->InsertExprConstantExpression(
1423 Constraint*
SetIsEqual(absl::Span<const int64_t> values,
1424 const std::vector<IntVar*>& vars) {
1425 if (value_watcher_ ==
nullptr) {
1426 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1427 reinterpret_cast<void*
>(solver()->RevAlloc(
1428 new ValueWatcher(solver(),
this))));
1429 for (
int i = 0;
i < vars.size(); ++
i) {
1430 value_watcher_->SetValueWatcher(vars[i], values[i]);
1433 return value_watcher_;
1436 IntVar* IsDifferent(int64_t constant)
override {
1437 Solver*
const s = solver();
1438 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1439 return s->MakeIsGreaterOrEqualCstVar(
this, constant + 1);
1441 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1442 return s->MakeIsLessOrEqualCstVar(
this, constant - 1);
1444 if (!Contains(constant)) {
1445 return s->MakeIntConst(int64_t{1});
1447 if (Bound() && min_.Value() == constant) {
1448 return s->MakeIntConst(int64_t{0});
1450 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1452 if (cache !=
nullptr) {
1453 return cache->Var();
1455 IntVar*
const boolvar = s->MakeDifference(1, IsEqual(constant))->Var();
1456 s->Cache()->InsertExprConstantExpression(
1462 IntVar* IsGreaterOrEqual(int64_t constant)
override {
1463 Solver*
const s = solver();
1464 if (max_.Value() < constant) {
1465 return s->MakeIntConst(int64_t{0});
1467 if (min_.Value() >= constant) {
1468 return s->MakeIntConst(int64_t{1});
1470 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1472 if (cache !=
nullptr) {
1473 return cache->Var();
1475 if (bound_watcher_ ==
nullptr) {
1476 if (
CapSub(Max(), Min()) <= 256) {
1477 solver()->SaveAndSetValue(
1478 reinterpret_cast<void**
>(&bound_watcher_),
1479 reinterpret_cast<void*
>(solver()->RevAlloc(
1480 new DenseUpperBoundWatcher(solver(),
this))));
1481 solver()->AddConstraint(bound_watcher_);
1483 solver()->SaveAndSetValue(
1484 reinterpret_cast<void**
>(&bound_watcher_),
1485 reinterpret_cast<void*
>(
1486 solver()->RevAlloc(
new UpperBoundWatcher(solver(),
this))));
1487 solver()->AddConstraint(bound_watcher_);
1490 IntVar*
const boolvar =
1491 bound_watcher_->GetOrMakeUpperBoundWatcher(constant);
1492 s->Cache()->InsertExprConstantExpression(
1493 boolvar,
this, constant,
1500 const std::vector<IntVar*>& vars) {
1501 if (bound_watcher_ ==
nullptr) {
1502 if (
CapSub(Max(), Min()) <= 256) {
1503 solver()->SaveAndSetValue(
1504 reinterpret_cast<void**
>(&bound_watcher_),
1505 reinterpret_cast<void*
>(solver()->RevAlloc(
1506 new DenseUpperBoundWatcher(solver(),
this))));
1507 solver()->AddConstraint(bound_watcher_);
1509 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&bound_watcher_),
1510 reinterpret_cast<void*
>(solver()->RevAlloc(
1511 new UpperBoundWatcher(solver(),
this))));
1512 solver()->AddConstraint(bound_watcher_);
1514 for (
int i = 0;
i < values.size(); ++
i) {
1515 bound_watcher_->SetUpperBoundWatcher(vars[i], values[i]);
1518 return bound_watcher_;
1521 IntVar* IsLessOrEqual(int64_t constant)
override {
1522 Solver*
const s = solver();
1523 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1525 if (cache !=
nullptr) {
1526 return cache->Var();
1528 IntVar*
const boolvar =
1529 s->MakeDifference(1, IsGreaterOrEqual(constant + 1))->Var();
1530 s->Cache()->InsertExprConstantExpression(
1538 void CleanInProcess();
1539 uint64_t Size()
const override {
1540 if (bits_ !=
nullptr)
return bits_->Size();
1541 return (
static_cast<uint64_t
>(max_.Value()) -
1542 static_cast<uint64_t
>(min_.Value()) + 1);
1544 bool Contains(int64_t v)
const override {
1545 if (v < min_.Value() || v > max_.Value())
return false;
1546 return (bits_ ==
nullptr ?
true : bits_->Contains(v));
1548 IntVarIterator* MakeHoleIterator(
bool reversible)
const override;
1549 IntVarIterator* MakeDomainIterator(
bool reversible)
const override;
1550 int64_t OldMin()
const override {
return std::min(old_min_, min_.Value()); }
1551 int64_t OldMax()
const override {
return std::max(old_max_, max_.Value()); }
1553 std::string DebugString()
const override;
1554 BitSet* bitset()
const {
return bits_; }
1556 std::string BaseName()
const override {
return "IntegerVar"; }
1558 friend class PlusCstDomainIntVar;
1559 friend class LinkExprAndDomainIntVar;
1562 void CheckOldMin() {
1563 if (old_min_ > min_.Value()) {
1564 old_min_ = min_.Value();
1567 void CheckOldMax() {
1568 if (old_max_ < max_.Value()) {
1569 old_max_ = max_.Value();
1578 SimpleRevFIFO<Demon*> bound_demons_;
1579 SimpleRevFIFO<Demon*> range_demons_;
1580 SimpleRevFIFO<Demon*> domain_demons_;
1581 SimpleRevFIFO<Demon*> delayed_bound_demons_;
1582 SimpleRevFIFO<Demon*> delayed_range_demons_;
1583 SimpleRevFIFO<Demon*> delayed_domain_demons_;
1584 QueueHandler handler_;
1587 BaseValueWatcher* value_watcher_;
1588 BaseUpperBoundWatcher* bound_watcher_;
1597inline bool ClosedIntervalNoLargerThan(int64_t a, int64_t b, int64_t K) {
1607class SimpleBitSet :
public DomainIntVar::BitSet {
1609 SimpleBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1615 size_(vmax - vmin + 1),
1617 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1618 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1619 bits_ =
new uint64_t[bsize_];
1620 stamps_ =
new uint64_t[bsize_];
1621 for (
int i = 0;
i < bsize_; ++
i) {
1623 (
i == size_.Value() - 1) ? 63 -
BitPos64(size_.Value()) : 0;
1625 stamps_[
i] = s->stamp() - 1;
1629 SimpleBitSet(Solver*
const s, absl::Span<const int64_t> sorted_values,
1630 int64_t vmin, int64_t vmax)
1636 size_(sorted_values.size()),
1638 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1639 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1640 bits_ =
new uint64_t[bsize_];
1641 stamps_ =
new uint64_t[bsize_];
1642 for (
int i = 0;
i < bsize_; ++
i) {
1643 bits_[
i] = uint64_t{0};
1644 stamps_[
i] = s->stamp() - 1;
1646 for (
int i = 0;
i < sorted_values.size(); ++
i) {
1647 const int64_t val = sorted_values[
i];
1650 const int pos =
BitPos64(val - omin_);
1655 ~SimpleBitSet()
override {
1660 bool bit(int64_t val)
const {
return IsBitSet64(bits_, val - omin_); }
1662 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1663 DCHECK_GE(nmin, cmin);
1664 DCHECK_LE(nmin, cmax);
1665 DCHECK_LE(cmin, cmax);
1666 DCHECK_GE(cmin, omin_);
1667 DCHECK_LE(cmax, omax_);
1668 const int64_t new_min =
1671 const uint64_t removed_bits =
1673 size_.Add(solver_, -removed_bits);
1677 int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax)
override {
1678 DCHECK_GE(nmax, cmin);
1679 DCHECK_LE(nmax, cmax);
1680 DCHECK_LE(cmin, cmax);
1681 DCHECK_GE(cmin, omin_);
1682 DCHECK_LE(cmax, omax_);
1683 const int64_t new_max =
1686 const uint64_t removed_bits =
1688 size_.Add(solver_, -removed_bits);
1692 bool SetValue(int64_t val)
override {
1693 DCHECK_GE(val, omin_);
1694 DCHECK_LE(val, omax_);
1696 size_.SetValue(solver_, 1);
1702 bool Contains(int64_t val)
const override {
1703 DCHECK_GE(val, omin_);
1704 DCHECK_LE(val, omax_);
1708 bool RemoveValue(int64_t val)
override {
1709 if (val < omin_ || val > omax_ || !bit(val)) {
1713 const int64_t val_offset = val - omin_;
1715 const uint64_t current_stamp = solver_->stamp();
1716 if (stamps_[offset] < current_stamp) {
1717 stamps_[offset] = current_stamp;
1718 solver_->SaveValue(&bits_[offset]);
1720 const int pos =
BitPos64(val_offset);
1721 bits_[offset] &= ~OneBit64(pos);
1723 size_.Decr(solver_);
1729 uint64_t Size()
const override {
return size_.Value(); }
1731 std::string DebugString()
const override {
1733 absl::StrAppendFormat(&out,
"SimpleBitSet(%d..%d : ", omin_, omax_);
1734 for (
int i = 0;
i < bsize_; ++
i) {
1735 absl::StrAppendFormat(&out,
"%x", bits_[i]);
1741 void DelayRemoveValue(int64_t val)
override { removed_.push_back(val); }
1743 void ApplyRemovedValues(DomainIntVar* var)
override {
1744 std::sort(removed_.begin(), removed_.end());
1745 for (std::vector<int64_t>::iterator it = removed_.begin();
1746 it != removed_.end(); ++it) {
1747 var->RemoveValue(*it);
1751 void ClearRemovedValues()
override { removed_.clear(); }
1753 std::string pretty_DebugString(int64_t min, int64_t max)
const override {
1759 int64_t start_cumul = min;
1760 for (int64_t v = min + 1; v < max; ++v) {
1768 if (v == start_cumul + 1) {
1769 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1770 }
else if (v == start_cumul + 2) {
1771 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1773 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1780 if (max == start_cumul + 1) {
1781 absl::StrAppendFormat(&out,
"%d %d", start_cumul, max);
1783 absl::StrAppendFormat(&out,
"%d..%d", start_cumul, max);
1786 absl::StrAppendFormat(&out,
"%d", max);
1789 absl::StrAppendFormat(&out,
"%d", min);
1794 DomainIntVar::BitSetIterator* MakeIterator()
override {
1795 return new DomainIntVar::BitSetIterator(bits_, omin_);
1801 const int64_t omin_;
1802 const int64_t omax_;
1803 NumericalRev<int64_t> size_;
1805 std::vector<int64_t> removed_;
1811class SmallBitSet :
public DomainIntVar::BitSet {
1813 SmallBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1816 stamp_(s->stamp() - 1),
1819 size_(vmax - vmin + 1) {
1820 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1824 SmallBitSet(Solver*
const s, absl::Span<const int64_t> sorted_values,
1825 int64_t vmin, int64_t vmax)
1828 stamp_(s->stamp() - 1),
1831 size_(sorted_values.size()) {
1832 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1834 for (
int i = 0;
i < sorted_values.size(); ++
i) {
1835 const int64_t val = sorted_values[
i];
1836 DCHECK_GE(val, vmin);
1837 DCHECK_LE(val, vmax);
1843 ~SmallBitSet()
override {}
1845 bool bit(int64_t val)
const {
1846 DCHECK_GE(val, omin_);
1847 DCHECK_LE(val, omax_);
1848 return (bits_ &
OneBit64(val - omin_)) != 0;
1851 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1852 DCHECK_GE(nmin, cmin);
1853 DCHECK_LE(nmin, cmax);
1854 DCHECK_LE(cmin, cmax);
1855 DCHECK_GE(cmin, omin_);
1856 DCHECK_LE(cmax, omax_);
1861 const uint64_t new_bits = bits_ &
OneRange64(nmin - omin_, cmax - omin_);
1862 if (new_bits != uint64_t{0}) {
1864 size_.SetValue(solver_,
BitCount64(new_bits));
1871 return std::numeric_limits<int64_t>::max();
1875 int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax)
override {
1876 DCHECK_GE(nmax, cmin);
1877 DCHECK_LE(nmax, cmax);
1878 DCHECK_LE(cmin, cmax);
1879 DCHECK_GE(cmin, omin_);
1880 DCHECK_LE(cmax, omax_);
1885 const uint64_t new_bits = bits_ &
OneRange64(cmin - omin_, nmax - omin_);
1886 if (new_bits != uint64_t{0}) {
1888 size_.SetValue(solver_,
BitCount64(new_bits));
1895 return std::numeric_limits<int64_t>::min();
1899 bool SetValue(int64_t val)
override {
1900 DCHECK_GE(val, omin_);
1901 DCHECK_LE(val, omax_);
1905 size_.SetValue(solver_, 1);
1911 bool Contains(int64_t val)
const override {
1912 DCHECK_GE(val, omin_);
1913 DCHECK_LE(val, omax_);
1917 bool RemoveValue(int64_t val)
override {
1918 DCHECK_GE(val, omin_);
1919 DCHECK_LE(val, omax_);
1922 const uint64_t current_stamp = solver_->stamp();
1923 if (stamp_ < current_stamp) {
1924 stamp_ = current_stamp;
1925 solver_->SaveValue(&bits_);
1927 bits_ &= ~OneBit64(val - omin_);
1930 size_.Decr(solver_);
1940 uint64_t Size()
const override {
return size_.Value(); }
1942 std::string DebugString()
const override {
1943 return absl::StrFormat(
"SmallBitSet(%d..%d : %llx)", omin_, omax_, bits_);
1946 void DelayRemoveValue(int64_t val)
override {
1947 DCHECK_GE(val, omin_);
1948 DCHECK_LE(val, omax_);
1949 removed_.push_back(val);
1952 void ApplyRemovedValues(DomainIntVar* var)
override {
1953 std::sort(removed_.begin(), removed_.end());
1954 for (std::vector<int64_t>::iterator it = removed_.begin();
1955 it != removed_.end(); ++it) {
1956 var->RemoveValue(*it);
1960 void ClearRemovedValues()
override { removed_.clear(); }
1962 std::string pretty_DebugString(int64_t min, int64_t max)
const override {
1968 int64_t start_cumul = min;
1969 for (int64_t v = min + 1; v < max; ++v) {
1977 if (v == start_cumul + 1) {
1978 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1979 }
else if (v == start_cumul + 2) {
1980 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1982 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1989 if (max == start_cumul + 1) {
1990 absl::StrAppendFormat(&out,
"%d %d", start_cumul, max);
1992 absl::StrAppendFormat(&out,
"%d..%d", start_cumul, max);
1995 absl::StrAppendFormat(&out,
"%d", max);
1998 absl::StrAppendFormat(&out,
"%d", min);
2003 DomainIntVar::BitSetIterator* MakeIterator()
override {
2004 return new DomainIntVar::BitSetIterator(&bits_, omin_);
2010 const int64_t omin_;
2011 const int64_t omax_;
2012 NumericalRev<int64_t> size_;
2013 std::vector<int64_t> removed_;
2018 ~EmptyIterator()
override {}
2019 void Init()
override {}
2020 bool Ok()
const override {
return false; }
2021 int64_t
Value()
const override {
2022 LOG(FATAL) <<
"Should not be called";
2025 void Next()
override {}
2030 explicit RangeIterator(
const IntVar*
const var)
2032 min_(std::numeric_limits<int64_t>::max()),
2033 max_(std::numeric_limits<int64_t>::min()),
2036 ~RangeIterator()
override {}
2038 void Init()
override {
2044 bool Ok()
const override {
return current_ <= max_; }
2046 int64_t
Value()
const override {
return current_; }
2048 void Next()
override { current_++; }
2051 const IntVar*
const var_;
2059 explicit DomainIntVarHoleIterator(
const DomainIntVar*
const v)
2060 : var_(v), bits_(nullptr), values_(nullptr), size_(0), index_(0) {}
2062 ~DomainIntVarHoleIterator()
override {}
2064 void Init()
override {
2065 bits_ = var_->bitset();
2066 if (bits_ !=
nullptr) {
2068 values_ = bits_->Holes().data();
2069 size_ = bits_->Holes().size();
2077 bool Ok()
const override {
return index_ < size_; }
2079 int64_t
Value()
const override {
2080 DCHECK(bits_ !=
nullptr);
2081 DCHECK(index_ < size_);
2082 return values_[index_];
2085 void Next()
override { index_++; }
2088 const DomainIntVar*
const var_;
2089 DomainIntVar::BitSet* bits_;
2090 const int64_t* values_;
2097 explicit DomainIntVarDomainIterator(
const DomainIntVar*
const v,
2100 bitset_iterator_(nullptr),
2101 min_(std::numeric_limits<int64_t>::max()),
2102 max_(std::numeric_limits<int64_t>::min()),
2104 reversible_(reversible) {}
2106 ~DomainIntVarDomainIterator()
override {
2107 if (!reversible_ && bitset_iterator_) {
2108 delete bitset_iterator_;
2112 void Init()
override {
2113 if (var_->bitset() !=
nullptr && !var_->Bound()) {
2115 if (!bitset_iterator_) {
2116 Solver*
const solver = var_->solver();
2117 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2118 bitset_iterator_ = solver->RevAlloc(var_->bitset()->MakeIterator());
2121 if (bitset_iterator_) {
2122 delete bitset_iterator_;
2124 bitset_iterator_ = var_->bitset()->MakeIterator();
2126 bitset_iterator_->Init(var_->Min(), var_->Max());
2128 if (bitset_iterator_) {
2130 Solver*
const solver = var_->solver();
2131 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2133 delete bitset_iterator_;
2135 bitset_iterator_ =
nullptr;
2143 bool Ok()
const override {
2144 return bitset_iterator_ ? bitset_iterator_->Ok() : (current_ <= max_);
2147 int64_t
Value()
const override {
2148 return bitset_iterator_ ? bitset_iterator_->Value() : current_;
2151 void Next()
override {
2152 if (bitset_iterator_) {
2153 bitset_iterator_->Next();
2160 const DomainIntVar*
const var_;
2161 DomainIntVar::BitSetIterator* bitset_iterator_;
2165 const bool reversible_;
2170 UnaryIterator(
const IntVar*
const v,
bool hole,
bool reversible)
2171 : iterator_(hole ? v->MakeHoleIterator(reversible)
2172 : v->MakeDomainIterator(reversible)),
2173 reversible_(reversible) {}
2175 ~UnaryIterator()
override {
2181 void Init()
override { iterator_->Init(); }
2183 bool Ok()
const override {
return iterator_->Ok(); }
2185 void Next()
override { iterator_->Next(); }
2188 IntVarIterator*
const iterator_;
2189 const bool reversible_;
2192DomainIntVar::DomainIntVar(
Solver*
const s, int64_t vmin, int64_t vmax,
2193 const std::string& name)
2204 value_watcher_(nullptr),
2205 bound_watcher_(nullptr) {}
2207DomainIntVar::DomainIntVar(
Solver*
const s,
2208 absl::Span<const int64_t> sorted_values,
2209 const std::string& name)
2211 min_(std::numeric_limits<int64_t>::max()),
2212 max_(std::numeric_limits<int64_t>::min()),
2213 old_min_(std::numeric_limits<int64_t>::max()),
2214 old_max_(std::numeric_limits<int64_t>::min()),
2215 new_min_(std::numeric_limits<int64_t>::max()),
2216 new_max_(std::numeric_limits<int64_t>::min()),
2220 value_watcher_(nullptr),
2221 bound_watcher_(nullptr) {
2222 CHECK_GE(sorted_values.size(), 1);
2224 const int64_t vmin = sorted_values.front();
2225 const int64_t vmax = sorted_values.back();
2226 const bool contiguous = vmax - vmin + 1 == sorted_values.size();
2228 min_.SetValue(
solver(), vmin);
2231 max_.SetValue(
solver(), vmax);
2236 if (vmax - vmin + 1 < 65) {
2238 new SmallBitSet(
solver(), sorted_values, vmin, vmax));
2241 new SimpleBitSet(
solver(), sorted_values, vmin, vmax));
2246DomainIntVar::~DomainIntVar() {}
2248void DomainIntVar::SetMin(int64_t m) {
2249 if (m <= min_.Value())
return;
2250 if (m > max_.Value()) solver()->Fail();
2254 if (new_min_ > new_max_) {
2260 const int64_t new_min =
2263 : bits_->ComputeNewMin(m, min_.Value(), max_.Value()));
2264 min_.SetValue(solver(), new_min);
2265 if (min_.Value() > max_.Value()) {
2272void DomainIntVar::SetMax(int64_t m) {
2273 if (m >= max_.Value())
return;
2274 if (m < min_.Value()) solver()->Fail();
2278 if (new_max_ < new_min_) {
2284 const int64_t new_max =
2287 : bits_->ComputeNewMax(m, min_.Value(), max_.Value()));
2288 max_.SetValue(solver(), new_max);
2289 if (min_.Value() > max_.Value()) {
2296void DomainIntVar::SetRange(int64_t mi, int64_t ma) {
2300 if (mi > ma || mi > max_.Value() || ma < min_.Value()) solver()->Fail();
2301 if (mi <= min_.Value() && ma >= max_.Value())
return;
2303 if (ma < new_max_) {
2306 if (mi > new_min_) {
2309 if (new_min_ > new_max_) {
2313 if (mi > min_.Value()) {
2315 const int64_t new_min =
2318 : bits_->ComputeNewMin(mi, min_.Value(), max_.Value()));
2319 min_.SetValue(solver(), new_min);
2321 if (min_.Value() > ma) {
2324 if (ma < max_.Value()) {
2326 const int64_t new_max =
2329 : bits_->ComputeNewMax(ma, min_.Value(), max_.Value()));
2330 max_.SetValue(solver(), new_max);
2332 if (min_.Value() > max_.Value()) {
2340void DomainIntVar::SetValue(int64_t v) {
2341 if (v != min_.Value() || v != max_.Value()) {
2342 if (v < min_.Value() || v > max_.Value()) {
2346 if (v > new_max_ || v < new_min_) {
2352 if (bits_ && !bits_->SetValue(v)) {
2357 min_.SetValue(solver(), v);
2358 max_.SetValue(solver(), v);
2364void DomainIntVar::RemoveValue(int64_t v) {
2365 if (v < min_.Value() || v > max_.Value())
return;
2366 if (v == min_.Value()) {
2368 }
else if (v == max_.Value()) {
2371 if (bits_ ==
nullptr) {
2375 if (v >= new_min_ && v <= new_max_ && bits_->Contains(v)) {
2376 bits_->DelayRemoveValue(v);
2379 if (bits_->RemoveValue(v)) {
2386void DomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2387 if (l <= min_.Value()) {
2389 }
else if (u >= max_.Value()) {
2392 for (int64_t v = l; v <= u; ++v) {
2398void DomainIntVar::CreateBits() {
2399 solver()->SaveValue(
reinterpret_cast<void**
>(&bits_));
2400 if (max_.Value() - min_.Value() < 64) {
2401 bits_ = solver()->RevAlloc(
2402 new SmallBitSet(solver(), min_.Value(), max_.Value()));
2404 bits_ = solver()->RevAlloc(
2405 new SimpleBitSet(solver(), min_.Value(), max_.Value()));
2409void DomainIntVar::CleanInProcess() {
2410 in_process_ =
false;
2411 if (bits_ !=
nullptr) {
2412 bits_->ClearHoles();
2416void DomainIntVar::Push() {
2417 const bool in_process = in_process_;
2418 EnqueueVar(&handler_);
2419 CHECK_EQ(in_process, in_process_);
2422void DomainIntVar::Process() {
2423 CHECK(!in_process_);
2425 if (bits_ !=
nullptr) {
2426 bits_->ClearRemovedValues();
2428 set_variable_to_clean_on_fail(
this);
2429 new_min_ = min_.Value();
2430 new_max_ = max_.Value();
2431 const bool is_bound = min_.Value() == max_.Value();
2432 const bool range_changed =
2433 min_.Value() != OldMin() || max_.Value() != OldMax();
2436 ExecuteAll(bound_demons_);
2438 if (range_changed) {
2439 ExecuteAll(range_demons_);
2441 ExecuteAll(domain_demons_);
2445 EnqueueAll(delayed_bound_demons_);
2447 if (range_changed) {
2448 EnqueueAll(delayed_range_demons_);
2450 EnqueueAll(delayed_domain_demons_);
2453 set_variable_to_clean_on_fail(
nullptr);
2455 old_min_ = min_.Value();
2456 old_max_ = max_.Value();
2457 if (min_.Value() < new_min_) {
2460 if (max_.Value() > new_max_) {
2463 if (bits_ !=
nullptr) {
2464 bits_->ApplyRemovedValues(
this);
2468template <
typename T>
2469T* CondRevAlloc(Solver* solver,
bool reversible, T*
object) {
2470 return reversible ? solver->RevAlloc(
object) : object;
2473IntVarIterator* DomainIntVar::MakeHoleIterator(
bool reversible)
const {
2474 return CondRevAlloc(solver(), reversible,
new DomainIntVarHoleIterator(
this));
2477IntVarIterator* DomainIntVar::MakeDomainIterator(
bool reversible)
const {
2478 return CondRevAlloc(solver(), reversible,
2479 new DomainIntVarDomainIterator(
this, reversible));
2482std::string DomainIntVar::DebugString()
const {
2484 const std::string& var_name = name();
2485 if (!var_name.empty()) {
2486 out = var_name +
"(";
2488 out =
"DomainIntVar(";
2490 if (min_.Value() == max_.Value()) {
2491 absl::StrAppendFormat(&out,
"%d", min_.Value());
2492 }
else if (bits_ !=
nullptr) {
2493 out.append(bits_->pretty_DebugString(min_.Value(), max_.Value()));
2495 absl::StrAppendFormat(&out,
"%d..%d", min_.Value(), max_.Value());
2503class ConcreteBooleanVar :
public BooleanVar {
2506 class Handler :
public Demon {
2508 explicit Handler(ConcreteBooleanVar*
const var) : Demon(), var_(var) {}
2509 ~Handler()
override {}
2510 void Run(Solver*
const s)
override {
2511 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
2513 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
2515 Solver::DemonPriority priority()
const override {
2516 return Solver::VAR_PRIORITY;
2518 std::string DebugString()
const override {
2519 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
2523 ConcreteBooleanVar*
const var_;
2526 ConcreteBooleanVar(Solver*
const s,
const std::string& name)
2527 : BooleanVar(s, name), handler_(this) {}
2529 ~ConcreteBooleanVar()
override {}
2531 void SetValue(int64_t v)
override {
2532 if (value_ == kUnboundBooleanVarValue) {
2533 if ((v & 0xfffffffffffffffe) == 0) {
2535 value_ =
static_cast<int>(v);
2536 EnqueueVar(&handler_);
2539 }
else if (v == value_) {
2546 DCHECK_NE(value_, kUnboundBooleanVarValue);
2547 ExecuteAll(bound_demons_);
2548 for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_); it.ok();
2550 EnqueueDelayedDemon(*it);
2554 int64_t OldMin()
const override {
return 0LL; }
2555 int64_t OldMax()
const override {
return 1LL; }
2556 void RestoreValue()
override { value_ = kUnboundBooleanVarValue; }
2564class IntConst :
public IntVar {
2566 IntConst(Solver*
const s, int64_t value,
const std::string& name =
"")
2567 : IntVar(s, name), value_(value) {}
2568 ~IntConst()
override {}
2570 int64_t Min()
const override {
return value_; }
2571 void SetMin(int64_t m)
override {
2576 int64_t Max()
const override {
return value_; }
2577 void SetMax(int64_t m)
override {
2582 void SetRange(int64_t l, int64_t u)
override {
2583 if (l > value_ || u < value_) {
2587 void SetValue(int64_t v)
override {
2592 bool Bound()
const override {
return true; }
2593 int64_t
Value()
const override {
return value_; }
2594 void RemoveValue(int64_t v)
override {
2599 void RemoveInterval(int64_t l, int64_t u)
override {
2600 if (l <= value_ && value_ <= u) {
2604 void WhenBound(Demon* d)
override {}
2605 void WhenRange(Demon* d)
override {}
2606 void WhenDomain(Demon* d)
override {}
2607 uint64_t Size()
const override {
return 1; }
2608 bool Contains(int64_t v)
const override {
return (v == value_); }
2609 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2610 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
2612 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2613 return CondRevAlloc(solver(), reversible,
new RangeIterator(
this));
2615 int64_t OldMin()
const override {
return value_; }
2616 int64_t OldMax()
const override {
return value_; }
2617 std::string DebugString()
const override {
2619 if (solver()->HasName(
this)) {
2620 const std::string& var_name = name();
2621 absl::StrAppendFormat(&out,
"%s(%d)", var_name, value_);
2623 absl::StrAppendFormat(&out,
"IntConst(%d)", value_);
2628 int VarType()
const override {
return CONST_VAR; }
2630 IntVar* IsEqual(int64_t constant)
override {
2631 if (constant == value_) {
2632 return solver()->MakeIntConst(1);
2634 return solver()->MakeIntConst(0);
2638 IntVar* IsDifferent(int64_t constant)
override {
2639 if (constant == value_) {
2640 return solver()->MakeIntConst(0);
2642 return solver()->MakeIntConst(1);
2646 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2647 return solver()->MakeIntConst(value_ >= constant);
2650 IntVar* IsLessOrEqual(int64_t constant)
override {
2651 return solver()->MakeIntConst(value_ <= constant);
2654 std::string name()
const override {
2655 if (solver()->HasName(
this)) {
2656 return PropagationBaseObject::name();
2658 return absl::StrCat(value_);
2668class PlusCstVar :
public IntVar {
2670 PlusCstVar(Solver*
const s, IntVar* v, int64_t c)
2671 : IntVar(s), var_(v), cst_(
c) {}
2673 ~PlusCstVar()
override {}
2675 void WhenRange(Demon* d)
override { var_->
WhenRange(d); }
2677 void WhenBound(Demon* d)
override { var_->
WhenBound(d); }
2679 void WhenDomain(Demon* d)
override { var_->
WhenDomain(d); }
2681 int64_t OldMin()
const override {
return CapAdd(var_->
OldMin(), cst_); }
2683 int64_t OldMax()
const override {
return CapAdd(var_->
OldMax(), cst_); }
2685 std::string DebugString()
const override {
2687 return absl::StrFormat(
"%s(%s + %d)", name(), var_->
DebugString(), cst_);
2689 return absl::StrFormat(
"(%s + %d)", var_->
DebugString(), cst_);
2693 int VarType()
const override {
return VAR_ADD_CST; }
2695 void Accept(ModelVisitor*
const visitor)
const override {
2696 visitor->VisitIntegerVariable(
this, ModelVisitor::kSumOperation, cst_,
2700 IntVar* IsEqual(int64_t constant)
override {
2701 return var_->
IsEqual(constant - cst_);
2704 IntVar* IsDifferent(int64_t constant)
override {
2708 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2712 IntVar* IsLessOrEqual(int64_t constant)
override {
2716 IntVar* SubVar()
const {
return var_; }
2718 int64_t Constant()
const {
return cst_; }
2725class PlusCstIntVar :
public PlusCstVar {
2727 class PlusCstIntVarIterator :
public UnaryIterator {
2729 PlusCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2730 : UnaryIterator(v, hole, rev), cst_(
c) {}
2732 ~PlusCstIntVarIterator()
override {}
2734 int64_t
Value()
const override {
return iterator_->Value() + cst_; }
2740 PlusCstIntVar(Solver*
const s, IntVar* v, int64_t c) : PlusCstVar(s, v,
c) {}
2742 ~PlusCstIntVar()
override {}
2744 int64_t Min()
const override {
return var_->Min() + cst_; }
2746 void SetMin(int64_t m)
override { var_->SetMin(
CapSub(m, cst_)); }
2748 int64_t Max()
const override {
return var_->Max() + cst_; }
2750 void SetMax(int64_t m)
override { var_->SetMax(
CapSub(m, cst_)); }
2752 void SetRange(int64_t l, int64_t u)
override {
2756 void SetValue(int64_t v)
override { var_->SetValue(v - cst_); }
2758 int64_t
Value()
const override {
return var_->Value() + cst_; }
2760 bool Bound()
const override {
return var_->Bound(); }
2762 void RemoveValue(int64_t v)
override { var_->RemoveValue(v - cst_); }
2764 void RemoveInterval(int64_t l, int64_t u)
override {
2765 var_->RemoveInterval(l - cst_, u - cst_);
2768 uint64_t Size()
const override {
return var_->Size(); }
2770 bool Contains(int64_t v)
const override {
return var_->Contains(v - cst_); }
2772 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2773 return CondRevAlloc(
2774 solver(), reversible,
2775 new PlusCstIntVarIterator(var_, cst_,
true, reversible));
2777 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2778 return CondRevAlloc(
2779 solver(), reversible,
2780 new PlusCstIntVarIterator(var_, cst_,
false, reversible));
2784class PlusCstDomainIntVar :
public PlusCstVar {
2786 class PlusCstDomainIntVarIterator :
public UnaryIterator {
2788 PlusCstDomainIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
2790 : UnaryIterator(v, hole, reversible), cst_(
c) {}
2792 ~PlusCstDomainIntVarIterator()
override {}
2794 int64_t
Value()
const override {
return iterator_->Value() + cst_; }
2800 PlusCstDomainIntVar(Solver*
const s, DomainIntVar* v, int64_t c)
2801 : PlusCstVar(s, v,
c) {}
2803 ~PlusCstDomainIntVar()
override {}
2805 int64_t Min()
const override;
2806 void SetMin(int64_t m)
override;
2807 int64_t Max()
const override;
2808 void SetMax(int64_t m)
override;
2809 void SetRange(int64_t l, int64_t u)
override;
2810 void SetValue(int64_t v)
override;
2811 bool Bound()
const override;
2812 int64_t
Value()
const override;
2813 void RemoveValue(int64_t v)
override;
2814 void RemoveInterval(int64_t l, int64_t u)
override;
2815 uint64_t Size()
const override;
2816 bool Contains(int64_t v)
const override;
2818 DomainIntVar* domain_int_var()
const {
2819 return reinterpret_cast<DomainIntVar*
>(var_);
2822 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2823 return CondRevAlloc(
2824 solver(), reversible,
2825 new PlusCstDomainIntVarIterator(var_, cst_,
true, reversible));
2827 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2828 return CondRevAlloc(
2829 solver(), reversible,
2830 new PlusCstDomainIntVarIterator(var_, cst_,
false, reversible));
2834int64_t PlusCstDomainIntVar::Min()
const {
2835 return domain_int_var()->min_.Value() + cst_;
2838void PlusCstDomainIntVar::SetMin(int64_t m) {
2839 domain_int_var()->DomainIntVar::SetMin(
CapSub(m, cst_));
2842int64_t PlusCstDomainIntVar::Max()
const {
2843 return domain_int_var()->max_.Value() + cst_;
2846void PlusCstDomainIntVar::SetMax(int64_t m) {
2847 domain_int_var()->DomainIntVar::SetMax(
CapSub(m, cst_));
2850void PlusCstDomainIntVar::SetRange(int64_t l, int64_t u) {
2851 domain_int_var()->DomainIntVar::SetRange(l - cst_, u - cst_);
2854void PlusCstDomainIntVar::SetValue(int64_t v) {
2855 domain_int_var()->DomainIntVar::SetValue(v - cst_);
2858bool PlusCstDomainIntVar::Bound()
const {
2859 return domain_int_var()->min_.Value() == domain_int_var()->max_.Value();
2862int64_t PlusCstDomainIntVar::Value()
const {
2863 CHECK_EQ(domain_int_var()->min_.Value(), domain_int_var()->max_.Value())
2864 <<
" variable is not bound";
2865 return domain_int_var()->min_.Value() + cst_;
2868void PlusCstDomainIntVar::RemoveValue(int64_t v) {
2869 domain_int_var()->DomainIntVar::RemoveValue(v - cst_);
2872void PlusCstDomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2873 domain_int_var()->DomainIntVar::RemoveInterval(l - cst_, u - cst_);
2876uint64_t PlusCstDomainIntVar::Size()
const {
2877 return domain_int_var()->DomainIntVar::Size();
2880bool PlusCstDomainIntVar::Contains(int64_t v)
const {
2881 return domain_int_var()->DomainIntVar::Contains(v - cst_);
2886class SubCstIntVar :
public IntVar {
2888 class SubCstIntVarIterator :
public UnaryIterator {
2890 SubCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2891 : UnaryIterator(v, hole, rev), cst_(
c) {}
2892 ~SubCstIntVarIterator()
override {}
2894 int64_t
Value()
const override {
return cst_ - iterator_->Value(); }
2900 SubCstIntVar(Solver* s, IntVar* v, int64_t c);
2901 ~SubCstIntVar()
override;
2903 int64_t Min()
const override;
2904 void SetMin(int64_t m)
override;
2905 int64_t Max()
const override;
2906 void SetMax(int64_t m)
override;
2907 void SetRange(int64_t l, int64_t u)
override;
2908 void SetValue(int64_t v)
override;
2909 bool Bound()
const override;
2910 int64_t
Value()
const override;
2911 void RemoveValue(int64_t v)
override;
2912 void RemoveInterval(int64_t l, int64_t u)
override;
2913 uint64_t Size()
const override;
2914 bool Contains(int64_t v)
const override;
2915 void WhenRange(Demon* d)
override;
2916 void WhenBound(Demon* d)
override;
2917 void WhenDomain(Demon* d)
override;
2918 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2919 return CondRevAlloc(solver(), reversible,
2920 new SubCstIntVarIterator(var_, cst_,
true, reversible));
2922 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2923 return CondRevAlloc(
2924 solver(), reversible,
2925 new SubCstIntVarIterator(var_, cst_,
false, reversible));
2927 int64_t OldMin()
const override {
return CapSub(cst_, var_->
OldMax()); }
2928 int64_t OldMax()
const override {
return CapSub(cst_, var_->
OldMin()); }
2929 std::string DebugString()
const override;
2930 std::string name()
const override;
2931 int VarType()
const override {
return CST_SUB_VAR; }
2933 void Accept(ModelVisitor*
const visitor)
const override {
2934 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation,
2938 IntVar* IsEqual(int64_t constant)
override {
2939 return var_->
IsEqual(cst_ - constant);
2942 IntVar* IsDifferent(int64_t constant)
override {
2946 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2950 IntVar* IsLessOrEqual(int64_t constant)
override {
2954 IntVar* SubVar()
const {
return var_; }
2955 int64_t Constant()
const {
return cst_; }
2962SubCstIntVar::SubCstIntVar(Solver*
const s, IntVar* v, int64_t c)
2963 : IntVar(s), var_(v), cst_(
c) {}
2965SubCstIntVar::~SubCstIntVar() {}
2967int64_t SubCstIntVar::Min()
const {
return cst_ - var_->
Max(); }
2969void SubCstIntVar::SetMin(int64_t m) { var_->
SetMax(
CapSub(cst_, m)); }
2971int64_t SubCstIntVar::Max()
const {
return cst_ - var_->
Min(); }
2973void SubCstIntVar::SetMax(int64_t m) { var_->
SetMin(
CapSub(cst_, m)); }
2975void SubCstIntVar::SetRange(int64_t l, int64_t u) {
2979void SubCstIntVar::SetValue(int64_t v) { var_->
SetValue(cst_ - v); }
2981bool SubCstIntVar::Bound()
const {
return var_->
Bound(); }
2983void SubCstIntVar::WhenRange(Demon* d) { var_->
WhenRange(d); }
2985int64_t SubCstIntVar::Value()
const {
return cst_ - var_->
Value(); }
2987void SubCstIntVar::RemoveValue(int64_t v) { var_->
RemoveValue(cst_ - v); }
2989void SubCstIntVar::RemoveInterval(int64_t l, int64_t u) {
2993void SubCstIntVar::WhenBound(Demon* d) { var_->
WhenBound(d); }
2995void SubCstIntVar::WhenDomain(Demon* d) { var_->
WhenDomain(d); }
2997uint64_t SubCstIntVar::Size()
const {
return var_->
Size(); }
2999bool SubCstIntVar::Contains(int64_t v)
const {
3003std::string SubCstIntVar::DebugString()
const {
3004 if (cst_ == 1 && var_->
VarType() == BOOLEAN_VAR) {
3005 return absl::StrFormat(
"Not(%s)", var_->
DebugString());
3007 return absl::StrFormat(
"(%d - %s)", cst_, var_->
DebugString());
3011std::string SubCstIntVar::name()
const {
3012 if (solver()->HasName(
this)) {
3013 return PropagationBaseObject::name();
3014 }
else if (cst_ == 1 && var_->
VarType() == BOOLEAN_VAR) {
3015 return absl::StrFormat(
"Not(%s)", var_->
name());
3017 return absl::StrFormat(
"(%d - %s)", cst_, var_->
name());
3023class OppIntVar :
public IntVar {
3025 class OppIntVarIterator :
public UnaryIterator {
3027 OppIntVarIterator(
const IntVar*
const v,
bool hole,
bool reversible)
3028 : UnaryIterator(v, hole, reversible) {}
3029 ~OppIntVarIterator()
override {}
3031 int64_t
Value()
const override {
return -iterator_->Value(); }
3034 OppIntVar(Solver* s, IntVar* v);
3035 ~OppIntVar()
override;
3037 int64_t Min()
const override;
3038 void SetMin(int64_t m)
override;
3039 int64_t Max()
const override;
3040 void SetMax(int64_t m)
override;
3041 void SetRange(int64_t l, int64_t u)
override;
3042 void SetValue(int64_t v)
override;
3043 bool Bound()
const override;
3044 int64_t
Value()
const override;
3045 void RemoveValue(int64_t v)
override;
3046 void RemoveInterval(int64_t l, int64_t u)
override;
3047 uint64_t Size()
const override;
3048 bool Contains(int64_t v)
const override;
3049 void WhenRange(Demon* d)
override;
3050 void WhenBound(Demon* d)
override;
3051 void WhenDomain(Demon* d)
override;
3052 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3053 return CondRevAlloc(solver(), reversible,
3054 new OppIntVarIterator(var_,
true, reversible));
3056 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3057 return CondRevAlloc(solver(), reversible,
3058 new OppIntVarIterator(var_,
false, reversible));
3060 int64_t OldMin()
const override {
return CapOpp(var_->
OldMax()); }
3061 int64_t OldMax()
const override {
return CapOpp(var_->
OldMin()); }
3062 std::string DebugString()
const override;
3063 int VarType()
const override {
return OPP_VAR; }
3065 void Accept(ModelVisitor*
const visitor)
const override {
3066 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation, 0,
3070 IntVar* IsEqual(int64_t constant)
override {
3071 return var_->
IsEqual(-constant);
3074 IntVar* IsDifferent(int64_t constant)
override {
3078 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3082 IntVar* IsLessOrEqual(int64_t constant)
override {
3086 IntVar* SubVar()
const {
return var_; }
3092OppIntVar::OppIntVar(Solver*
const s, IntVar* v) : IntVar(s), var_(v) {}
3094OppIntVar::~OppIntVar() {}
3096int64_t OppIntVar::Min()
const {
return -var_->
Max(); }
3098void OppIntVar::SetMin(int64_t m) { var_->
SetMax(
CapOpp(m)); }
3100int64_t OppIntVar::Max()
const {
return -var_->
Min(); }
3102void OppIntVar::SetMax(int64_t m) { var_->
SetMin(
CapOpp(m)); }
3104void OppIntVar::SetRange(int64_t l, int64_t u) {
3108void OppIntVar::SetValue(int64_t v) { var_->
SetValue(
CapOpp(v)); }
3110bool OppIntVar::Bound()
const {
return var_->
Bound(); }
3112void OppIntVar::WhenRange(Demon* d) { var_->
WhenRange(d); }
3114int64_t OppIntVar::Value()
const {
return -var_->
Value(); }
3116void OppIntVar::RemoveValue(int64_t v) { var_->
RemoveValue(-v); }
3118void OppIntVar::RemoveInterval(int64_t l, int64_t u) {
3122void OppIntVar::WhenBound(Demon* d) { var_->
WhenBound(d); }
3124void OppIntVar::WhenDomain(Demon* d) { var_->
WhenDomain(d); }
3126uint64_t OppIntVar::Size()
const {
return var_->
Size(); }
3128bool OppIntVar::Contains(int64_t v)
const {
return var_->
Contains(-v); }
3130std::string OppIntVar::DebugString()
const {
3131 return absl::StrFormat(
"-(%s)", var_->
DebugString());
3138class TimesCstIntVar :
public IntVar {
3140 TimesCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3141 : IntVar(s), var_(v), cst_(
c) {}
3142 ~TimesCstIntVar()
override {}
3144 IntVar* SubVar()
const {
return var_; }
3145 int64_t Constant()
const {
return cst_; }
3147 void Accept(ModelVisitor*
const visitor)
const override {
3148 visitor->VisitIntegerVariable(
this, ModelVisitor::kProductOperation, cst_,
3152 IntVar* IsEqual(int64_t constant)
override {
3153 if (constant % cst_ == 0) {
3154 return var_->
IsEqual(constant / cst_);
3156 return solver()->MakeIntConst(0);
3160 IntVar* IsDifferent(int64_t constant)
override {
3161 if (constant % cst_ == 0) {
3164 return solver()->MakeIntConst(1);
3168 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3176 IntVar* IsLessOrEqual(int64_t constant)
override {
3184 std::string DebugString()
const override {
3185 return absl::StrFormat(
"(%s * %d)", var_->
DebugString(), cst_);
3195class TimesPosCstIntVar :
public TimesCstIntVar {
3197 class TimesPosCstIntVarIterator :
public UnaryIterator {
3199 TimesPosCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3201 : UnaryIterator(v, hole, reversible), cst_(
c) {}
3202 ~TimesPosCstIntVarIterator()
override {}
3204 int64_t
Value()
const override {
return iterator_->Value() * cst_; }
3210 TimesPosCstIntVar(Solver* s, IntVar* v, int64_t c);
3211 ~TimesPosCstIntVar()
override;
3213 int64_t Min()
const override;
3214 void SetMin(int64_t m)
override;
3215 int64_t Max()
const override;
3216 void SetMax(int64_t m)
override;
3217 void SetRange(int64_t l, int64_t u)
override;
3218 void SetValue(int64_t v)
override;
3219 bool Bound()
const override;
3220 int64_t
Value()
const override;
3221 void RemoveValue(int64_t v)
override;
3222 void RemoveInterval(int64_t l, int64_t u)
override;
3223 uint64_t Size()
const override;
3224 bool Contains(int64_t v)
const override;
3225 void WhenRange(Demon* d)
override;
3226 void WhenBound(Demon* d)
override;
3227 void WhenDomain(Demon* d)
override;
3228 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3229 return CondRevAlloc(
3230 solver(), reversible,
3231 new TimesPosCstIntVarIterator(var_, cst_,
true, reversible));
3233 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3234 return CondRevAlloc(
3235 solver(), reversible,
3236 new TimesPosCstIntVarIterator(var_, cst_,
false, reversible));
3238 int64_t OldMin()
const override {
return CapProd(var_->OldMin(), cst_); }
3239 int64_t OldMax()
const override {
return CapProd(var_->OldMax(), cst_); }
3244TimesPosCstIntVar::TimesPosCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3245 : TimesCstIntVar(s, v,
c) {}
3247TimesPosCstIntVar::~TimesPosCstIntVar() {}
3249int64_t TimesPosCstIntVar::Min()
const {
return CapProd(var_->Min(), cst_); }
3251void TimesPosCstIntVar::SetMin(int64_t m) {
3252 if (m != std::numeric_limits<int64_t>::min()) {
3257int64_t TimesPosCstIntVar::Max()
const {
return CapProd(var_->Max(), cst_); }
3259void TimesPosCstIntVar::SetMax(int64_t m) {
3260 if (m != std::numeric_limits<int64_t>::max()) {
3265void TimesPosCstIntVar::SetRange(int64_t l, int64_t u) {
3269void TimesPosCstIntVar::SetValue(int64_t v) {
3270 if (v % cst_ != 0) {
3273 var_->SetValue(v / cst_);
3276bool TimesPosCstIntVar::Bound()
const {
return var_->Bound(); }
3278void TimesPosCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3280int64_t TimesPosCstIntVar::Value()
const {
3281 return CapProd(var_->Value(), cst_);
3284void TimesPosCstIntVar::RemoveValue(int64_t v) {
3285 if (v % cst_ == 0) {
3286 var_->RemoveValue(v / cst_);
3290void TimesPosCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3291 for (int64_t v = l; v <= u; ++v) {
3297void TimesPosCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3299void TimesPosCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3301uint64_t TimesPosCstIntVar::Size()
const {
return var_->Size(); }
3303bool TimesPosCstIntVar::Contains(int64_t v)
const {
3304 return (v % cst_ == 0 && var_->Contains(v / cst_));
3309class TimesPosCstBoolVar :
public TimesCstIntVar {
3311 class TimesPosCstBoolVarIterator :
public UnaryIterator {
3314 TimesPosCstBoolVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3316 : UnaryIterator(v, hole, reversible), cst_(
c) {}
3317 ~TimesPosCstBoolVarIterator()
override {}
3319 int64_t
Value()
const override {
return iterator_->Value() * cst_; }
3325 TimesPosCstBoolVar(Solver* s, BooleanVar* v, int64_t c);
3326 ~TimesPosCstBoolVar()
override;
3328 int64_t Min()
const override;
3329 void SetMin(int64_t m)
override;
3330 int64_t Max()
const override;
3331 void SetMax(int64_t m)
override;
3332 void SetRange(int64_t l, int64_t u)
override;
3333 void SetValue(int64_t v)
override;
3334 bool Bound()
const override;
3335 int64_t
Value()
const override;
3336 void RemoveValue(int64_t v)
override;
3337 void RemoveInterval(int64_t l, int64_t u)
override;
3338 uint64_t Size()
const override;
3339 bool Contains(int64_t v)
const override;
3340 void WhenRange(Demon* d)
override;
3341 void WhenBound(Demon* d)
override;
3342 void WhenDomain(Demon* d)
override;
3343 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3344 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
3346 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3347 return CondRevAlloc(
3348 solver(), reversible,
3349 new TimesPosCstBoolVarIterator(boolean_var(), cst_,
false, reversible));
3351 int64_t OldMin()
const override {
return 0; }
3352 int64_t OldMax()
const override {
return cst_; }
3354 BooleanVar* boolean_var()
const {
3355 return reinterpret_cast<BooleanVar*
>(var_);
3361TimesPosCstBoolVar::TimesPosCstBoolVar(Solver*
const s, BooleanVar* v,
3363 : TimesCstIntVar(s, v,
c) {}
3365TimesPosCstBoolVar::~TimesPosCstBoolVar() {}
3367int64_t TimesPosCstBoolVar::Min()
const {
3368 return (boolean_var()->RawValue() == 1) * cst_;
3371void TimesPosCstBoolVar::SetMin(int64_t m) {
3375 boolean_var()->SetMin(1);
3379int64_t TimesPosCstBoolVar::Max()
const {
3380 return (boolean_var()->RawValue() != 0) * cst_;
3383void TimesPosCstBoolVar::SetMax(int64_t m) {
3386 }
else if (m < cst_) {
3387 boolean_var()->SetMax(0);
3391void TimesPosCstBoolVar::SetRange(int64_t l, int64_t u) {
3392 if (u < 0 || l > cst_ || l > u) {
3396 boolean_var()->SetMin(1);
3397 }
else if (u < cst_) {
3398 boolean_var()->SetMax(0);
3402void TimesPosCstBoolVar::SetValue(int64_t v) {
3404 boolean_var()->SetValue(0);
3405 }
else if (v == cst_) {
3406 boolean_var()->SetValue(1);
3412bool TimesPosCstBoolVar::Bound()
const {
3413 return boolean_var()->RawValue() != BooleanVar::kUnboundBooleanVarValue;
3416void TimesPosCstBoolVar::WhenRange(Demon* d) { boolean_var()->WhenRange(d); }
3418int64_t TimesPosCstBoolVar::Value()
const {
3419 CHECK_NE(boolean_var()->RawValue(), BooleanVar::kUnboundBooleanVarValue)
3420 <<
" variable is not bound";
3421 return boolean_var()->RawValue() * cst_;
3424void TimesPosCstBoolVar::RemoveValue(int64_t v) {
3426 boolean_var()->RemoveValue(0);
3427 }
else if (v == cst_) {
3428 boolean_var()->RemoveValue(1);
3432void TimesPosCstBoolVar::RemoveInterval(int64_t l, int64_t u) {
3433 if (l <= 0 && u >= 0) {
3434 boolean_var()->RemoveValue(0);
3436 if (l <= cst_ && u >= cst_) {
3437 boolean_var()->RemoveValue(1);
3441void TimesPosCstBoolVar::WhenBound(Demon* d) { boolean_var()->WhenBound(d); }
3443void TimesPosCstBoolVar::WhenDomain(Demon* d) { boolean_var()->WhenDomain(d); }
3445uint64_t TimesPosCstBoolVar::Size()
const {
3447 (boolean_var()->RawValue() == BooleanVar::kUnboundBooleanVarValue));
3450bool TimesPosCstBoolVar::Contains(int64_t v)
const {
3452 return boolean_var()->RawValue() != 1;
3453 }
else if (v == cst_) {
3454 return boolean_var()->RawValue() != 0;
3461class TimesNegCstIntVar :
public TimesCstIntVar {
3463 class TimesNegCstIntVarIterator :
public UnaryIterator {
3465 TimesNegCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3467 : UnaryIterator(v, hole, reversible), cst_(
c) {}
3468 ~TimesNegCstIntVarIterator()
override {}
3470 int64_t
Value()
const override {
return iterator_->Value() * cst_; }
3476 TimesNegCstIntVar(Solver* s, IntVar* v, int64_t c);
3477 ~TimesNegCstIntVar()
override;
3479 int64_t Min()
const override;
3480 void SetMin(int64_t m)
override;
3481 int64_t Max()
const override;
3482 void SetMax(int64_t m)
override;
3483 void SetRange(int64_t l, int64_t u)
override;
3484 void SetValue(int64_t v)
override;
3485 bool Bound()
const override;
3486 int64_t
Value()
const override;
3487 void RemoveValue(int64_t v)
override;
3488 void RemoveInterval(int64_t l, int64_t u)
override;
3489 uint64_t Size()
const override;
3490 bool Contains(int64_t v)
const override;
3491 void WhenRange(Demon* d)
override;
3492 void WhenBound(Demon* d)
override;
3493 void WhenDomain(Demon* d)
override;
3494 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3495 return CondRevAlloc(
3496 solver(), reversible,
3497 new TimesNegCstIntVarIterator(var_, cst_,
true, reversible));
3499 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3500 return CondRevAlloc(
3501 solver(), reversible,
3502 new TimesNegCstIntVarIterator(var_, cst_,
false, reversible));
3504 int64_t OldMin()
const override {
return CapProd(var_->OldMax(), cst_); }
3505 int64_t OldMax()
const override {
return CapProd(var_->OldMin(), cst_); }
3510TimesNegCstIntVar::TimesNegCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3511 : TimesCstIntVar(s, v,
c) {}
3513TimesNegCstIntVar::~TimesNegCstIntVar() {}
3515int64_t TimesNegCstIntVar::Min()
const {
return CapProd(var_->Max(), cst_); }
3517void TimesNegCstIntVar::SetMin(int64_t m) {
3518 if (m != std::numeric_limits<int64_t>::min()) {
3523int64_t TimesNegCstIntVar::Max()
const {
return CapProd(var_->Min(), cst_); }
3525void TimesNegCstIntVar::SetMax(int64_t m) {
3526 if (m != std::numeric_limits<int64_t>::max()) {
3531void TimesNegCstIntVar::SetRange(int64_t l, int64_t u) {
3536void TimesNegCstIntVar::SetValue(int64_t v) {
3537 if (v % cst_ != 0) {
3540 var_->SetValue(v / cst_);
3543bool TimesNegCstIntVar::Bound()
const {
return var_->Bound(); }
3545void TimesNegCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3547int64_t TimesNegCstIntVar::Value()
const {
3548 return CapProd(var_->Value(), cst_);
3551void TimesNegCstIntVar::RemoveValue(int64_t v) {
3552 if (v % cst_ == 0) {
3553 var_->RemoveValue(v / cst_);
3557void TimesNegCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3558 for (int64_t v = l; v <= u; ++v) {
3564void TimesNegCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3566void TimesNegCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3568uint64_t TimesNegCstIntVar::Size()
const {
return var_->Size(); }
3570bool TimesNegCstIntVar::Contains(int64_t v)
const {
3571 return (v % cst_ == 0 && var_->Contains(v / cst_));
3578class PlusIntExpr :
public BaseIntExpr {
3580 PlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3581 : BaseIntExpr(s), left_(l), right_(r) {}
3583 ~PlusIntExpr()
override {}
3585 int64_t Min()
const override {
return left_->
Min() + right_->
Min(); }
3587 void SetMin(int64_t m)
override {
3588 if (m > left_->
Min() + right_->
Min()) {
3590 if (m > right_->
Max() + left_->
Max()) solver()->Fail();
3596 void SetRange(int64_t l, int64_t u)
override {
3597 const int64_t left_min = left_->
Min();
3598 const int64_t right_min = right_->
Min();
3599 const int64_t left_max = left_->
Max();
3600 const int64_t right_max = right_->
Max();
3601 if (l > left_min + right_min) {
3603 if (l > right_max + left_max) solver()->Fail();
3604 left_->
SetMin(l - right_max);
3605 right_->
SetMin(l - left_max);
3607 if (u < left_max + right_max) {
3609 if (u < right_min + left_min) solver()->Fail();
3610 left_->
SetMax(u - right_min);
3611 right_->
SetMax(u - left_min);
3615 int64_t Max()
const override {
return left_->
Max() + right_->
Max(); }
3617 void SetMax(int64_t m)
override {
3618 if (m < left_->Max() + right_->
Max()) {
3620 if (m < right_->Min() + left_->
Min()) solver()->Fail();
3626 bool Bound()
const override {
return (left_->
Bound() && right_->
Bound()); }
3628 void Range(int64_t*
const mi, int64_t*
const ma)
override {
3629 *mi = left_->
Min() + right_->
Min();
3630 *ma = left_->
Max() + right_->
Max();
3633 std::string name()
const override {
3634 return absl::StrFormat(
"(%s + %s)", left_->
name(), right_->
name());
3637 std::string DebugString()
const override {
3638 return absl::StrFormat(
"(%s + %s)", left_->
DebugString(),
3642 void WhenRange(Demon* d)
override {
3647 void ExpandPlusIntExpr(IntExpr*
const expr, std::vector<IntExpr*>* subs) {
3648 PlusIntExpr*
const casted =
dynamic_cast<PlusIntExpr*
>(expr);
3649 if (casted !=
nullptr) {
3650 ExpandPlusIntExpr(casted->left_, subs);
3651 ExpandPlusIntExpr(casted->right_, subs);
3653 subs->push_back(expr);
3657 IntVar* CastToVar()
override {
3658 if (
dynamic_cast<PlusIntExpr*
>(left_) !=
nullptr ||
3659 dynamic_cast<PlusIntExpr*
>(right_) !=
nullptr) {
3660 std::vector<IntExpr*> sub_exprs;
3661 ExpandPlusIntExpr(left_, &sub_exprs);
3662 ExpandPlusIntExpr(right_, &sub_exprs);
3663 if (sub_exprs.size() >= 3) {
3664 std::vector<IntVar*> sub_vars(sub_exprs.size());
3665 for (
int i = 0;
i < sub_exprs.size(); ++
i) {
3666 sub_vars[
i] = sub_exprs[
i]->Var();
3668 return solver()->MakeSum(sub_vars)->Var();
3671 return BaseIntExpr::CastToVar();
3674 void Accept(ModelVisitor*
const visitor)
const override {
3675 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3676 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3677 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3679 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3683 IntExpr*
const left_;
3684 IntExpr*
const right_;
3687class SafePlusIntExpr :
public BaseIntExpr {
3689 SafePlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3690 : BaseIntExpr(s), left_(l), right_(r) {}
3692 ~SafePlusIntExpr()
override {}
3694 int64_t Min()
const override {
return CapAdd(left_->
Min(), right_->
Min()); }
3696 void SetMin(int64_t m)
override {
3701 void SetRange(int64_t l, int64_t u)
override {
3702 const int64_t left_min = left_->
Min();
3703 const int64_t right_min = right_->
Min();
3704 const int64_t left_max = left_->
Max();
3705 const int64_t right_max = right_->
Max();
3706 if (l >
CapAdd(left_min, right_min)) {
3710 if (u <
CapAdd(left_max, right_max)) {
3716 int64_t Max()
const override {
return CapAdd(left_->
Max(), right_->
Max()); }
3718 void SetMax(int64_t m)
override {
3723 bool Bound()
const override {
return (left_->
Bound() && right_->
Bound()); }
3725 std::string name()
const override {
3726 return absl::StrFormat(
"(%s + %s)", left_->
name(), right_->
name());
3729 std::string DebugString()
const override {
3730 return absl::StrFormat(
"(%s + %s)", left_->
DebugString(),
3734 void WhenRange(Demon* d)
override {
3739 void Accept(ModelVisitor*
const visitor)
const override {
3740 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3741 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3742 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3744 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3748 IntExpr*
const left_;
3749 IntExpr*
const right_;
3754class PlusIntCstExpr :
public BaseIntExpr {
3756 PlusIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3757 : BaseIntExpr(s), expr_(e), value_(v) {}
3758 ~PlusIntCstExpr()
override {}
3759 int64_t Min()
const override {
return CapAdd(expr_->
Min(), value_); }
3760 void SetMin(int64_t m)
override { expr_->
SetMin(
CapSub(m, value_)); }
3761 int64_t Max()
const override {
return CapAdd(expr_->
Max(), value_); }
3762 void SetMax(int64_t m)
override { expr_->
SetMax(
CapSub(m, value_)); }
3763 bool Bound()
const override {
return (expr_->
Bound()); }
3764 std::string name()
const override {
3765 return absl::StrFormat(
"(%s + %d)", expr_->
name(), value_);
3767 std::string DebugString()
const override {
3768 return absl::StrFormat(
"(%s + %d)", expr_->
DebugString(), value_);
3770 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
3771 IntVar* CastToVar()
override;
3772 void Accept(ModelVisitor*
const visitor)
const override {
3773 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3774 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3776 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3777 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3781 IntExpr*
const expr_;
3782 const int64_t value_;
3785IntVar* PlusIntCstExpr::CastToVar() {
3786 Solver*
const s = solver();
3787 IntVar*
const var = expr_->
Var();
3788 IntVar* cast =
nullptr;
3791 return BaseIntExpr::CastToVar();
3793 switch (var->VarType()) {
3795 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstDomainIntVar(
3796 s,
reinterpret_cast<DomainIntVar*
>(var), value_)));
3800 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstIntVar(s, var, value_)));
3808class SubIntExpr :
public BaseIntExpr {
3810 SubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3811 : BaseIntExpr(s), left_(l), right_(r) {}
3813 ~SubIntExpr()
override {}
3815 int64_t Min()
const override {
return left_->
Min() - right_->
Max(); }
3817 void SetMin(int64_t m)
override {
3822 int64_t Max()
const override {
return left_->
Max() - right_->
Min(); }
3824 void SetMax(int64_t m)
override {
3829 void Range(int64_t* mi, int64_t* ma)
override {
3830 *mi = left_->
Min() - right_->
Max();
3831 *ma = left_->
Max() - right_->
Min();
3834 void SetRange(int64_t l, int64_t u)
override {
3835 const int64_t left_min = left_->
Min();
3836 const int64_t right_min = right_->
Min();
3837 const int64_t left_max = left_->
Max();
3838 const int64_t right_max = right_->
Max();
3839 if (l > left_min - right_max) {
3843 if (u < left_max - right_min) {
3849 bool Bound()
const override {
return (left_->
Bound() && right_->
Bound()); }
3851 std::string name()
const override {
3852 return absl::StrFormat(
"(%s - %s)", left_->
name(), right_->
name());
3855 std::string DebugString()
const override {
3856 return absl::StrFormat(
"(%s - %s)", left_->
DebugString(),
3860 void WhenRange(Demon* d)
override {
3865 void Accept(ModelVisitor*
const visitor)
const override {
3866 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3867 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3868 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3870 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3873 IntExpr* left()
const {
return left_; }
3874 IntExpr* right()
const {
return right_; }
3877 IntExpr*
const left_;
3878 IntExpr*
const right_;
3881class SafeSubIntExpr :
public SubIntExpr {
3883 SafeSubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3884 : SubIntExpr(s, l, r) {}
3886 ~SafeSubIntExpr()
override {}
3888 int64_t Min()
const override {
return CapSub(left_->Min(), right_->Max()); }
3890 void SetMin(int64_t m)
override {
3891 left_->SetMin(
CapAdd(m, right_->Min()));
3892 right_->SetMax(
CapSub(left_->Max(), m));
3895 void SetRange(int64_t l, int64_t u)
override {
3896 const int64_t left_min = left_->Min();
3897 const int64_t right_min = right_->Min();
3898 const int64_t left_max = left_->Max();
3899 const int64_t right_max = right_->Max();
3900 if (l >
CapSub(left_min, right_max)) {
3901 left_->SetMin(
CapAdd(l, right_min));
3902 right_->SetMax(
CapSub(left_max, l));
3904 if (u <
CapSub(left_max, right_min)) {
3905 left_->SetMax(
CapAdd(u, right_max));
3906 right_->SetMin(
CapSub(left_min, u));
3910 void Range(int64_t* mi, int64_t* ma)
override {
3911 *mi =
CapSub(left_->Min(), right_->Max());
3912 *ma =
CapSub(left_->Max(), right_->Min());
3915 int64_t Max()
const override {
return CapSub(left_->Max(), right_->Min()); }
3917 void SetMax(int64_t m)
override {
3918 left_->SetMax(
CapAdd(m, right_->Max()));
3919 right_->SetMin(
CapSub(left_->Min(), m));
3927class SubIntCstExpr :
public BaseIntExpr {
3929 SubIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3930 : BaseIntExpr(s), expr_(e), value_(v) {}
3931 ~SubIntCstExpr()
override {}
3932 int64_t Min()
const override {
return CapSub(value_, expr_->
Max()); }
3933 void SetMin(int64_t m)
override { expr_->
SetMax(
CapSub(value_, m)); }
3934 int64_t Max()
const override {
return CapSub(value_, expr_->
Min()); }
3935 void SetMax(int64_t m)
override { expr_->
SetMin(
CapSub(value_, m)); }
3936 bool Bound()
const override {
return (expr_->
Bound()); }
3937 std::string name()
const override {
3938 return absl::StrFormat(
"(%d - %s)", value_, expr_->
name());
3940 std::string DebugString()
const override {
3941 return absl::StrFormat(
"(%d - %s)", value_, expr_->
DebugString());
3943 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
3944 IntVar* CastToVar()
override;
3946 void Accept(ModelVisitor*
const visitor)
const override {
3947 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3948 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3949 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3951 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3955 IntExpr*
const expr_;
3956 const int64_t value_;
3959IntVar* SubIntCstExpr::CastToVar() {
3962 return BaseIntExpr::CastToVar();
3964 Solver*
const s = solver();
3966 s->RegisterIntVar(s->RevAlloc(
new SubCstIntVar(s, expr_->
Var(), value_)));
3972class OppIntExpr :
public BaseIntExpr {
3974 OppIntExpr(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s), expr_(e) {}
3975 ~OppIntExpr()
override {}
3976 int64_t Min()
const override {
return (
CapOpp(expr_->
Max())); }
3977 void SetMin(int64_t m)
override { expr_->
SetMax(
CapOpp(m)); }
3978 int64_t Max()
const override {
return (
CapOpp(expr_->
Min())); }
3979 void SetMax(int64_t m)
override { expr_->
SetMin(
CapOpp(m)); }
3980 bool Bound()
const override {
return (expr_->
Bound()); }
3981 std::string name()
const override {
3982 return absl::StrFormat(
"(-%s)", expr_->
name());
3984 std::string DebugString()
const override {
3985 return absl::StrFormat(
"(-%s)", expr_->
DebugString());
3987 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
3988 IntVar* CastToVar()
override;
3990 void Accept(ModelVisitor*
const visitor)
const override {
3991 visitor->BeginVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3992 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3994 visitor->EndVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3998 IntExpr*
const expr_;
4001IntVar* OppIntExpr::CastToVar() {
4002 Solver*
const s = solver();
4004 s->RegisterIntVar(s->RevAlloc(
new OppIntVar(s, expr_->
Var())));
4010class TimesIntCstExpr :
public BaseIntExpr {
4012 TimesIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4013 : BaseIntExpr(s), expr_(e), value_(v) {}
4015 ~TimesIntCstExpr()
override {}
4017 bool Bound()
const override {
return (expr_->
Bound()); }
4019 std::string name()
const override {
4020 return absl::StrFormat(
"(%s * %d)", expr_->
name(), value_);
4023 std::string DebugString()
const override {
4024 return absl::StrFormat(
"(%s * %d)", expr_->
DebugString(), value_);
4027 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
4029 IntExpr* Expr()
const {
return expr_; }
4031 int64_t Constant()
const {
return value_; }
4033 void Accept(ModelVisitor*
const visitor)
const override {
4034 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4035 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4037 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4038 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4042 IntExpr*
const expr_;
4043 const int64_t value_;
4048class TimesPosIntCstExpr :
public TimesIntCstExpr {
4050 TimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4051 : TimesIntCstExpr(s, e, v) {
4055 ~TimesPosIntCstExpr()
override {}
4057 int64_t Min()
const override {
return expr_->Min() * value_; }
4059 void SetMin(int64_t m)
override { expr_->SetMin(
PosIntDivUp(m, value_)); }
4061 int64_t Max()
const override {
return expr_->Max() * value_; }
4063 void SetMax(int64_t m)
override { expr_->SetMax(
PosIntDivDown(m, value_)); }
4065 IntVar* CastToVar()
override {
4066 Solver*
const s = solver();
4067 IntVar* var =
nullptr;
4068 if (expr_->IsVar() &&
4069 reinterpret_cast<IntVar*
>(expr_)->VarType() == BOOLEAN_VAR) {
4070 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4071 s,
reinterpret_cast<BooleanVar*
>(expr_), value_)));
4073 var = s->RegisterIntVar(
4074 s->RevAlloc(
new TimesPosCstIntVar(s, expr_->Var(), value_)));
4082class SafeTimesPosIntCstExpr :
public TimesIntCstExpr {
4084 SafeTimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4085 : TimesIntCstExpr(s, e, v) {
4089 ~SafeTimesPosIntCstExpr()
override {}
4091 int64_t Min()
const override {
return CapProd(expr_->Min(), value_); }
4093 void SetMin(int64_t m)
override {
4094 if (m != std::numeric_limits<int64_t>::min()) {
4099 int64_t Max()
const override {
return CapProd(expr_->Max(), value_); }
4101 void SetMax(int64_t m)
override {
4102 if (m != std::numeric_limits<int64_t>::max()) {
4107 IntVar* CastToVar()
override {
4108 Solver*
const s = solver();
4109 IntVar* var =
nullptr;
4110 if (expr_->IsVar() &&
4111 reinterpret_cast<IntVar*
>(expr_)->VarType() == BOOLEAN_VAR) {
4112 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4113 s,
reinterpret_cast<BooleanVar*
>(expr_), value_)));
4116 var = s->RegisterIntVar(
4117 s->RevAlloc(
new TimesPosCstIntVar(s, expr_->Var(), value_)));
4125class TimesIntNegCstExpr :
public TimesIntCstExpr {
4127 TimesIntNegCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4128 : TimesIntCstExpr(s, e, v) {
4132 ~TimesIntNegCstExpr()
override {}
4134 int64_t Min()
const override {
return CapProd(expr_->Max(), value_); }
4136 void SetMin(int64_t m)
override {
4137 if (m != std::numeric_limits<int64_t>::min()) {
4142 int64_t Max()
const override {
return CapProd(expr_->Min(), value_); }
4144 void SetMax(int64_t m)
override {
4145 if (m != std::numeric_limits<int64_t>::max()) {
4150 IntVar* CastToVar()
override {
4151 Solver*
const s = solver();
4152 IntVar* var =
nullptr;
4153 var = s->RegisterIntVar(
4154 s->RevAlloc(
new TimesNegCstIntVar(s, expr_->Var(), value_)));
4162void SetPosPosMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4163 DCHECK_GE(left->Min(), 0);
4164 DCHECK_GE(right->Min(), 0);
4165 const int64_t lmax = left->Max();
4166 const int64_t rmax = right->Max();
4167 if (m >
CapProd(lmax, rmax)) {
4168 left->solver()->Fail();
4170 if (m >
CapProd(left->Min(), right->Min())) {
4182void SetPosPosMaxExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4183 DCHECK_GE(left->Min(), 0);
4184 DCHECK_GE(right->Min(), 0);
4185 const int64_t lmin = left->Min();
4186 const int64_t rmin = right->Min();
4187 if (m <
CapProd(lmin, rmin)) {
4188 left->solver()->Fail();
4190 if (m <
CapProd(left->Max(), right->Max())) {
4202void SetPosGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4203 DCHECK_GE(left->Min(), 0);
4204 DCHECK_GT(right->Max(), 0);
4205 DCHECK_LT(right->Min(), 0);
4206 const int64_t lmax = left->Max();
4207 const int64_t rmax = right->Max();
4208 if (m >
CapProd(lmax, rmax)) {
4209 left->solver()->Fail();
4211 if (left->Max() == 0) {
4212 DCHECK_EQ(0, left->Min());
4218 }
else if (m == 0) {
4219 const int64_t lmin = left->Min();
4224 const int64_t lmin = left->Min();
4233void SetGenGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4234 DCHECK_LT(left->Min(), 0);
4235 DCHECK_GT(left->Max(), 0);
4236 DCHECK_GT(right->Max(), 0);
4237 DCHECK_LT(right->Min(), 0);
4238 const int64_t lmin = left->Min();
4239 const int64_t lmax = left->Max();
4240 const int64_t rmin = right->Min();
4241 const int64_t rmax = right->Max();
4243 left->solver()->Fail();
4249 }
else if (m >
CapProd(lmax, rmax)) {
4255void TimesSetMin(IntExpr*
const left, IntExpr*
const right,
4256 IntExpr*
const minus_left, IntExpr*
const minus_right,
4258 if (left->Min() >= 0) {
4259 if (right->Min() >= 0) {
4260 SetPosPosMinExpr(left, right, m);
4261 }
else if (right->Max() <= 0) {
4262 SetPosPosMaxExpr(left, minus_right, -m);
4264 SetPosGenMinExpr(left, right, m);
4266 }
else if (left->Max() <= 0) {
4267 if (right->Min() >= 0) {
4268 SetPosPosMaxExpr(right, minus_left, -m);
4269 }
else if (right->Max() <= 0) {
4270 SetPosPosMinExpr(minus_left, minus_right, m);
4272 SetPosGenMinExpr(minus_left, minus_right, m);
4274 }
else if (right->Min() >= 0) {
4275 SetPosGenMinExpr(right, left, m);
4276 }
else if (right->Max() <= 0) {
4277 SetPosGenMinExpr(minus_right, minus_left, m);
4280 SetGenGenMinExpr(left, right, m);
4284class TimesIntExpr :
public BaseIntExpr {
4286 TimesIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4290 minus_left_(s->MakeOpposite(left_)),
4291 minus_right_(s->MakeOpposite(right_)) {}
4292 ~TimesIntExpr()
override {}
4293 int64_t Min()
const override {
4294 const int64_t lmin = left_->
Min();
4295 const int64_t lmax = left_->
Max();
4296 const int64_t rmin = right_->
Min();
4297 const int64_t rmax = right_->
Max();
4298 return std::min(std::min(
CapProd(lmin, rmin),
CapProd(lmax, rmax)),
4301 void SetMin(int64_t m)
override;
4302 int64_t Max()
const override {
4303 const int64_t lmin = left_->
Min();
4304 const int64_t lmax = left_->
Max();
4305 const int64_t rmin = right_->
Min();
4306 const int64_t rmax = right_->
Max();
4307 return std::max(std::max(
CapProd(lmin, rmin),
CapProd(lmax, rmax)),
4310 void SetMax(int64_t m)
override;
4311 bool Bound()
const override;
4312 std::string name()
const override {
4313 return absl::StrFormat(
"(%s * %s)", left_->
name(), right_->
name());
4315 std::string DebugString()
const override {
4316 return absl::StrFormat(
"(%s * %s)", left_->
DebugString(),
4319 void WhenRange(Demon* d)
override {
4324 void Accept(ModelVisitor*
const visitor)
const override {
4325 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4326 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4327 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4329 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4333 IntExpr*
const left_;
4334 IntExpr*
const right_;
4335 IntExpr*
const minus_left_;
4336 IntExpr*
const minus_right_;
4339void TimesIntExpr::SetMin(int64_t m) {
4340 if (m != std::numeric_limits<int64_t>::min()) {
4341 TimesSetMin(left_, right_, minus_left_, minus_right_, m);
4345void TimesIntExpr::SetMax(int64_t m) {
4346 if (m != std::numeric_limits<int64_t>::max()) {
4347 TimesSetMin(left_, minus_right_, minus_left_, right_,
CapOpp(m));
4351bool TimesIntExpr::Bound()
const {
4352 const bool left_bound = left_->
Bound();
4353 const bool right_bound = right_->
Bound();
4354 return ((left_bound && left_->
Max() == 0) ||
4355 (right_bound && right_->
Max() == 0) || (left_bound && right_bound));
4360class TimesPosIntExpr :
public BaseIntExpr {
4362 TimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4363 : BaseIntExpr(s), left_(l), right_(r) {}
4364 ~TimesPosIntExpr()
override {}
4365 int64_t Min()
const override {
return (left_->
Min() * right_->
Min()); }
4366 void SetMin(int64_t m)
override;
4367 int64_t Max()
const override {
return (left_->
Max() * right_->
Max()); }
4368 void SetMax(int64_t m)
override;
4369 bool Bound()
const override;
4370 std::string name()
const override {
4371 return absl::StrFormat(
"(%s * %s)", left_->
name(), right_->
name());
4373 std::string DebugString()
const override {
4374 return absl::StrFormat(
"(%s * %s)", left_->
DebugString(),
4377 void WhenRange(Demon* d)
override {
4382 void Accept(ModelVisitor*
const visitor)
const override {
4383 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4384 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4385 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4387 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4391 IntExpr*
const left_;
4392 IntExpr*
const right_;
4395void TimesPosIntExpr::SetMin(int64_t m) { SetPosPosMinExpr(left_, right_, m); }
4397void TimesPosIntExpr::SetMax(int64_t m) { SetPosPosMaxExpr(left_, right_, m); }
4399bool TimesPosIntExpr::Bound()
const {
4400 return (left_->
Max() == 0 || right_->
Max() == 0 ||
4406class SafeTimesPosIntExpr :
public BaseIntExpr {
4408 SafeTimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4409 : BaseIntExpr(s), left_(l), right_(r) {}
4410 ~SafeTimesPosIntExpr()
override {}
4411 int64_t Min()
const override {
return CapProd(left_->
Min(), right_->
Min()); }
4412 void SetMin(int64_t m)
override {
4413 if (m != std::numeric_limits<int64_t>::min()) {
4414 SetPosPosMinExpr(left_, right_, m);
4417 int64_t Max()
const override {
return CapProd(left_->
Max(), right_->
Max()); }
4418 void SetMax(int64_t m)
override {
4419 if (m != std::numeric_limits<int64_t>::max()) {
4420 SetPosPosMaxExpr(left_, right_, m);
4423 bool Bound()
const override {
4424 return (left_->
Max() == 0 || right_->
Max() == 0 ||
4427 std::string name()
const override {
4428 return absl::StrFormat(
"(%s * %s)", left_->
name(), right_->
name());
4430 std::string DebugString()
const override {
4431 return absl::StrFormat(
"(%s * %s)", left_->
DebugString(),
4434 void WhenRange(Demon* d)
override {
4439 void Accept(ModelVisitor*
const visitor)
const override {
4440 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4441 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4442 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4444 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4448 IntExpr*
const left_;
4449 IntExpr*
const right_;
4454class TimesBooleanPosIntExpr :
public BaseIntExpr {
4456 TimesBooleanPosIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4457 : BaseIntExpr(s), boolvar_(
b), expr_(e) {}
4458 ~TimesBooleanPosIntExpr()
override {}
4459 int64_t Min()
const override {
4460 return (boolvar_->
RawValue() == 1 ? expr_->
Min() : 0);
4462 void SetMin(int64_t m)
override;
4463 int64_t Max()
const override {
4464 return (boolvar_->
RawValue() == 0 ? 0 : expr_->
Max());
4466 void SetMax(int64_t m)
override;
4467 void Range(int64_t* mi, int64_t* ma)
override;
4468 void SetRange(int64_t mi, int64_t ma)
override;
4469 bool Bound()
const override;
4470 std::string name()
const override {
4471 return absl::StrFormat(
"(%s * %s)", boolvar_->
name(), expr_->
name());
4473 std::string DebugString()
const override {
4474 return absl::StrFormat(
"(%s * %s)", boolvar_->
DebugString(),
4477 void WhenRange(Demon* d)
override {
4482 void Accept(ModelVisitor*
const visitor)
const override {
4483 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4484 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4486 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4488 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4492 BooleanVar*
const boolvar_;
4493 IntExpr*
const expr_;
4496void TimesBooleanPosIntExpr::SetMin(int64_t m) {
4503void TimesBooleanPosIntExpr::SetMax(int64_t m) {
4507 if (m < expr_->Min()) {
4515void TimesBooleanPosIntExpr::Range(int64_t* mi, int64_t* ma) {
4516 const int value = boolvar_->
RawValue();
4520 }
else if (value == 1) {
4521 expr_->
Range(mi, ma);
4528void TimesBooleanPosIntExpr::SetRange(int64_t mi, int64_t ma) {
4529 if (ma < 0 || mi > ma) {
4536 if (ma < expr_->Min()) {
4544bool TimesBooleanPosIntExpr::Bound()
const {
4545 return (boolvar_->
RawValue() == 0 || expr_->
Max() == 0 ||
4546 (boolvar_->
RawValue() != BooleanVar::kUnboundBooleanVarValue &&
4552class TimesBooleanIntExpr :
public BaseIntExpr {
4554 TimesBooleanIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4555 : BaseIntExpr(s), boolvar_(
b), expr_(e) {}
4556 ~TimesBooleanIntExpr()
override {}
4557 int64_t Min()
const override {
4563 return expr_->
Min();
4566 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4567 return std::min(int64_t{0}, expr_->
Min());
4571 void SetMin(int64_t m)
override;
4572 int64_t Max()
const override {
4578 return expr_->
Max();
4581 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4582 return std::max(int64_t{0}, expr_->
Max());
4586 void SetMax(int64_t m)
override;
4587 void Range(int64_t* mi, int64_t* ma)
override;
4588 void SetRange(int64_t mi, int64_t ma)
override;
4589 bool Bound()
const override;
4590 std::string name()
const override {
4591 return absl::StrFormat(
"(%s * %s)", boolvar_->
name(), expr_->
name());
4593 std::string DebugString()
const override {
4594 return absl::StrFormat(
"(%s * %s)", boolvar_->
DebugString(),
4597 void WhenRange(Demon* d)
override {
4602 void Accept(ModelVisitor*
const visitor)
const override {
4603 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4604 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4606 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4608 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4612 BooleanVar*
const boolvar_;
4613 IntExpr*
const expr_;
4616void TimesBooleanIntExpr::SetMin(int64_t m) {
4629 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4633 }
else if (m <= 0 && expr_->Max() < m) {
4640void TimesBooleanIntExpr::SetMax(int64_t m) {
4653 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4657 }
else if (m >= 0 && expr_->
Min() > m) {
4664void TimesBooleanIntExpr::Range(int64_t* mi, int64_t* ma) {
4677 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4678 *mi = std::min(int64_t{0}, expr_->
Min());
4679 *ma = std::max(int64_t{0}, expr_->
Max());
4685void TimesBooleanIntExpr::SetRange(int64_t mi, int64_t ma) {
4691 if (mi > 0 || ma < 0) {
4701 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4705 }
else if (mi == 0 && expr_->
Max() < 0) {
4711 }
else if (ma == 0 && expr_->
Min() > 0) {
4719bool TimesBooleanIntExpr::Bound()
const {
4720 return (boolvar_->
RawValue() == 0 ||
4722 (boolvar_->
RawValue() != BooleanVar::kUnboundBooleanVarValue ||
4723 expr_->
Max() == 0)));
4728class DivPosIntCstExpr :
public BaseIntExpr {
4730 DivPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4731 : BaseIntExpr(s), expr_(e), value_(v) {
4734 ~DivPosIntCstExpr()
override {}
4736 int64_t Min()
const override {
return expr_->
Min() / value_; }
4738 void SetMin(int64_t m)
override {
4740 expr_->
SetMin(m * value_);
4742 expr_->
SetMin((m - 1) * value_ + 1);
4745 int64_t Max()
const override {
return expr_->
Max() / value_; }
4747 void SetMax(int64_t m)
override {
4749 expr_->
SetMax((m + 1) * value_ - 1);
4751 expr_->
SetMax(m * value_);
4755 std::string name()
const override {
4756 return absl::StrFormat(
"(%s div %d)", expr_->
name(), value_);
4759 std::string DebugString()
const override {
4760 return absl::StrFormat(
"(%s div %d)", expr_->
DebugString(), value_);
4763 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
4765 void Accept(ModelVisitor*
const visitor)
const override {
4766 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4767 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4769 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4770 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4774 IntExpr*
const expr_;
4775 const int64_t value_;
4780class DivPosIntExpr :
public BaseIntExpr {
4782 DivPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4786 opp_num_(s->MakeOpposite(num)) {}
4788 ~DivPosIntExpr()
override {}
4790 int64_t Min()
const override {
4791 return num_->
Min() >= 0
4792 ? num_->
Min() / denom_->
Max()
4793 : (denom_->
Min() == 0 ? num_->
Min()
4794 : num_->
Min() / denom_->
Min());
4797 int64_t Max()
const override {
4798 return num_->
Max() >= 0 ? (denom_->
Min() == 0 ? num_->
Max()
4799 : num_->
Max() / denom_->
Min())
4800 : num_->
Max() / denom_->
Max();
4803 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4804 num->SetMin(m * denom->Min());
4805 denom->SetMax(num->Max() / m);
4808 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4809 num->SetMax((m + 1) * denom->Max() - 1);
4810 denom->SetMin(num->Min() / (m + 1) + 1);
4813 void SetMin(int64_t m)
override {
4815 SetPosMin(num_, denom_, m);
4817 SetPosMax(opp_num_, denom_, -m);
4821 void SetMax(int64_t m)
override {
4823 SetPosMax(num_, denom_, m);
4825 SetPosMin(opp_num_, denom_, -m);
4829 std::string name()
const override {
4830 return absl::StrFormat(
"(%s div %s)", num_->
name(), denom_->
name());
4832 std::string DebugString()
const override {
4833 return absl::StrFormat(
"(%s div %s)", num_->
DebugString(),
4836 void WhenRange(Demon* d)
override {
4841 void Accept(ModelVisitor*
const visitor)
const override {
4842 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4843 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4844 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4846 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4850 IntExpr*
const num_;
4851 IntExpr*
const denom_;
4852 IntExpr*
const opp_num_;
4855class DivPosPosIntExpr :
public BaseIntExpr {
4857 DivPosPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4858 : BaseIntExpr(s), num_(num), denom_(denom) {}
4860 ~DivPosPosIntExpr()
override {}
4862 int64_t Min()
const override {
4863 if (denom_->
Max() == 0) {
4866 return num_->
Min() / denom_->
Max();
4869 int64_t Max()
const override {
4870 if (denom_->
Min() == 0) {
4873 return num_->
Max() / denom_->
Min();
4877 void SetMin(int64_t m)
override {
4884 void SetMax(int64_t m)
override {
4886 num_->
SetMax((m + 1) * denom_->
Max() - 1);
4887 denom_->
SetMin(num_->
Min() / (m + 1) + 1);
4893 std::string name()
const override {
4894 return absl::StrFormat(
"(%s div %s)", num_->
name(), denom_->
name());
4897 std::string DebugString()
const override {
4898 return absl::StrFormat(
"(%s div %s)", num_->
DebugString(),
4902 void WhenRange(Demon* d)
override {
4907 void Accept(ModelVisitor*
const visitor)
const override {
4908 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4909 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4910 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4912 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4916 IntExpr*
const num_;
4917 IntExpr*
const denom_;
4922class DivIntExpr :
public BaseIntExpr {
4924 DivIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4928 opp_num_(s->MakeOpposite(num)) {}
4930 ~DivIntExpr()
override {}
4932 int64_t Min()
const override {
4933 const int64_t num_min = num_->
Min();
4934 const int64_t num_max = num_->
Max();
4935 const int64_t denom_min = denom_->
Min();
4936 const int64_t denom_max = denom_->
Max();
4938 if (denom_min == 0 && denom_max == 0) {
4939 return std::numeric_limits<int64_t>::max();
4943 if (denom_min >= 0) {
4944 DCHECK_GT(denom_max, 0);
4945 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4946 return num_min >= 0 ? num_min / denom_max : num_min / adjusted_denom_min;
4947 }
else if (denom_max <= 0) {
4948 DCHECK_LT(denom_min, 0);
4949 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4950 return num_max >= 0 ? num_max / adjusted_denom_max : num_max / denom_min;
4952 return std::min(num_min, -num_max);
4956 int64_t Max()
const override {
4957 const int64_t num_min = num_->
Min();
4958 const int64_t num_max = num_->
Max();
4959 const int64_t denom_min = denom_->
Min();
4960 const int64_t denom_max = denom_->
Max();
4962 if (denom_min == 0 && denom_max == 0) {
4963 return std::numeric_limits<int64_t>::min();
4967 if (denom_min >= 0) {
4968 DCHECK_GT(denom_max, 0);
4969 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4970 return num_max >= 0 ? num_max / adjusted_denom_min : num_max / denom_max;
4971 }
else if (denom_max <= 0) {
4972 DCHECK_LT(denom_min, 0);
4973 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4974 return num_min >= 0 ? num_min / denom_min
4975 : -num_min / -adjusted_denom_max;
4977 return std::max(num_max, -num_min);
4981 void AdjustDenominator() {
4982 if (denom_->
Min() == 0) {
4984 }
else if (denom_->
Max() == 0) {
4990 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4992 const int64_t num_min = num->Min();
4993 const int64_t num_max = num->Max();
4994 const int64_t denom_min = denom->Min();
4995 const int64_t denom_max = denom->Max();
4996 DCHECK_NE(denom_min, 0);
4997 DCHECK_NE(denom_max, 0);
4998 if (denom_min > 0) {
4999 num->SetMin(m * denom_min);
5000 denom->SetMax(num_max / m);
5001 }
else if (denom_max < 0) {
5002 num->SetMax(m * denom_max);
5003 denom->SetMin(num_min / m);
5007 denom->SetRange(1, num_max / m);
5008 }
else if (num_max <= 0) {
5010 denom->SetRange(num_min / m, -1);
5014 denom->SetRange(1, num_max / m);
5015 }
else if (m > num_max) {
5017 denom->SetRange(num_min / m, -1);
5019 denom->SetRange(num_min / m, num_max / m);
5026 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
5028 const int64_t num_min = num->Min();
5029 const int64_t num_max = num->Max();
5030 const int64_t denom_min = denom->Min();
5031 const int64_t denom_max = denom->Max();
5032 DCHECK_NE(denom_min, 0);
5033 DCHECK_NE(denom_max, 0);
5034 if (denom_min > 0) {
5035 num->SetMax((m + 1) * denom_max - 1);
5036 denom->SetMin((num_min / (m + 1)) + 1);
5037 }
else if (denom_max < 0) {
5038 num->SetMin((m + 1) * denom_min + 1);
5039 denom->SetMax(num_max / (m + 1) - 1);
5040 }
else if (num_min > (m + 1) * denom_max - 1) {
5042 }
else if (num_max < (m + 1) * denom_min + 1) {
5047 void SetMin(int64_t m)
override {
5048 AdjustDenominator();
5050 SetPosMin(num_, denom_, m);
5052 SetPosMax(opp_num_, denom_, -m);
5056 void SetMax(int64_t m)
override {
5057 AdjustDenominator();
5059 SetPosMax(num_, denom_, m);
5061 SetPosMin(opp_num_, denom_, -m);
5065 std::string name()
const override {
5066 return absl::StrFormat(
"(%s div %s)", num_->
name(), denom_->
name());
5068 std::string DebugString()
const override {
5069 return absl::StrFormat(
"(%s div %s)", num_->
DebugString(),
5072 void WhenRange(Demon* d)
override {
5077 void Accept(ModelVisitor*
const visitor)
const override {
5078 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
5079 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
5080 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5082 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
5086 IntExpr*
const num_;
5087 IntExpr*
const denom_;
5088 IntExpr*
const opp_num_;
5093class IntAbsConstraint :
public CastConstraint {
5095 IntAbsConstraint(Solver*
const s, IntVar*
const sub, IntVar*
const target)
5096 : CastConstraint(s, target), sub_(sub) {}
5098 ~IntAbsConstraint()
override {}
5100 void Post()
override {
5102 solver(),
this, &IntAbsConstraint::PropagateSub,
"PropagateSub");
5105 solver(),
this, &IntAbsConstraint::PropagateTarget,
"PropagateTarget");
5106 target_var_->WhenRange(target_demon);
5109 void InitialPropagate()
override {
5114 void PropagateSub() {
5115 const int64_t smin = sub_->
Min();
5116 const int64_t smax = sub_->
Max();
5118 target_var_->SetRange(-smax, -smin);
5119 }
else if (smin >= 0) {
5120 target_var_->SetRange(smin, smax);
5122 target_var_->SetRange(0, std::max(-smin, smax));
5126 void PropagateTarget() {
5127 const int64_t target_max = target_var_->Max();
5128 sub_->
SetRange(-target_max, target_max);
5129 const int64_t target_min = target_var_->Min();
5130 if (target_min > 0) {
5131 if (sub_->
Min() > -target_min) {
5132 sub_->
SetMin(target_min);
5133 }
else if (sub_->
Max() < target_min) {
5134 sub_->
SetMax(-target_min);
5139 std::string DebugString()
const override {
5140 return absl::StrFormat(
"IntAbsConstraint(%s, %s)", sub_->
DebugString(),
5141 target_var_->DebugString());
5144 void Accept(ModelVisitor*
const visitor)
const override {
5145 visitor->BeginVisitConstraint(ModelVisitor::kAbsEqual,
this);
5146 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5148 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
5150 visitor->EndVisitConstraint(ModelVisitor::kAbsEqual,
this);
5157class IntAbs :
public BaseIntExpr {
5159 IntAbs(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s), expr_(e) {}
5161 ~IntAbs()
override {}
5163 int64_t Min()
const override {
5166 expr_->
Range(&emin, &emax);
5176 void SetMin(int64_t m)
override {
5180 expr_->
Range(&emin, &emax);
5183 }
else if (emax < m) {
5189 int64_t Max()
const override {
5192 expr_->
Range(&emin, &emax);
5193 return std::max(-emin, emax);
5196 void SetMax(int64_t m)
override { expr_->
SetRange(-m, m); }
5198 void SetRange(int64_t mi, int64_t ma)
override {
5203 expr_->
Range(&emin, &emax);
5206 }
else if (emax < mi) {
5212 void Range(int64_t* mi, int64_t* ma)
override {
5215 expr_->
Range(&emin, &emax);
5219 }
else if (emax <= 0) {
5224 *ma = std::max(-emin, emax);
5228 bool Bound()
const override {
return expr_->
Bound(); }
5230 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5232 std::string name()
const override {
5233 return absl::StrFormat(
"IntAbs(%s)", expr_->
name());
5236 std::string DebugString()
const override {
5237 return absl::StrFormat(
"IntAbs(%s)", expr_->
DebugString());
5240 void Accept(ModelVisitor*
const visitor)
const override {
5241 visitor->BeginVisitIntegerExpression(ModelVisitor::kAbs,
this);
5242 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5244 visitor->EndVisitIntegerExpression(ModelVisitor::kAbs,
this);
5247 IntVar* CastToVar()
override {
5248 int64_t min_value = 0;
5249 int64_t max_value = 0;
5250 Range(&min_value, &max_value);
5251 Solver*
const s = solver();
5252 const std::string name = absl::StrFormat(
"AbsVar(%s)", expr_->
name());
5253 IntVar*
const target = s->MakeIntVar(min_value, max_value, name);
5254 CastConstraint*
const ct =
5255 s->RevAlloc(
new IntAbsConstraint(s, expr_->
Var(), target));
5256 s->AddCastConstraint(ct, target,
this);
5261 IntExpr*
const expr_;
5267class IntSquare :
public BaseIntExpr {
5269 IntSquare(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s), expr_(e) {}
5270 ~IntSquare()
override {}
5272 int64_t Min()
const override {
5273 const int64_t emin = expr_->
Min();
5275 return emin >= std::numeric_limits<int32_t>::max()
5276 ? std::numeric_limits<int64_t>::max()
5279 const int64_t emax = expr_->
Max();
5281 return emax <= -std::numeric_limits<int32_t>::max()
5282 ? std::numeric_limits<int64_t>::max()
5287 void SetMin(int64_t m)
override {
5292 const int64_t emin = expr_->
Min();
5293 const int64_t emax = expr_->
Max();
5294 const int64_t root =
5295 static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5298 }
else if (emax <= 0) {
5300 }
else if (expr_->
IsVar()) {
5301 reinterpret_cast<IntVar*
>(expr_)->RemoveInterval(-root + 1, root - 1);
5304 int64_t Max()
const override {
5305 const int64_t emax = expr_->
Max();
5306 const int64_t emin = expr_->
Min();
5307 if (emax >= std::numeric_limits<int32_t>::max() ||
5308 emin <= -std::numeric_limits<int32_t>::max()) {
5309 return std::numeric_limits<int64_t>::max();
5311 return std::max(emin * emin, emax * emax);
5313 void SetMax(int64_t m)
override {
5317 if (m == std::numeric_limits<int64_t>::max()) {
5320 const int64_t root =
5321 static_cast<int64_t
>(
floor(sqrt(
static_cast<double>(m))));
5324 bool Bound()
const override {
return expr_->
Bound(); }
5325 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5326 std::string name()
const override {
5327 return absl::StrFormat(
"IntSquare(%s)", expr_->
name());
5329 std::string DebugString()
const override {
5330 return absl::StrFormat(
"IntSquare(%s)", expr_->
DebugString());
5333 void Accept(ModelVisitor*
const visitor)
const override {
5334 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare,
this);
5335 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5337 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare,
this);
5340 IntExpr* expr()
const {
return expr_; }
5343 IntExpr*
const expr_;
5346class PosIntSquare :
public IntSquare {
5348 PosIntSquare(Solver*
const s, IntExpr*
const e) : IntSquare(s, e) {}
5349 ~PosIntSquare()
override {}
5351 int64_t Min()
const override {
5352 const int64_t emin = expr_->Min();
5353 return emin >= std::numeric_limits<int32_t>::max()
5354 ? std::numeric_limits<int64_t>::max()
5357 void SetMin(int64_t m)
override {
5361 int64_t root =
static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5362 if (
CapProd(root, root) < m) {
5365 expr_->SetMin(root);
5367 int64_t Max()
const override {
5368 const int64_t emax = expr_->Max();
5369 return emax >= std::numeric_limits<int32_t>::max()
5370 ? std::numeric_limits<int64_t>::max()
5373 void SetMax(int64_t m)
override {
5377 if (m == std::numeric_limits<int64_t>::max()) {
5380 int64_t root =
static_cast<int64_t
>(
floor(sqrt(
static_cast<double>(m))));
5381 if (
CapProd(root, root) > m) {
5385 expr_->SetMax(root);
5391int64_t IntPower(int64_t value, int64_t power) {
5392 int64_t result = value;
5394 for (
int i = 1;
i < power; ++
i) {
5400int64_t OverflowLimit(int64_t power) {
5401 return static_cast<int64_t
>(
floor(exp(
5402 log(
static_cast<double>(std::numeric_limits<int64_t>::max())) / power)));
5405class BasePower :
public BaseIntExpr {
5407 BasePower(Solver*
const s, IntExpr*
const e, int64_t n)
5408 : BaseIntExpr(s), expr_(e), pow_(n), limit_(OverflowLimit(n)) {
5412 ~BasePower()
override {}
5414 bool Bound()
const override {
return expr_->
Bound(); }
5416 IntExpr* expr()
const {
return expr_; }
5418 int64_t exponant()
const {
return pow_; }
5420 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5422 std::string name()
const override {
5423 return absl::StrFormat(
"IntPower(%s, %d)", expr_->
name(), pow_);
5426 std::string DebugString()
const override {
5427 return absl::StrFormat(
"IntPower(%s, %d)", expr_->
DebugString(), pow_);
5430 void Accept(ModelVisitor*
const visitor)
const override {
5431 visitor->BeginVisitIntegerExpression(ModelVisitor::kPower,
this);
5432 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5434 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, pow_);
5435 visitor->EndVisitIntegerExpression(ModelVisitor::kPower,
this);
5439 int64_t Pown(int64_t value)
const {
5440 if (value >= limit_) {
5441 return std::numeric_limits<int64_t>::max();
5443 if (value <= -limit_) {
5444 if (pow_ % 2 == 0) {
5445 return std::numeric_limits<int64_t>::max();
5447 return std::numeric_limits<int64_t>::min();
5450 return IntPower(value, pow_);
5453 int64_t SqrnDown(int64_t value)
const {
5454 if (value == std::numeric_limits<int64_t>::min()) {
5455 return std::numeric_limits<int64_t>::min();
5457 if (value == std::numeric_limits<int64_t>::max()) {
5458 return std::numeric_limits<int64_t>::max();
5461 const double d_value =
static_cast<double>(value);
5463 const double sq = exp(log(d_value) / pow_);
5464 res =
static_cast<int64_t
>(
floor(sq));
5466 CHECK_EQ(1, pow_ % 2);
5467 const double sq = exp(log(-d_value) / pow_);
5468 res = -
static_cast<int64_t
>(ceil(sq));
5470 const int64_t pow_res = Pown(res + 1);
5471 if (pow_res <= value) {
5478 int64_t SqrnUp(int64_t value)
const {
5479 if (value == std::numeric_limits<int64_t>::min()) {
5480 return std::numeric_limits<int64_t>::min();
5482 if (value == std::numeric_limits<int64_t>::max()) {
5483 return std::numeric_limits<int64_t>::max();
5486 const double d_value =
static_cast<double>(value);
5488 const double sq = exp(log(d_value) / pow_);
5489 res =
static_cast<int64_t
>(ceil(sq));
5491 CHECK_EQ(1, pow_ % 2);
5492 const double sq = exp(log(-d_value) / pow_);
5493 res = -
static_cast<int64_t
>(
floor(sq));
5495 const int64_t pow_res = Pown(res - 1);
5496 if (pow_res >= value) {
5503 IntExpr*
const expr_;
5505 const int64_t limit_;
5508class IntEvenPower :
public BasePower {
5510 IntEvenPower(Solver*
const s, IntExpr*
const e, int64_t n)
5511 : BasePower(s, e, n) {
5515 ~IntEvenPower()
override {}
5517 int64_t Min()
const override {
5520 expr_->Range(&emin, &emax);
5529 void SetMin(int64_t m)
override {
5535 expr_->Range(&emin, &emax);
5536 const int64_t root = SqrnUp(m);
5538 expr_->SetMin(root);
5539 }
else if (emax < root) {
5540 expr_->SetMax(-root);
5541 }
else if (expr_->IsVar()) {
5542 reinterpret_cast<IntVar*
>(expr_)->RemoveInterval(-root + 1, root - 1);
5546 int64_t Max()
const override {
5547 return std::max(Pown(expr_->Min()), Pown(expr_->Max()));
5550 void SetMax(int64_t m)
override {
5554 if (m == std::numeric_limits<int64_t>::max()) {
5557 const int64_t root = SqrnDown(m);
5558 expr_->SetRange(-root, root);
5562class PosIntEvenPower :
public BasePower {
5564 PosIntEvenPower(Solver*
const s, IntExpr*
const e, int64_t pow)
5565 : BasePower(s, e, pow) {
5566 CHECK_EQ(0, pow % 2);
5569 ~PosIntEvenPower()
override {}
5571 int64_t Min()
const override {
return Pown(expr_->Min()); }
5573 void SetMin(int64_t m)
override {
5577 expr_->SetMin(SqrnUp(m));
5579 int64_t Max()
const override {
return Pown(expr_->Max()); }
5581 void SetMax(int64_t m)
override {
5585 if (m == std::numeric_limits<int64_t>::max()) {
5588 expr_->SetMax(SqrnDown(m));
5592class IntOddPower :
public BasePower {
5594 IntOddPower(Solver*
const s, IntExpr*
const e, int64_t n)
5595 : BasePower(s, e, n) {
5599 ~IntOddPower()
override {}
5601 int64_t Min()
const override {
return Pown(expr_->Min()); }
5603 void SetMin(int64_t m)
override { expr_->SetMin(SqrnUp(m)); }
5605 int64_t Max()
const override {
return Pown(expr_->Max()); }
5607 void SetMax(int64_t m)
override { expr_->SetMax(SqrnDown(m)); }
5612class MinIntExpr :
public BaseIntExpr {
5614 MinIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5615 : BaseIntExpr(s), left_(l), right_(r) {}
5616 ~MinIntExpr()
override {}
5617 int64_t Min()
const override {
5618 const int64_t lmin = left_->
Min();
5619 const int64_t rmin = right_->
Min();
5620 return std::min(lmin, rmin);
5622 void SetMin(int64_t m)
override {
5626 int64_t Max()
const override {
5627 const int64_t lmax = left_->
Max();
5628 const int64_t rmax = right_->
Max();
5629 return std::min(lmax, rmax);
5631 void SetMax(int64_t m)
override {
5632 if (left_->
Min() > m) {
5635 if (right_->
Min() > m) {
5639 std::string name()
const override {
5640 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->
name(), right_->
name());
5642 std::string DebugString()
const override {
5643 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->
DebugString(),
5646 void WhenRange(Demon* d)
override {
5651 void Accept(ModelVisitor*
const visitor)
const override {
5652 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5653 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5654 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5656 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5660 IntExpr*
const left_;
5661 IntExpr*
const right_;
5666class MinCstIntExpr :
public BaseIntExpr {
5668 MinCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5669 : BaseIntExpr(s), expr_(e), value_(v) {}
5671 ~MinCstIntExpr()
override {}
5673 int64_t Min()
const override {
return std::min(expr_->
Min(), value_); }
5675 void SetMin(int64_t m)
override {
5682 int64_t Max()
const override {
return std::min(expr_->
Max(), value_); }
5684 void SetMax(int64_t m)
override {
5690 bool Bound()
const override {
5691 return (expr_->
Bound() || expr_->
Min() >= value_);
5694 std::string name()
const override {
5695 return absl::StrFormat(
"MinCstIntExpr(%s, %d)", expr_->
name(), value_);
5698 std::string DebugString()
const override {
5699 return absl::StrFormat(
"MinCstIntExpr(%s, %d)", expr_->
DebugString(),
5703 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5705 void Accept(ModelVisitor*
const visitor)
const override {
5706 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5707 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5709 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5710 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5714 IntExpr*
const expr_;
5715 const int64_t value_;
5720class MaxIntExpr :
public BaseIntExpr {
5722 MaxIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5723 : BaseIntExpr(s), left_(l), right_(r) {}
5725 ~MaxIntExpr()
override {}
5727 int64_t Min()
const override {
return std::max(left_->
Min(), right_->
Min()); }
5729 void SetMin(int64_t m)
override {
5730 if (left_->
Max() < m) {
5733 if (right_->
Max() < m) {
5739 int64_t Max()
const override {
return std::max(left_->
Max(), right_->
Max()); }
5741 void SetMax(int64_t m)
override {
5746 std::string name()
const override {
5747 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->
name(), right_->
name());
5750 std::string DebugString()
const override {
5751 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->
DebugString(),
5755 void WhenRange(Demon* d)
override {
5760 void Accept(ModelVisitor*
const visitor)
const override {
5761 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5762 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5763 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5765 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5769 IntExpr*
const left_;
5770 IntExpr*
const right_;
5775class MaxCstIntExpr :
public BaseIntExpr {
5777 MaxCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5778 : BaseIntExpr(s), expr_(e), value_(v) {}
5780 ~MaxCstIntExpr()
override {}
5782 int64_t Min()
const override {
return std::max(expr_->
Min(), value_); }
5784 void SetMin(int64_t m)
override {
5790 int64_t Max()
const override {
return std::max(expr_->
Max(), value_); }
5792 void SetMax(int64_t m)
override {
5799 bool Bound()
const override {
5800 return (expr_->
Bound() || expr_->
Max() <= value_);
5803 std::string name()
const override {
5804 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)", expr_->
name(), value_);
5807 std::string DebugString()
const override {
5808 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)", expr_->
DebugString(),
5812 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5814 void Accept(ModelVisitor*
const visitor)
const override {
5815 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5816 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5818 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5819 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5823 IntExpr*
const expr_;
5824 const int64_t value_;
5835class SimpleConvexPiecewiseExpr :
public BaseIntExpr {
5837 SimpleConvexPiecewiseExpr(Solver*
const s, IntExpr*
const e, int64_t ec,
5838 int64_t ed, int64_t ld, int64_t lc)
5842 early_date_(ec == 0 ? std::numeric_limits<int64_t>::min() : ed),
5843 late_date_(lc == 0 ? std::numeric_limits<int64_t>::max() : ld),
5845 DCHECK_GE(ec, int64_t{0});
5846 DCHECK_GE(lc, int64_t{0});
5853 ~SimpleConvexPiecewiseExpr()
override {}
5855 int64_t Min()
const override {
5856 const int64_t vmin = expr_->
Min();
5857 const int64_t vmax = expr_->
Max();
5858 if (vmin >= late_date_) {
5859 return (vmin - late_date_) * late_cost_;
5860 }
else if (vmax <= early_date_) {
5861 return (early_date_ - vmax) * early_cost_;
5867 void SetMin(int64_t m)
override {
5873 expr_->
Range(&vmin, &vmax);
5876 (late_cost_ == 0 ? vmax : late_date_ +
PosIntDivUp(m, late_cost_) - 1);
5878 (early_cost_ == 0 ? vmin
5881 if (expr_->
IsVar()) {
5886 int64_t Max()
const override {
5887 const int64_t vmin = expr_->
Min();
5888 const int64_t vmax = expr_->
Max();
5889 const int64_t mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0;
5891 vmin < early_date_ ? (early_date_ - vmin) * early_cost_ : 0;
5892 return std::max(mr, ml);
5895 void SetMax(int64_t m)
override {
5899 if (late_cost_ != 0LL) {
5900 const int64_t rb = late_date_ +
PosIntDivDown(m, late_cost_);
5901 if (early_cost_ != 0LL) {
5902 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5908 if (early_cost_ != 0LL) {
5909 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5915 std::string name()
const override {
5916 return absl::StrFormat(
5917 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5918 expr_->
name(), early_cost_, early_date_, late_date_, late_cost_);
5921 std::string DebugString()
const override {
5922 return absl::StrFormat(
5923 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5924 expr_->
DebugString(), early_cost_, early_date_, late_date_, late_cost_);
5927 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5929 void Accept(ModelVisitor*
const visitor)
const override {
5930 visitor->BeginVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5931 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5933 visitor->VisitIntegerArgument(ModelVisitor::kEarlyCostArgument,
5935 visitor->VisitIntegerArgument(ModelVisitor::kEarlyDateArgument,
5937 visitor->VisitIntegerArgument(ModelVisitor::kLateCostArgument, late_cost_);
5938 visitor->VisitIntegerArgument(ModelVisitor::kLateDateArgument, late_date_);
5939 visitor->EndVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5943 IntExpr*
const expr_;
5944 const int64_t early_cost_;
5945 const int64_t early_date_;
5946 const int64_t late_date_;
5947 const int64_t late_cost_;
5952class SemiContinuousExpr :
public BaseIntExpr {
5954 SemiContinuousExpr(Solver*
const s, IntExpr*
const e, int64_t fixed_charge,
5956 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge), step_(step) {
5957 DCHECK_GE(fixed_charge, int64_t{0});
5958 DCHECK_GT(step, int64_t{0});
5961 ~SemiContinuousExpr()
override {}
5963 int64_t
Value(int64_t x)
const {
5971 int64_t Min()
const override {
return Value(expr_->
Min()); }
5973 void SetMin(int64_t m)
override {
5974 if (m >=
CapAdd(fixed_charge_, step_)) {
5982 int64_t Max()
const override {
return Value(expr_->
Max()); }
5984 void SetMax(int64_t m)
override {
5988 if (m == std::numeric_limits<int64_t>::max()) {
5991 if (m <
CapAdd(fixed_charge_, step_)) {
5999 std::string name()
const override {
6000 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
6001 expr_->
name(), fixed_charge_, step_);
6004 std::string DebugString()
const override {
6005 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
6009 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
6011 void Accept(ModelVisitor*
const visitor)
const override {
6012 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6013 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6015 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6017 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, step_);
6018 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6022 IntExpr*
const expr_;
6023 const int64_t fixed_charge_;
6024 const int64_t step_;
6027class SemiContinuousStepOneExpr :
public BaseIntExpr {
6029 SemiContinuousStepOneExpr(Solver*
const s, IntExpr*
const e,
6030 int64_t fixed_charge)
6031 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) {
6032 DCHECK_GE(fixed_charge, int64_t{0});
6035 ~SemiContinuousStepOneExpr()
override {}
6037 int64_t
Value(int64_t x)
const {
6041 return fixed_charge_ +
x;
6045 int64_t Min()
const override {
return Value(expr_->
Min()); }
6047 void SetMin(int64_t m)
override {
6048 if (m >= fixed_charge_ + 1) {
6049 expr_->
SetMin(m - fixed_charge_);
6055 int64_t Max()
const override {
return Value(expr_->
Max()); }
6057 void SetMax(int64_t m)
override {
6061 if (m < fixed_charge_ + 1) {
6064 expr_->
SetMax(m - fixed_charge_);
6068 std::string name()
const override {
6069 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6070 expr_->
name(), fixed_charge_);
6073 std::string DebugString()
const override {
6074 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6078 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
6080 void Accept(ModelVisitor*
const visitor)
const override {
6081 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6082 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6084 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6086 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 1);
6087 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6091 IntExpr*
const expr_;
6092 const int64_t fixed_charge_;
6095class SemiContinuousStepZeroExpr :
public BaseIntExpr {
6097 SemiContinuousStepZeroExpr(Solver*
const s, IntExpr*
const e,
6098 int64_t fixed_charge)
6099 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) {
6100 DCHECK_GT(fixed_charge, int64_t{0});
6103 ~SemiContinuousStepZeroExpr()
override {}
6105 int64_t
Value(int64_t x)
const {
6109 return fixed_charge_;
6113 int64_t Min()
const override {
return Value(expr_->
Min()); }
6115 void SetMin(int64_t m)
override {
6116 if (m >= fixed_charge_) {
6123 int64_t Max()
const override {
return Value(expr_->
Max()); }
6125 void SetMax(int64_t m)
override {
6129 if (m < fixed_charge_) {
6134 std::string name()
const override {
6135 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6136 expr_->
name(), fixed_charge_);
6139 std::string DebugString()
const override {
6140 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6144 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
6146 void Accept(ModelVisitor*
const visitor)
const override {
6147 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6148 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6150 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6152 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 0);
6153 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6157 IntExpr*
const expr_;
6158 const int64_t fixed_charge_;
6162class LinkExprAndVar :
public CastConstraint {
6164 LinkExprAndVar(Solver*
const s, IntExpr*
const expr, IntVar*
const var)
6165 : CastConstraint(s, var), expr_(expr) {}
6167 ~LinkExprAndVar()
override {}
6169 void Post()
override {
6170 Solver*
const s = solver();
6171 Demon* d = s->MakeConstraintInitialPropagateCallback(
this);
6173 target_var_->WhenRange(d);
6176 void InitialPropagate()
override {
6177 expr_->
SetRange(target_var_->Min(), target_var_->Max());
6179 expr_->
Range(&l, &u);
6180 target_var_->SetRange(l, u);
6183 std::string DebugString()
const override {
6184 return absl::StrFormat(
"cast(%s, %s)", expr_->
DebugString(),
6185 target_var_->DebugString());
6188 void Accept(ModelVisitor*
const visitor)
const override {
6189 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6190 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6192 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6194 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6198 IntExpr*
const expr_;
6203class ExprWithEscapeValue :
public BaseIntExpr {
6205 ExprWithEscapeValue(Solver*
const s, IntVar*
const c, IntExpr*
const e,
6206 int64_t unperformed_value)
6210 unperformed_value_(unperformed_value) {}
6213 ExprWithEscapeValue(
const ExprWithEscapeValue&) =
delete;
6214 ExprWithEscapeValue& operator=(
const ExprWithEscapeValue&) =
delete;
6216 ~ExprWithEscapeValue()
override {}
6218 int64_t Min()
const override {
6219 if (condition_->
Min() == 1) {
6220 return expression_->
Min();
6221 }
else if (condition_->
Max() == 1) {
6222 return std::min(unperformed_value_, expression_->
Min());
6224 return unperformed_value_;
6228 void SetMin(int64_t m)
override {
6229 if (m > unperformed_value_) {
6232 }
else if (condition_->
Min() == 1) {
6234 }
else if (m > expression_->
Max()) {
6239 int64_t Max()
const override {
6240 if (condition_->
Min() == 1) {
6241 return expression_->
Max();
6242 }
else if (condition_->
Max() == 1) {
6243 return std::max(unperformed_value_, expression_->
Max());
6245 return unperformed_value_;
6249 void SetMax(int64_t m)
override {
6250 if (m < unperformed_value_) {
6253 }
else if (condition_->
Min() == 1) {
6255 }
else if (m < expression_->Min()) {
6260 void SetRange(int64_t mi, int64_t ma)
override {
6261 if (ma < unperformed_value_ || mi > unperformed_value_) {
6264 }
else if (condition_->
Min() == 1) {
6266 }
else if (ma < expression_->Min() || mi > expression_->
Max()) {
6271 void SetValue(int64_t v)
override {
6272 if (v != unperformed_value_) {
6275 }
else if (condition_->
Min() == 1) {
6277 }
else if (v < expression_->Min() || v > expression_->
Max()) {
6282 bool Bound()
const override {
6283 return condition_->
Max() == 0 || expression_->
Bound();
6286 void WhenRange(Demon* d)
override {
6291 std::string DebugString()
const override {
6292 return absl::StrFormat(
"ConditionExpr(%s, %s, %d)",
6297 void Accept(ModelVisitor*
const visitor)
const override {
6298 visitor->BeginVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6299 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
6301 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6303 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
6304 unperformed_value_);
6305 visitor->EndVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6309 IntVar*
const condition_;
6310 IntExpr*
const expression_;
6311 const int64_t unperformed_value_;
6315class LinkExprAndDomainIntVar :
public CastConstraint {
6317 LinkExprAndDomainIntVar(Solver*
const s, IntExpr*
const expr,
6318 DomainIntVar*
const var)
6319 : CastConstraint(s, var),
6321 cached_min_(std::numeric_limits<int64_t>::min()),
6322 cached_max_(std::numeric_limits<int64_t>::max()),
6323 fail_stamp_(uint64_t{0}) {}
6325 ~LinkExprAndDomainIntVar()
override {}
6327 DomainIntVar* var()
const {
6328 return reinterpret_cast<DomainIntVar*
>(target_var_);
6331 void Post()
override {
6332 Solver*
const s = solver();
6333 Demon*
const d = s->MakeConstraintInitialPropagateCallback(
this);
6336 solver(),
this, &LinkExprAndDomainIntVar::Propagate,
"Propagate");
6337 target_var_->WhenRange(target_var_demon);
6340 void InitialPropagate()
override {
6341 expr_->
SetRange(var()->min_.Value(), var()->max_.Value());
6342 expr_->
Range(&cached_min_, &cached_max_);
6343 var()->DomainIntVar::SetRange(cached_min_, cached_max_);
6347 if (var()->min_.Value() > cached_min_ ||
6348 var()->max_.Value() < cached_max_ ||
6349 solver()->fail_stamp() != fail_stamp_) {
6351 fail_stamp_ = solver()->fail_stamp();
6355 std::string DebugString()
const override {
6356 return absl::StrFormat(
"cast(%s, %s)", expr_->
DebugString(),
6357 target_var_->DebugString());
6360 void Accept(ModelVisitor*
const visitor)
const override {
6361 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6362 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6364 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6366 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6370 IntExpr*
const expr_;
6371 int64_t cached_min_;
6372 int64_t cached_max_;
6373 uint64_t fail_stamp_;
6380 return CondRevAlloc(
solver(), reversible,
new EmptyIterator());
6383 return CondRevAlloc(
solver(), reversible,
new RangeIterator(
this));
6390 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(var);
6391 dvar->CleanInProcess();
6395 const std::vector<IntVar*>& vars) {
6396 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(var);
6397 CHECK(dvar !=
nullptr);
6398 return dvar->SetIsEqual(values, vars);
6402 absl::Span<const int64_t> values,
6403 const std::vector<IntVar*>& vars) {
6404 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(var);
6405 CHECK(dvar !=
nullptr);
6406 return dvar->SetIsGreaterOrEqual(values, vars);
6421 if (min == 0 && max == 1) {
6423 }
else if (
CapSub(max, min) == 1) {
6424 const std::string inner_name =
"inner_" + name;
6427 ->VarWithName(name));
6446 const std::string& name) {
6447 DCHECK(!values.empty());
6449 if (values.size() == 1)
return MakeIntConst(values[0], name);
6451 std::vector<int64_t> unique_sorted_values = values;
6454 if (unique_sorted_values.size() == 1)
return MakeIntConst(values[0], name);
6456 if (unique_sorted_values.size() ==
6457 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6458 return MakeIntVar(unique_sorted_values.front(), unique_sorted_values.back(),
6464 for (
const int64_t v : unique_sorted_values) {
6474 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, name)));
6478 for (int64_t& v : unique_sorted_values) {
6479 DCHECK_EQ(0, v % gcd);
6482 const std::string new_name = name.empty() ?
"" :
"inner_" + name;
6484 IntVar* inner_intvar =
nullptr;
6485 if (unique_sorted_values.size() ==
6486 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6487 inner_intvar =
MakeIntVar(unique_sorted_values.front(),
6488 unique_sorted_values.back(), new_name);
6491 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, new_name)));
6493 return MakeProd(inner_intvar, gcd)->Var();
6501 const std::string& name) {
6513 if (absl::GetFlag(FLAGS_cp_share_int_consts) && name.empty() &&
6514 val >= MIN_CACHED_INT_CONST && val <= MAX_CACHED_INT_CONST) {
6515 return cached_constants_[val - MIN_CACHED_INT_CONST];
6517 return RevAlloc(
new IntConst(
this, val, name));
6525std::string IndexedName(absl::string_view prefix,
int index,
int max_index) {
6527#if defined(_MSC_VER)
6528 const int digits = max_index > 0 ?
6529 static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
6532 const int digits = max_index > 0 ?
static_cast<int>(log10(max_index)) + 1: 1;
6534 return absl::StrFormat(
"%s%0*d", prefix, digits, index);
6536 return absl::StrCat(prefix, index);
6542 const std::string& name,
6543 std::vector<IntVar*>* vars) {
6544 for (
int i = 0; i < var_count; ++i) {
6545 vars->push_back(
MakeIntVar(vmin, vmax, IndexedName(name, i, var_count)));
6550 std::vector<IntVar*>* vars) {
6551 for (
int i = 0; i < var_count; ++i) {
6557 const std::string& name) {
6559 for (
int i = 0; i < var_count; ++i) {
6560 vars[i] =
MakeIntVar(vmin, vmax, IndexedName(name, i, var_count));
6566 std::vector<IntVar*>* vars) {
6567 for (
int i = 0; i < var_count; ++i) {
6568 vars->push_back(
MakeBoolVar(IndexedName(name, i, var_count)));
6573 for (
int i = 0; i < var_count; ++i) {
6580 for (
int i = 0; i < var_count; ++i) {
6581 vars[i] =
MakeBoolVar(IndexedName(name, i, var_count));
6586void Solver::InitCachedIntConstants() {
6587 for (
int i = MIN_CACHED_INT_CONST; i <= MAX_CACHED_INT_CONST; ++i) {
6588 cached_constants_[i - MIN_CACHED_INT_CONST] =
6589 RevAlloc(
new IntConst(
this, i,
""));
6594 CHECK_EQ(
this, left->
solver());
6595 CHECK_EQ(
this, right->
solver());
6596 if (right->
Bound()) {
6599 if (left->
Bound()) {
6602 if (left == right) {
6605 IntExpr* cache = model_cache_->FindExprExprExpression(
6607 if (cache ==
nullptr) {
6608 cache = model_cache_->FindExprExprExpression(right, left,
6611 if (cache !=
nullptr) {
6619 model_cache_->InsertExprExprExpression(result, left, right,
6626 CHECK_EQ(
this, expr->
solver());
6627 if (expr->
Bound()) {
6635 if (result ==
nullptr) {
6642 this,
reinterpret_cast<DomainIntVar*
>(var), value)));
6650 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(var);
6651 IntVar*
const sub_var = add_var->SubVar();
6652 const int64_t new_constant = value + add_var->Constant();
6653 if (new_constant == 0) {
6657 DomainIntVar*
const dvar =
6658 reinterpret_cast<DomainIntVar*
>(sub_var);
6660 RevAlloc(
new PlusCstDomainIntVar(
this, dvar, new_constant)));
6663 RevAlloc(
new PlusCstIntVar(
this, sub_var, new_constant)));
6669 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(var);
6670 IntVar*
const sub_var = add_var->SubVar();
6671 const int64_t new_constant = value + add_var->Constant();
6673 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6677 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(var);
6678 IntVar*
const sub_var = add_var->SubVar();
6690 Cache()->InsertExprConstantExpression(result, expr, value,
6697 CHECK_EQ(
this, left->
solver());
6698 CHECK_EQ(
this, right->
solver());
6699 if (left->
Bound()) {
6702 if (right->
Bound()) {
6707 int64_t left_coef = 1;
6708 int64_t right_coef = 1;
6709 if (
IsProduct(left, &sub_left, &left_coef) &&
6710 IsProduct(right, &sub_right, &right_coef)) {
6711 const int64_t abs_gcd =
6713 if (abs_gcd != 0 && abs_gcd != 1) {
6715 MakeProd(sub_right, right_coef / abs_gcd)),
6722 if (result ==
nullptr) {
6729 Cache()->InsertExprExprExpression(result, left, right,
6737 CHECK_EQ(
this, expr->
solver());
6738 if (expr->
Bound()) {
6746 if (result ==
nullptr) {
6747 if (expr->
IsVar() && expr->
Min() != std::numeric_limits<int64_t>::min() &&
6753 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(var);
6754 IntVar*
const sub_var = add_var->SubVar();
6755 const int64_t new_constant = value - add_var->Constant();
6756 if (new_constant == 0) {
6760 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6765 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(var);
6766 IntVar*
const sub_var = add_var->SubVar();
6767 const int64_t new_constant = value - add_var->Constant();
6768 result =
MakeSum(sub_var, new_constant);
6772 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(var);
6773 IntVar*
const sub_var = add_var->SubVar();
6774 result =
MakeSum(sub_var, value);
6784 Cache()->InsertExprConstantExpression(result, expr, value,
6791 CHECK_EQ(
this, expr->
solver());
6792 if (expr->
Bound()) {
6797 if (result ==
nullptr) {
6798 if (expr->
IsVar()) {
6809 CHECK_EQ(
this, expr->
solver());
6812 if (result !=
nullptr) {
6816 int64_t coefficient = 1;
6817 if (
IsProduct(expr, &m_expr, &coefficient)) {
6818 coefficient =
CapProd(coefficient, value);
6821 coefficient = value;
6823 if (m_expr->
Bound()) {
6825 }
else if (coefficient == 1) {
6827 }
else if (coefficient == -1) {
6829 }
else if (coefficient > 0) {
6830 if (m_expr->
Max() > std::numeric_limits<int64_t>::max() / coefficient ||
6831 m_expr->
Min() < std::numeric_limits<int64_t>::min() / coefficient) {
6833 RevAlloc(
new SafeTimesPosIntCstExpr(
this, m_expr, coefficient)));
6836 RevAlloc(
new TimesPosIntCstExpr(
this, m_expr, coefficient)));
6838 }
else if (coefficient == 0) {
6842 RevAlloc(
new TimesIntNegCstExpr(
this, m_expr, coefficient)));
6844 if (m_expr->
IsVar() &&
6845 !absl::GetFlag(FLAGS_cp_disable_expression_optimization)) {
6846 result = result->
Var();
6848 Cache()->InsertExprConstantExpression(result, expr, value,
6855void ExtractPower(
IntExpr**
const expr, int64_t*
const exponant) {
6856 if (
dynamic_cast<BasePower*
>(*expr) !=
nullptr) {
6857 BasePower*
const power =
dynamic_cast<BasePower*
>(*expr);
6858 *expr = power->expr();
6859 *exponant = power->exponant();
6861 if (
dynamic_cast<IntSquare*
>(*expr) !=
nullptr) {
6862 IntSquare*
const power =
dynamic_cast<IntSquare*
>(*expr);
6863 *expr = power->expr();
6866 if ((*expr)->IsVar()) {
6867 IntVar*
const var = (*expr)->Var();
6868 IntExpr*
const sub = var->solver()->CastExpression(var);
6869 if (sub !=
nullptr &&
dynamic_cast<BasePower*
>(sub) !=
nullptr) {
6870 BasePower*
const power =
dynamic_cast<BasePower*
>(sub);
6871 *expr = power->expr();
6872 *exponant = power->exponant();
6874 if (sub !=
nullptr &&
dynamic_cast<IntSquare*
>(sub) !=
nullptr) {
6875 IntSquare*
const power =
dynamic_cast<IntSquare*
>(sub);
6876 *expr = power->expr();
6882void ExtractProduct(IntExpr**
const expr, int64_t*
const coefficient,
6884 if (
dynamic_cast<TimesCstIntVar*
>(*expr) !=
nullptr) {
6885 TimesCstIntVar*
const left_prod =
dynamic_cast<TimesCstIntVar*
>(*expr);
6886 *coefficient *= left_prod->Constant();
6887 *expr = left_prod->SubVar();
6889 }
else if (
dynamic_cast<TimesIntCstExpr*
>(*expr) !=
nullptr) {
6890 TimesIntCstExpr*
const left_prod =
dynamic_cast<TimesIntCstExpr*
>(*expr);
6891 *coefficient *= left_prod->Constant();
6892 *expr = left_prod->Expr();
6899 if (left->
Bound()) {
6903 if (right->
Bound()) {
6911 int64_t left_exponant = 1;
6912 int64_t right_exponant = 1;
6913 ExtractPower(&m_left, &left_exponant);
6914 ExtractPower(&m_right, &right_exponant);
6916 if (m_left == m_right) {
6917 return MakePower(m_left, left_exponant + right_exponant);
6924 int64_t coefficient = 1;
6925 bool modified =
false;
6927 ExtractProduct(&m_left, &coefficient, &modified);
6928 ExtractProduct(&m_right, &coefficient, &modified);
6935 CHECK_EQ(
this, left->
solver());
6936 CHECK_EQ(
this, right->
solver());
6937 IntExpr* result = model_cache_->FindExprExprExpression(
6939 if (result ==
nullptr) {
6940 result = model_cache_->FindExprExprExpression(right, left,
6943 if (result !=
nullptr) {
6947 if (right->
Min() >= 0) {
6949 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6952 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6954 }
else if (right->
IsVar() &&
6956 if (left->
Min() >= 0) {
6958 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6961 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6963 }
else if (left->
Min() >= 0 && right->
Min() >= 0) {
6965 std::numeric_limits<int64_t>::max()) {
6975 model_cache_->InsertExprExprExpression(result, left, right,
6981 CHECK(numerator !=
nullptr);
6982 CHECK(denominator !=
nullptr);
6983 if (denominator->
Bound()) {
6984 return MakeDiv(numerator, denominator->
Min());
6986 IntExpr* result = model_cache_->FindExprExprExpression(
6988 if (result !=
nullptr) {
6992 if (denominator->
Min() <= 0 && denominator->
Max() >= 0) {
6996 if (denominator->
Min() >= 0) {
6997 if (numerator->
Min() >= 0) {
6998 result =
RevAlloc(
new DivPosPosIntExpr(
this, numerator, denominator));
7000 result =
RevAlloc(
new DivPosIntExpr(
this, numerator, denominator));
7002 }
else if (denominator->
Max() <= 0) {
7003 if (numerator->
Max() <= 0) {
7008 new DivPosIntExpr(
this, numerator,
MakeOpposite(denominator))));
7011 result =
RevAlloc(
new DivIntExpr(
this, numerator, denominator));
7013 model_cache_->InsertExprExprExpression(result, numerator, denominator,
7019 CHECK(expr !=
nullptr);
7020 CHECK_EQ(
this, expr->
solver());
7021 if (expr->
Bound()) {
7023 }
else if (value == 1) {
7025 }
else if (value == -1) {
7027 }
else if (value > 0) {
7029 }
else if (value == 0) {
7030 LOG(FATAL) <<
"Cannot divide by 0";
7043 return RevAlloc(
new IntAbsConstraint(
this, var, abs_var));
7047 CHECK_EQ(
this, e->
solver());
7048 if (e->
Min() >= 0) {
7050 }
else if (e->
Max() <= 0) {
7054 if (result ==
nullptr) {
7055 int64_t coefficient = 1;
7057 if (
IsProduct(e, &expr, &coefficient)) {
7068 CHECK_EQ(
this, expr->
solver());
7069 if (expr->
Bound()) {
7070 const int64_t v = expr->
Min();
7074 if (result ==
nullptr) {
7075 if (expr->
Min() >= 0) {
7086 CHECK_EQ(
this, expr->
solver());
7088 if (expr->
Bound()) {
7089 const int64_t v = expr->
Min();
7090 if (v >= OverflowLimit(n)) {
7091 return MakeIntConst(std::numeric_limits<int64_t>::max());
7105 if (expr->
Min() >= 0) {
7120 CHECK_EQ(
this, left->
solver());
7121 CHECK_EQ(
this, right->
solver());
7122 if (left->
Bound()) {
7125 if (right->
Bound()) {
7128 if (left->
Min() >= right->
Max()) {
7131 if (right->
Min() >= left->
Max()) {
7138 CHECK_EQ(
this, expr->
solver());
7139 if (value <= expr->Min()) {
7142 if (expr->
Bound()) {
7145 if (expr->
Max() <= value) {
7152 return MakeMin(expr,
static_cast<int64_t
>(value));
7156 CHECK_EQ(
this, left->
solver());
7157 CHECK_EQ(
this, right->
solver());
7158 if (left->
Bound()) {
7161 if (right->
Bound()) {
7164 if (left->
Min() >= right->
Max()) {
7167 if (right->
Min() >= left->
Max()) {
7174 CHECK_EQ(
this, expr->
solver());
7175 if (expr->
Bound()) {
7178 if (value <= expr->Min()) {
7181 if (expr->
Max() <= value) {
7188 return MakeMax(expr,
static_cast<int64_t
>(value));
7192 int64_t early_date, int64_t late_date,
7193 int64_t late_cost) {
7195 this, expr, early_cost, early_date, late_date, late_cost)));
7199 int64_t fixed_charge, int64_t step) {
7201 if (fixed_charge == 0) {
7205 RevAlloc(
new SemiContinuousStepZeroExpr(
this, expr, fixed_charge)));
7207 }
else if (step == 1) {
7209 RevAlloc(
new SemiContinuousStepOneExpr(
this, expr, fixed_charge)));
7212 RevAlloc(
new SemiContinuousExpr(
this, expr, fixed_charge, step)));
7226 int64_t
Min()
const override {
7227 return f_.GetMinimum(expr_->Min(), expr_->Max());
7231 f_.GetSmallestRangeGreaterThanValue(expr_->Min(), expr_->Max(), m);
7232 expr_->SetRange(range.first, range.second);
7235 int64_t
Max()
const override {
7236 return f_.GetMaximum(expr_->Min(), expr_->Max());
7241 f_.GetSmallestRangeLessThanValue(expr_->Min(), expr_->Max(), m);
7242 expr_->SetRange(range.first, range.second);
7247 f_.GetSmallestRangeInValueRange(expr_->Min(), expr_->Max(), l, u);
7248 expr_->SetRange(range.first, range.second);
7250 std::string
name()
const override {
7251 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)", expr_->name(),
7256 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)", expr_->DebugString(),
7280 int64_t unperformed_value) {
7281 if (condition->
Min() == 1) {
7283 }
else if (condition->
Max() == 0) {
7286 IntExpr* cache =
Cache()->FindExprExprConstantExpression(
7287 condition, expr, unperformed_value,
7289 if (cache ==
nullptr) {
7291 new ExprWithEscapeValue(
this, condition, expr, unperformed_value));
7292 Cache()->InsertExprExprConstantExpression(
7293 cache, condition, expr, unperformed_value,
7330 const int size = values.size();
7354 int start_index = 0;
7355 int64_t new_min =
Min();
7356 if (values[start_index] <= new_min) {
7357 while (start_index < size - 1 &&
7358 values[start_index + 1] == values[start_index] + 1) {
7359 new_min = values[start_index + 1] + 1;
7363 int end_index = size - 1;
7364 int64_t new_max =
Max();
7365 if (values[end_index] >= new_max) {
7366 while (end_index > start_index + 1 &&
7367 values[end_index - 1] == values[end_index] - 1) {
7368 new_max = values[end_index - 1] - 1;
7373 for (
int i = start_index; i <= end_index; ++i) {
7386 switch (values.size()) {
7398 const int64_t l = std::min(values[0], values[1]);
7399 const int64_t u = std::max(values[0], values[1]);
7419 std::vector<int64_t>& tmp =
solver()->tmp_vector_;
7421 tmp.insert(tmp.end(), values.begin(), values.end());
7422 std::sort(tmp.begin(), tmp.end());
7423 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
7424 const int size = tmp.size();
7425 const int64_t vmin =
Min();
7426 const int64_t vmax =
Max();
7428 int last = size - 1;
7429 if (tmp.front() > vmax || tmp.back() < vmin) {
7433 while (tmp[first] < vmin || !
Contains(tmp[first])) {
7435 if (first > last || tmp[first] > vmax) {
7439 while (last > first && (tmp[last] > vmax || !
Contains(tmp[last]))) {
7443 DCHECK_GE(last, first);
7445 while (first < last) {
7446 const int64_t start = tmp[first] + 1;
7447 const int64_t
end = tmp[first + 1] - 1;
7459 if (!var->
Bound()) {
7461 DomainIntVar* dvar =
reinterpret_cast<DomainIntVar*
>(var);
7463 s->
RevAlloc(
new LinkExprAndDomainIntVar(s, expr, dvar)), dvar, expr);
7472 if (var_ ==
nullptr) {
7473 solver()->SaveValue(
reinterpret_cast<void**
>(&var_));
7481 Range(&vmin, &vmax);
7490 if (expr->
IsVar()) {
7492 expr = CastExpression(expr_var);
7496 SubIntExpr*
const sub_expr =
dynamic_cast<SubIntExpr*
>(expr);
7497 if (sub_expr !=
nullptr) {
7498 *left = sub_expr->left();
7499 *right = sub_expr->right();
7506 bool* is_negated)
const {
7508 *inner_var = expr->
Var();
7509 *is_negated =
false;
7512 SubCstIntVar*
const sub_var =
reinterpret_cast<SubCstIntVar*
>(expr);
7513 if (sub_var !=
nullptr && sub_var->Constant() == 1 &&
7516 *inner_var = sub_var->SubVar();
7524 int64_t* coefficient) {
7525 if (
dynamic_cast<TimesCstIntVar*
>(expr) !=
nullptr) {
7526 TimesCstIntVar*
const var =
dynamic_cast<TimesCstIntVar*
>(expr);
7527 *coefficient = var->Constant();
7528 *inner_expr = var->SubVar();
7530 }
else if (
dynamic_cast<TimesIntCstExpr*
>(expr) !=
nullptr) {
7531 TimesIntCstExpr*
const prod =
dynamic_cast<TimesIntCstExpr*
>(expr);
7532 *coefficient = prod->Constant();
7533 *inner_expr = prod->Expr();
virtual IntVar * CastToVar()
IntVar * Var() override
Creates a variable from the expression.
BaseIntExpr(Solver *const s)
bool Contains(int64_t v) const override
IntVarIterator * MakeDomainIterator(bool reversible) const override
IntVar * IsGreaterOrEqual(int64_t constant) override
IntVarIterator * MakeHoleIterator(bool reversible) const override
--— Misc --—
IntVar * IsEqual(int64_t constant) override
IsEqual.
void RemoveValue(int64_t v) override
This method removes the value 'v' from the domain of the variable.
IntVar * IsDifferent(int64_t constant) override
SimpleRevFIFO< Demon * > delayed_bound_demons_
void SetMax(int64_t m) override
void SetRange(int64_t mi, int64_t ma) override
This method sets both the min and the max of the expression.
void RemoveInterval(int64_t l, int64_t u) override
virtual void RestoreValue()=0
void SetMin(int64_t m) override
SimpleRevFIFO< Demon * > bound_demons_
uint64_t Size() const override
This method returns the number of values in the domain of the variable.
static const int kUnboundBooleanVarValue
--— Boolean variable --—
std::string DebugString() const override
void WhenBound(Demon *d) override
IntVar * IsLessOrEqual(int64_t constant) override
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
virtual Solver::DemonPriority priority() const
---------------— Demon class -------------—
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual void SetMax(int64_t m)=0
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
virtual int64_t Min() const =0
virtual void SetMin(int64_t m)=0
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
virtual void Range(int64_t *l, int64_t *u)
IntVar * VarWithName(const std::string &name)
-------— IntExpr -------—
virtual IntVar * Var()=0
Creates a variable from the expression.
virtual int64_t Max() const =0
virtual void WhenBound(Demon *d)=0
virtual void WhenDomain(Demon *d)=0
virtual void SetValues(const std::vector< int64_t > &values)
This method intersects the current domain with the values in the array.
void Accept(ModelVisitor *visitor) const override
Accepts the given visitor.
virtual IntVar * IsDifferent(int64_t constant)=0
IntVar(Solver *s)
-------— IntVar -------—
virtual int64_t OldMax() const =0
Returns the previous max.
virtual IntVar * IsLessOrEqual(int64_t constant)=0
virtual bool Contains(int64_t v) const =0
virtual int64_t Value() const =0
virtual int VarType() const
------— IntVar ------—
virtual void RemoveValue(int64_t v)=0
This method removes the value 'v' from the domain of the variable.
virtual uint64_t Size() const =0
This method returns the number of values in the domain of the variable.
virtual IntVar * IsGreaterOrEqual(int64_t constant)=0
virtual IntVar * IsEqual(int64_t constant)=0
IsEqual.
virtual void RemoveInterval(int64_t l, int64_t u)=0
virtual int64_t OldMin() const =0
Returns the previous min.
virtual void RemoveValues(const std::vector< int64_t > &values)
This method remove the values from the domain of the variable.
static int64_t GCD64(int64_t x, int64_t y)
@ EXPR_CONSTANT_IS_NOT_EQUAL
@ EXPR_CONSTANT_IS_GREATER_OR_EQUAL
@ EXPR_CONSTANT_IS_LESS_OR_EQUAL
@ EXPR_CONSTANT_DIFFERENCE
@ EXPR_EXPR_CONSTANT_CONDITIONAL
static const char kVarValueWatcher[]
virtual void VisitIntegerVariable(const IntVar *variable, IntExpr *delegate)
static const char kVarBoundWatcher[]
static const char kValuesArgument[]
static const char kVarsArgument[]
static const char kVariableArgument[]
void SetRange(int64_t l, int64_t u) override
This method sets both the min and the max of the expression.
void SetMax(int64_t m) override
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
PiecewiseLinearExpr(Solver *solver, IntExpr *expr, const PiecewiseLinearFunction &f)
int64_t Max() const override
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
~PiecewiseLinearExpr() override
int64_t Min() const override
std::string name() const override
Object naming.
std::string DebugString() const override
void SetMin(int64_t m) override
virtual std::string name() const
Object naming.
void set_name(absl::string_view name)
std::string DebugString() const override
For the time being, Solver is neither MT_SAFE nor MT_HOT.
IntExpr * MakeDiv(IntExpr *expr, int64_t value)
expr / value (integer division)
IntVar * MakeBoolVar(const std::string &name)
MakeBoolVar will create a variable with a {0, 1} domain.
Constraint * MakeNonEquality(IntExpr *left, IntExpr *right)
left != right
IntExpr * MakeMax(const std::vector< IntVar * > &vars)
std::max(vars)
IntExpr * MakeDifference(IntExpr *left, IntExpr *right)
left - right
IntVar * MakeBoolVar()
MakeBoolVar will create a variable with a {0, 1} domain.
IntExpr * MakeSum(IntExpr *left, IntExpr *right)
--— Integer Expressions --—
IntExpr * MakeMin(const std::vector< IntVar * > &vars)
std::min(vars)
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
@ OUTSIDE_SEARCH
Before search, after search.
IntVar * RegisterIntVar(IntVar *var)
Registers a new IntVar and wraps it inside a TraceIntVar if necessary.
bool IsBooleanVar(IntExpr *expr, IntVar **inner_var, bool *is_negated) const
Constraint * MakeLess(IntExpr *left, IntExpr *right)
left < right
ModelCache * Cache() const
Returns the cache of the model.
IntExpr * MakeOpposite(IntExpr *expr)
-expr
Constraint * MakeAbsEquality(IntVar *var, IntVar *abs_var)
Creates the constraint abs(var) == abs_var.
void MakeBoolVarArray(int var_count, const std::string &name, std::vector< IntVar * > *vars)
IntExpr * MakePiecewiseLinearExpr(IntExpr *expr, const PiecewiseLinearFunction &f)
IntExpr * RegisterIntExpr(IntExpr *expr)
Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary.
IntExpr * MakeModulo(IntExpr *x, int64_t mod)
Modulo expression x % mod (with the python convention for modulo).
Constraint * MakeGreater(IntExpr *left, IntExpr *right)
left > right
IntExpr * MakeAbs(IntExpr *expr)
expr
IntExpr * MakeSquare(IntExpr *expr)
expr * expr
Constraint * MakeBetweenCt(IntExpr *expr, int64_t l, int64_t u)
--— Between and related constraints --—
void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string &name, std::vector< IntVar * > *vars)
IntVar * MakeIntVar(int64_t min, int64_t max, const std::string &name)
--— Int Variables and Constants --—
bool IsProduct(IntExpr *expr, IntExpr **inner_expr, int64_t *coefficient)
IntExpr * MakeConvexPiecewiseExpr(IntExpr *expr, int64_t early_cost, int64_t early_date, int64_t late_date, int64_t late_cost)
Convex piecewise function.
IntExpr * MakePower(IntExpr *expr, int64_t n)
expr ^ n (n > 0)
IntExpr * MakeConditionalExpression(IntVar *condition, IntExpr *expr, int64_t unperformed_value)
Conditional Expr condition ? expr : unperformed_value.
IntExpr * MakeProd(IntExpr *left, IntExpr *right)
left * right
IntVar * MakeIntConst(int64_t val, const std::string &name)
IntConst will create a constant expression.
void AddConstraint(Constraint *c)
IntExpr * MakeSemiContinuousExpr(IntExpr *expr, int64_t fixed_charge, int64_t step)
void AddCastConstraint(CastConstraint *constraint, IntVar *target_var, IntExpr *expr)
ABSL_FLAG(bool, cp_disable_expression_optimization, false, "Disable special optimization when creating expressions.")
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)
For infeasible and unbounded see Not checked if options check_solutions_if_inf_or_unbounded and the If options first_solution_only is false
problem is infeasible or unbounded (default).
std::pair< double, double > Range
A range of values, first is the minimum, second is the maximum.
dual_gradient T(y - `dual_solution`) class DiagonalTrustRegionProblemFromQp
std::function< int64_t(const Model &)> Value(IntegerVariable v)
This checks that the variable is fixed.
In SWIG mode, we don't want anything besides these top-level includes.
int64_t SubOverflows(int64_t x, int64_t y)
int64_t UnsafeMostSignificantBitPosition64(const uint64_t *bitset, uint64_t start, uint64_t end)
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
int64_t CapAdd(int64_t x, int64_t y)
void RestoreBoolValue(IntVar *var)
--— Trail --—
int64_t UnsafeLeastSignificantBitPosition64(const uint64_t *bitset, uint64_t start, uint64_t end)
int64_t CapSub(int64_t x, int64_t y)
Constraint * SetIsGreaterOrEqual(IntVar *const var, absl::Span< const int64_t > values, const std::vector< IntVar * > &vars)
ClosedInterval::Iterator end(ClosedInterval interval)
Constraint * SetIsEqual(IntVar *const var, absl::Span< const int64_t > values, const std::vector< IntVar * > &vars)
bool AddOverflows(int64_t x, int64_t y)
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
--— Exported Methods for Unit Tests --—
static const uint64_t kAllBits64
Basic bit operations.
void LinkVarExpr(Solver *s, IntExpr *expr, IntVar *var)
--— IntExprElement --—
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
int64_t CapProd(int64_t x, int64_t y)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
--— Vector manipulations --—
uint64_t OneRange64(uint64_t s, uint64_t e)
Returns a word with bits from s to e set.
uint32_t BitPos64(uint64_t pos)
Bit operators used to manipulates bitsets.
uint64_t BitCountRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
Returns the number of bits set in bitset between positions start and end.
uint64_t BitCount64(uint64_t n)
Returns the number of bits set in n.
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
Returns true if the bit pos is set in bitset.
uint64_t OneBit64(int pos)
Returns a word with only bit pos set.
uint64_t BitOffset64(uint64_t pos)
Returns the word number corresponding to bit number pos.
int64_t PosIntDivDown(int64_t e, int64_t v)
uint64_t BitLength64(uint64_t size)
Returns the number of words needed to store size bits.
int LeastSignificantBitPosition64(uint64_t n)
void CleanVariableOnFail(IntVar *var)
---------------— Queue class ---------------—
int64_t CapOpp(int64_t v)
Note(user): -kint64min != kint64max, but kint64max == ~kint64min.
int MostSignificantBitPosition64(uint64_t n)
int64_t PosIntDivUp(int64_t e, int64_t v)
trees with all degrees equal w the current value of w