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