24#include "absl/container/flat_hash_map.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"
41ABSL_FLAG(
bool, cp_disable_expression_optimization,
false,
42 "Disable special optimization when creating expressions.");
44 "Share IntConst's with the same value.");
47#pragma warning(disable : 4351 4355)
65 :
IntExpr(s), index_(s->GetNewIntVarIndex()) {
86 if (mi > 1 || ma < 0 || mi > ma) {
110 if (l <= 0 && u >= 1) {
134 return ((v == 0 &&
value_ != 1) || (v == 1 &&
value_ != 0));
138 if (constant > 1 || constant < 0) {
149 if (constant > 1 || constant < 0) {
162 }
else if (constant <= 0) {
172 }
else if (constant >= 1) {
181 const std::string& var_name =
name();
182 if (!var_name.empty()) {
183 out = var_name +
"(";
207class DomainIntVar :
public IntVar {
212 BitSetIterator(uint64_t*
const bitset, int64_t omin)
215 max_(
std::numeric_limits<int64_t>::min()),
216 current_(
std::numeric_limits<int64_t>::max()) {}
218 ~BitSetIterator()
override {}
220 void Init(int64_t min, int64_t max) {
225 bool Ok()
const {
return current_ <= max_; }
227 int64_t
Value()
const {
return current_; }
230 if (++current_ <= max_) {
232 bitset_, current_ - omin_, max_ - omin_) +
237 std::string DebugString()
const override {
return "BitSetIterator"; }
240 uint64_t*
const bitset_;
246 class BitSet :
public BaseObject {
248 explicit BitSet(Solver*
const s) : solver_(s), holes_stamp_(0) {}
249 ~BitSet()
override {}
251 virtual int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax) = 0;
252 virtual int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax) = 0;
253 virtual bool Contains(int64_t val)
const = 0;
254 virtual bool SetValue(int64_t val) = 0;
255 virtual bool RemoveValue(int64_t val) = 0;
256 virtual uint64_t Size()
const = 0;
257 virtual void DelayRemoveValue(int64_t val) = 0;
258 virtual void ApplyRemovedValues(DomainIntVar* var) = 0;
259 virtual void ClearRemovedValues() = 0;
260 virtual std::string pretty_DebugString(int64_t min, int64_t max)
const = 0;
261 virtual BitSetIterator* MakeIterator() = 0;
264 const uint64_t current_stamp = solver_->stamp();
265 if (holes_stamp_ < current_stamp) {
267 holes_stamp_ = current_stamp;
271 virtual void ClearHoles() { holes_.clear(); }
273 const std::vector<int64_t>& Holes() {
return holes_; }
275 void AddHole(int64_t value) { holes_.push_back(value); }
277 int NumHoles()
const {
278 return holes_stamp_ < solver_->stamp() ? 0 : holes_.size();
282 Solver*
const solver_;
285 std::vector<int64_t> holes_;
286 uint64_t holes_stamp_;
289 class QueueHandler :
public Demon {
291 explicit QueueHandler(DomainIntVar*
const var) : var_(var) {}
292 ~QueueHandler()
override {}
293 void Run(Solver*
const s)
override {
294 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
296 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
301 std::string DebugString()
const override {
302 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
306 DomainIntVar*
const var_;
317 RevIntPtrMap(Solver*
const solver, int64_t rmin, int64_t rmax)
318 : solver_(solver), range_min_(rmin), start_(0) {}
322 bool Empty()
const {
return start_.Value() == elements_.size(); }
324 void SortActive() { std::sort(elements_.begin(), elements_.end()); }
329 void UnsafeRevInsert(int64_t value, T* elem) {
330 elements_.push_back(std::make_pair(value, elem));
332 solver_->AddBacktrackAction(
333 [
this, value](Solver* s) { Uninsert(value); },
false);
338 for (
int pos = start_.Value(); pos < elements_.size(); ++pos) {
339 if (elements_[pos].first == value) {
340 if (position !=
nullptr) *position = pos;
341 return At(pos).second;
349 const int start = start_.Value();
350 DCHECK_GE(position, start);
351 DCHECK_LT(position, elements_.size());
352 if (position > start) {
355 const std::pair<int64_t, T*> copy = elements_[start];
356 elements_[start] = elements_[position];
357 elements_[position] = copy;
359 start_.Incr(solver_);
362 const std::pair<int64_t, T*>& At(
int position)
const {
363 DCHECK_GE(position, start_.Value());
364 DCHECK_LT(position, elements_.size());
365 return elements_[position];
368 void RemoveAll() { start_.SetValue(solver_, elements_.size()); }
370 int start()
const {
return start_.Value(); }
371 int end()
const {
return elements_.size(); }
373 int Size()
const {
return elements_.size() - start_.Value(); }
376 void Uninsert(int64_t value) {
377 for (
int pos = 0; pos < elements_.size(); ++pos) {
378 if (elements_[pos].first == value) {
379 DCHECK_GE(pos, start_.Value());
380 const int last = elements_.size() - 1;
382 elements_[pos] = elements_.back();
384 elements_.pop_back();
388 LOG(FATAL) <<
"The element should have been removed";
392 Solver*
const solver_;
393 const int64_t range_min_;
394 NumericalRev<int> start_;
395 std::vector<std::pair<int64_t, T*>> elements_;
399 class BaseValueWatcher :
public Constraint {
401 explicit BaseValueWatcher(Solver*
const solver) : Constraint(solver) {}
403 ~BaseValueWatcher()
override {}
405 virtual IntVar* GetOrMakeValueWatcher(int64_t value) = 0;
407 virtual void SetValueWatcher(IntVar* boolvar, int64_t value) = 0;
412 class ValueWatcher :
public BaseValueWatcher {
414 class WatchDemon :
public Demon {
416 WatchDemon(ValueWatcher*
const watcher, int64_t value, IntVar* var)
417 : value_watcher_(watcher), value_(value), var_(var) {}
418 ~WatchDemon()
override {}
420 void Run(Solver*
const solver)
override {
421 value_watcher_->ProcessValueWatcher(value_, var_);
425 ValueWatcher*
const value_watcher_;
426 const int64_t value_;
430 class VarDemon :
public Demon {
432 explicit VarDemon(ValueWatcher*
const watcher)
433 : value_watcher_(watcher) {}
435 ~VarDemon()
override {}
437 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
440 ValueWatcher*
const value_watcher_;
443 ValueWatcher(Solver*
const solver, DomainIntVar*
const variable)
444 : BaseValueWatcher(solver),
446 hole_iterator_(variable_->MakeHoleIterator(
true)),
448 watchers_(solver, variable->Min(), variable->Max()) {}
450 ~ValueWatcher()
override {}
452 IntVar* GetOrMakeValueWatcher(int64_t value)
override {
453 IntVar*
const watcher = watchers_.FindPtrOrNull(value,
nullptr);
454 if (watcher !=
nullptr)
return watcher;
455 if (variable_->Contains(value)) {
456 if (variable_->Bound()) {
457 return solver()->MakeIntConst(1);
459 const std::string vname = variable_->HasName()
461 : variable_->DebugString();
462 const std::string bname =
463 absl::StrFormat(
"Watch<%s == %d>", vname, value);
464 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
465 watchers_.UnsafeRevInsert(value, boolvar);
466 if (posted_.Switched()) {
468 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
469 var_demon_->desinhibit(solver());
474 return variable_->solver()->MakeIntConst(0);
478 void SetValueWatcher(IntVar*
const boolvar, int64_t value)
override {
479 CHECK(watchers_.FindPtrOrNull(value,
nullptr) ==
nullptr);
480 if (!boolvar->Bound()) {
481 watchers_.UnsafeRevInsert(value, boolvar);
482 if (posted_.Switched() && !boolvar->Bound()) {
484 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
485 var_demon_->desinhibit(solver());
490 void Post()
override {
491 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
492 variable_->WhenDomain(var_demon_);
493 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
494 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
495 const int64_t value =
w.first;
496 IntVar*
const boolvar =
w.second;
497 if (!boolvar->Bound() && variable_->Contains(value)) {
499 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
502 posted_.Switch(solver());
505 void InitialPropagate()
override {
506 if (variable_->Bound()) {
509 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
510 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
511 const int64_t value =
w.first;
512 IntVar*
const boolvar =
w.second;
513 if (!variable_->Contains(value)) {
514 boolvar->SetValue(0);
515 watchers_.RemoveAt(pos);
517 if (boolvar->Bound()) {
518 ProcessValueWatcher(value, boolvar);
519 watchers_.RemoveAt(pos);
527 void ProcessValueWatcher(int64_t value, IntVar* boolvar) {
528 if (boolvar->Min() == 0) {
529 if (variable_->Size() < 0xFFFFFF) {
530 variable_->RemoveValue(value);
533 solver()->AddConstraint(solver()->MakeNonEquality(variable_, value));
536 variable_->SetValue(value);
541 const int kSmallList = 16;
542 if (variable_->Bound()) {
544 }
else if (watchers_.Size() <= kSmallList ||
545 variable_->Min() != variable_->OldMin() ||
546 variable_->Max() != variable_->OldMax()) {
556 BitSet*
const bitset = variable_->bitset();
557 if (bitset !=
nullptr && !watchers_.Empty()) {
558 if (bitset->NumHoles() * 2 < watchers_.Size()) {
559 for (
const int64_t hole : InitAndGetValues(hole_iterator_)) {
561 IntVar*
const boolvar = watchers_.FindPtrOrNull(hole, &pos);
562 if (boolvar !=
nullptr) {
563 boolvar->SetValue(0);
564 watchers_.RemoveAt(pos);
576 void VariableBound() {
577 DCHECK(variable_->Bound());
578 const int64_t value = variable_->Min();
579 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
580 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
581 w.second->SetValue(
w.first == value);
583 watchers_.RemoveAll();
584 var_demon_->inhibit(solver());
588 void ScanWatchers() {
589 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
590 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
591 if (!variable_->Contains(
w.first)) {
592 IntVar*
const boolvar =
w.second;
593 boolvar->SetValue(0);
594 watchers_.RemoveAt(pos);
601 void CheckInhibit() {
602 if (watchers_.Empty()) {
603 var_demon_->inhibit(solver());
607 void Accept(ModelVisitor*
const visitor)
const override {
611 std::vector<int64_t> all_coefficients;
612 std::vector<IntVar*> all_bool_vars;
613 for (
int position = watchers_.start(); position < watchers_.end();
615 const std::pair<int64_t, IntVar*>&
w = watchers_.At(position);
616 all_coefficients.push_back(
w.first);
617 all_bool_vars.push_back(
w.second);
626 std::string DebugString()
const override {
627 return absl::StrFormat(
"ValueWatcher(%s)", variable_->DebugString());
631 DomainIntVar*
const variable_;
632 IntVarIterator*
const hole_iterator_;
635 RevIntPtrMap<IntVar> watchers_;
639 class DenseValueWatcher :
public BaseValueWatcher {
641 class WatchDemon :
public Demon {
643 WatchDemon(DenseValueWatcher*
const watcher, int64_t value, IntVar* var)
644 : value_watcher_(watcher), value_(value), var_(var) {}
645 ~WatchDemon()
override {}
647 void Run(Solver*
const solver)
override {
648 value_watcher_->ProcessValueWatcher(value_, var_);
652 DenseValueWatcher*
const value_watcher_;
653 const int64_t value_;
657 class VarDemon :
public Demon {
659 explicit VarDemon(DenseValueWatcher*
const watcher)
660 : value_watcher_(watcher) {}
662 ~VarDemon()
override {}
664 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
667 DenseValueWatcher*
const value_watcher_;
670 DenseValueWatcher(Solver*
const solver, DomainIntVar*
const variable)
671 : BaseValueWatcher(solver),
673 hole_iterator_(variable_->MakeHoleIterator(
true)),
675 offset_(variable->Min()),
676 watchers_(variable->Max() - variable->Min() + 1, nullptr),
677 active_watchers_(0) {}
679 ~DenseValueWatcher()
override {}
681 IntVar* GetOrMakeValueWatcher(int64_t value)
override {
682 const int64_t var_max = offset_ + watchers_.size() - 1;
683 if (value < offset_ || value > var_max) {
684 return solver()->MakeIntConst(0);
686 const int index = value - offset_;
687 IntVar*
const watcher = watchers_[index];
688 if (watcher !=
nullptr)
return watcher;
689 if (variable_->Contains(value)) {
690 if (variable_->Bound()) {
691 return solver()->MakeIntConst(1);
693 const std::string vname = variable_->HasName()
695 : variable_->DebugString();
696 const std::string bname =
697 absl::StrFormat(
"Watch<%s == %d>", vname, value);
698 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
699 RevInsert(index, boolvar);
700 if (posted_.Switched()) {
702 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
703 var_demon_->desinhibit(solver());
708 return variable_->solver()->MakeIntConst(0);
712 void SetValueWatcher(IntVar*
const boolvar, int64_t value)
override {
713 const int index = value - offset_;
714 CHECK(watchers_[index] ==
nullptr);
715 if (!boolvar->Bound()) {
716 RevInsert(index, boolvar);
717 if (posted_.Switched() && !boolvar->Bound()) {
719 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
720 var_demon_->desinhibit(solver());
725 void Post()
override {
726 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
727 variable_->WhenDomain(var_demon_);
728 for (
int pos = 0; pos < watchers_.size(); ++pos) {
729 const int64_t value = pos + offset_;
730 IntVar*
const boolvar = watchers_[pos];
731 if (boolvar !=
nullptr && !boolvar->Bound() &&
732 variable_->Contains(value)) {
734 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
737 posted_.Switch(solver());
740 void InitialPropagate()
override {
741 if (variable_->Bound()) {
744 for (
int pos = 0; pos < watchers_.size(); ++pos) {
745 IntVar*
const boolvar = watchers_[pos];
746 if (boolvar ==
nullptr)
continue;
747 const int64_t value = pos + offset_;
748 if (!variable_->Contains(value)) {
749 boolvar->SetValue(0);
751 }
else if (boolvar->Bound()) {
752 ProcessValueWatcher(value, boolvar);
756 if (active_watchers_.Value() == 0) {
757 var_demon_->inhibit(solver());
762 void ProcessValueWatcher(int64_t value, IntVar* boolvar) {
763 if (boolvar->Min() == 0) {
764 variable_->RemoveValue(value);
766 variable_->SetValue(value);
771 if (variable_->Bound()) {
776 if (active_watchers_.Value() == 0) {
777 var_demon_->inhibit(solver());
783 void VariableBound() {
784 DCHECK(variable_->Bound());
785 const int64_t value = variable_->Min();
786 for (
int pos = 0; pos < watchers_.size(); ++pos) {
787 IntVar*
const boolvar = watchers_[pos];
788 if (boolvar !=
nullptr) {
789 boolvar->SetValue(pos + offset_ == value);
793 var_demon_->inhibit(solver());
797 void ScanWatchers() {
798 const int64_t old_min_index = variable_->OldMin() - offset_;
799 const int64_t old_max_index = variable_->OldMax() - offset_;
800 const int64_t min_index = variable_->Min() - offset_;
801 const int64_t max_index = variable_->Max() - offset_;
802 for (
int pos = old_min_index; pos < min_index; ++pos) {
803 IntVar*
const boolvar = watchers_[pos];
804 if (boolvar !=
nullptr) {
805 boolvar->SetValue(0);
809 for (
int pos = max_index + 1; pos <= old_max_index; ++pos) {
810 IntVar*
const boolvar = watchers_[pos];
811 if (boolvar !=
nullptr) {
812 boolvar->SetValue(0);
816 BitSet*
const bitset = variable_->bitset();
817 if (bitset !=
nullptr) {
818 if (bitset->NumHoles() * 2 < active_watchers_.Value()) {
819 for (
const int64_t hole : InitAndGetValues(hole_iterator_)) {
820 IntVar*
const boolvar = watchers_[hole - offset_];
821 if (boolvar !=
nullptr) {
822 boolvar->SetValue(0);
823 RevRemove(hole - offset_);
827 for (
int pos = min_index + 1; pos < max_index; ++pos) {
828 IntVar*
const boolvar = watchers_[pos];
829 if (boolvar !=
nullptr && !variable_->Contains(offset_ + pos)) {
830 boolvar->SetValue(0);
838 void RevRemove(
int pos) {
839 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
840 watchers_[pos] =
nullptr;
841 active_watchers_.Decr(solver());
844 void RevInsert(
int pos, IntVar* boolvar) {
845 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
846 watchers_[pos] = boolvar;
847 active_watchers_.Incr(solver());
850 void Accept(ModelVisitor*
const visitor)
const override {
854 std::vector<int64_t> all_coefficients;
855 std::vector<IntVar*> all_bool_vars;
856 for (
int position = 0; position < watchers_.size(); ++position) {
857 if (watchers_[position] !=
nullptr) {
858 all_coefficients.push_back(position + offset_);
859 all_bool_vars.push_back(watchers_[position]);
869 std::string DebugString()
const override {
870 return absl::StrFormat(
"DenseValueWatcher(%s)", variable_->DebugString());
874 DomainIntVar*
const variable_;
875 IntVarIterator*
const hole_iterator_;
878 const int64_t offset_;
879 std::vector<IntVar*> watchers_;
880 NumericalRev<int> active_watchers_;
883 class BaseUpperBoundWatcher :
public Constraint {
885 explicit BaseUpperBoundWatcher(Solver*
const solver) : Constraint(solver) {}
887 ~BaseUpperBoundWatcher()
override {}
889 virtual IntVar* GetOrMakeUpperBoundWatcher(int64_t value) = 0;
891 virtual void SetUpperBoundWatcher(IntVar* boolvar, int64_t value) = 0;
897 class UpperBoundWatcher :
public BaseUpperBoundWatcher {
899 class WatchDemon :
public Demon {
901 WatchDemon(UpperBoundWatcher*
const watcher, int64_t index,
903 : value_watcher_(watcher), index_(index), var_(var) {}
904 ~WatchDemon()
override {}
906 void Run(Solver*
const solver)
override {
907 value_watcher_->ProcessUpperBoundWatcher(index_, var_);
911 UpperBoundWatcher*
const value_watcher_;
912 const int64_t index_;
916 class VarDemon :
public Demon {
918 explicit VarDemon(UpperBoundWatcher*
const watcher)
919 : value_watcher_(watcher) {}
920 ~VarDemon()
override {}
922 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
925 UpperBoundWatcher*
const value_watcher_;
928 UpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
929 : BaseUpperBoundWatcher(solver),
932 watchers_(solver, variable->Min(), variable->Max()),
937 ~UpperBoundWatcher()
override {}
939 IntVar* GetOrMakeUpperBoundWatcher(int64_t value)
override {
940 IntVar*
const watcher = watchers_.FindPtrOrNull(value,
nullptr);
941 if (watcher !=
nullptr) {
944 if (variable_->Max() >= value) {
945 if (variable_->Min() >= value) {
946 return solver()->MakeIntConst(1);
948 const std::string vname = variable_->HasName()
950 : variable_->DebugString();
951 const std::string bname =
952 absl::StrFormat(
"Watch<%s >= %d>", vname, value);
953 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
954 watchers_.UnsafeRevInsert(value, boolvar);
955 if (posted_.Switched()) {
957 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
958 var_demon_->desinhibit(solver());
964 return variable_->solver()->MakeIntConst(0);
968 void SetUpperBoundWatcher(IntVar*
const boolvar, int64_t value)
override {
969 CHECK(watchers_.FindPtrOrNull(value,
nullptr) ==
nullptr);
970 watchers_.UnsafeRevInsert(value, boolvar);
971 if (posted_.Switched() && !boolvar->Bound()) {
973 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
974 var_demon_->desinhibit(solver());
979 void Post()
override {
980 const int kTooSmallToSort = 8;
981 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
982 variable_->WhenRange(var_demon_);
984 if (watchers_.Size() > kTooSmallToSort) {
985 watchers_.SortActive();
987 start_.SetValue(solver(), watchers_.start());
988 end_.SetValue(solver(), watchers_.end() - 1);
991 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
992 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
993 IntVar*
const boolvar =
w.second;
994 const int64_t value =
w.first;
995 if (!boolvar->Bound() && value > variable_->Min() &&
996 value <= variable_->Max()) {
998 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
1001 posted_.Switch(solver());
1004 void InitialPropagate()
override {
1005 const int64_t var_min = variable_->Min();
1006 const int64_t var_max = variable_->Max();
1008 while (start_.Value() <= end_.Value()) {
1009 const std::pair<int64_t, IntVar*>&
w = watchers_.At(start_.Value());
1010 if (
w.first <= var_min) {
1011 w.second->SetValue(1);
1012 start_.Incr(solver());
1017 while (end_.Value() >= start_.Value()) {
1018 const std::pair<int64_t, IntVar*>&
w = watchers_.At(end_.Value());
1019 if (
w.first > var_max) {
1020 w.second->SetValue(0);
1021 end_.Decr(solver());
1026 for (
int i = start_.Value(); i <= end_.Value(); ++i) {
1027 const std::pair<int64_t, IntVar*>&
w = watchers_.At(i);
1028 if (
w.second->Bound()) {
1029 ProcessUpperBoundWatcher(
w.first,
w.second);
1032 if (start_.Value() > end_.Value()) {
1033 var_demon_->inhibit(solver());
1036 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1037 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
1038 const int64_t value =
w.first;
1039 IntVar*
const boolvar =
w.second;
1041 if (value <= var_min) {
1042 boolvar->SetValue(1);
1043 watchers_.RemoveAt(pos);
1044 }
else if (value > var_max) {
1045 boolvar->SetValue(0);
1046 watchers_.RemoveAt(pos);
1047 }
else if (boolvar->Bound()) {
1048 ProcessUpperBoundWatcher(value, boolvar);
1049 watchers_.RemoveAt(pos);
1055 void Accept(ModelVisitor*
const visitor)
const override {
1059 std::vector<int64_t> all_coefficients;
1060 std::vector<IntVar*> all_bool_vars;
1061 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1062 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
1063 all_coefficients.push_back(
w.first);
1064 all_bool_vars.push_back(
w.second);
1073 std::string DebugString()
const override {
1074 return absl::StrFormat(
"UpperBoundWatcher(%s)", variable_->DebugString());
1078 void ProcessUpperBoundWatcher(int64_t value, IntVar*
const boolvar) {
1079 if (boolvar->Min() == 0) {
1080 variable_->SetMax(value - 1);
1082 variable_->SetMin(value);
1087 const int64_t var_min = variable_->Min();
1088 const int64_t var_max = variable_->Max();
1090 while (start_.Value() <= end_.Value()) {
1091 const std::pair<int64_t, IntVar*>&
w = watchers_.At(start_.Value());
1092 if (
w.first <= var_min) {
1093 w.second->SetValue(1);
1094 start_.Incr(solver());
1099 while (end_.Value() >= start_.Value()) {
1100 const std::pair<int64_t, IntVar*>&
w = watchers_.At(end_.Value());
1101 if (
w.first > var_max) {
1102 w.second->SetValue(0);
1103 end_.Decr(solver());
1108 if (start_.Value() > end_.Value()) {
1109 var_demon_->inhibit(solver());
1112 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1113 const std::pair<int64_t, IntVar*>&
w = watchers_.At(pos);
1114 const int64_t value =
w.first;
1115 IntVar*
const boolvar =
w.second;
1117 if (value <= var_min) {
1118 boolvar->SetValue(1);
1119 watchers_.RemoveAt(pos);
1120 }
else if (value > var_max) {
1121 boolvar->SetValue(0);
1122 watchers_.RemoveAt(pos);
1125 if (watchers_.Empty()) {
1126 var_demon_->inhibit(solver());
1131 DomainIntVar*
const variable_;
1134 RevIntPtrMap<IntVar> watchers_;
1135 NumericalRev<int> start_;
1136 NumericalRev<int> end_;
1141 class DenseUpperBoundWatcher :
public BaseUpperBoundWatcher {
1143 class WatchDemon :
public Demon {
1145 WatchDemon(DenseUpperBoundWatcher*
const watcher, int64_t value,
1147 : value_watcher_(watcher), value_(value), var_(var) {}
1148 ~WatchDemon()
override {}
1150 void Run(Solver*
const solver)
override {
1151 value_watcher_->ProcessUpperBoundWatcher(value_, var_);
1155 DenseUpperBoundWatcher*
const value_watcher_;
1156 const int64_t value_;
1160 class VarDemon :
public Demon {
1162 explicit VarDemon(DenseUpperBoundWatcher*
const watcher)
1163 : value_watcher_(watcher) {}
1165 ~VarDemon()
override {}
1167 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
1170 DenseUpperBoundWatcher*
const value_watcher_;
1173 DenseUpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
1174 : BaseUpperBoundWatcher(solver),
1175 variable_(variable),
1176 var_demon_(nullptr),
1177 offset_(variable->Min()),
1178 watchers_(variable->Max() - variable->Min() + 1, nullptr),
1179 active_watchers_(0) {}
1181 ~DenseUpperBoundWatcher()
override {}
1183 IntVar* GetOrMakeUpperBoundWatcher(int64_t value)
override {
1184 if (variable_->Max() >= value) {
1185 if (variable_->Min() >= value) {
1186 return solver()->MakeIntConst(1);
1188 const std::string vname = variable_->HasName()
1190 : variable_->DebugString();
1191 const std::string bname =
1192 absl::StrFormat(
"Watch<%s >= %d>", vname, value);
1193 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
1194 RevInsert(value - offset_, boolvar);
1195 if (posted_.Switched()) {
1197 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
1198 var_demon_->desinhibit(solver());
1203 return variable_->solver()->MakeIntConst(0);
1207 void SetUpperBoundWatcher(IntVar*
const boolvar, int64_t value)
override {
1208 const int index = value - offset_;
1209 CHECK(watchers_[index] ==
nullptr);
1210 if (!boolvar->Bound()) {
1211 RevInsert(index, boolvar);
1212 if (posted_.Switched() && !boolvar->Bound()) {
1214 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
1215 var_demon_->desinhibit(solver());
1220 void Post()
override {
1221 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
1222 variable_->WhenRange(var_demon_);
1223 for (
int pos = 0; pos < watchers_.size(); ++pos) {
1224 const int64_t value = pos + offset_;
1225 IntVar*
const boolvar = watchers_[pos];
1226 if (boolvar !=
nullptr && !boolvar->Bound() &&
1227 value > variable_->Min() && value <= variable_->Max()) {
1229 solver()->RevAlloc(
new WatchDemon(
this, value, boolvar)));
1232 posted_.Switch(solver());
1235 void InitialPropagate()
override {
1236 for (
int pos = 0; pos < watchers_.size(); ++pos) {
1237 IntVar*
const boolvar = watchers_[pos];
1238 if (boolvar ==
nullptr)
continue;
1239 const int64_t value = pos + offset_;
1240 if (value <= variable_->Min()) {
1241 boolvar->SetValue(1);
1243 }
else if (value > variable_->Max()) {
1244 boolvar->SetValue(0);
1246 }
else if (boolvar->Bound()) {
1247 ProcessUpperBoundWatcher(value, boolvar);
1251 if (active_watchers_.Value() == 0) {
1252 var_demon_->inhibit(solver());
1256 void ProcessUpperBoundWatcher(int64_t value, IntVar* boolvar) {
1257 if (boolvar->Min() == 0) {
1258 variable_->SetMax(value - 1);
1260 variable_->SetMin(value);
1265 const int64_t old_min_index = variable_->OldMin() - offset_;
1266 const int64_t old_max_index = variable_->OldMax() - offset_;
1267 const int64_t min_index = variable_->Min() - offset_;
1268 const int64_t max_index = variable_->Max() - offset_;
1269 for (
int pos = old_min_index; pos <= min_index; ++pos) {
1270 IntVar*
const boolvar = watchers_[pos];
1271 if (boolvar !=
nullptr) {
1272 boolvar->SetValue(1);
1277 for (
int pos = max_index + 1; pos <= old_max_index; ++pos) {
1278 IntVar*
const boolvar = watchers_[pos];
1279 if (boolvar !=
nullptr) {
1280 boolvar->SetValue(0);
1284 if (active_watchers_.Value() == 0) {
1285 var_demon_->inhibit(solver());
1289 void RevRemove(
int pos) {
1290 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
1291 watchers_[pos] =
nullptr;
1292 active_watchers_.Decr(solver());
1295 void RevInsert(
int pos, IntVar* boolvar) {
1296 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
1297 watchers_[pos] = boolvar;
1298 active_watchers_.Incr(solver());
1301 void Accept(ModelVisitor*
const visitor)
const override {
1305 std::vector<int64_t> all_coefficients;
1306 std::vector<IntVar*> all_bool_vars;
1307 for (
int position = 0; position < watchers_.size(); ++position) {
1308 if (watchers_[position] !=
nullptr) {
1309 all_coefficients.push_back(position + offset_);
1310 all_bool_vars.push_back(watchers_[position]);
1320 std::string DebugString()
const override {
1321 return absl::StrFormat(
"DenseUpperBoundWatcher(%s)",
1322 variable_->DebugString());
1326 DomainIntVar*
const variable_;
1329 const int64_t offset_;
1330 std::vector<IntVar*> watchers_;
1331 NumericalRev<int> active_watchers_;
1335 DomainIntVar(Solver* s, int64_t vmin, int64_t vmax,
const std::string& name);
1336 DomainIntVar(Solver* s, absl::Span<const int64_t> sorted_values,
1337 const std::string& name);
1338 ~DomainIntVar()
override;
1340 int64_t Min()
const override {
return min_.Value(); }
1341 void SetMin(int64_t m)
override;
1342 int64_t Max()
const override {
return max_.Value(); }
1343 void SetMax(int64_t m)
override;
1344 void SetRange(int64_t mi, int64_t ma)
override;
1345 void SetValue(int64_t v)
override;
1346 bool Bound()
const override {
return (min_.Value() == max_.Value()); }
1347 int64_t
Value()
const override {
1348 CHECK_EQ(min_.Value(), max_.Value())
1349 <<
" variable " << DebugString() <<
" is not bound.";
1350 return min_.Value();
1352 void RemoveValue(int64_t v)
override;
1353 void RemoveInterval(int64_t l, int64_t u)
override;
1355 void WhenBound(Demon* d)
override {
1356 if (min_.Value() != max_.Value()) {
1358 delayed_bound_demons_.PushIfNotTop(solver(),
1361 bound_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1365 void WhenRange(Demon* d)
override {
1366 if (min_.Value() != max_.Value()) {
1368 delayed_range_demons_.PushIfNotTop(solver(),
1371 range_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1375 void WhenDomain(Demon* d)
override {
1376 if (min_.Value() != max_.Value()) {
1378 delayed_domain_demons_.PushIfNotTop(solver(),
1381 domain_demons_.PushIfNotTop(solver(), solver()->
RegisterDemon(d));
1386 IntVar* IsEqual(int64_t constant)
override {
1387 Solver*
const s = solver();
1388 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1389 return s->MakeIsLessOrEqualCstVar(
this, constant);
1391 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1392 return s->MakeIsGreaterOrEqualCstVar(
this, constant);
1394 if (!Contains(constant)) {
1395 return s->MakeIntConst(int64_t{0});
1397 if (Bound() && min_.Value() == constant) {
1398 return s->MakeIntConst(int64_t{1});
1400 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1402 if (cache !=
nullptr) {
1403 return cache->Var();
1405 if (value_watcher_ ==
nullptr) {
1406 if (
CapSub(Max(), Min()) <= 256) {
1407 solver()->SaveAndSetValue(
1408 reinterpret_cast<void**
>(&value_watcher_),
1409 reinterpret_cast<void*
>(
1410 solver()->RevAlloc(
new DenseValueWatcher(solver(),
this))));
1413 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1414 reinterpret_cast<void*
>(solver()->RevAlloc(
1415 new ValueWatcher(solver(),
this))));
1417 solver()->AddConstraint(value_watcher_);
1419 IntVar*
const boolvar = value_watcher_->GetOrMakeValueWatcher(constant);
1420 s->Cache()->InsertExprConstantExpression(
1426 Constraint*
SetIsEqual(absl::Span<const int64_t> values,
1427 const std::vector<IntVar*>& vars) {
1428 if (value_watcher_ ==
nullptr) {
1429 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1430 reinterpret_cast<void*
>(solver()->RevAlloc(
1431 new ValueWatcher(solver(),
this))));
1432 for (
int i = 0;
i < vars.size(); ++
i) {
1433 value_watcher_->SetValueWatcher(vars[i], values[i]);
1436 return value_watcher_;
1439 IntVar* IsDifferent(int64_t constant)
override {
1440 Solver*
const s = solver();
1441 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1442 return s->MakeIsGreaterOrEqualCstVar(
this, constant + 1);
1444 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1445 return s->MakeIsLessOrEqualCstVar(
this, constant - 1);
1447 if (!Contains(constant)) {
1448 return s->MakeIntConst(int64_t{1});
1450 if (Bound() && min_.Value() == constant) {
1451 return s->MakeIntConst(int64_t{0});
1453 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1455 if (cache !=
nullptr) {
1456 return cache->Var();
1458 IntVar*
const boolvar = s->MakeDifference(1, IsEqual(constant))->Var();
1459 s->Cache()->InsertExprConstantExpression(
1465 IntVar* IsGreaterOrEqual(int64_t constant)
override {
1466 Solver*
const s = solver();
1467 if (max_.Value() < constant) {
1468 return s->MakeIntConst(int64_t{0});
1470 if (min_.Value() >= constant) {
1471 return s->MakeIntConst(int64_t{1});
1473 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1475 if (cache !=
nullptr) {
1476 return cache->Var();
1478 if (bound_watcher_ ==
nullptr) {
1479 if (
CapSub(Max(), Min()) <= 256) {
1480 solver()->SaveAndSetValue(
1481 reinterpret_cast<void**
>(&bound_watcher_),
1482 reinterpret_cast<void*
>(solver()->RevAlloc(
1483 new DenseUpperBoundWatcher(solver(),
this))));
1484 solver()->AddConstraint(bound_watcher_);
1486 solver()->SaveAndSetValue(
1487 reinterpret_cast<void**
>(&bound_watcher_),
1488 reinterpret_cast<void*
>(
1489 solver()->RevAlloc(
new UpperBoundWatcher(solver(),
this))));
1490 solver()->AddConstraint(bound_watcher_);
1493 IntVar*
const boolvar =
1494 bound_watcher_->GetOrMakeUpperBoundWatcher(constant);
1495 s->Cache()->InsertExprConstantExpression(
1496 boolvar,
this, constant,
1503 const std::vector<IntVar*>& vars) {
1504 if (bound_watcher_ ==
nullptr) {
1505 if (
CapSub(Max(), Min()) <= 256) {
1506 solver()->SaveAndSetValue(
1507 reinterpret_cast<void**
>(&bound_watcher_),
1508 reinterpret_cast<void*
>(solver()->RevAlloc(
1509 new DenseUpperBoundWatcher(solver(),
this))));
1510 solver()->AddConstraint(bound_watcher_);
1512 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&bound_watcher_),
1513 reinterpret_cast<void*
>(solver()->RevAlloc(
1514 new UpperBoundWatcher(solver(),
this))));
1515 solver()->AddConstraint(bound_watcher_);
1517 for (
int i = 0;
i < values.size(); ++
i) {
1518 bound_watcher_->SetUpperBoundWatcher(vars[i], values[i]);
1521 return bound_watcher_;
1524 IntVar* IsLessOrEqual(int64_t constant)
override {
1525 Solver*
const s = solver();
1526 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1528 if (cache !=
nullptr) {
1529 return cache->Var();
1531 IntVar*
const boolvar =
1532 s->MakeDifference(1, IsGreaterOrEqual(constant + 1))->Var();
1533 s->Cache()->InsertExprConstantExpression(
1541 void CleanInProcess();
1542 uint64_t Size()
const override {
1543 if (bits_ !=
nullptr)
return bits_->Size();
1544 return (
static_cast<uint64_t
>(max_.Value()) -
1545 static_cast<uint64_t
>(min_.Value()) + 1);
1547 bool Contains(int64_t v)
const override {
1548 if (v < min_.Value() || v > max_.Value())
return false;
1549 return (bits_ ==
nullptr ?
true : bits_->Contains(v));
1551 IntVarIterator* MakeHoleIterator(
bool reversible)
const override;
1552 IntVarIterator* MakeDomainIterator(
bool reversible)
const override;
1553 int64_t OldMin()
const override {
return std::min(old_min_, min_.Value()); }
1554 int64_t OldMax()
const override {
return std::max(old_max_, max_.Value()); }
1556 std::string DebugString()
const override;
1557 BitSet* bitset()
const {
return bits_; }
1559 std::string BaseName()
const override {
return "IntegerVar"; }
1561 friend class PlusCstDomainIntVar;
1562 friend class LinkExprAndDomainIntVar;
1565 void CheckOldMin() {
1566 if (old_min_ > min_.Value()) {
1567 old_min_ = min_.Value();
1570 void CheckOldMax() {
1571 if (old_max_ < max_.Value()) {
1572 old_max_ = max_.Value();
1581 SimpleRevFIFO<Demon*> bound_demons_;
1582 SimpleRevFIFO<Demon*> range_demons_;
1583 SimpleRevFIFO<Demon*> domain_demons_;
1584 SimpleRevFIFO<Demon*> delayed_bound_demons_;
1585 SimpleRevFIFO<Demon*> delayed_range_demons_;
1586 SimpleRevFIFO<Demon*> delayed_domain_demons_;
1587 QueueHandler handler_;
1590 BaseValueWatcher* value_watcher_;
1591 BaseUpperBoundWatcher* bound_watcher_;
1600inline bool ClosedIntervalNoLargerThan(int64_t a, int64_t b, int64_t K) {
1610class SimpleBitSet :
public DomainIntVar::BitSet {
1612 SimpleBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1618 size_(vmax - vmin + 1),
1620 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1621 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1622 bits_ =
new uint64_t[bsize_];
1623 stamps_ =
new uint64_t[bsize_];
1624 for (
int i = 0;
i < bsize_; ++
i) {
1626 (
i == size_.Value() - 1) ? 63 -
BitPos64(size_.Value()) : 0;
1628 stamps_[
i] = s->stamp() - 1;
1632 SimpleBitSet(Solver*
const s, absl::Span<const int64_t> sorted_values,
1633 int64_t vmin, int64_t vmax)
1639 size_(sorted_values.size()),
1641 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1642 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1643 bits_ =
new uint64_t[bsize_];
1644 stamps_ =
new uint64_t[bsize_];
1645 for (
int i = 0;
i < bsize_; ++
i) {
1646 bits_[
i] = uint64_t{0};
1647 stamps_[
i] = s->stamp() - 1;
1649 for (
int i = 0;
i < sorted_values.size(); ++
i) {
1650 const int64_t val = sorted_values[
i];
1653 const int pos =
BitPos64(val - omin_);
1658 ~SimpleBitSet()
override {
1663 bool bit(int64_t val)
const {
return IsBitSet64(bits_, val - omin_); }
1665 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1666 DCHECK_GE(nmin, cmin);
1667 DCHECK_LE(nmin, cmax);
1668 DCHECK_LE(cmin, cmax);
1669 DCHECK_GE(cmin, omin_);
1670 DCHECK_LE(cmax, omax_);
1671 const int64_t new_min =
1674 const uint64_t removed_bits =
1676 size_.Add(solver_, -removed_bits);
1680 int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax)
override {
1681 DCHECK_GE(nmax, cmin);
1682 DCHECK_LE(nmax, cmax);
1683 DCHECK_LE(cmin, cmax);
1684 DCHECK_GE(cmin, omin_);
1685 DCHECK_LE(cmax, omax_);
1686 const int64_t new_max =
1689 const uint64_t removed_bits =
1691 size_.Add(solver_, -removed_bits);
1695 bool SetValue(int64_t val)
override {
1696 DCHECK_GE(val, omin_);
1697 DCHECK_LE(val, omax_);
1699 size_.SetValue(solver_, 1);
1705 bool Contains(int64_t val)
const override {
1706 DCHECK_GE(val, omin_);
1707 DCHECK_LE(val, omax_);
1711 bool RemoveValue(int64_t val)
override {
1712 if (val < omin_ || val > omax_ || !bit(val)) {
1716 const int64_t val_offset = val - omin_;
1718 const uint64_t current_stamp = solver_->stamp();
1719 if (stamps_[offset] < current_stamp) {
1720 stamps_[offset] = current_stamp;
1721 solver_->SaveValue(&bits_[offset]);
1723 const int pos =
BitPos64(val_offset);
1724 bits_[offset] &= ~OneBit64(pos);
1726 size_.Decr(solver_);
1732 uint64_t Size()
const override {
return size_.Value(); }
1734 std::string DebugString()
const override {
1736 absl::StrAppendFormat(&out,
"SimpleBitSet(%d..%d : ", omin_, omax_);
1737 for (
int i = 0;
i < bsize_; ++
i) {
1738 absl::StrAppendFormat(&out,
"%x", bits_[i]);
1744 void DelayRemoveValue(int64_t val)
override { removed_.push_back(val); }
1746 void ApplyRemovedValues(DomainIntVar* var)
override {
1747 std::sort(removed_.begin(), removed_.end());
1748 for (std::vector<int64_t>::iterator it = removed_.begin();
1749 it != removed_.end(); ++it) {
1750 var->RemoveValue(*it);
1754 void ClearRemovedValues()
override { removed_.clear(); }
1756 std::string pretty_DebugString(int64_t min, int64_t max)
const override {
1762 int64_t start_cumul = min;
1763 for (int64_t v = min + 1; v < max; ++v) {
1771 if (v == start_cumul + 1) {
1772 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1773 }
else if (v == start_cumul + 2) {
1774 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1776 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1783 if (max == start_cumul + 1) {
1784 absl::StrAppendFormat(&out,
"%d %d", start_cumul, max);
1786 absl::StrAppendFormat(&out,
"%d..%d", start_cumul, max);
1789 absl::StrAppendFormat(&out,
"%d", max);
1792 absl::StrAppendFormat(&out,
"%d", min);
1797 DomainIntVar::BitSetIterator* MakeIterator()
override {
1798 return new DomainIntVar::BitSetIterator(bits_, omin_);
1804 const int64_t omin_;
1805 const int64_t omax_;
1806 NumericalRev<int64_t> size_;
1808 std::vector<int64_t> removed_;
1814class SmallBitSet :
public DomainIntVar::BitSet {
1816 SmallBitSet(Solver*
const s, int64_t vmin, int64_t vmax)
1819 stamp_(s->stamp() - 1),
1822 size_(vmax - vmin + 1) {
1823 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1827 SmallBitSet(Solver*
const s, absl::Span<const int64_t> sorted_values,
1828 int64_t vmin, int64_t vmax)
1831 stamp_(s->stamp() - 1),
1834 size_(sorted_values.size()) {
1835 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1837 for (
int i = 0;
i < sorted_values.size(); ++
i) {
1838 const int64_t val = sorted_values[
i];
1839 DCHECK_GE(val, vmin);
1840 DCHECK_LE(val, vmax);
1846 ~SmallBitSet()
override {}
1848 bool bit(int64_t val)
const {
1849 DCHECK_GE(val, omin_);
1850 DCHECK_LE(val, omax_);
1851 return (bits_ &
OneBit64(val - omin_)) != 0;
1854 int64_t ComputeNewMin(int64_t nmin, int64_t cmin, int64_t cmax)
override {
1855 DCHECK_GE(nmin, cmin);
1856 DCHECK_LE(nmin, cmax);
1857 DCHECK_LE(cmin, cmax);
1858 DCHECK_GE(cmin, omin_);
1859 DCHECK_LE(cmax, omax_);
1864 const uint64_t new_bits = bits_ &
OneRange64(nmin - omin_, cmax - omin_);
1865 if (new_bits != uint64_t{0}) {
1867 size_.SetValue(solver_,
BitCount64(new_bits));
1874 return std::numeric_limits<int64_t>::max();
1878 int64_t ComputeNewMax(int64_t nmax, int64_t cmin, int64_t cmax)
override {
1879 DCHECK_GE(nmax, cmin);
1880 DCHECK_LE(nmax, cmax);
1881 DCHECK_LE(cmin, cmax);
1882 DCHECK_GE(cmin, omin_);
1883 DCHECK_LE(cmax, omax_);
1888 const uint64_t new_bits = bits_ &
OneRange64(cmin - omin_, nmax - omin_);
1889 if (new_bits != uint64_t{0}) {
1891 size_.SetValue(solver_,
BitCount64(new_bits));
1898 return std::numeric_limits<int64_t>::min();
1902 bool SetValue(int64_t val)
override {
1903 DCHECK_GE(val, omin_);
1904 DCHECK_LE(val, omax_);
1908 size_.SetValue(solver_, 1);
1914 bool Contains(int64_t val)
const override {
1915 DCHECK_GE(val, omin_);
1916 DCHECK_LE(val, omax_);
1920 bool RemoveValue(int64_t val)
override {
1921 DCHECK_GE(val, omin_);
1922 DCHECK_LE(val, omax_);
1925 const uint64_t current_stamp = solver_->stamp();
1926 if (stamp_ < current_stamp) {
1927 stamp_ = current_stamp;
1928 solver_->SaveValue(&bits_);
1930 bits_ &= ~OneBit64(val - omin_);
1933 size_.Decr(solver_);
1943 uint64_t Size()
const override {
return size_.Value(); }
1945 std::string DebugString()
const override {
1946 return absl::StrFormat(
"SmallBitSet(%d..%d : %llx)", omin_, omax_, bits_);
1949 void DelayRemoveValue(int64_t val)
override {
1950 DCHECK_GE(val, omin_);
1951 DCHECK_LE(val, omax_);
1952 removed_.push_back(val);
1955 void ApplyRemovedValues(DomainIntVar* var)
override {
1956 std::sort(removed_.begin(), removed_.end());
1957 for (std::vector<int64_t>::iterator it = removed_.begin();
1958 it != removed_.end(); ++it) {
1959 var->RemoveValue(*it);
1963 void ClearRemovedValues()
override { removed_.clear(); }
1965 std::string pretty_DebugString(int64_t min, int64_t max)
const override {
1971 int64_t start_cumul = min;
1972 for (int64_t v = min + 1; v < max; ++v) {
1980 if (v == start_cumul + 1) {
1981 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1982 }
else if (v == start_cumul + 2) {
1983 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1985 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1992 if (max == start_cumul + 1) {
1993 absl::StrAppendFormat(&out,
"%d %d", start_cumul, max);
1995 absl::StrAppendFormat(&out,
"%d..%d", start_cumul, max);
1998 absl::StrAppendFormat(&out,
"%d", max);
2001 absl::StrAppendFormat(&out,
"%d", min);
2006 DomainIntVar::BitSetIterator* MakeIterator()
override {
2007 return new DomainIntVar::BitSetIterator(&bits_, omin_);
2013 const int64_t omin_;
2014 const int64_t omax_;
2015 NumericalRev<int64_t> size_;
2016 std::vector<int64_t> removed_;
2021 ~EmptyIterator()
override {}
2022 void Init()
override {}
2023 bool Ok()
const override {
return false; }
2024 int64_t
Value()
const override {
2025 LOG(FATAL) <<
"Should not be called";
2028 void Next()
override {}
2033 explicit RangeIterator(
const IntVar*
const var)
2035 min_(std::numeric_limits<int64_t>::max()),
2036 max_(std::numeric_limits<int64_t>::min()),
2039 ~RangeIterator()
override {}
2041 void Init()
override {
2047 bool Ok()
const override {
return current_ <= max_; }
2049 int64_t
Value()
const override {
return current_; }
2051 void Next()
override { current_++; }
2054 const IntVar*
const var_;
2062 explicit DomainIntVarHoleIterator(
const DomainIntVar*
const v)
2063 : var_(v), bits_(nullptr), values_(nullptr), size_(0), index_(0) {}
2065 ~DomainIntVarHoleIterator()
override {}
2067 void Init()
override {
2068 bits_ = var_->bitset();
2069 if (bits_ !=
nullptr) {
2071 values_ = bits_->Holes().data();
2072 size_ = bits_->Holes().size();
2080 bool Ok()
const override {
return index_ < size_; }
2082 int64_t
Value()
const override {
2083 DCHECK(bits_ !=
nullptr);
2084 DCHECK(index_ < size_);
2085 return values_[index_];
2088 void Next()
override { index_++; }
2091 const DomainIntVar*
const var_;
2092 DomainIntVar::BitSet* bits_;
2093 const int64_t* values_;
2100 explicit DomainIntVarDomainIterator(
const DomainIntVar*
const v,
2103 bitset_iterator_(nullptr),
2104 min_(std::numeric_limits<int64_t>::max()),
2105 max_(std::numeric_limits<int64_t>::min()),
2107 reversible_(reversible) {}
2109 ~DomainIntVarDomainIterator()
override {
2110 if (!reversible_ && bitset_iterator_) {
2111 delete bitset_iterator_;
2115 void Init()
override {
2116 if (var_->bitset() !=
nullptr && !var_->Bound()) {
2118 if (!bitset_iterator_) {
2119 Solver*
const solver = var_->solver();
2120 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2121 bitset_iterator_ = solver->RevAlloc(var_->bitset()->MakeIterator());
2124 if (bitset_iterator_) {
2125 delete bitset_iterator_;
2127 bitset_iterator_ = var_->bitset()->MakeIterator();
2129 bitset_iterator_->Init(var_->Min(), var_->Max());
2131 if (bitset_iterator_) {
2133 Solver*
const solver = var_->solver();
2134 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2136 delete bitset_iterator_;
2138 bitset_iterator_ =
nullptr;
2146 bool Ok()
const override {
2147 return bitset_iterator_ ? bitset_iterator_->Ok() : (current_ <= max_);
2150 int64_t
Value()
const override {
2151 return bitset_iterator_ ? bitset_iterator_->Value() : current_;
2154 void Next()
override {
2155 if (bitset_iterator_) {
2156 bitset_iterator_->Next();
2163 const DomainIntVar*
const var_;
2164 DomainIntVar::BitSetIterator* bitset_iterator_;
2168 const bool reversible_;
2173 UnaryIterator(
const IntVar*
const v,
bool hole,
bool reversible)
2174 : iterator_(hole ? v->MakeHoleIterator(reversible)
2175 : v->MakeDomainIterator(reversible)),
2176 reversible_(reversible) {}
2178 ~UnaryIterator()
override {
2184 void Init()
override { iterator_->Init(); }
2186 bool Ok()
const override {
return iterator_->Ok(); }
2188 void Next()
override { iterator_->Next(); }
2191 IntVarIterator*
const iterator_;
2192 const bool reversible_;
2195DomainIntVar::DomainIntVar(
Solver*
const s, int64_t vmin, int64_t vmax,
2196 const std::string& name)
2207 value_watcher_(nullptr),
2208 bound_watcher_(nullptr) {}
2210DomainIntVar::DomainIntVar(
Solver*
const s,
2211 absl::Span<const int64_t> sorted_values,
2212 const std::string& name)
2214 min_(std::numeric_limits<int64_t>::max()),
2215 max_(std::numeric_limits<int64_t>::min()),
2216 old_min_(std::numeric_limits<int64_t>::max()),
2217 old_max_(std::numeric_limits<int64_t>::min()),
2218 new_min_(std::numeric_limits<int64_t>::max()),
2219 new_max_(std::numeric_limits<int64_t>::min()),
2223 value_watcher_(nullptr),
2224 bound_watcher_(nullptr) {
2225 CHECK_GE(sorted_values.size(), 1);
2227 const int64_t vmin = sorted_values.front();
2228 const int64_t vmax = sorted_values.back();
2229 const bool contiguous = vmax - vmin + 1 == sorted_values.size();
2231 min_.SetValue(
solver(), vmin);
2234 max_.SetValue(
solver(), vmax);
2239 if (vmax - vmin + 1 < 65) {
2241 new SmallBitSet(
solver(), sorted_values, vmin, vmax));
2244 new SimpleBitSet(
solver(), sorted_values, vmin, vmax));
2249DomainIntVar::~DomainIntVar() {}
2251void DomainIntVar::SetMin(int64_t m) {
2252 if (m <= min_.Value())
return;
2253 if (m > max_.Value()) solver()->Fail();
2257 if (new_min_ > new_max_) {
2263 const int64_t new_min =
2266 : bits_->ComputeNewMin(m, min_.Value(), max_.Value()));
2267 min_.SetValue(solver(), new_min);
2268 if (min_.Value() > max_.Value()) {
2275void DomainIntVar::SetMax(int64_t m) {
2276 if (m >= max_.Value())
return;
2277 if (m < min_.Value()) solver()->Fail();
2281 if (new_max_ < new_min_) {
2287 const int64_t new_max =
2290 : bits_->ComputeNewMax(m, min_.Value(), max_.Value()));
2291 max_.SetValue(solver(), new_max);
2292 if (min_.Value() > max_.Value()) {
2299void DomainIntVar::SetRange(int64_t mi, int64_t ma) {
2303 if (mi > ma || mi > max_.Value() || ma < min_.Value()) solver()->Fail();
2304 if (mi <= min_.Value() && ma >= max_.Value())
return;
2306 if (ma < new_max_) {
2309 if (mi > new_min_) {
2312 if (new_min_ > new_max_) {
2316 if (mi > min_.Value()) {
2318 const int64_t new_min =
2321 : bits_->ComputeNewMin(mi, min_.Value(), max_.Value()));
2322 min_.SetValue(solver(), new_min);
2324 if (min_.Value() > ma) {
2327 if (ma < max_.Value()) {
2329 const int64_t new_max =
2332 : bits_->ComputeNewMax(ma, min_.Value(), max_.Value()));
2333 max_.SetValue(solver(), new_max);
2335 if (min_.Value() > max_.Value()) {
2343void DomainIntVar::SetValue(int64_t v) {
2344 if (v != min_.Value() || v != max_.Value()) {
2345 if (v < min_.Value() || v > max_.Value()) {
2349 if (v > new_max_ || v < new_min_) {
2355 if (bits_ && !bits_->SetValue(v)) {
2360 min_.SetValue(solver(), v);
2361 max_.SetValue(solver(), v);
2367void DomainIntVar::RemoveValue(int64_t v) {
2368 if (v < min_.Value() || v > max_.Value())
return;
2369 if (v == min_.Value()) {
2371 }
else if (v == max_.Value()) {
2374 if (bits_ ==
nullptr) {
2378 if (v >= new_min_ && v <= new_max_ && bits_->Contains(v)) {
2379 bits_->DelayRemoveValue(v);
2382 if (bits_->RemoveValue(v)) {
2389void DomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2390 if (l <= min_.Value()) {
2392 }
else if (u >= max_.Value()) {
2395 for (int64_t v = l; v <= u; ++v) {
2401void DomainIntVar::CreateBits() {
2402 solver()->SaveValue(
reinterpret_cast<void**
>(&bits_));
2403 if (max_.Value() - min_.Value() < 64) {
2404 bits_ = solver()->RevAlloc(
2405 new SmallBitSet(solver(), min_.Value(), max_.Value()));
2407 bits_ = solver()->RevAlloc(
2408 new SimpleBitSet(solver(), min_.Value(), max_.Value()));
2412void DomainIntVar::CleanInProcess() {
2413 in_process_ =
false;
2414 if (bits_ !=
nullptr) {
2415 bits_->ClearHoles();
2419void DomainIntVar::Push() {
2420 const bool in_process = in_process_;
2421 EnqueueVar(&handler_);
2422 CHECK_EQ(in_process, in_process_);
2425void DomainIntVar::Process() {
2426 CHECK(!in_process_);
2428 if (bits_ !=
nullptr) {
2429 bits_->ClearRemovedValues();
2431 set_variable_to_clean_on_fail(
this);
2432 new_min_ = min_.Value();
2433 new_max_ = max_.Value();
2434 const bool is_bound = min_.Value() == max_.Value();
2435 const bool range_changed =
2436 min_.Value() != OldMin() || max_.Value() != OldMax();
2439 ExecuteAll(bound_demons_);
2441 if (range_changed) {
2442 ExecuteAll(range_demons_);
2444 ExecuteAll(domain_demons_);
2448 EnqueueAll(delayed_bound_demons_);
2450 if (range_changed) {
2451 EnqueueAll(delayed_range_demons_);
2453 EnqueueAll(delayed_domain_demons_);
2456 set_variable_to_clean_on_fail(
nullptr);
2458 old_min_ = min_.Value();
2459 old_max_ = max_.Value();
2460 if (min_.Value() < new_min_) {
2463 if (max_.Value() > new_max_) {
2466 if (bits_ !=
nullptr) {
2467 bits_->ApplyRemovedValues(
this);
2471template <
typename T>
2472T* CondRevAlloc(Solver* solver,
bool reversible, T*
object) {
2473 return reversible ? solver->RevAlloc(
object) : object;
2476IntVarIterator* DomainIntVar::MakeHoleIterator(
bool reversible)
const {
2477 return CondRevAlloc(solver(), reversible,
new DomainIntVarHoleIterator(
this));
2480IntVarIterator* DomainIntVar::MakeDomainIterator(
bool reversible)
const {
2481 return CondRevAlloc(solver(), reversible,
2482 new DomainIntVarDomainIterator(
this, reversible));
2485std::string DomainIntVar::DebugString()
const {
2487 const std::string& var_name = name();
2488 if (!var_name.empty()) {
2489 out = var_name +
"(";
2491 out =
"DomainIntVar(";
2493 if (min_.Value() == max_.Value()) {
2494 absl::StrAppendFormat(&out,
"%d", min_.Value());
2495 }
else if (bits_ !=
nullptr) {
2496 out.append(bits_->pretty_DebugString(min_.Value(), max_.Value()));
2498 absl::StrAppendFormat(&out,
"%d..%d", min_.Value(), max_.Value());
2506class ConcreteBooleanVar :
public BooleanVar {
2509 class Handler :
public Demon {
2511 explicit Handler(ConcreteBooleanVar*
const var) : Demon(), var_(var) {}
2512 ~Handler()
override {}
2513 void Run(Solver*
const s)
override {
2514 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
2516 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
2518 Solver::DemonPriority priority()
const override {
2519 return Solver::VAR_PRIORITY;
2521 std::string DebugString()
const override {
2522 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
2526 ConcreteBooleanVar*
const var_;
2529 ConcreteBooleanVar(Solver*
const s,
const std::string& name)
2530 : BooleanVar(s, name), handler_(this) {}
2532 ~ConcreteBooleanVar()
override {}
2534 void SetValue(int64_t v)
override {
2535 if (value_ == kUnboundBooleanVarValue) {
2536 if ((v & 0xfffffffffffffffe) == 0) {
2538 value_ =
static_cast<int>(v);
2539 EnqueueVar(&handler_);
2542 }
else if (v == value_) {
2549 DCHECK_NE(value_, kUnboundBooleanVarValue);
2550 ExecuteAll(bound_demons_);
2551 for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_); it.ok();
2553 EnqueueDelayedDemon(*it);
2557 int64_t OldMin()
const override {
return 0LL; }
2558 int64_t OldMax()
const override {
return 1LL; }
2559 void RestoreValue()
override { value_ = kUnboundBooleanVarValue; }
2567class IntConst :
public IntVar {
2569 IntConst(Solver*
const s, int64_t value,
const std::string& name =
"")
2570 : IntVar(s, name), value_(value) {}
2571 ~IntConst()
override {}
2573 int64_t Min()
const override {
return value_; }
2574 void SetMin(int64_t m)
override {
2579 int64_t Max()
const override {
return value_; }
2580 void SetMax(int64_t m)
override {
2585 void SetRange(int64_t l, int64_t u)
override {
2586 if (l > value_ || u < value_) {
2590 void SetValue(int64_t v)
override {
2595 bool Bound()
const override {
return true; }
2596 int64_t
Value()
const override {
return value_; }
2597 void RemoveValue(int64_t v)
override {
2602 void RemoveInterval(int64_t l, int64_t u)
override {
2603 if (l <= value_ && value_ <= u) {
2607 void WhenBound(Demon* d)
override {}
2608 void WhenRange(Demon* d)
override {}
2609 void WhenDomain(Demon* d)
override {}
2610 uint64_t Size()
const override {
return 1; }
2611 bool Contains(int64_t v)
const override {
return (v == value_); }
2612 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2613 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
2615 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2616 return CondRevAlloc(solver(), reversible,
new RangeIterator(
this));
2618 int64_t OldMin()
const override {
return value_; }
2619 int64_t OldMax()
const override {
return value_; }
2620 std::string DebugString()
const override {
2622 if (solver()->HasName(
this)) {
2623 const std::string& var_name = name();
2624 absl::StrAppendFormat(&out,
"%s(%d)", var_name, value_);
2626 absl::StrAppendFormat(&out,
"IntConst(%d)", value_);
2631 int VarType()
const override {
return CONST_VAR; }
2633 IntVar* IsEqual(int64_t constant)
override {
2634 if (constant == value_) {
2635 return solver()->MakeIntConst(1);
2637 return solver()->MakeIntConst(0);
2641 IntVar* IsDifferent(int64_t constant)
override {
2642 if (constant == value_) {
2643 return solver()->MakeIntConst(0);
2645 return solver()->MakeIntConst(1);
2649 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2650 return solver()->MakeIntConst(value_ >= constant);
2653 IntVar* IsLessOrEqual(int64_t constant)
override {
2654 return solver()->MakeIntConst(value_ <= constant);
2657 std::string name()
const override {
2658 if (solver()->HasName(
this)) {
2659 return PropagationBaseObject::name();
2661 return absl::StrCat(value_);
2671class PlusCstVar :
public IntVar {
2673 PlusCstVar(Solver*
const s, IntVar* v, int64_t c)
2674 : IntVar(s), var_(v), cst_(
c) {}
2676 ~PlusCstVar()
override {}
2678 void WhenRange(Demon* d)
override { var_->
WhenRange(d); }
2680 void WhenBound(Demon* d)
override { var_->
WhenBound(d); }
2682 void WhenDomain(Demon* d)
override { var_->
WhenDomain(d); }
2684 int64_t OldMin()
const override {
return CapAdd(var_->
OldMin(), cst_); }
2686 int64_t OldMax()
const override {
return CapAdd(var_->
OldMax(), cst_); }
2688 std::string DebugString()
const override {
2690 return absl::StrFormat(
"%s(%s + %d)", name(), var_->
DebugString(), cst_);
2692 return absl::StrFormat(
"(%s + %d)", var_->
DebugString(), cst_);
2696 int VarType()
const override {
return VAR_ADD_CST; }
2698 void Accept(ModelVisitor*
const visitor)
const override {
2699 visitor->VisitIntegerVariable(
this, ModelVisitor::kSumOperation, cst_,
2703 IntVar* IsEqual(int64_t constant)
override {
2704 return var_->
IsEqual(constant - cst_);
2707 IntVar* IsDifferent(int64_t constant)
override {
2711 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2715 IntVar* IsLessOrEqual(int64_t constant)
override {
2719 IntVar* SubVar()
const {
return var_; }
2721 int64_t Constant()
const {
return cst_; }
2728class PlusCstIntVar :
public PlusCstVar {
2730 class PlusCstIntVarIterator :
public UnaryIterator {
2732 PlusCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2733 : UnaryIterator(v, hole, rev), cst_(
c) {}
2735 ~PlusCstIntVarIterator()
override {}
2737 int64_t
Value()
const override {
return iterator_->Value() + cst_; }
2743 PlusCstIntVar(Solver*
const s, IntVar* v, int64_t c) : PlusCstVar(s, v,
c) {}
2745 ~PlusCstIntVar()
override {}
2747 int64_t Min()
const override {
return var_->Min() + cst_; }
2749 void SetMin(int64_t m)
override { var_->SetMin(
CapSub(m, cst_)); }
2751 int64_t Max()
const override {
return var_->Max() + cst_; }
2753 void SetMax(int64_t m)
override { var_->SetMax(
CapSub(m, cst_)); }
2755 void SetRange(int64_t l, int64_t u)
override {
2759 void SetValue(int64_t v)
override { var_->SetValue(v - cst_); }
2761 int64_t
Value()
const override {
return var_->Value() + cst_; }
2763 bool Bound()
const override {
return var_->Bound(); }
2765 void RemoveValue(int64_t v)
override { var_->RemoveValue(v - cst_); }
2767 void RemoveInterval(int64_t l, int64_t u)
override {
2768 var_->RemoveInterval(l - cst_, u - cst_);
2771 uint64_t Size()
const override {
return var_->Size(); }
2773 bool Contains(int64_t v)
const override {
return var_->Contains(v - cst_); }
2775 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2776 return CondRevAlloc(
2777 solver(), reversible,
2778 new PlusCstIntVarIterator(var_, cst_,
true, reversible));
2780 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2781 return CondRevAlloc(
2782 solver(), reversible,
2783 new PlusCstIntVarIterator(var_, cst_,
false, reversible));
2787class PlusCstDomainIntVar :
public PlusCstVar {
2789 class PlusCstDomainIntVarIterator :
public UnaryIterator {
2791 PlusCstDomainIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
2793 : UnaryIterator(v, hole, reversible), cst_(
c) {}
2795 ~PlusCstDomainIntVarIterator()
override {}
2797 int64_t
Value()
const override {
return iterator_->Value() + cst_; }
2803 PlusCstDomainIntVar(Solver*
const s, DomainIntVar* v, int64_t c)
2804 : PlusCstVar(s, v,
c) {}
2806 ~PlusCstDomainIntVar()
override {}
2808 int64_t Min()
const override;
2809 void SetMin(int64_t m)
override;
2810 int64_t Max()
const override;
2811 void SetMax(int64_t m)
override;
2812 void SetRange(int64_t l, int64_t u)
override;
2813 void SetValue(int64_t v)
override;
2814 bool Bound()
const override;
2815 int64_t
Value()
const override;
2816 void RemoveValue(int64_t v)
override;
2817 void RemoveInterval(int64_t l, int64_t u)
override;
2818 uint64_t Size()
const override;
2819 bool Contains(int64_t v)
const override;
2821 DomainIntVar* domain_int_var()
const {
2822 return reinterpret_cast<DomainIntVar*
>(var_);
2825 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2826 return CondRevAlloc(
2827 solver(), reversible,
2828 new PlusCstDomainIntVarIterator(var_, cst_,
true, reversible));
2830 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2831 return CondRevAlloc(
2832 solver(), reversible,
2833 new PlusCstDomainIntVarIterator(var_, cst_,
false, reversible));
2837int64_t PlusCstDomainIntVar::Min()
const {
2838 return domain_int_var()->min_.Value() + cst_;
2841void PlusCstDomainIntVar::SetMin(int64_t m) {
2842 domain_int_var()->DomainIntVar::SetMin(
CapSub(m, cst_));
2845int64_t PlusCstDomainIntVar::Max()
const {
2846 return domain_int_var()->max_.Value() + cst_;
2849void PlusCstDomainIntVar::SetMax(int64_t m) {
2850 domain_int_var()->DomainIntVar::SetMax(
CapSub(m, cst_));
2853void PlusCstDomainIntVar::SetRange(int64_t l, int64_t u) {
2854 domain_int_var()->DomainIntVar::SetRange(l - cst_, u - cst_);
2857void PlusCstDomainIntVar::SetValue(int64_t v) {
2858 domain_int_var()->DomainIntVar::SetValue(v - cst_);
2861bool PlusCstDomainIntVar::Bound()
const {
2862 return domain_int_var()->min_.Value() == domain_int_var()->max_.Value();
2865int64_t PlusCstDomainIntVar::Value()
const {
2866 CHECK_EQ(domain_int_var()->min_.Value(), domain_int_var()->max_.Value())
2867 <<
" variable is not bound";
2868 return domain_int_var()->min_.Value() + cst_;
2871void PlusCstDomainIntVar::RemoveValue(int64_t v) {
2872 domain_int_var()->DomainIntVar::RemoveValue(v - cst_);
2875void PlusCstDomainIntVar::RemoveInterval(int64_t l, int64_t u) {
2876 domain_int_var()->DomainIntVar::RemoveInterval(l - cst_, u - cst_);
2879uint64_t PlusCstDomainIntVar::Size()
const {
2880 return domain_int_var()->DomainIntVar::Size();
2883bool PlusCstDomainIntVar::Contains(int64_t v)
const {
2884 return domain_int_var()->DomainIntVar::Contains(v - cst_);
2889class SubCstIntVar :
public IntVar {
2891 class SubCstIntVarIterator :
public UnaryIterator {
2893 SubCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
bool rev)
2894 : UnaryIterator(v, hole, rev), cst_(
c) {}
2895 ~SubCstIntVarIterator()
override {}
2897 int64_t
Value()
const override {
return cst_ - iterator_->Value(); }
2903 SubCstIntVar(Solver* s, IntVar* v, int64_t c);
2904 ~SubCstIntVar()
override;
2906 int64_t Min()
const override;
2907 void SetMin(int64_t m)
override;
2908 int64_t Max()
const override;
2909 void SetMax(int64_t m)
override;
2910 void SetRange(int64_t l, int64_t u)
override;
2911 void SetValue(int64_t v)
override;
2912 bool Bound()
const override;
2913 int64_t
Value()
const override;
2914 void RemoveValue(int64_t v)
override;
2915 void RemoveInterval(int64_t l, int64_t u)
override;
2916 uint64_t Size()
const override;
2917 bool Contains(int64_t v)
const override;
2918 void WhenRange(Demon* d)
override;
2919 void WhenBound(Demon* d)
override;
2920 void WhenDomain(Demon* d)
override;
2921 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2922 return CondRevAlloc(solver(), reversible,
2923 new SubCstIntVarIterator(var_, cst_,
true, reversible));
2925 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2926 return CondRevAlloc(
2927 solver(), reversible,
2928 new SubCstIntVarIterator(var_, cst_,
false, reversible));
2930 int64_t OldMin()
const override {
return CapSub(cst_, var_->
OldMax()); }
2931 int64_t OldMax()
const override {
return CapSub(cst_, var_->
OldMin()); }
2932 std::string DebugString()
const override;
2933 std::string name()
const override;
2934 int VarType()
const override {
return CST_SUB_VAR; }
2936 void Accept(ModelVisitor*
const visitor)
const override {
2937 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation,
2941 IntVar* IsEqual(int64_t constant)
override {
2942 return var_->
IsEqual(cst_ - constant);
2945 IntVar* IsDifferent(int64_t constant)
override {
2949 IntVar* IsGreaterOrEqual(int64_t constant)
override {
2953 IntVar* IsLessOrEqual(int64_t constant)
override {
2957 IntVar* SubVar()
const {
return var_; }
2958 int64_t Constant()
const {
return cst_; }
2965SubCstIntVar::SubCstIntVar(Solver*
const s, IntVar* v, int64_t c)
2966 : IntVar(s), var_(v), cst_(
c) {}
2968SubCstIntVar::~SubCstIntVar() {}
2970int64_t SubCstIntVar::Min()
const {
return cst_ - var_->
Max(); }
2972void SubCstIntVar::SetMin(int64_t m) { var_->
SetMax(
CapSub(cst_, m)); }
2974int64_t SubCstIntVar::Max()
const {
return cst_ - var_->
Min(); }
2976void SubCstIntVar::SetMax(int64_t m) { var_->
SetMin(
CapSub(cst_, m)); }
2978void SubCstIntVar::SetRange(int64_t l, int64_t u) {
2982void SubCstIntVar::SetValue(int64_t v) { var_->
SetValue(cst_ - v); }
2984bool SubCstIntVar::Bound()
const {
return var_->
Bound(); }
2986void SubCstIntVar::WhenRange(Demon* d) { var_->
WhenRange(d); }
2988int64_t SubCstIntVar::Value()
const {
return cst_ - var_->
Value(); }
2990void SubCstIntVar::RemoveValue(int64_t v) { var_->
RemoveValue(cst_ - v); }
2992void SubCstIntVar::RemoveInterval(int64_t l, int64_t u) {
2996void SubCstIntVar::WhenBound(Demon* d) { var_->
WhenBound(d); }
2998void SubCstIntVar::WhenDomain(Demon* d) { var_->
WhenDomain(d); }
3000uint64_t SubCstIntVar::Size()
const {
return var_->
Size(); }
3002bool SubCstIntVar::Contains(int64_t v)
const {
3006std::string SubCstIntVar::DebugString()
const {
3007 if (cst_ == 1 && var_->
VarType() == BOOLEAN_VAR) {
3008 return absl::StrFormat(
"Not(%s)", var_->
DebugString());
3010 return absl::StrFormat(
"(%d - %s)", cst_, var_->
DebugString());
3014std::string SubCstIntVar::name()
const {
3015 if (solver()->HasName(
this)) {
3016 return PropagationBaseObject::name();
3017 }
else if (cst_ == 1 && var_->
VarType() == BOOLEAN_VAR) {
3018 return absl::StrFormat(
"Not(%s)", var_->
name());
3020 return absl::StrFormat(
"(%d - %s)", cst_, var_->
name());
3026class OppIntVar :
public IntVar {
3028 class OppIntVarIterator :
public UnaryIterator {
3030 OppIntVarIterator(
const IntVar*
const v,
bool hole,
bool reversible)
3031 : UnaryIterator(v, hole, reversible) {}
3032 ~OppIntVarIterator()
override {}
3034 int64_t
Value()
const override {
return -iterator_->Value(); }
3037 OppIntVar(Solver* s, IntVar* v);
3038 ~OppIntVar()
override;
3040 int64_t Min()
const override;
3041 void SetMin(int64_t m)
override;
3042 int64_t Max()
const override;
3043 void SetMax(int64_t m)
override;
3044 void SetRange(int64_t l, int64_t u)
override;
3045 void SetValue(int64_t v)
override;
3046 bool Bound()
const override;
3047 int64_t
Value()
const override;
3048 void RemoveValue(int64_t v)
override;
3049 void RemoveInterval(int64_t l, int64_t u)
override;
3050 uint64_t Size()
const override;
3051 bool Contains(int64_t v)
const override;
3052 void WhenRange(Demon* d)
override;
3053 void WhenBound(Demon* d)
override;
3054 void WhenDomain(Demon* d)
override;
3055 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3056 return CondRevAlloc(solver(), reversible,
3057 new OppIntVarIterator(var_,
true, reversible));
3059 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3060 return CondRevAlloc(solver(), reversible,
3061 new OppIntVarIterator(var_,
false, reversible));
3063 int64_t OldMin()
const override {
return CapOpp(var_->
OldMax()); }
3064 int64_t OldMax()
const override {
return CapOpp(var_->
OldMin()); }
3065 std::string DebugString()
const override;
3066 int VarType()
const override {
return OPP_VAR; }
3068 void Accept(ModelVisitor*
const visitor)
const override {
3069 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation, 0,
3073 IntVar* IsEqual(int64_t constant)
override {
3074 return var_->
IsEqual(-constant);
3077 IntVar* IsDifferent(int64_t constant)
override {
3081 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3085 IntVar* IsLessOrEqual(int64_t constant)
override {
3089 IntVar* SubVar()
const {
return var_; }
3095OppIntVar::OppIntVar(Solver*
const s, IntVar* v) : IntVar(s), var_(v) {}
3097OppIntVar::~OppIntVar() {}
3099int64_t OppIntVar::Min()
const {
return -var_->
Max(); }
3101void OppIntVar::SetMin(int64_t m) { var_->
SetMax(
CapOpp(m)); }
3103int64_t OppIntVar::Max()
const {
return -var_->
Min(); }
3105void OppIntVar::SetMax(int64_t m) { var_->
SetMin(
CapOpp(m)); }
3107void OppIntVar::SetRange(int64_t l, int64_t u) {
3111void OppIntVar::SetValue(int64_t v) { var_->
SetValue(
CapOpp(v)); }
3113bool OppIntVar::Bound()
const {
return var_->
Bound(); }
3115void OppIntVar::WhenRange(Demon* d) { var_->
WhenRange(d); }
3117int64_t OppIntVar::Value()
const {
return -var_->
Value(); }
3119void OppIntVar::RemoveValue(int64_t v) { var_->
RemoveValue(-v); }
3121void OppIntVar::RemoveInterval(int64_t l, int64_t u) {
3125void OppIntVar::WhenBound(Demon* d) { var_->
WhenBound(d); }
3127void OppIntVar::WhenDomain(Demon* d) { var_->
WhenDomain(d); }
3129uint64_t OppIntVar::Size()
const {
return var_->
Size(); }
3131bool OppIntVar::Contains(int64_t v)
const {
return var_->
Contains(-v); }
3133std::string OppIntVar::DebugString()
const {
3134 return absl::StrFormat(
"-(%s)", var_->
DebugString());
3141class TimesCstIntVar :
public IntVar {
3143 TimesCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3144 : IntVar(s), var_(v), cst_(
c) {}
3145 ~TimesCstIntVar()
override {}
3147 IntVar* SubVar()
const {
return var_; }
3148 int64_t Constant()
const {
return cst_; }
3150 void Accept(ModelVisitor*
const visitor)
const override {
3151 visitor->VisitIntegerVariable(
this, ModelVisitor::kProductOperation, cst_,
3155 IntVar* IsEqual(int64_t constant)
override {
3156 if (constant % cst_ == 0) {
3157 return var_->
IsEqual(constant / cst_);
3159 return solver()->MakeIntConst(0);
3163 IntVar* IsDifferent(int64_t constant)
override {
3164 if (constant % cst_ == 0) {
3167 return solver()->MakeIntConst(1);
3171 IntVar* IsGreaterOrEqual(int64_t constant)
override {
3179 IntVar* IsLessOrEqual(int64_t constant)
override {
3187 std::string DebugString()
const override {
3188 return absl::StrFormat(
"(%s * %d)", var_->
DebugString(), cst_);
3198class TimesPosCstIntVar :
public TimesCstIntVar {
3200 class TimesPosCstIntVarIterator :
public UnaryIterator {
3202 TimesPosCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3204 : UnaryIterator(v, hole, reversible), cst_(
c) {}
3205 ~TimesPosCstIntVarIterator()
override {}
3207 int64_t
Value()
const override {
return iterator_->Value() * cst_; }
3213 TimesPosCstIntVar(Solver* s, IntVar* v, int64_t c);
3214 ~TimesPosCstIntVar()
override;
3216 int64_t Min()
const override;
3217 void SetMin(int64_t m)
override;
3218 int64_t Max()
const override;
3219 void SetMax(int64_t m)
override;
3220 void SetRange(int64_t l, int64_t u)
override;
3221 void SetValue(int64_t v)
override;
3222 bool Bound()
const override;
3223 int64_t
Value()
const override;
3224 void RemoveValue(int64_t v)
override;
3225 void RemoveInterval(int64_t l, int64_t u)
override;
3226 uint64_t Size()
const override;
3227 bool Contains(int64_t v)
const override;
3228 void WhenRange(Demon* d)
override;
3229 void WhenBound(Demon* d)
override;
3230 void WhenDomain(Demon* d)
override;
3231 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3232 return CondRevAlloc(
3233 solver(), reversible,
3234 new TimesPosCstIntVarIterator(var_, cst_,
true, reversible));
3236 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3237 return CondRevAlloc(
3238 solver(), reversible,
3239 new TimesPosCstIntVarIterator(var_, cst_,
false, reversible));
3241 int64_t OldMin()
const override {
return CapProd(var_->OldMin(), cst_); }
3242 int64_t OldMax()
const override {
return CapProd(var_->OldMax(), cst_); }
3247TimesPosCstIntVar::TimesPosCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3248 : TimesCstIntVar(s, v,
c) {}
3250TimesPosCstIntVar::~TimesPosCstIntVar() {}
3252int64_t TimesPosCstIntVar::Min()
const {
return CapProd(var_->Min(), cst_); }
3254void TimesPosCstIntVar::SetMin(int64_t m) {
3255 if (m != std::numeric_limits<int64_t>::min()) {
3260int64_t TimesPosCstIntVar::Max()
const {
return CapProd(var_->Max(), cst_); }
3262void TimesPosCstIntVar::SetMax(int64_t m) {
3263 if (m != std::numeric_limits<int64_t>::max()) {
3268void TimesPosCstIntVar::SetRange(int64_t l, int64_t u) {
3272void TimesPosCstIntVar::SetValue(int64_t v) {
3273 if (v % cst_ != 0) {
3276 var_->SetValue(v / cst_);
3279bool TimesPosCstIntVar::Bound()
const {
return var_->Bound(); }
3281void TimesPosCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3283int64_t TimesPosCstIntVar::Value()
const {
3284 return CapProd(var_->Value(), cst_);
3287void TimesPosCstIntVar::RemoveValue(int64_t v) {
3288 if (v % cst_ == 0) {
3289 var_->RemoveValue(v / cst_);
3293void TimesPosCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3294 for (int64_t v = l; v <= u; ++v) {
3300void TimesPosCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3302void TimesPosCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3304uint64_t TimesPosCstIntVar::Size()
const {
return var_->Size(); }
3306bool TimesPosCstIntVar::Contains(int64_t v)
const {
3307 return (v % cst_ == 0 && var_->Contains(v / cst_));
3312class TimesPosCstBoolVar :
public TimesCstIntVar {
3314 class TimesPosCstBoolVarIterator :
public UnaryIterator {
3317 TimesPosCstBoolVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3319 : UnaryIterator(v, hole, reversible), cst_(
c) {}
3320 ~TimesPosCstBoolVarIterator()
override {}
3322 int64_t
Value()
const override {
return iterator_->Value() * cst_; }
3328 TimesPosCstBoolVar(Solver* s, BooleanVar* v, int64_t c);
3329 ~TimesPosCstBoolVar()
override;
3331 int64_t Min()
const override;
3332 void SetMin(int64_t m)
override;
3333 int64_t Max()
const override;
3334 void SetMax(int64_t m)
override;
3335 void SetRange(int64_t l, int64_t u)
override;
3336 void SetValue(int64_t v)
override;
3337 bool Bound()
const override;
3338 int64_t
Value()
const override;
3339 void RemoveValue(int64_t v)
override;
3340 void RemoveInterval(int64_t l, int64_t u)
override;
3341 uint64_t Size()
const override;
3342 bool Contains(int64_t v)
const override;
3343 void WhenRange(Demon* d)
override;
3344 void WhenBound(Demon* d)
override;
3345 void WhenDomain(Demon* d)
override;
3346 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3347 return CondRevAlloc(solver(), reversible,
new EmptyIterator());
3349 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3350 return CondRevAlloc(
3351 solver(), reversible,
3352 new TimesPosCstBoolVarIterator(boolean_var(), cst_,
false, reversible));
3354 int64_t OldMin()
const override {
return 0; }
3355 int64_t OldMax()
const override {
return cst_; }
3357 BooleanVar* boolean_var()
const {
3358 return reinterpret_cast<BooleanVar*
>(var_);
3364TimesPosCstBoolVar::TimesPosCstBoolVar(Solver*
const s, BooleanVar* v,
3366 : TimesCstIntVar(s, v,
c) {}
3368TimesPosCstBoolVar::~TimesPosCstBoolVar() {}
3370int64_t TimesPosCstBoolVar::Min()
const {
3371 return (boolean_var()->RawValue() == 1) * cst_;
3374void TimesPosCstBoolVar::SetMin(int64_t m) {
3378 boolean_var()->SetMin(1);
3382int64_t TimesPosCstBoolVar::Max()
const {
3383 return (boolean_var()->RawValue() != 0) * cst_;
3386void TimesPosCstBoolVar::SetMax(int64_t m) {
3389 }
else if (m < cst_) {
3390 boolean_var()->SetMax(0);
3394void TimesPosCstBoolVar::SetRange(int64_t l, int64_t u) {
3395 if (u < 0 || l > cst_ || l > u) {
3399 boolean_var()->SetMin(1);
3400 }
else if (u < cst_) {
3401 boolean_var()->SetMax(0);
3405void TimesPosCstBoolVar::SetValue(int64_t v) {
3407 boolean_var()->SetValue(0);
3408 }
else if (v == cst_) {
3409 boolean_var()->SetValue(1);
3415bool TimesPosCstBoolVar::Bound()
const {
3416 return boolean_var()->RawValue() != BooleanVar::kUnboundBooleanVarValue;
3419void TimesPosCstBoolVar::WhenRange(Demon* d) { boolean_var()->WhenRange(d); }
3421int64_t TimesPosCstBoolVar::Value()
const {
3422 CHECK_NE(boolean_var()->RawValue(), BooleanVar::kUnboundBooleanVarValue)
3423 <<
" variable is not bound";
3424 return boolean_var()->RawValue() * cst_;
3427void TimesPosCstBoolVar::RemoveValue(int64_t v) {
3429 boolean_var()->RemoveValue(0);
3430 }
else if (v == cst_) {
3431 boolean_var()->RemoveValue(1);
3435void TimesPosCstBoolVar::RemoveInterval(int64_t l, int64_t u) {
3436 if (l <= 0 && u >= 0) {
3437 boolean_var()->RemoveValue(0);
3439 if (l <= cst_ && u >= cst_) {
3440 boolean_var()->RemoveValue(1);
3444void TimesPosCstBoolVar::WhenBound(Demon* d) { boolean_var()->WhenBound(d); }
3446void TimesPosCstBoolVar::WhenDomain(Demon* d) { boolean_var()->WhenDomain(d); }
3448uint64_t TimesPosCstBoolVar::Size()
const {
3450 (boolean_var()->RawValue() == BooleanVar::kUnboundBooleanVarValue));
3453bool TimesPosCstBoolVar::Contains(int64_t v)
const {
3455 return boolean_var()->RawValue() != 1;
3456 }
else if (v == cst_) {
3457 return boolean_var()->RawValue() != 0;
3464class TimesNegCstIntVar :
public TimesCstIntVar {
3466 class TimesNegCstIntVarIterator :
public UnaryIterator {
3468 TimesNegCstIntVarIterator(
const IntVar*
const v, int64_t c,
bool hole,
3470 : UnaryIterator(v, hole, reversible), cst_(
c) {}
3471 ~TimesNegCstIntVarIterator()
override {}
3473 int64_t
Value()
const override {
return iterator_->Value() * cst_; }
3479 TimesNegCstIntVar(Solver* s, IntVar* v, int64_t c);
3480 ~TimesNegCstIntVar()
override;
3482 int64_t Min()
const override;
3483 void SetMin(int64_t m)
override;
3484 int64_t Max()
const override;
3485 void SetMax(int64_t m)
override;
3486 void SetRange(int64_t l, int64_t u)
override;
3487 void SetValue(int64_t v)
override;
3488 bool Bound()
const override;
3489 int64_t
Value()
const override;
3490 void RemoveValue(int64_t v)
override;
3491 void RemoveInterval(int64_t l, int64_t u)
override;
3492 uint64_t Size()
const override;
3493 bool Contains(int64_t v)
const override;
3494 void WhenRange(Demon* d)
override;
3495 void WhenBound(Demon* d)
override;
3496 void WhenDomain(Demon* d)
override;
3497 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3498 return CondRevAlloc(
3499 solver(), reversible,
3500 new TimesNegCstIntVarIterator(var_, cst_,
true, reversible));
3502 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3503 return CondRevAlloc(
3504 solver(), reversible,
3505 new TimesNegCstIntVarIterator(var_, cst_,
false, reversible));
3507 int64_t OldMin()
const override {
return CapProd(var_->OldMax(), cst_); }
3508 int64_t OldMax()
const override {
return CapProd(var_->OldMin(), cst_); }
3513TimesNegCstIntVar::TimesNegCstIntVar(Solver*
const s, IntVar* v, int64_t c)
3514 : TimesCstIntVar(s, v,
c) {}
3516TimesNegCstIntVar::~TimesNegCstIntVar() {}
3518int64_t TimesNegCstIntVar::Min()
const {
return CapProd(var_->Max(), cst_); }
3520void TimesNegCstIntVar::SetMin(int64_t m) {
3521 if (m != std::numeric_limits<int64_t>::min()) {
3526int64_t TimesNegCstIntVar::Max()
const {
return CapProd(var_->Min(), cst_); }
3528void TimesNegCstIntVar::SetMax(int64_t m) {
3529 if (m != std::numeric_limits<int64_t>::max()) {
3534void TimesNegCstIntVar::SetRange(int64_t l, int64_t u) {
3539void TimesNegCstIntVar::SetValue(int64_t v) {
3540 if (v % cst_ != 0) {
3543 var_->SetValue(v / cst_);
3546bool TimesNegCstIntVar::Bound()
const {
return var_->Bound(); }
3548void TimesNegCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3550int64_t TimesNegCstIntVar::Value()
const {
3551 return CapProd(var_->Value(), cst_);
3554void TimesNegCstIntVar::RemoveValue(int64_t v) {
3555 if (v % cst_ == 0) {
3556 var_->RemoveValue(v / cst_);
3560void TimesNegCstIntVar::RemoveInterval(int64_t l, int64_t u) {
3561 for (int64_t v = l; v <= u; ++v) {
3567void TimesNegCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3569void TimesNegCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3571uint64_t TimesNegCstIntVar::Size()
const {
return var_->Size(); }
3573bool TimesNegCstIntVar::Contains(int64_t v)
const {
3574 return (v % cst_ == 0 && var_->Contains(v / cst_));
3581class PlusIntExpr :
public BaseIntExpr {
3583 PlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3584 : BaseIntExpr(s), left_(l), right_(r) {}
3586 ~PlusIntExpr()
override {}
3588 int64_t Min()
const override {
return left_->
Min() + right_->
Min(); }
3590 void SetMin(int64_t m)
override {
3591 if (m > left_->
Min() + right_->
Min()) {
3593 if (m > right_->
Max() + left_->
Max()) solver()->Fail();
3599 void SetRange(int64_t l, int64_t u)
override {
3600 const int64_t left_min = left_->
Min();
3601 const int64_t right_min = right_->
Min();
3602 const int64_t left_max = left_->
Max();
3603 const int64_t right_max = right_->
Max();
3604 if (l > left_min + right_min) {
3606 if (l > right_max + left_max) solver()->Fail();
3607 left_->
SetMin(l - right_max);
3608 right_->
SetMin(l - left_max);
3610 if (u < left_max + right_max) {
3612 if (u < right_min + left_min) solver()->Fail();
3613 left_->
SetMax(u - right_min);
3614 right_->
SetMax(u - left_min);
3618 int64_t Max()
const override {
return left_->
Max() + right_->
Max(); }
3620 void SetMax(int64_t m)
override {
3621 if (m < left_->Max() + right_->
Max()) {
3623 if (m < right_->Min() + left_->
Min()) solver()->Fail();
3629 bool Bound()
const override {
return (left_->
Bound() && right_->
Bound()); }
3631 void Range(int64_t*
const mi, int64_t*
const ma)
override {
3632 *mi = left_->
Min() + right_->
Min();
3633 *ma = left_->
Max() + right_->
Max();
3636 std::string name()
const override {
3637 return absl::StrFormat(
"(%s + %s)", left_->
name(), right_->
name());
3640 std::string DebugString()
const override {
3641 return absl::StrFormat(
"(%s + %s)", left_->
DebugString(),
3645 void WhenRange(Demon* d)
override {
3650 void ExpandPlusIntExpr(IntExpr*
const expr, std::vector<IntExpr*>* subs) {
3651 PlusIntExpr*
const casted =
dynamic_cast<PlusIntExpr*
>(expr);
3652 if (casted !=
nullptr) {
3653 ExpandPlusIntExpr(casted->left_, subs);
3654 ExpandPlusIntExpr(casted->right_, subs);
3656 subs->push_back(expr);
3660 IntVar* CastToVar()
override {
3661 if (
dynamic_cast<PlusIntExpr*
>(left_) !=
nullptr ||
3662 dynamic_cast<PlusIntExpr*
>(right_) !=
nullptr) {
3663 std::vector<IntExpr*> sub_exprs;
3664 ExpandPlusIntExpr(left_, &sub_exprs);
3665 ExpandPlusIntExpr(right_, &sub_exprs);
3666 if (sub_exprs.size() >= 3) {
3667 std::vector<IntVar*> sub_vars(sub_exprs.size());
3668 for (
int i = 0;
i < sub_exprs.size(); ++
i) {
3669 sub_vars[
i] = sub_exprs[
i]->Var();
3671 return solver()->MakeSum(sub_vars)->Var();
3674 return BaseIntExpr::CastToVar();
3677 void Accept(ModelVisitor*
const visitor)
const override {
3678 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3679 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3680 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3682 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3686 IntExpr*
const left_;
3687 IntExpr*
const right_;
3690class SafePlusIntExpr :
public BaseIntExpr {
3692 SafePlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3693 : BaseIntExpr(s), left_(l), right_(r) {}
3695 ~SafePlusIntExpr()
override {}
3697 int64_t Min()
const override {
return CapAdd(left_->
Min(), right_->
Min()); }
3699 void SetMin(int64_t m)
override {
3704 void SetRange(int64_t l, int64_t u)
override {
3705 const int64_t left_min = left_->
Min();
3706 const int64_t right_min = right_->
Min();
3707 const int64_t left_max = left_->
Max();
3708 const int64_t right_max = right_->
Max();
3709 if (l >
CapAdd(left_min, right_min)) {
3713 if (u <
CapAdd(left_max, right_max)) {
3719 int64_t Max()
const override {
return CapAdd(left_->
Max(), right_->
Max()); }
3721 void SetMax(int64_t m)
override {
3726 bool Bound()
const override {
return (left_->
Bound() && right_->
Bound()); }
3728 std::string name()
const override {
3729 return absl::StrFormat(
"(%s + %s)", left_->
name(), right_->
name());
3732 std::string DebugString()
const override {
3733 return absl::StrFormat(
"(%s + %s)", left_->
DebugString(),
3737 void WhenRange(Demon* d)
override {
3742 void Accept(ModelVisitor*
const visitor)
const override {
3743 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3744 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3745 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3747 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3751 IntExpr*
const left_;
3752 IntExpr*
const right_;
3757class PlusIntCstExpr :
public BaseIntExpr {
3759 PlusIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3760 : BaseIntExpr(s), expr_(e), value_(v) {}
3761 ~PlusIntCstExpr()
override {}
3762 int64_t Min()
const override {
return CapAdd(expr_->
Min(), value_); }
3763 void SetMin(int64_t m)
override { expr_->
SetMin(
CapSub(m, value_)); }
3764 int64_t Max()
const override {
return CapAdd(expr_->
Max(), value_); }
3765 void SetMax(int64_t m)
override { expr_->
SetMax(
CapSub(m, value_)); }
3766 bool Bound()
const override {
return (expr_->
Bound()); }
3767 std::string name()
const override {
3768 return absl::StrFormat(
"(%s + %d)", expr_->
name(), value_);
3770 std::string DebugString()
const override {
3771 return absl::StrFormat(
"(%s + %d)", expr_->
DebugString(), value_);
3773 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
3774 IntVar* CastToVar()
override;
3775 void Accept(ModelVisitor*
const visitor)
const override {
3776 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3777 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3779 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3780 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3784 IntExpr*
const expr_;
3785 const int64_t value_;
3788IntVar* PlusIntCstExpr::CastToVar() {
3789 Solver*
const s = solver();
3790 IntVar*
const var = expr_->
Var();
3791 IntVar* cast =
nullptr;
3794 return BaseIntExpr::CastToVar();
3796 switch (var->VarType()) {
3798 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstDomainIntVar(
3799 s,
reinterpret_cast<DomainIntVar*
>(var), value_)));
3803 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstIntVar(s, var, value_)));
3811class SubIntExpr :
public BaseIntExpr {
3813 SubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3814 : BaseIntExpr(s), left_(l), right_(r) {}
3816 ~SubIntExpr()
override {}
3818 int64_t Min()
const override {
return left_->
Min() - right_->
Max(); }
3820 void SetMin(int64_t m)
override {
3825 int64_t Max()
const override {
return left_->
Max() - right_->
Min(); }
3827 void SetMax(int64_t m)
override {
3832 void Range(int64_t* mi, int64_t* ma)
override {
3833 *mi = left_->
Min() - right_->
Max();
3834 *ma = left_->
Max() - right_->
Min();
3837 void SetRange(int64_t l, int64_t u)
override {
3838 const int64_t left_min = left_->
Min();
3839 const int64_t right_min = right_->
Min();
3840 const int64_t left_max = left_->
Max();
3841 const int64_t right_max = right_->
Max();
3842 if (l > left_min - right_max) {
3846 if (u < left_max - right_min) {
3852 bool Bound()
const override {
return (left_->
Bound() && right_->
Bound()); }
3854 std::string name()
const override {
3855 return absl::StrFormat(
"(%s - %s)", left_->
name(), right_->
name());
3858 std::string DebugString()
const override {
3859 return absl::StrFormat(
"(%s - %s)", left_->
DebugString(),
3863 void WhenRange(Demon* d)
override {
3868 void Accept(ModelVisitor*
const visitor)
const override {
3869 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3870 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3871 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3873 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3876 IntExpr* left()
const {
return left_; }
3877 IntExpr* right()
const {
return right_; }
3880 IntExpr*
const left_;
3881 IntExpr*
const right_;
3884class SafeSubIntExpr :
public SubIntExpr {
3886 SafeSubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3887 : SubIntExpr(s, l, r) {}
3889 ~SafeSubIntExpr()
override {}
3891 int64_t Min()
const override {
return CapSub(left_->Min(), right_->Max()); }
3893 void SetMin(int64_t m)
override {
3894 left_->SetMin(
CapAdd(m, right_->Min()));
3895 right_->SetMax(
CapSub(left_->Max(), m));
3898 void SetRange(int64_t l, int64_t u)
override {
3899 const int64_t left_min = left_->Min();
3900 const int64_t right_min = right_->Min();
3901 const int64_t left_max = left_->Max();
3902 const int64_t right_max = right_->Max();
3903 if (l >
CapSub(left_min, right_max)) {
3904 left_->SetMin(
CapAdd(l, right_min));
3905 right_->SetMax(
CapSub(left_max, l));
3907 if (u <
CapSub(left_max, right_min)) {
3908 left_->SetMax(
CapAdd(u, right_max));
3909 right_->SetMin(
CapSub(left_min, u));
3913 void Range(int64_t* mi, int64_t* ma)
override {
3914 *mi =
CapSub(left_->Min(), right_->Max());
3915 *ma =
CapSub(left_->Max(), right_->Min());
3918 int64_t Max()
const override {
return CapSub(left_->Max(), right_->Min()); }
3920 void SetMax(int64_t m)
override {
3921 left_->SetMax(
CapAdd(m, right_->Max()));
3922 right_->SetMin(
CapSub(left_->Min(), m));
3930class SubIntCstExpr :
public BaseIntExpr {
3932 SubIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
3933 : BaseIntExpr(s), expr_(e), value_(v) {}
3934 ~SubIntCstExpr()
override {}
3935 int64_t Min()
const override {
return CapSub(value_, expr_->
Max()); }
3936 void SetMin(int64_t m)
override { expr_->
SetMax(
CapSub(value_, m)); }
3937 int64_t Max()
const override {
return CapSub(value_, expr_->
Min()); }
3938 void SetMax(int64_t m)
override { expr_->
SetMin(
CapSub(value_, m)); }
3939 bool Bound()
const override {
return (expr_->
Bound()); }
3940 std::string name()
const override {
3941 return absl::StrFormat(
"(%d - %s)", value_, expr_->
name());
3943 std::string DebugString()
const override {
3944 return absl::StrFormat(
"(%d - %s)", value_, expr_->
DebugString());
3946 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
3947 IntVar* CastToVar()
override;
3949 void Accept(ModelVisitor*
const visitor)
const override {
3950 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3951 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3952 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3954 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3958 IntExpr*
const expr_;
3959 const int64_t value_;
3962IntVar* SubIntCstExpr::CastToVar() {
3965 return BaseIntExpr::CastToVar();
3967 Solver*
const s = solver();
3969 s->RegisterIntVar(s->RevAlloc(
new SubCstIntVar(s, expr_->
Var(), value_)));
3975class OppIntExpr :
public BaseIntExpr {
3977 OppIntExpr(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s), expr_(e) {}
3978 ~OppIntExpr()
override {}
3979 int64_t Min()
const override {
return (
CapOpp(expr_->
Max())); }
3980 void SetMin(int64_t m)
override { expr_->
SetMax(
CapOpp(m)); }
3981 int64_t Max()
const override {
return (
CapOpp(expr_->
Min())); }
3982 void SetMax(int64_t m)
override { expr_->
SetMin(
CapOpp(m)); }
3983 bool Bound()
const override {
return (expr_->
Bound()); }
3984 std::string name()
const override {
3985 return absl::StrFormat(
"(-%s)", expr_->
name());
3987 std::string DebugString()
const override {
3988 return absl::StrFormat(
"(-%s)", expr_->
DebugString());
3990 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
3991 IntVar* CastToVar()
override;
3993 void Accept(ModelVisitor*
const visitor)
const override {
3994 visitor->BeginVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3995 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3997 visitor->EndVisitIntegerExpression(ModelVisitor::kOpposite,
this);
4001 IntExpr*
const expr_;
4004IntVar* OppIntExpr::CastToVar() {
4005 Solver*
const s = solver();
4007 s->RegisterIntVar(s->RevAlloc(
new OppIntVar(s, expr_->
Var())));
4013class TimesIntCstExpr :
public BaseIntExpr {
4015 TimesIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4016 : BaseIntExpr(s), expr_(e), value_(v) {}
4018 ~TimesIntCstExpr()
override {}
4020 bool Bound()
const override {
return (expr_->
Bound()); }
4022 std::string name()
const override {
4023 return absl::StrFormat(
"(%s * %d)", expr_->
name(), value_);
4026 std::string DebugString()
const override {
4027 return absl::StrFormat(
"(%s * %d)", expr_->
DebugString(), value_);
4030 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
4032 IntExpr* Expr()
const {
return expr_; }
4034 int64_t Constant()
const {
return value_; }
4036 void Accept(ModelVisitor*
const visitor)
const override {
4037 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4038 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4040 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4041 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4045 IntExpr*
const expr_;
4046 const int64_t value_;
4051class TimesPosIntCstExpr :
public TimesIntCstExpr {
4053 TimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4054 : TimesIntCstExpr(s, e, v) {
4058 ~TimesPosIntCstExpr()
override {}
4060 int64_t Min()
const override {
return expr_->Min() * value_; }
4062 void SetMin(int64_t m)
override { expr_->SetMin(
PosIntDivUp(m, value_)); }
4064 int64_t Max()
const override {
return expr_->Max() * value_; }
4066 void SetMax(int64_t m)
override { expr_->SetMax(
PosIntDivDown(m, value_)); }
4068 IntVar* CastToVar()
override {
4069 Solver*
const s = solver();
4070 IntVar* var =
nullptr;
4071 if (expr_->IsVar() &&
4072 reinterpret_cast<IntVar*
>(expr_)->VarType() == BOOLEAN_VAR) {
4073 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4074 s,
reinterpret_cast<BooleanVar*
>(expr_), value_)));
4076 var = s->RegisterIntVar(
4077 s->RevAlloc(
new TimesPosCstIntVar(s, expr_->Var(), value_)));
4085class SafeTimesPosIntCstExpr :
public TimesIntCstExpr {
4087 SafeTimesPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4088 : TimesIntCstExpr(s, e, v) {
4092 ~SafeTimesPosIntCstExpr()
override {}
4094 int64_t Min()
const override {
return CapProd(expr_->Min(), value_); }
4096 void SetMin(int64_t m)
override {
4097 if (m != std::numeric_limits<int64_t>::min()) {
4102 int64_t Max()
const override {
return CapProd(expr_->Max(), value_); }
4104 void SetMax(int64_t m)
override {
4105 if (m != std::numeric_limits<int64_t>::max()) {
4110 IntVar* CastToVar()
override {
4111 Solver*
const s = solver();
4112 IntVar* var =
nullptr;
4113 if (expr_->IsVar() &&
4114 reinterpret_cast<IntVar*
>(expr_)->VarType() == BOOLEAN_VAR) {
4115 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4116 s,
reinterpret_cast<BooleanVar*
>(expr_), value_)));
4119 var = s->RegisterIntVar(
4120 s->RevAlloc(
new TimesPosCstIntVar(s, expr_->Var(), value_)));
4128class TimesIntNegCstExpr :
public TimesIntCstExpr {
4130 TimesIntNegCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4131 : TimesIntCstExpr(s, e, v) {
4135 ~TimesIntNegCstExpr()
override {}
4137 int64_t Min()
const override {
return CapProd(expr_->Max(), value_); }
4139 void SetMin(int64_t m)
override {
4140 if (m != std::numeric_limits<int64_t>::min()) {
4145 int64_t Max()
const override {
return CapProd(expr_->Min(), value_); }
4147 void SetMax(int64_t m)
override {
4148 if (m != std::numeric_limits<int64_t>::max()) {
4153 IntVar* CastToVar()
override {
4154 Solver*
const s = solver();
4155 IntVar* var =
nullptr;
4156 var = s->RegisterIntVar(
4157 s->RevAlloc(
new TimesNegCstIntVar(s, expr_->Var(), value_)));
4165void SetPosPosMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4166 DCHECK_GE(left->Min(), 0);
4167 DCHECK_GE(right->Min(), 0);
4168 const int64_t lmax = left->Max();
4169 const int64_t rmax = right->Max();
4170 if (m >
CapProd(lmax, rmax)) {
4171 left->solver()->Fail();
4173 if (m >
CapProd(left->Min(), right->Min())) {
4185void SetPosPosMaxExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4186 DCHECK_GE(left->Min(), 0);
4187 DCHECK_GE(right->Min(), 0);
4188 const int64_t lmin = left->Min();
4189 const int64_t rmin = right->Min();
4190 if (m <
CapProd(lmin, rmin)) {
4191 left->solver()->Fail();
4193 if (m <
CapProd(left->Max(), right->Max())) {
4205void SetPosGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4206 DCHECK_GE(left->Min(), 0);
4207 DCHECK_GT(right->Max(), 0);
4208 DCHECK_LT(right->Min(), 0);
4209 const int64_t lmax = left->Max();
4210 const int64_t rmax = right->Max();
4211 if (m >
CapProd(lmax, rmax)) {
4212 left->solver()->Fail();
4214 if (left->Max() == 0) {
4215 DCHECK_EQ(0, left->Min());
4221 }
else if (m == 0) {
4222 const int64_t lmin = left->Min();
4227 const int64_t lmin = left->Min();
4236void SetGenGenMinExpr(IntExpr*
const left, IntExpr*
const right, int64_t m) {
4237 DCHECK_LT(left->Min(), 0);
4238 DCHECK_GT(left->Max(), 0);
4239 DCHECK_GT(right->Max(), 0);
4240 DCHECK_LT(right->Min(), 0);
4241 const int64_t lmin = left->Min();
4242 const int64_t lmax = left->Max();
4243 const int64_t rmin = right->Min();
4244 const int64_t rmax = right->Max();
4246 left->solver()->Fail();
4252 }
else if (m >
CapProd(lmax, rmax)) {
4258void TimesSetMin(IntExpr*
const left, IntExpr*
const right,
4259 IntExpr*
const minus_left, IntExpr*
const minus_right,
4261 if (left->Min() >= 0) {
4262 if (right->Min() >= 0) {
4263 SetPosPosMinExpr(left, right, m);
4264 }
else if (right->Max() <= 0) {
4265 SetPosPosMaxExpr(left, minus_right, -m);
4267 SetPosGenMinExpr(left, right, m);
4269 }
else if (left->Max() <= 0) {
4270 if (right->Min() >= 0) {
4271 SetPosPosMaxExpr(right, minus_left, -m);
4272 }
else if (right->Max() <= 0) {
4273 SetPosPosMinExpr(minus_left, minus_right, m);
4275 SetPosGenMinExpr(minus_left, minus_right, m);
4277 }
else if (right->Min() >= 0) {
4278 SetPosGenMinExpr(right, left, m);
4279 }
else if (right->Max() <= 0) {
4280 SetPosGenMinExpr(minus_right, minus_left, m);
4283 SetGenGenMinExpr(left, right, m);
4287class TimesIntExpr :
public BaseIntExpr {
4289 TimesIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4293 minus_left_(s->MakeOpposite(left_)),
4294 minus_right_(s->MakeOpposite(right_)) {}
4295 ~TimesIntExpr()
override {}
4296 int64_t Min()
const override {
4297 const int64_t lmin = left_->
Min();
4298 const int64_t lmax = left_->
Max();
4299 const int64_t rmin = right_->
Min();
4300 const int64_t rmax = right_->
Max();
4301 return std::min(std::min(
CapProd(lmin, rmin),
CapProd(lmax, rmax)),
4304 void SetMin(int64_t m)
override;
4305 int64_t Max()
const override {
4306 const int64_t lmin = left_->
Min();
4307 const int64_t lmax = left_->
Max();
4308 const int64_t rmin = right_->
Min();
4309 const int64_t rmax = right_->
Max();
4310 return std::max(std::max(
CapProd(lmin, rmin),
CapProd(lmax, rmax)),
4313 void SetMax(int64_t m)
override;
4314 bool Bound()
const override;
4315 std::string name()
const override {
4316 return absl::StrFormat(
"(%s * %s)", left_->
name(), right_->
name());
4318 std::string DebugString()
const override {
4319 return absl::StrFormat(
"(%s * %s)", left_->
DebugString(),
4322 void WhenRange(Demon* d)
override {
4327 void Accept(ModelVisitor*
const visitor)
const override {
4328 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4329 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4330 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4332 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4336 IntExpr*
const left_;
4337 IntExpr*
const right_;
4338 IntExpr*
const minus_left_;
4339 IntExpr*
const minus_right_;
4342void TimesIntExpr::SetMin(int64_t m) {
4343 if (m != std::numeric_limits<int64_t>::min()) {
4344 TimesSetMin(left_, right_, minus_left_, minus_right_, m);
4348void TimesIntExpr::SetMax(int64_t m) {
4349 if (m != std::numeric_limits<int64_t>::max()) {
4350 TimesSetMin(left_, minus_right_, minus_left_, right_,
CapOpp(m));
4354bool TimesIntExpr::Bound()
const {
4355 const bool left_bound = left_->
Bound();
4356 const bool right_bound = right_->
Bound();
4357 return ((left_bound && left_->
Max() == 0) ||
4358 (right_bound && right_->
Max() == 0) || (left_bound && right_bound));
4363class TimesPosIntExpr :
public BaseIntExpr {
4365 TimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4366 : BaseIntExpr(s), left_(l), right_(r) {}
4367 ~TimesPosIntExpr()
override {}
4368 int64_t Min()
const override {
return (left_->
Min() * right_->
Min()); }
4369 void SetMin(int64_t m)
override;
4370 int64_t Max()
const override {
return (left_->
Max() * right_->
Max()); }
4371 void SetMax(int64_t m)
override;
4372 bool Bound()
const override;
4373 std::string name()
const override {
4374 return absl::StrFormat(
"(%s * %s)", left_->
name(), right_->
name());
4376 std::string DebugString()
const override {
4377 return absl::StrFormat(
"(%s * %s)", left_->
DebugString(),
4380 void WhenRange(Demon* d)
override {
4385 void Accept(ModelVisitor*
const visitor)
const override {
4386 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4387 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4388 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4390 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4394 IntExpr*
const left_;
4395 IntExpr*
const right_;
4398void TimesPosIntExpr::SetMin(int64_t m) { SetPosPosMinExpr(left_, right_, m); }
4400void TimesPosIntExpr::SetMax(int64_t m) { SetPosPosMaxExpr(left_, right_, m); }
4402bool TimesPosIntExpr::Bound()
const {
4403 return (left_->
Max() == 0 || right_->
Max() == 0 ||
4409class SafeTimesPosIntExpr :
public BaseIntExpr {
4411 SafeTimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4412 : BaseIntExpr(s), left_(l), right_(r) {}
4413 ~SafeTimesPosIntExpr()
override {}
4414 int64_t Min()
const override {
return CapProd(left_->
Min(), right_->
Min()); }
4415 void SetMin(int64_t m)
override {
4416 if (m != std::numeric_limits<int64_t>::min()) {
4417 SetPosPosMinExpr(left_, right_, m);
4420 int64_t Max()
const override {
return CapProd(left_->
Max(), right_->
Max()); }
4421 void SetMax(int64_t m)
override {
4422 if (m != std::numeric_limits<int64_t>::max()) {
4423 SetPosPosMaxExpr(left_, right_, m);
4426 bool Bound()
const override {
4427 return (left_->
Max() == 0 || right_->
Max() == 0 ||
4430 std::string name()
const override {
4431 return absl::StrFormat(
"(%s * %s)", left_->
name(), right_->
name());
4433 std::string DebugString()
const override {
4434 return absl::StrFormat(
"(%s * %s)", left_->
DebugString(),
4437 void WhenRange(Demon* d)
override {
4442 void Accept(ModelVisitor*
const visitor)
const override {
4443 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4444 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4445 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4447 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4451 IntExpr*
const left_;
4452 IntExpr*
const right_;
4457class TimesBooleanPosIntExpr :
public BaseIntExpr {
4459 TimesBooleanPosIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4460 : BaseIntExpr(s), boolvar_(
b), expr_(e) {}
4461 ~TimesBooleanPosIntExpr()
override {}
4462 int64_t Min()
const override {
4463 return (boolvar_->
RawValue() == 1 ? expr_->
Min() : 0);
4465 void SetMin(int64_t m)
override;
4466 int64_t Max()
const override {
4467 return (boolvar_->
RawValue() == 0 ? 0 : expr_->
Max());
4469 void SetMax(int64_t m)
override;
4470 void Range(int64_t* mi, int64_t* ma)
override;
4471 void SetRange(int64_t mi, int64_t ma)
override;
4472 bool Bound()
const override;
4473 std::string name()
const override {
4474 return absl::StrFormat(
"(%s * %s)", boolvar_->
name(), expr_->
name());
4476 std::string DebugString()
const override {
4477 return absl::StrFormat(
"(%s * %s)", boolvar_->
DebugString(),
4480 void WhenRange(Demon* d)
override {
4485 void Accept(ModelVisitor*
const visitor)
const override {
4486 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4487 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4489 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4491 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4495 BooleanVar*
const boolvar_;
4496 IntExpr*
const expr_;
4499void TimesBooleanPosIntExpr::SetMin(int64_t m) {
4506void TimesBooleanPosIntExpr::SetMax(int64_t m) {
4510 if (m < expr_->Min()) {
4518void TimesBooleanPosIntExpr::Range(int64_t* mi, int64_t* ma) {
4519 const int value = boolvar_->
RawValue();
4523 }
else if (value == 1) {
4524 expr_->
Range(mi, ma);
4531void TimesBooleanPosIntExpr::SetRange(int64_t mi, int64_t ma) {
4532 if (ma < 0 || mi > ma) {
4539 if (ma < expr_->Min()) {
4547bool TimesBooleanPosIntExpr::Bound()
const {
4548 return (boolvar_->
RawValue() == 0 || expr_->
Max() == 0 ||
4549 (boolvar_->
RawValue() != BooleanVar::kUnboundBooleanVarValue &&
4555class TimesBooleanIntExpr :
public BaseIntExpr {
4557 TimesBooleanIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4558 : BaseIntExpr(s), boolvar_(
b), expr_(e) {}
4559 ~TimesBooleanIntExpr()
override {}
4560 int64_t Min()
const override {
4566 return expr_->
Min();
4569 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4570 return std::min(int64_t{0}, expr_->
Min());
4574 void SetMin(int64_t m)
override;
4575 int64_t Max()
const override {
4581 return expr_->
Max();
4584 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4585 return std::max(int64_t{0}, expr_->
Max());
4589 void SetMax(int64_t m)
override;
4590 void Range(int64_t* mi, int64_t* ma)
override;
4591 void SetRange(int64_t mi, int64_t ma)
override;
4592 bool Bound()
const override;
4593 std::string name()
const override {
4594 return absl::StrFormat(
"(%s * %s)", boolvar_->
name(), expr_->
name());
4596 std::string DebugString()
const override {
4597 return absl::StrFormat(
"(%s * %s)", boolvar_->
DebugString(),
4600 void WhenRange(Demon* d)
override {
4605 void Accept(ModelVisitor*
const visitor)
const override {
4606 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4607 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4609 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4611 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4615 BooleanVar*
const boolvar_;
4616 IntExpr*
const expr_;
4619void TimesBooleanIntExpr::SetMin(int64_t m) {
4632 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4636 }
else if (m <= 0 && expr_->Max() < m) {
4643void TimesBooleanIntExpr::SetMax(int64_t m) {
4656 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4660 }
else if (m >= 0 && expr_->
Min() > m) {
4667void TimesBooleanIntExpr::Range(int64_t* mi, int64_t* ma) {
4680 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4681 *mi = std::min(int64_t{0}, expr_->
Min());
4682 *ma = std::max(int64_t{0}, expr_->
Max());
4688void TimesBooleanIntExpr::SetRange(int64_t mi, int64_t ma) {
4694 if (mi > 0 || ma < 0) {
4704 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->
RawValue());
4708 }
else if (mi == 0 && expr_->
Max() < 0) {
4714 }
else if (ma == 0 && expr_->
Min() > 0) {
4722bool TimesBooleanIntExpr::Bound()
const {
4723 return (boolvar_->
RawValue() == 0 ||
4725 (boolvar_->
RawValue() != BooleanVar::kUnboundBooleanVarValue ||
4726 expr_->
Max() == 0)));
4731class DivPosIntCstExpr :
public BaseIntExpr {
4733 DivPosIntCstExpr(Solver*
const s, IntExpr*
const e, int64_t v)
4734 : BaseIntExpr(s), expr_(e), value_(v) {
4737 ~DivPosIntCstExpr()
override {}
4739 int64_t Min()
const override {
return expr_->
Min() / value_; }
4741 void SetMin(int64_t m)
override {
4743 expr_->
SetMin(m * value_);
4745 expr_->
SetMin((m - 1) * value_ + 1);
4748 int64_t Max()
const override {
return expr_->
Max() / value_; }
4750 void SetMax(int64_t m)
override {
4752 expr_->
SetMax((m + 1) * value_ - 1);
4754 expr_->
SetMax(m * value_);
4758 std::string name()
const override {
4759 return absl::StrFormat(
"(%s div %d)", expr_->
name(), value_);
4762 std::string DebugString()
const override {
4763 return absl::StrFormat(
"(%s div %d)", expr_->
DebugString(), value_);
4766 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
4768 void Accept(ModelVisitor*
const visitor)
const override {
4769 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4770 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4772 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4773 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4777 IntExpr*
const expr_;
4778 const int64_t value_;
4783class DivPosIntExpr :
public BaseIntExpr {
4785 DivPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4789 opp_num_(s->MakeOpposite(num)) {}
4791 ~DivPosIntExpr()
override {}
4793 int64_t Min()
const override {
4794 return num_->
Min() >= 0
4795 ? num_->
Min() / denom_->
Max()
4796 : (denom_->
Min() == 0 ? num_->
Min()
4797 : num_->
Min() / denom_->
Min());
4800 int64_t Max()
const override {
4801 return num_->
Max() >= 0 ? (denom_->
Min() == 0 ? num_->
Max()
4802 : num_->
Max() / denom_->
Min())
4803 : num_->
Max() / denom_->
Max();
4806 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4807 num->SetMin(m * denom->Min());
4808 denom->SetMax(num->Max() / m);
4811 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4812 num->SetMax((m + 1) * denom->Max() - 1);
4813 denom->SetMin(num->Min() / (m + 1) + 1);
4816 void SetMin(int64_t m)
override {
4818 SetPosMin(num_, denom_, m);
4820 SetPosMax(opp_num_, denom_, -m);
4824 void SetMax(int64_t m)
override {
4826 SetPosMax(num_, denom_, m);
4828 SetPosMin(opp_num_, denom_, -m);
4832 std::string name()
const override {
4833 return absl::StrFormat(
"(%s div %s)", num_->
name(), denom_->
name());
4835 std::string DebugString()
const override {
4836 return absl::StrFormat(
"(%s div %s)", num_->
DebugString(),
4839 void WhenRange(Demon* d)
override {
4844 void Accept(ModelVisitor*
const visitor)
const override {
4845 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4846 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4847 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4849 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4853 IntExpr*
const num_;
4854 IntExpr*
const denom_;
4855 IntExpr*
const opp_num_;
4858class DivPosPosIntExpr :
public BaseIntExpr {
4860 DivPosPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4861 : BaseIntExpr(s), num_(num), denom_(denom) {}
4863 ~DivPosPosIntExpr()
override {}
4865 int64_t Min()
const override {
4866 if (denom_->
Max() == 0) {
4869 return num_->
Min() / denom_->
Max();
4872 int64_t Max()
const override {
4873 if (denom_->
Min() == 0) {
4876 return num_->
Max() / denom_->
Min();
4880 void SetMin(int64_t m)
override {
4887 void SetMax(int64_t m)
override {
4889 num_->
SetMax((m + 1) * denom_->
Max() - 1);
4890 denom_->
SetMin(num_->
Min() / (m + 1) + 1);
4896 std::string name()
const override {
4897 return absl::StrFormat(
"(%s div %s)", num_->
name(), denom_->
name());
4900 std::string DebugString()
const override {
4901 return absl::StrFormat(
"(%s div %s)", num_->
DebugString(),
4905 void WhenRange(Demon* d)
override {
4910 void Accept(ModelVisitor*
const visitor)
const override {
4911 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4912 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4913 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4915 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4919 IntExpr*
const num_;
4920 IntExpr*
const denom_;
4925class DivIntExpr :
public BaseIntExpr {
4927 DivIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4931 opp_num_(s->MakeOpposite(num)) {}
4933 ~DivIntExpr()
override {}
4935 int64_t Min()
const override {
4936 const int64_t num_min = num_->
Min();
4937 const int64_t num_max = num_->
Max();
4938 const int64_t denom_min = denom_->
Min();
4939 const int64_t denom_max = denom_->
Max();
4941 if (denom_min == 0 && denom_max == 0) {
4942 return std::numeric_limits<int64_t>::max();
4946 if (denom_min >= 0) {
4947 DCHECK_GT(denom_max, 0);
4948 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4949 return num_min >= 0 ? num_min / denom_max : num_min / adjusted_denom_min;
4950 }
else if (denom_max <= 0) {
4951 DCHECK_LT(denom_min, 0);
4952 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4953 return num_max >= 0 ? num_max / adjusted_denom_max : num_max / denom_min;
4955 return std::min(num_min, -num_max);
4959 int64_t Max()
const override {
4960 const int64_t num_min = num_->
Min();
4961 const int64_t num_max = num_->
Max();
4962 const int64_t denom_min = denom_->
Min();
4963 const int64_t denom_max = denom_->
Max();
4965 if (denom_min == 0 && denom_max == 0) {
4966 return std::numeric_limits<int64_t>::min();
4970 if (denom_min >= 0) {
4971 DCHECK_GT(denom_max, 0);
4972 const int64_t adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4973 return num_max >= 0 ? num_max / adjusted_denom_min : num_max / denom_max;
4974 }
else if (denom_max <= 0) {
4975 DCHECK_LT(denom_min, 0);
4976 const int64_t adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4977 return num_min >= 0 ? num_min / denom_min
4978 : -num_min / -adjusted_denom_max;
4980 return std::max(num_max, -num_min);
4984 void AdjustDenominator() {
4985 if (denom_->
Min() == 0) {
4987 }
else if (denom_->
Max() == 0) {
4993 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
4995 const int64_t num_min = num->Min();
4996 const int64_t num_max = num->Max();
4997 const int64_t denom_min = denom->Min();
4998 const int64_t denom_max = denom->Max();
4999 DCHECK_NE(denom_min, 0);
5000 DCHECK_NE(denom_max, 0);
5001 if (denom_min > 0) {
5002 num->SetMin(m * denom_min);
5003 denom->SetMax(num_max / m);
5004 }
else if (denom_max < 0) {
5005 num->SetMax(m * denom_max);
5006 denom->SetMin(num_min / m);
5010 denom->SetRange(1, num_max / m);
5011 }
else if (num_max <= 0) {
5013 denom->SetRange(num_min / m, -1);
5017 denom->SetRange(1, num_max / m);
5018 }
else if (m > num_max) {
5020 denom->SetRange(num_min / m, -1);
5022 denom->SetRange(num_min / m, num_max / m);
5029 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom, int64_t m) {
5031 const int64_t num_min = num->Min();
5032 const int64_t num_max = num->Max();
5033 const int64_t denom_min = denom->Min();
5034 const int64_t denom_max = denom->Max();
5035 DCHECK_NE(denom_min, 0);
5036 DCHECK_NE(denom_max, 0);
5037 if (denom_min > 0) {
5038 num->SetMax((m + 1) * denom_max - 1);
5039 denom->SetMin((num_min / (m + 1)) + 1);
5040 }
else if (denom_max < 0) {
5041 num->SetMin((m + 1) * denom_min + 1);
5042 denom->SetMax(num_max / (m + 1) - 1);
5043 }
else if (num_min > (m + 1) * denom_max - 1) {
5045 }
else if (num_max < (m + 1) * denom_min + 1) {
5050 void SetMin(int64_t m)
override {
5051 AdjustDenominator();
5053 SetPosMin(num_, denom_, m);
5055 SetPosMax(opp_num_, denom_, -m);
5059 void SetMax(int64_t m)
override {
5060 AdjustDenominator();
5062 SetPosMax(num_, denom_, m);
5064 SetPosMin(opp_num_, denom_, -m);
5068 std::string name()
const override {
5069 return absl::StrFormat(
"(%s div %s)", num_->
name(), denom_->
name());
5071 std::string DebugString()
const override {
5072 return absl::StrFormat(
"(%s div %s)", num_->
DebugString(),
5075 void WhenRange(Demon* d)
override {
5080 void Accept(ModelVisitor*
const visitor)
const override {
5081 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
5082 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
5083 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5085 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
5089 IntExpr*
const num_;
5090 IntExpr*
const denom_;
5091 IntExpr*
const opp_num_;
5096class IntAbsConstraint :
public CastConstraint {
5098 IntAbsConstraint(Solver*
const s, IntVar*
const sub, IntVar*
const target)
5099 : CastConstraint(s, target), sub_(sub) {}
5101 ~IntAbsConstraint()
override {}
5103 void Post()
override {
5105 solver(),
this, &IntAbsConstraint::PropagateSub,
"PropagateSub");
5108 solver(),
this, &IntAbsConstraint::PropagateTarget,
"PropagateTarget");
5109 target_var_->WhenRange(target_demon);
5112 void InitialPropagate()
override {
5117 void PropagateSub() {
5118 const int64_t smin = sub_->
Min();
5119 const int64_t smax = sub_->
Max();
5121 target_var_->SetRange(-smax, -smin);
5122 }
else if (smin >= 0) {
5123 target_var_->SetRange(smin, smax);
5125 target_var_->SetRange(0, std::max(-smin, smax));
5129 void PropagateTarget() {
5130 const int64_t target_max = target_var_->Max();
5131 sub_->
SetRange(-target_max, target_max);
5132 const int64_t target_min = target_var_->Min();
5133 if (target_min > 0) {
5134 if (sub_->
Min() > -target_min) {
5135 sub_->
SetMin(target_min);
5136 }
else if (sub_->
Max() < target_min) {
5137 sub_->
SetMax(-target_min);
5142 std::string DebugString()
const override {
5143 return absl::StrFormat(
"IntAbsConstraint(%s, %s)", sub_->
DebugString(),
5144 target_var_->DebugString());
5147 void Accept(ModelVisitor*
const visitor)
const override {
5148 visitor->BeginVisitConstraint(ModelVisitor::kAbsEqual,
this);
5149 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5151 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
5153 visitor->EndVisitConstraint(ModelVisitor::kAbsEqual,
this);
5160class IntAbs :
public BaseIntExpr {
5162 IntAbs(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s), expr_(e) {}
5164 ~IntAbs()
override {}
5166 int64_t Min()
const override {
5169 expr_->
Range(&emin, &emax);
5179 void SetMin(int64_t m)
override {
5183 expr_->
Range(&emin, &emax);
5186 }
else if (emax < m) {
5192 int64_t Max()
const override {
5195 expr_->
Range(&emin, &emax);
5196 return std::max(-emin, emax);
5199 void SetMax(int64_t m)
override { expr_->
SetRange(-m, m); }
5201 void SetRange(int64_t mi, int64_t ma)
override {
5206 expr_->
Range(&emin, &emax);
5209 }
else if (emax < mi) {
5215 void Range(int64_t* mi, int64_t* ma)
override {
5218 expr_->
Range(&emin, &emax);
5222 }
else if (emax <= 0) {
5227 *ma = std::max(-emin, emax);
5231 bool Bound()
const override {
return expr_->
Bound(); }
5233 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5235 std::string name()
const override {
5236 return absl::StrFormat(
"IntAbs(%s)", expr_->
name());
5239 std::string DebugString()
const override {
5240 return absl::StrFormat(
"IntAbs(%s)", expr_->
DebugString());
5243 void Accept(ModelVisitor*
const visitor)
const override {
5244 visitor->BeginVisitIntegerExpression(ModelVisitor::kAbs,
this);
5245 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5247 visitor->EndVisitIntegerExpression(ModelVisitor::kAbs,
this);
5250 IntVar* CastToVar()
override {
5251 int64_t min_value = 0;
5252 int64_t max_value = 0;
5253 Range(&min_value, &max_value);
5254 Solver*
const s = solver();
5255 const std::string name = absl::StrFormat(
"AbsVar(%s)", expr_->
name());
5256 IntVar*
const target = s->MakeIntVar(min_value, max_value, name);
5257 CastConstraint*
const ct =
5258 s->RevAlloc(
new IntAbsConstraint(s, expr_->
Var(), target));
5259 s->AddCastConstraint(ct, target,
this);
5264 IntExpr*
const expr_;
5270class IntSquare :
public BaseIntExpr {
5272 IntSquare(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s), expr_(e) {}
5273 ~IntSquare()
override {}
5275 int64_t Min()
const override {
5276 const int64_t emin = expr_->
Min();
5278 return emin >= std::numeric_limits<int32_t>::max()
5279 ? std::numeric_limits<int64_t>::max()
5282 const int64_t emax = expr_->
Max();
5284 return emax <= -std::numeric_limits<int32_t>::max()
5285 ? std::numeric_limits<int64_t>::max()
5290 void SetMin(int64_t m)
override {
5295 const int64_t emin = expr_->
Min();
5296 const int64_t emax = expr_->
Max();
5297 const int64_t root =
5298 static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5301 }
else if (emax <= 0) {
5303 }
else if (expr_->
IsVar()) {
5304 reinterpret_cast<IntVar*
>(expr_)->RemoveInterval(-root + 1, root - 1);
5307 int64_t Max()
const override {
5308 const int64_t emax = expr_->
Max();
5309 const int64_t emin = expr_->
Min();
5310 if (emax >= std::numeric_limits<int32_t>::max() ||
5311 emin <= -std::numeric_limits<int32_t>::max()) {
5312 return std::numeric_limits<int64_t>::max();
5314 return std::max(emin * emin, emax * emax);
5316 void SetMax(int64_t m)
override {
5320 if (m == std::numeric_limits<int64_t>::max()) {
5323 const int64_t root =
5324 static_cast<int64_t
>(
floor(sqrt(
static_cast<double>(m))));
5327 bool Bound()
const override {
return expr_->
Bound(); }
5328 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5329 std::string name()
const override {
5330 return absl::StrFormat(
"IntSquare(%s)", expr_->
name());
5332 std::string DebugString()
const override {
5333 return absl::StrFormat(
"IntSquare(%s)", expr_->
DebugString());
5336 void Accept(ModelVisitor*
const visitor)
const override {
5337 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare,
this);
5338 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5340 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare,
this);
5343 IntExpr* expr()
const {
return expr_; }
5346 IntExpr*
const expr_;
5349class PosIntSquare :
public IntSquare {
5351 PosIntSquare(Solver*
const s, IntExpr*
const e) : IntSquare(s, e) {}
5352 ~PosIntSquare()
override {}
5354 int64_t Min()
const override {
5355 const int64_t emin = expr_->Min();
5356 return emin >= std::numeric_limits<int32_t>::max()
5357 ? std::numeric_limits<int64_t>::max()
5360 void SetMin(int64_t m)
override {
5364 int64_t root =
static_cast<int64_t
>(ceil(sqrt(
static_cast<double>(m))));
5365 if (
CapProd(root, root) < m) {
5368 expr_->SetMin(root);
5370 int64_t Max()
const override {
5371 const int64_t emax = expr_->Max();
5372 return emax >= std::numeric_limits<int32_t>::max()
5373 ? std::numeric_limits<int64_t>::max()
5376 void SetMax(int64_t m)
override {
5380 if (m == std::numeric_limits<int64_t>::max()) {
5383 int64_t root =
static_cast<int64_t
>(
floor(sqrt(
static_cast<double>(m))));
5384 if (
CapProd(root, root) > m) {
5388 expr_->SetMax(root);
5394int64_t IntPower(int64_t value, int64_t power) {
5395 int64_t result = value;
5397 for (
int i = 1;
i < power; ++
i) {
5403int64_t OverflowLimit(int64_t power) {
5404 return static_cast<int64_t
>(
floor(exp(
5405 log(
static_cast<double>(std::numeric_limits<int64_t>::max())) / power)));
5408class BasePower :
public BaseIntExpr {
5410 BasePower(Solver*
const s, IntExpr*
const e, int64_t n)
5411 : BaseIntExpr(s), expr_(e), pow_(n), limit_(OverflowLimit(n)) {
5415 ~BasePower()
override {}
5417 bool Bound()
const override {
return expr_->
Bound(); }
5419 IntExpr* expr()
const {
return expr_; }
5421 int64_t exponant()
const {
return pow_; }
5423 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5425 std::string name()
const override {
5426 return absl::StrFormat(
"IntPower(%s, %d)", expr_->
name(), pow_);
5429 std::string DebugString()
const override {
5430 return absl::StrFormat(
"IntPower(%s, %d)", expr_->
DebugString(), pow_);
5433 void Accept(ModelVisitor*
const visitor)
const override {
5434 visitor->BeginVisitIntegerExpression(ModelVisitor::kPower,
this);
5435 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5437 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, pow_);
5438 visitor->EndVisitIntegerExpression(ModelVisitor::kPower,
this);
5442 int64_t Pown(int64_t value)
const {
5443 if (value >= limit_) {
5444 return std::numeric_limits<int64_t>::max();
5446 if (value <= -limit_) {
5447 if (pow_ % 2 == 0) {
5448 return std::numeric_limits<int64_t>::max();
5450 return std::numeric_limits<int64_t>::min();
5453 return IntPower(value, pow_);
5456 int64_t SqrnDown(int64_t value)
const {
5457 if (value == std::numeric_limits<int64_t>::min()) {
5458 return std::numeric_limits<int64_t>::min();
5460 if (value == std::numeric_limits<int64_t>::max()) {
5461 return std::numeric_limits<int64_t>::max();
5464 const double d_value =
static_cast<double>(value);
5466 const double sq = exp(log(d_value) / pow_);
5467 res =
static_cast<int64_t
>(
floor(sq));
5469 CHECK_EQ(1, pow_ % 2);
5470 const double sq = exp(log(-d_value) / pow_);
5471 res = -
static_cast<int64_t
>(ceil(sq));
5473 const int64_t pow_res = Pown(res + 1);
5474 if (pow_res <= value) {
5481 int64_t SqrnUp(int64_t value)
const {
5482 if (value == std::numeric_limits<int64_t>::min()) {
5483 return std::numeric_limits<int64_t>::min();
5485 if (value == std::numeric_limits<int64_t>::max()) {
5486 return std::numeric_limits<int64_t>::max();
5489 const double d_value =
static_cast<double>(value);
5491 const double sq = exp(log(d_value) / pow_);
5492 res =
static_cast<int64_t
>(ceil(sq));
5494 CHECK_EQ(1, pow_ % 2);
5495 const double sq = exp(log(-d_value) / pow_);
5496 res = -
static_cast<int64_t
>(
floor(sq));
5498 const int64_t pow_res = Pown(res - 1);
5499 if (pow_res >= value) {
5506 IntExpr*
const expr_;
5508 const int64_t limit_;
5511class IntEvenPower :
public BasePower {
5513 IntEvenPower(Solver*
const s, IntExpr*
const e, int64_t n)
5514 : BasePower(s, e, n) {
5518 ~IntEvenPower()
override {}
5520 int64_t Min()
const override {
5523 expr_->Range(&emin, &emax);
5532 void SetMin(int64_t m)
override {
5538 expr_->Range(&emin, &emax);
5539 const int64_t root = SqrnUp(m);
5541 expr_->SetMin(root);
5542 }
else if (emax < root) {
5543 expr_->SetMax(-root);
5544 }
else if (expr_->IsVar()) {
5545 reinterpret_cast<IntVar*
>(expr_)->RemoveInterval(-root + 1, root - 1);
5549 int64_t Max()
const override {
5550 return std::max(Pown(expr_->Min()), Pown(expr_->Max()));
5553 void SetMax(int64_t m)
override {
5557 if (m == std::numeric_limits<int64_t>::max()) {
5560 const int64_t root = SqrnDown(m);
5561 expr_->SetRange(-root, root);
5565class PosIntEvenPower :
public BasePower {
5567 PosIntEvenPower(Solver*
const s, IntExpr*
const e, int64_t pow)
5568 : BasePower(s, e, pow) {
5569 CHECK_EQ(0, pow % 2);
5572 ~PosIntEvenPower()
override {}
5574 int64_t Min()
const override {
return Pown(expr_->Min()); }
5576 void SetMin(int64_t m)
override {
5580 expr_->SetMin(SqrnUp(m));
5582 int64_t Max()
const override {
return Pown(expr_->Max()); }
5584 void SetMax(int64_t m)
override {
5588 if (m == std::numeric_limits<int64_t>::max()) {
5591 expr_->SetMax(SqrnDown(m));
5595class IntOddPower :
public BasePower {
5597 IntOddPower(Solver*
const s, IntExpr*
const e, int64_t n)
5598 : BasePower(s, e, n) {
5602 ~IntOddPower()
override {}
5604 int64_t Min()
const override {
return Pown(expr_->Min()); }
5606 void SetMin(int64_t m)
override { expr_->SetMin(SqrnUp(m)); }
5608 int64_t Max()
const override {
return Pown(expr_->Max()); }
5610 void SetMax(int64_t m)
override { expr_->SetMax(SqrnDown(m)); }
5615class MinIntExpr :
public BaseIntExpr {
5617 MinIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5618 : BaseIntExpr(s), left_(l), right_(r) {}
5619 ~MinIntExpr()
override {}
5620 int64_t Min()
const override {
5621 const int64_t lmin = left_->
Min();
5622 const int64_t rmin = right_->
Min();
5623 return std::min(lmin, rmin);
5625 void SetMin(int64_t m)
override {
5629 int64_t Max()
const override {
5630 const int64_t lmax = left_->
Max();
5631 const int64_t rmax = right_->
Max();
5632 return std::min(lmax, rmax);
5634 void SetMax(int64_t m)
override {
5635 if (left_->
Min() > m) {
5638 if (right_->
Min() > m) {
5642 std::string name()
const override {
5643 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->
name(), right_->
name());
5645 std::string DebugString()
const override {
5646 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->
DebugString(),
5649 void WhenRange(Demon* d)
override {
5654 void Accept(ModelVisitor*
const visitor)
const override {
5655 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5656 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5657 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5659 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5663 IntExpr*
const left_;
5664 IntExpr*
const right_;
5669class MinCstIntExpr :
public BaseIntExpr {
5671 MinCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5672 : BaseIntExpr(s), expr_(e), value_(v) {}
5674 ~MinCstIntExpr()
override {}
5676 int64_t Min()
const override {
return std::min(expr_->
Min(), value_); }
5678 void SetMin(int64_t m)
override {
5685 int64_t Max()
const override {
return std::min(expr_->
Max(), value_); }
5687 void SetMax(int64_t m)
override {
5693 bool Bound()
const override {
5694 return (expr_->
Bound() || expr_->
Min() >= value_);
5697 std::string name()
const override {
5698 return absl::StrFormat(
"MinCstIntExpr(%s, %d)", expr_->
name(), value_);
5701 std::string DebugString()
const override {
5702 return absl::StrFormat(
"MinCstIntExpr(%s, %d)", expr_->
DebugString(),
5706 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5708 void Accept(ModelVisitor*
const visitor)
const override {
5709 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5710 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5712 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5713 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5717 IntExpr*
const expr_;
5718 const int64_t value_;
5723class MaxIntExpr :
public BaseIntExpr {
5725 MaxIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5726 : BaseIntExpr(s), left_(l), right_(r) {}
5728 ~MaxIntExpr()
override {}
5730 int64_t Min()
const override {
return std::max(left_->
Min(), right_->
Min()); }
5732 void SetMin(int64_t m)
override {
5733 if (left_->
Max() < m) {
5736 if (right_->
Max() < m) {
5742 int64_t Max()
const override {
return std::max(left_->
Max(), right_->
Max()); }
5744 void SetMax(int64_t m)
override {
5749 std::string name()
const override {
5750 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->
name(), right_->
name());
5753 std::string DebugString()
const override {
5754 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->
DebugString(),
5758 void WhenRange(Demon* d)
override {
5763 void Accept(ModelVisitor*
const visitor)
const override {
5764 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5765 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5766 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5768 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5772 IntExpr*
const left_;
5773 IntExpr*
const right_;
5778class MaxCstIntExpr :
public BaseIntExpr {
5780 MaxCstIntExpr(Solver*
const s, IntExpr*
const e, int64_t v)
5781 : BaseIntExpr(s), expr_(e), value_(v) {}
5783 ~MaxCstIntExpr()
override {}
5785 int64_t Min()
const override {
return std::max(expr_->
Min(), value_); }
5787 void SetMin(int64_t m)
override {
5793 int64_t Max()
const override {
return std::max(expr_->
Max(), value_); }
5795 void SetMax(int64_t m)
override {
5802 bool Bound()
const override {
5803 return (expr_->
Bound() || expr_->
Max() <= value_);
5806 std::string name()
const override {
5807 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)", expr_->
name(), value_);
5810 std::string DebugString()
const override {
5811 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)", expr_->
DebugString(),
5815 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5817 void Accept(ModelVisitor*
const visitor)
const override {
5818 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5819 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5821 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5822 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5826 IntExpr*
const expr_;
5827 const int64_t value_;
5838class SimpleConvexPiecewiseExpr :
public BaseIntExpr {
5840 SimpleConvexPiecewiseExpr(Solver*
const s, IntExpr*
const e, int64_t ec,
5841 int64_t ed, int64_t ld, int64_t lc)
5845 early_date_(ec == 0 ? std::numeric_limits<int64_t>::min() : ed),
5846 late_date_(lc == 0 ? std::numeric_limits<int64_t>::max() : ld),
5848 DCHECK_GE(ec, int64_t{0});
5849 DCHECK_GE(lc, int64_t{0});
5856 ~SimpleConvexPiecewiseExpr()
override {}
5858 int64_t Min()
const override {
5859 const int64_t vmin = expr_->
Min();
5860 const int64_t vmax = expr_->
Max();
5861 if (vmin >= late_date_) {
5862 return (vmin - late_date_) * late_cost_;
5863 }
else if (vmax <= early_date_) {
5864 return (early_date_ - vmax) * early_cost_;
5870 void SetMin(int64_t m)
override {
5876 expr_->
Range(&vmin, &vmax);
5879 (late_cost_ == 0 ? vmax : late_date_ +
PosIntDivUp(m, late_cost_) - 1);
5881 (early_cost_ == 0 ? vmin
5884 if (expr_->
IsVar()) {
5889 int64_t Max()
const override {
5890 const int64_t vmin = expr_->
Min();
5891 const int64_t vmax = expr_->
Max();
5892 const int64_t mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0;
5894 vmin < early_date_ ? (early_date_ - vmin) * early_cost_ : 0;
5895 return std::max(mr, ml);
5898 void SetMax(int64_t m)
override {
5902 if (late_cost_ != 0LL) {
5903 const int64_t rb = late_date_ +
PosIntDivDown(m, late_cost_);
5904 if (early_cost_ != 0LL) {
5905 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5911 if (early_cost_ != 0LL) {
5912 const int64_t lb = early_date_ -
PosIntDivDown(m, early_cost_);
5918 std::string name()
const override {
5919 return absl::StrFormat(
5920 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5921 expr_->
name(), early_cost_, early_date_, late_date_, late_cost_);
5924 std::string DebugString()
const override {
5925 return absl::StrFormat(
5926 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5927 expr_->
DebugString(), early_cost_, early_date_, late_date_, late_cost_);
5930 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
5932 void Accept(ModelVisitor*
const visitor)
const override {
5933 visitor->BeginVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5934 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5936 visitor->VisitIntegerArgument(ModelVisitor::kEarlyCostArgument,
5938 visitor->VisitIntegerArgument(ModelVisitor::kEarlyDateArgument,
5940 visitor->VisitIntegerArgument(ModelVisitor::kLateCostArgument, late_cost_);
5941 visitor->VisitIntegerArgument(ModelVisitor::kLateDateArgument, late_date_);
5942 visitor->EndVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5946 IntExpr*
const expr_;
5947 const int64_t early_cost_;
5948 const int64_t early_date_;
5949 const int64_t late_date_;
5950 const int64_t late_cost_;
5955class SemiContinuousExpr :
public BaseIntExpr {
5957 SemiContinuousExpr(Solver*
const s, IntExpr*
const e, int64_t fixed_charge,
5959 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge), step_(step) {
5960 DCHECK_GE(fixed_charge, int64_t{0});
5961 DCHECK_GT(step, int64_t{0});
5964 ~SemiContinuousExpr()
override {}
5966 int64_t
Value(int64_t x)
const {
5974 int64_t Min()
const override {
return Value(expr_->
Min()); }
5976 void SetMin(int64_t m)
override {
5977 if (m >=
CapAdd(fixed_charge_, step_)) {
5985 int64_t Max()
const override {
return Value(expr_->
Max()); }
5987 void SetMax(int64_t m)
override {
5991 if (m == std::numeric_limits<int64_t>::max()) {
5994 if (m <
CapAdd(fixed_charge_, step_)) {
6002 std::string name()
const override {
6003 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
6004 expr_->
name(), fixed_charge_, step_);
6007 std::string DebugString()
const override {
6008 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
6012 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
6014 void Accept(ModelVisitor*
const visitor)
const override {
6015 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6016 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6018 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6020 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, step_);
6021 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6025 IntExpr*
const expr_;
6026 const int64_t fixed_charge_;
6027 const int64_t step_;
6030class SemiContinuousStepOneExpr :
public BaseIntExpr {
6032 SemiContinuousStepOneExpr(Solver*
const s, IntExpr*
const e,
6033 int64_t fixed_charge)
6034 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) {
6035 DCHECK_GE(fixed_charge, int64_t{0});
6038 ~SemiContinuousStepOneExpr()
override {}
6040 int64_t
Value(int64_t x)
const {
6044 return fixed_charge_ +
x;
6048 int64_t Min()
const override {
return Value(expr_->
Min()); }
6050 void SetMin(int64_t m)
override {
6051 if (m >= fixed_charge_ + 1) {
6052 expr_->
SetMin(m - fixed_charge_);
6058 int64_t Max()
const override {
return Value(expr_->
Max()); }
6060 void SetMax(int64_t m)
override {
6064 if (m < fixed_charge_ + 1) {
6067 expr_->
SetMax(m - fixed_charge_);
6071 std::string name()
const override {
6072 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6073 expr_->
name(), fixed_charge_);
6076 std::string DebugString()
const override {
6077 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6081 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
6083 void Accept(ModelVisitor*
const visitor)
const override {
6084 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6085 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6087 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6089 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 1);
6090 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6094 IntExpr*
const expr_;
6095 const int64_t fixed_charge_;
6098class SemiContinuousStepZeroExpr :
public BaseIntExpr {
6100 SemiContinuousStepZeroExpr(Solver*
const s, IntExpr*
const e,
6101 int64_t fixed_charge)
6102 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) {
6103 DCHECK_GT(fixed_charge, int64_t{0});
6106 ~SemiContinuousStepZeroExpr()
override {}
6108 int64_t
Value(int64_t x)
const {
6112 return fixed_charge_;
6116 int64_t Min()
const override {
return Value(expr_->
Min()); }
6118 void SetMin(int64_t m)
override {
6119 if (m >= fixed_charge_) {
6126 int64_t Max()
const override {
return Value(expr_->
Max()); }
6128 void SetMax(int64_t m)
override {
6132 if (m < fixed_charge_) {
6137 std::string name()
const override {
6138 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6139 expr_->
name(), fixed_charge_);
6142 std::string DebugString()
const override {
6143 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6147 void WhenRange(Demon* d)
override { expr_->
WhenRange(d); }
6149 void Accept(ModelVisitor*
const visitor)
const override {
6150 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6151 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6153 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6155 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 0);
6156 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6160 IntExpr*
const expr_;
6161 const int64_t fixed_charge_;
6165class LinkExprAndVar :
public CastConstraint {
6167 LinkExprAndVar(Solver*
const s, IntExpr*
const expr, IntVar*
const var)
6168 : CastConstraint(s, var), expr_(expr) {}
6170 ~LinkExprAndVar()
override {}
6172 void Post()
override {
6173 Solver*
const s = solver();
6174 Demon* d = s->MakeConstraintInitialPropagateCallback(
this);
6176 target_var_->WhenRange(d);
6179 void InitialPropagate()
override {
6180 expr_->
SetRange(target_var_->Min(), target_var_->Max());
6182 expr_->
Range(&l, &u);
6183 target_var_->SetRange(l, u);
6186 std::string DebugString()
const override {
6187 return absl::StrFormat(
"cast(%s, %s)", expr_->
DebugString(),
6188 target_var_->DebugString());
6191 void Accept(ModelVisitor*
const visitor)
const override {
6192 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6193 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6195 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6197 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6201 IntExpr*
const expr_;
6206class ExprWithEscapeValue :
public BaseIntExpr {
6208 ExprWithEscapeValue(Solver*
const s, IntVar*
const c, IntExpr*
const e,
6209 int64_t unperformed_value)
6213 unperformed_value_(unperformed_value) {}
6216 ExprWithEscapeValue(
const ExprWithEscapeValue&) =
delete;
6217 ExprWithEscapeValue& operator=(
const ExprWithEscapeValue&) =
delete;
6219 ~ExprWithEscapeValue()
override {}
6221 int64_t Min()
const override {
6222 if (condition_->
Min() == 1) {
6223 return expression_->
Min();
6224 }
else if (condition_->
Max() == 1) {
6225 return std::min(unperformed_value_, expression_->
Min());
6227 return unperformed_value_;
6231 void SetMin(int64_t m)
override {
6232 if (m > unperformed_value_) {
6235 }
else if (condition_->
Min() == 1) {
6237 }
else if (m > expression_->
Max()) {
6242 int64_t Max()
const override {
6243 if (condition_->
Min() == 1) {
6244 return expression_->
Max();
6245 }
else if (condition_->
Max() == 1) {
6246 return std::max(unperformed_value_, expression_->
Max());
6248 return unperformed_value_;
6252 void SetMax(int64_t m)
override {
6253 if (m < unperformed_value_) {
6256 }
else if (condition_->
Min() == 1) {
6258 }
else if (m < expression_->Min()) {
6263 void SetRange(int64_t mi, int64_t ma)
override {
6264 if (ma < unperformed_value_ || mi > unperformed_value_) {
6267 }
else if (condition_->
Min() == 1) {
6269 }
else if (ma < expression_->Min() || mi > expression_->
Max()) {
6274 void SetValue(int64_t v)
override {
6275 if (v != unperformed_value_) {
6278 }
else if (condition_->
Min() == 1) {
6280 }
else if (v < expression_->Min() || v > expression_->
Max()) {
6285 bool Bound()
const override {
6286 return condition_->
Max() == 0 || expression_->
Bound();
6289 void WhenRange(Demon* d)
override {
6294 std::string DebugString()
const override {
6295 return absl::StrFormat(
"ConditionExpr(%s, %s, %d)",
6300 void Accept(ModelVisitor*
const visitor)
const override {
6301 visitor->BeginVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6302 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
6304 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6306 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
6307 unperformed_value_);
6308 visitor->EndVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6312 IntVar*
const condition_;
6313 IntExpr*
const expression_;
6314 const int64_t unperformed_value_;
6318class LinkExprAndDomainIntVar :
public CastConstraint {
6320 LinkExprAndDomainIntVar(Solver*
const s, IntExpr*
const expr,
6321 DomainIntVar*
const var)
6322 : CastConstraint(s, var),
6324 cached_min_(std::numeric_limits<int64_t>::min()),
6325 cached_max_(std::numeric_limits<int64_t>::max()),
6326 fail_stamp_(uint64_t{0}) {}
6328 ~LinkExprAndDomainIntVar()
override {}
6330 DomainIntVar* var()
const {
6331 return reinterpret_cast<DomainIntVar*
>(target_var_);
6334 void Post()
override {
6335 Solver*
const s = solver();
6336 Demon*
const d = s->MakeConstraintInitialPropagateCallback(
this);
6339 solver(),
this, &LinkExprAndDomainIntVar::Propagate,
"Propagate");
6340 target_var_->WhenRange(target_var_demon);
6343 void InitialPropagate()
override {
6344 expr_->
SetRange(var()->min_.Value(), var()->max_.Value());
6345 expr_->
Range(&cached_min_, &cached_max_);
6346 var()->DomainIntVar::SetRange(cached_min_, cached_max_);
6350 if (var()->min_.Value() > cached_min_ ||
6351 var()->max_.Value() < cached_max_ ||
6352 solver()->fail_stamp() != fail_stamp_) {
6354 fail_stamp_ = solver()->fail_stamp();
6358 std::string DebugString()
const override {
6359 return absl::StrFormat(
"cast(%s, %s)", expr_->
DebugString(),
6360 target_var_->DebugString());
6363 void Accept(ModelVisitor*
const visitor)
const override {
6364 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6365 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6367 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6369 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6373 IntExpr*
const expr_;
6374 int64_t cached_min_;
6375 int64_t cached_max_;
6376 uint64_t fail_stamp_;
6383 return CondRevAlloc(
solver(), reversible,
new EmptyIterator());
6386 return CondRevAlloc(
solver(), reversible,
new RangeIterator(
this));
6393 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(var);
6394 dvar->CleanInProcess();
6398 const std::vector<IntVar*>& vars) {
6399 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(var);
6400 CHECK(dvar !=
nullptr);
6401 return dvar->SetIsEqual(values, vars);
6405 absl::Span<const int64_t> values,
6406 const std::vector<IntVar*>& vars) {
6407 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(var);
6408 CHECK(dvar !=
nullptr);
6409 return dvar->SetIsGreaterOrEqual(values, vars);
6424 if (min == 0 && max == 1) {
6426 }
else if (
CapSub(max, min) == 1) {
6427 const std::string inner_name =
"inner_" + name;
6430 ->VarWithName(name));
6449 const std::string& name) {
6450 DCHECK(!values.empty());
6452 if (values.size() == 1)
return MakeIntConst(values[0], name);
6454 std::vector<int64_t> unique_sorted_values = values;
6457 if (unique_sorted_values.size() == 1)
return MakeIntConst(values[0], name);
6459 if (unique_sorted_values.size() ==
6460 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6461 return MakeIntVar(unique_sorted_values.front(), unique_sorted_values.back(),
6467 for (
const int64_t v : unique_sorted_values) {
6477 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, name)));
6481 for (int64_t& v : unique_sorted_values) {
6482 DCHECK_EQ(0, v % gcd);
6485 const std::string new_name = name.empty() ?
"" :
"inner_" + name;
6487 IntVar* inner_intvar =
nullptr;
6488 if (unique_sorted_values.size() ==
6489 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6490 inner_intvar =
MakeIntVar(unique_sorted_values.front(),
6491 unique_sorted_values.back(), new_name);
6494 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, new_name)));
6496 return MakeProd(inner_intvar, gcd)->Var();
6504 const std::string& name) {
6516 if (absl::GetFlag(FLAGS_cp_share_int_consts) && name.empty() &&
6517 val >= MIN_CACHED_INT_CONST && val <= MAX_CACHED_INT_CONST) {
6518 return cached_constants_[val - MIN_CACHED_INT_CONST];
6520 return RevAlloc(
new IntConst(
this, val, name));
6528std::string IndexedName(absl::string_view prefix,
int index,
int max_index) {
6530#if defined(_MSC_VER)
6531 const int digits = max_index > 0 ?
6532 static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
6535 const int digits = max_index > 0 ?
static_cast<int>(log10(max_index)) + 1: 1;
6537 return absl::StrFormat(
"%s%0*d", prefix, digits, index);
6539 return absl::StrCat(prefix, index);
6545 const std::string& name,
6546 std::vector<IntVar*>* vars) {
6547 for (
int i = 0; i < var_count; ++i) {
6548 vars->push_back(
MakeIntVar(vmin, vmax, IndexedName(name, i, var_count)));
6553 std::vector<IntVar*>* vars) {
6554 for (
int i = 0; i < var_count; ++i) {
6560 const std::string& name) {
6562 for (
int i = 0; i < var_count; ++i) {
6563 vars[i] =
MakeIntVar(vmin, vmax, IndexedName(name, i, var_count));
6569 std::vector<IntVar*>* vars) {
6570 for (
int i = 0; i < var_count; ++i) {
6571 vars->push_back(
MakeBoolVar(IndexedName(name, i, var_count)));
6576 for (
int i = 0; i < var_count; ++i) {
6583 for (
int i = 0; i < var_count; ++i) {
6584 vars[i] =
MakeBoolVar(IndexedName(name, i, var_count));
6589void Solver::InitCachedIntConstants() {
6590 for (
int i = MIN_CACHED_INT_CONST; i <= MAX_CACHED_INT_CONST; ++i) {
6591 cached_constants_[i - MIN_CACHED_INT_CONST] =
6592 RevAlloc(
new IntConst(
this, i,
""));
6597 CHECK_EQ(
this, left->
solver());
6598 CHECK_EQ(
this, right->
solver());
6599 if (right->
Bound()) {
6602 if (left->
Bound()) {
6605 if (left == right) {
6608 IntExpr* cache = model_cache_->FindExprExprExpression(
6610 if (cache ==
nullptr) {
6611 cache = model_cache_->FindExprExprExpression(right, left,
6614 if (cache !=
nullptr) {
6622 model_cache_->InsertExprExprExpression(result, left, right,
6629 CHECK_EQ(
this, expr->
solver());
6630 if (expr->
Bound()) {
6638 if (result ==
nullptr) {
6645 this,
reinterpret_cast<DomainIntVar*
>(var), value)));
6653 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(var);
6654 IntVar*
const sub_var = add_var->SubVar();
6655 const int64_t new_constant = value + add_var->Constant();
6656 if (new_constant == 0) {
6660 DomainIntVar*
const dvar =
6661 reinterpret_cast<DomainIntVar*
>(sub_var);
6663 RevAlloc(
new PlusCstDomainIntVar(
this, dvar, new_constant)));
6666 RevAlloc(
new PlusCstIntVar(
this, sub_var, new_constant)));
6672 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(var);
6673 IntVar*
const sub_var = add_var->SubVar();
6674 const int64_t new_constant = value + add_var->Constant();
6676 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6680 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(var);
6681 IntVar*
const sub_var = add_var->SubVar();
6693 Cache()->InsertExprConstantExpression(result, expr, value,
6700 CHECK_EQ(
this, left->
solver());
6701 CHECK_EQ(
this, right->
solver());
6702 if (left->
Bound()) {
6705 if (right->
Bound()) {
6710 int64_t left_coef = 1;
6711 int64_t right_coef = 1;
6712 if (
IsProduct(left, &sub_left, &left_coef) &&
6713 IsProduct(right, &sub_right, &right_coef)) {
6714 const int64_t abs_gcd =
6716 if (abs_gcd != 0 && abs_gcd != 1) {
6718 MakeProd(sub_right, right_coef / abs_gcd)),
6725 if (result ==
nullptr) {
6732 Cache()->InsertExprExprExpression(result, left, right,
6740 CHECK_EQ(
this, expr->
solver());
6741 if (expr->
Bound()) {
6749 if (result ==
nullptr) {
6750 if (expr->
IsVar() && expr->
Min() != std::numeric_limits<int64_t>::min() &&
6756 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(var);
6757 IntVar*
const sub_var = add_var->SubVar();
6758 const int64_t new_constant = value - add_var->Constant();
6759 if (new_constant == 0) {
6763 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6768 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(var);
6769 IntVar*
const sub_var = add_var->SubVar();
6770 const int64_t new_constant = value - add_var->Constant();
6771 result =
MakeSum(sub_var, new_constant);
6775 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(var);
6776 IntVar*
const sub_var = add_var->SubVar();
6777 result =
MakeSum(sub_var, value);
6787 Cache()->InsertExprConstantExpression(result, expr, value,
6794 CHECK_EQ(
this, expr->
solver());
6795 if (expr->
Bound()) {
6800 if (result ==
nullptr) {
6801 if (expr->
IsVar()) {
6812 CHECK_EQ(
this, expr->
solver());
6815 if (result !=
nullptr) {
6819 int64_t coefficient = 1;
6820 if (
IsProduct(expr, &m_expr, &coefficient)) {
6821 coefficient =
CapProd(coefficient, value);
6824 coefficient = value;
6826 if (m_expr->
Bound()) {
6828 }
else if (coefficient == 1) {
6830 }
else if (coefficient == -1) {
6832 }
else if (coefficient > 0) {
6833 if (m_expr->
Max() > std::numeric_limits<int64_t>::max() / coefficient ||
6834 m_expr->
Min() < std::numeric_limits<int64_t>::min() / coefficient) {
6836 RevAlloc(
new SafeTimesPosIntCstExpr(
this, m_expr, coefficient)));
6839 RevAlloc(
new TimesPosIntCstExpr(
this, m_expr, coefficient)));
6841 }
else if (coefficient == 0) {
6845 RevAlloc(
new TimesIntNegCstExpr(
this, m_expr, coefficient)));
6847 if (m_expr->
IsVar() &&
6848 !absl::GetFlag(FLAGS_cp_disable_expression_optimization)) {
6849 result = result->
Var();
6851 Cache()->InsertExprConstantExpression(result, expr, value,
6858void ExtractPower(
IntExpr**
const expr, int64_t*
const exponant) {
6859 if (
dynamic_cast<BasePower*
>(*expr) !=
nullptr) {
6860 BasePower*
const power =
dynamic_cast<BasePower*
>(*expr);
6861 *expr = power->expr();
6862 *exponant = power->exponant();
6864 if (
dynamic_cast<IntSquare*
>(*expr) !=
nullptr) {
6865 IntSquare*
const power =
dynamic_cast<IntSquare*
>(*expr);
6866 *expr = power->expr();
6869 if ((*expr)->IsVar()) {
6870 IntVar*
const var = (*expr)->Var();
6871 IntExpr*
const sub = var->solver()->CastExpression(var);
6872 if (sub !=
nullptr &&
dynamic_cast<BasePower*
>(sub) !=
nullptr) {
6873 BasePower*
const power =
dynamic_cast<BasePower*
>(sub);
6874 *expr = power->expr();
6875 *exponant = power->exponant();
6877 if (sub !=
nullptr &&
dynamic_cast<IntSquare*
>(sub) !=
nullptr) {
6878 IntSquare*
const power =
dynamic_cast<IntSquare*
>(sub);
6879 *expr = power->expr();
6885void ExtractProduct(IntExpr**
const expr, int64_t*
const coefficient,
6887 if (
dynamic_cast<TimesCstIntVar*
>(*expr) !=
nullptr) {
6888 TimesCstIntVar*
const left_prod =
dynamic_cast<TimesCstIntVar*
>(*expr);
6889 *coefficient *= left_prod->Constant();
6890 *expr = left_prod->SubVar();
6892 }
else if (
dynamic_cast<TimesIntCstExpr*
>(*expr) !=
nullptr) {
6893 TimesIntCstExpr*
const left_prod =
dynamic_cast<TimesIntCstExpr*
>(*expr);
6894 *coefficient *= left_prod->Constant();
6895 *expr = left_prod->Expr();
6902 if (left->
Bound()) {
6906 if (right->
Bound()) {
6914 int64_t left_exponant = 1;
6915 int64_t right_exponant = 1;
6916 ExtractPower(&m_left, &left_exponant);
6917 ExtractPower(&m_right, &right_exponant);
6919 if (m_left == m_right) {
6920 return MakePower(m_left, left_exponant + right_exponant);
6927 int64_t coefficient = 1;
6928 bool modified =
false;
6930 ExtractProduct(&m_left, &coefficient, &modified);
6931 ExtractProduct(&m_right, &coefficient, &modified);
6938 CHECK_EQ(
this, left->
solver());
6939 CHECK_EQ(
this, right->
solver());
6940 IntExpr* result = model_cache_->FindExprExprExpression(
6942 if (result ==
nullptr) {
6943 result = model_cache_->FindExprExprExpression(right, left,
6946 if (result !=
nullptr) {
6950 if (right->
Min() >= 0) {
6952 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6955 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6957 }
else if (right->
IsVar() &&
6959 if (left->
Min() >= 0) {
6961 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6964 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6966 }
else if (left->
Min() >= 0 && right->
Min() >= 0) {
6968 std::numeric_limits<int64_t>::max()) {
6978 model_cache_->InsertExprExprExpression(result, left, right,
6984 CHECK(numerator !=
nullptr);
6985 CHECK(denominator !=
nullptr);
6986 if (denominator->
Bound()) {
6987 return MakeDiv(numerator, denominator->
Min());
6989 IntExpr* result = model_cache_->FindExprExprExpression(
6991 if (result !=
nullptr) {
6995 if (denominator->
Min() <= 0 && denominator->
Max() >= 0) {
6999 if (denominator->
Min() >= 0) {
7000 if (numerator->
Min() >= 0) {
7001 result =
RevAlloc(
new DivPosPosIntExpr(
this, numerator, denominator));
7003 result =
RevAlloc(
new DivPosIntExpr(
this, numerator, denominator));
7005 }
else if (denominator->
Max() <= 0) {
7006 if (numerator->
Max() <= 0) {
7011 new DivPosIntExpr(
this, numerator,
MakeOpposite(denominator))));
7014 result =
RevAlloc(
new DivIntExpr(
this, numerator, denominator));
7016 model_cache_->InsertExprExprExpression(result, numerator, denominator,
7022 CHECK(expr !=
nullptr);
7023 CHECK_EQ(
this, expr->
solver());
7024 if (expr->
Bound()) {
7026 }
else if (value == 1) {
7028 }
else if (value == -1) {
7030 }
else if (value > 0) {
7032 }
else if (value == 0) {
7033 LOG(FATAL) <<
"Cannot divide by 0";
7046 return RevAlloc(
new IntAbsConstraint(
this, var, abs_var));
7050 CHECK_EQ(
this, e->
solver());
7051 if (e->
Min() >= 0) {
7053 }
else if (e->
Max() <= 0) {
7057 if (result ==
nullptr) {
7058 int64_t coefficient = 1;
7060 if (
IsProduct(e, &expr, &coefficient)) {
7071 CHECK_EQ(
this, expr->
solver());
7072 if (expr->
Bound()) {
7073 const int64_t v = expr->
Min();
7077 if (result ==
nullptr) {
7078 if (expr->
Min() >= 0) {
7089 CHECK_EQ(
this, expr->
solver());
7091 if (expr->
Bound()) {
7092 const int64_t v = expr->
Min();
7093 if (v >= OverflowLimit(n)) {
7094 return MakeIntConst(std::numeric_limits<int64_t>::max());
7108 if (expr->
Min() >= 0) {
7123 CHECK_EQ(
this, left->
solver());
7124 CHECK_EQ(
this, right->
solver());
7125 if (left->
Bound()) {
7128 if (right->
Bound()) {
7131 if (left->
Min() >= right->
Max()) {
7134 if (right->
Min() >= left->
Max()) {
7141 CHECK_EQ(
this, expr->
solver());
7142 if (value <= expr->Min()) {
7145 if (expr->
Bound()) {
7148 if (expr->
Max() <= value) {
7155 return MakeMin(expr,
static_cast<int64_t
>(value));
7159 CHECK_EQ(
this, left->
solver());
7160 CHECK_EQ(
this, right->
solver());
7161 if (left->
Bound()) {
7164 if (right->
Bound()) {
7167 if (left->
Min() >= right->
Max()) {
7170 if (right->
Min() >= left->
Max()) {
7177 CHECK_EQ(
this, expr->
solver());
7178 if (expr->
Bound()) {
7181 if (value <= expr->Min()) {
7184 if (expr->
Max() <= value) {
7191 return MakeMax(expr,
static_cast<int64_t
>(value));
7195 int64_t early_date, int64_t late_date,
7196 int64_t late_cost) {
7198 this, expr, early_cost, early_date, late_date, late_cost)));
7202 int64_t fixed_charge, int64_t step) {
7204 if (fixed_charge == 0) {
7208 RevAlloc(
new SemiContinuousStepZeroExpr(
this, expr, fixed_charge)));
7210 }
else if (step == 1) {
7212 RevAlloc(
new SemiContinuousStepOneExpr(
this, expr, fixed_charge)));
7215 RevAlloc(
new SemiContinuousExpr(
this, expr, fixed_charge, step)));
7229 int64_t
Min()
const override {
7230 return f_.GetMinimum(expr_->Min(), expr_->Max());
7234 f_.GetSmallestRangeGreaterThanValue(expr_->Min(), expr_->Max(), m);
7235 expr_->SetRange(range.first, range.second);
7238 int64_t
Max()
const override {
7239 return f_.GetMaximum(expr_->Min(), expr_->Max());
7244 f_.GetSmallestRangeLessThanValue(expr_->Min(), expr_->Max(), m);
7245 expr_->SetRange(range.first, range.second);
7250 f_.GetSmallestRangeInValueRange(expr_->Min(), expr_->Max(), l, u);
7251 expr_->SetRange(range.first, range.second);
7253 std::string
name()
const override {
7254 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)", expr_->name(),
7259 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)", expr_->DebugString(),
7283 int64_t unperformed_value) {
7284 if (condition->
Min() == 1) {
7286 }
else if (condition->
Max() == 0) {
7289 IntExpr* cache =
Cache()->FindExprExprConstantExpression(
7290 condition, expr, unperformed_value,
7292 if (cache ==
nullptr) {
7294 new ExprWithEscapeValue(
this, condition, expr, unperformed_value));
7295 Cache()->InsertExprExprConstantExpression(
7296 cache, condition, expr, unperformed_value,
7333 const int size = values.size();
7357 int start_index = 0;
7358 int64_t new_min =
Min();
7359 if (values[start_index] <= new_min) {
7360 while (start_index < size - 1 &&
7361 values[start_index + 1] == values[start_index] + 1) {
7362 new_min = values[start_index + 1] + 1;
7366 int end_index = size - 1;
7367 int64_t new_max =
Max();
7368 if (values[end_index] >= new_max) {
7369 while (end_index > start_index + 1 &&
7370 values[end_index - 1] == values[end_index] - 1) {
7371 new_max = values[end_index - 1] - 1;
7376 for (
int i = start_index; i <= end_index; ++i) {
7389 switch (values.size()) {
7401 const int64_t l = std::min(values[0], values[1]);
7402 const int64_t u = std::max(values[0], values[1]);
7422 std::vector<int64_t>& tmp =
solver()->tmp_vector_;
7424 tmp.insert(tmp.end(), values.begin(), values.end());
7425 std::sort(tmp.begin(), tmp.end());
7426 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
7427 const int size = tmp.size();
7428 const int64_t vmin =
Min();
7429 const int64_t vmax =
Max();
7431 int last = size - 1;
7432 if (tmp.front() > vmax || tmp.back() < vmin) {
7436 while (tmp[first] < vmin || !
Contains(tmp[first])) {
7438 if (first > last || tmp[first] > vmax) {
7442 while (last > first && (tmp[last] > vmax || !
Contains(tmp[last]))) {
7446 DCHECK_GE(last, first);
7448 while (first < last) {
7449 const int64_t start = tmp[first] + 1;
7450 const int64_t end = tmp[first + 1] - 1;
7462 if (!var->
Bound()) {
7464 DomainIntVar* dvar =
reinterpret_cast<DomainIntVar*
>(var);
7466 s->
RevAlloc(
new LinkExprAndDomainIntVar(s, expr, dvar)), dvar, expr);
7475 if (var_ ==
nullptr) {
7476 solver()->SaveValue(
reinterpret_cast<void**
>(&var_));
7484 Range(&vmin, &vmax);
7493 if (expr->
IsVar()) {
7495 expr = CastExpression(expr_var);
7499 SubIntExpr*
const sub_expr =
dynamic_cast<SubIntExpr*
>(expr);
7500 if (sub_expr !=
nullptr) {
7501 *left = sub_expr->left();
7502 *right = sub_expr->right();
7509 bool* is_negated)
const {
7511 *inner_var = expr->
Var();
7512 *is_negated =
false;
7515 SubCstIntVar*
const sub_var =
reinterpret_cast<SubCstIntVar*
>(expr);
7516 if (sub_var !=
nullptr && sub_var->Constant() == 1 &&
7519 *inner_var = sub_var->SubVar();
7527 int64_t* coefficient) {
7528 if (
dynamic_cast<TimesCstIntVar*
>(expr) !=
nullptr) {
7529 TimesCstIntVar*
const var =
dynamic_cast<TimesCstIntVar*
>(expr);
7530 *coefficient = var->Constant();
7531 *inner_expr = var->SubVar();
7533 }
else if (
dynamic_cast<TimesIntCstExpr*
>(expr) !=
nullptr) {
7534 TimesIntCstExpr*
const prod =
dynamic_cast<TimesIntCstExpr*
>(expr);
7535 *coefficient = prod->Constant();
7536 *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)
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