00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <math.h>
00015 #include <string.h>
00016 #include <algorithm>
00017 #include "base/hash.h"
00018 #include <string>
00019 #include <utility>
00020 #include <vector>
00021
00022 #include "base/commandlineflags.h"
00023 #include "base/integral_types.h"
00024 #include "base/logging.h"
00025 #include "base/scoped_ptr.h"
00026 #include "base/stringprintf.h"
00027 #include "base/map-util.h"
00028 #include "constraint_solver/constraint_solver.h"
00029 #include "constraint_solver/constraint_solveri.h"
00030 #include "util/bitset.h"
00031 #include "util/const_int_array.h"
00032
00033 DEFINE_bool(cp_disable_expression_optimization, false,
00034 "Disable special optimization when creating expressions.");
00035 DEFINE_bool(cp_share_int_consts, true,
00036 "Share IntConst's with the same value.");
00037
00038 #if defined(_MSC_VER)
00039 #pragma warning(disable : 4351 4355)
00040 #endif
00041
00042 namespace operations_research {
00043
00044
00045
00046 IntVar* IntExpr::VarWithName(const string& name) {
00047 IntVar* const var = Var();
00048 var->set_name(name);
00049 return var;
00050 }
00051
00052
00053
00054 IntVar::IntVar(Solver* const s) : IntExpr(s) {}
00055
00056 IntVar::IntVar(Solver* const s, const string& name) : IntExpr(s) {
00057 set_name(name);
00058 }
00059
00060 namespace {
00061 int64* NewUniqueSortedArray(const int64* const values, int* size) {
00062 int64* new_array = new int64[*size];
00063 memcpy(new_array, values, (*size) * sizeof(*values));
00064 std::sort(new_array, new_array + (*size));
00065 int non_unique = 0;
00066 for (int i = 0; i < (*size) - 1; ++i) {
00067 if (new_array[i] == new_array[i + 1]) {
00068 non_unique++;
00069 }
00070 }
00071 if (non_unique > 0) {
00072 scoped_array<int64> sorted(new_array);
00073 DCHECK_GT(*size, 0);
00074 new_array = new int64[(*size) - non_unique];
00075 new_array[0] = sorted[0];
00076 int pos = 1;
00077 for (int i = 1; i < (*size); ++i) {
00078 if (sorted[i] != sorted[i - 1]) {
00079 new_array[pos++] = sorted[i];
00080 }
00081 }
00082 DCHECK_EQ((*size) - non_unique, pos);
00083 *size = pos;
00084 }
00085 return new_array;
00086 }
00087
00088 bool IsArrayActuallySorted(const int64* const values, int size) {
00089 for (int i = 0; i < size - 1; ++i) {
00090 if (values[i + 1] < values[i]) {
00091 return false;
00092 }
00093 }
00094 return true;
00095 }
00096
00097
00098
00099
00100
00101 class DomainIntVar : public IntVar {
00102 public:
00103
00104 class BitSetIterator : public BaseObject {
00105 public:
00106 BitSetIterator(uint64* const bitset, int64 omin)
00107 : bitset_(bitset),
00108 omin_(omin),
00109 max_(kint64min),
00110 current_(kint64max) {}
00111
00112 ~BitSetIterator() {}
00113
00114 void Init(int64 min, int64 max) {
00115 max_ = max;
00116 current_ = min;
00117 }
00118
00119 bool Ok() const { return current_ <= max_; }
00120
00121 int64 Value() const { return current_; }
00122
00123 void Next() {
00124 if (++current_ <= max_) {
00125 current_ = UnsafeLeastSignificantBitPosition64(bitset_,
00126 current_ - omin_,
00127 max_ - omin_) + omin_;
00128 }
00129 }
00130
00131 private:
00132 uint64* const bitset_;
00133 const int64 omin_;
00134 int64 max_;
00135 int64 current_;
00136 };
00137
00138 class BitSet : public BaseObject {
00139 public:
00140 explicit BitSet(Solver* const s) : solver_(s), holes_stamp_(0) {}
00141 virtual ~BitSet() {}
00142
00143 virtual int64 ComputeNewMin(int64 nmin, int64 cmin, int64 cmax) = 0;
00144 virtual int64 ComputeNewMax(int64 nmax, int64 cmin, int64 cmax) = 0;
00145 virtual bool Contains(int64 val) const = 0;
00146 virtual bool SetValue(int64 val) = 0;
00147 virtual bool RemoveValue(int64 val) = 0;
00148 virtual uint64 Size() const = 0;
00149 virtual void DelayRemoveValue(int64 val) = 0;
00150 virtual void ApplyRemovedValues(DomainIntVar* var) = 0;
00151 virtual void ClearRemovedValues() = 0;
00152 virtual string pretty_DebugString(int64 min, int64 max) const = 0;
00153 virtual BitSetIterator* MakeIterator() = 0;
00154
00155 void InitHoles() {
00156 const uint64 current_stamp = solver_->stamp();
00157 if (holes_stamp_ < current_stamp) {
00158 holes_.clear();
00159 holes_stamp_ = current_stamp;
00160 }
00161 }
00162
00163 virtual void ClearHoles() {
00164 holes_.clear();
00165 }
00166
00167 const std::vector<int64>& Holes() {
00168 return holes_;
00169 }
00170
00171 void AddHole(int64 value) {
00172 holes_.push_back(value);
00173 }
00174
00175 protected:
00176 Solver* const solver_;
00177
00178 private:
00179 std::vector<int64> holes_;
00180 uint64 holes_stamp_;
00181 };
00182
00183 class QueueHandler : public Demon {
00184 public:
00185 explicit QueueHandler(DomainIntVar* const var) : var_(var) {}
00186 virtual ~QueueHandler() {}
00187 virtual void Run(Solver* const s) {
00188 var_->Process();
00189 }
00190 virtual Solver::DemonPriority priority() const {
00191 return Solver::VAR_PRIORITY;
00192 }
00193 virtual string DebugString() const {
00194 return StringPrintf("Handler(%s)", var_->DebugString().c_str());
00195 }
00196 private:
00197 DomainIntVar* const var_;
00198 };
00199
00200 DomainIntVar(Solver* const s,
00201 int64 vmin,
00202 int64 vmax,
00203 const string& name);
00204 DomainIntVar(Solver* const s,
00205 const std::vector<int64>& sorted_values,
00206 const string& name);
00207 virtual ~DomainIntVar();
00208
00209 virtual int64 Min() const {
00210 return min_.Value();
00211 }
00212 virtual void SetMin(int64 m);
00213 virtual int64 Max() const {
00214 return max_.Value();
00215 }
00216 virtual void SetMax(int64 m);
00217 virtual void SetRange(int64 l, int64 u);
00218 virtual void SetValue(int64 v);
00219 virtual bool Bound() const { return (min_.Value() == max_.Value()); }
00220 virtual int64 Value() const {
00221 CHECK_EQ(min_.Value(), max_.Value()) << "variable "
00222 << DebugString().c_str()
00223 << "is not bound.";
00224 return min_.Value();
00225 }
00226 virtual void RemoveValue(int64 v);
00227 virtual void RemoveInterval(int64 l, int64 u);
00228 void CreateBits();
00229 virtual void WhenBound(Demon* d) {
00230 if (min_.Value() != max_.Value()) {
00231 bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00232 }
00233 }
00234 virtual void WhenRange(Demon* d) {
00235 if (min_.Value() != max_.Value()) {
00236 range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00237 }
00238 }
00239 virtual void WhenDomain(Demon* d) {
00240 if (min_.Value() != max_.Value()) {
00241 domain_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00242 }
00243 }
00244
00245 void Process();
00246 void Push();
00247 void ClearInProcess();
00248 virtual uint64 Size() const {
00249 if (bits_ != NULL)
00250 return bits_->Size();
00251 return (max_.Value() - min_.Value() + 1);
00252 }
00253 virtual bool Contains(int64 v) const {
00254 if (v < min_.Value() || v > max_.Value())
00255 return false;
00256 return (bits_ == NULL ? true : bits_->Contains(v));
00257 }
00258 virtual IntVarIterator* MakeHoleIterator(bool reversible) const;
00259 virtual IntVarIterator* MakeDomainIterator(bool reversible) const;
00260 virtual int64 OldMin() const { return std::min(old_min_, min_.Value()); }
00261 virtual int64 OldMax() const { return std::max(old_max_, max_.Value()); }
00262
00263 virtual string DebugString() const;
00264 BitSet* bitset() const { return bits_; }
00265 virtual int VarType() const { return DOMAIN_INT_VAR; }
00266 virtual string BaseName() const { return "IntegerVar"; }
00267
00268 friend class PlusCstDomainIntVar;
00269 friend class LinkExprAndDomainIntVar;
00270 private:
00271 void CheckOldMin() {
00272 if (old_min_ > min_.Value()) {
00273 old_min_ = min_.Value();
00274 }
00275 }
00276 void CheckOldMax() {
00277 if (old_max_ < max_.Value()) {
00278 old_max_ = max_.Value();
00279 }
00280 }
00281 Rev<int64> min_;
00282 Rev<int64> max_;
00283 int64 old_min_;
00284 int64 old_max_;
00285 int64 new_min_;
00286 int64 new_max_;
00287 SimpleRevFIFO<Demon*> bound_demons_;
00288 SimpleRevFIFO<Demon*> range_demons_;
00289 SimpleRevFIFO<Demon*> domain_demons_;
00290 QueueHandler handler_;
00291 bool in_process_;
00292 BitSet* bits_;
00293 };
00294
00295
00296
00297 class SimpleBitSet : public DomainIntVar::BitSet {
00298 public:
00299 SimpleBitSet(Solver* const s, int64 vmin, int64 vmax)
00300 : BitSet(s),
00301 bits_(NULL),
00302 stamps_(NULL),
00303 omin_(vmin),
00304 omax_(vmax),
00305 size_(vmax - vmin + 1),
00306 bsize_(BitLength64(size_.Value())) {
00307 CHECK_LT(size_.Value(), 0xFFFFFFFF) << "Bitset too large";
00308 bits_ = new uint64[bsize_];
00309 stamps_ = new uint64[bsize_];
00310 for (int i = 0; i < bsize_; ++i) {
00311 const int bs = (i == size_.Value() - 1) ?
00312 63 - BitPos64(size_.Value()) :
00313 0;
00314 bits_[i] = kAllBits64 >> bs;
00315 stamps_[i] = s->stamp() - 1;
00316 }
00317 }
00318
00319 SimpleBitSet(Solver* const s,
00320 const std::vector<int64>& sorted_values,
00321 int64 vmin,
00322 int64 vmax)
00323 : BitSet(s),
00324 bits_(NULL),
00325 stamps_(NULL),
00326 omin_(vmin),
00327 omax_(vmax),
00328 size_(sorted_values.size()),
00329 bsize_(BitLength64(vmax - vmin + 1)) {
00330 CHECK_LT(size_.Value(), 0xFFFFFFFF) << "Bitset too large";
00331 bits_ = new uint64[bsize_];
00332 stamps_ = new uint64[bsize_];
00333 for (int i = 0; i < bsize_; ++i) {
00334 bits_[i] = GG_ULONGLONG(0);
00335 stamps_[i] = s->stamp() - 1;
00336 }
00337 for (int i = 0; i < sorted_values.size(); ++i) {
00338 const int64 val = sorted_values[i];
00339 DCHECK(!bit(val));
00340 const int offset = BitOffset64(val - omin_);
00341 const int pos = BitPos64(val - omin_);
00342 bits_[offset] |= OneBit64(pos);
00343 }
00344 }
00345
00346 virtual ~SimpleBitSet() {
00347 delete [] bits_;
00348 delete [] stamps_;
00349 }
00350
00351 bool bit(int64 val) const {
00352 return IsBitSet64(bits_, val - omin_);
00353 }
00354
00355 virtual int64 ComputeNewMin(int64 nmin, int64 cmin, int64 cmax) {
00356 DCHECK_GE(nmin, omin_);
00357 DCHECK_LE(nmin, omax_);
00358 DCHECK_LE(nmin, cmax);
00359 const int64 new_min =
00360 UnsafeLeastSignificantBitPosition64(bits_, nmin - omin_, cmax - omin_)
00361 + omin_;
00362 const uint64 removed_bits =
00363 BitCountRange64(bits_, cmin - omin_, new_min - omin_ - 1);
00364 size_.Add(solver_, -removed_bits);
00365 return new_min;
00366 }
00367
00368 virtual int64 ComputeNewMax(int64 nmax, int64 cmin, int64 cmax) {
00369 DCHECK_GE(nmax, omin_);
00370 DCHECK_LE(nmax, omax_);
00371 const int64 new_max =
00372 UnsafeMostSignificantBitPosition64(bits_, cmin - omin_, nmax - omin_)
00373 + omin_;
00374 const uint64 removed_bits =
00375 BitCountRange64(bits_, new_max - omin_ + 1, cmax - omin_);
00376 size_.Add(solver_, -removed_bits);
00377 return new_max;
00378 }
00379
00380 virtual bool SetValue(int64 val) {
00381 DCHECK_GE(val, omin_);
00382 DCHECK_LE(val, omax_);
00383 if (bit(val)) {
00384 size_.SetValue(solver_, 1);
00385 return true;
00386 }
00387 return false;
00388 }
00389
00390 virtual bool Contains(int64 val) const {
00391 DCHECK_GE(val, omin_);
00392 DCHECK_LE(val, omax_);
00393 return bit(val);
00394 }
00395
00396 virtual bool RemoveValue(int64 val) {
00397 if (val < omin_ || val > omax_ || !bit(val)) {
00398 return false;
00399 }
00400
00401 const int64 val_offset = val - omin_;
00402 const int offset = BitOffset64(val_offset);
00403 const uint64 current_stamp = solver_->stamp();
00404 if (stamps_[offset] < current_stamp) {
00405 stamps_[offset] = current_stamp;
00406 solver_->SaveValue(&bits_[offset]);
00407 }
00408 const int pos = BitPos64(val_offset);
00409 bits_[offset] &= ~OneBit64(pos);
00410
00411 size_.Decr(solver_);
00412
00413 InitHoles();
00414 AddHole(val);
00415 return true;
00416 }
00417 virtual uint64 Size() const {
00418 return size_.Value();
00419 }
00420
00421 virtual string DebugString() const {
00422 string out;
00423 SStringPrintf(&out, "SimpleBitSet(%" GG_LL_FORMAT
00424 "d..%" GG_LL_FORMAT "d : ", omin_, omax_);
00425 for (int i = 0; i < bsize_; ++i) {
00426 StringAppendF(&out, "%llx", bits_[i]);
00427 }
00428 out += ")";
00429 return out;
00430 }
00431
00432 virtual void DelayRemoveValue(int64 val) {
00433 removed_.push_back(val);
00434 }
00435
00436 virtual void ApplyRemovedValues(DomainIntVar* var) {
00437 sort(removed_.begin(), removed_.end());
00438 for (std::vector<int64>::iterator it = removed_.begin();
00439 it != removed_.end();
00440 ++it) {
00441 var->RemoveValue(*it);
00442 }
00443 }
00444
00445 virtual void ClearRemovedValues() {
00446 removed_.clear();
00447 }
00448
00449 virtual string pretty_DebugString(int64 min, int64 max) const {
00450 string out;
00451 DCHECK(bit(min));
00452 DCHECK(bit(max));
00453 if (max != min) {
00454 int cumul = true;
00455 int64 start_cumul = min;
00456 for (int64 v = min + 1; v < max; ++v) {
00457 if (bit(v)) {
00458 if (!cumul) {
00459 cumul = true;
00460 start_cumul = v;
00461 }
00462 } else {
00463 if (cumul) {
00464 if (v == start_cumul + 1) {
00465 StringAppendF(&out, "%" GG_LL_FORMAT "d ", start_cumul);
00466 } else if (v == start_cumul + 2) {
00467 StringAppendF(&out, "%" GG_LL_FORMAT
00468 "d %" GG_LL_FORMAT "d ", start_cumul, v - 1);
00469 } else {
00470 StringAppendF(&out, "%" GG_LL_FORMAT "d..%"
00471 GG_LL_FORMAT "d ", start_cumul, v - 1);
00472 }
00473 cumul = false;
00474 }
00475 }
00476 }
00477 if (cumul) {
00478 if (max == start_cumul + 1) {
00479 StringAppendF(&out, "%" GG_LL_FORMAT "d %"
00480 GG_LL_FORMAT "d", start_cumul, max);
00481 } else {
00482 StringAppendF(&out, "%" GG_LL_FORMAT "d..%"
00483 GG_LL_FORMAT "d", start_cumul, max);
00484 }
00485 } else {
00486 StringAppendF(&out, "%" GG_LL_FORMAT "d", max);
00487 }
00488 } else {
00489 StringAppendF(&out, "%" GG_LL_FORMAT "d", min);
00490 }
00491 return out;
00492 }
00493
00494 virtual DomainIntVar::BitSetIterator* MakeIterator() {
00495 return new DomainIntVar::BitSetIterator(bits_, omin_);
00496 }
00497
00498 private:
00499 uint64* bits_;
00500 uint64* stamps_;
00501 const int64 omin_;
00502 const int64 omax_;
00503 NumericalRev<int64> size_;
00504 const int bsize_;
00505 std::vector<int64> removed_;
00506 };
00507
00508
00509
00510 class SmallBitSet : public DomainIntVar::BitSet {
00511 public:
00512 SmallBitSet(Solver* const s, int64 vmin, int64 vmax)
00513 : BitSet(s),
00514 bits_(GG_ULONGLONG(0)),
00515 stamp_(s->stamp() - 1),
00516 omin_(vmin), omax_(vmax),
00517 size_(vmax - vmin + 1) {
00518 CHECK_LE(size_.Value(), 64) << "Bitset too large";
00519 bits_ = OneRange64(0, size_.Value() - 1);
00520 }
00521
00522 SmallBitSet(Solver* const s,
00523 const std::vector<int64>& sorted_values,
00524 int64 vmin,
00525 int64 vmax)
00526 : BitSet(s),
00527 bits_(GG_ULONGLONG(0)),
00528 stamp_(s->stamp() - 1),
00529 omin_(vmin),
00530 omax_(vmax),
00531 size_(sorted_values.size()) {
00532
00533 CHECK_LE(size_.Value(), 64) << "Bitset too large";
00534 for (int i = 0; i < sorted_values.size(); ++i) {
00535 const int64 val = sorted_values[i];
00536 DCHECK(!IsBitSet64(&bits_, val - omin_));
00537 bits_ |= OneBit64(val - omin_);
00538 }
00539 }
00540
00541 virtual ~SmallBitSet() {}
00542
00543 bool bit(int64 val) const {
00544 DCHECK_GE(val - omin_, 0);
00545 DCHECK_LT(val - omin_, 64);
00546 return (bits_ & OneBit64(val - omin_)) != 0;
00547 }
00548
00549 virtual int64 ComputeNewMin(int64 nmin, int64 cmin, int64 cmax) {
00550
00551
00552
00553
00554 const uint64 new_bits = bits_ & OneRange64(nmin - omin_, cmax - omin_);
00555 if (new_bits != GG_ULONGLONG(0)) {
00556
00557 size_.SetValue(solver_, BitCount64(new_bits));
00558 if (bit(nmin)) {
00559 return nmin;
00560 }
00561 return LeastSignificantBitPosition64(new_bits) + omin_;
00562 } else {
00563 solver_->Fail();
00564 return kint64max;
00565 }
00566 }
00567
00568 virtual int64 ComputeNewMax(int64 nmax, int64 cmin, int64 cmax) {
00569
00570
00571
00572
00573 const uint64 new_bits = bits_ & OneRange64(cmin - omin_, nmax - omin_);
00574 if (new_bits != GG_ULONGLONG(0)) {
00575
00576 size_.SetValue(solver_, BitCount64(new_bits));
00577 if (bit(nmax)) {
00578 return nmax;
00579 }
00580 return MostSignificantBitPosition64(new_bits) + omin_;
00581 } else {
00582 solver_->Fail();
00583 return kint64min;
00584 }
00585 }
00586
00587 virtual bool SetValue(int64 val) {
00588 DCHECK_GE(val, omin_);
00589 DCHECK_LE(val, omax_);
00590
00591
00592 if (bit(val)) {
00593 size_.SetValue(solver_, 1);
00594 return true;
00595 }
00596 return false;
00597 }
00598
00599 virtual bool Contains(int64 val) const {
00600 DCHECK_GE(val, omin_);
00601 DCHECK_LE(val, omax_);
00602 return bit(val);
00603 }
00604
00605 virtual bool RemoveValue(int64 val) {
00606 DCHECK_GE(val, omin_);
00607 DCHECK_LE(val, omax_);
00608 if (bit(val)) {
00609
00610 const uint64 current_stamp = solver_->stamp();
00611 if (stamp_ < current_stamp) {
00612 stamp_ = current_stamp;
00613 solver_->SaveValue(&bits_);
00614 }
00615 bits_ &= ~OneBit64(val - omin_);
00616 DCHECK(!bit(val));
00617
00618 size_.Decr(solver_);
00619
00620 InitHoles();
00621 AddHole(val);
00622 return true;
00623 } else {
00624 return false;
00625 }
00626 }
00627
00628 virtual uint64 Size() const {
00629 return size_.Value();
00630 }
00631
00632 virtual string DebugString() const {
00633 return StringPrintf("SmallBitSet(%" GG_LL_FORMAT
00634 "d..%" GG_LL_FORMAT "d : %llx)", omin_, omax_, bits_);
00635 }
00636
00637 virtual void DelayRemoveValue(int64 val) {
00638 DCHECK_GE(val, omin_);
00639 DCHECK_LE(val, omax_);
00640 removed_.push_back(val);
00641 }
00642
00643 virtual void ApplyRemovedValues(DomainIntVar* var) {
00644 sort(removed_.begin(), removed_.end());
00645 for (std::vector<int64>::iterator it = removed_.begin();
00646 it != removed_.end();
00647 ++it) {
00648 var->RemoveValue(*it);
00649 }
00650 }
00651
00652 virtual void ClearRemovedValues() {
00653 removed_.clear();
00654 }
00655
00656
00657 virtual string pretty_DebugString(int64 min, int64 max) const {
00658 string out;
00659 DCHECK(bit(min));
00660 DCHECK(bit(max));
00661 if (max != min) {
00662 int cumul = true;
00663 int64 start_cumul = min;
00664 for (int64 v = min + 1; v < max; ++v) {
00665 if (bit(v)) {
00666 if (!cumul) {
00667 cumul = true;
00668 start_cumul = v;
00669 }
00670 } else {
00671 if (cumul) {
00672 if (v == start_cumul + 1) {
00673 StringAppendF(&out, "%" GG_LL_FORMAT "d ", start_cumul);
00674 } else if (v == start_cumul + 2) {
00675 StringAppendF(&out, "%" GG_LL_FORMAT
00676 "d %" GG_LL_FORMAT "d ", start_cumul, v - 1);
00677 } else {
00678 StringAppendF(&out, "%" GG_LL_FORMAT "d..%"
00679 GG_LL_FORMAT "d ", start_cumul, v - 1);
00680 }
00681 cumul = false;
00682 }
00683 }
00684 }
00685 if (cumul) {
00686 if (max == start_cumul + 1) {
00687 StringAppendF(&out, "%" GG_LL_FORMAT "d %" GG_LL_FORMAT
00688 "d", start_cumul, max);
00689 } else {
00690 StringAppendF(&out, "%" GG_LL_FORMAT "d..%" GG_LL_FORMAT
00691 "d", start_cumul, max);
00692 }
00693 } else {
00694 StringAppendF(&out, "%" GG_LL_FORMAT "d", max);
00695 }
00696 } else {
00697 StringAppendF(&out, "%" GG_LL_FORMAT "d", min);
00698 }
00699 return out;
00700 }
00701
00702 virtual DomainIntVar::BitSetIterator* MakeIterator() {
00703 return new DomainIntVar::BitSetIterator(&bits_, omin_);
00704 }
00705
00706 private:
00707 uint64 bits_;
00708 uint64 stamp_;
00709 const int64 omin_;
00710 const int64 omax_;
00711 NumericalRev<int64> size_;
00712 std::vector<int64> removed_;
00713 };
00714
00715 class EmptyIterator : public IntVarIterator {
00716 public:
00717 virtual ~EmptyIterator() {}
00718 virtual void Init() {}
00719 virtual bool Ok() const { return false; }
00720 virtual int64 Value() const {
00721 LOG(FATAL) << "Should not be called";
00722 return 0LL;
00723 }
00724 virtual void Next() {}
00725 };
00726
00727 class RangeIterator : public IntVarIterator {
00728 public:
00729 explicit RangeIterator(const IntVar* const var)
00730 : var_(var), min_(kint64max), max_(kint64min), current_(-1) {}
00731
00732 virtual ~RangeIterator() {}
00733
00734 virtual void Init() {
00735 min_ = var_->Min();
00736 max_ = var_->Max();
00737 current_ = min_;
00738 }
00739
00740 virtual bool Ok() const { return current_ <= max_; }
00741
00742 virtual int64 Value() const { return current_; }
00743
00744 virtual void Next() { current_++; }
00745
00746 private:
00747 const IntVar* const var_;
00748 int64 min_;
00749 int64 max_;
00750 int64 current_;
00751 };
00752
00753 class DomainIntVarHoleIterator : public IntVarIterator {
00754 public:
00755 explicit DomainIntVarHoleIterator(const DomainIntVar* const v)
00756 : var_(v), bits_(NULL), values_(NULL), size_(0), index_(0) {}
00757
00758 ~DomainIntVarHoleIterator() {}
00759
00760 virtual void Init() {
00761 bits_ = var_->bitset();
00762 if (bits_ != 0) {
00763 bits_->InitHoles();
00764 values_ = bits_->Holes().data();
00765 size_ = bits_->Holes().size();
00766 } else {
00767 values_ = NULL;
00768 size_ = 0;
00769 }
00770 index_ = 0;
00771 }
00772
00773 virtual bool Ok() const {
00774 return index_ < size_;
00775 }
00776
00777 virtual int64 Value() const {
00778 DCHECK(bits_ != NULL);
00779 DCHECK(index_ < size_);
00780 return values_[index_];
00781 }
00782
00783 virtual void Next() {
00784 index_++;
00785 }
00786
00787 private:
00788 const DomainIntVar* const var_;
00789 DomainIntVar::BitSet* bits_;
00790 const int64* values_;
00791 int size_;
00792 int index_;
00793 };
00794
00795 class DomainIntVarDomainIterator : public IntVarIterator {
00796 public:
00797 explicit DomainIntVarDomainIterator(const DomainIntVar* const v,
00798 bool reversible)
00799 : var_(v),
00800 bitset_iterator_(NULL),
00801 min_(kint64max),
00802 max_(kint64min),
00803 current_(-1),
00804 reversible_(reversible) {}
00805
00806 virtual ~DomainIntVarDomainIterator() {
00807 if (!reversible_ && bitset_iterator_) {
00808 delete bitset_iterator_;
00809 }
00810 }
00811
00812 virtual void Init() {
00813 if (var_->bitset() != NULL && !var_->Bound()) {
00814 if (reversible_) {
00815 if (!bitset_iterator_) {
00816 Solver* const solver = var_->solver();
00817 solver->SaveValue(reinterpret_cast<void**>(&bitset_iterator_));
00818 bitset_iterator_ = solver->RevAlloc(var_->bitset()->MakeIterator());
00819 }
00820 } else {
00821 if (bitset_iterator_) {
00822 delete bitset_iterator_;
00823 }
00824 bitset_iterator_ = var_->bitset()->MakeIterator();
00825 }
00826 bitset_iterator_->Init(var_->Min(), var_->Max());
00827 } else {
00828 if (bitset_iterator_) {
00829 if (reversible_) {
00830 Solver* const solver = var_->solver();
00831 solver->SaveAndSetValue(reinterpret_cast<void**>(&bitset_iterator_),
00832 reinterpret_cast<void*>(NULL));
00833 } else {
00834 delete bitset_iterator_;
00835 bitset_iterator_ = NULL;
00836 }
00837 }
00838 min_ = var_->Min();
00839 max_ = var_->Max();
00840 current_ = min_;
00841 }
00842 }
00843
00844 virtual bool Ok() const {
00845 return bitset_iterator_ ? bitset_iterator_->Ok() : (current_ <= max_);
00846 }
00847
00848 virtual int64 Value() const {
00849 return bitset_iterator_ ? bitset_iterator_->Value() : current_;
00850 }
00851
00852 virtual void Next() {
00853 if (bitset_iterator_) {
00854 bitset_iterator_->Next();
00855 } else {
00856 current_++;
00857 }
00858 }
00859
00860 private:
00861 const DomainIntVar* const var_;
00862 DomainIntVar::BitSetIterator* bitset_iterator_;
00863 int64 min_;
00864 int64 max_;
00865 int64 current_;
00866 const bool reversible_;
00867 };
00868
00869 class UnaryIterator : public IntVarIterator {
00870 public:
00871 UnaryIterator(const IntVar* const v, bool hole, bool reversible)
00872 : iterator_(hole ?
00873 v->MakeHoleIterator(reversible) :
00874 v->MakeDomainIterator(reversible)),
00875 reversible_(reversible) {}
00876
00877 virtual ~UnaryIterator() {
00878 if (!reversible_) {
00879 delete iterator_;
00880 }
00881 }
00882
00883 virtual void Init() {
00884 iterator_->Init();
00885 }
00886
00887 virtual bool Ok() const {
00888 return iterator_->Ok();
00889 }
00890
00891 virtual void Next() {
00892 iterator_->Next();
00893 }
00894
00895 protected:
00896 IntVarIterator* const iterator_;
00897 const bool reversible_;
00898 };
00899
00900 DomainIntVar::DomainIntVar(Solver* const s,
00901 int64 vmin,
00902 int64 vmax,
00903 const string& name)
00904 : IntVar(s, name), min_(vmin), max_(vmax), old_min_(vmin),
00905 old_max_(vmax), new_min_(vmin), new_max_(vmax),
00906 handler_(this), in_process_(false), bits_(NULL) {}
00907
00908 DomainIntVar::DomainIntVar(Solver* const s,
00909 const std::vector<int64>& sorted_values,
00910 const string& name)
00911 : IntVar(s, name), min_(kint64max), max_(kint64min), old_min_(kint64max),
00912 old_max_(kint64min), new_min_(kint64max), new_max_(kint64min),
00913 handler_(this), in_process_(false), bits_(NULL) {
00914 CHECK_GE(sorted_values.size(), 1);
00915
00916 const int64 vmin = sorted_values.front();
00917 const int64 vmax = sorted_values.back();
00918 const bool contiguous = vmax - vmin + 1 == sorted_values.size();
00919
00920 min_.SetValue(solver(), vmin);
00921 old_min_ = vmin;
00922 new_min_ = vmin;
00923 max_.SetValue(solver(), vmax);
00924 old_max_ = vmax;
00925 new_max_ = vmax;
00926
00927 if (!contiguous) {
00928 if (vmax - vmin + 1 < 65) {
00929 bits_ = solver()->RevAlloc(new SmallBitSet(solver(),
00930 sorted_values,
00931 vmin,
00932 vmax));
00933 } else {
00934 bits_ = solver()->RevAlloc(new SimpleBitSet(solver(),
00935 sorted_values,
00936 vmin,
00937 vmax));
00938 }
00939 }
00940 }
00941
00942 DomainIntVar::~DomainIntVar() {}
00943
00944 void DomainIntVar::SetMin(int64 m) {
00945 if (m <= min_.Value())
00946 return;
00947 if (m > max_.Value())
00948 solver()->Fail();
00949 if (in_process_) {
00950 if (m > new_min_) {
00951 new_min_ = m;
00952 if (new_min_ > new_max_) {
00953 solver()->Fail();
00954 }
00955 }
00956 } else {
00957 CheckOldMin();
00958 const int64 new_min = (bits_ == NULL ?
00959 m :
00960 bits_->ComputeNewMin(m, min_.Value(), max_.Value()));
00961 min_.SetValue(solver(), new_min);
00962 if (min_.Value() > max_.Value()) {
00963 solver()->Fail();
00964 }
00965 Push();
00966 }
00967 }
00968
00969 void DomainIntVar::SetMax(int64 m) {
00970 if (m >= max_.Value())
00971 return;
00972 if (m < min_.Value())
00973 solver()->Fail();
00974 if (in_process_) {
00975 if (m < new_max_) {
00976 new_max_ = m;
00977 if (new_max_ < new_min_) {
00978 solver()->Fail();
00979 }
00980 }
00981 } else {
00982 CheckOldMax();
00983 const int64 new_max = (bits_ == NULL ?
00984 m :
00985 bits_->ComputeNewMax(m, min_.Value(), max_.Value()));
00986 max_.SetValue(solver(), new_max);
00987 if (min_.Value() > max_.Value()) {
00988 solver()->Fail();
00989 }
00990 Push();
00991 }
00992 }
00993
00994 void DomainIntVar::SetRange(int64 mi, int64 ma) {
00995 if (mi == ma) {
00996 SetValue(mi);
00997 } else {
00998 if (mi > ma || mi > max_.Value() || ma < min_.Value())
00999 solver()->Fail();
01000 if (mi <= min_.Value() && ma >= max_.Value())
01001 return;
01002 if (in_process_) {
01003 if (ma < new_max_) {
01004 new_max_ = ma;
01005 }
01006 if (mi > new_min_) {
01007 new_min_ = mi;
01008 }
01009 if (new_min_ > new_max_) {
01010 solver()->Fail();
01011 }
01012 } else {
01013 if (mi > min_.Value()) {
01014 CheckOldMin();
01015 const int64 new_min = (bits_ == NULL ?
01016 mi :
01017 bits_->ComputeNewMin(mi,
01018 min_.Value(),
01019 max_.Value()));
01020 min_.SetValue(solver(), new_min);
01021 }
01022 if (min_.Value() > ma) {
01023 solver()->Fail();
01024 }
01025 if (ma < max_.Value()) {
01026 CheckOldMax();
01027 const int64 new_max = (bits_ == NULL ?
01028 ma :
01029 bits_->ComputeNewMax(ma,
01030 min_.Value(),
01031 max_.Value()));
01032 max_.SetValue(solver(), new_max);
01033 }
01034 if (min_.Value() > max_.Value()) {
01035 solver()->Fail();
01036 }
01037 Push();
01038 }
01039 }
01040 }
01041
01042 void DomainIntVar::SetValue(int64 v) {
01043 if (v != min_.Value() || v != max_.Value()) {
01044 if (v < min_.Value() || v > max_.Value()) {
01045 solver()->Fail();
01046 }
01047 if (in_process_) {
01048 if (v > new_max_ || v < new_min_) {
01049 solver()->Fail();
01050 }
01051 new_min_ = v;
01052 new_max_ = v;
01053 } else {
01054 if (bits_ && !bits_->SetValue(v)) {
01055 solver()->Fail();
01056 }
01057 CheckOldMin();
01058 CheckOldMax();
01059 min_.SetValue(solver(), v);
01060 max_.SetValue(solver(), v);
01061 Push();
01062 }
01063 }
01064 }
01065
01066 void DomainIntVar::RemoveValue(int64 v) {
01067 if (v < min_.Value() || v > max_.Value())
01068 return;
01069 if (v == min_.Value()) {
01070 SetMin(v + 1);
01071 } else if (v == max_.Value()) {
01072 SetMax(v - 1);
01073 } else {
01074 if (bits_ == NULL) {
01075 CreateBits();
01076 }
01077 if (in_process_) {
01078 if (v >= new_min_ && v <= new_max_ && bits_->Contains(v)) {
01079 bits_->DelayRemoveValue(v);
01080 }
01081 } else {
01082 if (bits_->RemoveValue(v)) {
01083 Push();
01084 }
01085 }
01086 }
01087 }
01088
01089 void DomainIntVar::RemoveInterval(int64 l, int64 u) {
01090 if (l <= min_.Value()) {
01091 SetMin(u + 1);
01092 } else if (u >= max_.Value()) {
01093 SetMax(l - 1);
01094 } else {
01095 for (int64 v = l; v <= u; ++v) {
01096 RemoveValue(v);
01097 }
01098 }
01099 }
01100
01101 void DomainIntVar::CreateBits() {
01102 solver()->SaveValue(reinterpret_cast<void**>(&bits_));
01103 if (max_.Value() - min_.Value() < 64) {
01104 bits_ = solver()->RevAlloc(
01105 new SmallBitSet(solver(), min_.Value(), max_.Value()));
01106 } else {
01107 bits_ = solver()->RevAlloc(
01108 new SimpleBitSet(solver(), min_.Value(), max_.Value()));
01109 }
01110 }
01111
01112 void DomainIntVar::ClearInProcess() {
01113 in_process_ = false;
01114 if (bits_ != NULL) {
01115 bits_->ClearHoles();
01116 }
01117 }
01118
01119 void DomainIntVar::Push() {
01120 const bool in_process = in_process_;
01121 Enqueue(&handler_);
01122 CHECK_EQ(in_process, in_process_);
01123 }
01124
01125 void DomainIntVar::Process() {
01126 CHECK(!in_process_);
01127 in_process_ = true;
01128 if (bits_ != NULL) {
01129 bits_->ClearRemovedValues();
01130 }
01131 SetQueueCleanerOnFail(solver(), this);
01132 new_min_ = min_.Value();
01133 new_max_ = max_.Value();
01134 if (min_.Value() == max_.Value()) {
01135 for (SimpleRevFIFO<Demon*>::Iterator it(&bound_demons_); it.ok(); ++it) {
01136 Enqueue(*it);
01137 }
01138 }
01139 if (min_.Value() != OldMin() || max_.Value() != OldMax()) {
01140 for (SimpleRevFIFO<Demon*>::Iterator it(&range_demons_); it.ok(); ++it) {
01141 Enqueue(*it);
01142 }
01143 }
01144 for (SimpleRevFIFO<Demon*>::Iterator it(&domain_demons_); it.ok(); ++it) {
01145 Enqueue(*it);
01146 }
01147 ProcessDemonsOnQueue();
01148 clear_queue_action_on_fail();
01149 ClearInProcess();
01150 old_min_ = min_.Value();
01151 old_max_ = max_.Value();
01152 if (min_.Value() < new_min_) {
01153 SetMin(new_min_);
01154 }
01155 if (max_.Value() > new_max_) {
01156 SetMax(new_max_);
01157 }
01158 if (bits_ != NULL) {
01159 bits_->ApplyRemovedValues(this);
01160 }
01161 }
01162
01163 #define COND_REV_ALLOC(rev, alloc) \
01164 rev ? solver()->RevAlloc(alloc) : alloc;
01165
01166 IntVarIterator* DomainIntVar::MakeHoleIterator(bool reversible) const {
01167 return COND_REV_ALLOC(reversible, new DomainIntVarHoleIterator(this));
01168 }
01169
01170 IntVarIterator* DomainIntVar::MakeDomainIterator(bool reversible) const {
01171 return COND_REV_ALLOC(reversible,
01172 new DomainIntVarDomainIterator(this, reversible));
01173 }
01174
01175 string DomainIntVar::DebugString() const {
01176 string out;
01177 const string& var_name = name();
01178 if (!var_name.empty()) {
01179 out = var_name + "(";
01180 } else {
01181 out = "DomainIntVar(";
01182 }
01183 if (min_.Value() == max_.Value()) {
01184 StringAppendF(&out, "%" GG_LL_FORMAT "d", min_.Value());
01185 } else if (bits_ != NULL) {
01186 StringAppendF(&out,
01187 "%s",
01188 bits_->pretty_DebugString(min_.Value(),
01189 max_.Value()).c_str());
01190 } else {
01191 StringAppendF(&out,
01192 "%" GG_LL_FORMAT "d..%" GG_LL_FORMAT "d",
01193 min_.Value(),
01194 max_.Value());
01195 }
01196 out += ")";
01197 return out;
01198 }
01199
01200
01201
01202 static const int kUnboundBooleanVarValue = 2;
01203
01204 class BooleanVar : public IntVar {
01205 public:
01206
01207 class Handler : public Demon {
01208 public:
01209 explicit Handler(BooleanVar* const var) : Demon(), var_(var) {}
01210 virtual ~Handler() {}
01211 virtual void Run(Solver* const s) {
01212 var_->Process();
01213 }
01214 virtual Solver::DemonPriority priority() const {
01215 return Solver::VAR_PRIORITY;
01216 }
01217 virtual string DebugString() const {
01218 return StringPrintf("Handler(%s)", var_->DebugString().c_str());
01219 }
01220 private:
01221 BooleanVar* const var_;
01222 };
01223
01224 BooleanVar(Solver* const s, const string& name = "")
01225 : IntVar(s, name), value_(kUnboundBooleanVarValue), handler_(this) {
01226 }
01227 virtual ~BooleanVar() {}
01228
01229 virtual int64 Min() const {
01230 return (value_ == 1);
01231 }
01232 virtual void SetMin(int64 m);
01233 virtual int64 Max() const {
01234 return (value_ != 0);
01235 }
01236 virtual void SetMax(int64 m);
01237 virtual void SetRange(int64 l, int64 u);
01238 virtual void SetValue(int64 v);
01239 virtual bool Bound() const { return (value_ != kUnboundBooleanVarValue); }
01240 virtual int64 Value() const {
01241 CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
01242 return value_;
01243 }
01244 virtual void RemoveValue(int64 v);
01245 virtual void RemoveInterval(int64 l, int64 u);
01246 virtual void WhenBound(Demon* d) {
01247 if (value_ == kUnboundBooleanVarValue) {
01248 bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
01249 }
01250 }
01251 virtual void WhenRange(Demon* d) {
01252 if (value_ == kUnboundBooleanVarValue) {
01253 bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
01254 }
01255 }
01256 virtual void WhenDomain(Demon* d) {
01257 if (value_ == kUnboundBooleanVarValue) {
01258 bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
01259 }
01260 }
01261 void Process();
01262 void Push() {
01263 Enqueue(&handler_);
01264 }
01265 virtual uint64 Size() const {
01266 return (1 + (value_ == kUnboundBooleanVarValue));
01267 }
01268 virtual bool Contains(int64 v) const {
01269 return ((v == 0 && value_ != 1) || (v == 1 && value_ != 0));
01270 }
01271 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
01272 return COND_REV_ALLOC(reversible, new EmptyIterator());
01273 }
01274 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
01275 return COND_REV_ALLOC(reversible, new RangeIterator(this));
01276 }
01277 virtual int64 OldMin() const {
01278 return 0LL;
01279 }
01280 virtual int64 OldMax() const {
01281 return 1LL;
01282 }
01283 virtual string DebugString() const;
01284 virtual int VarType() const { return BOOLEAN_VAR; }
01285
01286 void RestoreValue() { value_ = kUnboundBooleanVarValue; }
01287
01288 virtual string BaseName() const { return "BooleanVar"; }
01289
01290 friend class TimesBooleanPosIntExpr;
01291 friend class TimesBooleanIntExpr;
01292 friend class TimesPosCstBoolVar;
01293
01294 private:
01295 int value_;
01296 SimpleRevFIFO<Demon*> bound_demons_;
01297 Handler handler_;
01298 };
01299
01300 void BooleanVar::SetMin(int64 m) {
01301 if (m <= 0) {
01302 return;
01303 }
01304 if (m > 1)
01305 solver()->Fail();
01306 SetValue(1);
01307 }
01308
01309 void BooleanVar::SetMax(int64 m) {
01310 if (m >= 1) {
01311 return;
01312 }
01313 if (m < 0) {
01314 solver()->Fail();
01315 }
01316 SetValue(0);
01317 }
01318
01319 void BooleanVar::SetRange(int64 mi, int64 ma) {
01320 if (mi > 1 || ma < 0 || mi > ma) {
01321 solver()->Fail();
01322 }
01323 if (mi == 1) {
01324 SetValue(1);
01325 } else if (ma == 0) {
01326 SetValue(0);
01327 }
01328 }
01329
01330 void BooleanVar::SetValue(int64 v) {
01331 if (value_ == kUnboundBooleanVarValue) {
01332 if (v == 0 || v == 1) {
01333 InternalSaveBooleanVarValue(solver(), this);
01334 value_ = static_cast<int>(v);
01335 Push();
01336 return;
01337 }
01338 } else if (v == value_) {
01339 return;
01340 }
01341 solver()->Fail();
01342 }
01343
01344 void BooleanVar::RemoveValue(int64 v) {
01345 if (value_ == kUnboundBooleanVarValue) {
01346 if (v == 0) {
01347 SetValue(1);
01348 } else if (v == 1) {
01349 SetValue(0);
01350 }
01351 } else if (v == value_) {
01352 solver()->Fail();
01353 }
01354 }
01355
01356 void BooleanVar::RemoveInterval(int64 l, int64 u) {
01357 if (l <= 0 && u >= 1) {
01358 solver()->Fail();
01359 } else if (l == 1) {
01360 SetValue(0);
01361 } else if (u == 0) {
01362 SetValue(1);
01363 }
01364 }
01365
01366 void BooleanVar::Process() {
01367 DCHECK_NE(value_, kUnboundBooleanVarValue);
01368 for (SimpleRevFIFO<Demon*>::Iterator it(&bound_demons_); it.ok(); ++it) {
01369 Enqueue(*it);
01370 }
01371 }
01372
01373 string BooleanVar::DebugString() const {
01374 string out;
01375 const string& var_name = name();
01376 if (!var_name.empty()) {
01377 out = var_name + "(";
01378 } else {
01379 out = "BooleanVar(";
01380 }
01381 switch (value_) {
01382 case 0:
01383 out += "0";
01384 break;
01385 case 1:
01386 out += "1";
01387 break;
01388 case kUnboundBooleanVarValue:
01389 out += "0 .. 1";
01390 break;
01391 }
01392 out += ")";
01393 return out;
01394 }
01395
01396
01397
01398 class IntConst : public IntVar {
01399 public:
01400 IntConst(Solver* const s, int64 value, const string& name = "")
01401 : IntVar(s, name), value_(value) {}
01402 virtual ~IntConst() {}
01403
01404 virtual int64 Min() const {
01405 return value_;
01406 }
01407 virtual void SetMin(int64 m) {
01408 if (m > value_) {
01409 solver()->Fail();
01410 }
01411 }
01412 virtual int64 Max() const {
01413 return value_;
01414 }
01415 virtual void SetMax(int64 m) {
01416 if (m < value_) {
01417 solver()->Fail();
01418 }
01419 }
01420 virtual void SetRange(int64 l, int64 u) {
01421 if (l > value_ || u < value_) {
01422 solver()->Fail();
01423 }
01424 }
01425 virtual void SetValue(int64 v) {
01426 if (v != value_) {
01427 solver()->Fail();
01428 }
01429 }
01430 virtual bool Bound() const { return true; }
01431 virtual int64 Value() const {
01432 return value_;
01433 }
01434 virtual void RemoveValue(int64 v) {
01435 if (v == value_) {
01436 solver()->Fail();
01437 }
01438 }
01439 virtual void RemoveInterval(int64 l, int64 u) {
01440 if (l <= value_ && value_ <= u) {
01441 solver()->Fail();
01442 }
01443 }
01444 virtual void WhenBound(Demon* d) {}
01445 virtual void WhenRange(Demon* d) {}
01446 virtual void WhenDomain(Demon* d) {}
01447 virtual uint64 Size() const {
01448 return 1;
01449 }
01450 virtual bool Contains(int64 v) const {
01451 return (v == value_);
01452 }
01453 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
01454 return COND_REV_ALLOC(reversible, new EmptyIterator());
01455 }
01456 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
01457 return COND_REV_ALLOC(reversible, new RangeIterator(this));
01458 }
01459 virtual int64 OldMin() const {
01460 return value_;
01461 }
01462 virtual int64 OldMax() const {
01463 return value_;
01464 }
01465 virtual string DebugString() const;
01466 virtual int VarType() const { return CONST_VAR; }
01467
01468 private:
01469 int64 value_;
01470 };
01471
01472 string IntConst::DebugString() const {
01473 string out;
01474 const string& var_name = name();
01475 if (!var_name.empty()) {
01476 SStringPrintf(&out, "%s(%" GG_LL_FORMAT "d)", var_name.c_str(), value_);
01477 } else {
01478 SStringPrintf(&out, "IntConst(%" GG_LL_FORMAT "d)", value_);
01479 }
01480 return out;
01481 }
01482
01483
01484
01485 class PlusCstIntVar : public IntVar {
01486 public:
01487 class PlusCstIntVarIterator : public UnaryIterator {
01488 public:
01489 PlusCstIntVarIterator(const IntVar* const v, int64 c, bool hole, bool rev)
01490 : UnaryIterator(v, hole, rev), cst_(c) {}
01491
01492 virtual ~PlusCstIntVarIterator() {}
01493
01494 virtual int64 Value() const {
01495 return iterator_->Value() + cst_;
01496 }
01497
01498 private:
01499 const int64 cst_;
01500 };
01501 PlusCstIntVar(Solver* const s, IntVar* v, int64 c);
01502 virtual ~PlusCstIntVar();
01503
01504 virtual int64 Min() const;
01505 virtual void SetMin(int64 m);
01506 virtual int64 Max() const;
01507 virtual void SetMax(int64 m);
01508 virtual void SetRange(int64 l, int64 u);
01509 virtual void SetValue(int64 v);
01510 virtual bool Bound() const;
01511 virtual int64 Value() const;
01512 virtual void RemoveValue(int64 v);
01513 virtual void RemoveInterval(int64 l, int64 u);
01514 virtual uint64 Size() const;
01515 virtual bool Contains(int64 v) const;
01516 virtual void WhenRange(Demon* d);
01517 virtual void WhenBound(Demon* d);
01518 virtual void WhenDomain(Demon* d);
01519 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
01520 return COND_REV_ALLOC(reversible,
01521 new PlusCstIntVarIterator(var_, cst_,
01522 true, reversible));
01523 }
01524 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
01525 return COND_REV_ALLOC(reversible,
01526 new PlusCstIntVarIterator(var_, cst_,
01527 false, reversible));
01528 }
01529 virtual int64 OldMin() const {
01530 return var_->OldMin() + cst_;
01531 }
01532 virtual int64 OldMax() const {
01533 return var_->OldMax() + cst_;
01534 }
01535
01536 virtual string DebugString() const;
01537 virtual int VarType() const { return VAR_ADD_CST; }
01538
01539 virtual void Accept(ModelVisitor* const visitor) const {
01540 visitor->VisitIntegerVariable(this,
01541 ModelVisitor::kSumOperation,
01542 cst_,
01543 var_);
01544 }
01545
01546 private:
01547 IntVar* const var_;
01548 const int64 cst_;
01549 };
01550
01551 PlusCstIntVar::PlusCstIntVar(Solver* const s, IntVar* v, int64 c)
01552 : IntVar(s), var_(v), cst_(c) {}
01553 PlusCstIntVar::~PlusCstIntVar() {}
01554
01555 int64 PlusCstIntVar::Min() const {
01556 return var_->Min() + cst_;
01557 }
01558
01559 void PlusCstIntVar::SetMin(int64 m) {
01560 var_->SetMin(m - cst_);
01561 }
01562
01563 int64 PlusCstIntVar::Max() const {
01564 return var_->Max() + cst_;
01565 }
01566
01567 void PlusCstIntVar::SetMax(int64 m) {
01568 var_->SetMax(m - cst_);
01569 }
01570
01571 void PlusCstIntVar::SetRange(int64 l, int64 u) {
01572 var_->SetRange(l - cst_, u - cst_);
01573 }
01574
01575 void PlusCstIntVar::SetValue(int64 v) {
01576 var_->SetValue(v - cst_);
01577 }
01578 bool PlusCstIntVar::Bound() const {
01579 return var_->Bound();
01580 }
01581
01582 void PlusCstIntVar::WhenRange(Demon* d) {
01583 var_->WhenRange(d);
01584 }
01585
01586 int64 PlusCstIntVar::Value() const {
01587 return var_->Value() + cst_;
01588 }
01589
01590 void PlusCstIntVar::RemoveValue(int64 v) {
01591 var_->RemoveValue(v - cst_);
01592 }
01593
01594 void PlusCstIntVar::RemoveInterval(int64 l, int64 u) {
01595 var_->RemoveInterval(l - cst_, u - cst_);
01596 }
01597
01598 void PlusCstIntVar::WhenBound(Demon* d) {
01599 var_->WhenBound(d);
01600 }
01601
01602 void PlusCstIntVar::WhenDomain(Demon* d) {
01603 var_->WhenDomain(d);
01604 }
01605
01606 uint64 PlusCstIntVar::Size() const {
01607 return var_->Size();
01608 }
01609
01610 bool PlusCstIntVar::Contains(int64 v) const {
01611 return var_->Contains(v - cst_);
01612 }
01613
01614 string PlusCstIntVar::DebugString() const {
01615 return StringPrintf("(%s + %" GG_LL_FORMAT "d)",
01616 var_->DebugString().c_str(), cst_);
01617 }
01618
01619 class PlusCstDomainIntVar : public IntVar {
01620 public:
01621 class PlusCstDomainIntVarIterator : public UnaryIterator {
01622 public:
01623 PlusCstDomainIntVarIterator(const IntVar* const v,
01624 int64 c,
01625 bool hole,
01626 bool reversible)
01627 : UnaryIterator(v, hole, reversible), cst_(c) {}
01628
01629 virtual ~PlusCstDomainIntVarIterator() {}
01630
01631 virtual int64 Value() const {
01632 return iterator_->Value() + cst_;
01633 }
01634
01635 private:
01636 const int64 cst_;
01637 };
01638 PlusCstDomainIntVar(Solver* const s, DomainIntVar* v, int64 c);
01639 virtual ~PlusCstDomainIntVar();
01640
01641 virtual int64 Min() const;
01642 virtual void SetMin(int64 m);
01643 virtual int64 Max() const;
01644 virtual void SetMax(int64 m);
01645 virtual void SetRange(int64 l, int64 u);
01646 virtual void SetValue(int64 v);
01647 virtual bool Bound() const;
01648 virtual int64 Value() const;
01649 virtual void RemoveValue(int64 v);
01650 virtual void RemoveInterval(int64 l, int64 u);
01651 virtual uint64 Size() const;
01652 virtual bool Contains(int64 v) const;
01653 virtual void WhenRange(Demon* d);
01654 virtual void WhenBound(Demon* d);
01655 virtual void WhenDomain(Demon* d);
01656 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
01657 return COND_REV_ALLOC(reversible,
01658 new PlusCstDomainIntVarIterator(var_, cst_,
01659 true, reversible));
01660 }
01661 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
01662 return COND_REV_ALLOC(reversible,
01663 new PlusCstDomainIntVarIterator(var_, cst_,
01664 false, reversible));
01665 }
01666 virtual int64 OldMin() const {
01667 return var_->OldMin() + cst_;
01668 }
01669 virtual int64 OldMax() const {
01670 return var_->OldMax() + cst_;
01671 }
01672
01673 virtual string DebugString() const;
01674 virtual int VarType() const { return DOMAIN_INT_VAR_ADD_CST; }
01675
01676 virtual void Accept(ModelVisitor* const visitor) const {
01677 visitor->VisitIntegerVariable(this,
01678 ModelVisitor::kSumOperation,
01679 cst_,
01680 var_);
01681 }
01682
01683 private:
01684 DomainIntVar* const var_;
01685 const int64 cst_;
01686 };
01687
01688 PlusCstDomainIntVar::PlusCstDomainIntVar(Solver* const s,
01689 DomainIntVar* v,
01690 int64 c)
01691 : IntVar(s), var_(v), cst_(c) {}
01692 PlusCstDomainIntVar::~PlusCstDomainIntVar() {}
01693
01694 int64 PlusCstDomainIntVar::Min() const {
01695 return var_->min_.Value() + cst_;
01696 }
01697
01698 void PlusCstDomainIntVar::SetMin(int64 m) {
01699 var_->DomainIntVar::SetMin(m - cst_);
01700 }
01701
01702 int64 PlusCstDomainIntVar::Max() const {
01703 return var_->max_.Value() + cst_;
01704 }
01705
01706 void PlusCstDomainIntVar::SetMax(int64 m) {
01707 var_->DomainIntVar::SetMax(m - cst_);
01708 }
01709
01710 void PlusCstDomainIntVar::SetRange(int64 l, int64 u) {
01711 var_->DomainIntVar::SetRange(l - cst_, u - cst_);
01712 }
01713
01714 void PlusCstDomainIntVar::SetValue(int64 v) {
01715 var_->DomainIntVar::SetValue(v - cst_);
01716 }
01717
01718 bool PlusCstDomainIntVar::Bound() const {
01719 return var_->min_.Value() == var_->max_.Value();
01720 }
01721
01722 void PlusCstDomainIntVar::WhenRange(Demon* d) {
01723 var_->WhenRange(d);
01724 }
01725
01726 int64 PlusCstDomainIntVar::Value() const {
01727 CHECK_EQ(var_->min_.Value(), var_->max_.Value()) << "variable is not bound";
01728 return var_->min_.Value() + cst_;
01729 }
01730
01731 void PlusCstDomainIntVar::RemoveValue(int64 v) {
01732 var_->DomainIntVar::RemoveValue(v - cst_);
01733 }
01734
01735 void PlusCstDomainIntVar::RemoveInterval(int64 l, int64 u) {
01736 var_->DomainIntVar::RemoveInterval(l - cst_, u - cst_);
01737 }
01738
01739 void PlusCstDomainIntVar::WhenBound(Demon* d) {
01740 var_->WhenBound(d);
01741 }
01742
01743 void PlusCstDomainIntVar::WhenDomain(Demon* d) {
01744 var_->WhenDomain(d);
01745 }
01746
01747 uint64 PlusCstDomainIntVar::Size() const {
01748 return var_->DomainIntVar::Size();
01749 }
01750
01751 bool PlusCstDomainIntVar::Contains(int64 v) const {
01752 return var_->DomainIntVar::Contains(v - cst_);
01753 }
01754
01755 string PlusCstDomainIntVar::DebugString() const {
01756 return StringPrintf("(%s + %" GG_LL_FORMAT "d)",
01757 var_->DebugString().c_str(), cst_);
01758 }
01759
01760
01761
01762 class SubCstIntVar : public IntVar {
01763 public:
01764 class SubCstIntVarIterator : public UnaryIterator {
01765 public:
01766 SubCstIntVarIterator(const IntVar* const v, int64 c, bool hole, bool rev)
01767 : UnaryIterator(v, hole, rev), cst_(c) {}
01768 virtual ~SubCstIntVarIterator() {}
01769
01770 virtual int64 Value() const {
01771 return cst_ - iterator_->Value();
01772 }
01773
01774 private:
01775 const int64 cst_;
01776 };
01777
01778 SubCstIntVar(Solver* const s, IntVar* v, int64 c);
01779 virtual ~SubCstIntVar();
01780
01781 virtual int64 Min() const;
01782 virtual void SetMin(int64 m);
01783 virtual int64 Max() const;
01784 virtual void SetMax(int64 m);
01785 virtual void SetRange(int64 l, int64 u);
01786 virtual void SetValue(int64 v);
01787 virtual bool Bound() const;
01788 virtual int64 Value() const;
01789 virtual void RemoveValue(int64 v);
01790 virtual void RemoveInterval(int64 l, int64 u);
01791 virtual uint64 Size() const;
01792 virtual bool Contains(int64 v) const;
01793 virtual void WhenRange(Demon* d);
01794 virtual void WhenBound(Demon* d);
01795 virtual void WhenDomain(Demon* d);
01796 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
01797 return COND_REV_ALLOC(reversible,
01798 new SubCstIntVarIterator(var_, cst_,
01799 true, reversible));
01800 }
01801 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
01802 return COND_REV_ALLOC(reversible,
01803 new SubCstIntVarIterator(var_, cst_,
01804 false, reversible));
01805 }
01806 virtual int64 OldMin() const {
01807 return cst_ - var_->OldMax();
01808 }
01809 virtual int64 OldMax() const {
01810 return cst_ - var_->OldMin();
01811 }
01812 virtual string DebugString() const;
01813 virtual int VarType() const { return CST_SUB_VAR; }
01814
01815 virtual void Accept(ModelVisitor* const visitor) const {
01816 visitor->VisitIntegerVariable(this,
01817 ModelVisitor::kDifferenceOperation,
01818 cst_,
01819 var_);
01820 }
01821
01822 private:
01823 IntVar* const var_;
01824 const int64 cst_;
01825 };
01826
01827 SubCstIntVar::SubCstIntVar(Solver* const s, IntVar* v, int64 c)
01828 : IntVar(s), var_(v), cst_(c) {}
01829
01830 SubCstIntVar::~SubCstIntVar() {}
01831
01832 int64 SubCstIntVar::Min() const {
01833 return cst_ - var_->Max();
01834 }
01835
01836 void SubCstIntVar::SetMin(int64 m) {
01837 var_->SetMax(cst_ - m);
01838 }
01839
01840 int64 SubCstIntVar::Max() const {
01841 return cst_ - var_->Min();
01842 }
01843
01844 void SubCstIntVar::SetMax(int64 m) {
01845 var_->SetMin(cst_ - m);
01846 }
01847
01848 void SubCstIntVar::SetRange(int64 l, int64 u) {
01849 var_->SetRange(cst_ - u, cst_ - l);
01850 }
01851
01852 void SubCstIntVar::SetValue(int64 v) {
01853 var_->SetValue(cst_ - v);
01854 }
01855 bool SubCstIntVar::Bound() const {
01856 return var_->Bound();
01857 }
01858
01859 void SubCstIntVar::WhenRange(Demon* d) {
01860 var_->WhenRange(d);
01861 }
01862
01863 int64 SubCstIntVar::Value() const {
01864 return cst_ - var_->Value();
01865 }
01866
01867 void SubCstIntVar::RemoveValue(int64 v) {
01868 var_->RemoveValue(cst_ - v);
01869 }
01870
01871 void SubCstIntVar::RemoveInterval(int64 l, int64 u) {
01872 var_->RemoveInterval(cst_ - u, cst_ - l);
01873 }
01874
01875 void SubCstIntVar::WhenBound(Demon* d) {
01876 var_->WhenBound(d);
01877 }
01878
01879 void SubCstIntVar::WhenDomain(Demon* d) {
01880 var_->WhenDomain(d);
01881 }
01882
01883 uint64 SubCstIntVar::Size() const {
01884 return var_->Size();
01885 }
01886
01887 bool SubCstIntVar::Contains(int64 v) const {
01888 return var_->Contains(cst_ - v);
01889 }
01890
01891 string SubCstIntVar::DebugString() const {
01892 return StringPrintf("(%" GG_LL_FORMAT "d - %s)",
01893 cst_, var_->DebugString().c_str());
01894 }
01895
01896
01897
01898 class OppIntVar : public IntVar {
01899 public:
01900 class OppIntVarIterator : public UnaryIterator {
01901 public:
01902 OppIntVarIterator(const IntVar* const v, bool hole, bool reversible)
01903 : UnaryIterator(v, hole, reversible) {}
01904 virtual ~OppIntVarIterator() {}
01905
01906 virtual int64 Value() const {
01907 return -iterator_->Value();
01908 }
01909 };
01910
01911 OppIntVar(Solver* const s, IntVar* v);
01912 virtual ~OppIntVar();
01913
01914 virtual int64 Min() const;
01915 virtual void SetMin(int64 m);
01916 virtual int64 Max() const;
01917 virtual void SetMax(int64 m);
01918 virtual void SetRange(int64 l, int64 u);
01919 virtual void SetValue(int64 v);
01920 virtual bool Bound() const;
01921 virtual int64 Value() const;
01922 virtual void RemoveValue(int64 v);
01923 virtual void RemoveInterval(int64 l, int64 u);
01924 virtual uint64 Size() const;
01925 virtual bool Contains(int64 v) const;
01926 virtual void WhenRange(Demon* d);
01927 virtual void WhenBound(Demon* d);
01928 virtual void WhenDomain(Demon* d);
01929 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
01930 return COND_REV_ALLOC(reversible,
01931 new OppIntVarIterator(var_, true, reversible));
01932 }
01933 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
01934 return COND_REV_ALLOC(reversible,
01935 new OppIntVarIterator(var_, false, reversible));
01936 }
01937 virtual int64 OldMin() const {
01938 return -var_->OldMax();
01939 }
01940 virtual int64 OldMax() const {
01941 return -var_->OldMin();
01942 }
01943 virtual string DebugString() const;
01944 virtual int VarType() const { return OPP_VAR; }
01945
01946 virtual void Accept(ModelVisitor* const visitor) const {
01947 visitor->VisitIntegerVariable(this,
01948 ModelVisitor::kDifferenceOperation,
01949 0,
01950 var_);
01951 }
01952
01953 private:
01954 IntVar* const var_;
01955 };
01956
01957 OppIntVar::OppIntVar(Solver* const s, IntVar* v) : IntVar(s), var_(v) {}
01958
01959 OppIntVar::~OppIntVar() {}
01960
01961 int64 OppIntVar::Min() const {
01962 return -var_->Max();
01963 }
01964
01965 void OppIntVar::SetMin(int64 m) {
01966 var_->SetMax(-m);
01967 }
01968
01969 int64 OppIntVar::Max() const {
01970 return -var_->Min();
01971 }
01972
01973 void OppIntVar::SetMax(int64 m) {
01974 var_->SetMin(-m);
01975 }
01976
01977 void OppIntVar::SetRange(int64 l, int64 u) {
01978 var_->SetRange(-u, -l);
01979 }
01980
01981 void OppIntVar::SetValue(int64 v) {
01982 var_->SetValue(-v);
01983 }
01984 bool OppIntVar::Bound() const {
01985 return var_->Bound();
01986 }
01987
01988 void OppIntVar::WhenRange(Demon* d) {
01989 var_->WhenRange(d);
01990 }
01991
01992 int64 OppIntVar::Value() const {
01993 return -var_->Value();
01994 }
01995
01996 void OppIntVar::RemoveValue(int64 v) {
01997 var_->RemoveValue(-v);
01998 }
01999
02000 void OppIntVar::RemoveInterval(int64 l, int64 u) {
02001 var_->RemoveInterval(-u, -l);
02002 }
02003
02004 void OppIntVar::WhenBound(Demon* d) {
02005 var_->WhenBound(d);
02006 }
02007
02008 void OppIntVar::WhenDomain(Demon* d) {
02009 var_->WhenDomain(d);
02010 }
02011
02012 uint64 OppIntVar::Size() const {
02013 return var_->Size();
02014 }
02015
02016 bool OppIntVar::Contains(int64 v) const {
02017 return var_->Contains(-v);
02018 }
02019
02020 string OppIntVar::DebugString() const {
02021 return StringPrintf("-(%s)", var_->DebugString().c_str());
02022 }
02023
02024
02025
02026 int64 PosIntDivUp(int64 e, int64 v) {
02027 if (e >= 0) {
02028 return (e + v - 1) / v;
02029 } else {
02030 return -(-e / v);
02031 }
02032 }
02033 int64 PosIntDivDown(int64 e, int64 v) {
02034 if (e >= 0) {
02035 return e / v;
02036 } else {
02037 return -(-e + v - 1) / v;
02038 }
02039 }
02040
02041
02042
02043 class TimesPosCstIntVar : public IntVar {
02044 public:
02045 class TimesPosCstIntVarIterator : public UnaryIterator {
02046 public:
02047 TimesPosCstIntVarIterator(const IntVar* const v,
02048 int64 c,
02049 bool hole,
02050 bool reversible)
02051 : UnaryIterator(v, hole, reversible), cst_(c) {}
02052 virtual ~TimesPosCstIntVarIterator() {}
02053
02054 virtual int64 Value() const {
02055 return iterator_->Value() * cst_;
02056 }
02057
02058 private:
02059 const int64 cst_;
02060 };
02061
02062 TimesPosCstIntVar(Solver* const s, IntVar* v, int64 c);
02063 virtual ~TimesPosCstIntVar();
02064
02065 virtual int64 Min() const;
02066 virtual void SetMin(int64 m);
02067 virtual int64 Max() const;
02068 virtual void SetMax(int64 m);
02069 virtual void SetRange(int64 l, int64 u);
02070 virtual void SetValue(int64 v);
02071 virtual bool Bound() const;
02072 virtual int64 Value() const;
02073 virtual void RemoveValue(int64 v);
02074 virtual void RemoveInterval(int64 l, int64 u);
02075 virtual uint64 Size() const;
02076 virtual bool Contains(int64 v) const;
02077 virtual void WhenRange(Demon* d);
02078 virtual void WhenBound(Demon* d);
02079 virtual void WhenDomain(Demon* d);
02080 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
02081 return COND_REV_ALLOC(reversible,
02082 new TimesPosCstIntVarIterator(var_, cst_,
02083 true, reversible));
02084 }
02085 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
02086 return COND_REV_ALLOC(reversible,
02087 new TimesPosCstIntVarIterator(var_, cst_,
02088 false, reversible));
02089 }
02090 virtual int64 OldMin() const {
02091 return var_->OldMin() * cst_;
02092 }
02093 virtual int64 OldMax() const {
02094 return var_->OldMax() * cst_;
02095 }
02096 virtual string DebugString() const;
02097 virtual int VarType() const { return VAR_TIMES_POS_CST; }
02098
02099 virtual void Accept(ModelVisitor* const visitor) const {
02100 visitor->VisitIntegerVariable(this,
02101 ModelVisitor::kProductOperation,
02102 cst_,
02103 var_);
02104 }
02105
02106 private:
02107 IntVar* const var_;
02108 const int64 cst_;
02109 };
02110
02111
02112
02113 TimesPosCstIntVar::TimesPosCstIntVar(Solver* const s, IntVar* v, int64 c)
02114 : IntVar(s), var_(v), cst_(c) {}
02115
02116 TimesPosCstIntVar::~TimesPosCstIntVar() {}
02117
02118 int64 TimesPosCstIntVar::Min() const {
02119 return var_->Min() * cst_;
02120 }
02121
02122 void TimesPosCstIntVar::SetMin(int64 m) {
02123 var_->SetMin(PosIntDivUp(m, cst_));
02124 }
02125
02126 int64 TimesPosCstIntVar::Max() const {
02127 return var_->Max() * cst_;
02128 }
02129
02130 void TimesPosCstIntVar::SetMax(int64 m) {
02131 var_->SetMax(PosIntDivDown(m, cst_));
02132 }
02133
02134 void TimesPosCstIntVar::SetRange(int64 l, int64 u) {
02135 var_->SetRange(PosIntDivUp(l, cst_), PosIntDivDown(u, cst_));
02136 }
02137
02138 void TimesPosCstIntVar::SetValue(int64 v) {
02139 if (v % cst_ != 0) {
02140 solver()->Fail();
02141 }
02142 var_->SetValue(v / cst_);
02143 }
02144
02145 bool TimesPosCstIntVar::Bound() const {
02146 return var_->Bound();
02147 }
02148
02149 void TimesPosCstIntVar::WhenRange(Demon* d) {
02150 var_->WhenRange(d);
02151 }
02152
02153 int64 TimesPosCstIntVar::Value() const {
02154 return var_->Value() * cst_;
02155 }
02156
02157 void TimesPosCstIntVar::RemoveValue(int64 v) {
02158 if (v % cst_ == 0) {
02159 var_->RemoveValue(v / cst_);
02160 }
02161 }
02162
02163 void TimesPosCstIntVar::RemoveInterval(int64 l, int64 u) {
02164 for (int64 v = l; v <= u; ++v) {
02165 RemoveValue(v);
02166 }
02167
02168 }
02169
02170 void TimesPosCstIntVar::WhenBound(Demon* d) {
02171 var_->WhenBound(d);
02172 }
02173
02174 void TimesPosCstIntVar::WhenDomain(Demon* d) {
02175 var_->WhenDomain(d);
02176 }
02177
02178 uint64 TimesPosCstIntVar::Size() const {
02179 return var_->Size();
02180 }
02181
02182 bool TimesPosCstIntVar::Contains(int64 v) const {
02183 return (v % cst_ == 0 && var_->Contains(v / cst_));
02184 }
02185
02186 string TimesPosCstIntVar::DebugString() const {
02187 return StringPrintf("(%s * %" GG_LL_FORMAT "d",
02188 var_->DebugString().c_str(), cst_);
02189 }
02190
02191
02192
02193 class TimesPosCstBoolVar : public IntVar {
02194 public:
02195 class TimesPosCstBoolVarIterator : public UnaryIterator {
02196 public:
02197
02198 TimesPosCstBoolVarIterator(const IntVar* const v,
02199 int64 c,
02200 bool hole,
02201 bool reversible)
02202 : UnaryIterator(v, hole, reversible), cst_(c) {}
02203 virtual ~TimesPosCstBoolVarIterator() {}
02204
02205 virtual int64 Value() const {
02206 return iterator_->Value() * cst_;
02207 }
02208
02209 private:
02210 const int64 cst_;
02211 };
02212
02213 TimesPosCstBoolVar(Solver* const s, BooleanVar* v, int64 c);
02214 virtual ~TimesPosCstBoolVar();
02215
02216 virtual int64 Min() const;
02217 virtual void SetMin(int64 m);
02218 virtual int64 Max() const;
02219 virtual void SetMax(int64 m);
02220 virtual void SetRange(int64 l, int64 u);
02221 virtual void SetValue(int64 v);
02222 virtual bool Bound() const;
02223 virtual int64 Value() const;
02224 virtual void RemoveValue(int64 v);
02225 virtual void RemoveInterval(int64 l, int64 u);
02226 virtual uint64 Size() const;
02227 virtual bool Contains(int64 v) const;
02228 virtual void WhenRange(Demon* d);
02229 virtual void WhenBound(Demon* d);
02230 virtual void WhenDomain(Demon* d);
02231 virtual IntVarIterator* MakeHoleIterator(bool reversible) const {
02232 return COND_REV_ALLOC(reversible, new EmptyIterator());
02233 }
02234 virtual IntVarIterator* MakeDomainIterator(bool reversible) const {
02235 return COND_REV_ALLOC(reversible,
02236 new TimesPosCstBoolVarIterator(var_, cst_,
02237 false, reversible));
02238 }
02239 virtual int64 OldMin() const {
02240 return 0;
02241 }
02242 virtual int64 OldMax() const {
02243 return cst_;
02244 }
02245 virtual string DebugString() const;
02246 virtual int VarType() const { return BOOLEAN_VAR_TIMES_POS_CST; }
02247
02248 virtual void Accept(ModelVisitor* const visitor) const {
02249 visitor->VisitIntegerVariable(this,
02250 ModelVisitor::kProductOperation,
02251 cst_,
02252 var_);
02253 }
02254
02255 private:
02256 BooleanVar* const var_;
02257 const int64 cst_;
02258 };
02259
02260
02261
02262 TimesPosCstBoolVar::TimesPosCstBoolVar(Solver* const s, BooleanVar* v, int64 c)
02263 : IntVar(s), var_(v), cst_(c) {}
02264
02265 TimesPosCstBoolVar::~TimesPosCstBoolVar() {}
02266
02267 int64 TimesPosCstBoolVar::Min() const {
02268 return (var_->value_ == 1) * cst_;
02269 }
02270
02271 void TimesPosCstBoolVar::SetMin(int64 m) {
02272 if (m > cst_) {
02273 solver()->Fail();
02274 } else if (m > 0) {
02275 var_->SetMin(1);
02276 }
02277 }
02278
02279 int64 TimesPosCstBoolVar::Max() const {
02280 return (var_->value_ != 0) * cst_;
02281 }
02282
02283 void TimesPosCstBoolVar::SetMax(int64 m) {
02284 if (m < 0) {
02285 solver()->Fail();
02286 } else if (m < cst_) {
02287 var_->SetMax(0);
02288 }
02289 }
02290
02291 void TimesPosCstBoolVar::SetRange(int64 l, int64 u) {
02292 if (u < 0 || l > cst_ || l > u) {
02293 solver()->Fail();
02294 }
02295 if (l > 0) {
02296 var_->SetMin(1);
02297 } else if (u < cst_) {
02298 var_->SetMax(0);
02299 }
02300 }
02301
02302 void TimesPosCstBoolVar::SetValue(int64 v) {
02303 if (v == 0) {
02304 var_->SetValue(0);
02305 } else if (v == cst_) {
02306 var_->SetValue(1);
02307 } else {
02308 solver()->Fail();
02309 }
02310 }
02311
02312 bool TimesPosCstBoolVar::Bound() const {
02313 return var_->value_ != kUnboundBooleanVarValue;
02314 }
02315
02316 void TimesPosCstBoolVar::WhenRange(Demon* d) {
02317 var_->WhenRange(d);
02318 }
02319
02320 int64 TimesPosCstBoolVar::Value() const {
02321 CHECK_NE(var_->value_, kUnboundBooleanVarValue) << "variable is not bound";
02322 return var_->value_ * cst_;
02323 }
02324
02325 void TimesPosCstBoolVar::RemoveValue(int64 v) {
02326 if (v == 0) {
02327 var_->RemoveValue(0);
02328 } else if (v == cst_) {
02329 var_->RemoveValue(1);
02330 }
02331 }
02332
02333 void TimesPosCstBoolVar::RemoveInterval(int64 l, int64 u) {
02334 if (l <= 0 && u >= 0) {
02335 var_->RemoveValue(0);
02336 }
02337 if (l <= cst_ && u >= cst_) {
02338 var_->RemoveValue(1);
02339 }
02340 }
02341
02342 void TimesPosCstBoolVar::WhenBound(Demon* d) {
02343 var_->WhenBound(d);
02344 }
02345
02346 void TimesPosCstBoolVar::WhenDomain(Demon* d) {
02347 var_->WhenDomain(d);
02348 }
02349
02350 uint64 TimesPosCstBoolVar::Size() const {
02351 return (1 + (var_->value_ == kUnboundBooleanVarValue));
02352 }
02353
02354 bool TimesPosCstBoolVar::Contains(int64 v) const {
02355 if (v == 0) {
02356 return var_->value_ != 1;
02357 } else if (v == cst_) {
02358 return var_->value_ != 0;
02359 }
02360 return false;
02361 }
02362
02363 string TimesPosCstBoolVar::DebugString() const {
02364 return StringPrintf("(%s * %" GG_LL_FORMAT "d)",
02365 var_->DebugString().c_str(), cst_);
02366 }
02367
02368
02369
02370
02371
02372 class PlusIntExpr : public BaseIntExpr {
02373 public:
02374 PlusIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r)
02375 : BaseIntExpr(s), left_(l), right_(r) {}
02376 virtual ~PlusIntExpr() {}
02377 virtual int64 Min() const {
02378 return (left_->Min() + right_->Min());
02379 }
02380 virtual void SetMin(int64 m) {
02381 left_->SetMin(m - right_->Max());
02382 right_->SetMin(m - left_->Max());
02383 }
02384 virtual void SetRange(int64 l, int64 u);
02385 virtual int64 Max() const {
02386 return (left_->Max() + right_->Max());
02387 }
02388 virtual void SetMax(int64 m) {
02389 left_->SetMax(m - right_->Min());
02390 right_->SetMax(m - left_->Min());
02391 }
02392 virtual bool Bound() const { return (left_->Bound() && right_->Bound()); }
02393 virtual string name() const {
02394 return StringPrintf("(%s + %s)",
02395 left_->name().c_str(),
02396 right_->name().c_str());
02397 }
02398 virtual string DebugString() const {
02399 return StringPrintf("(%s + %s)",
02400 left_->DebugString().c_str(),
02401 right_->DebugString().c_str());
02402 }
02403 virtual void WhenRange(Demon* d) {
02404 left_->WhenRange(d);
02405 right_->WhenRange(d);
02406 }
02407
02408 virtual void Accept(ModelVisitor* const visitor) const {
02409 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum, this);
02410 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
02411 left_);
02412 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
02413 right_);
02414 visitor->EndVisitIntegerExpression(ModelVisitor::kSum, this);
02415 }
02416
02417 private:
02418 IntExpr* const left_;
02419 IntExpr* const right_;
02420 };
02421
02422 void PlusIntExpr::SetRange(int64 l, int64 u) {
02423 const int64 left_min = left_->Min();
02424 const int64 left_max = right_->Min();
02425 const int64 right_min = left_->Max();
02426 const int64 right_max = right_->Max();
02427 if (l > left_min + left_max) {
02428 left_->SetMin(l - right_max);
02429 right_->SetMin(l - right_min);
02430 }
02431 if (u < right_min + right_max) {
02432 left_->SetMax(u - left_max);
02433 right_->SetMax(u - left_min);
02434 }
02435 }
02436
02437
02438
02439 class PlusIntCstExpr : public BaseIntExpr {
02440 public:
02441 PlusIntCstExpr(Solver* const s, IntExpr* const e, int64 v)
02442 : BaseIntExpr(s), expr_(e), value_(v) {}
02443 virtual ~PlusIntCstExpr() {}
02444 virtual int64 Min() const {
02445 return (expr_->Min() + value_);
02446 }
02447 virtual void SetMin(int64 m) {
02448 expr_->SetMin(m - value_);
02449 }
02450 virtual int64 Max() const {
02451 return (expr_->Max() + value_);
02452 }
02453 virtual void SetMax(int64 m) {
02454 expr_->SetMax(m - value_);
02455 }
02456 virtual bool Bound() const { return (expr_->Bound()); }
02457 virtual string name() const {
02458 return StringPrintf("(%s + %" GG_LL_FORMAT "d)",
02459 expr_->name().c_str(), value_);
02460 }
02461 virtual string DebugString() const {
02462 return StringPrintf("(%s + %" GG_LL_FORMAT "d)",
02463 expr_->DebugString().c_str(), value_);
02464 }
02465 virtual void WhenRange(Demon* d) {
02466 expr_->WhenRange(d);
02467 }
02468 virtual IntVar* CastToVar();
02469 virtual void Accept(ModelVisitor* const visitor) const {
02470 visitor->BeginVisitIntegerExpression(ModelVisitor::kSum, this);
02471 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
02472 expr_);
02473 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
02474 visitor->EndVisitIntegerExpression(ModelVisitor::kSum, this);
02475 }
02476
02477 private:
02478 IntExpr* const expr_;
02479 const int64 value_;
02480 };
02481
02482 IntVar* PlusIntCstExpr::CastToVar() {
02483 Solver* const s = solver();
02484 IntVar* const var = expr_->Var();
02485 IntVar* cast = NULL;
02486 switch (var->VarType()) {
02487 case DOMAIN_INT_VAR:
02488 cast = s->RegisterIntVar(s->RevAlloc(
02489 new PlusCstDomainIntVar(s,
02490 reinterpret_cast<DomainIntVar*>(var),
02491 value_)));
02492 default:
02493 cast = s->RegisterIntVar(s->RevAlloc(new PlusCstIntVar(s, var, value_)));
02494 }
02495 return cast;
02496 }
02497
02498
02499
02500 class SubIntExpr : public BaseIntExpr {
02501 public:
02502 SubIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r)
02503 : BaseIntExpr(s), left_(l), right_(r) {}
02504 virtual ~SubIntExpr() {}
02505 virtual int64 Min() const {
02506 return (left_->Min() - right_->Max());
02507 }
02508 virtual void SetMin(int64 m) {
02509 left_->SetMin(m + right_->Min());
02510 right_->SetMax(left_->Max() - m);
02511 }
02512 virtual void SetRange(int64 l, int64 u);
02513 virtual int64 Max() const {
02514 return (left_->Max() - right_->Min());
02515 }
02516 virtual void SetMax(int64 m) {
02517 left_->SetMax(m + right_->Max());
02518 right_->SetMin(left_->Min() - m);
02519 }
02520 virtual bool Bound() const { return (left_->Bound() && right_->Bound()); }
02521 virtual string name() const {
02522 return StringPrintf("(%s - %s)",
02523 left_->name().c_str(),
02524 right_->name().c_str());
02525 }
02526 virtual string DebugString() const {
02527 return StringPrintf("(%s - %s)",
02528 left_->DebugString().c_str(),
02529 right_->DebugString().c_str());
02530 }
02531 virtual void WhenRange(Demon* d) {
02532 left_->WhenRange(d);
02533 right_->WhenRange(d);
02534 }
02535
02536 virtual void Accept(ModelVisitor* const visitor) const {
02537 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference, this);
02538 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
02539 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
02540 right_);
02541 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference, this);
02542 }
02543
02544 private:
02545 IntExpr* const left_;
02546 IntExpr* const right_;
02547 };
02548
02549 void SubIntExpr::SetRange(int64 l, int64 u) {
02550 const int64 left_min = left_->Min();
02551 const int64 left_max = right_->Min();
02552 const int64 right_min = left_->Max();
02553 const int64 right_max = right_->Max();
02554 if (l > left_min - right_max) {
02555 left_->SetMin(l + left_max);
02556 right_->SetMax(right_min - l);
02557 }
02558 if (u < right_min - left_max) {
02559 left_->SetMax(u + right_max);
02560 right_->SetMin(left_min - u);
02561 }
02562 }
02563
02564
02565
02566
02567
02568 class SubIntCstExpr : public BaseIntExpr {
02569 public:
02570 SubIntCstExpr(Solver* const s, IntExpr* const e, int64 v)
02571 : BaseIntExpr(s), expr_(e), value_(v) {}
02572 virtual ~SubIntCstExpr() {}
02573 virtual int64 Min() const {
02574 return (value_ - expr_->Max());
02575 }
02576 virtual void SetMin(int64 m) {
02577 expr_->SetMax(value_ - m);
02578 }
02579 virtual int64 Max() const {
02580 return (value_ - expr_->Min());
02581 }
02582 virtual void SetMax(int64 m) {
02583 expr_->SetMin(value_ - m);
02584 }
02585 virtual bool Bound() const { return (expr_->Bound()); }
02586 virtual string name() const {
02587 return StringPrintf("(%" GG_LL_FORMAT "d - %s)",
02588 value_, expr_->name().c_str());
02589 }
02590 virtual string DebugString() const {
02591 return StringPrintf("(%" GG_LL_FORMAT "d - %s)",
02592 value_, expr_->DebugString().c_str());
02593 }
02594 virtual void WhenRange(Demon* d) {
02595 expr_->WhenRange(d);
02596 }
02597 virtual IntVar* CastToVar();
02598
02599 virtual void Accept(ModelVisitor* const visitor) const {
02600 visitor->BeginVisitIntegerExpression(ModelVisitor::kDifference, this);
02601 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
02602 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
02603 expr_);
02604 visitor->EndVisitIntegerExpression(ModelVisitor::kDifference, this);
02605 }
02606
02607 private:
02608 IntExpr* const expr_;
02609 const int64 value_;
02610 };
02611
02612 IntVar* SubIntCstExpr::CastToVar() {
02613 Solver* const s = solver();
02614 IntVar* const var =
02615 s->RegisterIntVar(s->RevAlloc(new SubCstIntVar(s, expr_->Var(), value_)));
02616 return var;
02617 }
02618
02619
02620
02621 class OppIntExpr : public BaseIntExpr {
02622 public:
02623 OppIntExpr(Solver* const s, IntExpr* const e) : BaseIntExpr(s), expr_(e) {}
02624 virtual ~OppIntExpr() {}
02625 virtual int64 Min() const {
02626 return (-expr_->Max());
02627 }
02628 virtual void SetMin(int64 m) {
02629 expr_->SetMax(-m);
02630 }
02631 virtual int64 Max() const {
02632 return (-expr_->Min());
02633 }
02634 virtual void SetMax(int64 m) {
02635 expr_->SetMin(-m);
02636 }
02637 virtual bool Bound() const { return (expr_->Bound()); }
02638 virtual string name() const {
02639 return StringPrintf("(-%s)", expr_->name().c_str());
02640 }
02641 virtual string DebugString() const {
02642 return StringPrintf("(-%s)", expr_->DebugString().c_str());
02643 }
02644 virtual void WhenRange(Demon* d) {
02645 expr_->WhenRange(d);
02646 }
02647 virtual IntVar* CastToVar();
02648
02649 virtual void Accept(ModelVisitor* const visitor) const {
02650 visitor->BeginVisitIntegerExpression(ModelVisitor::kOpposite, this);
02651 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
02652 expr_);
02653 visitor->EndVisitIntegerExpression(ModelVisitor::kOpposite, this);
02654 }
02655
02656 private:
02657 IntExpr* const expr_;
02658 };
02659
02660 IntVar* OppIntExpr::CastToVar() {
02661 Solver* const s = solver();
02662 IntVar* const var =
02663 s->RegisterIntVar(s->RevAlloc(new OppIntVar(s, expr_->Var())));
02664 return var;
02665 }
02666
02667
02668
02669 class TimesIntPosCstExpr : public BaseIntExpr {
02670 public:
02671 TimesIntPosCstExpr(Solver* const s, IntExpr* const e, int64 v);
02672 virtual ~TimesIntPosCstExpr();
02673 virtual int64 Min() const {
02674 return (expr_->Min() * value_);
02675 }
02676 virtual void SetMin(int64 m);
02677 virtual int64 Max() const {
02678 return (expr_->Max() * value_);
02679 }
02680 virtual void SetMax(int64 m);
02681 virtual bool Bound() const { return (expr_->Bound()); }
02682 virtual string name() const {
02683 return StringPrintf("(%s * %" GG_LL_FORMAT "d)",
02684 expr_->name().c_str(), value_);
02685 }
02686 virtual string DebugString() const {
02687 return StringPrintf("(%s * %" GG_LL_FORMAT "d)",
02688 expr_->DebugString().c_str(), value_);
02689 }
02690 virtual void WhenRange(Demon* d) {
02691 expr_->WhenRange(d);
02692 }
02693 virtual IntVar* CastToVar();
02694
02695 virtual void Accept(ModelVisitor* const visitor) const {
02696 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this);
02697 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
02698 expr_);
02699 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
02700 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct, this);
02701 }
02702
02703 private:
02704 IntExpr* const expr_;
02705 const int64 value_;
02706 };
02707
02708 TimesIntPosCstExpr::TimesIntPosCstExpr(Solver* const s,
02709 IntExpr* const e,
02710 int64 v)
02711 : BaseIntExpr(s), expr_(e), value_(v) {
02712 CHECK_GE(v, 0);
02713 }
02714
02715 TimesIntPosCstExpr::~TimesIntPosCstExpr() {}
02716
02717 void TimesIntPosCstExpr::SetMin(int64 m) {
02718 expr_->SetMin(PosIntDivUp(m, value_));
02719 }
02720
02721 void TimesIntPosCstExpr::SetMax(int64 m) {
02722 expr_->SetMax(PosIntDivDown(m, value_));
02723 }
02724
02725 IntVar* TimesIntPosCstExpr::CastToVar() {
02726 Solver* const s = solver();
02727 IntVar* var = NULL;
02728 if (expr_->IsVar() &&
02729 reinterpret_cast<IntVar*>(expr_)->VarType() == BOOLEAN_VAR) {
02730 var = s->RegisterIntVar(s->RevAlloc(
02731 new TimesPosCstBoolVar(s,
02732 reinterpret_cast<BooleanVar*>(expr_),
02733 value_)));
02734 } else {
02735 var = s->RegisterIntVar(
02736 s->RevAlloc(new TimesPosCstIntVar(s, expr_->Var(), value_)));
02737 }
02738 return var;
02739 }
02740
02741
02742
02743 class TimesIntNegCstExpr : public BaseIntExpr {
02744 public:
02745 TimesIntNegCstExpr(Solver* const s, IntExpr* const e, int64 v);
02746 virtual ~TimesIntNegCstExpr();
02747 virtual int64 Min() const {
02748 return (expr_->Max() * value_);
02749 }
02750 virtual void SetMin(int64 m);
02751 virtual int64 Max() const {
02752 return (expr_->Min() * value_);
02753 }
02754 virtual void SetMax(int64 m);
02755 virtual bool Bound() const { return (expr_->Bound()); }
02756 virtual string name() const {
02757 return StringPrintf("(%s * %" GG_LL_FORMAT "d)",
02758 expr_->name().c_str(), value_);
02759 }
02760 virtual string DebugString() const {
02761 return StringPrintf("(%s * %" GG_LL_FORMAT "d)",
02762 expr_->DebugString().c_str(), value_);
02763 }
02764 virtual void WhenRange(Demon* d) {
02765 expr_->WhenRange(d);
02766 }
02767
02768 virtual void Accept(ModelVisitor* const visitor) const {
02769 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this);
02770 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
02771 expr_);
02772 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
02773 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct, this);
02774 }
02775
02776 private:
02777 IntExpr* const expr_;
02778 const int64 value_;
02779 };
02780
02781 TimesIntNegCstExpr::TimesIntNegCstExpr(Solver* const s,
02782 IntExpr* const e,
02783 int64 v)
02784 : BaseIntExpr(s), expr_(e), value_(v) {
02785 CHECK_LE(v, 0);
02786 }
02787
02788 TimesIntNegCstExpr::~TimesIntNegCstExpr() {}
02789
02790 void TimesIntNegCstExpr::SetMin(int64 m) {
02791 expr_->SetMax(PosIntDivDown(-m, -value_));
02792 }
02793
02794 void TimesIntNegCstExpr::SetMax(int64 m) {
02795 expr_->SetMin(PosIntDivUp(-m, -value_));
02796 }
02797
02798
02799
02800
02801
02802 void SetPosPosMinExpr(IntExpr* const left, IntExpr* const right, int64 m) {
02803 DCHECK_GE(left->Min(), 0);
02804 DCHECK_GE(right->Min(), 0);
02805 const int64 lmax = left->Max();
02806 const int64 rmax = right->Max();
02807 if (m > lmax * rmax) {
02808 left->solver()->Fail();
02809 }
02810 if (m > left->Min() * right->Min()) {
02811
02812 if (0 != rmax) {
02813 left->SetMin(PosIntDivUp(m, rmax));
02814 }
02815 if (0 != lmax) {
02816 right->SetMin(PosIntDivUp(m, lmax));
02817 }
02818 }
02819 }
02820
02821
02822 void SetPosPosMaxExpr(IntExpr* const left, IntExpr* const right, int64 m) {
02823 DCHECK_GE(left->Min(), 0);
02824 DCHECK_GE(right->Min(), 0);
02825 const int64 lmin = left->Min();
02826 const int64 rmin = right->Min();
02827 if (m < lmin * rmin) {
02828 left->solver()->Fail();
02829 }
02830 if (m < left->Max() * right->Max()) {
02831 if (0 != lmin) {
02832 right->SetMax(PosIntDivDown(m, lmin));
02833 }
02834 if (0 != rmin) {
02835 left->SetMax(PosIntDivDown(m, rmin));
02836 }
02837
02838 }
02839 }
02840
02841
02842 void SetPosGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) {
02843 DCHECK_GE(left->Min(), 0);
02844 DCHECK_GT(right->Max(), 0);
02845 DCHECK_LT(right->Min(), 0);
02846 const int64 lmax = left->Max();
02847 const int64 rmax = right->Max();
02848 if (m > lmax * rmax) {
02849 left->solver()->Fail();
02850 }
02851 DCHECK_GT(left->Max(), 0);
02852 if (m > 0) {
02853 left->SetMin(PosIntDivUp(m, rmax));
02854 right->SetMin(PosIntDivUp(m, lmax));
02855 } else if (m == 0) {
02856 const int64 lmin = left->Min();
02857 if (lmin > 0) {
02858 right->SetMin(0);
02859 }
02860 } else {
02861 const int64 lmin = left->Min();
02862 if (0 != lmin) {
02863 right->SetMin(-PosIntDivDown(-m, lmin));
02864 }
02865 }
02866 }
02867
02868
02869 void SetGenGenMinExpr(IntExpr* const left, IntExpr* const right, int64 m) {
02870 DCHECK_LT(left->Min(), 0);
02871 DCHECK_GT(left->Max(), 0);
02872 DCHECK_GT(right->Max(), 0);
02873 DCHECK_LT(right->Min(), 0);
02874 const int64 lmin = left->Min();
02875 const int64 lmax = left->Max();
02876 const int64 rmin = right->Min();
02877 const int64 rmax = right->Max();
02878 if (m > std::max(lmin * rmin, lmax * rmax)) {
02879 left->solver()->Fail();
02880 }
02881 if (m > lmin * rmin) {
02882 left->SetMin(PosIntDivUp(m, rmax));
02883 right->SetMin(PosIntDivUp(m, lmax));
02884 } else if (m > lmax * rmax) {
02885 left->SetMax(-PosIntDivUp(m, -rmin));
02886 right->SetMax(-PosIntDivUp(m, -lmin));
02887 }
02888 }
02889
02890 void TimesSetMin(IntExpr* const left,
02891 IntExpr* const right,
02892 IntExpr* const minus_left,
02893 IntExpr* const minus_right,
02894 int m) {
02895 if (left->Min() >= 0) {
02896 if (right->Min() >= 0) {
02897 SetPosPosMinExpr(left, right, m);
02898 } else if (right->Max() <= 0) {
02899 SetPosPosMaxExpr(left, minus_right, -m);
02900 } else {
02901 SetPosGenMinExpr(left, right, m);
02902 }
02903 } else if (left->Max() <= 0) {
02904 if (right->Min() >= 0) {
02905 SetPosPosMaxExpr(right, minus_left, -m);
02906 } else if (right->Max() <= 0) {
02907 SetPosPosMinExpr(minus_left, minus_right, m);
02908 } else {
02909 SetPosGenMinExpr(minus_left, minus_right, m);
02910 }
02911 } else if (right->Min() >= 0) {
02912 SetPosGenMinExpr(right, left, m);
02913 } else if (right->Max() <= 0) {
02914 SetPosGenMinExpr(minus_right, minus_left, m);
02915 } else {
02916
02917 SetGenGenMinExpr(left, right, m);
02918 }
02919 }
02920
02921 class TimesIntExpr : public BaseIntExpr {
02922 public:
02923 TimesIntExpr(Solver* const s,
02924 IntExpr* const l,
02925 IntExpr* const r)
02926 : BaseIntExpr(s),
02927 left_(l),
02928 right_(r),
02929 minus_left_(s->MakeOpposite(left_)),
02930 minus_right_(s->MakeOpposite(right_)) {}
02931 virtual ~TimesIntExpr() {}
02932 virtual int64 Min() const {
02933 const int64 lmin = left_->Min();
02934 const int64 lmax = left_->Max();
02935 const int64 rmin = right_->Min();
02936 const int64 rmax = right_->Max();
02937 return std::min(std::min(lmin * rmin, lmax * rmax),
02938 std::min(lmax * rmin, lmin * rmax));
02939 }
02940 virtual void SetMin(int64 m);
02941 virtual int64 Max() const {
02942 const int64 lmin = left_->Min();
02943 const int64 lmax = left_->Max();
02944 const int64 rmin = right_->Min();
02945 const int64 rmax = right_->Max();
02946 return std::max(std::max(lmin * rmin, lmax * rmax),
02947 std::max(lmax * rmin, lmin * rmax));
02948 }
02949 virtual void SetMax(int64 m);
02950 virtual bool Bound() const;
02951 virtual string name() const {
02952 return StringPrintf("(%s * %s)",
02953 left_->name().c_str(),
02954 right_->name().c_str());
02955 }
02956 virtual string DebugString() const {
02957 return StringPrintf("(%s * %s)",
02958 left_->DebugString().c_str(),
02959 right_->DebugString().c_str());
02960 }
02961 virtual void WhenRange(Demon* d) {
02962 left_->WhenRange(d);
02963 right_->WhenRange(d);
02964 }
02965
02966 virtual void Accept(ModelVisitor* const visitor) const {
02967 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this);
02968 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
02969 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
02970 right_);
02971 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct, this);
02972 }
02973
02974 private:
02975 IntExpr* const left_;
02976 IntExpr* const right_;
02977 IntExpr* const minus_left_;
02978 IntExpr* const minus_right_;
02979 };
02980
02981 void TimesIntExpr::SetMin(int64 m) {
02982 TimesSetMin(left_, right_, minus_left_, minus_right_, m);
02983 }
02984
02985 void TimesIntExpr::SetMax(int64 m) {
02986 TimesSetMin(left_, minus_right_, minus_left_, right_, -m);
02987 }
02988
02989 bool TimesIntExpr::Bound() const {
02990 const bool left_bound = left_->Bound();
02991 const bool right_bound = right_->Bound();
02992 return ((left_bound && left_->Max() == 0) ||
02993 (right_bound && right_->Max() == 0) ||
02994 (left_bound && right_bound));
02995 }
02996
02997
02998
02999 class TimesIntPosExpr : public BaseIntExpr {
03000 public:
03001 TimesIntPosExpr(Solver* const s, IntExpr* const l, IntExpr* const r)
03002 : BaseIntExpr(s), left_(l), right_(r) {}
03003 virtual ~TimesIntPosExpr() {}
03004 virtual int64 Min() const {
03005 return (left_->Min() * right_->Min());
03006 }
03007 virtual void SetMin(int64 m);
03008 virtual int64 Max() const {
03009 return (left_->Max() * right_->Max());
03010 }
03011 virtual void SetMax(int64 m);
03012 virtual bool Bound() const;
03013 virtual string name() const {
03014 return StringPrintf("(%s * %s)",
03015 left_->name().c_str(),
03016 right_->name().c_str());
03017 }
03018 virtual string DebugString() const {
03019 return StringPrintf("(%s * %s)",
03020 left_->DebugString().c_str(),
03021 right_->DebugString().c_str());
03022 }
03023 virtual void WhenRange(Demon* d) {
03024 left_->WhenRange(d);
03025 right_->WhenRange(d);
03026 }
03027
03028 virtual void Accept(ModelVisitor* const visitor) const {
03029 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this);
03030 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
03031 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
03032 right_);
03033 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct, this);
03034 }
03035
03036 private:
03037 IntExpr* const left_;
03038 IntExpr* const right_;
03039 };
03040
03041 void TimesIntPosExpr::SetMin(int64 m) {
03042 SetPosPosMinExpr(left_, right_, m);
03043 }
03044
03045 void TimesIntPosExpr::SetMax(int64 m) {
03046 SetPosPosMaxExpr(left_, right_, m);
03047 }
03048
03049 bool TimesIntPosExpr::Bound() const {
03050 return (left_->Max() == 0 ||
03051 right_->Max() == 0 ||
03052 (left_->Bound() && right_->Bound()));
03053 }
03054
03055
03056
03057 class TimesBooleanPosIntExpr : public BaseIntExpr {
03058 public:
03059 TimesBooleanPosIntExpr(Solver* const s, BooleanVar* const b, IntExpr* const e)
03060 : BaseIntExpr(s), boolvar_(b), expr_(e) {}
03061 virtual ~TimesBooleanPosIntExpr() {}
03062 virtual int64 Min() const {
03063 return (boolvar_->value_ == 1 ? expr_->Min() : 0);
03064 }
03065 virtual void SetMin(int64 m);
03066 virtual int64 Max() const {
03067 return (boolvar_->value_ == 0 ? 0 : expr_->Max());
03068 }
03069 virtual void SetMax(int64 m);
03070 virtual void Range(int64* mi, int64* ma);
03071 virtual void SetRange(int64 mi, int64 ma);
03072 virtual bool Bound() const;
03073 virtual string name() const {
03074 return StringPrintf("(%s * %s)",
03075 boolvar_->name().c_str(),
03076 expr_->name().c_str());
03077 }
03078 virtual string DebugString() const {
03079 return StringPrintf("(%s * %s)",
03080 boolvar_->DebugString().c_str(),
03081 expr_->DebugString().c_str());
03082 }
03083 virtual void WhenRange(Demon* d) {
03084 boolvar_->WhenRange(d);
03085 expr_->WhenRange(d);
03086 }
03087
03088 virtual void Accept(ModelVisitor* const visitor) const {
03089 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this);
03090 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
03091 boolvar_);
03092 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
03093 expr_);
03094 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct, this);
03095 }
03096
03097 private:
03098 BooleanVar* const boolvar_;
03099 IntExpr* const expr_;
03100 };
03101
03102 void TimesBooleanPosIntExpr::SetMin(int64 m) {
03103 if (m > 0) {
03104 boolvar_->SetValue(1);
03105 expr_->SetMin(m);
03106 }
03107 }
03108
03109 void TimesBooleanPosIntExpr::SetMax(int64 m) {
03110 if (m < 0) {
03111 solver()->Fail();
03112 }
03113 if (m < expr_->Min()) {
03114 boolvar_->SetValue(0);
03115 }
03116 if (boolvar_->value_ == 1) {
03117 expr_->SetMax(m);
03118 }
03119 }
03120
03121 void TimesBooleanPosIntExpr::Range(int64* mi, int64* ma) {
03122 const int value = boolvar_->value_;
03123 if (value == 0) {
03124 *mi = 0;
03125 *ma = 0;
03126 } else if (value == 1) {
03127 expr_->Range(mi, ma);
03128 } else {
03129 *mi = 0;
03130 *ma = expr_->Max();
03131 }
03132 }
03133
03134 void TimesBooleanPosIntExpr::SetRange(int64 mi, int64 ma) {
03135 if (ma < 0 || mi > ma) {
03136 solver()->Fail();
03137 }
03138 if (mi > 0) {
03139 boolvar_->SetValue(1);
03140 expr_->SetMin(mi);
03141 }
03142 if (ma < expr_->Min()) {
03143 boolvar_->SetValue(0);
03144 }
03145 if (boolvar_->value_ == 1) {
03146 expr_->SetMax(ma);
03147 }
03148 }
03149
03150 bool TimesBooleanPosIntExpr::Bound() const {
03151 return (boolvar_->value_ == 0 ||
03152 expr_->Max() == 0 ||
03153 (boolvar_->value_ != kUnboundBooleanVarValue && expr_->Bound()));
03154 }
03155
03156
03157
03158 class TimesBooleanIntExpr : public BaseIntExpr {
03159 public:
03160 TimesBooleanIntExpr(Solver* const s, BooleanVar* const b, IntExpr* const e)
03161 : BaseIntExpr(s), boolvar_(b), expr_(e) {}
03162 virtual ~TimesBooleanIntExpr() {}
03163 virtual int64 Min() const {
03164 switch (boolvar_->value_) {
03165 case 0: {
03166 return 0LL;
03167 }
03168 case 1: {
03169 return expr_->Min();
03170 }
03171 default: {
03172 DCHECK_EQ(kUnboundBooleanVarValue, boolvar_->value_);
03173 return std::min(0LL, expr_->Min());
03174 }
03175 }
03176 }
03177 virtual void SetMin(int64 m);
03178 virtual int64 Max() const {
03179 switch (boolvar_->value_) {
03180 case 0: {
03181 return 0LL;
03182 }
03183 case 1: {
03184 return expr_->Max();
03185 }
03186 default: {
03187 DCHECK_EQ(kUnboundBooleanVarValue, boolvar_->value_);
03188 return std::max(0LL, expr_->Max());
03189 }
03190 }
03191 }
03192 virtual void SetMax(int64 m);
03193 virtual void Range(int64* mi, int64* ma);
03194 virtual void SetRange(int64 mi, int64 ma);
03195 virtual bool Bound() const;
03196 virtual string name() const {
03197 return StringPrintf("(%s * %s)",
03198 boolvar_->name().c_str(),
03199 expr_->name().c_str());
03200 }
03201 virtual string DebugString() const {
03202 return StringPrintf("(%s * %s)",
03203 boolvar_->DebugString().c_str(),
03204 expr_->DebugString().c_str());
03205 }
03206 virtual void WhenRange(Demon* d) {
03207 boolvar_->WhenRange(d);
03208 expr_->WhenRange(d);
03209 }
03210
03211 virtual void Accept(ModelVisitor* const visitor) const {
03212 visitor->BeginVisitIntegerExpression(ModelVisitor::kProduct, this);
03213 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
03214 boolvar_);
03215 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
03216 expr_);
03217 visitor->EndVisitIntegerExpression(ModelVisitor::kProduct, this);
03218 }
03219
03220 private:
03221 BooleanVar* const boolvar_;
03222 IntExpr* const expr_;
03223 };
03224
03225 void TimesBooleanIntExpr::SetMin(int64 m) {
03226 switch (boolvar_->value_) {
03227 case 0: {
03228 if (m > 0) {
03229 solver()->Fail();
03230 }
03231 break;
03232 }
03233 case 1: {
03234 expr_->SetMin(m);
03235 break;
03236 }
03237 default: {
03238 DCHECK_EQ(kUnboundBooleanVarValue, boolvar_->value_);
03239 if (m > 0) {
03240 boolvar_->SetValue(1);
03241 expr_->SetMin(m);
03242 } else if (m <= 0 && expr_->Max() < m) {
03243 boolvar_->SetValue(0);
03244 }
03245 }
03246 }
03247 }
03248
03249 void TimesBooleanIntExpr::SetMax(int64 m) {
03250 switch (boolvar_->value_) {
03251 case 0: {
03252 if (m < 0) {
03253 solver()->Fail();
03254 }
03255 break;
03256 }
03257 case 1: {
03258 expr_->SetMax(m);
03259 break;
03260 }
03261 default: {
03262 DCHECK_EQ(kUnboundBooleanVarValue, boolvar_->value_);
03263 if (m < 0) {
03264 boolvar_->SetValue(1);
03265 expr_->SetMax(m);
03266 } else if (m >= 0 && expr_->Min() > m) {
03267 boolvar_->SetValue(0);
03268 }
03269 }
03270 }
03271 }
03272
03273 void TimesBooleanIntExpr::Range(int64* mi, int64* ma) {
03274 switch (boolvar_->value_) {
03275 case 0: {
03276 *mi = 0;
03277 *ma = 0;
03278 break;
03279 }
03280 case 1: {
03281 *mi = expr_->Min();
03282 *ma = expr_->Max();
03283 break;
03284 }
03285 default: {
03286 DCHECK_EQ(kUnboundBooleanVarValue, boolvar_->value_);
03287 *mi = std::min(0LL, expr_->Min());
03288 *ma = std::max(0LL, expr_->Max());
03289 break;
03290 }
03291 }
03292 }
03293
03294 void TimesBooleanIntExpr::SetRange(int64 mi, int64 ma) {
03295 if (mi > ma) {
03296 solver()->Fail();
03297 }
03298 switch (boolvar_->value_) {
03299 case 0: {
03300 if (mi > 0 || ma < 0) {
03301 solver()->Fail();
03302 }
03303 break;
03304 }
03305 case 1: {
03306 expr_->SetRange(mi, ma);
03307 break;
03308 }
03309 default: {
03310 DCHECK_EQ(kUnboundBooleanVarValue, boolvar_->value_);
03311 if (mi > 0) {
03312 boolvar_->SetValue(1);
03313 expr_->SetMin(mi);
03314 } else if (mi == 0 && expr_->Max() < 0) {
03315 boolvar_->SetValue(0);
03316 }
03317 if (ma < 0) {
03318 boolvar_->SetValue(1);
03319 expr_->SetMax(ma);
03320 } else if (ma == 0 && expr_->Min() > 0) {
03321 boolvar_->SetValue(0);
03322 }
03323 break;
03324 }
03325 }
03326 }
03327
03328 bool TimesBooleanIntExpr::Bound() const {
03329 return (boolvar_->value_ == 0 ||
03330 (expr_->Bound() && (
03331 boolvar_->value_ != kUnboundBooleanVarValue ||
03332 expr_->Max() == 0)));
03333 }
03334
03335
03336
03337 class DivIntPosCstExpr : public BaseIntExpr {
03338 public:
03339 DivIntPosCstExpr(Solver* const s, IntExpr* const e, int64 v)
03340 : BaseIntExpr(s), expr_(e), value_(v) {
03341 CHECK_GE(v, 0);
03342 }
03343 virtual ~DivIntPosCstExpr() {}
03344 virtual int64 Min() const {
03345 return PosIntDivDown(expr_->Min(), value_);
03346 }
03347 virtual void SetMin(int64 m) {
03348 expr_->SetMin(m * value_);
03349 }
03350 virtual int64 Max() const {
03351 return PosIntDivDown(expr_->Max(), value_);
03352 }
03353 virtual void SetMax(int64 m) {
03354 expr_->SetMax((m + 1) * value_ - 1);
03355 }
03356 virtual string name() const {
03357 return StringPrintf("(%s div %" GG_LL_FORMAT "d)",
03358 expr_->name().c_str(), value_);
03359 }
03360 virtual string DebugString() const {
03361 return StringPrintf("(%s div %" GG_LL_FORMAT "d)",
03362 expr_->DebugString().c_str(), value_);
03363 }
03364 virtual void WhenRange(Demon* d) {
03365 expr_->WhenRange(d);
03366 }
03367
03368 virtual void Accept(ModelVisitor* const visitor) const {
03369 visitor->BeginVisitIntegerExpression(ModelVisitor::kDivide, this);
03370 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03371 expr_);
03372 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
03373 visitor->EndVisitIntegerExpression(ModelVisitor::kDivide, this);
03374 }
03375
03376 private:
03377 IntExpr* const expr_;
03378 const int64 value_;
03379 };
03380
03381
03382
03383 class IntAbs : public BaseIntExpr {
03384 public:
03385 IntAbs(Solver* const s, IntExpr* const e) : BaseIntExpr(s), expr_(e) {}
03386 virtual ~IntAbs() {}
03387
03388 virtual int64 Min() const;
03389 virtual void SetMin(int64 m);
03390 virtual int64 Max() const;
03391 virtual void SetMax(int64 m) {
03392 expr_->SetRange(-m, m);
03393 }
03394 virtual bool Bound() const {
03395 return expr_->Bound();
03396 }
03397 virtual void WhenRange(Demon* d) {
03398 expr_->WhenRange(d);
03399 }
03400 virtual string name() const {
03401 return StringPrintf("IntAbs(%s)", expr_->name().c_str());
03402 }
03403 virtual string DebugString() const {
03404 return StringPrintf("IntAbs(%s)", expr_->DebugString().c_str());
03405 }
03406
03407 virtual void Accept(ModelVisitor* const visitor) const {
03408 visitor->BeginVisitIntegerExpression(ModelVisitor::kAbs, this);
03409 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03410 expr_);
03411 visitor->EndVisitIntegerExpression(ModelVisitor::kAbs, this);
03412 }
03413
03414 private:
03415 IntExpr* const expr_;
03416 };
03417
03418 void IntAbs::SetMin(int64 m) {
03419 const int64 emin = expr_->Min();
03420 const int64 emax = expr_->Max();
03421 if (emin >= 0) {
03422 expr_->SetMin(m);
03423 } else if (emax <= 0) {
03424 expr_->SetMax(-m);
03425 } else if (expr_->IsVar()) {
03426 reinterpret_cast<IntVar*>(expr_)->RemoveInterval(-m + 1, m - 1);
03427 }
03428 }
03429
03430 int64 IntAbs::Min() const {
03431 const int64 emin = expr_->Min();
03432 const int64 emax = expr_->Max();
03433 if (emin >= 0) {
03434 return emin;
03435 }
03436 if (emax <= 0) {
03437 return -emax;
03438 }
03439 return 0;
03440 }
03441
03442 int64 IntAbs::Max() const {
03443 const int64 emin = expr_->Min();
03444 const int64 emax = expr_->Max();
03445 if (emin >= 0) {
03446 return emax;
03447 }
03448 if (emax <= 0) {
03449 return -emin;
03450 }
03451 return std::max(-emin, emax);
03452 }
03453
03454
03455
03456 class IntSquare : public BaseIntExpr {
03457 public:
03458 IntSquare(Solver* const s, IntExpr* const e) : BaseIntExpr(s), expr_(e) {}
03459 virtual ~IntSquare() {}
03460
03461 virtual int64 Min() const {
03462 const int64 emin = expr_->Min();
03463 if (emin >= 0) {
03464 return emin * emin;
03465 }
03466 const int64 emax = expr_->Max();
03467 if (emax < 0) {
03468 return emax * emax;
03469 }
03470 return 0LL;
03471 }
03472 virtual void SetMin(int64 m) {
03473 if (m <= 0) {
03474 return;
03475 }
03476 const int64 emin = expr_->Min();
03477 const int64 emax = expr_->Max();
03478 const int64 root = static_cast<int64>(ceil(sqrt(static_cast<double>(m))));
03479 if (emin >= 0) {
03480 expr_->SetMin(root);
03481 } else if (emax <= 0) {
03482 expr_->SetMax(-root);
03483 } else if (expr_->IsVar()) {
03484 reinterpret_cast<IntVar*>(expr_)->RemoveInterval(-root + 1, root - 1);
03485 }
03486 }
03487 virtual int64 Max() const {
03488 const int64 emax = expr_->Max();
03489 const int64 emin = expr_->Min();
03490 return std::max(emin * emin, emax * emax);
03491 }
03492 virtual void SetMax(int64 m) {
03493 if (m < 0) {
03494 solver()->Fail();
03495 }
03496 const int64 root = static_cast<int64>(floor(sqrt(static_cast<double>(m))));
03497 expr_->SetRange(-root, root);
03498 }
03499 virtual bool Bound() const {
03500 return expr_->Bound();
03501 }
03502 virtual void WhenRange(Demon* d) {
03503 expr_->WhenRange(d);
03504 }
03505 virtual string name() const {
03506 return StringPrintf("IntSquare(%s)", expr_->name().c_str());
03507 }
03508 virtual string DebugString() const {
03509 return StringPrintf("IntSquare(%s)", expr_->DebugString().c_str());
03510 }
03511
03512 virtual void Accept(ModelVisitor* const visitor) const {
03513 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare, this);
03514 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03515 expr_);
03516 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare, this);
03517 }
03518
03519 private:
03520 IntExpr* const expr_;
03521 };
03522
03523 class PosIntSquare : public BaseIntExpr {
03524 public:
03525 PosIntSquare(Solver* const s, IntExpr* const e) : BaseIntExpr(s), expr_(e) {}
03526 virtual ~PosIntSquare() {}
03527
03528 virtual int64 Min() const {
03529 const int64 emin = expr_->Min();
03530 return emin * emin;
03531 }
03532 virtual void SetMin(int64 m) {
03533 if (m <= 0) {
03534 return;
03535 }
03536 const int64 root = static_cast<int64>(ceil(sqrt(static_cast<double>(m))));
03537 expr_->SetMin(root);
03538 }
03539 virtual int64 Max() const {
03540 const int64 emax = expr_->Max();
03541 return emax * emax;
03542 }
03543 virtual void SetMax(int64 m) {
03544 if (m < 0) {
03545 solver()->Fail();
03546 }
03547 const int64 root = static_cast<int64>(floor(sqrt(static_cast<double>(m))));
03548 expr_->SetMax(root);
03549 }
03550 virtual bool Bound() const {
03551 return expr_->Bound();
03552 }
03553 virtual void WhenRange(Demon* d) {
03554 expr_->WhenRange(d);
03555 }
03556 virtual string name() const {
03557 return StringPrintf("PosIntSquare(%s)", expr_->name().c_str());
03558 }
03559 virtual string DebugString() const {
03560 return StringPrintf("PosIntSquare(%s)", expr_->DebugString().c_str());
03561 }
03562
03563 virtual void Accept(ModelVisitor* const visitor) const {
03564 visitor->BeginVisitIntegerExpression(ModelVisitor::kSquare, this);
03565 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03566 expr_);
03567 visitor->EndVisitIntegerExpression(ModelVisitor::kSquare, this);
03568 }
03569
03570 private:
03571 IntExpr* const expr_;
03572 };
03573
03574
03575
03576 class MinIntExpr : public BaseIntExpr {
03577 public:
03578 MinIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r)
03579 : BaseIntExpr(s), left_(l), right_(r) {}
03580 virtual ~MinIntExpr() {}
03581 virtual int64 Min() const {
03582 const int64 lmin = left_->Min();
03583 const int64 rmin = right_->Min();
03584 return std::min(lmin, rmin);
03585 }
03586 virtual void SetMin(int64 m) {
03587 left_->SetMin(m);
03588 right_->SetMin(m);
03589 }
03590 virtual int64 Max() const {
03591 const int64 lmax = left_->Max();
03592 const int64 rmax = right_->Max();
03593 return std::min(lmax, rmax);
03594 }
03595 virtual void SetMax(int64 m) {
03596 if (left_->Min() > m) {
03597 right_->SetMax(m);
03598 }
03599 if (right_->Min() > m) {
03600 left_->SetMax(m);
03601 }
03602 }
03603 virtual string name() const {
03604 return StringPrintf("MinIntExpr(%s, %s)", left_->name().c_str(),
03605 right_->name().c_str());
03606 }
03607 virtual string DebugString() const {
03608 return StringPrintf("MinIntExpr(%s, %s)",
03609 left_->DebugString().c_str(),
03610 right_->DebugString().c_str());
03611 }
03612 virtual void WhenRange(Demon* d) {
03613 left_->WhenRange(d);
03614 right_->WhenRange(d);
03615 }
03616
03617 virtual void Accept(ModelVisitor* const visitor) const {
03618 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin, this);
03619 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument,
03620 left_);
03621 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
03622 right_);
03623 visitor->EndVisitIntegerExpression(ModelVisitor::kMin, this);
03624 }
03625
03626 private:
03627 IntExpr* const left_;
03628 IntExpr* const right_;
03629 };
03630
03631
03632
03633 class MinCstIntExpr : public BaseIntExpr {
03634 public:
03635 MinCstIntExpr(Solver* const s, IntExpr* const e, int64 v)
03636 : BaseIntExpr(s), expr_(e), value_(v) {}
03637 virtual ~MinCstIntExpr() {}
03638 virtual int64 Min() const {
03639 const int64 emin = expr_->Min();
03640 return std::min(emin, value_);
03641 }
03642 virtual void SetMin(int64 m) {
03643 if (m > value_) {
03644 solver()->Fail();
03645 }
03646 expr_->SetMin(m);
03647 }
03648 virtual int64 Max() const {
03649 const int64 emax = expr_->Max();
03650 return std::min(emax, value_);
03651 }
03652 virtual void SetMax(int64 m) {
03653 if (value_ > m) {
03654 expr_->SetMax(m);
03655 }
03656 }
03657 virtual bool Bound() const {
03658 return (expr_->Bound() || expr_->Min() >= value_);
03659 }
03660 virtual string name() const {
03661 return StringPrintf("MinCstIntExpr(%s, %" GG_LL_FORMAT "d)",
03662 expr_->name().c_str(), value_);
03663 }
03664 virtual string DebugString() const {
03665 return StringPrintf("MinCstIntExpr(%s, %" GG_LL_FORMAT "d)",
03666 expr_->DebugString().c_str(), value_);
03667 }
03668 virtual void WhenRange(Demon* d) {
03669 expr_->WhenRange(d);
03670 }
03671
03672 virtual void Accept(ModelVisitor* const visitor) const {
03673 visitor->BeginVisitIntegerExpression(ModelVisitor::kMin, this);
03674 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03675 expr_);
03676 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
03677 visitor->EndVisitIntegerExpression(ModelVisitor::kMin, this);
03678 }
03679
03680 private:
03681 IntExpr* const expr_;
03682 const int64 value_;
03683 };
03684
03685
03686
03687 class MaxIntExpr : public BaseIntExpr {
03688 public:
03689 MaxIntExpr(Solver* const s, IntExpr* const l, IntExpr* const r)
03690 : BaseIntExpr(s), left_(l), right_(r) {}
03691 virtual ~MaxIntExpr() {}
03692 virtual int64 Min() const {
03693 const int64 lmin = left_->Min();
03694 const int64 rmin = right_->Min();
03695 return std::max(lmin, rmin);
03696 }
03697 virtual void SetMin(int64 m) {
03698 const int64 lmax = left_->Max();
03699 if (lmax < m) {
03700 right_->SetMin(m);
03701 }
03702 const int64 rmax = right_->Max();
03703 if (rmax < m) {
03704 left_->SetMin(m);
03705 }
03706 }
03707 virtual int64 Max() const {
03708 const int64 lmax = left_->Max();
03709 const int64 rmax = right_->Max();
03710 return std::max(lmax, rmax);
03711 }
03712 virtual void SetMax(int64 m) {
03713 left_->SetMax(m);
03714 right_->SetMax(m);
03715 }
03716 virtual string name() const {
03717 return StringPrintf("MaxIntExpr(%s, %s)", left_->name().c_str(),
03718 right_->name().c_str());
03719 }
03720 virtual string DebugString() const {
03721 return StringPrintf("MaxIntExpr(%s, %s)",
03722 left_->DebugString().c_str(),
03723 right_->DebugString().c_str());
03724 }
03725 virtual void WhenRange(Demon* d) {
03726 left_->WhenRange(d);
03727 right_->WhenRange(d);
03728 }
03729
03730 virtual void Accept(ModelVisitor* const visitor) const {
03731 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax, this);
03732 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
03733 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
03734 right_);
03735 visitor->EndVisitIntegerExpression(ModelVisitor::kMax, this);
03736 }
03737
03738 private:
03739 IntExpr* const left_;
03740 IntExpr* const right_;
03741 };
03742
03743
03744
03745 class MaxCstIntExpr : public BaseIntExpr {
03746 public:
03747 MaxCstIntExpr(Solver* const s, IntExpr* const e, int64 v)
03748 : BaseIntExpr(s), expr_(e), value_(v) {}
03749 virtual ~MaxCstIntExpr() {}
03750 virtual int64 Min() const {
03751 const int64 emin = expr_->Min();
03752 return std::max(emin, value_);
03753 }
03754 virtual void SetMin(int64 m) {
03755 if (value_ < m) {
03756 expr_->SetMin(m);
03757 }
03758 }
03759 virtual int64 Max() const {
03760 const int64 emax = expr_->Max();
03761 return std::max(emax, value_);
03762 }
03763 virtual void SetMax(int64 m) {
03764 if (m < value_) {
03765 solver()->Fail();
03766 }
03767 expr_->SetMax(m);
03768 }
03769 virtual bool Bound() const {
03770 return (expr_->Bound() || expr_->Max() <= value_);
03771 }
03772 virtual string name() const {
03773 return StringPrintf("MaxCstIntExpr(%s, %" GG_LL_FORMAT "d)",
03774 expr_->name().c_str(), value_);
03775 }
03776 virtual string DebugString() const {
03777 return StringPrintf("MaxCstIntExpr(%s, %" GG_LL_FORMAT "d)",
03778 expr_->DebugString().c_str(), value_);
03779 }
03780 virtual void WhenRange(Demon* d) {
03781 expr_->WhenRange(d);
03782 }
03783
03784 virtual void Accept(ModelVisitor* const visitor) const {
03785 visitor->BeginVisitIntegerExpression(ModelVisitor::kMax, this);
03786 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03787 expr_);
03788 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, value_);
03789 visitor->EndVisitIntegerExpression(ModelVisitor::kMax, this);
03790 }
03791
03792 private:
03793 IntExpr* const expr_;
03794 const int64 value_;
03795 };
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805 class SimpleConvexPiecewiseExpr : public BaseIntExpr {
03806 public:
03807 SimpleConvexPiecewiseExpr(Solver* const s, IntVar* const e,
03808 int64 ec, int64 ed,
03809 int64 ld, int64 lc)
03810 : BaseIntExpr(s),
03811 var_(e),
03812 early_cost_(ec),
03813 early_date_(ec == 0 ? kint64min : ed),
03814 late_date_(lc == 0 ? kint64max : ld),
03815 late_cost_(lc) {
03816 DCHECK_GE(ec, 0LL);
03817 DCHECK_GE(lc, 0LL);
03818 DCHECK_GE(ld, ed);
03819
03820
03821
03822 }
03823
03824 virtual ~SimpleConvexPiecewiseExpr() {}
03825
03826 virtual int64 Min() const {
03827 const int64 vmin = var_->Min();
03828 const int64 vmax = var_->Max();
03829 if (vmin >= late_date_) {
03830 return (vmin - late_date_) * late_cost_;
03831 } else if (vmax <= early_date_) {
03832 return (early_date_ - vmax) * early_cost_;
03833 } else {
03834 return 0LL;
03835 }
03836 }
03837
03838 virtual void SetMin(int64 m) {
03839 if (m <= 0) {
03840 return;
03841 }
03842 const int64 vmin = var_->Min();
03843 const int64 vmax = var_->Max();
03844 const int64 rb = (late_cost_ == 0 ?
03845 vmax :
03846 late_date_ + PosIntDivUp(m , late_cost_) - 1);
03847 const int64 lb = (early_cost_ == 0 ?
03848 vmin :
03849 early_date_ - PosIntDivUp(m , early_cost_) + 1);
03850 var_->RemoveInterval(lb, rb);
03851 }
03852
03853 virtual int64 Max() const {
03854 const int64 vmin = var_->Min();
03855 const int64 vmax = var_->Max();
03856 const int64 mr = vmax > late_date_ ? (vmax - late_date_) * late_cost_ : 0;
03857 const int64 ml = vmin < early_date_
03858 ? (early_date_ - vmin) * early_cost_
03859 : 0;
03860 return std::max(mr, ml);
03861 }
03862
03863 virtual void SetMax(int64 m) {
03864 if (m < 0) {
03865 solver()->Fail();
03866 }
03867 if (late_cost_ != 0LL) {
03868 const int64 rb = late_date_ + PosIntDivDown(m, late_cost_);
03869 if (early_cost_ != 0LL) {
03870 const int64 lb = early_date_ - PosIntDivDown(m, early_cost_);
03871 var_->SetRange(lb, rb);
03872 } else {
03873 var_->SetMax(rb);
03874 }
03875 } else {
03876 if (early_cost_ != 0LL) {
03877 const int64 lb = early_date_ - PosIntDivDown(m, early_cost_);
03878 var_->SetMin(lb);
03879 }
03880 }
03881 }
03882
03883 virtual string name() const {
03884 return StringPrintf(
03885 "ConvexPiecewiseExpr(%s, ec = %" GG_LL_FORMAT "d, ed = %"
03886 GG_LL_FORMAT "d, ld = %" GG_LL_FORMAT "d, lc = %" GG_LL_FORMAT "d)",
03887 var_->name().c_str(),
03888 early_cost_, early_date_, late_date_, late_cost_);
03889 }
03890
03891 virtual string DebugString() const {
03892 return StringPrintf(
03893 "ConvexPiecewiseExpr(%s, ec = %" GG_LL_FORMAT "d, ed = %"
03894 GG_LL_FORMAT "d, ld = %" GG_LL_FORMAT "d, lc = %" GG_LL_FORMAT "d)",
03895 var_->DebugString().c_str(),
03896 early_cost_, early_date_, late_date_, late_cost_);
03897 }
03898
03899 virtual void WhenRange(Demon* d) {
03900 var_->WhenRange(d);
03901 }
03902
03903 virtual void Accept(ModelVisitor* const visitor) const {
03904 visitor->BeginVisitIntegerExpression(ModelVisitor::kConvexPiecewise, this);
03905 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03906 var_);
03907 visitor->VisitIntegerArgument(ModelVisitor::kEarlyCostArgument,
03908 early_cost_);
03909 visitor->VisitIntegerArgument(ModelVisitor::kEarlyDateArgument,
03910 early_date_);
03911 visitor->VisitIntegerArgument(ModelVisitor::kLateCostArgument,
03912 late_cost_);
03913 visitor->VisitIntegerArgument(ModelVisitor::kLateDateArgument,
03914 late_date_);
03915 visitor->EndVisitIntegerExpression(ModelVisitor::kConvexPiecewise, this);
03916 }
03917
03918 private:
03919 IntVar* const var_;
03920 const int64 early_cost_;
03921 const int64 early_date_;
03922 const int64 late_date_;
03923 const int64 late_cost_;
03924 };
03925
03926
03927
03928 class SemiContinuousExpr : public BaseIntExpr {
03929 public:
03930 SemiContinuousExpr(Solver* const s, IntExpr* const e,
03931 int64 fixed_charge, int64 step)
03932 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge), step_(step) {
03933 DCHECK_GE(fixed_charge, 0LL);
03934 DCHECK_GT(step, 0LL);
03935 }
03936
03937 virtual ~SemiContinuousExpr() {}
03938
03939 int64 Value(int64 x) const {
03940 if (x <= 0) {
03941 return 0;
03942 } else {
03943 return fixed_charge_ + x * step_;
03944 }
03945 }
03946
03947 virtual int64 Min() const {
03948 return Value(expr_->Min());
03949 }
03950
03951 virtual void SetMin(int64 m) {
03952 if (m >= fixed_charge_ + step_) {
03953 const int64 y = PosIntDivUp(m - fixed_charge_, step_);
03954 expr_->SetMin(y);
03955 } else if (m > 0) {
03956 expr_->SetMin(1);
03957 }
03958 }
03959
03960 virtual int64 Max() const {
03961 return Value(expr_->Max());
03962 }
03963
03964 virtual void SetMax(int64 m) {
03965 if (m < 0) {
03966 solver()->Fail();
03967 }
03968 if (m < fixed_charge_ + step_) {
03969 expr_->SetMax(0);
03970 } else {
03971 const int64 y = PosIntDivDown(m - fixed_charge_, step_);
03972 expr_->SetMax(y);
03973 }
03974 }
03975
03976 virtual string name() const {
03977 return StringPrintf("SemiContinuous(%s, fixed_charge = %" GG_LL_FORMAT
03978 "d, step = %" GG_LL_FORMAT "d)",
03979 expr_->name().c_str(), fixed_charge_, step_);
03980 }
03981
03982 virtual string DebugString() const {
03983 return StringPrintf("SemiContinuous(%s, fixed_charge = %" GG_LL_FORMAT
03984 "d, step = %" GG_LL_FORMAT "d)",
03985 expr_->DebugString().c_str(), fixed_charge_, step_);
03986 }
03987
03988 virtual void WhenRange(Demon* d) {
03989 expr_->WhenRange(d);
03990 }
03991
03992 virtual void Accept(ModelVisitor* const visitor) const {
03993 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous, this);
03994 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
03995 expr_);
03996 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
03997 fixed_charge_);
03998 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, step_);
03999 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous, this);
04000 }
04001
04002 private:
04003 IntExpr* const expr_;
04004 const int64 fixed_charge_;
04005 const int64 step_;
04006 };
04007
04008 class SemiContinuousStepOneExpr : public BaseIntExpr {
04009 public:
04010 SemiContinuousStepOneExpr(Solver* const s, IntExpr* const e,
04011 int64 fixed_charge)
04012 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) {
04013 DCHECK_GE(fixed_charge, 0LL);
04014 }
04015
04016 virtual ~SemiContinuousStepOneExpr() {}
04017
04018 int64 Value(int64 x) const {
04019 if (x <= 0) {
04020 return 0;
04021 } else {
04022 return fixed_charge_ + x;
04023 }
04024 }
04025
04026 virtual int64 Min() const {
04027 return Value(expr_->Min());
04028 }
04029
04030 virtual void SetMin(int64 m) {
04031 if (m >= fixed_charge_ + 1) {
04032 expr_->SetMin(m - fixed_charge_);
04033 } else if (m > 0) {
04034 expr_->SetMin(1);
04035 }
04036 }
04037
04038 virtual int64 Max() const {
04039 return Value(expr_->Max());
04040 }
04041
04042 virtual void SetMax(int64 m) {
04043 if (m < 0) {
04044 solver()->Fail();
04045 }
04046 if (m < fixed_charge_ + 1) {
04047 expr_->SetMax(0);
04048 } else {
04049 expr_->SetMax(m - fixed_charge_);
04050 }
04051 }
04052
04053 virtual string name() const {
04054 return StringPrintf("SemiContinuousStepOne(%s, fixed_charge = %"
04055 GG_LL_FORMAT "d)",
04056 expr_->name().c_str(), fixed_charge_);
04057 }
04058
04059 virtual string DebugString() const {
04060 return StringPrintf("SemiContinuousStepOne(%s, fixed_charge = %"
04061 GG_LL_FORMAT "d)",
04062 expr_->DebugString().c_str(), fixed_charge_);
04063 }
04064
04065 virtual void WhenRange(Demon* d) {
04066 expr_->WhenRange(d);
04067 }
04068
04069 virtual void Accept(ModelVisitor* const visitor) const {
04070 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous, this);
04071 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
04072 expr_);
04073 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
04074 fixed_charge_);
04075 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 1);
04076 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous, this);
04077 }
04078
04079 private:
04080 IntExpr* const expr_;
04081 const int64 fixed_charge_;
04082 };
04083
04084 class SemiContinuousStepZeroExpr : public BaseIntExpr {
04085 public:
04086 SemiContinuousStepZeroExpr(Solver* const s, IntExpr* const e,
04087 int64 fixed_charge)
04088 : BaseIntExpr(s), expr_(e), fixed_charge_(fixed_charge) {
04089 DCHECK_GT(fixed_charge, 0LL);
04090 }
04091
04092 virtual ~SemiContinuousStepZeroExpr() {}
04093
04094 int64 Value(int64 x) const {
04095 if (x <= 0) {
04096 return 0;
04097 } else {
04098 return fixed_charge_;
04099 }
04100 }
04101
04102 virtual int64 Min() const {
04103 return Value(expr_->Min());
04104 }
04105
04106 virtual void SetMin(int64 m) {
04107 if (m >= fixed_charge_) {
04108 solver()->Fail();
04109 } else if (m > 0) {
04110 expr_->SetMin(1);
04111 }
04112 }
04113
04114 virtual int64 Max() const {
04115 return Value(expr_->Max());
04116 }
04117
04118 virtual void SetMax(int64 m) {
04119 if (m < 0) {
04120 solver()->Fail();
04121 }
04122 if (m < fixed_charge_) {
04123 expr_->SetMax(0);
04124 }
04125 }
04126
04127 virtual string name() const {
04128 return StringPrintf("SemiContinuousStepZero(%s, fixed_charge = %"
04129 GG_LL_FORMAT "d)",
04130 expr_->name().c_str(), fixed_charge_);
04131 }
04132
04133 virtual string DebugString() const {
04134 return StringPrintf("SemiContinuousStepZero(%s, fixed_charge = %"
04135 GG_LL_FORMAT "d)",
04136 expr_->DebugString().c_str(), fixed_charge_);
04137 }
04138
04139 virtual void WhenRange(Demon* d) {
04140 expr_->WhenRange(d);
04141 }
04142
04143 virtual void Accept(ModelVisitor* const visitor) const {
04144 visitor->BeginVisitIntegerExpression(ModelVisitor::kSemiContinuous, this);
04145 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
04146 expr_);
04147 visitor->VisitIntegerArgument(ModelVisitor::kFixedChargeArgument,
04148 fixed_charge_);
04149 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, 0);
04150 visitor->EndVisitIntegerExpression(ModelVisitor::kSemiContinuous, this);
04151 }
04152
04153 private:
04154 IntExpr* const expr_;
04155 const int64 fixed_charge_;
04156 };
04157
04158
04159 class LinkExprAndVar : public CastConstraint {
04160 public:
04161 LinkExprAndVar(Solver* const s,
04162 IntExpr* const expr,
04163 IntVar* const var) : CastConstraint(s, var), expr_(expr) {}
04164
04165 virtual ~LinkExprAndVar() {}
04166
04167 virtual void Post() {
04168 Solver* const s = solver();
04169 Demon* d = s->MakeConstraintInitialPropagateCallback(this);
04170 expr_->WhenRange(d);
04171 target_var_->WhenRange(d);
04172 }
04173
04174 virtual void InitialPropagate() {
04175 expr_->SetRange(target_var_->Min(), target_var_->Max());
04176 int64 l, u;
04177 expr_->Range(&l, &u);
04178 target_var_->SetRange(l, u);
04179 }
04180
04181 virtual string DebugString() const {
04182 return StringPrintf("cast(%s, %s)",
04183 expr_->DebugString().c_str(),
04184 target_var_->DebugString().c_str());
04185 }
04186
04187 virtual void Accept(ModelVisitor* const visitor) const {
04188 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar, this);
04189 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
04190 expr_);
04191 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
04192 target_var_);
04193 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar, this);
04194 }
04195
04196 private:
04197 IntExpr* const expr_;
04198 };
04199
04200
04201 class LinkExprAndDomainIntVar : public CastConstraint {
04202 public:
04203 LinkExprAndDomainIntVar(Solver* const s,
04204 IntExpr* const expr,
04205 DomainIntVar* const var)
04206 : CastConstraint(s, var), expr_(expr), cached_min_(kint64min),
04207 cached_max_(kint64max), fail_stamp_(GG_ULONGLONG(0)) {}
04208
04209 virtual ~LinkExprAndDomainIntVar() {}
04210
04211 DomainIntVar* var() const {
04212 return reinterpret_cast<DomainIntVar*>(target_var_);
04213 }
04214
04215 virtual void Post() {
04216 Solver* const s = solver();
04217 Demon* const d = s->MakeConstraintInitialPropagateCallback(this);
04218 expr_->WhenRange(d);
04219 Demon* const target_var_demon =
04220 MakeConstraintDemon0(solver(),
04221 this,
04222 &LinkExprAndDomainIntVar::Propagate,
04223 "Propagate");
04224 target_var_->WhenRange(target_var_demon);
04225 }
04226
04227 virtual void InitialPropagate() {
04228 expr_->SetRange(var()->min_.Value(), var()->max_.Value());
04229 expr_->Range(&cached_min_, &cached_max_);
04230 var()->DomainIntVar::SetRange(cached_min_, cached_max_);
04231 }
04232
04233 void Propagate() {
04234 if (var()->min_.Value() > cached_min_ ||
04235 var()->max_.Value() < cached_max_ ||
04236 solver()->fail_stamp() != fail_stamp_) {
04237 InitialPropagate();
04238 fail_stamp_ = solver()->fail_stamp();
04239 }
04240 }
04241
04242 virtual string DebugString() const {
04243 return StringPrintf("cast(%s, %s)",
04244 expr_->DebugString().c_str(),
04245 target_var_->DebugString().c_str());
04246 }
04247
04248 virtual void Accept(ModelVisitor* const visitor) const {
04249 visitor->BeginVisitConstraint(ModelVisitor::kLinkExprVar, this);
04250 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
04251 expr_);
04252 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
04253 target_var_);
04254 visitor->EndVisitConstraint(ModelVisitor::kLinkExprVar, this);
04255 }
04256
04257 private:
04258 IntExpr* const expr_;
04259 int64 cached_min_;
04260 int64 cached_max_;
04261 uint64 fail_stamp_;
04262 };
04263
04264
04265
04266
04267
04268 class VariableQueueCleaner : public Action {
04269 public:
04270 VariableQueueCleaner() : var_(NULL) {}
04271
04272 virtual ~VariableQueueCleaner() {}
04273
04274 virtual void Run(Solver* const solver) {
04275 DCHECK(var_ != NULL);
04276 var_->ClearInProcess();
04277 }
04278
04279 void set_var(DomainIntVar* const var) { var_ = var; }
04280
04281 private:
04282 DomainIntVar* var_;
04283 };
04284 }
04285
04286 Action* NewDomainIntVarCleaner() {
04287 return new VariableQueueCleaner;
04288 }
04289
04290 void Solver::set_queue_cleaner_on_fail(IntVar* const var) {
04291 DCHECK_EQ(DOMAIN_INT_VAR, var->VarType());
04292 DomainIntVar* const dvar = reinterpret_cast<DomainIntVar*>(var);
04293 VariableQueueCleaner* const cleaner =
04294 reinterpret_cast<VariableQueueCleaner*>(variable_cleaner_.get());
04295 cleaner->set_var(dvar);
04296 set_queue_action_on_fail(cleaner);
04297 }
04298
04299 void RestoreBoolValue(IntVar* const var) {
04300 DCHECK_EQ(BOOLEAN_VAR, var->VarType());
04301 BooleanVar* const boolean_var = reinterpret_cast<BooleanVar*>(var);
04302 boolean_var->RestoreValue();
04303 }
04304
04305
04306
04307 IntVar* Solver::MakeIntVar(int64 min, int64 max, const string& name) {
04308 if (min == max) {
04309 return RevAlloc(new IntConst(this, min, name));
04310 }
04311 if (min == 0 && max == 1) {
04312 return RegisterIntVar(RevAlloc(new BooleanVar(this, name)));
04313 } else {
04314 return RegisterIntVar(RevAlloc(new DomainIntVar(this, min, max, name)));
04315 }
04316 }
04317
04318 IntVar* Solver::MakeIntVar(int64 min, int64 max) {
04319 return MakeIntVar(min, max, "");
04320 }
04321
04322 IntVar* Solver::MakeBoolVar(const string& name) {
04323 return RegisterIntVar(RevAlloc(new BooleanVar(this, name)));
04324 }
04325
04326 IntVar* Solver::MakeBoolVar() {
04327 return RegisterIntVar(RevAlloc(new BooleanVar(this, "")));
04328 }
04329
04330 IntVar* Solver::MakeIntVar(const std::vector<int64>& values, const string& name) {
04331 ConstIntArray domain(values);
04332 scoped_ptr<std::vector<int64> > sorted_values(
04333 domain.SortedCopyWithoutDuplicates(true));
04334 IntVar* const var =
04335 RegisterIntVar(RevAlloc(new DomainIntVar(this,
04336 *sorted_values.get(),
04337 name)));
04338 return var;
04339 }
04340
04341 IntVar* Solver::MakeIntVar(const std::vector<int64>& values) {
04342 return MakeIntVar(values, "");
04343 }
04344
04345 IntVar* Solver::MakeIntVar(const std::vector<int>& values, const string& name) {
04346 ConstIntArray domain(values);
04347 scoped_ptr<std::vector<int64> > sorted_values(
04348 domain.SortedCopyWithoutDuplicates(true));
04349 IntVar* const var =
04350 RegisterIntVar(RevAlloc(new DomainIntVar(this,
04351 *sorted_values.get(),
04352 name)));
04353 return var;
04354 }
04355
04356 IntVar* Solver::MakeIntVar(const std::vector<int>& values) {
04357 return MakeIntVar(values, "");
04358 }
04359
04360 IntVar* Solver::MakeIntConst(int64 val, const string& name) {
04361
04362
04363
04364 if (FLAGS_cp_share_int_consts &&
04365 name.empty() &&
04366 val >= MIN_CACHED_INT_CONST && val <= MAX_CACHED_INT_CONST) {
04367 return cached_constants_[val - MIN_CACHED_INT_CONST];
04368 }
04369 return RevAlloc(new IntConst(this, val, name));
04370 }
04371
04372 IntVar* Solver::MakeIntConst(int64 val) {
04373 return MakeIntConst(val, "");
04374 }
04375
04376
04377
04378 namespace {
04379 string IndexedName(const string& prefix, int index, int max_index) {
04380 #if defined(_MSC_VER)
04381 const int digits = max_index > 0 ?
04382 static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
04383 1;
04384 #else
04385 const int digits = max_index > 0 ? static_cast<int>(log10(max_index)) + 1: 1;
04386 #endif
04387 return StringPrintf("%s%0*d", prefix.c_str(), digits, index);
04388 }
04389 }
04390
04391 void Solver::MakeIntVarArray(int var_count,
04392 int64 vmin,
04393 int64 vmax,
04394 const string& name,
04395 std::vector<IntVar*>* vars) {
04396 for (int i = 0; i < var_count; ++i) {
04397 vars->push_back(MakeIntVar(vmin, vmax, IndexedName(name, i, var_count)));
04398 }
04399 }
04400
04401 void Solver::MakeIntVarArray(int var_count,
04402 int64 vmin,
04403 int64 vmax,
04404 std::vector<IntVar*>* vars) {
04405 for (int i = 0; i < var_count; ++i) {
04406 vars->push_back(MakeIntVar(vmin, vmax));
04407 }
04408 }
04409
04410 IntVar** Solver::MakeIntVarArray(int var_count,
04411 int64 vmin,
04412 int64 vmax,
04413 const string& name) {
04414 IntVar** vars = new IntVar*[var_count];
04415 for (int i = 0; i < var_count; ++i) {
04416 vars[i] = MakeIntVar(vmin, vmax, IndexedName(name, i, var_count));
04417 }
04418 return vars;
04419 }
04420
04421 void Solver::MakeBoolVarArray(int var_count,
04422 const string& name,
04423 std::vector<IntVar*>* vars) {
04424 for (int i = 0; i < var_count; ++i) {
04425 vars->push_back(MakeBoolVar(IndexedName(name, i, var_count)));
04426 }
04427 }
04428
04429 void Solver::MakeBoolVarArray(int var_count, std::vector<IntVar*>* vars) {
04430 for (int i = 0; i < var_count; ++i) {
04431 vars->push_back(MakeBoolVar());
04432 }
04433 }
04434
04435 IntVar** Solver::MakeBoolVarArray(int var_count, const string& name) {
04436 IntVar** vars = new IntVar*[var_count];
04437 for (int i = 0; i < var_count; ++i) {
04438 vars[i] = MakeBoolVar(IndexedName(name, i, var_count));
04439 }
04440 return vars;
04441 }
04442
04443 void Solver::InitCachedIntConstants() {
04444 for (int i = MIN_CACHED_INT_CONST; i <= MAX_CACHED_INT_CONST; ++i) {
04445 cached_constants_[i - MIN_CACHED_INT_CONST] =
04446 RevAlloc(new IntConst(this, i, ""));
04447 }
04448 }
04449
04450 IntExpr* Solver::MakeSum(IntExpr* const l, IntExpr* const r) {
04451 CHECK_EQ(this, l->solver());
04452 CHECK_EQ(this, r->solver());
04453 if (r->Bound()) {
04454 return MakeSum(l, r->Min());
04455 }
04456 if (l->Bound()) {
04457 return MakeSum(r, l->Min());
04458 }
04459 if (l == r) {
04460 return MakeProd(l, 2);
04461 }
04462 return RegisterIntExpr(RevAlloc(new PlusIntExpr(this, l, r)));
04463 }
04464
04465 IntExpr* Solver::MakeSum(IntExpr* const e, int64 v) {
04466 CHECK_EQ(this, e->solver());
04467 if (e->Bound()) {
04468 return MakeIntConst(e->Min() + v);
04469 }
04470 if (v == 0) {
04471 return e;
04472 }
04473 return RegisterIntExpr(RevAlloc(new PlusIntCstExpr(this, e, v)));
04474 }
04475 IntExpr* Solver::MakeDifference(IntExpr* const l, IntExpr* const r) {
04476 CHECK_EQ(this, l->solver());
04477 CHECK_EQ(this, r->solver());
04478 if (l->Bound()) {
04479 return MakeDifference(l->Min(), r);
04480 }
04481 if (r->Bound()) {
04482 return MakeSum(l, -r->Min());
04483 }
04484 return RegisterIntExpr(RevAlloc(new SubIntExpr(this, l, r)));
04485 }
04486
04487 IntVar* Solver::MakeIsEqualVar(IntExpr* const v1, IntExpr* const v2) {
04488 CHECK_EQ(this, v1->solver());
04489 CHECK_EQ(this, v2->solver());
04490 if (v1->Bound()) {
04491 return MakeIsEqualCstVar(v2->Var(), v1->Min());
04492 } else if (v2->Bound()) {
04493 return MakeIsEqualCstVar(v1->Var(), v2->Min());
04494 }
04495 IntVar* const var1 = v1->Var();
04496 IntVar* const var2 = v2->Var();
04497 IntExpr* const cache = model_cache_->FindVarVarExpression(
04498 var1,
04499 var2,
04500 ModelCache::VAR_VAR_IS_EQUAL);
04501 if (cache != NULL) {
04502 return cache->Var();
04503 } else {
04504 string name1 = var1->name();
04505 if (name1.empty()) {
04506 name1 = var1->DebugString();
04507 }
04508 string name2 = var2->name();
04509 if (name2.empty()) {
04510 name2 = var2->DebugString();
04511 }
04512 IntVar* const boolvar = MakeIsEqualCstVar(MakeDifference(v1, v2)->Var(), 0);
04513 model_cache_->InsertVarVarExpression(
04514 boolvar,
04515 var1,
04516 var2,
04517 ModelCache::VAR_VAR_IS_EQUAL);
04518 return boolvar;
04519 }
04520 }
04521
04522 Constraint* Solver::MakeIsEqualCt(IntExpr* const v1,
04523 IntExpr* const v2,
04524 IntVar* b) {
04525 CHECK_EQ(this, v1->solver());
04526 CHECK_EQ(this, v2->solver());
04527 if (v1->Bound()) {
04528 return MakeIsEqualCstCt(v2->Var(), v1->Min(), b);
04529 } else if (v2->Bound()) {
04530 return MakeIsEqualCstCt(v1->Var(), v2->Min(), b);
04531 }
04532 return MakeIsEqualCstCt(MakeDifference(v1, v2)->Var(), 0, b);
04533 }
04534
04535 IntVar* Solver::MakeIsDifferentVar(IntExpr* const v1, IntExpr* const v2) {
04536 CHECK_EQ(this, v1->solver());
04537 CHECK_EQ(this, v2->solver());
04538 if (v1->Bound()) {
04539 return MakeIsDifferentCstVar(v2->Var(), v1->Min());
04540 } else if (v2->Bound()) {
04541 return MakeIsDifferentCstVar(v1->Var(), v2->Min());
04542 }
04543 IntVar* const var1 = v1->Var();
04544 IntVar* const var2 = v2->Var();
04545 IntExpr* const cache = model_cache_->FindVarVarExpression(
04546 var1,
04547 var2,
04548 ModelCache::VAR_VAR_IS_NOT_EQUAL);
04549 if (cache != NULL) {
04550 return cache->Var();
04551 } else {
04552 string name1 = var1->name();
04553 if (name1.empty()) {
04554 name1 = var1->DebugString();
04555 }
04556 string name2 = var2->name();
04557 if (name2.empty()) {
04558 name2 = var2->DebugString();
04559 }
04560 IntVar* const boolvar =
04561 MakeIsDifferentCstVar(MakeDifference(v1, v2)->Var(), 0);
04562 model_cache_->InsertVarVarExpression(
04563 boolvar,
04564 var1,
04565 var2,
04566 ModelCache::VAR_VAR_IS_NOT_EQUAL);
04567 return boolvar;
04568 }
04569 }
04570
04571 Constraint* Solver::MakeIsDifferentCt(IntExpr* const v1,
04572 IntExpr* const v2,
04573 IntVar* b) {
04574 CHECK_EQ(this, v1->solver());
04575 CHECK_EQ(this, v2->solver());
04576 if (v1->Bound()) {
04577 return MakeIsDifferentCstCt(v2->Var(), v1->Min(), b);
04578 } else if (v2->Bound()) {
04579 return MakeIsDifferentCstCt(v1->Var(), v2->Min(), b);
04580 }
04581 return MakeIsDifferentCstCt(MakeDifference(v1, v2)->Var(), 0, b);
04582 }
04583
04584 IntVar* Solver::MakeIsLessOrEqualVar(
04585 IntExpr* const left, IntExpr* const right) {
04586 CHECK_EQ(this, left->solver());
04587 CHECK_EQ(this, right->solver());
04588 if (left->Bound()) {
04589 return MakeIsGreaterOrEqualCstVar(right->Var(), left->Min());
04590 } else if (right->Bound()) {
04591 return MakeIsLessOrEqualCstVar(left->Var(), right->Min());
04592 }
04593 IntVar* const var1 = left->Var();
04594 IntVar* const var2 = right->Var();
04595 IntExpr* const cache = model_cache_->FindVarVarExpression(
04596 var1,
04597 var2,
04598 ModelCache::VAR_VAR_IS_LESS_OR_EQUAL);
04599 if (cache != NULL) {
04600 return cache->Var();
04601 } else {
04602 string name1 = var1->name();
04603 if (name1.empty()) {
04604 name1 = var1->DebugString();
04605 }
04606 string name2 = var2->name();
04607 if (name2.empty()) {
04608 name2 = var2->DebugString();
04609 }
04610 IntVar* const boolvar =
04611 MakeIsLessOrEqualCstVar(MakeDifference(left, right)->Var(), 0);
04612 model_cache_->InsertVarVarExpression(
04613 boolvar,
04614 var1,
04615 var2,
04616 ModelCache::VAR_VAR_IS_LESS_OR_EQUAL);
04617 return boolvar;
04618 }
04619 }
04620
04621 Constraint* Solver::MakeIsLessOrEqualCt(
04622 IntExpr* const left, IntExpr* const right, IntVar* const b) {
04623 CHECK_EQ(this, left->solver());
04624 CHECK_EQ(this, right->solver());
04625 if (left->Bound()) {
04626 return MakeIsGreaterOrEqualCstCt(right->Var(), left->Min(), b);
04627 } else if (right->Bound()) {
04628 return MakeIsLessOrEqualCstCt(left->Var(), right->Min(), b);
04629 }
04630 return MakeIsLessOrEqualCstCt(MakeDifference(left, right)->Var(), 0, b);
04631 }
04632
04633 IntVar* Solver::MakeIsLessVar(
04634 IntExpr* const left, IntExpr* const right) {
04635 CHECK_EQ(this, left->solver());
04636 CHECK_EQ(this, right->solver());
04637 if (left->Bound()) {
04638 return MakeIsGreaterCstVar(right->Var(), left->Min());
04639 } else if (right->Bound()) {
04640 return MakeIsLessCstVar(left->Var(), right->Min());
04641 }
04642 IntVar* const var1 = left->Var();
04643 IntVar* const var2 = right->Var();
04644 IntExpr* const cache = model_cache_->FindVarVarExpression(
04645 var1,
04646 var2,
04647 ModelCache::VAR_VAR_IS_LESS);
04648 if (cache != NULL) {
04649 return cache->Var();
04650 } else {
04651 string name1 = var1->name();
04652 if (name1.empty()) {
04653 name1 = var1->DebugString();
04654 }
04655 string name2 = var2->name();
04656 if (name2.empty()) {
04657 name2 = var2->DebugString();
04658 }
04659 IntVar* const boolvar =
04660 MakeIsLessCstVar(MakeDifference(left, right)->Var(), 0);
04661 model_cache_->InsertVarVarExpression(
04662 boolvar,
04663 var1,
04664 var2,
04665 ModelCache::VAR_VAR_IS_LESS);
04666 return boolvar;
04667 }
04668 }
04669
04670 Constraint* Solver::MakeIsLessCt(
04671 IntExpr* const left, IntExpr* const right, IntVar* const b) {
04672 CHECK_EQ(this, left->solver());
04673 CHECK_EQ(this, right->solver());
04674 if (left->Bound()) {
04675 return MakeIsGreaterCstCt(right->Var(), left->Min(), b);
04676 } else if (right->Bound()) {
04677 return MakeIsLessCstCt(left->Var(), right->Min(), b);
04678 }
04679 return MakeIsLessCstCt(MakeDifference(left, right)->Var(), 0, b);
04680 }
04681
04682 IntVar* Solver::MakeIsGreaterOrEqualVar(
04683 IntExpr* const left, IntExpr* const right) {
04684 return MakeIsLessOrEqualVar(right, left);
04685 }
04686
04687 Constraint* Solver::MakeIsGreaterOrEqualCt(
04688 IntExpr* const left, IntExpr* const right, IntVar* const b) {
04689
04690 return MakeIsLessOrEqualCt(right, left, b);
04691 }
04692
04693 IntVar* Solver::MakeIsGreaterVar(
04694 IntExpr* const left, IntExpr* const right) {
04695 return MakeIsLessVar(right, left);
04696 }
04697
04698 Constraint* Solver::MakeIsGreaterCt(
04699 IntExpr* const left, IntExpr* const right, IntVar* const b) {
04700 return MakeIsLessCt(right, left, b);
04701 }
04702
04703
04704 IntExpr* Solver::MakeDifference(int64 v, IntExpr* const e) {
04705 CHECK_EQ(this, e->solver());
04706 if (e->Bound()) {
04707 return MakeIntConst(v - e->Min());
04708 }
04709 if (v == 0) {
04710 return MakeOpposite(e);
04711 }
04712 return RegisterIntExpr(RevAlloc(new SubIntCstExpr(this, e, v)));
04713 }
04714
04715 IntExpr* Solver::MakeOpposite(IntExpr* const e) {
04716 CHECK_EQ(this, e->solver());
04717 if (e->Bound()) {
04718 return MakeIntConst(-e->Min());
04719 }
04720 if (e->IsVar()) {
04721 return RegisterIntVar(RevAlloc(new OppIntExpr(this, e))->Var());
04722 } else {
04723 return RegisterIntExpr(RevAlloc(new OppIntExpr(this, e)));
04724 }
04725 }
04726
04727 IntExpr* Solver::MakeProd(IntExpr* const e, int64 v) {
04728 CHECK_EQ(this, e->solver());
04729 IntExpr* result;
04730 if (e->Bound()) {
04731 return MakeIntConst(v * e->Min());
04732 } else if (v == 1) {
04733 return e;
04734 } else if (v == -1) {
04735 return MakeOpposite(e);
04736 } else if (v > 0) {
04737 result = RegisterIntExpr(RevAlloc(new TimesIntPosCstExpr(this, e, v)));
04738 } else if (v == 0) {
04739 result = MakeIntConst(0);
04740 } else {
04741 result = RegisterIntExpr(RevAlloc(new TimesIntNegCstExpr(this, e, v)));
04742 }
04743 if (e->IsVar() && !FLAGS_cp_disable_expression_optimization) {
04744 result = result->Var();
04745 }
04746 return result;
04747 }
04748
04749 IntExpr* Solver::MakeProd(IntExpr* const l, IntExpr* const r) {
04750 if (l->Bound()) {
04751 return MakeProd(r, l->Min());
04752 }
04753 if (r->Bound()) {
04754 return MakeProd(l, r->Min());
04755 }
04756 if (l == r) {
04757 return MakeSquare(l);
04758 }
04759 CHECK_EQ(this, l->solver());
04760 CHECK_EQ(this, r->solver());
04761 if (l->IsVar() &&
04762 reinterpret_cast<IntVar*>(l)->VarType() == BOOLEAN_VAR) {
04763 if (r->Min() >= 0) {
04764 return RegisterIntExpr(RevAlloc(
04765 new TimesBooleanPosIntExpr(this,
04766 reinterpret_cast<BooleanVar*>(l), r)));
04767 } else {
04768 return RegisterIntExpr(RevAlloc(
04769 new TimesBooleanIntExpr(this, reinterpret_cast<BooleanVar*>(l), r)));
04770 }
04771 }
04772 if (r->IsVar() &&
04773 reinterpret_cast<IntVar*>(r)->VarType() == BOOLEAN_VAR) {
04774 if (l->Min() >= 0) {
04775 return RegisterIntExpr(RevAlloc(
04776 new TimesBooleanPosIntExpr(this,
04777 reinterpret_cast<BooleanVar*>(r), l)));
04778 } else {
04779 return RegisterIntExpr(RevAlloc(
04780 new TimesBooleanIntExpr(this, reinterpret_cast<BooleanVar*>(r), l)));
04781 }
04782 }
04783 if (l->Min() >= 0 && r->Min() >= 0) {
04784 return RegisterIntExpr(RevAlloc(new TimesIntPosExpr(this, l, r)));
04785 } else {
04786 return RegisterIntExpr(RevAlloc(new TimesIntExpr(this, l, r)));
04787 }
04788 }
04789
04790 IntExpr* Solver::MakeDiv(IntExpr* const numerator, IntExpr* const denominator) {
04791
04792
04793 AddConstraint(MakeGreater(denominator, 0));
04794 IntVar* const result = MakeIntVar(0, numerator->Max());
04795 IntExpr* const product = MakeProd(denominator, result);
04796
04797
04798
04799
04800 AddConstraint(MakeGreaterOrEqual(numerator->Var(), product->Var()));
04801
04802 IntExpr* const product_up = RegisterIntExpr(MakeSum(product, denominator));
04803 AddConstraint(MakeLess(numerator->Var(), product_up->Var()));
04804 return result;
04805 }
04806
04807 IntExpr* Solver::MakeDiv(IntExpr* const e, int64 v) {
04808 CHECK(e != NULL);
04809 CHECK_EQ(this, e->solver());
04810 if (e->Bound()) {
04811 return MakeIntConst(PosIntDivDown(e->Min(), v));
04812 } else if (v == 1) {
04813 return e;
04814 } else if (v == -1) {
04815 return MakeOpposite(e);
04816 } else if (v > 0) {
04817 return RegisterIntExpr(RevAlloc(new DivIntPosCstExpr(this, e, v)));
04818 } else if (v == 0) {
04819 LOG(FATAL) << "Cannot divide by 0";
04820 return NULL;
04821 } else {
04822 return RegisterIntExpr(
04823 MakeOpposite(RevAlloc(new DivIntPosCstExpr(this, e, -v))));
04824
04825 }
04826 }
04827
04828 IntExpr* Solver::MakeAbs(IntExpr* const e) {
04829 CHECK_EQ(this, e->solver());
04830 if (e->Min() >= 0) {
04831 return e;
04832 } else if (e->Max() <= 0) {
04833 return MakeOpposite(e);
04834 }
04835 return RegisterIntExpr(RevAlloc(new IntAbs(this, e)));
04836 }
04837
04838 IntExpr* Solver::MakeSquare(IntExpr* const e) {
04839 CHECK_EQ(this, e->solver());
04840 if (e->Bound()) {
04841 const int64 v = e->Min();
04842 return MakeIntConst(v * v);
04843 }
04844 if (e->Min() >= 0) {
04845 return RegisterIntExpr(RevAlloc(new PosIntSquare(this, e)));
04846 }
04847 return RegisterIntExpr(RevAlloc(new IntSquare(this, e)));
04848 }
04849
04850 IntExpr* Solver::MakeMin(IntExpr* const l, IntExpr* const r) {
04851 CHECK_EQ(this, l->solver());
04852 CHECK_EQ(this, r->solver());
04853 if (l->Bound()) {
04854 return MakeMin(r, l->Min());
04855 }
04856 if (r->Bound()) {
04857 return MakeMin(l, r->Min());
04858 }
04859 if (l->Min() > r->Max()) {
04860 return r;
04861 }
04862 if (r->Min() > l->Max()) {
04863 return l;
04864 }
04865 return RegisterIntExpr(RevAlloc(new MinIntExpr(this, l, r)));
04866 }
04867
04868 IntExpr* Solver::MakeMin(IntExpr* const e, int64 v) {
04869 CHECK_EQ(this, e->solver());
04870 if (v < e->Min()) {
04871 return MakeIntConst(v);
04872 }
04873 if (e->Bound()) {
04874 return MakeIntConst(std::min(e->Min(), v));
04875 }
04876 if (e->Max() < v) {
04877 return e;
04878 }
04879 return RegisterIntExpr(RevAlloc(new MinCstIntExpr(this, e, v)));
04880 }
04881
04882 IntExpr* Solver::MakeMin(IntExpr* const e, int v) {
04883 return MakeMin(e, static_cast<int64>(v));
04884 }
04885
04886 IntExpr* Solver::MakeMax(IntExpr* const l, IntExpr* const r) {
04887 CHECK_EQ(this, l->solver());
04888 CHECK_EQ(this, r->solver());
04889 if (l->Bound()) {
04890 return MakeMax(r, l->Min());
04891 }
04892 if (r->Bound()) {
04893 return MakeMax(l, r->Min());
04894 }
04895 if (l->Min() > r->Max()) {
04896 return l;
04897 }
04898 if (r->Min() > l->Max()) {
04899 return r;
04900 }
04901 return RegisterIntExpr(RevAlloc(new MaxIntExpr(this, l, r)));
04902 }
04903
04904 IntExpr* Solver::MakeMax(IntExpr* const e, int64 v) {
04905 CHECK_EQ(this, e->solver());
04906 if (e->Bound()) {
04907 return MakeIntConst(std::max(e->Min(), v));
04908 }
04909 if (v < e->Min()) {
04910 return e;
04911 }
04912 if (e->Max() < v) {
04913 return MakeIntConst(v);
04914 }
04915 return RegisterIntExpr(RevAlloc(new MaxCstIntExpr(this, e, v)));
04916 }
04917
04918 IntExpr* Solver::MakeMax(IntExpr* const e, int v) {
04919 return MakeMax(e, static_cast<int64>(v));
04920 }
04921
04922 IntExpr* Solver::MakeConvexPiecewiseExpr(IntVar* e,
04923 int64 early_cost, int64 early_date,
04924 int64 late_date, int64 late_cost) {
04925 return RegisterIntExpr(RevAlloc(
04926 new SimpleConvexPiecewiseExpr(this, e,
04927 early_cost, early_date,
04928 late_date, late_cost)));
04929 }
04930
04931 IntExpr* Solver::MakeSemiContinuousExpr(IntExpr* const e,
04932 int64 fixed_charge,
04933 int64 step) {
04934 if (step == 0) {
04935 if (fixed_charge == 0) {
04936 return MakeIntConst(0LL);
04937 } else {
04938 return RegisterIntExpr(RevAlloc(
04939 new SemiContinuousStepZeroExpr(this, e, fixed_charge)));
04940 }
04941 } else if (step == 1) {
04942 return RegisterIntExpr(RevAlloc(
04943 new SemiContinuousStepOneExpr(this, e, fixed_charge)));
04944 } else {
04945 return RegisterIntExpr(RevAlloc(
04946 new SemiContinuousExpr(this, e, fixed_charge, step)));
04947 }
04948
04949
04950 }
04951
04952
04953
04954 int IntVar::VarType() const {
04955 return UNSPECIFIED;
04956 }
04957
04958 void IntVar::RemoveValues(const int64* const values, int size) {
04959 DCHECK_GE(size, 0);
04960 for (int i = 0; i < size; ++i) {
04961 RemoveValue(values[i]);
04962 }
04963 }
04964
04965 void IntVar::Accept(ModelVisitor* const visitor) const {
04966 const IntExpr* casted = NULL;
04967 const Solver::IntegerCastInfo* const cast_info =
04968 FindOrNull(solver()->cast_information_, this);
04969 if (cast_info != NULL) {
04970 casted = cast_info->expression;
04971 }
04972 visitor->VisitIntegerVariable(this, casted);
04973 }
04974
04975 void IntVar::SetValues(const int64* const values, int size) {
04976
04977
04978 const int64* const new_array = IsArrayActuallySorted(values, size) ?
04979 values :
04980 NewUniqueSortedArray(values, &size);
04981 const int64 vmin = Min();
04982 const int64 vmax = Max();
04983 const int64* first_pos = new_array;
04984 const int64* last_pos = first_pos + size - 1;
04985 if (*first_pos > vmax || *last_pos < vmin) {
04986 solver()->Fail();
04987 }
04988
04989 while (first_pos <= last_pos &&
04990 (*first_pos < vmin || !Contains(*first_pos))) {
04991 if (*first_pos > vmax) {
04992 solver()->Fail();
04993 }
04994 first_pos++;
04995 }
04996 if (first_pos > last_pos) {
04997 solver()->Fail();
04998 }
04999 while (last_pos >= first_pos &&
05000 (*last_pos > vmax ||
05001 !Contains(*last_pos))) {
05002 last_pos--;
05003 }
05004 DCHECK_GE(last_pos, first_pos);
05005 SetRange(*first_pos, *last_pos);
05006 while (first_pos < last_pos) {
05007 const int64 start = (*first_pos) + 1;
05008 const int64 end = *(first_pos + 1) - 1;
05009 if (start <= end) {
05010 RemoveInterval(start, end);
05011 }
05012 first_pos++;
05013 }
05014 }
05015
05016
05017
05018 void LinkVarExpr(Solver* const s, IntExpr* const expr, IntVar* const var) {
05019 if (!var->Bound()) {
05020 if (var->VarType() == DOMAIN_INT_VAR) {
05021 DomainIntVar* dvar = reinterpret_cast<DomainIntVar*>(var);
05022 s->AddCastConstraint(
05023 s->RevAlloc(new LinkExprAndDomainIntVar(s, expr, dvar)), dvar, expr);
05024 } else {
05025 s->AddCastConstraint(
05026 s->RevAlloc(new LinkExprAndVar(s, expr, var)), var, expr);
05027 }
05028 }
05029 }
05030
05031 IntVar* BaseIntExpr::Var() {
05032 if (var_ == NULL) {
05033 solver()->SaveValue(reinterpret_cast<void**>(&var_));
05034 var_ = CastToVar();
05035 }
05036 return var_;
05037 }
05038
05039 IntVar* BaseIntExpr::CastToVar() {
05040 int64 vmin, vmax;
05041 Range(&vmin, &vmax);
05042 IntVar* const var = solver()->MakeIntVar(vmin, vmax);
05043 LinkVarExpr(solver(), this, var);
05044 return var;
05045 }
05046 }