21 #include "absl/container/flat_hash_map.h"
22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/str_format.h"
37 "Disable special optimization when creating expressions.");
38 DEFINE_bool(cp_share_int_consts,
true,
"Share IntConst's with the same value.");
41 #pragma warning(disable : 4351 4355)
48 IntVar* IntExpr::VarWithName(
const std::string&
name) {
49 IntVar*
const var = Var();
56 IntVar::IntVar(Solver*
const s) : IntExpr(s), index_(s->GetNewIntVarIndex()) {}
58 IntVar::IntVar(Solver*
const s,
const std::string&
name)
59 : IntExpr(s), index_(s->GetNewIntVarIndex()) {
65 const int BooleanVar::kUnboundBooleanVarValue = 2;
67 void BooleanVar::SetMin(
int64 m) {
69 if (m > 1) solver()->Fail();
73 void BooleanVar::SetMax(
int64 m) {
75 if (m < 0) solver()->Fail();
80 if (mi > 1 || ma < 0 || mi > ma) {
90 void BooleanVar::RemoveValue(
int64 v) {
91 if (value_ == kUnboundBooleanVarValue) {
97 }
else if (v == value_) {
104 if (l <= 0 && u >= 1) {
113 void BooleanVar::WhenBound(Demon* d) {
114 if (value_ == kUnboundBooleanVarValue) {
115 if (d->priority() == Solver::DELAYED_PRIORITY) {
124 return (1 + (value_ == kUnboundBooleanVarValue));
127 bool BooleanVar::Contains(
int64 v)
const {
128 return ((v == 0 && value_ != 1) || (v == 1 && value_ != 0));
131 IntVar* BooleanVar::IsEqual(
int64 constant) {
132 if (constant > 1 || constant < 0) {
133 return solver()->MakeIntConst(0);
138 return solver()->MakeDifference(1,
this)->Var();
142 IntVar* BooleanVar::IsDifferent(
int64 constant) {
143 if (constant > 1 || constant < 0) {
144 return solver()->MakeIntConst(1);
147 return solver()->MakeDifference(1,
this)->Var();
153 IntVar* BooleanVar::IsGreaterOrEqual(
int64 constant) {
155 return solver()->MakeIntConst(0);
156 }
else if (constant <= 0) {
157 return solver()->MakeIntConst(1);
163 IntVar* BooleanVar::IsLessOrEqual(
int64 constant) {
165 return solver()->MakeIntConst(0);
166 }
else if (constant >= 1) {
167 return solver()->MakeIntConst(1);
173 std::string BooleanVar::DebugString()
const {
175 const std::string& var_name =
name();
176 if (!var_name.empty()) {
177 out = var_name +
"(";
188 case kUnboundBooleanVarValue:
201 class DomainIntVar :
public IntVar {
204 class BitSetIterator :
public BaseObject {
209 ~BitSetIterator()
override {}
216 bool Ok()
const {
return current_ <= max_; }
223 bitset_,
current_ - omin_, max_ - omin_) +
228 std::string DebugString()
const override {
return "BitSetIterator"; }
237 class BitSet :
public BaseObject {
239 explicit BitSet(Solver*
const s) :
solver_(s), holes_stamp_(0) {}
240 ~BitSet()
override {}
244 virtual bool Contains(
int64 val)
const = 0;
245 virtual bool SetValue(
int64 val) = 0;
246 virtual bool RemoveValue(
int64 val) = 0;
247 virtual uint64 Size()
const = 0;
248 virtual void DelayRemoveValue(
int64 val) = 0;
249 virtual void ApplyRemovedValues(DomainIntVar*
var) = 0;
250 virtual void ClearRemovedValues() = 0;
252 virtual BitSetIterator* MakeIterator() = 0;
256 if (holes_stamp_ < current_stamp) {
258 holes_stamp_ = current_stamp;
262 virtual void ClearHoles() {
holes_.clear(); }
264 const std::vector<int64>& Holes() {
return holes_; }
268 int NumHoles()
const {
276 std::vector<int64>
holes_;
280 class QueueHandler :
public Demon {
282 explicit QueueHandler(DomainIntVar*
const var) : var_(
var) {}
283 ~QueueHandler()
override {}
284 void Run(Solver*
const s)
override {
285 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
287 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
289 Solver::DemonPriority priority()
const override {
290 return Solver::VAR_PRIORITY;
292 std::string DebugString()
const override {
293 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
297 DomainIntVar*
const var_;
308 RevIntPtrMap(Solver*
const solver,
int64 rmin,
int64 rmax)
309 :
solver_(solver), range_min_(rmin), start_(0) {}
313 bool Empty()
const {
return start_.Value() == elements_.size(); }
315 void SortActive() { std::sort(elements_.begin(), elements_.end()); }
321 elements_.push_back(std::make_pair(
value, elem));
322 if (
solver_->state() != Solver::OUTSIDE_SEARCH) {
324 [
this,
value](Solver* s) { Uninsert(
value); },
false);
329 for (
int pos = start_.Value(); pos < elements_.size(); ++pos) {
330 if (elements_[pos].first ==
value) {
331 if (position !=
nullptr) *position = pos;
332 return At(pos).second;
340 const int start = start_.Value();
341 DCHECK_GE(position, start);
342 DCHECK_LT(position, elements_.size());
343 if (position > start) {
346 const std::pair<int64, T*> copy = elements_[start];
347 elements_[start] = elements_[position];
348 elements_[position] = copy;
353 const std::pair<int64, T*>& At(
int position)
const {
354 DCHECK_GE(position, start_.Value());
355 DCHECK_LT(position, elements_.size());
356 return elements_[position];
359 void RemoveAll() { start_.SetValue(
solver_, elements_.size()); }
361 int start()
const {
return start_.Value(); }
362 int end()
const {
return elements_.size(); }
364 int Size()
const {
return elements_.size() - start_.Value(); }
368 for (
int pos = 0; pos < elements_.size(); ++pos) {
369 if (elements_[pos].first ==
value) {
370 DCHECK_GE(pos, start_.Value());
371 const int last = elements_.size() - 1;
373 elements_[pos] = elements_.back();
375 elements_.pop_back();
379 LOG(FATAL) <<
"The element should have been removed";
384 const int64 range_min_;
385 NumericalRev<int> start_;
386 std::vector<std::pair<int64, T*>> elements_;
390 class BaseValueWatcher :
public Constraint {
392 explicit BaseValueWatcher(Solver*
const solver) : Constraint(solver) {}
394 ~BaseValueWatcher()
override {}
396 virtual IntVar* GetOrMakeValueWatcher(
int64 value) = 0;
398 virtual void SetValueWatcher(IntVar*
const boolvar,
int64 value) = 0;
403 class ValueWatcher :
public BaseValueWatcher {
405 class WatchDemon :
public Demon {
407 WatchDemon(ValueWatcher*
const watcher,
int64 value, IntVar*
var)
408 : value_watcher_(watcher), value_(
value), var_(
var) {}
409 ~WatchDemon()
override {}
411 void Run(Solver*
const solver)
override {
412 value_watcher_->ProcessValueWatcher(value_, var_);
416 ValueWatcher*
const value_watcher_;
421 class VarDemon :
public Demon {
423 explicit VarDemon(ValueWatcher*
const watcher)
424 : value_watcher_(watcher) {}
426 ~VarDemon()
override {}
428 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
431 ValueWatcher*
const value_watcher_;
434 ValueWatcher(Solver*
const solver, DomainIntVar*
const variable)
435 : BaseValueWatcher(solver),
437 hole_iterator_(variable_->MakeHoleIterator(true)),
439 watchers_(solver, variable->Min(), variable->Max()) {}
441 ~ValueWatcher()
override {}
443 IntVar* GetOrMakeValueWatcher(
int64 value)
override {
444 IntVar*
const watcher = watchers_.FindPtrOrNull(
value,
nullptr);
445 if (watcher !=
nullptr)
return watcher;
446 if (variable_->Contains(
value)) {
447 if (variable_->Bound()) {
448 return solver()->MakeIntConst(1);
450 const std::string vname = variable_->HasName()
452 : variable_->DebugString();
453 const std::string bname =
454 absl::StrFormat(
"Watch<%s == %d>", vname,
value);
455 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
456 watchers_.UnsafeRevInsert(
value, boolvar);
457 if (posted_.Switched()) {
459 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
460 var_demon_->desinhibit(solver());
465 return variable_->solver()->MakeIntConst(0);
469 void SetValueWatcher(IntVar*
const boolvar,
int64 value)
override {
470 CHECK(watchers_.FindPtrOrNull(
value,
nullptr) ==
nullptr);
471 if (!boolvar->Bound()) {
472 watchers_.UnsafeRevInsert(
value, boolvar);
473 if (posted_.Switched() && !boolvar->Bound()) {
475 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
476 var_demon_->desinhibit(solver());
481 void Post()
override {
482 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
483 variable_->WhenDomain(var_demon_);
484 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
485 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
487 IntVar*
const boolvar = w.second;
488 if (!boolvar->Bound() && variable_->Contains(
value)) {
490 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
493 posted_.Switch(solver());
496 void InitialPropagate()
override {
497 if (variable_->Bound()) {
500 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
501 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
503 IntVar*
const boolvar = w.second;
504 if (!variable_->Contains(
value)) {
505 boolvar->SetValue(0);
506 watchers_.RemoveAt(pos);
508 if (boolvar->Bound()) {
509 ProcessValueWatcher(
value, boolvar);
510 watchers_.RemoveAt(pos);
518 void ProcessValueWatcher(
int64 value, IntVar* boolvar) {
519 if (boolvar->Min() == 0) {
520 if (variable_->Size() < 0xFFFFFF) {
521 variable_->RemoveValue(
value);
524 solver()->AddConstraint(solver()->MakeNonEquality(variable_,
value));
527 variable_->SetValue(
value);
532 const int kSmallList = 16;
533 if (variable_->Bound()) {
535 }
else if (watchers_.Size() <= kSmallList ||
536 variable_->Min() != variable_->OldMin() ||
537 variable_->Max() != variable_->OldMax()) {
547 BitSet*
const bitset = variable_->bitset();
548 if (bitset !=
nullptr && !watchers_.Empty()) {
549 if (bitset->NumHoles() * 2 < watchers_.Size()) {
550 for (
const int64 hole : InitAndGetValues(hole_iterator_)) {
552 IntVar*
const boolvar = watchers_.FindPtrOrNull(hole, &pos);
553 if (boolvar !=
nullptr) {
554 boolvar->SetValue(0);
555 watchers_.RemoveAt(pos);
567 void VariableBound() {
568 DCHECK(variable_->Bound());
570 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
571 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
572 w.second->SetValue(w.first ==
value);
574 watchers_.RemoveAll();
575 var_demon_->inhibit(solver());
579 void ScanWatchers() {
580 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
581 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
582 if (!variable_->Contains(w.first)) {
583 IntVar*
const boolvar = w.second;
584 boolvar->SetValue(0);
585 watchers_.RemoveAt(pos);
592 void CheckInhibit() {
593 if (watchers_.Empty()) {
594 var_demon_->inhibit(solver());
598 void Accept(ModelVisitor*
const visitor)
const override {
599 visitor->BeginVisitConstraint(ModelVisitor::kVarValueWatcher,
this);
600 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
602 std::vector<int64> all_coefficients;
603 std::vector<IntVar*> all_bool_vars;
604 for (
int position = watchers_.start(); position < watchers_.end();
606 const std::pair<int64, IntVar*>& w = watchers_.At(position);
607 all_coefficients.push_back(w.first);
608 all_bool_vars.push_back(w.second);
610 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
612 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
614 visitor->EndVisitConstraint(ModelVisitor::kVarValueWatcher,
this);
617 std::string DebugString()
const override {
618 return absl::StrFormat(
"ValueWatcher(%s)", variable_->DebugString());
622 DomainIntVar*
const variable_;
623 IntVarIterator*
const hole_iterator_;
626 RevIntPtrMap<IntVar> watchers_;
630 class DenseValueWatcher :
public BaseValueWatcher {
632 class WatchDemon :
public Demon {
634 WatchDemon(DenseValueWatcher*
const watcher,
int64 value, IntVar*
var)
635 : value_watcher_(watcher), value_(
value), var_(
var) {}
636 ~WatchDemon()
override {}
638 void Run(Solver*
const solver)
override {
639 value_watcher_->ProcessValueWatcher(value_, var_);
643 DenseValueWatcher*
const value_watcher_;
648 class VarDemon :
public Demon {
650 explicit VarDemon(DenseValueWatcher*
const watcher)
651 : value_watcher_(watcher) {}
653 ~VarDemon()
override {}
655 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
658 DenseValueWatcher*
const value_watcher_;
661 DenseValueWatcher(Solver*
const solver, DomainIntVar*
const variable)
662 : BaseValueWatcher(solver),
664 hole_iterator_(variable_->MakeHoleIterator(true)),
667 watchers_(variable->Max() - variable->Min() + 1, nullptr),
668 active_watchers_(0) {}
670 ~DenseValueWatcher()
override {}
672 IntVar* GetOrMakeValueWatcher(
int64 value)
override {
674 if (value < offset_ || value > var_max) {
675 return solver()->MakeIntConst(0);
678 IntVar*
const watcher = watchers_[
index];
679 if (watcher !=
nullptr)
return watcher;
680 if (variable_->Contains(
value)) {
681 if (variable_->Bound()) {
682 return solver()->MakeIntConst(1);
684 const std::string vname = variable_->HasName()
686 : variable_->DebugString();
687 const std::string bname =
688 absl::StrFormat(
"Watch<%s == %d>", vname,
value);
689 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
690 RevInsert(
index, boolvar);
691 if (posted_.Switched()) {
693 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
694 var_demon_->desinhibit(solver());
699 return variable_->solver()->MakeIntConst(0);
703 void SetValueWatcher(IntVar*
const boolvar,
int64 value)
override {
705 CHECK(watchers_[
index] ==
nullptr);
706 if (!boolvar->Bound()) {
707 RevInsert(
index, boolvar);
708 if (posted_.Switched() && !boolvar->Bound()) {
710 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
711 var_demon_->desinhibit(solver());
716 void Post()
override {
717 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
718 variable_->WhenDomain(var_demon_);
719 for (
int pos = 0; pos < watchers_.size(); ++pos) {
721 IntVar*
const boolvar = watchers_[pos];
722 if (boolvar !=
nullptr && !boolvar->Bound() &&
723 variable_->Contains(
value)) {
725 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
728 posted_.Switch(solver());
731 void InitialPropagate()
override {
732 if (variable_->Bound()) {
735 for (
int pos = 0; pos < watchers_.size(); ++pos) {
736 IntVar*
const boolvar = watchers_[pos];
737 if (boolvar ==
nullptr)
continue;
739 if (!variable_->Contains(
value)) {
740 boolvar->SetValue(0);
742 }
else if (boolvar->Bound()) {
743 ProcessValueWatcher(
value, boolvar);
747 if (active_watchers_.Value() == 0) {
748 var_demon_->inhibit(solver());
753 void ProcessValueWatcher(
int64 value, IntVar* boolvar) {
754 if (boolvar->Min() == 0) {
755 variable_->RemoveValue(
value);
757 variable_->SetValue(
value);
762 if (variable_->Bound()) {
767 if (active_watchers_.Value() == 0) {
768 var_demon_->inhibit(solver());
774 void VariableBound() {
775 DCHECK(variable_->Bound());
777 for (
int pos = 0; pos < watchers_.size(); ++pos) {
778 IntVar*
const boolvar = watchers_[pos];
779 if (boolvar !=
nullptr) {
784 var_demon_->inhibit(solver());
788 void ScanWatchers() {
789 const int64 old_min_index = variable_->OldMin() -
offset_;
790 const int64 old_max_index = variable_->OldMax() -
offset_;
793 for (
int pos = old_min_index; pos < min_index; ++pos) {
794 IntVar*
const boolvar = watchers_[pos];
795 if (boolvar !=
nullptr) {
796 boolvar->SetValue(0);
800 for (
int pos = max_index + 1; pos <= old_max_index; ++pos) {
801 IntVar*
const boolvar = watchers_[pos];
802 if (boolvar !=
nullptr) {
803 boolvar->SetValue(0);
807 BitSet*
const bitset = variable_->bitset();
808 if (bitset !=
nullptr) {
809 if (bitset->NumHoles() * 2 < active_watchers_.Value()) {
810 for (
const int64 hole : InitAndGetValues(hole_iterator_)) {
811 IntVar*
const boolvar = watchers_[hole -
offset_];
812 if (boolvar !=
nullptr) {
813 boolvar->SetValue(0);
818 for (
int pos = min_index + 1; pos < max_index; ++pos) {
819 IntVar*
const boolvar = watchers_[pos];
820 if (boolvar !=
nullptr && !variable_->Contains(
offset_ + pos)) {
821 boolvar->SetValue(0);
829 void RevRemove(
int pos) {
830 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
831 watchers_[pos] =
nullptr;
832 active_watchers_.Decr(solver());
835 void RevInsert(
int pos, IntVar* boolvar) {
836 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
837 watchers_[pos] = boolvar;
838 active_watchers_.Incr(solver());
841 void Accept(ModelVisitor*
const visitor)
const override {
842 visitor->BeginVisitConstraint(ModelVisitor::kVarValueWatcher,
this);
843 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
845 std::vector<int64> all_coefficients;
846 std::vector<IntVar*> all_bool_vars;
847 for (
int position = 0; position < watchers_.size(); ++position) {
848 if (watchers_[position] !=
nullptr) {
849 all_coefficients.push_back(position +
offset_);
850 all_bool_vars.push_back(watchers_[position]);
853 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
855 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
857 visitor->EndVisitConstraint(ModelVisitor::kVarValueWatcher,
this);
860 std::string DebugString()
const override {
861 return absl::StrFormat(
"DenseValueWatcher(%s)", variable_->DebugString());
865 DomainIntVar*
const variable_;
866 IntVarIterator*
const hole_iterator_;
870 std::vector<IntVar*> watchers_;
871 NumericalRev<int> active_watchers_;
874 class BaseUpperBoundWatcher :
public Constraint {
876 explicit BaseUpperBoundWatcher(Solver*
const solver) : Constraint(solver) {}
878 ~BaseUpperBoundWatcher()
override {}
880 virtual IntVar* GetOrMakeUpperBoundWatcher(
int64 value) = 0;
882 virtual void SetUpperBoundWatcher(IntVar*
const boolvar,
int64 value) = 0;
888 class UpperBoundWatcher :
public BaseUpperBoundWatcher {
890 class WatchDemon :
public Demon {
892 WatchDemon(UpperBoundWatcher*
const watcher,
int64 index,
894 : value_watcher_(watcher), index_(
index), var_(
var) {}
895 ~WatchDemon()
override {}
897 void Run(Solver*
const solver)
override {
898 value_watcher_->ProcessUpperBoundWatcher(index_, var_);
902 UpperBoundWatcher*
const value_watcher_;
907 class VarDemon :
public Demon {
909 explicit VarDemon(UpperBoundWatcher*
const watcher)
910 : value_watcher_(watcher) {}
911 ~VarDemon()
override {}
913 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
916 UpperBoundWatcher*
const value_watcher_;
919 UpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
920 : BaseUpperBoundWatcher(solver),
923 watchers_(solver, variable->Min(), variable->Max()),
928 ~UpperBoundWatcher()
override {}
930 IntVar* GetOrMakeUpperBoundWatcher(
int64 value)
override {
931 IntVar*
const watcher = watchers_.FindPtrOrNull(
value,
nullptr);
932 if (watcher !=
nullptr) {
935 if (variable_->Max() >=
value) {
936 if (variable_->Min() >=
value) {
937 return solver()->MakeIntConst(1);
939 const std::string vname = variable_->HasName()
941 : variable_->DebugString();
942 const std::string bname =
943 absl::StrFormat(
"Watch<%s >= %d>", vname,
value);
944 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
945 watchers_.UnsafeRevInsert(
value, boolvar);
946 if (posted_.Switched()) {
948 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
949 var_demon_->desinhibit(solver());
955 return variable_->solver()->MakeIntConst(0);
959 void SetUpperBoundWatcher(IntVar*
const boolvar,
int64 value)
override {
960 CHECK(watchers_.FindPtrOrNull(
value,
nullptr) ==
nullptr);
961 watchers_.UnsafeRevInsert(
value, boolvar);
962 if (posted_.Switched() && !boolvar->Bound()) {
964 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
965 var_demon_->desinhibit(solver());
970 void Post()
override {
971 const int kTooSmallToSort = 8;
972 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
973 variable_->WhenRange(var_demon_);
975 if (watchers_.Size() > kTooSmallToSort) {
976 watchers_.SortActive();
978 start_.SetValue(solver(), watchers_.start());
979 end_.SetValue(solver(), watchers_.end() - 1);
982 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
983 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
984 IntVar*
const boolvar = w.second;
986 if (!boolvar->Bound() &&
value > variable_->Min() &&
987 value <= variable_->Max()) {
989 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
992 posted_.Switch(solver());
995 void InitialPropagate()
override {
996 const int64 var_min = variable_->Min();
997 const int64 var_max = variable_->Max();
999 while (start_.Value() <= end_.Value()) {
1000 const std::pair<int64, IntVar*>& w = watchers_.At(start_.Value());
1001 if (w.first <= var_min) {
1002 w.second->SetValue(1);
1003 start_.Incr(solver());
1008 while (end_.Value() >= start_.Value()) {
1009 const std::pair<int64, IntVar*>& w = watchers_.At(end_.Value());
1010 if (w.first > var_max) {
1011 w.second->SetValue(0);
1012 end_.Decr(solver());
1017 for (
int i = start_.Value(); i <= end_.Value(); ++i) {
1018 const std::pair<int64, IntVar*>& w = watchers_.At(i);
1019 if (w.second->Bound()) {
1020 ProcessUpperBoundWatcher(w.first, w.second);
1023 if (start_.Value() > end_.Value()) {
1024 var_demon_->inhibit(solver());
1027 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1028 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
1030 IntVar*
const boolvar = w.second;
1032 if (
value <= var_min) {
1033 boolvar->SetValue(1);
1034 watchers_.RemoveAt(pos);
1035 }
else if (
value > var_max) {
1036 boolvar->SetValue(0);
1037 watchers_.RemoveAt(pos);
1038 }
else if (boolvar->Bound()) {
1039 ProcessUpperBoundWatcher(
value, boolvar);
1040 watchers_.RemoveAt(pos);
1046 void Accept(ModelVisitor*
const visitor)
const override {
1047 visitor->BeginVisitConstraint(ModelVisitor::kVarBoundWatcher,
this);
1048 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
1050 std::vector<int64> all_coefficients;
1051 std::vector<IntVar*> all_bool_vars;
1052 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1053 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
1054 all_coefficients.push_back(w.first);
1055 all_bool_vars.push_back(w.second);
1057 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
1059 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
1061 visitor->EndVisitConstraint(ModelVisitor::kVarBoundWatcher,
this);
1064 std::string DebugString()
const override {
1065 return absl::StrFormat(
"UpperBoundWatcher(%s)", variable_->DebugString());
1069 void ProcessUpperBoundWatcher(
int64 value, IntVar*
const boolvar) {
1070 if (boolvar->Min() == 0) {
1071 variable_->SetMax(
value - 1);
1073 variable_->SetMin(
value);
1078 const int64 var_min = variable_->Min();
1079 const int64 var_max = variable_->Max();
1081 while (start_.Value() <= end_.Value()) {
1082 const std::pair<int64, IntVar*>& w = watchers_.At(start_.Value());
1083 if (w.first <= var_min) {
1084 w.second->SetValue(1);
1085 start_.Incr(solver());
1090 while (end_.Value() >= start_.Value()) {
1091 const std::pair<int64, IntVar*>& w = watchers_.At(end_.Value());
1092 if (w.first > var_max) {
1093 w.second->SetValue(0);
1094 end_.Decr(solver());
1099 if (start_.Value() > end_.Value()) {
1100 var_demon_->inhibit(solver());
1103 for (
int pos = watchers_.start(); pos < watchers_.end(); ++pos) {
1104 const std::pair<int64, IntVar*>& w = watchers_.At(pos);
1106 IntVar*
const boolvar = w.second;
1108 if (
value <= var_min) {
1109 boolvar->SetValue(1);
1110 watchers_.RemoveAt(pos);
1111 }
else if (
value > var_max) {
1112 boolvar->SetValue(0);
1113 watchers_.RemoveAt(pos);
1116 if (watchers_.Empty()) {
1117 var_demon_->inhibit(solver());
1122 DomainIntVar*
const variable_;
1125 RevIntPtrMap<IntVar> watchers_;
1126 NumericalRev<int> start_;
1127 NumericalRev<int> end_;
1132 class DenseUpperBoundWatcher :
public BaseUpperBoundWatcher {
1134 class WatchDemon :
public Demon {
1136 WatchDemon(DenseUpperBoundWatcher*
const watcher,
int64 value,
1138 : value_watcher_(watcher), value_(
value), var_(
var) {}
1139 ~WatchDemon()
override {}
1141 void Run(Solver*
const solver)
override {
1142 value_watcher_->ProcessUpperBoundWatcher(value_, var_);
1146 DenseUpperBoundWatcher*
const value_watcher_;
1151 class VarDemon :
public Demon {
1153 explicit VarDemon(DenseUpperBoundWatcher*
const watcher)
1154 : value_watcher_(watcher) {}
1156 ~VarDemon()
override {}
1158 void Run(Solver*
const solver)
override { value_watcher_->ProcessVar(); }
1161 DenseUpperBoundWatcher*
const value_watcher_;
1164 DenseUpperBoundWatcher(Solver*
const solver, DomainIntVar*
const variable)
1165 : BaseUpperBoundWatcher(solver),
1166 variable_(variable),
1167 var_demon_(nullptr),
1169 watchers_(variable->Max() - variable->Min() + 1, nullptr),
1170 active_watchers_(0) {}
1172 ~DenseUpperBoundWatcher()
override {}
1174 IntVar* GetOrMakeUpperBoundWatcher(
int64 value)
override {
1175 if (variable_->Max() >=
value) {
1176 if (variable_->Min() >=
value) {
1177 return solver()->MakeIntConst(1);
1179 const std::string vname = variable_->HasName()
1181 : variable_->DebugString();
1182 const std::string bname =
1183 absl::StrFormat(
"Watch<%s >= %d>", vname,
value);
1184 IntVar*
const boolvar = solver()->MakeBoolVar(bname);
1186 if (posted_.Switched()) {
1188 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
1189 var_demon_->desinhibit(solver());
1194 return variable_->solver()->MakeIntConst(0);
1198 void SetUpperBoundWatcher(IntVar*
const boolvar,
int64 value)
override {
1200 CHECK(watchers_[
index] ==
nullptr);
1201 if (!boolvar->Bound()) {
1202 RevInsert(
index, boolvar);
1203 if (posted_.Switched() && !boolvar->Bound()) {
1205 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
1206 var_demon_->desinhibit(solver());
1211 void Post()
override {
1212 var_demon_ = solver()->RevAlloc(
new VarDemon(
this));
1213 variable_->WhenRange(var_demon_);
1214 for (
int pos = 0; pos < watchers_.size(); ++pos) {
1216 IntVar*
const boolvar = watchers_[pos];
1217 if (boolvar !=
nullptr && !boolvar->Bound() &&
1218 value > variable_->Min() && value <= variable_->Max()) {
1220 solver()->RevAlloc(
new WatchDemon(
this,
value, boolvar)));
1223 posted_.Switch(solver());
1226 void InitialPropagate()
override {
1227 for (
int pos = 0; pos < watchers_.size(); ++pos) {
1228 IntVar*
const boolvar = watchers_[pos];
1229 if (boolvar ==
nullptr)
continue;
1231 if (value <= variable_->Min()) {
1232 boolvar->SetValue(1);
1234 }
else if (
value > variable_->Max()) {
1235 boolvar->SetValue(0);
1237 }
else if (boolvar->Bound()) {
1238 ProcessUpperBoundWatcher(
value, boolvar);
1242 if (active_watchers_.Value() == 0) {
1243 var_demon_->inhibit(solver());
1247 void ProcessUpperBoundWatcher(
int64 value, IntVar* boolvar) {
1248 if (boolvar->Min() == 0) {
1249 variable_->SetMax(
value - 1);
1251 variable_->SetMin(
value);
1256 const int64 old_min_index = variable_->OldMin() -
offset_;
1257 const int64 old_max_index = variable_->OldMax() -
offset_;
1260 for (
int pos = old_min_index; pos <= min_index; ++pos) {
1261 IntVar*
const boolvar = watchers_[pos];
1262 if (boolvar !=
nullptr) {
1263 boolvar->SetValue(1);
1268 for (
int pos = max_index + 1; pos <= old_max_index; ++pos) {
1269 IntVar*
const boolvar = watchers_[pos];
1270 if (boolvar !=
nullptr) {
1271 boolvar->SetValue(0);
1275 if (active_watchers_.Value() == 0) {
1276 var_demon_->inhibit(solver());
1280 void RevRemove(
int pos) {
1281 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
1282 watchers_[pos] =
nullptr;
1283 active_watchers_.Decr(solver());
1286 void RevInsert(
int pos, IntVar* boolvar) {
1287 solver()->SaveValue(
reinterpret_cast<void**
>(&watchers_[pos]));
1288 watchers_[pos] = boolvar;
1289 active_watchers_.Incr(solver());
1292 void Accept(ModelVisitor*
const visitor)
const override {
1293 visitor->BeginVisitConstraint(ModelVisitor::kVarBoundWatcher,
this);
1294 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
1296 std::vector<int64> all_coefficients;
1297 std::vector<IntVar*> all_bool_vars;
1298 for (
int position = 0; position < watchers_.size(); ++position) {
1299 if (watchers_[position] !=
nullptr) {
1300 all_coefficients.push_back(position +
offset_);
1301 all_bool_vars.push_back(watchers_[position]);
1304 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
1306 visitor->VisitIntegerArrayArgument(ModelVisitor::kValuesArgument,
1308 visitor->EndVisitConstraint(ModelVisitor::kVarBoundWatcher,
this);
1311 std::string DebugString()
const override {
1312 return absl::StrFormat(
"DenseUpperBoundWatcher(%s)",
1313 variable_->DebugString());
1317 DomainIntVar*
const variable_;
1321 std::vector<IntVar*> watchers_;
1322 NumericalRev<int> active_watchers_;
1326 DomainIntVar(Solver*
const s,
int64 vmin,
int64 vmax,
1327 const std::string&
name);
1328 DomainIntVar(Solver*
const s,
const std::vector<int64>& sorted_values,
1329 const std::string&
name);
1330 ~DomainIntVar()
override;
1332 int64 Min()
const override {
return min_.Value(); }
1333 void SetMin(
int64 m)
override;
1334 int64 Max()
const override {
return max_.Value(); }
1335 void SetMax(
int64 m)
override;
1337 void SetValue(
int64 v)
override;
1338 bool Bound()
const override {
return (min_.Value() == max_.Value()); }
1340 CHECK_EQ(min_.Value(), max_.Value())
1341 <<
" variable " << DebugString() <<
" is not bound.";
1342 return min_.Value();
1344 void RemoveValue(
int64 v)
override;
1345 void RemoveInterval(
int64 l,
int64 u)
override;
1347 void WhenBound(Demon* d)
override {
1348 if (min_.Value() != max_.Value()) {
1349 if (d->priority() == Solver::DELAYED_PRIORITY) {
1357 void WhenRange(Demon* d)
override {
1358 if (min_.Value() != max_.Value()) {
1359 if (d->priority() == Solver::DELAYED_PRIORITY) {
1367 void WhenDomain(Demon* d)
override {
1368 if (min_.Value() != max_.Value()) {
1369 if (d->priority() == Solver::DELAYED_PRIORITY) {
1378 IntVar* IsEqual(
int64 constant)
override {
1379 Solver*
const s = solver();
1380 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1381 return s->MakeIsLessOrEqualCstVar(
this, constant);
1383 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1384 return s->MakeIsGreaterOrEqualCstVar(
this, constant);
1386 if (!Contains(constant)) {
1387 return s->MakeIntConst(
int64{0});
1389 if (Bound() && min_.Value() == constant) {
1390 return s->MakeIntConst(
int64{1});
1392 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1393 this, constant, ModelCache::EXPR_CONSTANT_IS_EQUAL);
1394 if (cache !=
nullptr) {
1395 return cache->Var();
1397 if (value_watcher_ ==
nullptr) {
1398 if (
CapSub(Max(), Min()) <= 256) {
1399 solver()->SaveAndSetValue(
1400 reinterpret_cast<void**
>(&value_watcher_),
1401 reinterpret_cast<void*
>(
1402 solver()->RevAlloc(
new DenseValueWatcher(solver(),
this))));
1405 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1406 reinterpret_cast<void*
>(solver()->RevAlloc(
1407 new ValueWatcher(solver(),
this))));
1409 solver()->AddConstraint(value_watcher_);
1411 IntVar*
const boolvar = value_watcher_->GetOrMakeValueWatcher(constant);
1412 s->Cache()->InsertExprConstantExpression(
1413 boolvar,
this, constant, ModelCache::EXPR_CONSTANT_IS_EQUAL);
1418 Constraint*
SetIsEqual(
const std::vector<int64>& values,
1419 const std::vector<IntVar*>& vars) {
1420 if (value_watcher_ ==
nullptr) {
1421 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&value_watcher_),
1422 reinterpret_cast<void*
>(solver()->RevAlloc(
1423 new ValueWatcher(solver(),
this))));
1424 for (
int i = 0; i < vars.size(); ++i) {
1425 value_watcher_->SetValueWatcher(vars[i], values[i]);
1428 return value_watcher_;
1431 IntVar* IsDifferent(
int64 constant)
override {
1432 Solver*
const s = solver();
1433 if (constant == min_.Value() && value_watcher_ ==
nullptr) {
1434 return s->MakeIsGreaterOrEqualCstVar(
this, constant + 1);
1436 if (constant == max_.Value() && value_watcher_ ==
nullptr) {
1437 return s->MakeIsLessOrEqualCstVar(
this, constant - 1);
1439 if (!Contains(constant)) {
1440 return s->MakeIntConst(
int64{1});
1442 if (Bound() && min_.Value() == constant) {
1443 return s->MakeIntConst(
int64{0});
1445 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1446 this, constant, ModelCache::EXPR_CONSTANT_IS_NOT_EQUAL);
1447 if (cache !=
nullptr) {
1448 return cache->Var();
1450 IntVar*
const boolvar = s->MakeDifference(1, IsEqual(constant))->Var();
1451 s->Cache()->InsertExprConstantExpression(
1452 boolvar,
this, constant, ModelCache::EXPR_CONSTANT_IS_NOT_EQUAL);
1457 IntVar* IsGreaterOrEqual(
int64 constant)
override {
1458 Solver*
const s = solver();
1459 if (max_.Value() < constant) {
1460 return s->MakeIntConst(
int64{0});
1462 if (min_.Value() >= constant) {
1463 return s->MakeIntConst(
int64{1});
1465 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1466 this, constant, ModelCache::EXPR_CONSTANT_IS_GREATER_OR_EQUAL);
1467 if (cache !=
nullptr) {
1468 return cache->Var();
1470 if (bound_watcher_ ==
nullptr) {
1471 if (
CapSub(Max(), Min()) <= 256) {
1472 solver()->SaveAndSetValue(
1473 reinterpret_cast<void**
>(&bound_watcher_),
1474 reinterpret_cast<void*
>(solver()->RevAlloc(
1475 new DenseUpperBoundWatcher(solver(),
this))));
1476 solver()->AddConstraint(bound_watcher_);
1478 solver()->SaveAndSetValue(
1479 reinterpret_cast<void**
>(&bound_watcher_),
1480 reinterpret_cast<void*
>(
1481 solver()->RevAlloc(
new UpperBoundWatcher(solver(),
this))));
1482 solver()->AddConstraint(bound_watcher_);
1485 IntVar*
const boolvar =
1486 bound_watcher_->GetOrMakeUpperBoundWatcher(constant);
1487 s->Cache()->InsertExprConstantExpression(
1488 boolvar,
this, constant,
1489 ModelCache::EXPR_CONSTANT_IS_GREATER_OR_EQUAL);
1495 const std::vector<IntVar*>& vars) {
1496 if (bound_watcher_ ==
nullptr) {
1497 if (
CapSub(Max(), Min()) <= 256) {
1498 solver()->SaveAndSetValue(
1499 reinterpret_cast<void**
>(&bound_watcher_),
1500 reinterpret_cast<void*
>(solver()->RevAlloc(
1501 new DenseUpperBoundWatcher(solver(),
this))));
1502 solver()->AddConstraint(bound_watcher_);
1504 solver()->SaveAndSetValue(
reinterpret_cast<void**
>(&bound_watcher_),
1505 reinterpret_cast<void*
>(solver()->RevAlloc(
1506 new UpperBoundWatcher(solver(),
this))));
1507 solver()->AddConstraint(bound_watcher_);
1509 for (
int i = 0; i < values.size(); ++i) {
1510 bound_watcher_->SetUpperBoundWatcher(vars[i], values[i]);
1513 return bound_watcher_;
1516 IntVar* IsLessOrEqual(
int64 constant)
override {
1517 Solver*
const s = solver();
1518 IntExpr*
const cache = s->Cache()->FindExprConstantExpression(
1519 this, constant, ModelCache::EXPR_CONSTANT_IS_LESS_OR_EQUAL);
1520 if (cache !=
nullptr) {
1521 return cache->Var();
1523 IntVar*
const boolvar =
1524 s->MakeDifference(1, IsGreaterOrEqual(constant + 1))->Var();
1525 s->Cache()->InsertExprConstantExpression(
1526 boolvar,
this, constant, ModelCache::EXPR_CONSTANT_IS_LESS_OR_EQUAL);
1533 void CleanInProcess();
1534 uint64 Size()
const override {
1535 if (bits_ !=
nullptr)
return bits_->Size();
1536 return (
static_cast<uint64>(max_.Value()) -
1537 static_cast<uint64>(min_.Value()) + 1);
1539 bool Contains(
int64 v)
const override {
1540 if (v < min_.Value() || v > max_.Value())
return false;
1541 return (bits_ ==
nullptr ?
true : bits_->Contains(v));
1543 IntVarIterator* MakeHoleIterator(
bool reversible)
const override;
1544 IntVarIterator* MakeDomainIterator(
bool reversible)
const override;
1545 int64 OldMin()
const override {
return std::min(old_min_, min_.Value()); }
1546 int64 OldMax()
const override {
return std::max(old_max_, max_.Value()); }
1548 std::string DebugString()
const override;
1549 BitSet* bitset()
const {
return bits_; }
1551 std::string BaseName()
const override {
return "IntegerVar"; }
1553 friend class PlusCstDomainIntVar;
1554 friend class LinkExprAndDomainIntVar;
1557 void CheckOldMin() {
1558 if (old_min_ > min_.Value()) {
1559 old_min_ = min_.Value();
1562 void CheckOldMax() {
1563 if (old_max_ < max_.Value()) {
1564 old_max_ = max_.Value();
1573 SimpleRevFIFO<Demon*> bound_demons_;
1574 SimpleRevFIFO<Demon*> range_demons_;
1575 SimpleRevFIFO<Demon*> domain_demons_;
1576 SimpleRevFIFO<Demon*> delayed_bound_demons_;
1577 SimpleRevFIFO<Demon*> delayed_range_demons_;
1578 SimpleRevFIFO<Demon*> delayed_domain_demons_;
1582 BaseValueWatcher* value_watcher_;
1583 BaseUpperBoundWatcher* bound_watcher_;
1602 class SimpleBitSet :
public DomainIntVar::BitSet {
1604 SimpleBitSet(Solver*
const s,
int64 vmin,
int64 vmax)
1610 size_(vmax - vmin + 1),
1612 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1613 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1614 bits_ =
new uint64[bsize_];
1615 stamps_ =
new uint64[bsize_];
1616 for (
int i = 0; i < bsize_; ++i) {
1618 (i == size_.Value() - 1) ? 63 -
BitPos64(size_.Value()) : 0;
1620 stamps_[i] = s->stamp() - 1;
1624 SimpleBitSet(Solver*
const s,
const std::vector<int64>& sorted_values,
1631 size_(sorted_values.size()),
1633 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 0xFFFFFFFF))
1634 <<
"Bitset too large: [" << vmin <<
", " << vmax <<
"]";
1635 bits_ =
new uint64[bsize_];
1636 stamps_ =
new uint64[bsize_];
1637 for (
int i = 0; i < bsize_; ++i) {
1639 stamps_[i] = s->stamp() - 1;
1641 for (
int i = 0; i < sorted_values.size(); ++i) {
1642 const int64 val = sorted_values[i];
1645 const int pos =
BitPos64(val - omin_);
1650 ~SimpleBitSet()
override {
1658 DCHECK_GE(nmin, cmin);
1659 DCHECK_LE(nmin, cmax);
1660 DCHECK_LE(cmin, cmax);
1661 DCHECK_GE(cmin, omin_);
1662 DCHECK_LE(cmax, omax_);
1663 const int64 new_min =
1666 const uint64 removed_bits =
1668 size_.Add(
solver_, -removed_bits);
1673 DCHECK_GE(nmax, cmin);
1674 DCHECK_LE(nmax, cmax);
1675 DCHECK_LE(cmin, cmax);
1676 DCHECK_GE(cmin, omin_);
1677 DCHECK_LE(cmax, omax_);
1678 const int64 new_max =
1681 const uint64 removed_bits =
1683 size_.Add(
solver_, -removed_bits);
1687 bool SetValue(
int64 val)
override {
1688 DCHECK_GE(val, omin_);
1689 DCHECK_LE(val, omax_);
1697 bool Contains(
int64 val)
const override {
1698 DCHECK_GE(val, omin_);
1699 DCHECK_LE(val, omax_);
1703 bool RemoveValue(
int64 val)
override {
1704 if (val < omin_ || val > omax_ || !bit(val)) {
1708 const int64 val_offset = val - omin_;
1711 if (stamps_[offset] < current_stamp) {
1712 stamps_[offset] = current_stamp;
1713 solver_->SaveValue(&bits_[offset]);
1715 const int pos =
BitPos64(val_offset);
1724 uint64 Size()
const override {
return size_.Value(); }
1726 std::string DebugString()
const override {
1728 absl::StrAppendFormat(&out,
"SimpleBitSet(%d..%d : ", omin_, omax_);
1729 for (
int i = 0; i < bsize_; ++i) {
1730 absl::StrAppendFormat(&out,
"%x", bits_[i]);
1736 void DelayRemoveValue(
int64 val)
override { removed_.push_back(val); }
1738 void ApplyRemovedValues(DomainIntVar*
var)
override {
1739 std::sort(removed_.begin(), removed_.end());
1740 for (std::vector<int64>::iterator it = removed_.begin();
1741 it != removed_.end(); ++it) {
1742 var->RemoveValue(*it);
1746 void ClearRemovedValues()
override { removed_.clear(); }
1763 if (v == start_cumul + 1) {
1764 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1765 }
else if (v == start_cumul + 2) {
1766 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1768 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1775 if (
max == start_cumul + 1) {
1776 absl::StrAppendFormat(&out,
"%d %d", start_cumul,
max);
1778 absl::StrAppendFormat(&out,
"%d..%d", start_cumul,
max);
1781 absl::StrAppendFormat(&out,
"%d",
max);
1784 absl::StrAppendFormat(&out,
"%d",
min);
1789 DomainIntVar::BitSetIterator* MakeIterator()
override {
1790 return new DomainIntVar::BitSetIterator(bits_, omin_);
1798 NumericalRev<int64> size_;
1800 std::vector<int64> removed_;
1806 class SmallBitSet :
public DomainIntVar::BitSet {
1808 SmallBitSet(Solver*
const s,
int64 vmin,
int64 vmax)
1814 size_(vmax - vmin + 1) {
1815 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1819 SmallBitSet(Solver*
const s,
const std::vector<int64>& sorted_values,
1826 size_(sorted_values.size()) {
1827 CHECK(ClosedIntervalNoLargerThan(vmin, vmax, 64)) << vmin <<
", " << vmax;
1829 for (
int i = 0; i < sorted_values.size(); ++i) {
1830 const int64 val = sorted_values[i];
1831 DCHECK_GE(val, vmin);
1832 DCHECK_LE(val, vmax);
1838 ~SmallBitSet()
override {}
1840 bool bit(
int64 val)
const {
1841 DCHECK_GE(val, omin_);
1842 DCHECK_LE(val, omax_);
1843 return (bits_ &
OneBit64(val - omin_)) != 0;
1847 DCHECK_GE(nmin, cmin);
1848 DCHECK_LE(nmin, cmax);
1849 DCHECK_LE(cmin, cmax);
1850 DCHECK_GE(cmin, omin_);
1851 DCHECK_LE(cmax, omax_);
1871 DCHECK_GE(nmax, cmin);
1872 DCHECK_LE(nmax, cmax);
1873 DCHECK_LE(cmin, cmax);
1874 DCHECK_GE(cmin, omin_);
1875 DCHECK_LE(cmax, omax_);
1894 bool SetValue(
int64 val)
override {
1895 DCHECK_GE(val, omin_);
1896 DCHECK_LE(val, omax_);
1906 bool Contains(
int64 val)
const override {
1907 DCHECK_GE(val, omin_);
1908 DCHECK_LE(val, omax_);
1912 bool RemoveValue(
int64 val)
override {
1913 DCHECK_GE(val, omin_);
1914 DCHECK_LE(val, omax_);
1918 if (
stamp_ < current_stamp) {
1935 uint64 Size()
const override {
return size_.Value(); }
1937 std::string DebugString()
const override {
1938 return absl::StrFormat(
"SmallBitSet(%d..%d : %llx)", omin_, omax_, bits_);
1941 void DelayRemoveValue(
int64 val)
override {
1942 DCHECK_GE(val, omin_);
1943 DCHECK_LE(val, omax_);
1944 removed_.push_back(val);
1947 void ApplyRemovedValues(DomainIntVar*
var)
override {
1948 std::sort(removed_.begin(), removed_.end());
1949 for (std::vector<int64>::iterator it = removed_.begin();
1950 it != removed_.end(); ++it) {
1951 var->RemoveValue(*it);
1955 void ClearRemovedValues()
override { removed_.clear(); }
1972 if (v == start_cumul + 1) {
1973 absl::StrAppendFormat(&out,
"%d ", start_cumul);
1974 }
else if (v == start_cumul + 2) {
1975 absl::StrAppendFormat(&out,
"%d %d ", start_cumul, v - 1);
1977 absl::StrAppendFormat(&out,
"%d..%d ", start_cumul, v - 1);
1984 if (
max == start_cumul + 1) {
1985 absl::StrAppendFormat(&out,
"%d %d", start_cumul,
max);
1987 absl::StrAppendFormat(&out,
"%d..%d", start_cumul,
max);
1990 absl::StrAppendFormat(&out,
"%d",
max);
1993 absl::StrAppendFormat(&out,
"%d",
min);
1998 DomainIntVar::BitSetIterator* MakeIterator()
override {
1999 return new DomainIntVar::BitSetIterator(&bits_, omin_);
2007 NumericalRev<int64> size_;
2008 std::vector<int64> removed_;
2011 class EmptyIterator :
public IntVarIterator {
2013 ~EmptyIterator()
override {}
2014 void Init()
override {}
2015 bool Ok()
const override {
return false; }
2017 LOG(FATAL) <<
"Should not be called";
2020 void Next()
override {}
2023 class RangeIterator :
public IntVarIterator {
2025 explicit RangeIterator(
const IntVar*
const var)
2028 ~RangeIterator()
override {}
2030 void Init()
override {
2036 bool Ok()
const override {
return current_ <= max_; }
2040 void Next()
override {
current_++; }
2043 const IntVar*
const var_;
2049 class DomainIntVarHoleIterator :
public IntVarIterator {
2051 explicit DomainIntVarHoleIterator(
const DomainIntVar*
const v)
2052 : var_(v), bits_(nullptr), values_(nullptr), size_(0), index_(0) {}
2054 ~DomainIntVarHoleIterator()
override {}
2056 void Init()
override {
2057 bits_ = var_->bitset();
2058 if (bits_ !=
nullptr) {
2060 values_ = bits_->Holes().data();
2061 size_ = bits_->Holes().size();
2069 bool Ok()
const override {
return index_ < size_; }
2072 DCHECK(bits_ !=
nullptr);
2073 DCHECK(index_ < size_);
2074 return values_[index_];
2077 void Next()
override { index_++; }
2080 const DomainIntVar*
const var_;
2081 DomainIntVar::BitSet* bits_;
2082 const int64* values_;
2087 class DomainIntVarDomainIterator :
public IntVarIterator {
2089 explicit DomainIntVarDomainIterator(
const DomainIntVar*
const v,
2092 bitset_iterator_(nullptr),
2096 reversible_(reversible) {}
2098 ~DomainIntVarDomainIterator()
override {
2099 if (!reversible_ && bitset_iterator_) {
2100 delete bitset_iterator_;
2104 void Init()
override {
2105 if (var_->bitset() !=
nullptr && !var_->Bound()) {
2107 if (!bitset_iterator_) {
2108 Solver*
const solver = var_->solver();
2109 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2110 bitset_iterator_ = solver->RevAlloc(var_->bitset()->MakeIterator());
2113 if (bitset_iterator_) {
2114 delete bitset_iterator_;
2116 bitset_iterator_ = var_->bitset()->MakeIterator();
2118 bitset_iterator_->Init(var_->Min(), var_->Max());
2120 if (bitset_iterator_) {
2122 Solver*
const solver = var_->solver();
2123 solver->SaveValue(
reinterpret_cast<void**
>(&bitset_iterator_));
2125 delete bitset_iterator_;
2127 bitset_iterator_ =
nullptr;
2135 bool Ok()
const override {
2136 return bitset_iterator_ ? bitset_iterator_->Ok() : (
current_ <= max_);
2140 return bitset_iterator_ ? bitset_iterator_->Value() :
current_;
2143 void Next()
override {
2144 if (bitset_iterator_) {
2145 bitset_iterator_->Next();
2152 const DomainIntVar*
const var_;
2153 DomainIntVar::BitSetIterator* bitset_iterator_;
2157 const bool reversible_;
2160 class UnaryIterator :
public IntVarIterator {
2162 UnaryIterator(
const IntVar*
const v,
bool hole,
bool reversible)
2163 :
iterator_(hole ? v->MakeHoleIterator(reversible)
2164 : v->MakeDomainIterator(reversible)),
2165 reversible_(reversible) {}
2167 ~UnaryIterator()
override {
2173 void Init()
override {
iterator_->Init(); }
2175 bool Ok()
const override {
return iterator_->Ok(); }
2177 void Next()
override {
iterator_->Next(); }
2181 const bool reversible_;
2184 DomainIntVar::DomainIntVar(Solver*
const s,
int64 vmin,
int64 vmax,
2185 const std::string&
name)
2196 value_watcher_(nullptr),
2197 bound_watcher_(nullptr) {}
2199 DomainIntVar::DomainIntVar(Solver*
const s,
2200 const std::vector<int64>& sorted_values,
2201 const std::string&
name)
2212 value_watcher_(nullptr),
2213 bound_watcher_(nullptr) {
2214 CHECK_GE(sorted_values.size(), 1);
2216 const int64 vmin = sorted_values.front();
2217 const int64 vmax = sorted_values.back();
2218 const bool contiguous = vmax - vmin + 1 == sorted_values.size();
2220 min_.SetValue(solver(), vmin);
2223 max_.SetValue(solver(), vmax);
2228 if (vmax - vmin + 1 < 65) {
2229 bits_ = solver()->RevAlloc(
2230 new SmallBitSet(solver(), sorted_values, vmin, vmax));
2232 bits_ = solver()->RevAlloc(
2233 new SimpleBitSet(solver(), sorted_values, vmin, vmax));
2238 DomainIntVar::~DomainIntVar() {}
2240 void DomainIntVar::SetMin(
int64 m) {
2241 if (m <= min_.Value())
return;
2242 if (m > max_.Value()) solver()->Fail();
2246 if (new_min_ > new_max_) {
2252 const int64 new_min =
2255 : bits_->ComputeNewMin(m, min_.Value(), max_.Value()));
2256 min_.SetValue(solver(), new_min);
2257 if (min_.Value() > max_.Value()) {
2264 void DomainIntVar::SetMax(
int64 m) {
2265 if (m >= max_.Value())
return;
2266 if (m < min_.Value()) solver()->Fail();
2270 if (new_max_ < new_min_) {
2276 const int64 new_max =
2279 : bits_->ComputeNewMax(m, min_.Value(), max_.Value()));
2280 max_.SetValue(solver(), new_max);
2281 if (min_.Value() > max_.Value()) {
2288 void DomainIntVar::SetRange(
int64 mi,
int64 ma) {
2292 if (mi > ma || mi > max_.Value() || ma < min_.Value()) solver()->Fail();
2293 if (mi <= min_.Value() && ma >= max_.Value())
return;
2295 if (ma < new_max_) {
2298 if (mi > new_min_) {
2301 if (new_min_ > new_max_) {
2305 if (mi > min_.Value()) {
2307 const int64 new_min =
2310 : bits_->ComputeNewMin(mi, min_.Value(), max_.Value()));
2311 min_.SetValue(solver(), new_min);
2313 if (min_.Value() > ma) {
2316 if (ma < max_.Value()) {
2318 const int64 new_max =
2321 : bits_->ComputeNewMax(ma, min_.Value(), max_.Value()));
2322 max_.SetValue(solver(), new_max);
2324 if (min_.Value() > max_.Value()) {
2332 void DomainIntVar::SetValue(
int64 v) {
2333 if (v != min_.Value() || v != max_.Value()) {
2334 if (v < min_.Value() || v > max_.Value()) {
2338 if (v > new_max_ || v < new_min_) {
2344 if (bits_ && !bits_->SetValue(v)) {
2349 min_.SetValue(solver(), v);
2350 max_.SetValue(solver(), v);
2356 void DomainIntVar::RemoveValue(
int64 v) {
2357 if (v < min_.Value() || v > max_.Value())
return;
2358 if (v == min_.Value()) {
2360 }
else if (v == max_.Value()) {
2363 if (bits_ ==
nullptr) {
2367 if (v >= new_min_ && v <= new_max_ && bits_->Contains(v)) {
2368 bits_->DelayRemoveValue(v);
2371 if (bits_->RemoveValue(v)) {
2378 void DomainIntVar::RemoveInterval(
int64 l,
int64 u) {
2379 if (l <= min_.Value()) {
2381 }
else if (u >= max_.Value()) {
2384 for (
int64 v = l; v <= u; ++v) {
2390 void DomainIntVar::CreateBits() {
2391 solver()->SaveValue(
reinterpret_cast<void**
>(&bits_));
2392 if (max_.Value() - min_.Value() < 64) {
2393 bits_ = solver()->RevAlloc(
2394 new SmallBitSet(solver(), min_.Value(), max_.Value()));
2396 bits_ = solver()->RevAlloc(
2397 new SimpleBitSet(solver(), min_.Value(), max_.Value()));
2401 void DomainIntVar::CleanInProcess() {
2403 if (bits_ !=
nullptr) {
2404 bits_->ClearHoles();
2408 void DomainIntVar::Push() {
2414 void DomainIntVar::Process() {
2417 if (bits_ !=
nullptr) {
2418 bits_->ClearRemovedValues();
2420 set_variable_to_clean_on_fail(
this);
2421 new_min_ = min_.Value();
2422 new_max_ = max_.Value();
2423 const bool is_bound = min_.Value() == max_.Value();
2424 const bool range_changed =
2425 min_.Value() != OldMin() || max_.Value() != OldMax();
2428 ExecuteAll(bound_demons_);
2430 if (range_changed) {
2431 ExecuteAll(range_demons_);
2433 ExecuteAll(domain_demons_);
2437 EnqueueAll(delayed_bound_demons_);
2439 if (range_changed) {
2440 EnqueueAll(delayed_range_demons_);
2442 EnqueueAll(delayed_domain_demons_);
2445 set_variable_to_clean_on_fail(
nullptr);
2447 old_min_ = min_.Value();
2448 old_max_ = max_.Value();
2449 if (min_.Value() < new_min_) {
2452 if (max_.Value() > new_max_) {
2455 if (bits_ !=
nullptr) {
2456 bits_->ApplyRemovedValues(
this);
2460 #define COND_REV_ALLOC(rev, alloc) rev ? solver()->RevAlloc(alloc) : alloc;
2462 IntVarIterator* DomainIntVar::MakeHoleIterator(
bool reversible)
const {
2463 return COND_REV_ALLOC(reversible,
new DomainIntVarHoleIterator(
this));
2466 IntVarIterator* DomainIntVar::MakeDomainIterator(
bool reversible)
const {
2468 new DomainIntVarDomainIterator(
this, reversible));
2471 std::string DomainIntVar::DebugString()
const {
2473 const std::string& var_name =
name();
2474 if (!var_name.empty()) {
2475 out = var_name +
"(";
2477 out =
"DomainIntVar(";
2479 if (min_.Value() == max_.Value()) {
2480 absl::StrAppendFormat(&out,
"%d", min_.Value());
2481 }
else if (bits_ !=
nullptr) {
2482 out.append(bits_->pretty_DebugString(min_.Value(), max_.Value()));
2484 absl::StrAppendFormat(&out,
"%d..%d", min_.Value(), max_.Value());
2492 class ConcreteBooleanVar :
public BooleanVar {
2495 class Handler :
public Demon {
2497 explicit Handler(ConcreteBooleanVar*
const var) : Demon(), var_(
var) {}
2498 ~Handler()
override {}
2499 void Run(Solver*
const s)
override {
2500 s->GetPropagationMonitor()->StartProcessingIntegerVariable(var_);
2502 s->GetPropagationMonitor()->EndProcessingIntegerVariable(var_);
2504 Solver::DemonPriority priority()
const override {
2505 return Solver::VAR_PRIORITY;
2507 std::string DebugString()
const override {
2508 return absl::StrFormat(
"Handler(%s)", var_->DebugString());
2512 ConcreteBooleanVar*
const var_;
2515 ConcreteBooleanVar(Solver*
const s,
const std::string&
name)
2518 ~ConcreteBooleanVar()
override {}
2520 void SetValue(
int64 v)
override {
2521 if (value_ == kUnboundBooleanVarValue) {
2522 if ((v & 0xfffffffffffffffe) == 0) {
2524 value_ =
static_cast<int>(v);
2528 }
else if (v == value_) {
2535 DCHECK_NE(value_, kUnboundBooleanVarValue);
2536 ExecuteAll(bound_demons_);
2537 for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_); it.ok();
2539 EnqueueDelayedDemon(*it);
2543 int64 OldMin()
const override {
return 0LL; }
2544 int64 OldMax()
const override {
return 1LL; }
2545 void RestoreValue()
override { value_ = kUnboundBooleanVarValue; }
2553 class IntConst :
public IntVar {
2555 IntConst(Solver*
const s,
int64 value,
const std::string&
name =
"")
2557 ~IntConst()
override {}
2559 int64 Min()
const override {
return value_; }
2560 void SetMin(
int64 m)
override {
2565 int64 Max()
const override {
return value_; }
2566 void SetMax(
int64 m)
override {
2572 if (l > value_ || u < value_) {
2576 void SetValue(
int64 v)
override {
2581 bool Bound()
const override {
return true; }
2582 int64 Value()
const override {
return value_; }
2583 void RemoveValue(
int64 v)
override {
2588 void RemoveInterval(
int64 l,
int64 u)
override {
2589 if (l <= value_ && value_ <= u) {
2593 void WhenBound(Demon* d)
override {}
2594 void WhenRange(Demon* d)
override {}
2595 void WhenDomain(Demon* d)
override {}
2596 uint64 Size()
const override {
return 1; }
2597 bool Contains(
int64 v)
const override {
return (v == value_); }
2598 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2601 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2604 int64 OldMin()
const override {
return value_; }
2605 int64 OldMax()
const override {
return value_; }
2606 std::string DebugString()
const override {
2608 if (solver()->HasName(
this)) {
2609 const std::string& var_name =
name();
2610 absl::StrAppendFormat(&out,
"%s(%d)", var_name, value_);
2612 absl::StrAppendFormat(&out,
"IntConst(%d)", value_);
2617 int VarType()
const override {
return CONST_VAR; }
2619 IntVar* IsEqual(
int64 constant)
override {
2620 if (constant == value_) {
2621 return solver()->MakeIntConst(1);
2623 return solver()->MakeIntConst(0);
2627 IntVar* IsDifferent(
int64 constant)
override {
2628 if (constant == value_) {
2629 return solver()->MakeIntConst(0);
2631 return solver()->MakeIntConst(1);
2635 IntVar* IsGreaterOrEqual(
int64 constant)
override {
2636 return solver()->MakeIntConst(value_ >= constant);
2639 IntVar* IsLessOrEqual(
int64 constant)
override {
2640 return solver()->MakeIntConst(value_ <= constant);
2643 std::string
name()
const override {
2644 if (solver()->HasName(
this)) {
2647 return absl::StrCat(value_);
2657 class PlusCstVar :
public IntVar {
2659 PlusCstVar(Solver*
const s, IntVar* v,
int64 c)
2660 : IntVar(s), var_(v),
cst_(c) {}
2662 ~PlusCstVar()
override {}
2664 void WhenRange(Demon* d)
override { var_->WhenRange(d); }
2666 void WhenBound(Demon* d)
override { var_->WhenBound(d); }
2668 void WhenDomain(Demon* d)
override { var_->WhenDomain(d); }
2670 int64 OldMin()
const override {
return CapAdd(var_->OldMin(),
cst_); }
2672 int64 OldMax()
const override {
return CapAdd(var_->OldMax(),
cst_); }
2674 std::string DebugString()
const override {
2676 return absl::StrFormat(
"%s(%s + %d)",
name(), var_->DebugString(),
cst_);
2678 return absl::StrFormat(
"(%s + %d)", var_->DebugString(),
cst_);
2682 int VarType()
const override {
return VAR_ADD_CST; }
2684 void Accept(ModelVisitor*
const visitor)
const override {
2685 visitor->VisitIntegerVariable(
this, ModelVisitor::kSumOperation,
cst_,
2689 IntVar* IsEqual(
int64 constant)
override {
2690 return var_->IsEqual(constant -
cst_);
2693 IntVar* IsDifferent(
int64 constant)
override {
2694 return var_->IsDifferent(constant -
cst_);
2697 IntVar* IsGreaterOrEqual(
int64 constant)
override {
2698 return var_->IsGreaterOrEqual(constant -
cst_);
2701 IntVar* IsLessOrEqual(
int64 constant)
override {
2702 return var_->IsLessOrEqual(constant -
cst_);
2705 IntVar* SubVar()
const {
return var_; }
2714 class PlusCstIntVar :
public PlusCstVar {
2716 class PlusCstIntVarIterator :
public UnaryIterator {
2718 PlusCstIntVarIterator(
const IntVar*
const v,
int64 c,
bool hole,
bool rev)
2719 : UnaryIterator(v, hole, rev),
cst_(c) {}
2721 ~PlusCstIntVarIterator()
override {}
2729 PlusCstIntVar(Solver*
const s, IntVar* v,
int64 c) : PlusCstVar(s, v, c) {}
2731 ~PlusCstIntVar()
override {}
2733 int64 Min()
const override {
return var_->Min() +
cst_; }
2737 int64 Max()
const override {
return var_->Max() +
cst_; }
2745 void SetValue(
int64 v)
override { var_->SetValue(v -
cst_); }
2749 bool Bound()
const override {
return var_->Bound(); }
2751 void RemoveValue(
int64 v)
override { var_->RemoveValue(v -
cst_); }
2753 void RemoveInterval(
int64 l,
int64 u)
override {
2754 var_->RemoveInterval(l -
cst_, u -
cst_);
2757 uint64 Size()
const override {
return var_->Size(); }
2759 bool Contains(
int64 v)
const override {
return var_->Contains(v -
cst_); }
2761 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2763 reversible,
new PlusCstIntVarIterator(var_,
cst_,
true, reversible));
2765 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2767 reversible,
new PlusCstIntVarIterator(var_,
cst_,
false, reversible));
2771 class PlusCstDomainIntVar :
public PlusCstVar {
2773 class PlusCstDomainIntVarIterator :
public UnaryIterator {
2775 PlusCstDomainIntVarIterator(
const IntVar*
const v,
int64 c,
bool hole,
2777 : UnaryIterator(v, hole, reversible),
cst_(c) {}
2779 ~PlusCstDomainIntVarIterator()
override {}
2787 PlusCstDomainIntVar(Solver*
const s, DomainIntVar* v,
int64 c)
2788 : PlusCstVar(s, v, c) {}
2790 ~PlusCstDomainIntVar()
override {}
2792 int64 Min()
const override;
2793 void SetMin(
int64 m)
override;
2794 int64 Max()
const override;
2795 void SetMax(
int64 m)
override;
2797 void SetValue(
int64 v)
override;
2798 bool Bound()
const override;
2800 void RemoveValue(
int64 v)
override;
2801 void RemoveInterval(
int64 l,
int64 u)
override;
2802 uint64 Size()
const override;
2803 bool Contains(
int64 v)
const override;
2805 DomainIntVar* domain_int_var()
const {
2806 return reinterpret_cast<DomainIntVar*
>(var_);
2809 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2810 return COND_REV_ALLOC(reversible,
new PlusCstDomainIntVarIterator(
2811 var_,
cst_,
true, reversible));
2813 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2814 return COND_REV_ALLOC(reversible,
new PlusCstDomainIntVarIterator(
2815 var_,
cst_,
false, reversible));
2819 int64 PlusCstDomainIntVar::Min()
const {
2820 return domain_int_var()->min_.Value() +
cst_;
2823 void PlusCstDomainIntVar::SetMin(
int64 m) {
2824 domain_int_var()->DomainIntVar::SetMin(m -
cst_);
2827 int64 PlusCstDomainIntVar::Max()
const {
2828 return domain_int_var()->max_.Value() +
cst_;
2831 void PlusCstDomainIntVar::SetMax(
int64 m) {
2832 domain_int_var()->DomainIntVar::SetMax(m -
cst_);
2835 void PlusCstDomainIntVar::SetRange(
int64 l,
int64 u) {
2836 domain_int_var()->DomainIntVar::SetRange(l -
cst_, u -
cst_);
2839 void PlusCstDomainIntVar::SetValue(
int64 v) {
2840 domain_int_var()->DomainIntVar::SetValue(v -
cst_);
2843 bool PlusCstDomainIntVar::Bound()
const {
2844 return domain_int_var()->min_.Value() == domain_int_var()->max_.Value();
2848 CHECK_EQ(domain_int_var()->min_.Value(), domain_int_var()->max_.Value())
2849 <<
" variable is not bound";
2850 return domain_int_var()->min_.Value() +
cst_;
2853 void PlusCstDomainIntVar::RemoveValue(
int64 v) {
2854 domain_int_var()->DomainIntVar::RemoveValue(v -
cst_);
2857 void PlusCstDomainIntVar::RemoveInterval(
int64 l,
int64 u) {
2858 domain_int_var()->DomainIntVar::RemoveInterval(l -
cst_, u -
cst_);
2861 uint64 PlusCstDomainIntVar::Size()
const {
2862 return domain_int_var()->DomainIntVar::Size();
2865 bool PlusCstDomainIntVar::Contains(
int64 v)
const {
2866 return domain_int_var()->DomainIntVar::Contains(v -
cst_);
2871 class SubCstIntVar :
public IntVar {
2873 class SubCstIntVarIterator :
public UnaryIterator {
2875 SubCstIntVarIterator(
const IntVar*
const v,
int64 c,
bool hole,
bool rev)
2876 : UnaryIterator(v, hole, rev),
cst_(c) {}
2877 ~SubCstIntVarIterator()
override {}
2885 SubCstIntVar(Solver*
const s, IntVar* v,
int64 c);
2886 ~SubCstIntVar()
override;
2888 int64 Min()
const override;
2889 void SetMin(
int64 m)
override;
2890 int64 Max()
const override;
2891 void SetMax(
int64 m)
override;
2893 void SetValue(
int64 v)
override;
2894 bool Bound()
const override;
2896 void RemoveValue(
int64 v)
override;
2897 void RemoveInterval(
int64 l,
int64 u)
override;
2898 uint64 Size()
const override;
2899 bool Contains(
int64 v)
const override;
2900 void WhenRange(Demon* d)
override;
2901 void WhenBound(Demon* d)
override;
2902 void WhenDomain(Demon* d)
override;
2903 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
2905 reversible,
new SubCstIntVarIterator(var_,
cst_,
true, reversible));
2907 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
2909 reversible,
new SubCstIntVarIterator(var_,
cst_,
false, reversible));
2911 int64 OldMin()
const override {
return CapSub(
cst_, var_->OldMax()); }
2912 int64 OldMax()
const override {
return CapSub(
cst_, var_->OldMin()); }
2913 std::string DebugString()
const override;
2914 std::string
name()
const override;
2915 int VarType()
const override {
return CST_SUB_VAR; }
2917 void Accept(ModelVisitor*
const visitor)
const override {
2918 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation,
2922 IntVar* IsEqual(
int64 constant)
override {
2923 return var_->IsEqual(
cst_ - constant);
2926 IntVar* IsDifferent(
int64 constant)
override {
2927 return var_->IsDifferent(
cst_ - constant);
2930 IntVar* IsGreaterOrEqual(
int64 constant)
override {
2931 return var_->IsLessOrEqual(
cst_ - constant);
2934 IntVar* IsLessOrEqual(
int64 constant)
override {
2935 return var_->IsGreaterOrEqual(
cst_ - constant);
2938 IntVar* SubVar()
const {
return var_; }
2946 SubCstIntVar::SubCstIntVar(Solver*
const s, IntVar* v,
int64 c)
2947 : IntVar(s), var_(v),
cst_(c) {}
2949 SubCstIntVar::~SubCstIntVar() {}
2951 int64 SubCstIntVar::Min()
const {
return cst_ - var_->Max(); }
2955 int64 SubCstIntVar::Max()
const {
return cst_ - var_->Min(); }
2959 void SubCstIntVar::SetRange(
int64 l,
int64 u) {
2963 void SubCstIntVar::SetValue(
int64 v) { var_->SetValue(
cst_ - v); }
2965 bool SubCstIntVar::Bound()
const {
return var_->Bound(); }
2967 void SubCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
2971 void SubCstIntVar::RemoveValue(
int64 v) { var_->RemoveValue(
cst_ - v); }
2973 void SubCstIntVar::RemoveInterval(
int64 l,
int64 u) {
2974 var_->RemoveInterval(
cst_ - u,
cst_ - l);
2977 void SubCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
2979 void SubCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
2981 uint64 SubCstIntVar::Size()
const {
return var_->Size(); }
2983 bool SubCstIntVar::Contains(
int64 v)
const {
return var_->Contains(
cst_ - v); }
2985 std::string SubCstIntVar::DebugString()
const {
2987 return absl::StrFormat(
"Not(%s)", var_->DebugString());
2989 return absl::StrFormat(
"(%d - %s)",
cst_, var_->DebugString());
2994 if (solver()->HasName(
this)) {
2997 return absl::StrFormat(
"Not(%s)", var_->name());
2999 return absl::StrFormat(
"(%d - %s)",
cst_, var_->name());
3005 class OppIntVar :
public IntVar {
3007 class OppIntVarIterator :
public UnaryIterator {
3009 OppIntVarIterator(
const IntVar*
const v,
bool hole,
bool reversible)
3010 : UnaryIterator(v, hole, reversible) {}
3011 ~OppIntVarIterator()
override {}
3016 OppIntVar(Solver*
const s, IntVar* v);
3017 ~OppIntVar()
override;
3019 int64 Min()
const override;
3020 void SetMin(
int64 m)
override;
3021 int64 Max()
const override;
3022 void SetMax(
int64 m)
override;
3024 void SetValue(
int64 v)
override;
3025 bool Bound()
const override;
3027 void RemoveValue(
int64 v)
override;
3028 void RemoveInterval(
int64 l,
int64 u)
override;
3029 uint64 Size()
const override;
3030 bool Contains(
int64 v)
const override;
3031 void WhenRange(Demon* d)
override;
3032 void WhenBound(Demon* d)
override;
3033 void WhenDomain(Demon* d)
override;
3034 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3036 new OppIntVarIterator(var_,
true, reversible));
3038 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3040 new OppIntVarIterator(var_,
false, reversible));
3042 int64 OldMin()
const override {
return CapOpp(var_->OldMax()); }
3043 int64 OldMax()
const override {
return CapOpp(var_->OldMin()); }
3044 std::string DebugString()
const override;
3045 int VarType()
const override {
return OPP_VAR; }
3047 void Accept(ModelVisitor*
const visitor)
const override {
3048 visitor->VisitIntegerVariable(
this, ModelVisitor::kDifferenceOperation, 0,
3052 IntVar* IsEqual(
int64 constant)
override {
return var_->IsEqual(-constant); }
3054 IntVar* IsDifferent(
int64 constant)
override {
3055 return var_->IsDifferent(-constant);
3058 IntVar* IsGreaterOrEqual(
int64 constant)
override {
3059 return var_->IsLessOrEqual(-constant);
3062 IntVar* IsLessOrEqual(
int64 constant)
override {
3063 return var_->IsGreaterOrEqual(-constant);
3066 IntVar* SubVar()
const {
return var_; }
3072 OppIntVar::OppIntVar(Solver*
const s, IntVar* v) : IntVar(s), var_(v) {}
3074 OppIntVar::~OppIntVar() {}
3076 int64 OppIntVar::Min()
const {
return -var_->Max(); }
3078 void OppIntVar::SetMin(
int64 m) { var_->SetMax(
CapOpp(m)); }
3080 int64 OppIntVar::Max()
const {
return -var_->Min(); }
3082 void OppIntVar::SetMax(
int64 m) { var_->SetMin(
CapOpp(m)); }
3088 void OppIntVar::SetValue(
int64 v) { var_->SetValue(
CapOpp(v)); }
3090 bool OppIntVar::Bound()
const {
return var_->Bound(); }
3092 void OppIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3096 void OppIntVar::RemoveValue(
int64 v) { var_->RemoveValue(-v); }
3098 void OppIntVar::RemoveInterval(
int64 l,
int64 u) {
3099 var_->RemoveInterval(-u, -l);
3102 void OppIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3104 void OppIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3106 uint64 OppIntVar::Size()
const {
return var_->Size(); }
3108 bool OppIntVar::Contains(
int64 v)
const {
return var_->Contains(-v); }
3110 std::string OppIntVar::DebugString()
const {
3111 return absl::StrFormat(
"-(%s)", var_->DebugString());
3118 class TimesCstIntVar :
public IntVar {
3120 TimesCstIntVar(Solver*
const s, IntVar* v,
int64 c)
3121 : IntVar(s), var_(v),
cst_(c) {}
3122 ~TimesCstIntVar()
override {}
3124 IntVar* SubVar()
const {
return var_; }
3127 void Accept(ModelVisitor*
const visitor)
const override {
3128 visitor->VisitIntegerVariable(
this, ModelVisitor::kProductOperation,
cst_,
3132 IntVar* IsEqual(
int64 constant)
override {
3133 if (constant %
cst_ == 0) {
3134 return var_->IsEqual(constant /
cst_);
3136 return solver()->MakeIntConst(0);
3140 IntVar* IsDifferent(
int64 constant)
override {
3141 if (constant %
cst_ == 0) {
3142 return var_->IsDifferent(constant /
cst_);
3144 return solver()->MakeIntConst(1);
3148 IntVar* IsGreaterOrEqual(
int64 constant)
override {
3156 IntVar* IsLessOrEqual(
int64 constant)
override {
3164 std::string DebugString()
const override {
3165 return absl::StrFormat(
"(%s * %d)", var_->DebugString(),
cst_);
3175 class TimesPosCstIntVar :
public TimesCstIntVar {
3177 class TimesPosCstIntVarIterator :
public UnaryIterator {
3179 TimesPosCstIntVarIterator(
const IntVar*
const v,
int64 c,
bool hole,
3181 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3182 ~TimesPosCstIntVarIterator()
override {}
3190 TimesPosCstIntVar(Solver*
const s, IntVar* v,
int64 c);
3191 ~TimesPosCstIntVar()
override;
3193 int64 Min()
const override;
3194 void SetMin(
int64 m)
override;
3195 int64 Max()
const override;
3196 void SetMax(
int64 m)
override;
3198 void SetValue(
int64 v)
override;
3199 bool Bound()
const override;
3201 void RemoveValue(
int64 v)
override;
3202 void RemoveInterval(
int64 l,
int64 u)
override;
3203 uint64 Size()
const override;
3204 bool Contains(
int64 v)
const override;
3205 void WhenRange(Demon* d)
override;
3206 void WhenBound(Demon* d)
override;
3207 void WhenDomain(Demon* d)
override;
3208 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3210 var_,
cst_,
true, reversible));
3212 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3214 var_,
cst_,
false, reversible));
3222 TimesPosCstIntVar::TimesPosCstIntVar(Solver*
const s, IntVar* v,
int64 c)
3223 : TimesCstIntVar(s, v, c) {}
3225 TimesPosCstIntVar::~TimesPosCstIntVar() {}
3227 int64 TimesPosCstIntVar::Min()
const {
return CapProd(var_->Min(),
cst_); }
3229 void TimesPosCstIntVar::SetMin(
int64 m) {
3235 int64 TimesPosCstIntVar::Max()
const {
return CapProd(var_->Max(),
cst_); }
3237 void TimesPosCstIntVar::SetMax(
int64 m) {
3243 void TimesPosCstIntVar::SetRange(
int64 l,
int64 u) {
3247 void TimesPosCstIntVar::SetValue(
int64 v) {
3248 if (v %
cst_ != 0) {
3251 var_->SetValue(v /
cst_);
3254 bool TimesPosCstIntVar::Bound()
const {
return var_->Bound(); }
3256 void TimesPosCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3260 void TimesPosCstIntVar::RemoveValue(
int64 v) {
3261 if (v %
cst_ == 0) {
3262 var_->RemoveValue(v /
cst_);
3266 void TimesPosCstIntVar::RemoveInterval(
int64 l,
int64 u) {
3267 for (
int64 v = l; v <= u; ++v) {
3273 void TimesPosCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3275 void TimesPosCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3277 uint64 TimesPosCstIntVar::Size()
const {
return var_->Size(); }
3279 bool TimesPosCstIntVar::Contains(
int64 v)
const {
3280 return (v %
cst_ == 0 && var_->Contains(v /
cst_));
3285 class TimesPosCstBoolVar :
public TimesCstIntVar {
3287 class TimesPosCstBoolVarIterator :
public UnaryIterator {
3290 TimesPosCstBoolVarIterator(
const IntVar*
const v,
int64 c,
bool hole,
3292 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3293 ~TimesPosCstBoolVarIterator()
override {}
3301 TimesPosCstBoolVar(Solver*
const s, BooleanVar* v,
int64 c);
3302 ~TimesPosCstBoolVar()
override;
3304 int64 Min()
const override;
3305 void SetMin(
int64 m)
override;
3306 int64 Max()
const override;
3307 void SetMax(
int64 m)
override;
3309 void SetValue(
int64 v)
override;
3310 bool Bound()
const override;
3312 void RemoveValue(
int64 v)
override;
3313 void RemoveInterval(
int64 l,
int64 u)
override;
3314 uint64 Size()
const override;
3315 bool Contains(
int64 v)
const override;
3316 void WhenRange(Demon* d)
override;
3317 void WhenBound(Demon* d)
override;
3318 void WhenDomain(Demon* d)
override;
3319 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3322 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3325 new TimesPosCstBoolVarIterator(boolean_var(),
cst_,
false, reversible));
3327 int64 OldMin()
const override {
return 0; }
3328 int64 OldMax()
const override {
return cst_; }
3330 BooleanVar* boolean_var()
const {
3331 return reinterpret_cast<BooleanVar*
>(var_);
3337 TimesPosCstBoolVar::TimesPosCstBoolVar(Solver*
const s, BooleanVar* v,
int64 c)
3338 : TimesCstIntVar(s, v, c) {}
3340 TimesPosCstBoolVar::~TimesPosCstBoolVar() {}
3342 int64 TimesPosCstBoolVar::Min()
const {
3343 return (boolean_var()->RawValue() == 1) *
cst_;
3346 void TimesPosCstBoolVar::SetMin(
int64 m) {
3350 boolean_var()->SetMin(1);
3354 int64 TimesPosCstBoolVar::Max()
const {
3355 return (boolean_var()->RawValue() != 0) *
cst_;
3358 void TimesPosCstBoolVar::SetMax(
int64 m) {
3361 }
else if (m <
cst_) {
3362 boolean_var()->SetMax(0);
3366 void TimesPosCstBoolVar::SetRange(
int64 l,
int64 u) {
3367 if (u < 0 || l >
cst_ || l > u) {
3371 boolean_var()->SetMin(1);
3372 }
else if (u <
cst_) {
3373 boolean_var()->SetMax(0);
3377 void TimesPosCstBoolVar::SetValue(
int64 v) {
3379 boolean_var()->SetValue(0);
3380 }
else if (v ==
cst_) {
3381 boolean_var()->SetValue(1);
3387 bool TimesPosCstBoolVar::Bound()
const {
3388 return boolean_var()->RawValue() != BooleanVar::kUnboundBooleanVarValue;
3391 void TimesPosCstBoolVar::WhenRange(Demon* d) { boolean_var()->WhenRange(d); }
3394 CHECK_NE(boolean_var()->RawValue(), BooleanVar::kUnboundBooleanVarValue)
3395 <<
" variable is not bound";
3396 return boolean_var()->RawValue() *
cst_;
3399 void TimesPosCstBoolVar::RemoveValue(
int64 v) {
3401 boolean_var()->RemoveValue(0);
3402 }
else if (v ==
cst_) {
3403 boolean_var()->RemoveValue(1);
3407 void TimesPosCstBoolVar::RemoveInterval(
int64 l,
int64 u) {
3408 if (l <= 0 && u >= 0) {
3409 boolean_var()->RemoveValue(0);
3411 if (l <= cst_ && u >=
cst_) {
3412 boolean_var()->RemoveValue(1);
3416 void TimesPosCstBoolVar::WhenBound(Demon* d) { boolean_var()->WhenBound(d); }
3418 void TimesPosCstBoolVar::WhenDomain(Demon* d) { boolean_var()->WhenDomain(d); }
3420 uint64 TimesPosCstBoolVar::Size()
const {
3422 (boolean_var()->RawValue() == BooleanVar::kUnboundBooleanVarValue));
3425 bool TimesPosCstBoolVar::Contains(
int64 v)
const {
3427 return boolean_var()->RawValue() != 1;
3428 }
else if (v ==
cst_) {
3429 return boolean_var()->RawValue() != 0;
3436 class TimesNegCstIntVar :
public TimesCstIntVar {
3438 class TimesNegCstIntVarIterator :
public UnaryIterator {
3440 TimesNegCstIntVarIterator(
const IntVar*
const v,
int64 c,
bool hole,
3442 : UnaryIterator(v, hole, reversible),
cst_(c) {}
3443 ~TimesNegCstIntVarIterator()
override {}
3451 TimesNegCstIntVar(Solver*
const s, IntVar* v,
int64 c);
3452 ~TimesNegCstIntVar()
override;
3454 int64 Min()
const override;
3455 void SetMin(
int64 m)
override;
3456 int64 Max()
const override;
3457 void SetMax(
int64 m)
override;
3459 void SetValue(
int64 v)
override;
3460 bool Bound()
const override;
3462 void RemoveValue(
int64 v)
override;
3463 void RemoveInterval(
int64 l,
int64 u)
override;
3464 uint64 Size()
const override;
3465 bool Contains(
int64 v)
const override;
3466 void WhenRange(Demon* d)
override;
3467 void WhenBound(Demon* d)
override;
3468 void WhenDomain(Demon* d)
override;
3469 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
3471 var_,
cst_,
true, reversible));
3473 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
3475 var_,
cst_,
false, reversible));
3483 TimesNegCstIntVar::TimesNegCstIntVar(Solver*
const s, IntVar* v,
int64 c)
3484 : TimesCstIntVar(s, v, c) {}
3486 TimesNegCstIntVar::~TimesNegCstIntVar() {}
3488 int64 TimesNegCstIntVar::Min()
const {
return CapProd(var_->Max(),
cst_); }
3490 void TimesNegCstIntVar::SetMin(
int64 m) {
3496 int64 TimesNegCstIntVar::Max()
const {
return CapProd(var_->Min(),
cst_); }
3498 void TimesNegCstIntVar::SetMax(
int64 m) {
3504 void TimesNegCstIntVar::SetRange(
int64 l,
int64 u) {
3508 void TimesNegCstIntVar::SetValue(
int64 v) {
3509 if (v %
cst_ != 0) {
3512 var_->SetValue(v /
cst_);
3515 bool TimesNegCstIntVar::Bound()
const {
return var_->Bound(); }
3517 void TimesNegCstIntVar::WhenRange(Demon* d) { var_->WhenRange(d); }
3521 void TimesNegCstIntVar::RemoveValue(
int64 v) {
3522 if (v %
cst_ == 0) {
3523 var_->RemoveValue(v /
cst_);
3527 void TimesNegCstIntVar::RemoveInterval(
int64 l,
int64 u) {
3528 for (
int64 v = l; v <= u; ++v) {
3534 void TimesNegCstIntVar::WhenBound(Demon* d) { var_->WhenBound(d); }
3536 void TimesNegCstIntVar::WhenDomain(Demon* d) { var_->WhenDomain(d); }
3538 uint64 TimesNegCstIntVar::Size()
const {
return var_->Size(); }
3540 bool TimesNegCstIntVar::Contains(
int64 v)
const {
3541 return (v %
cst_ == 0 && var_->Contains(v /
cst_));
3548 class PlusIntExpr :
public BaseIntExpr {
3550 PlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3551 : BaseIntExpr(s), left_(l), right_(r) {}
3553 ~PlusIntExpr()
override {}
3555 int64 Min()
const override {
return left_->Min() + right_->Min(); }
3557 void SetMin(
int64 m)
override {
3558 if (m > left_->Min() + right_->Min()) {
3559 left_->SetMin(m - right_->Max());
3560 right_->SetMin(m - left_->Max());
3565 const int64 left_min = left_->Min();
3566 const int64 right_min = right_->Min();
3567 const int64 left_max = left_->Max();
3568 const int64 right_max = right_->Max();
3569 if (l > left_min + right_min) {
3570 left_->SetMin(l - right_max);
3571 right_->SetMin(l - left_max);
3573 if (u < left_max + right_max) {
3574 left_->SetMax(u - right_min);
3575 right_->SetMax(u - left_min);
3579 int64 Max()
const override {
return left_->Max() + right_->Max(); }
3581 void SetMax(
int64 m)
override {
3582 if (m < left_->Max() + right_->Max()) {
3583 left_->SetMax(m - right_->Min());
3584 right_->SetMax(m - left_->Min());
3588 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3590 void Range(
int64*
const mi,
int64*
const ma)
override {
3591 *mi = left_->Min() + right_->Min();
3592 *ma = left_->Max() + right_->Max();
3595 std::string
name()
const override {
3596 return absl::StrFormat(
"(%s + %s)", left_->name(), right_->name());
3599 std::string DebugString()
const override {
3600 return absl::StrFormat(
"(%s + %s)", left_->DebugString(),
3601 right_->DebugString());
3604 void WhenRange(Demon* d)
override {
3605 left_->WhenRange(d);
3606 right_->WhenRange(d);
3609 void ExpandPlusIntExpr(IntExpr*
const expr, std::vector<IntExpr*>* subs) {
3610 PlusIntExpr*
const casted =
dynamic_cast<PlusIntExpr*
>(expr);
3611 if (casted !=
nullptr) {
3612 ExpandPlusIntExpr(casted->left_, subs);
3613 ExpandPlusIntExpr(casted->right_, subs);
3615 subs->push_back(expr);
3619 IntVar* CastToVar()
override {
3620 if (
dynamic_cast<PlusIntExpr*
>(left_) !=
nullptr ||
3621 dynamic_cast<PlusIntExpr*
>(right_) !=
nullptr) {
3622 std::vector<IntExpr*> sub_exprs;
3623 ExpandPlusIntExpr(left_, &sub_exprs);
3624 ExpandPlusIntExpr(right_, &sub_exprs);
3625 if (sub_exprs.size() >= 3) {
3626 std::vector<IntVar*> sub_vars(sub_exprs.size());
3627 for (
int i = 0; i < sub_exprs.size(); ++i) {
3628 sub_vars[i] = sub_exprs[i]->Var();
3630 return solver()->MakeSum(sub_vars)->Var();
3633 return BaseIntExpr::CastToVar();
3636 void Accept(ModelVisitor*
const visitor)
const override {
3637 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3638 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3639 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3641 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3645 IntExpr*
const left_;
3646 IntExpr*
const right_;
3649 class SafePlusIntExpr :
public BaseIntExpr {
3651 SafePlusIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3652 : BaseIntExpr(s), left_(l), right_(r) {}
3654 ~SafePlusIntExpr()
override {}
3656 int64 Min()
const override {
return CapAdd(left_->Min(), right_->Min()); }
3658 void SetMin(
int64 m)
override {
3659 left_->SetMin(
CapSub(m, right_->Max()));
3660 right_->SetMin(
CapSub(m, left_->Max()));
3664 const int64 left_min = left_->Min();
3665 const int64 right_min = right_->Min();
3666 const int64 left_max = left_->Max();
3667 const int64 right_max = right_->Max();
3668 if (l >
CapAdd(left_min, right_min)) {
3669 left_->SetMin(
CapSub(l, right_max));
3670 right_->SetMin(
CapSub(l, left_max));
3672 if (u <
CapAdd(left_max, right_max)) {
3673 left_->SetMax(
CapSub(u, right_min));
3674 right_->SetMax(
CapSub(u, left_min));
3678 int64 Max()
const override {
return CapAdd(left_->Max(), right_->Max()); }
3680 void SetMax(
int64 m)
override {
3681 left_->SetMax(
CapSub(m, right_->Min()));
3682 right_->SetMax(
CapSub(m, left_->Min()));
3685 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3687 std::string
name()
const override {
3688 return absl::StrFormat(
"(%s + %s)", left_->name(), right_->name());
3691 std::string DebugString()
const override {
3692 return absl::StrFormat(
"(%s + %s)", left_->DebugString(),
3693 right_->DebugString());
3696 void WhenRange(Demon* d)
override {
3697 left_->WhenRange(d);
3698 right_->WhenRange(d);
3701 void Accept(ModelVisitor*
const visitor)
const override {
3702 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3703 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3704 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3706 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3710 IntExpr*
const left_;
3711 IntExpr*
const right_;
3716 class PlusIntCstExpr :
public BaseIntExpr {
3718 PlusIntCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
3719 : BaseIntExpr(s),
expr_(e), value_(v) {}
3720 ~PlusIntCstExpr()
override {}
3725 bool Bound()
const override {
return (
expr_->Bound()); }
3726 std::string
name()
const override {
3727 return absl::StrFormat(
"(%s + %d)",
expr_->name(), value_);
3729 std::string DebugString()
const override {
3730 return absl::StrFormat(
"(%s + %d)",
expr_->DebugString(), value_);
3732 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3733 IntVar* CastToVar()
override;
3734 void Accept(ModelVisitor*
const visitor)
const override {
3735 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum,
this);
3736 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3738 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3739 visitor->EndVisitIntegerExpression(ModelVisitor::kSum,
this);
3743 IntExpr*
const expr_;
3747 IntVar* PlusIntCstExpr::CastToVar() {
3748 Solver*
const s = solver();
3750 IntVar* cast =
nullptr;
3753 return BaseIntExpr::CastToVar();
3755 switch (
var->VarType()) {
3757 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstDomainIntVar(
3758 s,
reinterpret_cast<DomainIntVar*
>(
var), value_)));
3762 cast = s->RegisterIntVar(s->RevAlloc(
new PlusCstIntVar(s,
var, value_)));
3770 class SubIntExpr :
public BaseIntExpr {
3772 SubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3773 : BaseIntExpr(s), left_(l), right_(r) {}
3775 ~SubIntExpr()
override {}
3777 int64 Min()
const override {
return left_->Min() - right_->Max(); }
3779 void SetMin(
int64 m)
override {
3780 left_->SetMin(
CapAdd(m, right_->Min()));
3781 right_->SetMax(
CapSub(left_->Max(), m));
3784 int64 Max()
const override {
return left_->Max() - right_->Min(); }
3786 void SetMax(
int64 m)
override {
3787 left_->SetMax(
CapAdd(m, right_->Max()));
3788 right_->SetMin(
CapSub(left_->Min(), m));
3792 *mi = left_->Min() - right_->Max();
3793 *ma = left_->Max() - right_->Min();
3797 const int64 left_min = left_->Min();
3798 const int64 right_min = right_->Min();
3799 const int64 left_max = left_->Max();
3800 const int64 right_max = right_->Max();
3801 if (l > left_min - right_max) {
3802 left_->SetMin(
CapAdd(l, right_min));
3803 right_->SetMax(
CapSub(left_max, l));
3805 if (u < left_max - right_min) {
3806 left_->SetMax(
CapAdd(u, right_max));
3807 right_->SetMin(
CapSub(left_min, u));
3811 bool Bound()
const override {
return (left_->Bound() && right_->Bound()); }
3813 std::string
name()
const override {
3814 return absl::StrFormat(
"(%s - %s)", left_->name(), right_->name());
3817 std::string DebugString()
const override {
3818 return absl::StrFormat(
"(%s - %s)", left_->DebugString(),
3819 right_->DebugString());
3822 void WhenRange(Demon* d)
override {
3823 left_->WhenRange(d);
3824 right_->WhenRange(d);
3827 void Accept(ModelVisitor*
const visitor)
const override {
3828 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3829 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
3830 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
3832 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3835 IntExpr* left()
const {
return left_; }
3836 IntExpr* right()
const {
return right_; }
3839 IntExpr*
const left_;
3840 IntExpr*
const right_;
3843 class SafeSubIntExpr :
public SubIntExpr {
3845 SafeSubIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
3846 : SubIntExpr(s, l, r) {}
3848 ~SafeSubIntExpr()
override {}
3850 int64 Min()
const override {
return CapSub(left_->Min(), right_->Max()); }
3852 void SetMin(
int64 m)
override {
3853 left_->SetMin(
CapAdd(m, right_->Min()));
3854 right_->SetMax(
CapSub(left_->Max(), m));
3858 const int64 left_min = left_->Min();
3859 const int64 right_min = right_->Min();
3860 const int64 left_max = left_->Max();
3861 const int64 right_max = right_->Max();
3862 if (l >
CapSub(left_min, right_max)) {
3863 left_->SetMin(
CapAdd(l, right_min));
3864 right_->SetMax(
CapSub(left_max, l));
3866 if (u <
CapSub(left_max, right_min)) {
3867 left_->SetMax(
CapAdd(u, right_max));
3868 right_->SetMin(
CapSub(left_min, u));
3873 *mi =
CapSub(left_->Min(), right_->Max());
3874 *ma =
CapSub(left_->Max(), right_->Min());
3877 int64 Max()
const override {
return CapSub(left_->Max(), right_->Min()); }
3879 void SetMax(
int64 m)
override {
3880 left_->SetMax(
CapAdd(m, right_->Max()));
3881 right_->SetMin(
CapSub(left_->Min(), m));
3889 class SubIntCstExpr :
public BaseIntExpr {
3891 SubIntCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
3892 : BaseIntExpr(s),
expr_(e), value_(v) {}
3893 ~SubIntCstExpr()
override {}
3898 bool Bound()
const override {
return (
expr_->Bound()); }
3899 std::string
name()
const override {
3900 return absl::StrFormat(
"(%d - %s)", value_,
expr_->name());
3902 std::string DebugString()
const override {
3903 return absl::StrFormat(
"(%d - %s)", value_,
expr_->DebugString());
3905 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3906 IntVar* CastToVar()
override;
3908 void Accept(ModelVisitor*
const visitor)
const override {
3909 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference,
this);
3910 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
3911 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3913 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference,
this);
3917 IntExpr*
const expr_;
3921 IntVar* SubIntCstExpr::CastToVar() {
3924 return BaseIntExpr::CastToVar();
3926 Solver*
const s = solver();
3928 s->RegisterIntVar(s->RevAlloc(
new SubCstIntVar(s,
expr_->Var(), value_)));
3934 class OppIntExpr :
public BaseIntExpr {
3936 OppIntExpr(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
3937 ~OppIntExpr()
override {}
3938 int64 Min()
const override {
return (-
expr_->Max()); }
3939 void SetMin(
int64 m)
override {
expr_->SetMax(-m); }
3940 int64 Max()
const override {
return (-
expr_->Min()); }
3941 void SetMax(
int64 m)
override {
expr_->SetMin(-m); }
3942 bool Bound()
const override {
return (
expr_->Bound()); }
3943 std::string
name()
const override {
3944 return absl::StrFormat(
"(-%s)",
expr_->name());
3946 std::string DebugString()
const override {
3947 return absl::StrFormat(
"(-%s)",
expr_->DebugString());
3949 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3950 IntVar* CastToVar()
override;
3952 void Accept(ModelVisitor*
const visitor)
const override {
3953 visitor->BeginVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3954 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3956 visitor->EndVisitIntegerExpression(ModelVisitor::kOpposite,
this);
3960 IntExpr*
const expr_;
3963 IntVar* OppIntExpr::CastToVar() {
3964 Solver*
const s = solver();
3966 s->RegisterIntVar(s->RevAlloc(
new OppIntVar(s,
expr_->Var())));
3972 class TimesIntCstExpr :
public BaseIntExpr {
3974 TimesIntCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
3975 : BaseIntExpr(s),
expr_(e), value_(v) {}
3977 ~TimesIntCstExpr()
override {}
3979 bool Bound()
const override {
return (
expr_->Bound()); }
3981 std::string
name()
const override {
3982 return absl::StrFormat(
"(%s * %d)",
expr_->name(), value_);
3985 std::string DebugString()
const override {
3986 return absl::StrFormat(
"(%s * %d)",
expr_->DebugString(), value_);
3989 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
3991 IntExpr* Expr()
const {
return expr_; }
3993 int64 Constant()
const {
return value_; }
3995 void Accept(ModelVisitor*
const visitor)
const override {
3996 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
3997 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
3999 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4000 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4004 IntExpr*
const expr_;
4010 class TimesPosIntCstExpr :
public TimesIntCstExpr {
4012 TimesPosIntCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
4013 : TimesIntCstExpr(s, e, v) {
4017 ~TimesPosIntCstExpr()
override {}
4019 int64 Min()
const override {
return expr_->Min() * value_; }
4023 int64 Max()
const override {
return expr_->Max() * value_; }
4027 IntVar* CastToVar()
override {
4028 Solver*
const s = solver();
4029 IntVar*
var =
nullptr;
4030 if (
expr_->IsVar() &&
4032 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4033 s,
reinterpret_cast<BooleanVar*
>(
expr_), value_)));
4035 var = s->RegisterIntVar(
4036 s->RevAlloc(
new TimesPosCstIntVar(s,
expr_->Var(), value_)));
4044 class SafeTimesPosIntCstExpr :
public TimesIntCstExpr {
4046 SafeTimesPosIntCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
4047 : TimesIntCstExpr(s, e, v) {
4051 ~SafeTimesPosIntCstExpr()
override {}
4055 void SetMin(
int64 m)
override {
4063 void SetMax(
int64 m)
override {
4069 IntVar* CastToVar()
override {
4070 Solver*
const s = solver();
4071 IntVar*
var =
nullptr;
4072 if (
expr_->IsVar() &&
4074 var = s->RegisterIntVar(s->RevAlloc(
new TimesPosCstBoolVar(
4075 s,
reinterpret_cast<BooleanVar*
>(
expr_), value_)));
4078 var = s->RegisterIntVar(
4079 s->RevAlloc(
new TimesPosCstIntVar(s,
expr_->Var(), value_)));
4087 class TimesIntNegCstExpr :
public TimesIntCstExpr {
4089 TimesIntNegCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
4090 : TimesIntCstExpr(s, e, v) {
4094 ~TimesIntNegCstExpr()
override {}
4098 void SetMin(
int64 m)
override {
4106 void SetMax(
int64 m)
override {
4112 IntVar* CastToVar()
override {
4113 Solver*
const s = solver();
4114 IntVar*
var =
nullptr;
4115 var = s->RegisterIntVar(
4116 s->RevAlloc(
new TimesNegCstIntVar(s,
expr_->Var(), value_)));
4124 void SetPosPosMinExpr(IntExpr*
const left, IntExpr*
const right,
int64 m) {
4125 DCHECK_GE(left->Min(), 0);
4126 DCHECK_GE(right->Min(), 0);
4127 const int64 lmax = left->Max();
4128 const int64 rmax = right->Max();
4129 if (m >
CapProd(lmax, rmax)) {
4130 left->solver()->Fail();
4132 if (m >
CapProd(left->Min(), right->Min())) {
4144 void SetPosPosMaxExpr(IntExpr*
const left, IntExpr*
const right,
int64 m) {
4145 DCHECK_GE(left->Min(), 0);
4146 DCHECK_GE(right->Min(), 0);
4147 const int64 lmin = left->Min();
4148 const int64 rmin = right->Min();
4149 if (m <
CapProd(lmin, rmin)) {
4150 left->solver()->Fail();
4152 if (m <
CapProd(left->Max(), right->Max())) {
4164 void SetPosGenMinExpr(IntExpr*
const left, IntExpr*
const right,
int64 m) {
4165 DCHECK_GE(left->Min(), 0);
4166 DCHECK_GT(right->Max(), 0);
4167 DCHECK_LT(right->Min(), 0);
4168 const int64 lmax = left->Max();
4169 const int64 rmax = right->Max();
4170 if (m >
CapProd(lmax, rmax)) {
4171 left->solver()->Fail();
4173 if (left->Max() == 0) {
4174 DCHECK_EQ(0, left->Min());
4180 }
else if (m == 0) {
4181 const int64 lmin = left->Min();
4186 const int64 lmin = left->Min();
4195 void SetGenGenMinExpr(IntExpr*
const left, IntExpr*
const right,
int64 m) {
4196 DCHECK_LT(left->Min(), 0);
4197 DCHECK_GT(left->Max(), 0);
4198 DCHECK_GT(right->Max(), 0);
4199 DCHECK_LT(right->Min(), 0);
4200 const int64 lmin = left->Min();
4201 const int64 lmax = left->Max();
4202 const int64 rmin = right->Min();
4203 const int64 rmax = right->Max();
4205 left->solver()->Fail();
4207 if (m > lmin * rmin) {
4210 }
else if (m >
CapProd(lmax, rmax)) {
4216 void TimesSetMin(IntExpr*
const left, IntExpr*
const right,
4217 IntExpr*
const minus_left, IntExpr*
const minus_right,
4219 if (left->Min() >= 0) {
4220 if (right->Min() >= 0) {
4221 SetPosPosMinExpr(left, right, m);
4222 }
else if (right->Max() <= 0) {
4223 SetPosPosMaxExpr(left, minus_right, -m);
4225 SetPosGenMinExpr(left, right, m);
4227 }
else if (left->Max() <= 0) {
4228 if (right->Min() >= 0) {
4229 SetPosPosMaxExpr(right, minus_left, -m);
4230 }
else if (right->Max() <= 0) {
4231 SetPosPosMinExpr(minus_left, minus_right, m);
4233 SetPosGenMinExpr(minus_left, minus_right, m);
4235 }
else if (right->Min() >= 0) {
4236 SetPosGenMinExpr(right, left, m);
4237 }
else if (right->Max() <= 0) {
4238 SetPosGenMinExpr(minus_right, minus_left, m);
4241 SetGenGenMinExpr(left, right, m);
4245 class TimesIntExpr :
public BaseIntExpr {
4247 TimesIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4251 minus_left_(s->MakeOpposite(left_)),
4252 minus_right_(s->MakeOpposite(right_)) {}
4253 ~TimesIntExpr()
override {}
4254 int64 Min()
const override {
4255 const int64 lmin = left_->Min();
4256 const int64 lmax = left_->Max();
4257 const int64 rmin = right_->Min();
4258 const int64 rmax = right_->Max();
4262 void SetMin(
int64 m)
override;
4263 int64 Max()
const override {
4264 const int64 lmin = left_->Min();
4265 const int64 lmax = left_->Max();
4266 const int64 rmin = right_->Min();
4267 const int64 rmax = right_->Max();
4271 void SetMax(
int64 m)
override;
4272 bool Bound()
const override;
4273 std::string
name()
const override {
4274 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4276 std::string DebugString()
const override {
4277 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4278 right_->DebugString());
4280 void WhenRange(Demon* d)
override {
4281 left_->WhenRange(d);
4282 right_->WhenRange(d);
4285 void Accept(ModelVisitor*
const visitor)
const override {
4286 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4287 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4288 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4290 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4294 IntExpr*
const left_;
4295 IntExpr*
const right_;
4296 IntExpr*
const minus_left_;
4297 IntExpr*
const minus_right_;
4300 void TimesIntExpr::SetMin(
int64 m) {
4302 TimesSetMin(left_, right_, minus_left_, minus_right_, m);
4306 void TimesIntExpr::SetMax(
int64 m) {
4308 TimesSetMin(left_, minus_right_, minus_left_, right_, -m);
4312 bool TimesIntExpr::Bound()
const {
4313 const bool left_bound = left_->Bound();
4314 const bool right_bound = right_->Bound();
4315 return ((left_bound && left_->Max() == 0) ||
4316 (right_bound && right_->Max() == 0) || (left_bound && right_bound));
4321 class TimesPosIntExpr :
public BaseIntExpr {
4323 TimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4324 : BaseIntExpr(s), left_(l), right_(r) {}
4325 ~TimesPosIntExpr()
override {}
4326 int64 Min()
const override {
return (left_->Min() * right_->Min()); }
4327 void SetMin(
int64 m)
override;
4328 int64 Max()
const override {
return (left_->Max() * right_->Max()); }
4329 void SetMax(
int64 m)
override;
4330 bool Bound()
const override;
4331 std::string
name()
const override {
4332 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4334 std::string DebugString()
const override {
4335 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4336 right_->DebugString());
4338 void WhenRange(Demon* d)
override {
4339 left_->WhenRange(d);
4340 right_->WhenRange(d);
4343 void Accept(ModelVisitor*
const visitor)
const override {
4344 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4345 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4346 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4348 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4352 IntExpr*
const left_;
4353 IntExpr*
const right_;
4356 void TimesPosIntExpr::SetMin(
int64 m) { SetPosPosMinExpr(left_, right_, m); }
4358 void TimesPosIntExpr::SetMax(
int64 m) { SetPosPosMaxExpr(left_, right_, m); }
4360 bool TimesPosIntExpr::Bound()
const {
4361 return (left_->Max() == 0 || right_->Max() == 0 ||
4362 (left_->Bound() && right_->Bound()));
4367 class SafeTimesPosIntExpr :
public BaseIntExpr {
4369 SafeTimesPosIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
4370 : BaseIntExpr(s), left_(l), right_(r) {}
4371 ~SafeTimesPosIntExpr()
override {}
4372 int64 Min()
const override {
return CapProd(left_->Min(), right_->Min()); }
4373 void SetMin(
int64 m)
override {
4375 SetPosPosMinExpr(left_, right_, m);
4378 int64 Max()
const override {
return CapProd(left_->Max(), right_->Max()); }
4379 void SetMax(
int64 m)
override {
4381 SetPosPosMaxExpr(left_, right_, m);
4384 bool Bound()
const override {
4385 return (left_->Max() == 0 || right_->Max() == 0 ||
4386 (left_->Bound() && right_->Bound()));
4388 std::string
name()
const override {
4389 return absl::StrFormat(
"(%s * %s)", left_->name(), right_->name());
4391 std::string DebugString()
const override {
4392 return absl::StrFormat(
"(%s * %s)", left_->DebugString(),
4393 right_->DebugString());
4395 void WhenRange(Demon* d)
override {
4396 left_->WhenRange(d);
4397 right_->WhenRange(d);
4400 void Accept(ModelVisitor*
const visitor)
const override {
4401 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4402 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
4403 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4405 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4409 IntExpr*
const left_;
4410 IntExpr*
const right_;
4415 class TimesBooleanPosIntExpr :
public BaseIntExpr {
4417 TimesBooleanPosIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4418 : BaseIntExpr(s), boolvar_(
b),
expr_(e) {}
4419 ~TimesBooleanPosIntExpr()
override {}
4420 int64 Min()
const override {
4421 return (boolvar_->RawValue() == 1 ?
expr_->Min() : 0);
4423 void SetMin(
int64 m)
override;
4424 int64 Max()
const override {
4425 return (boolvar_->RawValue() == 0 ? 0 :
expr_->Max());
4427 void SetMax(
int64 m)
override;
4430 bool Bound()
const override;
4431 std::string
name()
const override {
4432 return absl::StrFormat(
"(%s * %s)", boolvar_->name(),
expr_->name());
4434 std::string DebugString()
const override {
4435 return absl::StrFormat(
"(%s * %s)", boolvar_->DebugString(),
4436 expr_->DebugString());
4438 void WhenRange(Demon* d)
override {
4439 boolvar_->WhenRange(d);
4440 expr_->WhenRange(d);
4443 void Accept(ModelVisitor*
const visitor)
const override {
4444 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4445 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4447 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4449 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4453 BooleanVar*
const boolvar_;
4454 IntExpr*
const expr_;
4457 void TimesBooleanPosIntExpr::SetMin(
int64 m) {
4459 boolvar_->SetValue(1);
4464 void TimesBooleanPosIntExpr::SetMax(
int64 m) {
4468 if (m < expr_->Min()) {
4469 boolvar_->SetValue(0);
4471 if (boolvar_->RawValue() == 1) {
4476 void TimesBooleanPosIntExpr::Range(
int64* mi,
int64* ma) {
4477 const int value = boolvar_->RawValue();
4481 }
else if (
value == 1) {
4482 expr_->Range(mi, ma);
4489 void TimesBooleanPosIntExpr::SetRange(
int64 mi,
int64 ma) {
4490 if (ma < 0 || mi > ma) {
4494 boolvar_->SetValue(1);
4497 if (ma < expr_->Min()) {
4498 boolvar_->SetValue(0);
4500 if (boolvar_->RawValue() == 1) {
4505 bool TimesBooleanPosIntExpr::Bound()
const {
4506 return (boolvar_->RawValue() == 0 ||
expr_->Max() == 0 ||
4507 (boolvar_->RawValue() != BooleanVar::kUnboundBooleanVarValue &&
4513 class TimesBooleanIntExpr :
public BaseIntExpr {
4515 TimesBooleanIntExpr(Solver*
const s, BooleanVar*
const b, IntExpr*
const e)
4516 : BaseIntExpr(s), boolvar_(
b),
expr_(e) {}
4517 ~TimesBooleanIntExpr()
override {}
4518 int64 Min()
const override {
4519 switch (boolvar_->RawValue()) {
4524 return expr_->Min();
4527 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4532 void SetMin(
int64 m)
override;
4533 int64 Max()
const override {
4534 switch (boolvar_->RawValue()) {
4539 return expr_->Max();
4542 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4547 void SetMax(
int64 m)
override;
4550 bool Bound()
const override;
4551 std::string
name()
const override {
4552 return absl::StrFormat(
"(%s * %s)", boolvar_->name(),
expr_->name());
4554 std::string DebugString()
const override {
4555 return absl::StrFormat(
"(%s * %s)", boolvar_->DebugString(),
4556 expr_->DebugString());
4558 void WhenRange(Demon* d)
override {
4559 boolvar_->WhenRange(d);
4560 expr_->WhenRange(d);
4563 void Accept(ModelVisitor*
const visitor)
const override {
4564 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct,
this);
4565 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
4567 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4569 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct,
this);
4573 BooleanVar*
const boolvar_;
4574 IntExpr*
const expr_;
4577 void TimesBooleanIntExpr::SetMin(
int64 m) {
4578 switch (boolvar_->RawValue()) {
4590 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4592 boolvar_->SetValue(1);
4594 }
else if (m <= 0 && expr_->Max() < m) {
4595 boolvar_->SetValue(0);
4601 void TimesBooleanIntExpr::SetMax(
int64 m) {
4602 switch (boolvar_->RawValue()) {
4614 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4616 boolvar_->SetValue(1);
4618 }
else if (m >= 0 &&
expr_->Min() > m) {
4619 boolvar_->SetValue(0);
4625 void TimesBooleanIntExpr::Range(
int64* mi,
int64* ma) {
4626 switch (boolvar_->RawValue()) {
4638 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4646 void TimesBooleanIntExpr::SetRange(
int64 mi,
int64 ma) {
4650 switch (boolvar_->RawValue()) {
4652 if (mi > 0 || ma < 0) {
4658 expr_->SetRange(mi, ma);
4662 DCHECK_EQ(BooleanVar::kUnboundBooleanVarValue, boolvar_->RawValue());
4664 boolvar_->SetValue(1);
4666 }
else if (mi == 0 &&
expr_->Max() < 0) {
4667 boolvar_->SetValue(0);
4670 boolvar_->SetValue(1);
4672 }
else if (ma == 0 &&
expr_->Min() > 0) {
4673 boolvar_->SetValue(0);
4680 bool TimesBooleanIntExpr::Bound()
const {
4681 return (boolvar_->RawValue() == 0 ||
4683 (boolvar_->RawValue() != BooleanVar::kUnboundBooleanVarValue ||
4684 expr_->Max() == 0)));
4689 class DivPosIntCstExpr :
public BaseIntExpr {
4691 DivPosIntCstExpr(Solver*
const s, IntExpr*
const e,
int64 v)
4692 : BaseIntExpr(s),
expr_(e), value_(v) {
4695 ~DivPosIntCstExpr()
override {}
4697 int64 Min()
const override {
return expr_->Min() / value_; }
4699 void SetMin(
int64 m)
override {
4701 expr_->SetMin(m * value_);
4703 expr_->SetMin((m - 1) * value_ + 1);
4706 int64 Max()
const override {
return expr_->Max() / value_; }
4708 void SetMax(
int64 m)
override {
4710 expr_->SetMax((m + 1) * value_ - 1);
4712 expr_->SetMax(m * value_);
4716 std::string
name()
const override {
4717 return absl::StrFormat(
"(%s div %d)",
expr_->name(), value_);
4720 std::string DebugString()
const override {
4721 return absl::StrFormat(
"(%s div %d)",
expr_->DebugString(), value_);
4724 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
4726 void Accept(ModelVisitor*
const visitor)
const override {
4727 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4728 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
4730 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
4731 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4735 IntExpr*
const expr_;
4741 class DivPosIntExpr :
public BaseIntExpr {
4743 DivPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4747 opp_num_(s->MakeOpposite(num)) {}
4749 ~DivPosIntExpr()
override {}
4751 int64 Min()
const override {
4752 return num_->Min() >= 0
4753 ? num_->Min() / denom_->Max()
4754 : (denom_->Min() == 0 ? num_->Min()
4755 : num_->Min() / denom_->Min());
4758 int64 Max()
const override {
4759 return num_->Max() >= 0 ? (denom_->Min() == 0 ? num_->Max()
4760 : num_->Max() / denom_->Min())
4761 : num_->Max() / denom_->Max();
4764 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom,
int64 m) {
4765 num->SetMin(m * denom->Min());
4766 denom->SetMax(num->Max() / m);
4769 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom,
int64 m) {
4770 num->SetMax((m + 1) * denom->Max() - 1);
4771 denom->SetMin(num->Min() / (m + 1) + 1);
4774 void SetMin(
int64 m)
override {
4776 SetPosMin(num_, denom_, m);
4778 SetPosMax(opp_num_, denom_, -m);
4782 void SetMax(
int64 m)
override {
4784 SetPosMax(num_, denom_, m);
4786 SetPosMin(opp_num_, denom_, -m);
4790 std::string
name()
const override {
4791 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
4793 std::string DebugString()
const override {
4794 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
4795 denom_->DebugString());
4797 void WhenRange(Demon* d)
override {
4799 denom_->WhenRange(d);
4802 void Accept(ModelVisitor*
const visitor)
const override {
4803 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4804 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4805 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4807 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4811 IntExpr*
const num_;
4812 IntExpr*
const denom_;
4813 IntExpr*
const opp_num_;
4816 class DivPosPosIntExpr :
public BaseIntExpr {
4818 DivPosPosIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4819 : BaseIntExpr(s), num_(num), denom_(denom) {}
4821 ~DivPosPosIntExpr()
override {}
4823 int64 Min()
const override {
4824 if (denom_->Max() == 0) {
4827 return num_->Min() / denom_->Max();
4830 int64 Max()
const override {
4831 if (denom_->Min() == 0) {
4834 return num_->Max() / denom_->Min();
4838 void SetMin(
int64 m)
override {
4840 num_->SetMin(m * denom_->Min());
4841 denom_->SetMax(num_->Max() / m);
4845 void SetMax(
int64 m)
override {
4847 num_->SetMax((m + 1) * denom_->Max() - 1);
4848 denom_->SetMin(num_->Min() / (m + 1) + 1);
4854 std::string
name()
const override {
4855 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
4858 std::string DebugString()
const override {
4859 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
4860 denom_->DebugString());
4863 void WhenRange(Demon* d)
override {
4865 denom_->WhenRange(d);
4868 void Accept(ModelVisitor*
const visitor)
const override {
4869 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
4870 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
4871 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
4873 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
4877 IntExpr*
const num_;
4878 IntExpr*
const denom_;
4883 class DivIntExpr :
public BaseIntExpr {
4885 DivIntExpr(Solver*
const s, IntExpr*
const num, IntExpr*
const denom)
4889 opp_num_(s->MakeOpposite(num)) {}
4891 ~DivIntExpr()
override {}
4893 int64 Min()
const override {
4894 const int64 num_min = num_->Min();
4895 const int64 num_max = num_->Max();
4896 const int64 denom_min = denom_->Min();
4897 const int64 denom_max = denom_->Max();
4899 if (denom_min == 0 && denom_max == 0) {
4903 if (denom_min >= 0) {
4904 DCHECK_GT(denom_max, 0);
4905 const int64 adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4906 return num_min >= 0 ? num_min / denom_max : num_min / adjusted_denom_min;
4907 }
else if (denom_max <= 0) {
4908 DCHECK_LT(denom_min, 0);
4909 const int64 adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4910 return num_max >= 0 ? num_max / adjusted_denom_max : num_max / denom_min;
4912 return std::min(num_min, -num_max);
4916 int64 Max()
const override {
4917 const int64 num_min = num_->Min();
4918 const int64 num_max = num_->Max();
4919 const int64 denom_min = denom_->Min();
4920 const int64 denom_max = denom_->Max();
4922 if (denom_min == 0 && denom_max == 0) {
4926 if (denom_min >= 0) {
4927 DCHECK_GT(denom_max, 0);
4928 const int64 adjusted_denom_min = denom_min == 0 ? 1 : denom_min;
4929 return num_max >= 0 ? num_max / adjusted_denom_min : num_max / denom_max;
4930 }
else if (denom_max <= 0) {
4931 DCHECK_LT(denom_min, 0);
4932 const int64 adjusted_denom_max = denom_max == 0 ? -1 : denom_max;
4933 return num_min >= 0 ? num_min / denom_min
4934 : -num_min / -adjusted_denom_max;
4936 return std::max(num_max, -num_min);
4940 void AdjustDenominator() {
4941 if (denom_->Min() == 0) {
4943 }
else if (denom_->Max() == 0) {
4949 static void SetPosMin(IntExpr*
const num, IntExpr*
const denom,
int64 m) {
4951 const int64 num_min = num->Min();
4952 const int64 num_max = num->Max();
4953 const int64 denom_min = denom->Min();
4954 const int64 denom_max = denom->Max();
4955 DCHECK_NE(denom_min, 0);
4956 DCHECK_NE(denom_max, 0);
4957 if (denom_min > 0) {
4958 num->SetMin(m * denom_min);
4959 denom->SetMax(num_max / m);
4960 }
else if (denom_max < 0) {
4961 num->SetMax(m * denom_max);
4962 denom->SetMin(num_min / m);
4966 denom->SetRange(1, num_max / m);
4967 }
else if (num_max <= 0) {
4969 denom->SetRange(num_min / m, -1);
4973 denom->SetRange(1, num_max / m);
4974 }
else if (m > num_max) {
4976 denom->SetRange(num_min / m, -1);
4978 denom->SetRange(num_min / m, num_max / m);
4985 static void SetPosMax(IntExpr*
const num, IntExpr*
const denom,
int64 m) {
4987 const int64 num_min = num->Min();
4988 const int64 num_max = num->Max();
4989 const int64 denom_min = denom->Min();
4990 const int64 denom_max = denom->Max();
4991 DCHECK_NE(denom_min, 0);
4992 DCHECK_NE(denom_max, 0);
4993 if (denom_min > 0) {
4994 num->SetMax((m + 1) * denom_max - 1);
4995 denom->SetMin((num_min / (m + 1)) + 1);
4996 }
else if (denom_max < 0) {
4997 num->SetMin((m + 1) * denom_min + 1);
4998 denom->SetMax(num_max / (m + 1) - 1);
4999 }
else if (num_min > (m + 1) * denom_max - 1) {
5001 }
else if (num_max < (m + 1) * denom_min + 1) {
5006 void SetMin(
int64 m)
override {
5007 AdjustDenominator();
5009 SetPosMin(num_, denom_, m);
5011 SetPosMax(opp_num_, denom_, -m);
5015 void SetMax(
int64 m)
override {
5016 AdjustDenominator();
5018 SetPosMax(num_, denom_, m);
5020 SetPosMin(opp_num_, denom_, -m);
5024 std::string
name()
const override {
5025 return absl::StrFormat(
"(%s div %s)", num_->name(), denom_->name());
5027 std::string DebugString()
const override {
5028 return absl::StrFormat(
"(%s div %s)", num_->DebugString(),
5029 denom_->DebugString());
5031 void WhenRange(Demon* d)
override {
5033 denom_->WhenRange(d);
5036 void Accept(ModelVisitor*
const visitor)
const override {
5037 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide,
this);
5038 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, num_);
5039 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5041 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide,
this);
5045 IntExpr*
const num_;
5046 IntExpr*
const denom_;
5047 IntExpr*
const opp_num_;
5052 class IntAbsConstraint :
public CastConstraint {
5054 IntAbsConstraint(Solver*
const s, IntVar*
const sub, IntVar*
const target)
5055 : CastConstraint(s, target), sub_(sub) {}
5057 ~IntAbsConstraint()
override {}
5059 void Post()
override {
5061 solver(),
this, &IntAbsConstraint::PropagateSub,
"PropagateSub");
5062 sub_->WhenRange(sub_demon);
5064 solver(),
this, &IntAbsConstraint::PropagateTarget,
"PropagateTarget");
5068 void InitialPropagate()
override {
5073 void PropagateSub() {
5074 const int64 smin = sub_->Min();
5075 const int64 smax = sub_->Max();
5078 }
else if (smin >= 0) {
5085 void PropagateTarget() {
5087 sub_->SetRange(-target_max, target_max);
5089 if (target_min > 0) {
5090 if (sub_->Min() > -target_min) {
5091 sub_->SetMin(target_min);
5092 }
else if (sub_->Max() < target_min) {
5093 sub_->SetMax(-target_min);
5098 std::string DebugString()
const override {
5099 return absl::StrFormat(
"IntAbsConstraint(%s, %s)", sub_->DebugString(),
5103 void Accept(ModelVisitor*
const visitor)
const override {
5104 visitor->BeginVisitConstraint(ModelVisitor::kAbsEqual,
this);
5105 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5107 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
5109 visitor->EndVisitConstraint(ModelVisitor::kAbsEqual,
this);
5116 class IntAbs :
public BaseIntExpr {
5118 IntAbs(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
5120 ~IntAbs()
override {}
5122 int64 Min()
const override {
5125 expr_->Range(&emin, &emax);
5135 void SetMin(
int64 m)
override {
5139 expr_->Range(&emin, &emax);
5142 }
else if (emax < m) {
5148 int64 Max()
const override {
5151 expr_->Range(&emin, &emax);
5155 void SetMax(
int64 m)
override {
expr_->SetRange(-m, m); }
5158 expr_->SetRange(-ma, ma);
5162 expr_->Range(&emin, &emax);
5165 }
else if (emax < mi) {
5174 expr_->Range(&emin, &emax);
5178 }
else if (emax <= 0) {
5187 bool Bound()
const override {
return expr_->Bound(); }
5189 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5191 std::string
name()
const override {
5192 return absl::StrFormat(
"IntAbs(%s)",
expr_->name());
5195 std::string DebugString()
const override {
5196 return absl::StrFormat(
"IntAbs(%s)",
expr_->DebugString());
5199 void Accept(ModelVisitor*
const visitor)
const override {
5200 visitor->BeginVisitIntegerExpression(ModelVisitor::kAbs,
this);
5201 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5203 visitor->EndVisitIntegerExpression(ModelVisitor::kAbs,
this);
5206 IntVar* CastToVar()
override {
5207 int64 min_value = 0;
5208 int64 max_value = 0;
5209 Range(&min_value, &max_value);
5210 Solver*
const s = solver();
5211 const std::string
name = absl::StrFormat(
"AbsVar(%s)",
expr_->name());
5212 IntVar*
const target = s->MakeIntVar(min_value, max_value,
name);
5213 CastConstraint*
const ct =
5214 s->RevAlloc(
new IntAbsConstraint(s,
expr_->Var(), target));
5215 s->AddCastConstraint(
ct, target,
this);
5220 IntExpr*
const expr_;
5226 class IntSquare :
public BaseIntExpr {
5228 IntSquare(Solver*
const s, IntExpr*
const e) : BaseIntExpr(s),
expr_(e) {}
5229 ~IntSquare()
override {}
5231 int64 Min()
const override {
5242 void SetMin(
int64 m)
override {
5249 const int64 root =
static_cast<int64>(ceil(sqrt(
static_cast<double>(m))));
5251 expr_->SetMin(root);
5252 }
else if (emax <= 0) {
5253 expr_->SetMax(-root);
5254 }
else if (
expr_->IsVar()) {
5255 reinterpret_cast<IntVar*
>(
expr_)->RemoveInterval(-root + 1, root - 1);
5258 int64 Max()
const override {
5264 return std::max(emin * emin, emax * emax);
5266 void SetMax(
int64 m)
override {
5273 const int64 root =
static_cast<int64>(floor(sqrt(
static_cast<double>(m))));
5274 expr_->SetRange(-root, root);
5276 bool Bound()
const override {
return expr_->Bound(); }
5277 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5278 std::string
name()
const override {
5279 return absl::StrFormat(
"IntSquare(%s)",
expr_->name());
5281 std::string DebugString()
const override {
5282 return absl::StrFormat(
"IntSquare(%s)",
expr_->DebugString());
5285 void Accept(ModelVisitor*
const visitor)
const override {
5286 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare,
this);
5287 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5289 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare,
this);
5292 IntExpr* expr()
const {
return expr_; }
5295 IntExpr*
const expr_;
5298 class PosIntSquare :
public IntSquare {
5300 PosIntSquare(Solver*
const s, IntExpr*
const e) : IntSquare(s, e) {}
5301 ~PosIntSquare()
override {}
5303 int64 Min()
const override {
5307 void SetMin(
int64 m)
override {
5311 const int64 root =
static_cast<int64>(ceil(sqrt(
static_cast<double>(m))));
5312 expr_->SetMin(root);
5314 int64 Max()
const override {
5318 void SetMax(
int64 m)
override {
5325 const int64 root =
static_cast<int64>(floor(sqrt(
static_cast<double>(m))));
5326 expr_->SetMax(root);
5335 for (
int i = 1; i < power; ++i) {
5342 return static_cast<int64>(
5343 floor(exp(log(
static_cast<double>(
kint64max)) / power)));
5346 class BasePower :
public BaseIntExpr {
5348 BasePower(Solver*
const s, IntExpr*
const e,
int64 n)
5353 ~BasePower()
override {}
5355 bool Bound()
const override {
return expr_->Bound(); }
5357 IntExpr* expr()
const {
return expr_; }
5361 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5363 std::string
name()
const override {
5364 return absl::StrFormat(
"IntPower(%s, %d)",
expr_->name(),
pow_);
5367 std::string DebugString()
const override {
5368 return absl::StrFormat(
"IntPower(%s, %d)",
expr_->DebugString(),
pow_);
5371 void Accept(ModelVisitor*
const visitor)
const override {
5372 visitor->BeginVisitIntegerExpression(ModelVisitor::kPower,
this);
5373 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5375 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
pow_);
5376 visitor->EndVisitIntegerExpression(ModelVisitor::kPower,
this);
5385 if (
pow_ % 2 == 0) {
5402 const double d_value =
static_cast<double>(
value);
5404 const double sq = exp(log(d_value) /
pow_);
5405 res =
static_cast<int64>(floor(sq));
5407 CHECK_EQ(1,
pow_ % 2);
5408 const double sq = exp(log(-d_value) /
pow_);
5409 res = -
static_cast<int64>(ceil(sq));
5411 const int64 pow_res = Pown(res + 1);
5412 if (pow_res <=
value) {
5427 const double d_value =
static_cast<double>(
value);
5429 const double sq = exp(log(d_value) /
pow_);
5430 res =
static_cast<int64>(ceil(sq));
5432 CHECK_EQ(1,
pow_ % 2);
5433 const double sq = exp(log(-d_value) /
pow_);
5434 res = -
static_cast<int64>(floor(sq));
5436 const int64 pow_res = Pown(res - 1);
5437 if (pow_res >=
value) {
5444 IntExpr*
const expr_;
5449 class IntEvenPower :
public BasePower {
5451 IntEvenPower(Solver*
const s, IntExpr*
const e,
int64 n)
5452 : BasePower(s, e, n) {
5456 ~IntEvenPower()
override {}
5458 int64 Min()
const override {
5461 expr_->Range(&emin, &emax);
5470 void SetMin(
int64 m)
override {
5476 expr_->Range(&emin, &emax);
5477 const int64 root = SqrnUp(m);
5479 expr_->SetMin(root);
5480 }
else if (emax < root) {
5481 expr_->SetMax(-root);
5482 }
else if (
expr_->IsVar()) {
5483 reinterpret_cast<IntVar*
>(
expr_)->RemoveInterval(-root + 1, root - 1);
5487 int64 Max()
const override {
5491 void SetMax(
int64 m)
override {
5498 const int64 root = SqrnDown(m);
5499 expr_->SetRange(-root, root);
5503 class PosIntEvenPower :
public BasePower {
5505 PosIntEvenPower(Solver*
const s, IntExpr*
const e,
int64 pow)
5506 : BasePower(s, e, pow) {
5507 CHECK_EQ(0, pow % 2);
5510 ~PosIntEvenPower()
override {}
5512 int64 Min()
const override {
return Pown(
expr_->Min()); }
5514 void SetMin(
int64 m)
override {
5518 expr_->SetMin(SqrnUp(m));
5520 int64 Max()
const override {
return Pown(
expr_->Max()); }
5522 void SetMax(
int64 m)
override {
5529 expr_->SetMax(SqrnDown(m));
5533 class IntOddPower :
public BasePower {
5535 IntOddPower(Solver*
const s, IntExpr*
const e,
int64 n) : BasePower(s, e, n) {
5539 ~IntOddPower()
override {}
5541 int64 Min()
const override {
return Pown(
expr_->Min()); }
5543 void SetMin(
int64 m)
override {
expr_->SetMin(SqrnUp(m)); }
5545 int64 Max()
const override {
return Pown(
expr_->Max()); }
5547 void SetMax(
int64 m)
override {
expr_->SetMax(SqrnDown(m)); }
5552 class MinIntExpr :
public BaseIntExpr {
5554 MinIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5555 : BaseIntExpr(s), left_(l), right_(r) {}
5556 ~MinIntExpr()
override {}
5557 int64 Min()
const override {
5558 const int64 lmin = left_->Min();
5559 const int64 rmin = right_->Min();
5562 void SetMin(
int64 m)
override {
5566 int64 Max()
const override {
5567 const int64 lmax = left_->Max();
5568 const int64 rmax = right_->Max();
5571 void SetMax(
int64 m)
override {
5572 if (left_->Min() > m) {
5575 if (right_->Min() > m) {
5579 std::string
name()
const override {
5580 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->name(), right_->name());
5582 std::string DebugString()
const override {
5583 return absl::StrFormat(
"MinIntExpr(%s, %s)", left_->DebugString(),
5584 right_->DebugString());
5586 void WhenRange(Demon* d)
override {
5587 left_->WhenRange(d);
5588 right_->WhenRange(d);
5591 void Accept(ModelVisitor*
const visitor)
const override {
5592 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5593 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5594 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5596 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5600 IntExpr*
const left_;
5601 IntExpr*
const right_;
5606 class MinCstIntExpr :
public BaseIntExpr {
5608 MinCstIntExpr(Solver*
const s, IntExpr*
const e,
int64 v)
5609 : BaseIntExpr(s),
expr_(e), value_(v) {}
5611 ~MinCstIntExpr()
override {}
5615 void SetMin(
int64 m)
override {
5624 void SetMax(
int64 m)
override {
5630 bool Bound()
const override {
5631 return (
expr_->Bound() ||
expr_->Min() >= value_);
5634 std::string
name()
const override {
5635 return absl::StrFormat(
"MinCstIntExpr(%s, %d)",
expr_->name(), value_);
5638 std::string DebugString()
const override {
5639 return absl::StrFormat(
"MinCstIntExpr(%s, %d)",
expr_->DebugString(),
5643 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5645 void Accept(ModelVisitor*
const visitor)
const override {
5646 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin,
this);
5647 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5649 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5650 visitor->EndVisitIntegerExpression(ModelVisitor::kMin,
this);
5654 IntExpr*
const expr_;
5660 class MaxIntExpr :
public BaseIntExpr {
5662 MaxIntExpr(Solver*
const s, IntExpr*
const l, IntExpr*
const r)
5663 : BaseIntExpr(s), left_(l), right_(r) {}
5665 ~MaxIntExpr()
override {}
5667 int64 Min()
const override {
return std::max(left_->Min(), right_->Min()); }
5669 void SetMin(
int64 m)
override {
5670 if (left_->Max() < m) {
5673 if (right_->Max() < m) {
5679 int64 Max()
const override {
return std::max(left_->Max(), right_->Max()); }
5681 void SetMax(
int64 m)
override {
5686 std::string
name()
const override {
5687 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->name(), right_->name());
5690 std::string DebugString()
const override {
5691 return absl::StrFormat(
"MaxIntExpr(%s, %s)", left_->DebugString(),
5692 right_->DebugString());
5695 void WhenRange(Demon* d)
override {
5696 left_->WhenRange(d);
5697 right_->WhenRange(d);
5700 void Accept(ModelVisitor*
const visitor)
const override {
5701 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5702 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
5703 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
5705 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5709 IntExpr*
const left_;
5710 IntExpr*
const right_;
5715 class MaxCstIntExpr :
public BaseIntExpr {
5717 MaxCstIntExpr(Solver*
const s, IntExpr*
const e,
int64 v)
5718 : BaseIntExpr(s),
expr_(e), value_(v) {}
5720 ~MaxCstIntExpr()
override {}
5724 void SetMin(
int64 m)
override {
5732 void SetMax(
int64 m)
override {
5739 bool Bound()
const override {
5740 return (
expr_->Bound() ||
expr_->Max() <= value_);
5743 std::string
name()
const override {
5744 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)",
expr_->name(), value_);
5747 std::string DebugString()
const override {
5748 return absl::StrFormat(
"MaxCstIntExpr(%s, %d)",
expr_->DebugString(),
5752 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5754 void Accept(ModelVisitor*
const visitor)
const override {
5755 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax,
this);
5756 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5758 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
5759 visitor->EndVisitIntegerExpression(ModelVisitor::kMax,
this);
5763 IntExpr*
const expr_;
5775 class SimpleConvexPiecewiseExpr :
public BaseIntExpr {
5777 SimpleConvexPiecewiseExpr(Solver*
const s, IntExpr*
const e,
int64 ec,
5785 DCHECK_GE(ec,
int64{0});
5786 DCHECK_GE(lc,
int64{0});
5793 ~SimpleConvexPiecewiseExpr()
override {}
5795 int64 Min()
const override {
5798 if (vmin >= late_date_) {
5799 return (vmin - late_date_) * late_cost_;
5800 }
else if (vmax <= early_date_) {
5801 return (early_date_ - vmax) * early_cost_;
5807 void SetMin(
int64 m)
override {
5813 expr_->Range(&vmin, &vmax);
5816 (late_cost_ == 0 ? vmax : late_date_ +
PosIntDivUp(m, late_cost_) - 1);
5818 (early_cost_ == 0 ? vmin
5821 if (
expr_->IsVar()) {
5822 expr_->Var()->RemoveInterval(lb, rb);
5826 int64 Max()
const override {
5829 const int64 mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0;
5831 vmin < early_date_ ? (early_date_ - vmin) * early_cost_ : 0;
5835 void SetMax(
int64 m)
override {
5839 if (late_cost_ != 0LL) {
5841 if (early_cost_ != 0LL) {
5843 expr_->SetRange(lb, rb);
5848 if (early_cost_ != 0LL) {
5855 std::string
name()
const override {
5856 return absl::StrFormat(
5857 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5858 expr_->name(), early_cost_, early_date_, late_date_, late_cost_);
5861 std::string DebugString()
const override {
5862 return absl::StrFormat(
5863 "ConvexPiecewiseExpr(%s, ec = %d, ed = %d, ld = %d, lc = %d)",
5864 expr_->DebugString(), early_cost_, early_date_, late_date_, late_cost_);
5867 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5869 void Accept(ModelVisitor*
const visitor)
const override {
5870 visitor->BeginVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5871 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5873 visitor->VisitIntegerArgument(ModelVisitor::kEarlyCostArgument,
5875 visitor->VisitIntegerArgument(ModelVisitor::kEarlyDateArgument,
5877 visitor->VisitIntegerArgument(ModelVisitor::kLateCostArgument, late_cost_);
5878 visitor->VisitIntegerArgument(ModelVisitor::kLateDateArgument, late_date_);
5879 visitor->EndVisitIntegerExpression(ModelVisitor::kConvexPiecewise,
this);
5883 IntExpr*
const expr_;
5884 const int64 early_cost_;
5885 const int64 early_date_;
5886 const int64 late_date_;
5887 const int64 late_cost_;
5892 class SemiContinuousExpr :
public BaseIntExpr {
5894 SemiContinuousExpr(Solver*
const s, IntExpr*
const e,
int64 fixed_charge,
5896 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge),
step_(step) {
5897 DCHECK_GE(fixed_charge,
int64{0});
5898 DCHECK_GT(step,
int64{0});
5901 ~SemiContinuousExpr()
override {}
5913 void SetMin(
int64 m)
override {
5924 void SetMax(
int64 m)
override {
5939 std::string
name()
const override {
5940 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
5944 std::string DebugString()
const override {
5945 return absl::StrFormat(
"SemiContinuous(%s, fixed_charge = %d, step = %d)",
5949 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
5951 void Accept(ModelVisitor*
const visitor)
const override {
5952 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
5953 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
5955 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
5957 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument,
step_);
5958 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
5962 IntExpr*
const expr_;
5963 const int64 fixed_charge_;
5967 class SemiContinuousStepOneExpr :
public BaseIntExpr {
5969 SemiContinuousStepOneExpr(Solver*
const s, IntExpr*
const e,
5971 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge) {
5972 DCHECK_GE(fixed_charge,
int64{0});
5975 ~SemiContinuousStepOneExpr()
override {}
5981 return fixed_charge_ + x;
5987 void SetMin(
int64 m)
override {
5988 if (m >= fixed_charge_ + 1) {
5989 expr_->SetMin(m - fixed_charge_);
5997 void SetMax(
int64 m)
override {
6001 if (m < fixed_charge_ + 1) {
6004 expr_->SetMax(m - fixed_charge_);
6008 std::string
name()
const override {
6009 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6010 expr_->name(), fixed_charge_);
6013 std::string DebugString()
const override {
6014 return absl::StrFormat(
"SemiContinuousStepOne(%s, fixed_charge = %d)",
6015 expr_->DebugString(), fixed_charge_);
6018 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6020 void Accept(ModelVisitor*
const visitor)
const override {
6021 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6022 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6024 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6026 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 1);
6027 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6031 IntExpr*
const expr_;
6032 const int64 fixed_charge_;
6035 class SemiContinuousStepZeroExpr :
public BaseIntExpr {
6037 SemiContinuousStepZeroExpr(Solver*
const s, IntExpr*
const e,
6039 : BaseIntExpr(s),
expr_(e), fixed_charge_(fixed_charge) {
6040 DCHECK_GT(fixed_charge,
int64{0});
6043 ~SemiContinuousStepZeroExpr()
override {}
6049 return fixed_charge_;
6055 void SetMin(
int64 m)
override {
6056 if (m >= fixed_charge_) {
6065 void SetMax(
int64 m)
override {
6069 if (m < fixed_charge_) {
6074 std::string
name()
const override {
6075 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6076 expr_->name(), fixed_charge_);
6079 std::string DebugString()
const override {
6080 return absl::StrFormat(
"SemiContinuousStepZero(%s, fixed_charge = %d)",
6081 expr_->DebugString(), fixed_charge_);
6084 void WhenRange(Demon* d)
override {
expr_->WhenRange(d); }
6086 void Accept(ModelVisitor*
const visitor)
const override {
6087 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6088 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6090 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
6092 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 0);
6093 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous,
this);
6097 IntExpr*
const expr_;
6098 const int64 fixed_charge_;
6102 class LinkExprAndVar :
public CastConstraint {
6104 LinkExprAndVar(Solver*
const s, IntExpr*
const expr, IntVar*
const var)
6105 : CastConstraint(s,
var),
expr_(expr) {}
6107 ~LinkExprAndVar()
override {}
6109 void Post()
override {
6110 Solver*
const s = solver();
6111 Demon* d = s->MakeConstraintInitialPropagateCallback(
this);
6112 expr_->WhenRange(d);
6116 void InitialPropagate()
override {
6119 expr_->Range(&l, &u);
6123 std::string DebugString()
const override {
6124 return absl::StrFormat(
"cast(%s, %s)",
expr_->DebugString(),
6128 void Accept(ModelVisitor*
const visitor)
const override {
6129 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6130 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6132 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6134 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6138 IntExpr*
const expr_;
6143 class ExprWithEscapeValue :
public BaseIntExpr {
6145 ExprWithEscapeValue(Solver*
const s, IntVar*
const c, IntExpr*
const e,
6146 int64 unperformed_value)
6150 unperformed_value_(unperformed_value) {}
6152 ~ExprWithEscapeValue()
override {}
6154 int64 Min()
const override {
6155 if (condition_->Min() == 1) {
6156 return expression_->Min();
6157 }
else if (condition_->Max() == 1) {
6158 return std::min(unperformed_value_, expression_->Min());
6160 return unperformed_value_;
6164 void SetMin(
int64 m)
override {
6165 if (m > unperformed_value_) {
6166 condition_->SetValue(1);
6167 expression_->SetMin(m);
6168 }
else if (condition_->Min() == 1) {
6169 expression_->SetMin(m);
6170 }
else if (m > expression_->Max()) {
6171 condition_->SetValue(0);
6175 int64 Max()
const override {
6176 if (condition_->Min() == 1) {
6177 return expression_->Max();
6178 }
else if (condition_->Max() == 1) {
6179 return std::max(unperformed_value_, expression_->Max());
6181 return unperformed_value_;
6185 void SetMax(
int64 m)
override {
6186 if (m < unperformed_value_) {
6187 condition_->SetValue(1);
6188 expression_->SetMax(m);
6189 }
else if (condition_->Min() == 1) {
6190 expression_->SetMax(m);
6191 }
else if (m < expression_->Min()) {
6192 condition_->SetValue(0);
6197 if (ma < unperformed_value_ || mi > unperformed_value_) {
6198 condition_->SetValue(1);
6199 expression_->SetRange(mi, ma);
6200 }
else if (condition_->Min() == 1) {
6201 expression_->SetRange(mi, ma);
6202 }
else if (ma < expression_->Min() || mi > expression_->Max()) {
6203 condition_->SetValue(0);
6207 void SetValue(
int64 v)
override {
6208 if (v != unperformed_value_) {
6209 condition_->SetValue(1);
6210 expression_->SetValue(v);
6211 }
else if (condition_->Min() == 1) {
6212 expression_->SetValue(v);
6213 }
else if (v < expression_->Min() || v > expression_->Max()) {
6214 condition_->SetValue(0);
6218 bool Bound()
const override {
6219 return condition_->Max() == 0 || expression_->Bound();
6222 void WhenRange(Demon* d)
override {
6223 expression_->WhenRange(d);
6224 condition_->WhenBound(d);
6227 std::string DebugString()
const override {
6228 return absl::StrFormat(
"ConditionExpr(%s, %s, %d)",
6229 condition_->DebugString(),
6230 expression_->DebugString(), unperformed_value_);
6233 void Accept(ModelVisitor*
const visitor)
const override {
6234 visitor->BeginVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6235 visitor->VisitIntegerExpressionArgument(ModelVisitor::kVariableArgument,
6237 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6239 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument,
6240 unperformed_value_);
6241 visitor->EndVisitIntegerExpression(ModelVisitor::kConditionalExpr,
this);
6245 IntVar*
const condition_;
6246 IntExpr*
const expression_;
6247 const int64 unperformed_value_;
6252 class LinkExprAndDomainIntVar :
public CastConstraint {
6254 LinkExprAndDomainIntVar(Solver*
const s, IntExpr*
const expr,
6255 DomainIntVar*
const var)
6256 : CastConstraint(s,
var),
6262 ~LinkExprAndDomainIntVar()
override {}
6264 DomainIntVar*
var()
const {
6265 return reinterpret_cast<DomainIntVar*
>(
target_var_);
6268 void Post()
override {
6269 Solver*
const s = solver();
6270 Demon*
const d = s->MakeConstraintInitialPropagateCallback(
this);
6271 expr_->WhenRange(d);
6273 solver(),
this, &LinkExprAndDomainIntVar::Propagate,
"Propagate");
6277 void InitialPropagate()
override {
6278 expr_->SetRange(
var()->min_.Value(),
var()->max_.Value());
6279 expr_->Range(&cached_min_, &cached_max_);
6280 var()->DomainIntVar::SetRange(cached_min_, cached_max_);
6284 if (
var()->min_.Value() > cached_min_ ||
6285 var()->max_.Value() < cached_max_ ||
6286 solver()->fail_stamp() != fail_stamp_) {
6288 fail_stamp_ = solver()->fail_stamp();
6292 std::string DebugString()
const override {
6293 return absl::StrFormat(
"cast(%s, %s)",
expr_->DebugString(),
6297 void Accept(ModelVisitor*
const visitor)
const override {
6298 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6299 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
6301 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
6303 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar,
this);
6307 IntExpr*
const expr_;
6316 IntVarIterator* BooleanVar::MakeHoleIterator(
bool reversible)
const {
6319 IntVarIterator* BooleanVar::MakeDomainIterator(
bool reversible)
const {
6327 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6328 dvar->CleanInProcess();
6332 const std::vector<IntVar*>& vars) {
6333 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6334 CHECK(dvar !=
nullptr);
6335 return dvar->SetIsEqual(values, vars);
6339 const std::vector<int64>& values,
6340 const std::vector<IntVar*>& vars) {
6341 DomainIntVar*
const dvar =
reinterpret_cast<DomainIntVar*
>(
var);
6342 CHECK(dvar !=
nullptr);
6343 return dvar->SetIsGreaterOrEqual(values, vars);
6356 return MakeIntConst(
min,
name);
6358 if (
min == 0 &&
max == 1) {
6359 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
name)));
6361 const std::string inner_name =
"inner_" +
name;
6362 return RegisterIntVar(
6363 MakeSum(RevAlloc(
new ConcreteBooleanVar(
this, inner_name)),
min)
6364 ->VarWithName(
name));
6366 return RegisterIntVar(RevAlloc(
new DomainIntVar(
this,
min,
max,
name)));
6371 return MakeIntVar(
min,
max,
"");
6374 IntVar* Solver::MakeBoolVar(
const std::string&
name) {
6375 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
name)));
6378 IntVar* Solver::MakeBoolVar() {
6379 return RegisterIntVar(RevAlloc(
new ConcreteBooleanVar(
this,
"")));
6382 IntVar* Solver::MakeIntVar(
const std::vector<int64>& values,
6383 const std::string&
name) {
6384 DCHECK(!values.empty());
6386 if (values.size() == 1)
return MakeIntConst(values[0],
name);
6388 std::vector<int64> unique_sorted_values = values;
6391 if (unique_sorted_values.size() == 1)
return MakeIntConst(values[0],
name);
6393 if (unique_sorted_values.size() ==
6394 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6395 return MakeIntVar(unique_sorted_values.front(), unique_sorted_values.back(),
6401 for (
const int64 v : unique_sorted_values) {
6405 gcd = MathUtil::GCD64(gcd, std::abs(v));
6410 return RegisterIntVar(
6411 RevAlloc(
new DomainIntVar(
this, unique_sorted_values,
name)));
6415 for (
int64& v : unique_sorted_values) {
6416 DCHECK_EQ(0, v % gcd);
6419 const std::string new_name =
name.empty() ?
"" :
"inner_" +
name;
6421 IntVar* inner_intvar =
nullptr;
6422 if (unique_sorted_values.size() ==
6423 unique_sorted_values.back() - unique_sorted_values.front() + 1) {
6424 inner_intvar = MakeIntVar(unique_sorted_values.front(),
6425 unique_sorted_values.back(), new_name);
6427 inner_intvar = RegisterIntVar(
6428 RevAlloc(
new DomainIntVar(
this, unique_sorted_values, new_name)));
6430 return MakeProd(inner_intvar, gcd)->Var();
6433 IntVar* Solver::MakeIntVar(
const std::vector<int64>& values) {
6434 return MakeIntVar(values,
"");
6437 IntVar* Solver::MakeIntVar(
const std::vector<int>& values,
6438 const std::string&
name) {
6442 IntVar* Solver::MakeIntVar(
const std::vector<int>& values) {
6443 return MakeIntVar(values,
"");
6446 IntVar* Solver::MakeIntConst(
int64 val,
const std::string&
name) {
6450 if (FLAGS_cp_share_int_consts &&
name.empty() &&
6451 val >= MIN_CACHED_INT_CONST && val <= MAX_CACHED_INT_CONST) {
6452 return cached_constants_[val - MIN_CACHED_INT_CONST];
6454 return RevAlloc(
new IntConst(
this, val,
name));
6457 IntVar* Solver::MakeIntConst(
int64 val) {
return MakeIntConst(val,
""); }
6462 std::string IndexedName(
const std::string& prefix,
int index,
int max_index) {
6464 #if defined(_MSC_VER)
6465 const int digits = max_index > 0 ?
6466 static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
6469 const int digits = max_index > 0 ?
static_cast<int>(log10(max_index)) + 1: 1;
6471 return absl::StrFormat(
"%s%0*d", prefix, digits,
index);
6473 return absl::StrCat(prefix,
index);
6478 void Solver::MakeIntVarArray(
int var_count,
int64 vmin,
int64 vmax,
6479 const std::string&
name,
6480 std::vector<IntVar*>* vars) {
6481 for (
int i = 0; i < var_count; ++i) {
6482 vars->push_back(MakeIntVar(vmin, vmax, IndexedName(
name, i, var_count)));
6486 void Solver::MakeIntVarArray(
int var_count,
int64 vmin,
int64 vmax,
6487 std::vector<IntVar*>* vars) {
6488 for (
int i = 0; i < var_count; ++i) {
6489 vars->push_back(MakeIntVar(vmin, vmax));
6493 IntVar** Solver::MakeIntVarArray(
int var_count,
int64 vmin,
int64 vmax,
6494 const std::string&
name) {
6495 IntVar** vars =
new IntVar*[var_count];
6496 for (
int i = 0; i < var_count; ++i) {
6497 vars[i] = MakeIntVar(vmin, vmax, IndexedName(
name, i, var_count));
6502 void Solver::MakeBoolVarArray(
int var_count,
const std::string&
name,
6503 std::vector<IntVar*>* vars) {
6504 for (
int i = 0; i < var_count; ++i) {
6505 vars->push_back(MakeBoolVar(IndexedName(
name, i, var_count)));
6509 void Solver::MakeBoolVarArray(
int var_count, std::vector<IntVar*>* vars) {
6510 for (
int i = 0; i < var_count; ++i) {
6511 vars->push_back(MakeBoolVar());
6515 IntVar** Solver::MakeBoolVarArray(
int var_count,
const std::string&
name) {
6516 IntVar** vars =
new IntVar*[var_count];
6517 for (
int i = 0; i < var_count; ++i) {
6518 vars[i] = MakeBoolVar(IndexedName(
name, i, var_count));
6523 void Solver::InitCachedIntConstants() {
6524 for (
int i = MIN_CACHED_INT_CONST; i <= MAX_CACHED_INT_CONST; ++i) {
6525 cached_constants_[i - MIN_CACHED_INT_CONST] =
6526 RevAlloc(
new IntConst(
this, i,
""));
6530 IntExpr* Solver::MakeSum(IntExpr*
const left, IntExpr*
const right) {
6531 CHECK_EQ(
this, left->solver());
6532 CHECK_EQ(
this, right->solver());
6533 if (right->Bound()) {
6534 return MakeSum(left, right->Min());
6536 if (left->Bound()) {
6537 return MakeSum(right, left->Min());
6539 if (left == right) {
6540 return MakeProd(left, 2);
6542 IntExpr* cache = model_cache_->FindExprExprExpression(
6543 left, right, ModelCache::EXPR_EXPR_SUM);
6544 if (cache ==
nullptr) {
6545 cache = model_cache_->FindExprExprExpression(right, left,
6546 ModelCache::EXPR_EXPR_SUM);
6548 if (cache !=
nullptr) {
6551 IntExpr*
const result =
6554 ? RegisterIntExpr(RevAlloc(
new SafePlusIntExpr(
this, left, right)))
6555 : RegisterIntExpr(RevAlloc(new PlusIntExpr(this, left, right)));
6556 model_cache_->InsertExprExprExpression(result, left, right,
6557 ModelCache::EXPR_EXPR_SUM);
6562 IntExpr* Solver::MakeSum(IntExpr*
const expr,
int64 value) {
6563 CHECK_EQ(
this, expr->solver());
6564 if (expr->Bound()) {
6565 return MakeIntConst(expr->Min() +
value);
6570 IntExpr* result = Cache()->FindExprConstantExpression(
6571 expr,
value, ModelCache::EXPR_CONSTANT_SUM);
6572 if (result ==
nullptr) {
6575 IntVar*
const var = expr->Var();
6576 switch (
var->VarType()) {
6578 result = RegisterIntExpr(RevAlloc(
new PlusCstDomainIntVar(
6579 this,
reinterpret_cast<DomainIntVar*
>(
var),
value)));
6583 result = RegisterIntExpr(MakeIntConst(
var->Min() +
value));
6587 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(
var);
6588 IntVar*
const sub_var = add_var->SubVar();
6589 const int64 new_constant =
value + add_var->Constant();
6590 if (new_constant == 0) {
6594 DomainIntVar*
const dvar =
6595 reinterpret_cast<DomainIntVar*
>(sub_var);
6596 result = RegisterIntExpr(
6597 RevAlloc(
new PlusCstDomainIntVar(
this, dvar, new_constant)));
6599 result = RegisterIntExpr(
6600 RevAlloc(
new PlusCstIntVar(
this, sub_var, new_constant)));
6606 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(
var);
6607 IntVar*
const sub_var = add_var->SubVar();
6608 const int64 new_constant =
value + add_var->Constant();
6609 result = RegisterIntExpr(
6610 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6614 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(
var);
6615 IntVar*
const sub_var = add_var->SubVar();
6617 RegisterIntExpr(RevAlloc(
new SubCstIntVar(
this, sub_var,
value)));
6622 RegisterIntExpr(RevAlloc(
new PlusCstIntVar(
this,
var,
value)));
6625 result = RegisterIntExpr(RevAlloc(
new PlusIntCstExpr(
this, expr,
value)));
6627 Cache()->InsertExprConstantExpression(result, expr,
value,
6628 ModelCache::EXPR_CONSTANT_SUM);
6633 IntExpr* Solver::MakeDifference(IntExpr*
const left, IntExpr*
const right) {
6634 CHECK_EQ(
this, left->solver());
6635 CHECK_EQ(
this, right->solver());
6636 if (left->Bound()) {
6637 return MakeDifference(left->Min(), right);
6639 if (right->Bound()) {
6640 return MakeSum(left, -right->Min());
6642 IntExpr* sub_left =
nullptr;
6643 IntExpr* sub_right =
nullptr;
6644 int64 left_coef = 1;
6645 int64 right_coef = 1;
6646 if (IsProduct(left, &sub_left, &left_coef) &&
6647 IsProduct(right, &sub_right, &right_coef)) {
6648 const int64 abs_gcd =
6649 MathUtil::GCD64(std::abs(left_coef), std::abs(right_coef));
6650 if (abs_gcd != 0 && abs_gcd != 1) {
6651 return MakeProd(MakeDifference(MakeProd(sub_left, left_coef / abs_gcd),
6652 MakeProd(sub_right, right_coef / abs_gcd)),
6657 IntExpr* result = Cache()->FindExprExprExpression(
6658 left, right, ModelCache::EXPR_EXPR_DIFFERENCE);
6659 if (result ==
nullptr) {
6662 result = RegisterIntExpr(RevAlloc(
new SubIntExpr(
this, left, right)));
6664 result = RegisterIntExpr(RevAlloc(
new SafeSubIntExpr(
this, left, right)));
6666 Cache()->InsertExprExprExpression(result, left, right,
6667 ModelCache::EXPR_EXPR_DIFFERENCE);
6673 IntExpr* Solver::MakeDifference(
int64 value, IntExpr*
const expr) {
6674 CHECK_EQ(
this, expr->solver());
6675 if (expr->Bound()) {
6676 return MakeIntConst(
value - expr->Min());
6679 return MakeOpposite(expr);
6681 IntExpr* result = Cache()->FindExprConstantExpression(
6682 expr,
value, ModelCache::EXPR_CONSTANT_DIFFERENCE);
6683 if (result ==
nullptr) {
6684 if (expr->IsVar() && expr->Min() !=
kint64min &&
6687 IntVar*
const var = expr->Var();
6688 switch (
var->VarType()) {
6690 PlusCstVar*
const add_var =
reinterpret_cast<PlusCstVar*
>(
var);
6691 IntVar*
const sub_var = add_var->SubVar();
6692 const int64 new_constant =
value - add_var->Constant();
6693 if (new_constant == 0) {
6696 result = RegisterIntExpr(
6697 RevAlloc(
new SubCstIntVar(
this, sub_var, new_constant)));
6702 SubCstIntVar*
const add_var =
reinterpret_cast<SubCstIntVar*
>(
var);
6703 IntVar*
const sub_var = add_var->SubVar();
6704 const int64 new_constant =
value - add_var->Constant();
6705 result = MakeSum(sub_var, new_constant);
6709 OppIntVar*
const add_var =
reinterpret_cast<OppIntVar*
>(
var);
6710 IntVar*
const sub_var = add_var->SubVar();
6711 result = MakeSum(sub_var,
value);
6716 RegisterIntExpr(RevAlloc(
new SubCstIntVar(
this,
var,
value)));
6719 result = RegisterIntExpr(RevAlloc(
new SubIntCstExpr(
this, expr,
value)));
6721 Cache()->InsertExprConstantExpression(result, expr,
value,
6722 ModelCache::EXPR_CONSTANT_DIFFERENCE);
6727 IntExpr* Solver::MakeOpposite(IntExpr*
const expr) {
6728 CHECK_EQ(
this, expr->solver());
6729 if (expr->Bound()) {
6730 return MakeIntConst(-expr->Min());
6733 Cache()->FindExprExpression(expr, ModelCache::EXPR_OPPOSITE);
6734 if (result ==
nullptr) {
6735 if (expr->IsVar()) {
6736 result = RegisterIntVar(RevAlloc(
new OppIntExpr(
this, expr))->Var());
6738 result = RegisterIntExpr(RevAlloc(
new OppIntExpr(
this, expr)));
6740 Cache()->InsertExprExpression(result, expr, ModelCache::EXPR_OPPOSITE);
6745 IntExpr* Solver::MakeProd(IntExpr*
const expr,
int64 value) {
6746 CHECK_EQ(
this, expr->solver());
6747 IntExpr* result = Cache()->FindExprConstantExpression(
6748 expr,
value, ModelCache::EXPR_CONSTANT_PROD);
6749 if (result !=
nullptr) {
6752 IntExpr* m_expr =
nullptr;
6760 if (m_expr->Bound()) {
6765 return MakeOpposite(m_expr);
6769 result = RegisterIntExpr(
6770 RevAlloc(
new SafeTimesPosIntCstExpr(
this, m_expr,
coefficient)));
6772 result = RegisterIntExpr(
6773 RevAlloc(
new TimesPosIntCstExpr(
this, m_expr,
coefficient)));
6776 result = MakeIntConst(0);
6778 result = RegisterIntExpr(
6779 RevAlloc(
new TimesIntNegCstExpr(
this, m_expr,
coefficient)));
6781 if (m_expr->IsVar() && !FLAGS_cp_disable_expression_optimization) {
6782 result = result->Var();
6784 Cache()->InsertExprConstantExpression(result, expr,
value,
6785 ModelCache::EXPR_CONSTANT_PROD);
6791 void ExtractPower(IntExpr**
const expr,
int64*
const exponant) {
6792 if (
dynamic_cast<BasePower*
>(*expr) !=
nullptr) {
6793 BasePower*
const power =
dynamic_cast<BasePower*
>(*expr);
6794 *expr = power->expr();
6795 *exponant = power->exponant();
6797 if (
dynamic_cast<IntSquare*
>(*expr) !=
nullptr) {
6798 IntSquare*
const power =
dynamic_cast<IntSquare*
>(*expr);
6799 *expr = power->expr();
6802 if ((*expr)->IsVar()) {
6803 IntVar*
const var = (*expr)->Var();
6804 IntExpr*
const sub =
var->solver()->CastExpression(
var);
6805 if (sub !=
nullptr &&
dynamic_cast<BasePower*
>(sub) !=
nullptr) {
6806 BasePower*
const power =
dynamic_cast<BasePower*
>(sub);
6807 *expr = power->expr();
6808 *exponant = power->exponant();
6810 if (sub !=
nullptr &&
dynamic_cast<IntSquare*
>(sub) !=
nullptr) {
6811 IntSquare*
const power =
dynamic_cast<IntSquare*
>(sub);
6812 *expr = power->expr();
6820 if (
dynamic_cast<TimesCstIntVar*
>(*expr) !=
nullptr) {
6821 TimesCstIntVar*
const left_prod =
dynamic_cast<TimesCstIntVar*
>(*expr);
6823 *expr = left_prod->SubVar();
6825 }
else if (
dynamic_cast<TimesIntCstExpr*
>(*expr) !=
nullptr) {
6826 TimesIntCstExpr*
const left_prod =
dynamic_cast<TimesIntCstExpr*
>(*expr);
6828 *expr = left_prod->Expr();
6834 IntExpr* Solver::MakeProd(IntExpr*
const left, IntExpr*
const right) {
6835 if (left->Bound()) {
6836 return MakeProd(right, left->Min());
6839 if (right->Bound()) {
6840 return MakeProd(left, right->Min());
6845 IntExpr* m_left = left;
6846 IntExpr* m_right = right;
6847 int64 left_exponant = 1;
6848 int64 right_exponant = 1;
6849 ExtractPower(&m_left, &left_exponant);
6850 ExtractPower(&m_right, &right_exponant);
6852 if (m_left == m_right) {
6853 return MakePower(m_left, left_exponant + right_exponant);
6861 bool modified =
false;
6864 ExtractProduct(&m_right, &
coefficient, &modified);
6866 return MakeProd(MakeProd(m_left, m_right),
coefficient);
6871 CHECK_EQ(
this, left->solver());
6872 CHECK_EQ(
this, right->solver());
6873 IntExpr* result = model_cache_->FindExprExprExpression(
6874 left, right, ModelCache::EXPR_EXPR_PROD);
6875 if (result ==
nullptr) {
6876 result = model_cache_->FindExprExprExpression(right, left,
6877 ModelCache::EXPR_EXPR_PROD);
6879 if (result !=
nullptr) {
6882 if (left->IsVar() && left->Var()->VarType() ==
BOOLEAN_VAR) {
6883 if (right->Min() >= 0) {
6884 result = RegisterIntExpr(RevAlloc(
new TimesBooleanPosIntExpr(
6885 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6887 result = RegisterIntExpr(RevAlloc(
new TimesBooleanIntExpr(
6888 this,
reinterpret_cast<BooleanVar*
>(left), right)));
6890 }
else if (right->IsVar() &&
6891 reinterpret_cast<IntVar*
>(right)->VarType() ==
BOOLEAN_VAR) {
6892 if (left->Min() >= 0) {
6893 result = RegisterIntExpr(RevAlloc(
new TimesBooleanPosIntExpr(
6894 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6896 result = RegisterIntExpr(RevAlloc(
new TimesBooleanIntExpr(
6897 this,
reinterpret_cast<BooleanVar*
>(right), left)));
6899 }
else if (left->Min() >= 0 && right->Min() >= 0) {
6900 if (
CapProd(left->Max(), right->Max()) ==
6903 RegisterIntExpr(RevAlloc(
new SafeTimesPosIntExpr(
this, left, right)));
6906 RegisterIntExpr(RevAlloc(
new TimesPosIntExpr(
this, left, right)));
6909 result = RegisterIntExpr(RevAlloc(
new TimesIntExpr(
this, left, right)));
6911 model_cache_->InsertExprExprExpression(result, left, right,
6912 ModelCache::EXPR_EXPR_PROD);
6916 IntExpr* Solver::MakeDiv(IntExpr*
const numerator, IntExpr*
const denominator) {
6917 CHECK(numerator !=
nullptr);
6918 CHECK(denominator !=
nullptr);
6919 if (denominator->Bound()) {
6920 return MakeDiv(numerator, denominator->Min());
6922 IntExpr* result = model_cache_->FindExprExprExpression(
6923 numerator, denominator, ModelCache::EXPR_EXPR_DIV);
6924 if (result !=
nullptr) {
6928 if (denominator->Min() <= 0 && denominator->Max() >= 0) {
6929 AddConstraint(MakeNonEquality(denominator, 0));
6932 if (denominator->Min() >= 0) {
6933 if (numerator->Min() >= 0) {
6934 result = RevAlloc(
new DivPosPosIntExpr(
this, numerator, denominator));
6936 result = RevAlloc(
new DivPosIntExpr(
this, numerator, denominator));
6938 }
else if (denominator->Max() <= 0) {
6939 if (numerator->Max() <= 0) {
6940 result = RevAlloc(
new DivPosPosIntExpr(
this, MakeOpposite(numerator),
6941 MakeOpposite(denominator)));
6943 result = MakeOpposite(RevAlloc(
6944 new DivPosIntExpr(
this, numerator, MakeOpposite(denominator))));
6947 result = RevAlloc(
new DivIntExpr(
this, numerator, denominator));
6949 model_cache_->InsertExprExprExpression(result, numerator, denominator,
6950 ModelCache::EXPR_EXPR_DIV);
6954 IntExpr* Solver::MakeDiv(IntExpr*
const expr,
int64 value) {
6955 CHECK(expr !=
nullptr);
6956 CHECK_EQ(
this, expr->solver());
6957 if (expr->Bound()) {
6958 return MakeIntConst(expr->Min() /
value);
6959 }
else if (
value == 1) {
6961 }
else if (
value == -1) {
6962 return MakeOpposite(expr);
6963 }
else if (
value > 0) {
6964 return RegisterIntExpr(RevAlloc(
new DivPosIntCstExpr(
this, expr,
value)));
6965 }
else if (
value == 0) {
6966 LOG(FATAL) <<
"Cannot divide by 0";
6969 return RegisterIntExpr(
6970 MakeOpposite(RevAlloc(
new DivPosIntCstExpr(
this, expr, -
value))));
6975 Constraint* Solver::MakeAbsEquality(IntVar*
const var, IntVar*
const abs_var) {
6976 if (Cache()->FindExprExpression(
var, ModelCache::EXPR_ABS) ==
nullptr) {
6977 Cache()->InsertExprExpression(abs_var,
var, ModelCache::EXPR_ABS);
6979 return RevAlloc(
new IntAbsConstraint(
this,
var, abs_var));
6982 IntExpr* Solver::MakeAbs(IntExpr*
const e) {
6983 CHECK_EQ(
this, e->solver());
6984 if (e->Min() >= 0) {
6986 }
else if (e->Max() <= 0) {
6987 return MakeOpposite(e);
6989 IntExpr* result = Cache()->FindExprExpression(e, ModelCache::EXPR_ABS);
6990 if (result ==
nullptr) {
6992 IntExpr* expr =
nullptr;
6994 result = MakeProd(MakeAbs(expr), std::abs(
coefficient));
6996 result = RegisterIntExpr(RevAlloc(
new IntAbs(
this, e)));
6998 Cache()->InsertExprExpression(result, e, ModelCache::EXPR_ABS);
7003 IntExpr* Solver::MakeSquare(IntExpr*
const expr) {
7004 CHECK_EQ(
this, expr->solver());
7005 if (expr->Bound()) {
7006 const int64 v = expr->Min();
7007 return MakeIntConst(v * v);
7009 IntExpr* result = Cache()->FindExprExpression(expr, ModelCache::EXPR_SQUARE);
7010 if (result ==
nullptr) {
7011 if (expr->Min() >= 0) {
7012 result = RegisterIntExpr(RevAlloc(
new PosIntSquare(
this, expr)));
7014 result = RegisterIntExpr(RevAlloc(
new IntSquare(
this, expr)));
7016 Cache()->InsertExprExpression(result, expr, ModelCache::EXPR_SQUARE);
7021 IntExpr* Solver::MakePower(IntExpr*
const expr,
int64 n) {
7022 CHECK_EQ(
this, expr->solver());
7024 if (expr->Bound()) {
7025 const int64 v = expr->Min();
7026 if (v >= OverflowLimit(n)) {
7029 return MakeIntConst(IntPower(v, n));
7033 return MakeIntConst(1);
7037 return MakeSquare(expr);
7039 IntExpr* result =
nullptr;
7041 if (expr->Min() >= 0) {
7043 RegisterIntExpr(RevAlloc(
new PosIntEvenPower(
this, expr, n)));
7045 result = RegisterIntExpr(RevAlloc(
new IntEvenPower(
this, expr, n)));
7048 result = RegisterIntExpr(RevAlloc(
new IntOddPower(
this, expr, n)));
7055 IntExpr* Solver::MakeMin(IntExpr*
const left, IntExpr*
const right) {
7056 CHECK_EQ(
this, left->solver());
7057 CHECK_EQ(
this, right->solver());
7058 if (left->Bound()) {
7059 return MakeMin(right, left->Min());
7061 if (right->Bound()) {
7062 return MakeMin(left, right->Min());
7064 if (left->Min() >= right->Max()) {
7067 if (right->Min() >= left->Max()) {
7070 return RegisterIntExpr(RevAlloc(
new MinIntExpr(
this, left, right)));
7073 IntExpr* Solver::MakeMin(IntExpr*
const expr,
int64 value) {
7074 CHECK_EQ(
this, expr->solver());
7075 if (value <= expr->Min()) {
7076 return MakeIntConst(
value);
7078 if (expr->Bound()) {
7081 if (expr->Max() <=
value) {
7084 return RegisterIntExpr(RevAlloc(
new MinCstIntExpr(
this, expr,
value)));
7087 IntExpr* Solver::MakeMin(IntExpr*
const expr,
int value) {
7088 return MakeMin(expr,
static_cast<int64>(
value));
7091 IntExpr* Solver::MakeMax(IntExpr*
const left, IntExpr*
const right) {
7092 CHECK_EQ(
this, left->solver());
7093 CHECK_EQ(
this, right->solver());
7094 if (left->Bound()) {
7095 return MakeMax(right, left->Min());
7097 if (right->Bound()) {
7098 return MakeMax(left, right->Min());
7100 if (left->Min() >= right->Max()) {
7103 if (right->Min() >= left->Max()) {
7106 return RegisterIntExpr(RevAlloc(
new MaxIntExpr(
this, left, right)));
7109 IntExpr* Solver::MakeMax(IntExpr*
const expr,
int64 value) {
7110 CHECK_EQ(
this, expr->solver());
7111 if (expr->Bound()) {
7114 if (value <= expr->Min()) {
7117 if (expr->Max() <=
value) {
7118 return MakeIntConst(
value);
7120 return RegisterIntExpr(RevAlloc(
new MaxCstIntExpr(
this, expr,
value)));
7123 IntExpr* Solver::MakeMax(IntExpr*
const expr,
int value) {
7124 return MakeMax(expr,
static_cast<int64>(
value));
7127 IntExpr* Solver::MakeConvexPiecewiseExpr(IntExpr* expr,
int64 early_cost,
7130 return RegisterIntExpr(RevAlloc(
new SimpleConvexPiecewiseExpr(
7131 this, expr, early_cost, early_date, late_date, late_cost)));
7134 IntExpr* Solver::MakeSemiContinuousExpr(IntExpr*
const expr,
int64 fixed_charge,
7137 if (fixed_charge == 0) {
7138 return MakeIntConst(
int64{0});
7140 return RegisterIntExpr(
7141 RevAlloc(
new SemiContinuousStepZeroExpr(
this, expr, fixed_charge)));
7143 }
else if (step == 1) {
7144 return RegisterIntExpr(
7145 RevAlloc(
new SemiContinuousStepOneExpr(
this, expr, fixed_charge)));
7147 return RegisterIntExpr(
7148 RevAlloc(
new SemiContinuousExpr(
this, expr, fixed_charge, step)));
7163 return f_.GetMinimum(
expr_->Min(),
expr_->Max());
7167 f_.GetSmallestRangeGreaterThanValue(
expr_->Min(),
expr_->Max(), m);
7168 expr_->SetRange(range.first, range.second);
7172 return f_.GetMaximum(
expr_->Min(),
expr_->Max());
7177 f_.GetSmallestRangeLessThanValue(
expr_->Min(),
expr_->Max(), m);
7178 expr_->SetRange(range.first, range.second);
7183 f_.GetSmallestRangeInValueRange(
expr_->Min(),
expr_->Max(), l, u);
7184 expr_->SetRange(range.first, range.second);
7186 std::string
name()
const override {
7187 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)",
expr_->name(),
7192 return absl::StrFormat(
"PiecewiseLinear(%s, f = %s)",
expr_->DebugString(),
7198 void Accept(ModelVisitor*
const visitor)
const override {
7203 IntExpr*
const expr_;
7207 IntExpr* Solver::MakePiecewiseLinearExpr(IntExpr* expr,
7208 const PiecewiseLinearFunction& f) {
7209 return RegisterIntExpr(RevAlloc(
new PiecewiseLinearExpr(
this, expr, f)));
7214 IntExpr* Solver::MakeConditionalExpression(IntVar*
const condition,
7215 IntExpr*
const expr,
7216 int64 unperformed_value) {
7217 if (condition->Min() == 1) {
7219 }
else if (condition->Max() == 0) {
7220 return MakeIntConst(unperformed_value);
7222 IntExpr* cache = Cache()->FindExprExprConstantExpression(
7223 condition, expr, unperformed_value,
7224 ModelCache::EXPR_EXPR_CONSTANT_CONDITIONAL);
7225 if (cache ==
nullptr) {
7227 new ExprWithEscapeValue(
this, condition, expr, unperformed_value));
7228 Cache()->InsertExprExprConstantExpression(
7229 cache, condition, expr, unperformed_value,
7230 ModelCache::EXPR_EXPR_CONSTANT_CONDITIONAL);
7238 IntExpr* Solver::MakeModulo(IntExpr*
const x,
int64 mod) {
7239 IntVar*
const result =
7240 MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->Var();
7242 AddConstraint(MakeBetweenCt(result, 0, mod - 1));
7244 AddConstraint(MakeBetweenCt(result, mod + 1, 0));
7249 IntExpr* Solver::MakeModulo(IntExpr*
const x, IntExpr*
const mod) {
7251 return MakeModulo(x, mod->Min());
7253 IntVar*
const result =
7254 MakeDifference(x, MakeProd(MakeDiv(x, mod), mod))->Var();
7255 AddConstraint(MakeLess(result, MakeAbs(mod)));
7256 AddConstraint(MakeGreater(result, MakeOpposite(MakeAbs(mod))));
7262 int IntVar::VarType()
const {
return UNSPECIFIED; }
7264 void IntVar::RemoveValues(
const std::vector<int64>& values) {
7266 const int size = values.size();
7273 RemoveValue(values[0]);
7277 RemoveValue(values[0]);
7278 RemoveValue(values[1]);
7282 RemoveValue(values[0]);
7283 RemoveValue(values[1]);
7284 RemoveValue(values[2]);
7290 int start_index = 0;
7291 int64 new_min = Min();
7292 if (values[start_index] <= new_min) {
7293 while (start_index < size - 1 &&
7294 values[start_index + 1] == values[start_index] + 1) {
7295 new_min = values[start_index + 1] + 1;
7299 int end_index = size - 1;
7300 int64 new_max = Max();
7301 if (values[end_index] >= new_max) {
7302 while (end_index > start_index + 1 &&
7303 values[end_index - 1] == values[end_index] - 1) {
7304 new_max = values[end_index - 1] - 1;
7308 SetRange(new_min, new_max);
7309 for (
int i = start_index; i <= end_index; ++i) {
7310 RemoveValue(values[i]);
7316 void IntVar::Accept(ModelVisitor*
const visitor)
const {
7317 IntExpr*
const casted = solver()->CastExpression(
this);
7318 visitor->VisitIntegerVariable(
this, casted);
7321 void IntVar::SetValues(
const std::vector<int64>& values) {
7322 switch (values.size()) {
7328 SetValue(values.back());
7332 if (Contains(values[0])) {
7333 if (Contains(values[1])) {
7338 RemoveInterval(l + 1, u - 1);
7341 SetValue(values[0]);
7344 SetValue(values[1]);
7355 std::vector<int64>& tmp = solver()->tmp_vector_;
7357 tmp.insert(tmp.end(), values.begin(), values.end());
7358 std::sort(tmp.begin(), tmp.end());
7359 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
7360 const int size = tmp.size();
7361 const int64 vmin = Min();
7362 const int64 vmax = Max();
7364 int last = size - 1;
7365 if (tmp.front() > vmax || tmp.back() < vmin) {
7369 while (tmp[first] < vmin || !Contains(tmp[first])) {
7371 if (first > last || tmp[first] > vmax) {
7375 while (last > first && (tmp[last] > vmax || !Contains(tmp[last]))) {
7379 DCHECK_GE(last, first);
7380 SetRange(tmp[first], tmp[last]);
7381 while (first < last) {
7382 const int64 start = tmp[first] + 1;
7383 const int64 end = tmp[first + 1] - 1;
7385 RemoveInterval(start, end);
7395 if (!
var->Bound()) {
7397 DomainIntVar* dvar =
reinterpret_cast<DomainIntVar*
>(
var);
7398 s->AddCastConstraint(
7399 s->RevAlloc(
new LinkExprAndDomainIntVar(s, expr, dvar)), dvar, expr);
7401 s->AddCastConstraint(s->RevAlloc(
new LinkExprAndVar(s, expr,
var)),
var,
7407 IntVar* BaseIntExpr::Var() {
7408 if (var_ ==
nullptr) {
7409 solver()->SaveValue(
reinterpret_cast<void**
>(&var_));
7415 IntVar* BaseIntExpr::CastToVar() {
7417 Range(&vmin, &vmax);
7418 IntVar*
const var = solver()->MakeIntVar(vmin, vmax);
7424 bool Solver::IsADifference(IntExpr* expr, IntExpr**
const left,
7425 IntExpr**
const right) {
7426 if (expr->IsVar()) {
7427 IntVar*
const expr_var = expr->Var();
7428 expr = CastExpression(expr_var);
7432 SubIntExpr*
const sub_expr =
dynamic_cast<SubIntExpr*
>(expr);
7433 if (sub_expr !=
nullptr) {
7434 *left = sub_expr->left();
7435 *right = sub_expr->right();
7441 bool Solver::IsBooleanVar(IntExpr*
const expr, IntVar** inner_var,
7442 bool* is_negated)
const {
7443 if (expr->IsVar() && expr->Var()->VarType() ==
BOOLEAN_VAR) {
7444 *inner_var = expr->Var();
7445 *is_negated =
false;
7447 }
else if (expr->IsVar() && expr->Var()->VarType() ==
CST_SUB_VAR) {
7448 SubCstIntVar*
const sub_var =
reinterpret_cast<SubCstIntVar*
>(expr);
7449 if (sub_var !=
nullptr && sub_var->Constant() == 1 &&
7452 *inner_var = sub_var->SubVar();
7459 bool Solver::IsProduct(IntExpr*
const expr, IntExpr** inner_expr,
7461 if (
dynamic_cast<TimesCstIntVar*
>(expr) !=
nullptr) {
7462 TimesCstIntVar*
const var =
dynamic_cast<TimesCstIntVar*
>(expr);
7464 *inner_expr =
var->SubVar();
7466 }
else if (
dynamic_cast<TimesIntCstExpr*
>(expr) !=
nullptr) {
7467 TimesIntCstExpr*
const prod =
dynamic_cast<TimesIntCstExpr*
>(expr);
7469 *inner_expr = prod->Expr();
7477 #undef COND_REV_ALLOC