00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string>
00015 #include <vector>
00016
00017 #include "base/integral_types.h"
00018 #include "base/logging.h"
00019 #include "base/macros.h"
00020 #include "base/stringprintf.h"
00021 #include "constraint_solver/constraint_solver.h"
00022 #include "constraint_solver/constraint_solveri.h"
00023
00024 #if defined(_MSC_VER)
00025 #pragma warning(disable : 4351 4355 4804 4805)
00026 #endif
00027
00028 namespace operations_research {
00029
00030
00031
00032
00033
00034 const int64 IntervalVar::kMaxValidValue = kint64max >> 2;
00035 const int64 IntervalVar::kMinValidValue = -kMaxValidValue;
00036
00037 namespace {
00038
00039
00040 class MirrorIntervalVar : public IntervalVar {
00041 public:
00042 MirrorIntervalVar(Solver* const s, IntervalVar* const t)
00043 : IntervalVar(s, "Mirror<" + t->name() + ">"), t_(t) {}
00044 virtual ~MirrorIntervalVar() {}
00045
00046
00047
00048 virtual int64 StartMin() const { return -t_->EndMax(); }
00049 virtual int64 StartMax() const { return -t_->EndMin(); }
00050 virtual void SetStartMin(int64 m) { t_->SetEndMax(-m); }
00051 virtual void SetStartMax(int64 m) { t_->SetEndMin(-m); }
00052 virtual void SetStartRange(int64 mi, int64 ma) { t_->SetEndRange(-ma, -mi); }
00053 virtual void WhenStartRange(Demon* const d) { t_->WhenEndRange(d); }
00054 virtual void WhenStartBound(Demon* const d) { t_->WhenEndBound(d); }
00055
00056
00057 virtual int64 DurationMin() const { return t_->DurationMin(); }
00058 virtual int64 DurationMax() const { return t_->DurationMax(); }
00059 virtual void SetDurationMin(int64 m) { t_->SetDurationMin(m); }
00060 virtual void SetDurationMax(int64 m) { t_->SetDurationMax(m); }
00061 virtual void SetDurationRange(int64 mi, int64 ma) {
00062 t_->SetDurationRange(mi, ma);
00063 }
00064 virtual void WhenDurationRange(Demon* const d) { t_->WhenDurationRange(d); }
00065 virtual void WhenDurationBound(Demon* const d) { t_->WhenDurationBound(d); }
00066
00067
00068 virtual int64 EndMin() const { return -t_->StartMax(); }
00069 virtual int64 EndMax() const { return -t_->StartMin(); }
00070 virtual void SetEndMin(int64 m) { t_->SetStartMax(-m); }
00071 virtual void SetEndMax(int64 m) { t_->SetStartMin(-m); }
00072 virtual void SetEndRange(int64 mi, int64 ma) { t_->SetStartRange(-ma, -mi); }
00073 virtual void WhenEndRange(Demon* const d) { t_->WhenStartRange(d); }
00074 virtual void WhenEndBound(Demon* const d) { t_->WhenStartBound(d); }
00075
00076
00077
00078 virtual bool MustBePerformed() const { return t_->MustBePerformed(); }
00079 virtual bool MayBePerformed() const { return t_->MayBePerformed(); }
00080 virtual void SetPerformed(bool val) { t_->SetPerformed(val); }
00081 virtual void WhenPerformedBound(Demon* const d) { t_->WhenPerformedBound(d); }
00082
00083 virtual void Accept(ModelVisitor* const visitor) const {
00084 visitor->VisitIntervalVariable(this, ModelVisitor::kMirrorOperation, t_);
00085 }
00086
00087 private:
00088 IntervalVar* const t_;
00089 DISALLOW_COPY_AND_ASSIGN(MirrorIntervalVar);
00090 };
00091 }
00092
00093 IntervalVar* Solver::MakeMirrorInterval(IntervalVar* const t) {
00094 return RegisterIntervalVar(RevAlloc(new MirrorIntervalVar(this, t)));
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 namespace {
00111
00112
00113 class AlwaysPerformedIntervalVarWrapper : public IntervalVar {
00114 public:
00115 explicit AlwaysPerformedIntervalVarWrapper(IntervalVar* const t)
00116 : IntervalVar(t->solver(),
00117 StringPrintf("AlwaysPerformed<%s>", t->name().c_str())),
00118 t_(t) {}
00119 virtual ~AlwaysPerformedIntervalVarWrapper() {}
00120 virtual int64 StartMin() const {
00121 return MayUnderlyingBePerformed()? t_->StartMin() : kMinValidValue;
00122 }
00123 virtual int64 StartMax() const {
00124 return MayUnderlyingBePerformed() ? t_->StartMax() : kMaxValidValue;
00125 }
00126 virtual void SetStartMin(int64 m) { t_->SetStartMin(m); }
00127 virtual void SetStartMax(int64 m) { t_->SetStartMax(m); }
00128 virtual void SetStartRange(int64 mi, int64 ma) { t_->SetStartRange(mi, ma); }
00129 virtual void WhenStartRange(Demon* const d) { t_->WhenStartRange(d); }
00130 virtual void WhenStartBound(Demon* const d) { t_->WhenStartBound(d); }
00131 virtual int64 DurationMin() const {
00132 return MayUnderlyingBePerformed() ? t_->DurationMin() : 0LL;
00133 }
00134 virtual int64 DurationMax() const {
00135 return MayUnderlyingBePerformed() ? t_->DurationMax() : 0LL;
00136 }
00137 virtual void SetDurationMin(int64 m) { t_->SetDurationMin(m); }
00138 virtual void SetDurationMax(int64 m) { t_->SetDurationMax(m); }
00139 virtual void SetDurationRange(int64 mi, int64 ma) {
00140 t_->SetDurationRange(mi, ma);
00141 }
00142 virtual void WhenDurationRange(Demon* const d) { t_->WhenDurationRange(d); }
00143 virtual void WhenDurationBound(Demon* const d) { t_->WhenDurationBound(d); }
00144 virtual int64 EndMin() const {
00145 return MayUnderlyingBePerformed() ? t_->EndMin() : kMinValidValue;
00146 }
00147 virtual int64 EndMax() const {
00148 return MayUnderlyingBePerformed() ? t_->EndMax() : kMaxValidValue;
00149 }
00150 virtual void SetEndMin(int64 m) { t_->SetEndMin(m); }
00151 virtual void SetEndMax(int64 m) { t_->SetEndMax(m); }
00152 virtual void SetEndRange(int64 mi, int64 ma) { t_->SetEndRange(mi, ma); }
00153 virtual void WhenEndRange(Demon* const d) { t_->WhenEndRange(d); }
00154 virtual void WhenEndBound(Demon* const d) { t_->WhenEndBound(d); }
00155 virtual bool MustBePerformed() const { return true; }
00156 virtual bool MayBePerformed() const { return true; }
00157 virtual void SetPerformed(bool val) {
00158
00159
00160
00161
00162 if (!val) {
00163 solver()->Fail();
00164 }
00165 }
00166 virtual void WhenPerformedBound(Demon* const d) { t_->WhenPerformedBound(d); }
00167
00168 protected:
00169 const IntervalVar* const underlying() const { return t_; }
00170 bool MayUnderlyingBePerformed() const {
00171 return underlying()->MayBePerformed();
00172 }
00173
00174 private:
00175 IntervalVar* const t_;
00176 DISALLOW_COPY_AND_ASSIGN(AlwaysPerformedIntervalVarWrapper);
00177 };
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 class IntervalVarRelaxedMax : public AlwaysPerformedIntervalVarWrapper {
00193 public:
00194 explicit IntervalVarRelaxedMax(IntervalVar* const t)
00195 : AlwaysPerformedIntervalVarWrapper(t) {}
00196 virtual ~IntervalVarRelaxedMax() {}
00197 virtual int64 StartMax() const {
00198
00199 return underlying()->MustBePerformed() ?
00200 underlying()->StartMax() : (kMaxValidValue - DurationMin());
00201 }
00202 virtual void SetStartMax(int64 m) {
00203 LOG(FATAL)
00204 << "Calling SetStartMax on a IntervalVarRelaxedMax is not supported, "
00205 << "as it seems there is no legitimate use case.";
00206 }
00207 virtual int64 EndMax() const {
00208 return underlying()->MustBePerformed() ?
00209 underlying()->EndMax() : kMaxValidValue;
00210 }
00211 virtual void SetEndMax(int64 m) {
00212 LOG(FATAL)
00213 << "Calling SetEndMax on a IntervalVarRelaxedMax is not supported, "
00214 << "as it seems there is no legitimate use case.";
00215 }
00216
00217 virtual void Accept(ModelVisitor* const visitor) const {
00218 visitor->VisitIntervalVariable(this,
00219 ModelVisitor::kRelaxedMaxOperation,
00220 underlying());
00221 }
00222 };
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 class IntervalVarRelaxedMin : public AlwaysPerformedIntervalVarWrapper {
00239 public:
00240 explicit IntervalVarRelaxedMin(IntervalVar* const t)
00241 : AlwaysPerformedIntervalVarWrapper(t) {}
00242 virtual ~IntervalVarRelaxedMin() {}
00243 virtual int64 StartMin() const {
00244 return underlying()->MustBePerformed() ?
00245 underlying()->StartMin() : kMinValidValue;
00246 }
00247 virtual void SetStartMin(int64 m) {
00248 LOG(FATAL)
00249 << "Calling SetStartMin on a IntervalVarRelaxedMin is not supported, "
00250 << "as it seems there is no legitimate use case.";
00251 }
00252 virtual int64 EndMin() const {
00253
00254 return underlying()->MustBePerformed() ?
00255 underlying()->EndMin() : (kMinValidValue + DurationMin());
00256 }
00257 virtual void SetEndMin(int64 m) {
00258 LOG(FATAL)
00259 << "Calling SetEndMin on a IntervalVarRelaxedMin is not supported, "
00260 << "as it seems there is no legitimate use case.";
00261 }
00262
00263 virtual void Accept(ModelVisitor* const visitor) const {
00264 visitor->VisitIntervalVariable(this,
00265 ModelVisitor::kRelaxedMinOperation,
00266 underlying());
00267 }
00268 };
00269 }
00270
00271 IntervalVar* Solver::MakeIntervalRelaxedMax(IntervalVar* const interval_var) {
00272 if (interval_var->MustBePerformed()) {
00273 return interval_var;
00274 } else {
00275 return RegisterIntervalVar(
00276 RevAlloc(new IntervalVarRelaxedMax(interval_var)));
00277 }
00278 }
00279
00280 IntervalVar* Solver::MakeIntervalRelaxedMin(IntervalVar* const interval_var) {
00281 if (interval_var->MustBePerformed()) {
00282 return interval_var;
00283 } else {
00284 return RegisterIntervalVar(
00285 RevAlloc(new IntervalVarRelaxedMin(interval_var)));
00286 }
00287 }
00288
00289 namespace {
00290 class IntervalVarStartExpr : public BaseIntExpr {
00291 public:
00292 explicit IntervalVarStartExpr(IntervalVar* const i)
00293 : BaseIntExpr(i->solver()), interval_(i) {}
00294 virtual ~IntervalVarStartExpr() {}
00295
00296 virtual int64 Min() const {
00297 return interval_->StartMin();
00298 }
00299
00300 virtual void SetMin(int64 m) {
00301 interval_->SetStartMin(m);
00302 }
00303
00304 virtual int64 Max() const {
00305 return interval_->StartMax();
00306 }
00307
00308 virtual void SetMax(int64 m) {
00309 interval_->SetStartMax(m);
00310 }
00311
00312 virtual void SetRange(int64 l, int64 u) {
00313 interval_->SetStartRange(l, u);
00314 }
00315
00316 virtual void SetValue(int64 v) {
00317 interval_->SetStartRange(v, v);
00318 }
00319
00320 virtual bool Bound() const {
00321 return interval_->StartMin() == interval_->StartMax();
00322 }
00323
00324 virtual void WhenRange(Demon* d) {
00325 interval_->WhenStartRange(d);
00326 }
00327
00328 virtual string DebugString() const {
00329 return StringPrintf("start(%s)", interval_->DebugString().c_str());
00330 }
00331
00332 virtual void Accept(ModelVisitor* const visitor) const {
00333 visitor->BeginVisitIntegerExpression(ModelVisitor::kStartExpr, this);
00334 visitor->VisitIntervalArgument(ModelVisitor::kIntervalArgument,
00335 interval_);
00336 visitor->EndVisitIntegerExpression(ModelVisitor::kStartExpr, this);
00337 }
00338
00339 private:
00340 IntervalVar* interval_;
00341 DISALLOW_COPY_AND_ASSIGN(IntervalVarStartExpr);
00342 };
00343
00344 class IntervalVarEndExpr : public BaseIntExpr {
00345 public:
00346 explicit IntervalVarEndExpr(IntervalVar* const i)
00347 : BaseIntExpr(i->solver()), interval_(i) {}
00348 virtual ~IntervalVarEndExpr() {}
00349
00350 virtual int64 Min() const {
00351 return interval_->EndMin();
00352 }
00353
00354 virtual void SetMin(int64 m) {
00355 interval_->SetEndMin(m);
00356 }
00357
00358 virtual int64 Max() const {
00359 return interval_->EndMax();
00360 }
00361
00362 virtual void SetMax(int64 m) {
00363 interval_->SetEndMax(m);
00364 }
00365
00366 virtual void SetRange(int64 l, int64 u) {
00367 interval_->SetEndRange(l, u);
00368 }
00369
00370 virtual void SetValue(int64 v) {
00371 interval_->SetEndRange(v, v);
00372 }
00373
00374 virtual bool Bound() const {
00375 return interval_->EndMin() == interval_->EndMax();
00376 }
00377
00378 virtual void WhenRange(Demon* d) {
00379 interval_->WhenEndRange(d);
00380 }
00381
00382 virtual string DebugString() const {
00383 return StringPrintf("end(%s)", interval_->DebugString().c_str());
00384 }
00385
00386 virtual void Accept(ModelVisitor* const visitor) const {
00387 visitor->BeginVisitIntegerExpression(ModelVisitor::kEndExpr, this);
00388 visitor->VisitIntervalArgument(ModelVisitor::kIntervalArgument,
00389 interval_);
00390 visitor->EndVisitIntegerExpression(ModelVisitor::kEndExpr, this);
00391 }
00392
00393 private:
00394 IntervalVar* interval_;
00395 DISALLOW_COPY_AND_ASSIGN(IntervalVarEndExpr);
00396 };
00397
00398 class IntervalVarDurationExpr : public BaseIntExpr {
00399 public:
00400 explicit IntervalVarDurationExpr(IntervalVar* const i)
00401 : BaseIntExpr(i->solver()), interval_(i) {}
00402 virtual ~IntervalVarDurationExpr() {}
00403
00404 virtual int64 Min() const {
00405 return interval_->DurationMin();
00406 }
00407
00408 virtual void SetMin(int64 m) {
00409 interval_->SetDurationMin(m);
00410 }
00411
00412 virtual int64 Max() const {
00413 return interval_->DurationMax();
00414 }
00415
00416 virtual void SetMax(int64 m) {
00417 interval_->SetDurationMax(m);
00418 }
00419
00420 virtual void SetRange(int64 l, int64 u) {
00421 interval_->SetDurationRange(l, u);
00422 }
00423
00424 virtual void SetValue(int64 v) {
00425 interval_->SetDurationRange(v, v);
00426 }
00427
00428 virtual bool Bound() const {
00429 return interval_->DurationMin() == interval_->DurationMax();
00430 }
00431
00432 virtual void WhenRange(Demon* d) {
00433 interval_->WhenDurationRange(d);
00434 }
00435
00436 virtual string DebugString() const {
00437 return StringPrintf("duration(%s)", interval_->DebugString().c_str());
00438 }
00439
00440 virtual void Accept(ModelVisitor* const visitor) const {
00441 visitor->BeginVisitIntegerExpression(ModelVisitor::kDurationExpr, this);
00442 visitor->VisitIntervalArgument(ModelVisitor::kIntervalArgument,
00443 interval_);
00444 visitor->EndVisitIntegerExpression(ModelVisitor::kDurationExpr, this);
00445 }
00446
00447 private:
00448 IntervalVar* interval_;
00449 DISALLOW_COPY_AND_ASSIGN(IntervalVarDurationExpr);
00450 };
00451
00452 class IntervalVarPerformedExpr : public BaseIntExpr {
00453 public:
00454 explicit IntervalVarPerformedExpr(IntervalVar* const i)
00455 : BaseIntExpr(i->solver()), interval_(i) {}
00456 virtual ~IntervalVarPerformedExpr() {}
00457
00458 virtual int64 Min() const {
00459
00460 return static_cast<int64>(interval_->MustBePerformed());
00461 }
00462
00463 virtual void SetMin(int64 m) {
00464 if (m == 1) {
00465 interval_->SetPerformed(true);
00466 } else if (m > 1) {
00467 solver()->Fail();
00468 }
00469 }
00470
00471 virtual int64 Max() const {
00472
00473 return static_cast<int64>(interval_->MayBePerformed());
00474 }
00475
00476 virtual void SetMax(int64 m) {
00477 if (m == 0) {
00478 interval_->SetPerformed(false);
00479 } else if (m < 0) {
00480 solver()->Fail();
00481 }
00482 }
00483
00484 virtual void SetRange(int64 l, int64 u) {
00485 SetMin(l);
00486 SetMax(u);
00487 }
00488
00489 virtual void SetValue(int64 v) {
00490 SetRange(v, v);
00491 }
00492
00493 virtual bool Bound() const {
00494 return interval_->IsPerformedBound();
00495 }
00496
00497 virtual void WhenRange(Demon* d) {
00498 interval_->WhenPerformedBound(d);
00499 }
00500
00501 virtual string DebugString() const {
00502 return StringPrintf("performed(%s)", interval_->DebugString().c_str());
00503 }
00504
00505 virtual void Accept(ModelVisitor* const visitor) const {
00506 visitor->BeginVisitIntegerExpression(ModelVisitor::kPerformedExpr, this);
00507 visitor->VisitIntervalArgument(ModelVisitor::kIntervalArgument,
00508 interval_);
00509 visitor->EndVisitIntegerExpression(ModelVisitor::kPerformedExpr, this);
00510 }
00511
00512 private:
00513 IntervalVar* interval_;
00514 DISALLOW_COPY_AND_ASSIGN(IntervalVarPerformedExpr);
00515 };
00516
00517
00518
00519 class FixedDurationIntervalVar : public IntervalVar {
00520 public:
00521 enum PerformedStatus { UNPERFORMED, PERFORMED, UNDECIDED };
00522
00523 class Handler : public Demon {
00524 public:
00525 explicit Handler(FixedDurationIntervalVar* const var) : var_(var) {}
00526 virtual ~Handler() {}
00527 virtual void Run(Solver* const s) {
00528 var_->Process();
00529 }
00530 virtual Solver::DemonPriority priority() const {
00531 return Solver::VAR_PRIORITY;
00532 }
00533 virtual string DebugString() const {
00534 return StringPrintf("Handler(%s)", var_->DebugString().c_str());
00535 }
00536 private:
00537 FixedDurationIntervalVar* const var_;
00538 };
00539
00540 class Cleaner : public Action {
00541 public:
00542 explicit Cleaner(FixedDurationIntervalVar* const var) : var_(var) {}
00543 virtual ~Cleaner() {}
00544 virtual void Run(Solver* const s) {
00545 var_->ClearInProcess();
00546 }
00547 private:
00548 FixedDurationIntervalVar* const var_;
00549 };
00550
00551 FixedDurationIntervalVar(Solver* const s,
00552 int64 start_min,
00553 int64 start_max,
00554 int64 duration,
00555 bool optional,
00556 const string& name);
00557
00558 FixedDurationIntervalVar(Solver* const s, const string& name);
00559 virtual ~FixedDurationIntervalVar() {}
00560
00561 virtual int64 StartMin() const;
00562 virtual int64 StartMax() const;
00563 virtual void SetStartMin(int64 m);
00564 virtual void SetStartMax(int64 m);
00565 virtual void SetStartRange(int64 mi, int64 ma);
00566 virtual void WhenStartRange(Demon* const d) {
00567 if (performed_ != UNPERFORMED && start_min_ != start_max_) {
00568 start_range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00569 }
00570 }
00571 virtual void WhenStartBound(Demon* const d) {
00572 if (performed_ != UNPERFORMED && start_min_ != start_max_) {
00573 start_bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00574 }
00575 }
00576
00577 virtual int64 DurationMin() const;
00578 virtual int64 DurationMax() const;
00579 virtual void SetDurationMin(int64 m);
00580 virtual void SetDurationMax(int64 m);
00581 virtual void SetDurationRange(int64 mi, int64 ma);
00582 virtual void WhenDurationRange(Demon* const d) { }
00583 virtual void WhenDurationBound(Demon* const d) { }
00584
00585 virtual int64 EndMin() const;
00586 virtual int64 EndMax() const;
00587 virtual void SetEndMin(int64 m);
00588 virtual void SetEndMax(int64 m);
00589 virtual void SetEndRange(int64 mi, int64 ma);
00590 virtual void WhenEndRange(Demon* const d) {
00591 if (performed_ != UNPERFORMED && start_min_ != start_max_) {
00592 start_range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00593 }
00594 }
00595 virtual void WhenEndBound(Demon* const d) {
00596 if (performed_ != UNPERFORMED && start_min_ != start_max_) {
00597 start_bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00598 }
00599 }
00600
00601 virtual bool MustBePerformed() const;
00602 virtual bool MayBePerformed() const;
00603 virtual void SetPerformed(bool val);
00604 virtual void WhenPerformedBound(Demon* const d) {
00605 if (performed_ == UNDECIDED) {
00606 performed_bound_demons_.PushIfNotTop(solver(),
00607 solver()->RegisterDemon(d));
00608 }
00609 }
00610 void Process();
00611 void ClearInProcess();
00612 virtual string DebugString() const;
00613
00614 virtual void Accept(ModelVisitor* const visitor) const {
00615 visitor->VisitIntervalVariable(this, "", NULL);
00616 }
00617
00618 virtual string BaseName() const { return "IntervalVar"; }
00619
00620 private:
00621 void CheckOldStartBounds() {
00622 if (old_start_min_ > start_min_) {
00623 old_start_min_ = start_min_;
00624 }
00625 if (old_start_max_ < start_max_) {
00626 old_start_max_ = start_max_;
00627 }
00628 }
00629 void CheckOldPerformed() {
00630 if (performed_ == UNDECIDED) {
00631 old_performed_ = UNDECIDED;
00632 }
00633 }
00634 void CheckNotUnperformed() const {
00635 CHECK_NE(UNPERFORMED, performed_);
00636 }
00637 void Push();
00638
00639 int64 start_min_;
00640 int64 start_max_;
00641 int64 new_start_min_;
00642 int64 new_start_max_;
00643 int64 old_start_min_;
00644 int64 old_start_max_;
00645 int64 duration_;
00646 PerformedStatus performed_;
00647 PerformedStatus new_performed_;
00648 PerformedStatus old_performed_;
00649 SimpleRevFIFO<Demon*> start_bound_demons_;
00650 SimpleRevFIFO<Demon*> start_range_demons_;
00651 SimpleRevFIFO<Demon*> performed_bound_demons_;
00652 Handler handler_;
00653 Cleaner cleaner_;
00654 bool in_process_;
00655 };
00656
00657 FixedDurationIntervalVar::FixedDurationIntervalVar(Solver* const s,
00658 int64 start_min,
00659 int64 start_max,
00660 int64 duration,
00661 bool optional,
00662 const string& name)
00663 : IntervalVar(s, name),
00664 start_min_(start_min),
00665 start_max_(start_max),
00666 new_start_min_(start_min),
00667 new_start_max_(start_max),
00668 old_start_min_(start_min),
00669 old_start_max_(start_max),
00670 duration_(duration),
00671 performed_(optional ? UNDECIDED : PERFORMED),
00672 new_performed_(performed_),
00673 old_performed_(performed_),
00674 handler_(this),
00675 cleaner_(this),
00676 in_process_(false) {
00677 }
00678
00679 FixedDurationIntervalVar::FixedDurationIntervalVar(Solver* const s,
00680 const string& name)
00681 : IntervalVar(s, name),
00682 start_min_(0),
00683 start_max_(0),
00684 new_start_min_(0),
00685 new_start_max_(0),
00686 old_start_min_(0),
00687 old_start_max_(0),
00688 duration_(0),
00689 performed_(UNPERFORMED),
00690 new_performed_(UNPERFORMED),
00691 old_performed_(UNPERFORMED),
00692 handler_(this),
00693 cleaner_(this),
00694 in_process_(false) {
00695 }
00696
00697 void FixedDurationIntervalVar::Process() {
00698 CHECK(!in_process_);
00699 in_process_ = true;
00700 new_start_min_ = start_min_;
00701 new_start_max_ = start_max_;
00702 new_performed_ = performed_;
00703 set_queue_action_on_fail(&cleaner_);
00704 if (performed_ != UNPERFORMED) {
00705 if (start_min_ == start_max_) {
00706 for (SimpleRevFIFO<Demon*>::Iterator it(&start_bound_demons_);
00707 it.ok();
00708 ++it) {
00709 Enqueue(*it);
00710 }
00711 }
00712 if (start_min_ != old_start_min_ || start_max_ != old_start_max_) {
00713 for (SimpleRevFIFO<Demon*>::Iterator it(&start_range_demons_);
00714 it.ok();
00715 ++it) {
00716 Enqueue(*it);
00717 }
00718 }
00719 }
00720 if (old_performed_ != performed_) {
00721 for (SimpleRevFIFO<Demon*>::Iterator it(&performed_bound_demons_);
00722 it.ok();
00723 ++it) {
00724 Enqueue(*it);
00725 }
00726 }
00727 ProcessDemonsOnQueue();
00728 clear_queue_action_on_fail();
00729 ClearInProcess();
00730 old_start_min_ = start_min_;
00731 old_start_max_ = start_max_;
00732 old_performed_ = performed_;
00733 if (start_min_ < new_start_min_) {
00734 SetStartMin(new_start_min_);
00735 }
00736 if (start_max_ > new_start_max_) {
00737 SetStartMax(new_start_max_);
00738 }
00739 if (new_performed_ != performed_) {
00740 CHECK_NE(UNDECIDED, new_performed_);
00741 SetPerformed(new_performed_);
00742 }
00743 }
00744
00745 void FixedDurationIntervalVar::ClearInProcess() {
00746 in_process_ = false;
00747 }
00748
00749 int64 FixedDurationIntervalVar::StartMin() const {
00750 CheckNotUnperformed();
00751 return start_min_;
00752 }
00753
00754 int64 FixedDurationIntervalVar::StartMax() const {
00755 CheckNotUnperformed();
00756 return start_max_;
00757 }
00758
00759 void FixedDurationIntervalVar::SetStartMin(int64 m) {
00760 if (performed_ != UNPERFORMED) {
00761 if (m > start_max_) {
00762 SetPerformed(false);
00763 return;
00764 }
00765 if (m > start_min_) {
00766 if (in_process_) {
00767 if (m > new_start_max_) {
00768 solver()->Fail();
00769 }
00770 if (m > new_start_min_) {
00771 new_start_min_ = m;
00772 }
00773 } else {
00774 CheckOldStartBounds();
00775 solver()->SaveAndSetValue(&start_min_, m);
00776 Push();
00777 }
00778 }
00779 }
00780 }
00781
00782 void FixedDurationIntervalVar::SetStartMax(int64 m) {
00783 if (performed_ != UNPERFORMED) {
00784 if (m < start_min_) {
00785 SetPerformed(false);
00786 return;
00787 }
00788 if (m < start_max_) {
00789 if (in_process_) {
00790 if (m < new_start_min_) {
00791 solver()->Fail();
00792 }
00793 if (m < new_start_max_) {
00794 new_start_max_ = m;
00795 }
00796 } else {
00797 CheckOldStartBounds();
00798 solver()->SaveAndSetValue(&start_max_, m);
00799 Push();
00800 }
00801 }
00802 }
00803 }
00804
00805 void FixedDurationIntervalVar::SetStartRange(int64 mi, int64 ma) {
00806 SetStartMin(mi);
00807 SetStartMax(ma);
00808 }
00809
00810 int64 FixedDurationIntervalVar::DurationMin() const {
00811 CheckNotUnperformed();
00812 return duration_;
00813 }
00814
00815 int64 FixedDurationIntervalVar::DurationMax() const {
00816 CheckNotUnperformed();
00817 return duration_;
00818 }
00819
00820 void FixedDurationIntervalVar::SetDurationMin(int64 m) {
00821 if (m > duration_) {
00822 SetPerformed(false);
00823 }
00824 }
00825
00826 void FixedDurationIntervalVar::SetDurationMax(int64 m) {
00827 if (m < duration_) {
00828 SetPerformed(false);
00829 }
00830 }
00831 int64 FixedDurationIntervalVar::EndMin() const {
00832 CheckNotUnperformed();
00833 return start_min_ + duration_;
00834 }
00835
00836 int64 FixedDurationIntervalVar::EndMax() const {
00837 CheckNotUnperformed();
00838 return start_max_ + duration_;
00839 }
00840
00841 void FixedDurationIntervalVar::SetEndMin(int64 m) {
00842 if (m > start_min_ + duration_) {
00843 SetStartMin(m - duration_);
00844 }
00845 }
00846
00847 void FixedDurationIntervalVar::SetEndMax(int64 m) {
00848 if (m < start_max_ + duration_) {
00849 SetStartMax(m - duration_);
00850 }
00851 }
00852
00853 void FixedDurationIntervalVar::SetEndRange(int64 mi, int64 ma) {
00854 if (mi < start_min_ + duration_) {
00855 mi = start_min_ + duration_;
00856 }
00857 if (ma > start_max_ + duration_) {
00858 ma = start_max_ + duration_;
00859 }
00860 SetStartRange(mi - duration_, ma - duration_);
00861 }
00862
00863
00864 void FixedDurationIntervalVar::SetDurationRange(int64 mi, int64 ma) {
00865 if (mi > duration_ || ma < duration_ || mi > ma) {
00866 SetPerformed(false);
00867 }
00868 }
00869
00870 bool FixedDurationIntervalVar::MustBePerformed() const {
00871 return (performed_ == PERFORMED);
00872 }
00873
00874 bool FixedDurationIntervalVar::MayBePerformed() const {
00875 return (performed_ != UNPERFORMED);
00876 }
00877
00878 void FixedDurationIntervalVar::SetPerformed(bool val) {
00879 CHECK_GE(val, 0);
00880 CHECK_LE(val, 1);
00881 if (performed_ == UNDECIDED) {
00882 if (in_process_) {
00883 if (new_performed_ == UNDECIDED) {
00884 new_performed_ = static_cast<PerformedStatus>(val);
00885 } else if (new_performed_ != val) {
00886 solver()->Fail();
00887 }
00888 } else {
00889 CheckOldPerformed();
00890 solver()->SaveAndSetValue(reinterpret_cast<int*>(&performed_),
00891 static_cast<int>(val));
00892 Push();
00893 }
00894 } else if (performed_ != val) {
00895 solver()->Fail();
00896 }
00897 }
00898
00899 void FixedDurationIntervalVar::Push() {
00900 const bool in_process = in_process_;
00901 Enqueue(&handler_);
00902 CHECK_EQ(in_process, in_process_);
00903 }
00904
00905 string FixedDurationIntervalVar::DebugString() const {
00906 string out;
00907 const string& var_name = name();
00908 if (!var_name.empty()) {
00909 out = var_name + "(start = ";
00910 } else {
00911 out = "IntervalVar(start = ";
00912 }
00913 StringAppendF(&out, "%" GG_LL_FORMAT "d", start_min_);
00914 if (start_max_ != start_min_) {
00915 StringAppendF(&out, " .. %" GG_LL_FORMAT "d", start_max_);
00916 }
00917 StringAppendF(&out, ", duration = %" GG_LL_FORMAT "d, status = ", duration_);
00918 switch (performed_) {
00919 case UNPERFORMED:
00920 out += "unperformed)";
00921 break;
00922 case PERFORMED:
00923 out += "performed)";
00924 break;
00925 case UNDECIDED:
00926 out += "optional)";
00927 break;
00928 }
00929 return out;
00930 }
00931
00932
00933
00934 class FixedDurationPerformedIntervalVar : public IntervalVar {
00935 public:
00936 class Handler : public Demon {
00937 public:
00938 explicit Handler(FixedDurationPerformedIntervalVar* const var)
00939 : var_(var) {}
00940 virtual ~Handler() {}
00941 virtual void Run(Solver* const s) {
00942 var_->Process();
00943 }
00944 virtual Solver::DemonPriority priority() const {
00945 return Solver::VAR_PRIORITY;
00946 }
00947 virtual string DebugString() const {
00948 return StringPrintf("Handler(%s)", var_->DebugString().c_str());
00949 }
00950 private:
00951 FixedDurationPerformedIntervalVar* const var_;
00952 };
00953
00954 class Cleaner : public Action {
00955 public:
00956 explicit Cleaner(FixedDurationPerformedIntervalVar* const var)
00957 : var_(var) {}
00958 virtual ~Cleaner() {}
00959 virtual void Run(Solver* const s) {
00960 var_->ClearInProcess();
00961 }
00962 private:
00963 FixedDurationPerformedIntervalVar* const var_;
00964 };
00965
00966 FixedDurationPerformedIntervalVar(Solver* const s,
00967 int64 start_min,
00968 int64 start_max,
00969 int64 duration,
00970 const string& name);
00971
00972 FixedDurationPerformedIntervalVar(Solver* const s, const string& name);
00973 virtual ~FixedDurationPerformedIntervalVar() {}
00974
00975 virtual int64 StartMin() const;
00976 virtual int64 StartMax() const;
00977 virtual void SetStartMin(int64 m);
00978 virtual void SetStartMax(int64 m);
00979 virtual void SetStartRange(int64 mi, int64 ma);
00980 virtual void WhenStartRange(Demon* const d) {
00981 if (start_min_ != start_max_) {
00982 start_range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00983 }
00984 }
00985 virtual void WhenStartBound(Demon* const d) {
00986 if (start_min_ != start_max_) {
00987 start_bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
00988 }
00989 }
00990
00991 virtual int64 DurationMin() const;
00992 virtual int64 DurationMax() const;
00993 virtual void SetDurationMin(int64 m);
00994 virtual void SetDurationMax(int64 m);
00995 virtual void SetDurationRange(int64 mi, int64 ma);
00996 virtual void WhenDurationRange(Demon* const d) { }
00997 virtual void WhenDurationBound(Demon* const d) { }
00998
00999 virtual int64 EndMin() const;
01000 virtual int64 EndMax() const;
01001 virtual void SetEndMin(int64 m);
01002 virtual void SetEndMax(int64 m);
01003 virtual void SetEndRange(int64 mi, int64 ma);
01004 virtual void WhenEndRange(Demon* const d) {
01005 if (start_min_ != start_max_) {
01006 start_range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
01007 }
01008 }
01009 virtual void WhenEndBound(Demon* const d) {
01010 if (start_min_ != start_max_) {
01011 start_bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
01012 }
01013 }
01014
01015 virtual bool MustBePerformed() const;
01016 virtual bool MayBePerformed() const;
01017 virtual void SetPerformed(bool val);
01018 virtual void WhenPerformedBound(Demon* const d) {
01019 }
01020 void Process();
01021 void ClearInProcess();
01022 virtual string DebugString() const;
01023
01024 virtual void Accept(ModelVisitor* const visitor) const {
01025 visitor->VisitIntervalVariable(this, "", NULL);
01026 }
01027
01028 private:
01029 void CheckOldStartBounds() {
01030 if (old_start_min_ > start_min_) {
01031 old_start_min_ = start_min_;
01032 }
01033 if (old_start_max_ < start_max_) {
01034 old_start_max_ = start_max_;
01035 }
01036 }
01037 void CheckOldPerformed() {}
01038 void Push();
01039
01040 int64 start_min_;
01041 int64 start_max_;
01042 int64 new_start_min_;
01043 int64 new_start_max_;
01044 int64 old_start_min_;
01045 int64 old_start_max_;
01046 int64 duration_;
01047 SimpleRevFIFO<Demon*> start_bound_demons_;
01048 SimpleRevFIFO<Demon*> start_range_demons_;
01049 Handler handler_;
01050 Cleaner cleaner_;
01051 bool in_process_;
01052 };
01053
01054 FixedDurationPerformedIntervalVar::FixedDurationPerformedIntervalVar(
01055 Solver* const s,
01056 int64 start_min,
01057 int64 start_max,
01058 int64 duration,
01059 const string& name)
01060 : IntervalVar(s, name),
01061 start_min_(start_min),
01062 start_max_(start_max),
01063 new_start_min_(start_min),
01064 new_start_max_(start_max),
01065 old_start_min_(start_min),
01066 old_start_max_(start_max),
01067 duration_(duration),
01068 handler_(this),
01069 cleaner_(this),
01070 in_process_(false) {
01071 }
01072
01073 FixedDurationPerformedIntervalVar::FixedDurationPerformedIntervalVar(
01074 Solver* const s,
01075 const string& name)
01076 : IntervalVar(s, name),
01077 start_min_(0),
01078 start_max_(0),
01079 new_start_min_(0),
01080 new_start_max_(0),
01081 old_start_min_(0),
01082 old_start_max_(0),
01083 duration_(0),
01084 handler_(this),
01085 cleaner_(this),
01086 in_process_(false) {
01087 }
01088
01089 void FixedDurationPerformedIntervalVar::Process() {
01090 CHECK(!in_process_);
01091 in_process_ = true;
01092 new_start_min_ = start_min_;
01093 new_start_max_ = start_max_;
01094 set_queue_action_on_fail(&cleaner_);
01095 if (start_min_ == start_max_) {
01096 for (SimpleRevFIFO<Demon*>::Iterator it(&start_bound_demons_);
01097 it.ok();
01098 ++it) {
01099 Enqueue(*it);
01100 }
01101 }
01102 if (start_min_ != old_start_min_ || start_max_ != old_start_max_) {
01103 for (SimpleRevFIFO<Demon*>::Iterator it(&start_range_demons_);
01104 it.ok();
01105 ++it) {
01106 Enqueue(*it);
01107 }
01108 }
01109 ProcessDemonsOnQueue();
01110 clear_queue_action_on_fail();
01111 ClearInProcess();
01112 old_start_min_ = start_min_;
01113 old_start_max_ = start_max_;
01114 if (start_min_ < new_start_min_) {
01115 SetStartMin(new_start_min_);
01116 }
01117 if (start_max_ > new_start_max_) {
01118 SetStartMax(new_start_max_);
01119 }
01120 }
01121
01122 void FixedDurationPerformedIntervalVar::ClearInProcess() {
01123 in_process_ = false;
01124 }
01125
01126 int64 FixedDurationPerformedIntervalVar::StartMin() const {
01127 return start_min_;
01128 }
01129
01130 int64 FixedDurationPerformedIntervalVar::StartMax() const {
01131 return start_max_;
01132 }
01133
01134 void FixedDurationPerformedIntervalVar::SetStartMin(int64 m) {
01135 if (m > start_max_) {
01136 SetPerformed(false);
01137 return;
01138 }
01139 if (m > start_min_) {
01140 if (in_process_) {
01141 if (m > new_start_max_) {
01142 solver()->Fail();
01143 }
01144 if (m > new_start_min_) {
01145 new_start_min_ = m;
01146 }
01147 } else {
01148 CheckOldStartBounds();
01149 solver()->SaveAndSetValue(&start_min_, m);
01150 Push();
01151 }
01152 }
01153 }
01154
01155 void FixedDurationPerformedIntervalVar::SetStartMax(int64 m) {
01156 if (m < start_min_) {
01157 SetPerformed(false);
01158 return;
01159 }
01160 if (m < start_max_) {
01161 if (in_process_) {
01162 if (m < new_start_min_) {
01163 solver()->Fail();
01164 }
01165 if (m < new_start_max_) {
01166 new_start_max_ = m;
01167 }
01168 } else {
01169 CheckOldStartBounds();
01170 solver()->SaveAndSetValue(&start_max_, m);
01171 Push();
01172 }
01173 }
01174 }
01175
01176 void FixedDurationPerformedIntervalVar::SetStartRange(int64 mi, int64 ma) {
01177 SetStartMin(mi);
01178 SetStartMax(ma);
01179 }
01180
01181 int64 FixedDurationPerformedIntervalVar::DurationMin() const {
01182 return duration_;
01183 }
01184
01185 int64 FixedDurationPerformedIntervalVar::DurationMax() const {
01186 return duration_;
01187 }
01188
01189 void FixedDurationPerformedIntervalVar::SetDurationMin(int64 m) {
01190 if (m > duration_) {
01191 SetPerformed(false);
01192 }
01193 }
01194
01195 void FixedDurationPerformedIntervalVar::SetDurationMax(int64 m) {
01196 if (m < duration_) {
01197 SetPerformed(false);
01198 }
01199 }
01200 int64 FixedDurationPerformedIntervalVar::EndMin() const {
01201 return start_min_ + duration_;
01202 }
01203
01204 int64 FixedDurationPerformedIntervalVar::EndMax() const {
01205 return start_max_ + duration_;
01206 }
01207
01208 void FixedDurationPerformedIntervalVar::SetEndMin(int64 m) {
01209 if (m > start_min_ + duration_) {
01210 SetStartMin(m - duration_);
01211 }
01212 }
01213
01214 void FixedDurationPerformedIntervalVar::SetEndMax(int64 m) {
01215 if (m < start_max_ + duration_) {
01216 SetStartMax(m - duration_);
01217 }
01218 }
01219
01220 void FixedDurationPerformedIntervalVar::SetEndRange(int64 mi, int64 ma) {
01221 if (mi < start_min_ + duration_) {
01222 mi = start_min_ + duration_;
01223 }
01224 if (ma > start_max_ + duration_) {
01225 ma = start_max_ + duration_;
01226 }
01227 SetStartRange(mi - duration_, ma - duration_);
01228 }
01229
01230
01231 void FixedDurationPerformedIntervalVar::SetDurationRange(int64 mi, int64 ma) {
01232 if (mi > duration_ || ma < duration_ || mi > ma) {
01233 SetPerformed(false);
01234 }
01235 }
01236
01237 bool FixedDurationPerformedIntervalVar::MustBePerformed() const {
01238 return true;
01239 }
01240
01241 bool FixedDurationPerformedIntervalVar::MayBePerformed() const {
01242 return true;
01243 }
01244
01245 void FixedDurationPerformedIntervalVar::SetPerformed(bool val) {
01246 if (!val) {
01247 solver()->Fail();
01248 }
01249 }
01250
01251 void FixedDurationPerformedIntervalVar::Push() {
01252 const bool in_process = in_process_;
01253 Enqueue(&handler_);
01254 CHECK_EQ(in_process, in_process_);
01255 }
01256
01257 string FixedDurationPerformedIntervalVar::DebugString() const {
01258 string out;
01259 const string& var_name = name();
01260 if (!var_name.empty()) {
01261 out = var_name + "(start = ";
01262 } else {
01263 out = "IntervalVar(start = ";
01264 }
01265 StringAppendF(&out, "%" GG_LL_FORMAT "d", start_min_);
01266 if (start_max_ != start_min_) {
01267 StringAppendF(&out, " .. %" GG_LL_FORMAT "d", start_max_);
01268 }
01269 StringAppendF(&out, ", duration = %" GG_LL_FORMAT "d, status = ", duration_);
01270 out += "performed)";
01271 return out;
01272 }
01273
01274
01275
01276 class FixedInterval : public IntervalVar {
01277 public:
01278 FixedInterval(Solver* const s, int64 start, int64 duration,
01279 const string& name);
01280 virtual ~FixedInterval() {}
01281
01282 virtual int64 StartMin() const { return start_; }
01283 virtual int64 StartMax() const { return start_; }
01284 virtual void SetStartMin(int64 m);
01285 virtual void SetStartMax(int64 m);
01286 virtual void SetStartRange(int64 mi, int64 ma);
01287 virtual void WhenStartRange(Demon* const d) {}
01288 virtual void WhenStartBound(Demon* const d) {}
01289
01290 virtual int64 DurationMin() const { return duration_; }
01291 virtual int64 DurationMax() const { return duration_; }
01292 virtual void SetDurationMin(int64 m);
01293 virtual void SetDurationMax(int64 m);
01294 virtual void SetDurationRange(int64 mi, int64 ma);
01295 virtual void WhenDurationRange(Demon* const d) { }
01296 virtual void WhenDurationBound(Demon* const d) { }
01297
01298 virtual int64 EndMin() const { return start_ + duration_; }
01299 virtual int64 EndMax() const { return start_ + duration_; }
01300 virtual void SetEndMin(int64 m);
01301 virtual void SetEndMax(int64 m);
01302 virtual void SetEndRange(int64 mi, int64 ma);
01303 virtual void WhenEndRange(Demon* const d) {}
01304 virtual void WhenEndBound(Demon* const d) {}
01305
01306 virtual bool MustBePerformed() const { return true; }
01307 virtual bool MayBePerformed() const { return true; }
01308 virtual void SetPerformed(bool val);
01309 virtual void WhenPerformedBound(Demon* const d) {}
01310 virtual string DebugString() const;
01311
01312 virtual void Accept(ModelVisitor* const visitor) const {
01313 visitor->VisitIntervalVariable(this, "", NULL);
01314 }
01315
01316 private:
01317 const int64 start_;
01318 const int64 duration_;
01319 };
01320
01321 FixedInterval::FixedInterval(Solver* const s,
01322 int64 start,
01323 int64 duration,
01324 const string& name)
01325 : IntervalVar(s, name),
01326 start_(start),
01327 duration_(duration) {
01328 }
01329
01330 void FixedInterval::SetStartMin(int64 m) {
01331 if (m > start_) {
01332 solver()->Fail();
01333 }
01334 }
01335
01336 void FixedInterval::SetStartMax(int64 m) {
01337 if (m < start_) {
01338 solver()->Fail();
01339 }
01340 }
01341
01342 void FixedInterval::SetStartRange(int64 mi, int64 ma) {
01343 if (mi > start_ || ma < start_) {
01344 solver()->Fail();
01345 }
01346 }
01347
01348 void FixedInterval::SetDurationMin(int64 m) {
01349 if (m > duration_) {
01350 solver()->Fail();
01351 }
01352 }
01353
01354 void FixedInterval::SetDurationMax(int64 m) {
01355 if (m < duration_) {
01356 solver()->Fail();
01357 }
01358 }
01359
01360 void FixedInterval::SetEndMin(int64 m) {
01361 if (m > start_ + duration_) {
01362 solver()->Fail();
01363 }
01364 }
01365
01366 void FixedInterval::SetEndMax(int64 m) {
01367 if (m < start_ + duration_) {
01368 solver()->Fail();
01369 }
01370 }
01371
01372 void FixedInterval::SetEndRange(int64 mi, int64 ma) {
01373 if (mi > start_ + duration_ || ma < start_ + duration_) {
01374 solver()->Fail();
01375 }
01376 }
01377
01378 void FixedInterval::SetDurationRange(int64 mi, int64 ma) {
01379 if (mi > duration_ || ma < duration_) {
01380 solver()->Fail();
01381 }
01382 }
01383
01384 void FixedInterval::SetPerformed(bool val) {
01385 if (!val) {
01386 solver()->Fail();
01387 }
01388 }
01389
01390 string FixedInterval::DebugString() const {
01391 string out;
01392 const string& var_name = name();
01393 if (!var_name.empty()) {
01394 out = var_name + "(start = ";
01395 } else {
01396 out = "IntervalVar(start = ";
01397 }
01398 StringAppendF(&out, "%" GG_LL_FORMAT "d, duration = %" GG_LL_FORMAT
01399 "d, status = performed)",
01400 start_, duration_);
01401 return out;
01402 }
01403 }
01404
01405
01406
01407 void IntervalVar::WhenAnything(Demon* const d) {
01408 WhenStartRange(d);
01409 WhenDurationRange(d);
01410 WhenEndRange(d);
01411 WhenPerformedBound(d);
01412 }
01413
01414 IntExpr* IntervalVar::StartExpr() {
01415 if (start_expr_ == NULL) {
01416 solver()->SaveValue(reinterpret_cast<void**>(&start_expr_));
01417 start_expr_ = solver()->RegisterIntExpr(
01418 solver()->RevAlloc(new IntervalVarStartExpr(this)));
01419 if (HasName()) {
01420 start_expr_->set_name(StringPrintf("start(%s)", name().c_str()));
01421 }
01422 }
01423 return start_expr_;
01424 }
01425
01426 IntExpr* IntervalVar::DurationExpr() {
01427 if (duration_expr_ == NULL) {
01428 solver()->SaveValue(reinterpret_cast<void**>(&duration_expr_));
01429 duration_expr_ = solver()->RegisterIntExpr(
01430 solver()->RevAlloc(new IntervalVarDurationExpr(this)));
01431 if (HasName()) {
01432 duration_expr_->set_name(StringPrintf("duration(%s)", name().c_str()));
01433 }
01434 }
01435 return duration_expr_;
01436 }
01437
01438 IntExpr* IntervalVar::EndExpr() {
01439 if (end_expr_ == NULL) {
01440 solver()->SaveValue(reinterpret_cast<void**>(&end_expr_));
01441 end_expr_ = solver()->RegisterIntExpr(
01442 solver()->RevAlloc(new IntervalVarEndExpr(this)));
01443 if (HasName()) {
01444 end_expr_->set_name(StringPrintf("end(%s)", name().c_str()));
01445 }
01446 }
01447 return end_expr_;
01448 }
01449
01450 IntExpr* IntervalVar::PerformedExpr() {
01451 if (performed_expr_ == NULL) {
01452 solver()->SaveValue(reinterpret_cast<void**>(&performed_expr_));
01453 performed_expr_ = solver()->RegisterIntExpr(
01454 solver()->RevAlloc(new IntervalVarPerformedExpr(this)));
01455 if (HasName()) {
01456 performed_expr_->set_name(StringPrintf("performed(%s)", name().c_str()));
01457 }
01458 }
01459 return performed_expr_;
01460 }
01461
01462 IntervalVar* Solver::MakeFixedInterval(int64 start,
01463 int64 duration,
01464 const string& name) {
01465 return RevAlloc(new FixedInterval(this, start, duration, name));
01466 }
01467
01468 IntervalVar* Solver::MakeFixedDurationIntervalVar(int64 start_min,
01469 int64 start_max,
01470 int64 duration,
01471 bool optional,
01472 const string& name) {
01473 if (start_min == start_max && !optional) {
01474 return MakeFixedInterval(start_min, duration, name);
01475 } else if (!optional) {
01476 return RegisterIntervalVar(
01477 RevAlloc(new FixedDurationPerformedIntervalVar(this,
01478 start_min,
01479 start_max,
01480 duration,
01481 name)));
01482 }
01483 return RegisterIntervalVar(
01484 RevAlloc(new FixedDurationIntervalVar(this, start_min, start_max,
01485 duration, optional, name)));
01486 }
01487
01488 void Solver::MakeFixedDurationIntervalVarArray(int count,
01489 int64 start_min,
01490 int64 start_max,
01491 int64 duration,
01492 bool optional,
01493 const string& name,
01494 std::vector<IntervalVar*>* array) {
01495 CHECK_GT(count, 0);
01496 CHECK_NOTNULL(array);
01497 array->clear();
01498 for (int i = 0; i < count; ++i) {
01499 const string var_name = StringPrintf("%s%i", name.c_str(), i);
01500 array->push_back(MakeFixedDurationIntervalVar(start_min,
01501 start_max,
01502 duration,
01503 optional,
01504 var_name));
01505 }
01506 }
01507 }