OR-Tools  9.1
interval.cc
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include <cstdint>
15 #include <limits>
16 #include <string>
17 #include <vector>
18 
19 #include "absl/strings/str_cat.h"
20 #include "absl/strings/str_format.h"
22 #include "ortools/base/logging.h"
23 #include "ortools/base/macros.h"
27 
28 #if defined(_MSC_VER)
29 #pragma warning(disable : 4351 4355 4804 4805)
30 #endif
31 
32 namespace operations_research {
33 // Generic code for start/end/duration expressions.
34 // This is not done in a superclass as this is not compatible with the current
35 // class hierarchy.
36 
37 // ----- Expression builders ------
38 
39 IntExpr* BuildStartExpr(IntervalVar* var);
40 IntExpr* BuildDurationExpr(IntervalVar* var);
41 IntExpr* BuildEndExpr(IntervalVar* var);
42 IntExpr* BuildSafeStartExpr(IntervalVar* var, int64_t unperformed_value);
43 IntExpr* BuildSafeDurationExpr(IntervalVar* var, int64_t unperformed_value);
44 IntExpr* BuildSafeEndExpr(IntervalVar* var, int64_t unperformed_value);
45 void LinkVarExpr(Solver* const s, IntExpr* const expr, IntVar* const var);
46 
47 // It's good to have the two extreme values being symmetrical around zero: it
48 // makes mirroring easier.
49 const int64_t IntervalVar::kMaxValidValue =
51 const int64_t IntervalVar::kMinValidValue = -kMaxValidValue;
52 
53 namespace {
54 enum IntervalField { START, DURATION, END };
55 
56 IntervalVar* NullInterval() { return nullptr; }
57 // ----- MirrorIntervalVar -----
58 
59 class MirrorIntervalVar : public IntervalVar {
60  public:
61  MirrorIntervalVar(Solver* const s, IntervalVar* const t)
62  : IntervalVar(s, "Mirror<" + t->name() + ">"), t_(t) {}
63  ~MirrorIntervalVar() override {}
64 
65  // These methods query, set and watch the start position of the
66  // interval var.
67  int64_t StartMin() const override { return -t_->EndMax(); }
68  int64_t StartMax() const override { return -t_->EndMin(); }
69  void SetStartMin(int64_t m) override { t_->SetEndMax(-m); }
70  void SetStartMax(int64_t m) override { t_->SetEndMin(-m); }
71  void SetStartRange(int64_t mi, int64_t ma) override {
72  t_->SetEndRange(-ma, -mi);
73  }
74  int64_t OldStartMin() const override { return -t_->OldEndMax(); }
75  int64_t OldStartMax() const override { return -t_->OldEndMin(); }
76  void WhenStartRange(Demon* const d) override { t_->WhenEndRange(d); }
77  void WhenStartBound(Demon* const d) override { t_->WhenEndBound(d); }
78 
79  // These methods query, set and watch the duration of the interval var.
80  int64_t DurationMin() const override { return t_->DurationMin(); }
81  int64_t DurationMax() const override { return t_->DurationMax(); }
82  void SetDurationMin(int64_t m) override { t_->SetDurationMin(m); }
83  void SetDurationMax(int64_t m) override { t_->SetDurationMax(m); }
84  void SetDurationRange(int64_t mi, int64_t ma) override {
85  t_->SetDurationRange(mi, ma);
86  }
87  int64_t OldDurationMin() const override { return t_->OldDurationMin(); }
88  int64_t OldDurationMax() const override { return t_->OldDurationMax(); }
89  void WhenDurationRange(Demon* const d) override { t_->WhenDurationRange(d); }
90  void WhenDurationBound(Demon* const d) override { t_->WhenDurationBound(d); }
91 
92  // These methods query, set and watch the end position of the interval var.
93  int64_t EndMin() const override { return -t_->StartMax(); }
94  int64_t EndMax() const override { return -t_->StartMin(); }
95  void SetEndMin(int64_t m) override { t_->SetStartMax(-m); }
96  void SetEndMax(int64_t m) override { t_->SetStartMin(-m); }
97  void SetEndRange(int64_t mi, int64_t ma) override {
98  t_->SetStartRange(-ma, -mi);
99  }
100  int64_t OldEndMin() const override { return -t_->OldStartMax(); }
101  int64_t OldEndMax() const override { return -t_->OldStartMin(); }
102  void WhenEndRange(Demon* const d) override { t_->WhenStartRange(d); }
103  void WhenEndBound(Demon* const d) override { t_->WhenStartBound(d); }
104 
105  // These methods query, set and watches the performed status of the
106  // interval var.
107  bool MustBePerformed() const override { return t_->MustBePerformed(); }
108  bool MayBePerformed() const override { return t_->MayBePerformed(); }
109  void SetPerformed(bool val) override { t_->SetPerformed(val); }
110  bool WasPerformedBound() const override { return t_->WasPerformedBound(); }
111  void WhenPerformedBound(Demon* const d) override {
112  t_->WhenPerformedBound(d);
113  }
114 
115  void Accept(ModelVisitor* const visitor) const override {
116  visitor->VisitIntervalVariable(this, ModelVisitor::kMirrorOperation, 0, t_);
117  }
118 
119  std::string DebugString() const override {
120  return absl::StrFormat("MirrorInterval(%s)", t_->DebugString());
121  }
122 
123  IntExpr* StartExpr() override {
124  return solver()->MakeOpposite(t_->EndExpr());
125  }
126  IntExpr* DurationExpr() override { return t_->DurationExpr(); }
127  IntExpr* EndExpr() override {
128  return solver()->MakeOpposite(t_->StartExpr());
129  }
130  IntExpr* PerformedExpr() override { return t_->PerformedExpr(); }
131  // These methods create expressions encapsulating the start, end
132  // and duration of the interval var. If the interval var is
133  // unperformed, they will return the unperformed_value.
134  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
135  return solver()->MakeOpposite(t_->SafeEndExpr(-unperformed_value));
136  }
137  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
138  return t_->SafeDurationExpr(unperformed_value);
139  }
140  IntExpr* SafeEndExpr(int64_t unperformed_value) override {
141  return solver()->MakeOpposite(t_->SafeStartExpr(-unperformed_value));
142  }
143 
144  private:
145  IntervalVar* const t_;
146  DISALLOW_COPY_AND_ASSIGN(MirrorIntervalVar);
147 };
148 
149 // An IntervalVar that passes all function calls to an underlying interval
150 // variable as long as it is not prohibited, and that interprets prohibited
151 // intervals as intervals of duration 0 that must be executed between
152 // [kMinValidValue and kMaxValidValue].
153 //
154 // Such interval variables have a very similar behavior to others.
155 // Invariants such as StartMin() + DurationMin() <= EndMin() that are maintained
156 // for traditional interval variables are maintained for instances of
157 // AlwaysPerformedIntervalVarWrapper. However, there is no monotonicity of the
158 // values returned by the start/end getters. For example, during a given
159 // propagation, three successive calls to StartMin could return,
160 // in this order, 1, 2, and kMinValidValue.
161 //
162 
163 // This class exists so that we can easily implement the
164 // IntervalVarRelaxedMax and IntervalVarRelaxedMin classes below.
165 class AlwaysPerformedIntervalVarWrapper : public IntervalVar {
166  public:
167  explicit AlwaysPerformedIntervalVarWrapper(IntervalVar* const t)
168  : IntervalVar(t->solver(),
169  absl::StrFormat("AlwaysPerformed<%s>", t->name())),
170  t_(t),
171  start_expr_(nullptr),
172  duration_expr_(nullptr),
173  end_expr_(nullptr) {}
174 
175  ~AlwaysPerformedIntervalVarWrapper() override {}
176  int64_t StartMin() const override {
177  return MayUnderlyingBePerformed() ? t_->StartMin() : kMinValidValue;
178  }
179  int64_t StartMax() const override {
180  return MayUnderlyingBePerformed() ? t_->StartMax() : kMaxValidValue;
181  }
182  void SetStartMin(int64_t m) override { t_->SetStartMin(m); }
183  void SetStartMax(int64_t m) override { t_->SetStartMax(m); }
184  void SetStartRange(int64_t mi, int64_t ma) override {
185  t_->SetStartRange(mi, ma);
186  }
187  int64_t OldStartMin() const override {
188  return MayUnderlyingBePerformed() ? t_->OldStartMin() : kMinValidValue;
189  }
190  int64_t OldStartMax() const override {
191  return MayUnderlyingBePerformed() ? t_->OldStartMax() : kMaxValidValue;
192  }
193  void WhenStartRange(Demon* const d) override { t_->WhenStartRange(d); }
194  void WhenStartBound(Demon* const d) override { t_->WhenStartBound(d); }
195  int64_t DurationMin() const override {
196  return MayUnderlyingBePerformed() ? t_->DurationMin() : 0LL;
197  }
198  int64_t DurationMax() const override {
199  return MayUnderlyingBePerformed() ? t_->DurationMax() : 0LL;
200  }
201  void SetDurationMin(int64_t m) override { t_->SetDurationMin(m); }
202  void SetDurationMax(int64_t m) override { t_->SetDurationMax(m); }
203  void SetDurationRange(int64_t mi, int64_t ma) override {
204  t_->SetDurationRange(mi, ma);
205  }
206  int64_t OldDurationMin() const override {
207  return MayUnderlyingBePerformed() ? t_->OldDurationMin() : 0LL;
208  }
209  int64_t OldDurationMax() const override {
210  return MayUnderlyingBePerformed() ? t_->OldDurationMax() : 0LL;
211  }
212  void WhenDurationRange(Demon* const d) override { t_->WhenDurationRange(d); }
213  void WhenDurationBound(Demon* const d) override { t_->WhenDurationBound(d); }
214  int64_t EndMin() const override {
215  return MayUnderlyingBePerformed() ? t_->EndMin() : kMinValidValue;
216  }
217  int64_t EndMax() const override {
218  return MayUnderlyingBePerformed() ? t_->EndMax() : kMaxValidValue;
219  }
220  void SetEndMin(int64_t m) override { t_->SetEndMin(m); }
221  void SetEndMax(int64_t m) override { t_->SetEndMax(m); }
222  void SetEndRange(int64_t mi, int64_t ma) override { t_->SetEndRange(mi, ma); }
223  int64_t OldEndMin() const override {
224  return MayUnderlyingBePerformed() ? t_->OldEndMin() : kMinValidValue;
225  }
226  int64_t OldEndMax() const override {
227  return MayUnderlyingBePerformed() ? t_->OldEndMax() : kMaxValidValue;
228  }
229  void WhenEndRange(Demon* const d) override { t_->WhenEndRange(d); }
230  void WhenEndBound(Demon* const d) override { t_->WhenEndBound(d); }
231  bool MustBePerformed() const override { return true; }
232  bool MayBePerformed() const override { return true; }
233  void SetPerformed(bool val) override {
234  // An AlwaysPerformedIntervalVarWrapper interval variable is always
235  // performed. So setting it to be performed does not change anything,
236  // and setting it not to be performed is inconsistent and should cause
237  // a failure.
238  if (!val) {
239  solver()->Fail();
240  }
241  }
242  bool WasPerformedBound() const override { return true; }
243  void WhenPerformedBound(Demon* const d) override {
244  t_->WhenPerformedBound(d);
245  }
246  IntExpr* StartExpr() override {
247  if (start_expr_ == nullptr) {
248  solver()->SaveValue(reinterpret_cast<void**>(&start_expr_));
249  start_expr_ = BuildStartExpr(this);
250  }
251  return start_expr_;
252  }
253  IntExpr* DurationExpr() override {
254  if (duration_expr_ == nullptr) {
255  solver()->SaveValue(reinterpret_cast<void**>(&duration_expr_));
256  duration_expr_ = BuildDurationExpr(this);
257  }
258  return duration_expr_;
259  }
260  IntExpr* EndExpr() override {
261  if (end_expr_ == nullptr) {
262  solver()->SaveValue(reinterpret_cast<void**>(&end_expr_));
263  end_expr_ = BuildEndExpr(this);
264  }
265  return end_expr_;
266  }
267  IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); }
268  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
269  return StartExpr();
270  }
271  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
272  return DurationExpr();
273  }
274  IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); }
275 
276  protected:
277  IntervalVar* const underlying() const { return t_; }
278  bool MayUnderlyingBePerformed() const {
279  return underlying()->MayBePerformed();
280  }
281 
282  private:
283  IntervalVar* const t_;
284  IntExpr* start_expr_;
285  IntExpr* duration_expr_;
286  IntExpr* end_expr_;
287  DISALLOW_COPY_AND_ASSIGN(AlwaysPerformedIntervalVarWrapper);
288 };
289 
290 // An interval variable that wraps around an underlying one, relaxing the max
291 // start and end. Relaxing means making unbounded when optional.
292 //
293 // More precisely, such an interval variable behaves as follows:
294 // * When the underlying must be performed, this interval variable behaves
295 // exactly as the underlying;
296 // * When the underlying may or may not be performed, this interval variable
297 // behaves like the underlying, except that it is unbounded on the max side;
298 // * When the underlying cannot be performed, this interval variable is of
299 // duration 0 and must be performed in an interval unbounded on both sides.
300 //
301 // This class is very useful to implement propagators that may only modify
302 // the start min or end min.
303 class IntervalVarRelaxedMax : public AlwaysPerformedIntervalVarWrapper {
304  public:
305  explicit IntervalVarRelaxedMax(IntervalVar* const t)
306  : AlwaysPerformedIntervalVarWrapper(t) {}
307  ~IntervalVarRelaxedMax() override {}
308  int64_t StartMax() const override {
309  // It matters to use DurationMin() and not underlying()->DurationMin() here.
310  return underlying()->MustBePerformed() ? underlying()->StartMax()
311  : (kMaxValidValue - DurationMin());
312  }
313  void SetStartMax(int64_t m) override {
314  LOG(FATAL)
315  << "Calling SetStartMax on a IntervalVarRelaxedMax is not supported, "
316  << "as it seems there is no legitimate use case.";
317  }
318  int64_t EndMax() const override {
319  return underlying()->MustBePerformed() ? underlying()->EndMax()
320  : kMaxValidValue;
321  }
322  void SetEndMax(int64_t m) override {
323  LOG(FATAL)
324  << "Calling SetEndMax on a IntervalVarRelaxedMax is not supported, "
325  << "as it seems there is no legitimate use case.";
326  }
327 
328  void Accept(ModelVisitor* const visitor) const override {
329  visitor->VisitIntervalVariable(this, ModelVisitor::kRelaxedMaxOperation, 0,
330  underlying());
331  }
332 
333  std::string DebugString() const override {
334  return absl::StrFormat("IntervalVarRelaxedMax(%s)",
335  underlying()->DebugString());
336  }
337 };
338 
339 // An interval variable that wraps around an underlying one, relaxing the min
340 // start and end. Relaxing means making unbounded when optional.
341 //
342 // More precisely, such an interval variable behaves as follows:
343 // * When the underlying must be performed, this interval variable behaves
344 // exactly as the underlying;
345 // * When the underlying may or may not be performed, this interval variable
346 // behaves like the underlying, except that it is unbounded on the min side;
347 // * When the underlying cannot be performed, this interval variable is of
348 // duration 0 and must be performed in an interval unbounded on both sides.
349 //
350 
351 // This class is very useful to implement propagators that may only modify
352 // the start max or end max.
353 class IntervalVarRelaxedMin : public AlwaysPerformedIntervalVarWrapper {
354  public:
355  explicit IntervalVarRelaxedMin(IntervalVar* const t)
356  : AlwaysPerformedIntervalVarWrapper(t) {}
357  ~IntervalVarRelaxedMin() override {}
358  int64_t StartMin() const override {
359  return underlying()->MustBePerformed() ? underlying()->StartMin()
360  : kMinValidValue;
361  }
362  void SetStartMin(int64_t m) override {
363  LOG(FATAL)
364  << "Calling SetStartMin on a IntervalVarRelaxedMin is not supported, "
365  << "as it seems there is no legitimate use case.";
366  }
367  int64_t EndMin() const override {
368  // It matters to use DurationMin() and not underlying()->DurationMin() here.
369  return underlying()->MustBePerformed() ? underlying()->EndMin()
370  : (kMinValidValue + DurationMin());
371  }
372  void SetEndMin(int64_t m) override {
373  LOG(FATAL)
374  << "Calling SetEndMin on a IntervalVarRelaxedMin is not supported, "
375  << "as it seems there is no legitimate use case.";
376  }
377 
378  void Accept(ModelVisitor* const visitor) const override {
379  visitor->VisitIntervalVariable(this, ModelVisitor::kRelaxedMinOperation, 0,
380  underlying());
381  }
382 
383  std::string DebugString() const override {
384  return absl::StrFormat("IntervalVarRelaxedMin(%s)",
385  underlying()->DebugString());
386  }
387 };
388 
389 // ----- BaseIntervalVar -----
390 
391 class BaseIntervalVar : public IntervalVar {
392  public:
393  class Handler : public Demon {
394  public:
395  explicit Handler(BaseIntervalVar* const var) : var_(var) {}
396  ~Handler() override {}
397  void Run(Solver* const s) override { var_->Process(); }
398  Solver::DemonPriority priority() const override {
399  return Solver::VAR_PRIORITY;
400  }
401  std::string DebugString() const override {
402  return absl::StrFormat("Handler(%s)", var_->DebugString());
403  }
404 
405  private:
406  BaseIntervalVar* const var_;
407  };
408 
409  BaseIntervalVar(Solver* const s, const std::string& name)
410  : IntervalVar(s, name),
411  in_process_(false),
412  handler_(this),
413  cleaner_([this](Solver* s) { CleanInProcess(); }) {}
414 
415  ~BaseIntervalVar() override {}
416 
417  virtual void Process() = 0;
418 
419  virtual void Push() = 0;
420 
421  void CleanInProcess() { in_process_ = false; }
422 
423  std::string BaseName() const override { return "IntervalVar"; }
424 
425  bool InProcess() const { return in_process_; }
426 
427  protected:
429  Handler handler_;
431 };
432 
433 class RangeVar : public IntExpr {
434  public:
435  RangeVar(Solver* const s, BaseIntervalVar* var, int64_t mi, int64_t ma)
436  : IntExpr(s),
437  min_(mi),
438  max_(ma),
439  var_(var),
440  postponed_min_(mi),
441  postponed_max_(ma),
442  previous_min_(mi),
443  previous_max_(ma),
444  cast_var_(nullptr) {}
445 
446  ~RangeVar() override {}
447 
448  bool Bound() const override { return min_.Value() == max_.Value(); }
449 
450  int64_t Min() const override { return min_.Value(); }
451 
452  int64_t Max() const override { return max_.Value(); }
453 
454  void SetMin(int64_t m) override {
455  // No Op.
456  if (m <= min_.Value()) {
457  return;
458  }
459  // Inconsistent value.
460  if (m > max_.Value()) {
461  var_->SetPerformed(false);
462  return;
463  }
464  if (var_->InProcess()) {
465  // In process, postpone modifications.
466  if (m > postponed_max_) {
467  var_->SetPerformed(false);
468  }
469  if (m > postponed_min_) {
470  postponed_min_ = m;
471  }
472  } else {
473  // Not in process.
474  SyncPreviousBounds();
475  min_.SetValue(solver(), m);
476  var_->Push();
477  }
478  }
479 
480  int64_t OldMin() const {
481  DCHECK(var_->InProcess());
482  return previous_min_;
483  }
484 
485  void SetMax(int64_t m) override {
486  if (m >= max_.Value()) {
487  return;
488  }
489  if (m < min_.Value()) {
490  var_->SetPerformed(false);
491  return;
492  }
493  if (var_->InProcess()) {
494  // In process, postpone modifications.
495  if (m < postponed_min_) {
496  var_->SetPerformed(false);
497  }
498  if (m < postponed_max_) {
499  postponed_max_ = m;
500  }
501  } else {
502  // Not in process.
503  SyncPreviousBounds();
504  max_.SetValue(solver(), m);
505  var_->Push();
506  }
507  }
508 
509  int64_t OldMax() const { return previous_min_; }
510 
511  void SetRange(int64_t mi, int64_t ma) override {
512  if (mi <= min_.Value() && ma >= max_.Value()) {
513  // No Op.
514  return;
515  }
516  if (mi > max_.Value() || ma < min_.Value() || mi > ma) {
517  var_->SetPerformed(false);
518  }
519  if (var_->InProcess()) {
520  if (mi > postponed_max_ || ma < postponed_min_) {
521  var_->SetPerformed(false);
522  }
523  if (mi > postponed_min_) {
524  postponed_min_ = mi;
525  }
526  if (ma < postponed_max_) {
527  postponed_max_ = ma;
528  }
529  } else {
530  // Not in process.
531  SyncPreviousBounds();
532  if (mi > min_.Value()) {
533  min_.SetValue(solver(), mi);
534  }
535  if (ma < max_.Value()) {
536  max_.SetValue(solver(), ma);
537  }
538  var_->Push();
539  }
540  }
541 
542  void WhenRange(Demon* const demon) override {
543  if (!Bound()) {
544  if (demon->priority() == Solver::DELAYED_PRIORITY) {
545  delayed_range_demons_.PushIfNotTop(solver(),
546  solver()->RegisterDemon(demon));
547  } else {
548  range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(demon));
549  }
550  }
551  }
552 
553  virtual void WhenBound(Demon* const demon) {
554  if (!Bound()) {
555  if (demon->priority() == Solver::DELAYED_PRIORITY) {
556  delayed_bound_demons_.PushIfNotTop(solver(),
557  solver()->RegisterDemon(demon));
558  } else {
559  bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(demon));
560  }
561  }
562  }
563 
564  void UpdatePostponedBounds() {
565  postponed_min_ = min_.Value();
566  postponed_max_ = max_.Value();
567  }
568 
569  void ProcessDemons() {
570  if (Bound()) {
571  ExecuteAll(bound_demons_);
572  EnqueueAll(delayed_bound_demons_);
573  }
574  if (min_.Value() != previous_min_ || max_.Value() != previous_max_) {
575  ExecuteAll(range_demons_);
576  EnqueueAll(delayed_range_demons_);
577  }
578  }
579 
580  void UpdatePreviousBounds() {
581  previous_min_ = min_.Value();
582  previous_max_ = max_.Value();
583  }
584 
585  // TODO(user): Remove this interval field enum.
586  void ApplyPostponedBounds(IntervalField which) {
587  if (min_.Value() < postponed_min_ || max_.Value() > postponed_max_) {
588  switch (which) {
589  case START:
590  var_->SetStartRange(std::max(postponed_min_, min_.Value()),
591  std::min(postponed_max_, max_.Value()));
592  break;
593  case DURATION:
594  var_->SetDurationRange(std::max(postponed_min_, min_.Value()),
595  std::min(postponed_max_, max_.Value()));
596  break;
597  case END:
598  var_->SetEndRange(std::max(postponed_min_, min_.Value()),
599  std::min(postponed_max_, max_.Value()));
600  break;
601  }
602  }
603  }
604 
605  IntVar* Var() override {
606  if (cast_var_ == nullptr) {
607  solver()->SaveValue(reinterpret_cast<void**>(&cast_var_));
608  cast_var_ = solver()->MakeIntVar(min_.Value(), max_.Value());
609  LinkVarExpr(solver(), this, cast_var_);
610  }
611  return cast_var_;
612  }
613 
614  std::string DebugString() const override {
615  std::string out = absl::StrCat(min_.Value());
616  if (!Bound()) {
617  absl::StrAppendFormat(&out, " .. %d", max_.Value());
618  }
619  return out;
620  }
621 
622  private:
623  // The previous bounds are maintained lazily and non reversibly.
624  // When going down in the search tree, the modifications are
625  // monotonic, thus SyncPreviousBounds is a no-op because they are
626  // correctly updated at the end of the ProcessDemons() call. After
627  // a fail, if they are inconsistent, then they will be outside the
628  // current interval, thus this check.
629  void SyncPreviousBounds() {
630  if (previous_min_ > min_.Value()) {
631  previous_min_ = min_.Value();
632  }
633  if (previous_max_ < max_.Value()) {
634  previous_max_ = max_.Value();
635  }
636  }
637 
638  // The current reversible bounds of the interval.
639  NumericalRev<int64_t> min_;
640  NumericalRev<int64_t> max_;
641  BaseIntervalVar* const var_;
642  // When in process, the modifications are postponed and stored in
643  // these 2 fields.
644  int64_t postponed_min_;
645  int64_t postponed_max_;
646  // The previous bounds stores the bounds since the last time
647  // ProcessDemons() was run. These are maintained lazily.
648  int64_t previous_min_;
649  int64_t previous_max_;
650  // Demons attached to the 'bound' event (min == max).
651  SimpleRevFIFO<Demon*> bound_demons_;
652  SimpleRevFIFO<Demon*> delayed_bound_demons_;
653  // Demons attached to a modification of bounds.
654  SimpleRevFIFO<Demon*> range_demons_;
655  SimpleRevFIFO<Demon*> delayed_range_demons_;
656  IntVar* cast_var_;
657 }; // class RangeVar
658 
659 // ----- PerformedVar -----
660 
661 class PerformedVar : public BooleanVar {
662  public:
663  // Optional = true -> var = [0..1], Optional = false -> var = [1].
664  PerformedVar(Solver* const s, BaseIntervalVar* const var, bool optional)
665  : BooleanVar(s, ""),
666  var_(var),
667  previous_value_(optional ? kUnboundBooleanVarValue : 1),
668  postponed_value_(optional ? kUnboundBooleanVarValue : 1) {
669  if (!optional) {
670  value_ = 1;
671  }
672  }
673  // var = [0] (always unperformed).
674  PerformedVar(Solver* const s, BaseIntervalVar* var)
675  : BooleanVar(s, ""), var_(var), previous_value_(0), postponed_value_(0) {
676  value_ = 1;
677  }
678 
679  ~PerformedVar() override {}
680 
681  void SetValue(int64_t v) override {
682  if ((v & 0xfffffffffffffffe) != 0 || // Not 0 or 1.
683  (value_ != kUnboundBooleanVarValue && v != value_)) {
684  solver()->Fail();
685  }
686  if (var_->InProcess()) {
687  if (postponed_value_ != kUnboundBooleanVarValue &&
688  v != postponed_value_) { // Fail early.
689  solver()->Fail();
690  } else {
691  postponed_value_ = v;
692  }
693  } else if (value_ == kUnboundBooleanVarValue) {
694  previous_value_ = kUnboundBooleanVarValue;
695  InternalSaveBooleanVarValue(solver(), this);
696  value_ = static_cast<int>(v);
697  var_->Push();
698  }
699  }
700 
701  int64_t OldMin() const override { return previous_value_ == 1; }
702 
703  int64_t OldMax() const override { return previous_value_ != 0; }
704 
705  void RestoreValue() override {
706  previous_value_ = kUnboundBooleanVarValue;
707  value_ = kUnboundBooleanVarValue;
708  postponed_value_ = kUnboundBooleanVarValue;
709  }
710 
711  void Process() {
712  if (previous_value_ != value_) {
713  ExecuteAll(bound_demons_);
714  EnqueueAll(delayed_bound_demons_);
715  }
716  }
717 
718  void UpdatePostponedValue() { postponed_value_ = value_; }
719 
720  void UpdatePreviousValueAndApplyPostponedValue() {
721  previous_value_ = value_;
722  if (value_ != postponed_value_) {
723  DCHECK_NE(kUnboundBooleanVarValue, postponed_value_);
724  SetValue(postponed_value_);
725  }
726  }
727 
728  std::string DebugString() const override {
729  switch (value_) {
730  case 0:
731  return "false";
732  case 1:
733  return "true";
734  default:
735  return "undecided";
736  }
737  }
738 
739  private:
740  BaseIntervalVar* const var_;
741  int previous_value_;
742  int postponed_value_;
743 };
744 
745 // ----- FixedDurationIntervalVar -----
746 
747 class FixedDurationIntervalVar : public BaseIntervalVar {
748  public:
749  FixedDurationIntervalVar(Solver* const s, int64_t start_min,
750  int64_t start_max, int64_t duration, bool optional,
751  const std::string& name);
752  // Unperformed interval.
753  FixedDurationIntervalVar(Solver* const s, const std::string& name);
754  ~FixedDurationIntervalVar() override {}
755 
756  int64_t StartMin() const override;
757  int64_t StartMax() const override;
758  void SetStartMin(int64_t m) override;
759  void SetStartMax(int64_t m) override;
760  void SetStartRange(int64_t mi, int64_t ma) override;
761  int64_t OldStartMin() const override { return start_.OldMin(); }
762  int64_t OldStartMax() const override { return start_.OldMax(); }
763  void WhenStartRange(Demon* const d) override {
764  if (performed_.Max() == 1) {
765  start_.WhenRange(d);
766  }
767  }
768  void WhenStartBound(Demon* const d) override {
769  if (performed_.Max() == 1) {
770  start_.WhenBound(d);
771  }
772  }
773 
774  int64_t DurationMin() const override;
775  int64_t DurationMax() const override;
776  void SetDurationMin(int64_t m) override;
777  void SetDurationMax(int64_t m) override;
778  void SetDurationRange(int64_t mi, int64_t ma) override;
779  int64_t OldDurationMin() const override { return duration_; }
780  int64_t OldDurationMax() const override { return duration_; }
781  void WhenDurationRange(Demon* const d) override {}
782  void WhenDurationBound(Demon* const d) override {}
783 
784  int64_t EndMin() const override;
785  int64_t EndMax() const override;
786  void SetEndMin(int64_t m) override;
787  void SetEndMax(int64_t m) override;
788  void SetEndRange(int64_t mi, int64_t ma) override;
789  int64_t OldEndMin() const override {
790  return CapAdd(OldStartMin(), duration_);
791  }
792  int64_t OldEndMax() const override {
793  return CapAdd(OldStartMax(), duration_);
794  }
795  void WhenEndRange(Demon* const d) override { WhenStartRange(d); }
796  void WhenEndBound(Demon* const d) override { WhenStartBound(d); }
797 
798  bool MustBePerformed() const override;
799  bool MayBePerformed() const override;
800  void SetPerformed(bool val) override;
801  bool WasPerformedBound() const override {
802  return performed_.OldMin() == performed_.OldMax();
803  }
804  void WhenPerformedBound(Demon* const d) override { performed_.WhenBound(d); }
805  void Process() override;
806  std::string DebugString() const override;
807 
808  void Accept(ModelVisitor* const visitor) const override {
809  visitor->VisitIntervalVariable(this, "", 0, NullInterval());
810  }
811 
812  IntExpr* StartExpr() override { return &start_; }
813  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
814  IntExpr* EndExpr() override {
815  return solver()->MakeSum(StartExpr(), duration_);
816  }
817  IntExpr* PerformedExpr() override { return &performed_; }
818  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
819  return BuildSafeStartExpr(this, unperformed_value);
820  }
821  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
822  return BuildSafeDurationExpr(this, unperformed_value);
823  }
824  IntExpr* SafeEndExpr(int64_t unperformed_value) override {
825  return BuildSafeEndExpr(this, unperformed_value);
826  }
827 
828  void Push() override;
829 
830  private:
831  RangeVar start_;
832  int64_t duration_;
833  PerformedVar performed_;
834 };
835 
836 FixedDurationIntervalVar::FixedDurationIntervalVar(
837  Solver* const s, int64_t start_min, int64_t start_max, int64_t duration,
838  bool optional, const std::string& name)
839  : BaseIntervalVar(s, name),
840  start_(s, this, start_min, start_max),
841  duration_(duration),
842  performed_(s, this, optional) {}
843 
844 FixedDurationIntervalVar::FixedDurationIntervalVar(Solver* const s,
845  const std::string& name)
846  : BaseIntervalVar(s, name),
847  start_(s, this, 0, 0),
848  duration_(0),
849  performed_(s, this) {}
850 
851 void FixedDurationIntervalVar::Process() {
852  CHECK(!in_process_);
853  in_process_ = true;
854  start_.UpdatePostponedBounds();
855  performed_.UpdatePostponedValue();
856  set_action_on_fail(cleaner_);
857  if (performed_.Max() == 1) {
858  start_.ProcessDemons();
859  }
860  performed_.Process();
861  reset_action_on_fail();
862  CleanInProcess();
863  start_.UpdatePreviousBounds();
864  start_.ApplyPostponedBounds(START);
865  performed_.UpdatePreviousValueAndApplyPostponedValue();
866 }
867 
868 int64_t FixedDurationIntervalVar::StartMin() const {
869  CHECK_EQ(performed_.Max(), 1);
870  return start_.Min();
871 }
872 
873 int64_t FixedDurationIntervalVar::StartMax() const {
874  CHECK_EQ(performed_.Max(), 1);
875  return start_.Max();
876 }
877 
878 void FixedDurationIntervalVar::SetStartMin(int64_t m) {
879  if (performed_.Max() == 1) {
880  start_.SetMin(m);
881  }
882 }
883 
884 void FixedDurationIntervalVar::SetStartMax(int64_t m) {
885  if (performed_.Max() == 1) {
886  start_.SetMax(m);
887  }
888 }
889 
890 void FixedDurationIntervalVar::SetStartRange(int64_t mi, int64_t ma) {
891  if (performed_.Max() == 1) {
892  start_.SetRange(mi, ma);
893  }
894 }
895 
896 int64_t FixedDurationIntervalVar::DurationMin() const {
897  CHECK_EQ(performed_.Max(), 1);
898  return duration_;
899 }
900 
901 int64_t FixedDurationIntervalVar::DurationMax() const {
902  CHECK_EQ(performed_.Max(), 1);
903  return duration_;
904 }
905 
906 void FixedDurationIntervalVar::SetDurationMin(int64_t m) {
907  if (m > duration_) {
908  SetPerformed(false);
909  }
910 }
911 
912 void FixedDurationIntervalVar::SetDurationMax(int64_t m) {
913  if (m < duration_) {
914  SetPerformed(false);
915  }
916 }
917 
918 void FixedDurationIntervalVar::SetDurationRange(int64_t mi, int64_t ma) {
919  if (mi > duration_ || ma < duration_ || mi > ma) {
920  SetPerformed(false);
921  }
922 }
923 
924 int64_t FixedDurationIntervalVar::EndMin() const {
925  CHECK_EQ(performed_.Max(), 1);
926  return start_.Min() + duration_;
927 }
928 
929 int64_t FixedDurationIntervalVar::EndMax() const {
930  CHECK_EQ(performed_.Max(), 1);
931  return CapAdd(start_.Max(), duration_);
932 }
933 
934 void FixedDurationIntervalVar::SetEndMin(int64_t m) {
935  SetStartMin(CapSub(m, duration_));
936 }
937 
938 void FixedDurationIntervalVar::SetEndMax(int64_t m) {
939  SetStartMax(CapSub(m, duration_));
940 }
941 
942 void FixedDurationIntervalVar::SetEndRange(int64_t mi, int64_t ma) {
943  SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_));
944 }
945 
946 bool FixedDurationIntervalVar::MustBePerformed() const {
947  return (performed_.Min() == 1);
948 }
949 
950 bool FixedDurationIntervalVar::MayBePerformed() const {
951  return (performed_.Max() == 1);
952 }
953 
954 void FixedDurationIntervalVar::SetPerformed(bool val) {
955  performed_.SetValue(val);
956 }
957 
958 void FixedDurationIntervalVar::Push() {
960  EnqueueVar(&handler_);
962 }
963 
964 std::string FixedDurationIntervalVar::DebugString() const {
965  const std::string& var_name = name();
966  if (performed_.Max() == 0) {
967  if (!var_name.empty()) {
968  return absl::StrFormat("%s(performed = false)", var_name);
969  } else {
970  return "IntervalVar(performed = false)";
971  }
972  } else {
973  std::string out;
974  if (!var_name.empty()) {
975  out = var_name + "(start = ";
976  } else {
977  out = "IntervalVar(start = ";
978  }
979  absl::StrAppendFormat(&out, "%s, duration = %d, performed = %s)",
980  start_.DebugString(), duration_,
981  performed_.DebugString());
982  return out;
983  }
984 }
985 
986 // ----- FixedDurationPerformedIntervalVar -----
987 
988 class FixedDurationPerformedIntervalVar : public BaseIntervalVar {
989  public:
990  FixedDurationPerformedIntervalVar(Solver* const s, int64_t start_min,
991  int64_t start_max, int64_t duration,
992  const std::string& name);
993  // Unperformed interval.
994  FixedDurationPerformedIntervalVar(Solver* const s, const std::string& name);
995  ~FixedDurationPerformedIntervalVar() override {}
996 
997  int64_t StartMin() const override;
998  int64_t StartMax() const override;
999  void SetStartMin(int64_t m) override;
1000  void SetStartMax(int64_t m) override;
1001  void SetStartRange(int64_t mi, int64_t ma) override;
1002  int64_t OldStartMin() const override { return start_.OldMin(); }
1003  int64_t OldStartMax() const override { return start_.OldMax(); }
1004  void WhenStartRange(Demon* const d) override { start_.WhenRange(d); }
1005  void WhenStartBound(Demon* const d) override { start_.WhenBound(d); }
1006 
1007  int64_t DurationMin() const override;
1008  int64_t DurationMax() const override;
1009  void SetDurationMin(int64_t m) override;
1010  void SetDurationMax(int64_t m) override;
1011  void SetDurationRange(int64_t mi, int64_t ma) override;
1012  int64_t OldDurationMin() const override { return duration_; }
1013  int64_t OldDurationMax() const override { return duration_; }
1014  void WhenDurationRange(Demon* const d) override {}
1015  void WhenDurationBound(Demon* const d) override {}
1016 
1017  int64_t EndMin() const override;
1018  int64_t EndMax() const override;
1019  void SetEndMin(int64_t m) override;
1020  void SetEndMax(int64_t m) override;
1021  void SetEndRange(int64_t mi, int64_t ma) override;
1022  int64_t OldEndMin() const override {
1023  return CapAdd(OldStartMin(), duration_);
1024  }
1025  int64_t OldEndMax() const override {
1026  return CapAdd(OldStartMax(), duration_);
1027  }
1028  void WhenEndRange(Demon* const d) override { WhenStartRange(d); }
1029  void WhenEndBound(Demon* const d) override { WhenEndRange(d); }
1030 
1031  bool MustBePerformed() const override;
1032  bool MayBePerformed() const override;
1033  void SetPerformed(bool val) override;
1034  bool WasPerformedBound() const override { return true; }
1035  void WhenPerformedBound(Demon* const d) override {}
1036  void Process() override;
1037  std::string DebugString() const override;
1038 
1039  void Accept(ModelVisitor* const visitor) const override {
1040  visitor->VisitIntervalVariable(this, "", 0, NullInterval());
1041  }
1042 
1043  IntExpr* StartExpr() override { return &start_; }
1044  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
1045  IntExpr* EndExpr() override {
1046  return solver()->MakeSum(StartExpr(), duration_);
1047  }
1048  IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); }
1049  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
1050  return StartExpr();
1051  }
1052  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
1053  return DurationExpr();
1054  }
1055  IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); }
1056 
1057  private:
1058  void CheckOldPerformed() {}
1059  void Push() override;
1060 
1061  RangeVar start_;
1062  int64_t duration_;
1063 };
1064 
1065 FixedDurationPerformedIntervalVar::FixedDurationPerformedIntervalVar(
1066  Solver* const s, int64_t start_min, int64_t start_max, int64_t duration,
1067  const std::string& name)
1068  : BaseIntervalVar(s, name),
1069  start_(s, this, start_min, start_max),
1070  duration_(duration) {}
1071 
1072 FixedDurationPerformedIntervalVar::FixedDurationPerformedIntervalVar(
1073  Solver* const s, const std::string& name)
1074  : BaseIntervalVar(s, name), start_(s, this, 0, 0), duration_(0) {}
1075 
1076 void FixedDurationPerformedIntervalVar::Process() {
1077  CHECK(!in_process_);
1078  in_process_ = true;
1079  start_.UpdatePostponedBounds();
1080  set_action_on_fail(cleaner_);
1081  start_.ProcessDemons();
1082  reset_action_on_fail();
1083  CleanInProcess();
1084  start_.UpdatePreviousBounds();
1085  start_.ApplyPostponedBounds(START);
1086 }
1087 
1088 int64_t FixedDurationPerformedIntervalVar::StartMin() const {
1089  return start_.Min();
1090 }
1091 
1092 int64_t FixedDurationPerformedIntervalVar::StartMax() const {
1093  return start_.Max();
1094 }
1095 
1096 void FixedDurationPerformedIntervalVar::SetStartMin(int64_t m) {
1097  start_.SetMin(m);
1098 }
1099 
1100 void FixedDurationPerformedIntervalVar::SetStartMax(int64_t m) {
1101  start_.SetMax(m);
1102 }
1103 
1104 void FixedDurationPerformedIntervalVar::SetStartRange(int64_t mi, int64_t ma) {
1105  start_.SetRange(mi, ma);
1106 }
1107 
1108 int64_t FixedDurationPerformedIntervalVar::DurationMin() const {
1109  return duration_;
1110 }
1111 
1112 int64_t FixedDurationPerformedIntervalVar::DurationMax() const {
1113  return duration_;
1114 }
1115 
1116 void FixedDurationPerformedIntervalVar::SetDurationMin(int64_t m) {
1117  if (m > duration_) {
1118  SetPerformed(false);
1119  }
1120 }
1121 
1122 void FixedDurationPerformedIntervalVar::SetDurationMax(int64_t m) {
1123  if (m < duration_) {
1124  SetPerformed(false);
1125  }
1126 }
1127 int64_t FixedDurationPerformedIntervalVar::EndMin() const {
1128  return CapAdd(start_.Min(), duration_);
1129 }
1130 
1131 int64_t FixedDurationPerformedIntervalVar::EndMax() const {
1132  return CapAdd(start_.Max(), duration_);
1133 }
1134 
1135 void FixedDurationPerformedIntervalVar::SetEndMin(int64_t m) {
1136  SetStartMin(CapSub(m, duration_));
1137 }
1138 
1139 void FixedDurationPerformedIntervalVar::SetEndMax(int64_t m) {
1140  SetStartMax(CapSub(m, duration_));
1141 }
1142 
1143 void FixedDurationPerformedIntervalVar::SetEndRange(int64_t mi, int64_t ma) {
1144  SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_));
1145 }
1146 
1147 void FixedDurationPerformedIntervalVar::SetDurationRange(int64_t mi,
1148  int64_t ma) {
1149  if (mi > duration_ || ma < duration_ || mi > ma) {
1150  SetPerformed(false);
1151  }
1152 }
1153 
1154 bool FixedDurationPerformedIntervalVar::MustBePerformed() const { return true; }
1155 
1156 bool FixedDurationPerformedIntervalVar::MayBePerformed() const { return true; }
1157 
1158 void FixedDurationPerformedIntervalVar::SetPerformed(bool val) {
1159  if (!val) {
1160  solver()->Fail();
1161  }
1162 }
1163 
1164 void FixedDurationPerformedIntervalVar::Push() {
1165  DCHECK(!in_process_);
1166  EnqueueVar(&handler_);
1167  DCHECK(!in_process_);
1168 }
1169 
1170 std::string FixedDurationPerformedIntervalVar::DebugString() const {
1171  std::string out;
1172  const std::string& var_name = name();
1173  if (!var_name.empty()) {
1174  out = var_name + "(start = ";
1175  } else {
1176  out = "IntervalVar(start = ";
1177  }
1178  absl::StrAppendFormat(&out, "%s, duration = %d, performed = true)",
1179  start_.DebugString(), duration_);
1180  return out;
1181 }
1182 
1183 // ----- StartVarPerformedIntervalVar -----
1184 
1185 class StartVarPerformedIntervalVar : public IntervalVar {
1186  public:
1187  StartVarPerformedIntervalVar(Solver* const s, IntVar* const var,
1188  int64_t duration, const std::string& name);
1189  ~StartVarPerformedIntervalVar() override {}
1190 
1191  int64_t StartMin() const override;
1192  int64_t StartMax() const override;
1193  void SetStartMin(int64_t m) override;
1194  void SetStartMax(int64_t m) override;
1195  void SetStartRange(int64_t mi, int64_t ma) override;
1196  int64_t OldStartMin() const override { return start_var_->OldMin(); }
1197  int64_t OldStartMax() const override { return start_var_->OldMax(); }
1198  void WhenStartRange(Demon* const d) override { start_var_->WhenRange(d); }
1199  void WhenStartBound(Demon* const d) override { start_var_->WhenBound(d); }
1200 
1201  int64_t DurationMin() const override;
1202  int64_t DurationMax() const override;
1203  void SetDurationMin(int64_t m) override;
1204  void SetDurationMax(int64_t m) override;
1205  void SetDurationRange(int64_t mi, int64_t ma) override;
1206  int64_t OldDurationMin() const override { return duration_; }
1207  int64_t OldDurationMax() const override { return duration_; }
1208  void WhenDurationRange(Demon* const d) override {}
1209  void WhenDurationBound(Demon* const d) override {}
1210 
1211  int64_t EndMin() const override;
1212  int64_t EndMax() const override;
1213  void SetEndMin(int64_t m) override;
1214  void SetEndMax(int64_t m) override;
1215  void SetEndRange(int64_t mi, int64_t ma) override;
1216  int64_t OldEndMin() const override {
1217  return CapAdd(OldStartMin(), duration_);
1218  }
1219  int64_t OldEndMax() const override {
1220  return CapAdd(OldStartMax(), duration_);
1221  }
1222  void WhenEndRange(Demon* const d) override { start_var_->WhenRange(d); }
1223  void WhenEndBound(Demon* const d) override { start_var_->WhenBound(d); }
1224 
1225  bool MustBePerformed() const override;
1226  bool MayBePerformed() const override;
1227  void SetPerformed(bool val) override;
1228  bool WasPerformedBound() const override { return true; }
1229  void WhenPerformedBound(Demon* const d) override {}
1230  std::string DebugString() const override;
1231 
1232  IntExpr* StartExpr() override { return start_var_; }
1233  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
1234  IntExpr* EndExpr() override {
1235  return solver()->MakeSum(start_var_, duration_);
1236  }
1237  IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); }
1238  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
1239  return StartExpr();
1240  }
1241  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
1242  return DurationExpr();
1243  }
1244  IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); }
1245 
1246  void Accept(ModelVisitor* const visitor) const override {
1247  visitor->VisitIntervalVariable(this, "", 0, NullInterval());
1248  }
1249 
1250  private:
1251  IntVar* const start_var_;
1252  int64_t duration_;
1253 };
1254 
1255 // TODO(user): Take care of overflows.
1256 StartVarPerformedIntervalVar::StartVarPerformedIntervalVar(
1257  Solver* const s, IntVar* const var, int64_t duration,
1258  const std::string& name)
1259  : IntervalVar(s, name), start_var_(var), duration_(duration) {}
1260 
1261 int64_t StartVarPerformedIntervalVar::StartMin() const {
1262  return start_var_->Min();
1263 }
1264 
1265 int64_t StartVarPerformedIntervalVar::StartMax() const {
1266  return start_var_->Max();
1267 }
1268 
1269 void StartVarPerformedIntervalVar::SetStartMin(int64_t m) {
1270  start_var_->SetMin(m);
1271 }
1272 
1273 void StartVarPerformedIntervalVar::SetStartMax(int64_t m) {
1274  start_var_->SetMax(m);
1275 }
1276 
1277 void StartVarPerformedIntervalVar::SetStartRange(int64_t mi, int64_t ma) {
1278  start_var_->SetRange(mi, ma);
1279 }
1280 
1281 int64_t StartVarPerformedIntervalVar::DurationMin() const { return duration_; }
1282 
1283 int64_t StartVarPerformedIntervalVar::DurationMax() const { return duration_; }
1284 
1285 void StartVarPerformedIntervalVar::SetDurationMin(int64_t m) {
1286  if (m > duration_) {
1287  solver()->Fail();
1288  }
1289 }
1290 
1291 void StartVarPerformedIntervalVar::SetDurationMax(int64_t m) {
1292  if (m < duration_) {
1293  solver()->Fail();
1294  }
1295 }
1296 int64_t StartVarPerformedIntervalVar::EndMin() const {
1297  return start_var_->Min() + duration_;
1298 }
1299 
1300 int64_t StartVarPerformedIntervalVar::EndMax() const {
1301  return start_var_->Max() + duration_;
1302 }
1303 
1304 void StartVarPerformedIntervalVar::SetEndMin(int64_t m) {
1305  SetStartMin(CapSub(m, duration_));
1306 }
1307 
1308 void StartVarPerformedIntervalVar::SetEndMax(int64_t m) {
1309  SetStartMax(CapSub(m, duration_));
1310 }
1311 
1312 void StartVarPerformedIntervalVar::SetEndRange(int64_t mi, int64_t ma) {
1313  SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_));
1314 }
1315 
1316 void StartVarPerformedIntervalVar::SetDurationRange(int64_t mi, int64_t ma) {
1317  if (mi > duration_ || ma < duration_ || mi > ma) {
1318  solver()->Fail();
1319  }
1320 }
1321 
1322 bool StartVarPerformedIntervalVar::MustBePerformed() const { return true; }
1323 
1324 bool StartVarPerformedIntervalVar::MayBePerformed() const { return true; }
1325 
1326 void StartVarPerformedIntervalVar::SetPerformed(bool val) {
1327  if (!val) {
1328  solver()->Fail();
1329  }
1330 }
1331 
1332 std::string StartVarPerformedIntervalVar::DebugString() const {
1333  std::string out;
1334  const std::string& var_name = name();
1335  if (!var_name.empty()) {
1336  out = var_name + "(start = ";
1337  } else {
1338  out = "IntervalVar(start = ";
1339  }
1340  absl::StrAppendFormat(&out, "%d", start_var_->Min());
1341  if (!start_var_->Bound()) {
1342  absl::StrAppendFormat(&out, " .. %d", start_var_->Max());
1343  }
1344 
1345  absl::StrAppendFormat(&out, ", duration = %d, performed = true)", duration_);
1346  return out;
1347 }
1348 
1349 // ----- StartVarIntervalVar -----
1350 
1351 class StartVarIntervalVar : public BaseIntervalVar {
1352  public:
1353  StartVarIntervalVar(Solver* const s, IntVar* const start, int64_t duration,
1354  IntVar* const performed, const std::string& name);
1355  ~StartVarIntervalVar() override {}
1356 
1357  int64_t StartMin() const override;
1358  int64_t StartMax() const override;
1359  void SetStartMin(int64_t m) override;
1360  void SetStartMax(int64_t m) override;
1361  void SetStartRange(int64_t mi, int64_t ma) override;
1362  int64_t OldStartMin() const override { return start_->OldMin(); }
1363  int64_t OldStartMax() const override { return start_->OldMax(); }
1364  void WhenStartRange(Demon* const d) override {
1365  if (performed_->Max() == 1) {
1366  start_->WhenRange(d);
1367  }
1368  }
1369  void WhenStartBound(Demon* const d) override {
1370  if (performed_->Max() == 1) {
1371  start_->WhenBound(d);
1372  }
1373  }
1374 
1375  int64_t DurationMin() const override;
1376  int64_t DurationMax() const override;
1377  void SetDurationMin(int64_t m) override;
1378  void SetDurationMax(int64_t m) override;
1379  void SetDurationRange(int64_t mi, int64_t ma) override;
1380  int64_t OldDurationMin() const override { return duration_; }
1381  int64_t OldDurationMax() const override { return duration_; }
1382  void WhenDurationRange(Demon* const d) override {}
1383  void WhenDurationBound(Demon* const d) override {}
1384 
1385  int64_t EndMin() const override;
1386  int64_t EndMax() const override;
1387  void SetEndMin(int64_t m) override;
1388  void SetEndMax(int64_t m) override;
1389  void SetEndRange(int64_t mi, int64_t ma) override;
1390  int64_t OldEndMin() const override {
1391  return CapAdd(OldStartMin(), duration_);
1392  }
1393  int64_t OldEndMax() const override {
1394  return CapAdd(OldStartMax(), duration_);
1395  }
1396  void WhenEndRange(Demon* const d) override { WhenStartRange(d); }
1397  void WhenEndBound(Demon* const d) override { WhenStartBound(d); }
1398 
1399  bool MustBePerformed() const override;
1400  bool MayBePerformed() const override;
1401  void SetPerformed(bool val) override;
1402  bool WasPerformedBound() const override {
1403  return performed_->OldMin() == performed_->OldMax();
1404  }
1405  void WhenPerformedBound(Demon* const d) override { performed_->WhenBound(d); }
1406  std::string DebugString() const override;
1407 
1408  void Accept(ModelVisitor* const visitor) const override {
1409  visitor->VisitIntervalVariable(this, "", 0, NullInterval());
1410  }
1411 
1412  IntExpr* StartExpr() override { return start_; }
1413  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
1414  IntExpr* EndExpr() override {
1415  return solver()->MakeSum(StartExpr(), duration_);
1416  }
1417  IntExpr* PerformedExpr() override { return performed_; }
1418  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
1419  return BuildSafeStartExpr(this, unperformed_value);
1420  }
1421  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
1422  return BuildSafeDurationExpr(this, unperformed_value);
1423  }
1424  IntExpr* SafeEndExpr(int64_t unperformed_value) override {
1425  return BuildSafeEndExpr(this, unperformed_value);
1426  }
1427 
1428  void Process() override { LOG(FATAL) << "Should not be here"; }
1429 
1430  void Push() override { LOG(FATAL) << "Should not be here"; }
1431 
1432  int64_t StoredMin() const { return start_min_.Value(); }
1433  int64_t StoredMax() const { return start_max_.Value(); }
1434 
1435  private:
1436  IntVar* const start_;
1437  int64_t duration_;
1438  IntVar* const performed_;
1439  Rev<int64_t> start_min_;
1440  Rev<int64_t> start_max_;
1441 };
1442 
1443 StartVarIntervalVar::StartVarIntervalVar(Solver* const s, IntVar* const start,
1444  int64_t duration,
1445  IntVar* const performed,
1446  const std::string& name)
1447  : BaseIntervalVar(s, name),
1448  start_(start),
1449  duration_(duration),
1450  performed_(performed),
1451  start_min_(start->Min()),
1452  start_max_(start->Max()) {}
1453 
1454 int64_t StartVarIntervalVar::StartMin() const {
1455  DCHECK_EQ(performed_->Max(), 1);
1456  return std::max(start_->Min(), start_min_.Value());
1457 }
1458 
1459 int64_t StartVarIntervalVar::StartMax() const {
1460  DCHECK_EQ(performed_->Max(), 1);
1461  return std::min(start_->Max(), start_max_.Value());
1462 }
1463 
1464 void StartVarIntervalVar::SetStartMin(int64_t m) {
1465  if (performed_->Min() == 1) {
1466  start_->SetMin(m);
1467  } else {
1468  start_min_.SetValue(solver(), std::max(m, start_min_.Value()));
1469  if (start_min_.Value() > std::min(start_max_.Value(), start_->Max())) {
1470  performed_->SetValue(0);
1471  }
1472  }
1473 }
1474 
1475 void StartVarIntervalVar::SetStartMax(int64_t m) {
1476  if (performed_->Min() == 1) {
1477  start_->SetMax(m);
1478  } else {
1479  start_max_.SetValue(solver(), std::min(m, start_max_.Value()));
1480  if (start_max_.Value() < std::max(start_min_.Value(), start_->Min())) {
1481  performed_->SetValue(0);
1482  }
1483  }
1484 }
1485 
1486 void StartVarIntervalVar::SetStartRange(int64_t mi, int64_t ma) {
1487  if (performed_->Min() == 1) {
1488  start_->SetRange(mi, ma);
1489  } else {
1490  start_min_.SetValue(solver(), std::max(mi, start_min_.Value()));
1491  start_max_.SetValue(solver(), std::min(ma, start_max_.Value()));
1492  if (std::max(start_min_.Value(), start_->Min()) >
1493  std::min(start_max_.Value(), start_->Max())) {
1494  performed_->SetValue(0);
1495  }
1496  }
1497 }
1498 
1499 int64_t StartVarIntervalVar::DurationMin() const {
1500  DCHECK_EQ(performed_->Max(), 1);
1501  return duration_;
1502 }
1503 
1504 int64_t StartVarIntervalVar::DurationMax() const {
1505  DCHECK_EQ(performed_->Max(), 1);
1506  return duration_;
1507 }
1508 
1509 void StartVarIntervalVar::SetDurationMin(int64_t m) {
1510  if (m > duration_) {
1511  SetPerformed(false);
1512  }
1513 }
1514 
1515 void StartVarIntervalVar::SetDurationMax(int64_t m) {
1516  if (m < duration_) {
1517  SetPerformed(false);
1518  }
1519 }
1520 
1521 void StartVarIntervalVar::SetDurationRange(int64_t mi, int64_t ma) {
1522  if (mi > duration_ || ma < duration_ || mi > ma) {
1523  SetPerformed(false);
1524  }
1525 }
1526 
1527 int64_t StartVarIntervalVar::EndMin() const {
1528  DCHECK_EQ(performed_->Max(), 1);
1529  return CapAdd(StartMin(), duration_);
1530 }
1531 
1532 int64_t StartVarIntervalVar::EndMax() const {
1533  DCHECK_EQ(performed_->Max(), 1);
1534  return CapAdd(StartMax(), duration_);
1535 }
1536 
1537 void StartVarIntervalVar::SetEndMin(int64_t m) {
1538  SetStartMin(CapSub(m, duration_));
1539 }
1540 
1541 void StartVarIntervalVar::SetEndMax(int64_t m) {
1542  SetStartMax(CapSub(m, duration_));
1543 }
1544 
1545 void StartVarIntervalVar::SetEndRange(int64_t mi, int64_t ma) {
1546  SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_));
1547 }
1548 
1549 bool StartVarIntervalVar::MustBePerformed() const {
1550  return (performed_->Min() == 1);
1551 }
1552 
1553 bool StartVarIntervalVar::MayBePerformed() const {
1554  return (performed_->Max() == 1);
1555 }
1556 
1557 void StartVarIntervalVar::SetPerformed(bool val) {
1558  const bool was_bound = performed_->Bound();
1559  performed_->SetValue(val);
1560  if (val && !was_bound) {
1561  start_->SetRange(start_min_.Value(), start_max_.Value());
1562  }
1563 }
1564 
1565 std::string StartVarIntervalVar::DebugString() const {
1566  const std::string& var_name = name();
1567  if (performed_->Max() == 0) {
1568  if (!var_name.empty()) {
1569  return absl::StrFormat("%s(performed = false)", var_name);
1570  } else {
1571  return "IntervalVar(performed = false)";
1572  }
1573  } else {
1574  std::string out;
1575  if (!var_name.empty()) {
1576  out = var_name + "(start = ";
1577  } else {
1578  out = "IntervalVar(start = ";
1579  }
1580  absl::StrAppendFormat(&out, "%s, duration = %d, performed = %s)",
1581  start_->DebugString(), duration_,
1582  performed_->DebugString());
1583  return out;
1584  }
1585 }
1586 
1587 class LinkStartVarIntervalVar : public Constraint {
1588  public:
1589  LinkStartVarIntervalVar(Solver* const solver,
1590  StartVarIntervalVar* const interval,
1591  IntVar* const start, IntVar* const performed)
1592  : Constraint(solver),
1593  interval_(interval),
1594  start_(start),
1595  performed_(performed) {}
1596 
1597  ~LinkStartVarIntervalVar() override {}
1598 
1599  void Post() override {
1600  Demon* const demon = MakeConstraintDemon0(
1601  solver(), this, &LinkStartVarIntervalVar::PerformedBound,
1602  "PerformedBound");
1603  performed_->WhenBound(demon);
1604  }
1605 
1606  void InitialPropagate() override {
1607  if (performed_->Bound()) {
1608  PerformedBound();
1609  }
1610  }
1611 
1612  void PerformedBound() {
1613  if (performed_->Min() == 1) {
1614  start_->SetRange(interval_->StoredMin(), interval_->StoredMax());
1615  }
1616  }
1617 
1618  private:
1619  StartVarIntervalVar* const interval_;
1620  IntVar* const start_;
1621  IntVar* const performed_;
1622 };
1623 
1624 // ----- FixedInterval -----
1625 
1626 class FixedInterval : public IntervalVar {
1627  public:
1628  FixedInterval(Solver* const s, int64_t start, int64_t duration,
1629  const std::string& name);
1630  ~FixedInterval() override {}
1631 
1632  int64_t StartMin() const override { return start_; }
1633  int64_t StartMax() const override { return start_; }
1634  void SetStartMin(int64_t m) override;
1635  void SetStartMax(int64_t m) override;
1636  void SetStartRange(int64_t mi, int64_t ma) override;
1637  int64_t OldStartMin() const override { return start_; }
1638  int64_t OldStartMax() const override { return start_; }
1639  void WhenStartRange(Demon* const d) override {}
1640  void WhenStartBound(Demon* const d) override {}
1641 
1642  int64_t DurationMin() const override { return duration_; }
1643  int64_t DurationMax() const override { return duration_; }
1644  void SetDurationMin(int64_t m) override;
1645  void SetDurationMax(int64_t m) override;
1646  void SetDurationRange(int64_t mi, int64_t ma) override;
1647  int64_t OldDurationMin() const override { return duration_; }
1648  int64_t OldDurationMax() const override { return duration_; }
1649  void WhenDurationRange(Demon* const d) override {}
1650  void WhenDurationBound(Demon* const d) override {}
1651 
1652  int64_t EndMin() const override { return start_ + duration_; }
1653  int64_t EndMax() const override { return start_ + duration_; }
1654  void SetEndMin(int64_t m) override;
1655  void SetEndMax(int64_t m) override;
1656  void SetEndRange(int64_t mi, int64_t ma) override;
1657  int64_t OldEndMin() const override { return start_ + duration_; }
1658  int64_t OldEndMax() const override { return start_ + duration_; }
1659  void WhenEndRange(Demon* const d) override {}
1660  void WhenEndBound(Demon* const d) override {}
1661 
1662  bool MustBePerformed() const override { return true; }
1663  bool MayBePerformed() const override { return true; }
1664  void SetPerformed(bool val) override;
1665  bool WasPerformedBound() const override { return true; }
1666  void WhenPerformedBound(Demon* const d) override {}
1667  std::string DebugString() const override;
1668 
1669  void Accept(ModelVisitor* const visitor) const override {
1670  visitor->VisitIntervalVariable(this, "", 0, NullInterval());
1671  }
1672 
1673  IntExpr* StartExpr() override { return solver()->MakeIntConst(start_); }
1674  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
1675  IntExpr* EndExpr() override {
1676  return solver()->MakeIntConst(start_ + duration_);
1677  }
1678  IntExpr* PerformedExpr() override { return solver()->MakeIntConst(1); }
1679  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
1680  return StartExpr();
1681  }
1682  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
1683  return DurationExpr();
1684  }
1685  IntExpr* SafeEndExpr(int64_t unperformed_value) override { return EndExpr(); }
1686 
1687  private:
1688  const int64_t start_;
1689  const int64_t duration_;
1690 };
1691 
1692 FixedInterval::FixedInterval(Solver* const s, int64_t start, int64_t duration,
1693  const std::string& name)
1694  : IntervalVar(s, name), start_(start), duration_(duration) {}
1695 
1696 void FixedInterval::SetStartMin(int64_t m) {
1697  if (m > start_) {
1698  solver()->Fail();
1699  }
1700 }
1701 
1702 void FixedInterval::SetStartMax(int64_t m) {
1703  if (m < start_) {
1704  solver()->Fail();
1705  }
1706 }
1707 
1708 void FixedInterval::SetStartRange(int64_t mi, int64_t ma) {
1709  if (mi > start_ || ma < start_) {
1710  solver()->Fail();
1711  }
1712 }
1713 
1714 void FixedInterval::SetDurationMin(int64_t m) {
1715  if (m > duration_) {
1716  solver()->Fail();
1717  }
1718 }
1719 
1720 void FixedInterval::SetDurationMax(int64_t m) {
1721  if (m < duration_) {
1722  solver()->Fail();
1723  }
1724 }
1725 
1726 void FixedInterval::SetEndMin(int64_t m) {
1727  if (m > start_ + duration_) {
1728  solver()->Fail();
1729  }
1730 }
1731 
1732 void FixedInterval::SetEndMax(int64_t m) {
1733  if (m < start_ + duration_) {
1734  solver()->Fail();
1735  }
1736 }
1737 
1738 void FixedInterval::SetEndRange(int64_t mi, int64_t ma) {
1739  if (mi > start_ + duration_ || ma < start_ + duration_) {
1740  solver()->Fail();
1741  }
1742 }
1743 
1744 void FixedInterval::SetDurationRange(int64_t mi, int64_t ma) {
1745  if (mi > duration_ || ma < duration_) {
1746  solver()->Fail();
1747  }
1748 }
1749 
1750 void FixedInterval::SetPerformed(bool val) {
1751  if (!val) {
1752  solver()->Fail();
1753  }
1754 }
1755 
1756 std::string FixedInterval::DebugString() const {
1757  std::string out;
1758  const std::string& var_name = name();
1759  if (!var_name.empty()) {
1760  out = var_name + "(start = ";
1761  } else {
1762  out = "IntervalVar(start = ";
1763  }
1764  absl::StrAppendFormat(&out, "%d, duration = %d, performed = true)", start_,
1765  duration_);
1766  return out;
1767 }
1768 
1769 // ----- VariableDurationIntervalVar -----
1770 
1771 class VariableDurationIntervalVar : public BaseIntervalVar {
1772  public:
1773  VariableDurationIntervalVar(Solver* const s, int64_t start_min,
1774  int64_t start_max, int64_t duration_min,
1775  int64_t duration_max, int64_t end_min,
1776  int64_t end_max, bool optional,
1777  const std::string& name)
1778  : BaseIntervalVar(s, name),
1779  start_(s, this, std::max(start_min, CapSub(end_min, duration_max)),
1780  std::min(start_max, CapSub(end_max, duration_min))),
1781  duration_(s, this, std::max(duration_min, CapSub(end_min, start_max)),
1782  std::min(duration_max, CapSub(end_max, start_min))),
1783  end_(s, this, std::max(end_min, CapAdd(start_min, duration_min)),
1784  std::min(end_max, CapAdd(start_max, duration_max))),
1785  performed_(s, this, optional) {}
1786 
1787  ~VariableDurationIntervalVar() override {}
1788 
1789  int64_t StartMin() const override {
1790  CHECK_EQ(performed_.Max(), 1);
1791  return start_.Min();
1792  }
1793 
1794  int64_t StartMax() const override {
1795  CHECK_EQ(performed_.Max(), 1);
1796  return start_.Max();
1797  }
1798 
1799  void SetStartMin(int64_t m) override {
1800  if (performed_.Max() == 1) {
1801  start_.SetMin(m);
1802  }
1803  }
1804 
1805  void SetStartMax(int64_t m) override {
1806  if (performed_.Max() == 1) {
1807  start_.SetMax(m);
1808  }
1809  }
1810 
1811  void SetStartRange(int64_t mi, int64_t ma) override {
1812  if (performed_.Max() == 1) {
1813  start_.SetRange(mi, ma);
1814  }
1815  }
1816 
1817  int64_t OldStartMin() const override {
1818  CHECK_EQ(performed_.Max(), 1);
1819  CHECK(in_process_);
1820  return start_.OldMin();
1821  }
1822 
1823  int64_t OldStartMax() const override {
1824  CHECK_EQ(performed_.Max(), 1);
1825  CHECK(in_process_);
1826  return start_.OldMax();
1827  }
1828 
1829  void WhenStartRange(Demon* const d) override {
1830  if (performed_.Max() == 1) {
1831  start_.WhenRange(d);
1832  }
1833  }
1834 
1835  void WhenStartBound(Demon* const d) override {
1836  if (performed_.Max() == 1) {
1837  start_.WhenBound(d);
1838  }
1839  }
1840 
1841  int64_t DurationMin() const override {
1842  CHECK_EQ(performed_.Max(), 1);
1843  return duration_.Min();
1844  }
1845 
1846  int64_t DurationMax() const override {
1847  CHECK_EQ(performed_.Max(), 1);
1848  return duration_.Max();
1849  }
1850 
1851  void SetDurationMin(int64_t m) override {
1852  if (performed_.Max() == 1) {
1853  duration_.SetMin(m);
1854  }
1855  }
1856 
1857  void SetDurationMax(int64_t m) override {
1858  if (performed_.Max() == 1) {
1859  duration_.SetMax(m);
1860  }
1861  }
1862 
1863  void SetDurationRange(int64_t mi, int64_t ma) override {
1864  if (performed_.Max() == 1) {
1865  duration_.SetRange(mi, ma);
1866  }
1867  }
1868 
1869  int64_t OldDurationMin() const override {
1870  CHECK_EQ(performed_.Max(), 1);
1871  CHECK(in_process_);
1872  return duration_.OldMin();
1873  }
1874 
1875  int64_t OldDurationMax() const override {
1876  CHECK_EQ(performed_.Max(), 1);
1877  CHECK(in_process_);
1878  return duration_.OldMax();
1879  }
1880 
1881  void WhenDurationRange(Demon* const d) override {
1882  if (performed_.Max() == 1) {
1883  duration_.WhenRange(d);
1884  }
1885  }
1886 
1887  void WhenDurationBound(Demon* const d) override {
1888  if (performed_.Max() == 1) {
1889  duration_.WhenBound(d);
1890  }
1891  }
1892 
1893  int64_t EndMin() const override {
1894  CHECK_EQ(performed_.Max(), 1);
1895  return end_.Min();
1896  }
1897 
1898  int64_t EndMax() const override {
1899  CHECK_EQ(performed_.Max(), 1);
1900  return end_.Max();
1901  }
1902 
1903  void SetEndMin(int64_t m) override {
1904  if (performed_.Max() == 1) {
1905  end_.SetMin(m);
1906  }
1907  }
1908 
1909  void SetEndMax(int64_t m) override {
1910  if (performed_.Max() == 1) {
1911  end_.SetMax(m);
1912  }
1913  }
1914 
1915  void SetEndRange(int64_t mi, int64_t ma) override {
1916  if (performed_.Max() == 1) {
1917  end_.SetRange(mi, ma);
1918  }
1919  }
1920 
1921  int64_t OldEndMin() const override {
1922  CHECK_EQ(performed_.Max(), 1);
1924  return end_.OldMin();
1925  }
1926 
1927  int64_t OldEndMax() const override {
1928  CHECK_EQ(performed_.Max(), 1);
1930  return end_.OldMax();
1931  }
1932 
1933  void WhenEndRange(Demon* const d) override {
1934  if (performed_.Max() == 1) {
1935  end_.WhenRange(d);
1936  }
1937  }
1938 
1939  void WhenEndBound(Demon* const d) override {
1940  if (performed_.Max() == 1) {
1941  end_.WhenBound(d);
1942  }
1943  }
1944 
1945  bool MustBePerformed() const override { return (performed_.Min() == 1); }
1946 
1947  bool MayBePerformed() const override { return (performed_.Max() == 1); }
1948 
1949  void SetPerformed(bool val) override { performed_.SetValue(val); }
1950 
1951  bool WasPerformedBound() const override {
1952  CHECK(in_process_);
1953  return performed_.OldMin() == performed_.OldMax();
1954  }
1955 
1956  void WhenPerformedBound(Demon* const d) override { performed_.WhenBound(d); }
1957 
1958  void Process() override {
1959  CHECK(!in_process_);
1960  in_process_ = true;
1961  start_.UpdatePostponedBounds();
1962  duration_.UpdatePostponedBounds();
1963  end_.UpdatePostponedBounds();
1964  performed_.UpdatePostponedValue();
1965  set_action_on_fail(cleaner_);
1966  if (performed_.Max() == 1) {
1967  start_.ProcessDemons();
1968  duration_.ProcessDemons();
1969  end_.ProcessDemons();
1970  }
1971  performed_.Process();
1972  reset_action_on_fail();
1973  CleanInProcess();
1974  // TODO(user): Replace this enum by a callback.
1975  start_.UpdatePreviousBounds();
1976  start_.ApplyPostponedBounds(START);
1977  duration_.UpdatePreviousBounds();
1978  duration_.ApplyPostponedBounds(DURATION);
1979  end_.UpdatePreviousBounds();
1980  end_.ApplyPostponedBounds(END);
1981  performed_.UpdatePreviousValueAndApplyPostponedValue();
1982  }
1983 
1984  std::string DebugString() const override {
1985  const std::string& var_name = name();
1986  if (performed_.Max() != 1) {
1987  if (!var_name.empty()) {
1988  return absl::StrFormat("%s(performed = false)", var_name);
1989  } else {
1990  return "IntervalVar(performed = false)";
1991  }
1992  } else {
1993  std::string out;
1994  if (!var_name.empty()) {
1995  out = var_name + "(start = ";
1996  } else {
1997  out = "IntervalVar(start = ";
1998  }
1999 
2000  absl::StrAppendFormat(&out,
2001  "%s, duration = %s, end = %s, performed = %s)",
2002  start_.DebugString(), duration_.DebugString(),
2003  end_.DebugString(), performed_.DebugString());
2004  return out;
2005  }
2006  }
2007 
2008  void Accept(ModelVisitor* const visitor) const override {
2009  visitor->VisitIntervalVariable(this, "", 0, NullInterval());
2010  }
2011 
2012  IntExpr* StartExpr() override { return &start_; }
2013  IntExpr* DurationExpr() override { return &duration_; }
2014  IntExpr* EndExpr() override { return &end_; }
2015  IntExpr* PerformedExpr() override { return &performed_; }
2016  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
2017  return BuildSafeStartExpr(this, unperformed_value);
2018  }
2019  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
2020  return BuildSafeDurationExpr(this, unperformed_value);
2021  }
2022  IntExpr* SafeEndExpr(int64_t unperformed_value) override {
2023  return BuildSafeEndExpr(this, unperformed_value);
2024  }
2025 
2026  private:
2027  void Push() override {
2028  DCHECK(!in_process_);
2029  if (performed_.Max() == 1) {
2030  // Performs the intersection on all intervals before pushing the
2031  // variable onto the queue. This way, we make sure the interval variable
2032  // is always in a consistent minimal state.
2033  start_.SetRange(CapSub(end_.Min(), duration_.Max()),
2034  CapSub(end_.Max(), duration_.Min()));
2035  duration_.SetRange(CapSub(end_.Min(), start_.Max()),
2036  CapSub(end_.Max(), start_.Min()));
2037  end_.SetRange(CapAdd(start_.Min(), duration_.Min()),
2038  CapAdd(start_.Max(), duration_.Max()));
2039  }
2040  EnqueueVar(&handler_);
2041  DCHECK(!in_process_);
2042  }
2043 
2044  RangeVar start_;
2045  RangeVar duration_;
2046  RangeVar end_;
2047  PerformedVar performed_;
2048 };
2049 
2050 // ----- Base synced interval var -----
2051 
2052 class FixedDurationSyncedIntervalVar : public IntervalVar {
2053  public:
2054  FixedDurationSyncedIntervalVar(IntervalVar* const t, int64_t duration,
2055  int64_t offset, const std::string& name)
2056  : IntervalVar(t->solver(), name),
2057  t_(t),
2058  duration_(duration),
2059  offset_(offset) {}
2060  ~FixedDurationSyncedIntervalVar() override {}
2061  int64_t DurationMin() const override { return duration_; }
2062  int64_t DurationMax() const override { return duration_; }
2063  void SetDurationMin(int64_t m) override {
2064  if (m > duration_) {
2065  solver()->Fail();
2066  }
2067  }
2068  void SetDurationMax(int64_t m) override {
2069  if (m < duration_) {
2070  solver()->Fail();
2071  }
2072  }
2073  void SetDurationRange(int64_t mi, int64_t ma) override {
2074  if (mi > duration_ || ma < duration_ || mi > ma) {
2075  solver()->Fail();
2076  }
2077  }
2078  int64_t OldDurationMin() const override { return duration_; }
2079  int64_t OldDurationMax() const override { return duration_; }
2080  void WhenDurationRange(Demon* const d) override {}
2081  void WhenDurationBound(Demon* const d) override {}
2082  int64_t EndMin() const override { return CapAdd(StartMin(), duration_); }
2083  int64_t EndMax() const override { return CapAdd(StartMax(), duration_); }
2084  void SetEndMin(int64_t m) override { SetStartMin(CapSub(m, duration_)); }
2085  void SetEndMax(int64_t m) override { SetStartMax(CapSub(m, duration_)); }
2086  void SetEndRange(int64_t mi, int64_t ma) override {
2087  SetStartRange(CapSub(mi, duration_), CapSub(ma, duration_));
2088  }
2089  int64_t OldEndMin() const override {
2090  return CapAdd(OldStartMin(), duration_);
2091  }
2092  int64_t OldEndMax() const override {
2093  return CapAdd(OldStartMax(), duration_);
2094  }
2095  void WhenEndRange(Demon* const d) override { WhenStartRange(d); }
2096  void WhenEndBound(Demon* const d) override { WhenStartBound(d); }
2097  bool MustBePerformed() const override { return t_->MustBePerformed(); }
2098  bool MayBePerformed() const override { return t_->MayBePerformed(); }
2099  void SetPerformed(bool val) override { t_->SetPerformed(val); }
2100  bool WasPerformedBound() const override { return t_->WasPerformedBound(); }
2101  void WhenPerformedBound(Demon* const d) override {
2102  t_->WhenPerformedBound(d);
2103  }
2104 
2105  protected:
2106  IntervalVar* const t_;
2107  const int64_t duration_;
2108  const int64_t offset_;
2109 
2110  private:
2111  DISALLOW_COPY_AND_ASSIGN(FixedDurationSyncedIntervalVar);
2112 };
2113 
2114 // ----- Fixed duration interval var synced on start -----
2115 
2116 class FixedDurationIntervalVarStartSyncedOnStart
2117  : public FixedDurationSyncedIntervalVar {
2118  public:
2119  FixedDurationIntervalVarStartSyncedOnStart(IntervalVar* const t,
2120  int64_t duration, int64_t offset)
2121  : FixedDurationSyncedIntervalVar(
2122  t, duration, offset,
2123  absl::StrFormat(
2124  "IntervalStartSyncedOnStart(%s, duration = %d, offset = %d)",
2125  t->name(), duration, offset)) {}
2126  ~FixedDurationIntervalVarStartSyncedOnStart() override {}
2127  int64_t StartMin() const override { return CapAdd(t_->StartMin(), offset_); }
2128  int64_t StartMax() const override { return CapAdd(t_->StartMax(), offset_); }
2129  void SetStartMin(int64_t m) override { t_->SetStartMin(CapSub(m, offset_)); }
2130  void SetStartMax(int64_t m) override { t_->SetStartMax(CapSub(m, offset_)); }
2131  void SetStartRange(int64_t mi, int64_t ma) override {
2132  t_->SetStartRange(CapSub(mi, offset_), CapSub(ma, offset_));
2133  }
2134  int64_t OldStartMin() const override {
2135  return CapAdd(t_->OldStartMin(), offset_);
2136  }
2137  int64_t OldStartMax() const override {
2138  return CapAdd(t_->OldStartMax(), offset_);
2139  }
2140  void WhenStartRange(Demon* const d) override { t_->WhenStartRange(d); }
2141  void WhenStartBound(Demon* const d) override { t_->WhenStartBound(d); }
2142  IntExpr* StartExpr() override {
2143  return solver()->MakeSum(t_->StartExpr(), offset_);
2144  }
2145  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
2146  IntExpr* EndExpr() override {
2147  return solver()->MakeSum(t_->StartExpr(), offset_ + duration_);
2148  }
2149  IntExpr* PerformedExpr() override { return t_->PerformedExpr(); }
2150  // These methods create expressions encapsulating the start, end
2151  // and duration of the interval var. If the interval var is
2152  // unperformed, they will return the unperformed_value.
2153  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
2154  return BuildSafeStartExpr(t_, unperformed_value);
2155  }
2156  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
2157  return BuildSafeDurationExpr(t_, unperformed_value);
2158  }
2159  IntExpr* SafeEndExpr(int64_t unperformed_value) override {
2160  return BuildSafeEndExpr(t_, unperformed_value);
2161  }
2162  void Accept(ModelVisitor* const visitor) const override {
2163  visitor->VisitIntervalVariable(
2164  this, ModelVisitor::kStartSyncOnStartOperation, offset_, t_);
2165  }
2166  std::string DebugString() const override {
2167  return absl::StrFormat(
2168  "IntervalStartSyncedOnStart(%s, duration = %d, offset = %d)",
2169  t_->DebugString(), duration_, offset_);
2170  }
2171 };
2172 
2173 // ----- Fixed duration interval start synced on end -----
2174 
2175 class FixedDurationIntervalVarStartSyncedOnEnd
2176  : public FixedDurationSyncedIntervalVar {
2177  public:
2178  FixedDurationIntervalVarStartSyncedOnEnd(IntervalVar* const t,
2179  int64_t duration, int64_t offset)
2180  : FixedDurationSyncedIntervalVar(
2181  t, duration, offset,
2182  absl::StrFormat(
2183  "IntervalStartSyncedOnEnd(%s, duration = %d, offset = %d)",
2184  t->name(), duration, offset)) {}
2185  ~FixedDurationIntervalVarStartSyncedOnEnd() override {}
2186  int64_t StartMin() const override { return CapAdd(t_->EndMin(), offset_); }
2187  int64_t StartMax() const override { return CapAdd(t_->EndMax(), offset_); }
2188  void SetStartMin(int64_t m) override { t_->SetEndMin(CapSub(m, offset_)); }
2189  void SetStartMax(int64_t m) override { t_->SetEndMax(CapSub(m, offset_)); }
2190  void SetStartRange(int64_t mi, int64_t ma) override {
2191  t_->SetEndRange(CapSub(mi, offset_), CapSub(ma, offset_));
2192  }
2193  int64_t OldStartMin() const override {
2194  return CapAdd(t_->OldEndMin(), offset_);
2195  }
2196  int64_t OldStartMax() const override {
2197  return CapAdd(t_->OldEndMax(), offset_);
2198  }
2199  void WhenStartRange(Demon* const d) override { t_->WhenEndRange(d); }
2200  void WhenStartBound(Demon* const d) override { t_->WhenEndBound(d); }
2201  IntExpr* StartExpr() override {
2202  return solver()->MakeSum(t_->EndExpr(), offset_);
2203  }
2204  IntExpr* DurationExpr() override { return solver()->MakeIntConst(duration_); }
2205  IntExpr* EndExpr() override {
2206  return solver()->MakeSum(t_->EndExpr(), offset_ + duration_);
2207  }
2208  IntExpr* PerformedExpr() override { return t_->PerformedExpr(); }
2209  // These methods create expressions encapsulating the start, end
2210  // and duration of the interval var. If the interval var is
2211  // unperformed, they will return the unperformed_value.
2212  IntExpr* SafeStartExpr(int64_t unperformed_value) override {
2213  return BuildSafeStartExpr(t_, unperformed_value);
2214  }
2215  IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
2216  return BuildSafeDurationExpr(t_, unperformed_value);
2217  }
2218  IntExpr* SafeEndExpr(int64_t unperformed_value) override {
2219  return BuildSafeEndExpr(t_, unperformed_value);
2220  }
2221 
2222  void Accept(ModelVisitor* const visitor) const override {
2223  visitor->VisitIntervalVariable(this, ModelVisitor::kStartSyncOnEndOperation,
2224  offset_, t_);
2225  }
2226  std::string DebugString() const override {
2227  return absl::StrFormat(
2228  "IntervalStartSyncedOnEnd(%s, duration = %d, offset = %d)",
2229  t_->DebugString(), duration_, offset_);
2230  }
2231 };
2232 } // namespace
2233 
2234 // ----- API -----
2235 
2236 IntervalVar* Solver::MakeMirrorInterval(IntervalVar* const interval_var) {
2237  return RegisterIntervalVar(
2238  RevAlloc(new MirrorIntervalVar(this, interval_var)));
2239 }
2240 
2241 IntervalVar* Solver::MakeIntervalRelaxedMax(IntervalVar* const interval_var) {
2242  if (interval_var->MustBePerformed()) {
2243  return interval_var;
2244  } else {
2245  return RegisterIntervalVar(
2246  RevAlloc(new IntervalVarRelaxedMax(interval_var)));
2247  }
2248 }
2249 
2250 IntervalVar* Solver::MakeIntervalRelaxedMin(IntervalVar* const interval_var) {
2251  if (interval_var->MustBePerformed()) {
2252  return interval_var;
2253  } else {
2254  return RegisterIntervalVar(
2255  RevAlloc(new IntervalVarRelaxedMin(interval_var)));
2256  }
2257 }
2258 
2259 void IntervalVar::WhenAnything(Demon* const d) {
2260  WhenStartRange(d);
2261  WhenDurationRange(d);
2262  WhenEndRange(d);
2263  WhenPerformedBound(d);
2264 }
2265 
2266 IntervalVar* Solver::MakeFixedInterval(int64_t start, int64_t duration,
2267  const std::string& name) {
2268  return RevAlloc(new FixedInterval(this, start, duration, name));
2269 }
2270 
2271 IntervalVar* Solver::MakeFixedDurationIntervalVar(int64_t start_min,
2272  int64_t start_max,
2273  int64_t duration,
2274  bool optional,
2275  const std::string& name) {
2276  if (start_min == start_max && !optional) {
2277  return MakeFixedInterval(start_min, duration, name);
2278  } else if (!optional) {
2279  return RegisterIntervalVar(RevAlloc(new FixedDurationPerformedIntervalVar(
2280  this, start_min, start_max, duration, name)));
2281  }
2282  return RegisterIntervalVar(RevAlloc(new FixedDurationIntervalVar(
2283  this, start_min, start_max, duration, optional, name)));
2284 }
2285 
2286 void Solver::MakeFixedDurationIntervalVarArray(
2287  int count, int64_t start_min, int64_t start_max, int64_t duration,
2288  bool optional, const std::string& name, std::vector<IntervalVar*>* array) {
2289  CHECK_GT(count, 0);
2290  CHECK(array != nullptr);
2291  array->clear();
2292  for (int i = 0; i < count; ++i) {
2293  const std::string var_name = absl::StrCat(name, i);
2294  array->push_back(MakeFixedDurationIntervalVar(
2295  start_min, start_max, duration, optional, var_name));
2296  }
2297 }
2298 
2299 IntervalVar* Solver::MakeFixedDurationIntervalVar(IntVar* const start_variable,
2300  int64_t duration,
2301  const std::string& name) {
2302  CHECK(start_variable != nullptr);
2303  CHECK_GE(duration, 0);
2304  return RegisterIntervalVar(RevAlloc(
2305  new StartVarPerformedIntervalVar(this, start_variable, duration, name)));
2306 }
2307 
2308 // Creates an interval var with a fixed duration, and performed var.
2309 // The duration must be greater than 0.
2310 IntervalVar* Solver::MakeFixedDurationIntervalVar(
2311  IntVar* const start_variable, int64_t duration,
2312  IntVar* const performed_variable, const std::string& name) {
2313  CHECK(start_variable != nullptr);
2314  CHECK(performed_variable != nullptr);
2315  CHECK_GE(duration, 0);
2316  if (!performed_variable->Bound()) {
2317  StartVarIntervalVar* const interval =
2318  reinterpret_cast<StartVarIntervalVar*>(
2319  RegisterIntervalVar(RevAlloc(new StartVarIntervalVar(
2320  this, start_variable, duration, performed_variable, name))));
2321  AddConstraint(RevAlloc(new LinkStartVarIntervalVar(
2322  this, interval, start_variable, performed_variable)));
2323  return interval;
2324  } else if (performed_variable->Min() == 1) {
2325  return RegisterIntervalVar(RevAlloc(new StartVarPerformedIntervalVar(
2326  this, start_variable, duration, name)));
2327  }
2328  return nullptr;
2329 }
2330 
2331 void Solver::MakeFixedDurationIntervalVarArray(
2332  const std::vector<IntVar*>& start_variables, int64_t duration,
2333  const std::string& name, std::vector<IntervalVar*>* array) {
2334  CHECK(array != nullptr);
2335  array->clear();
2336  for (int i = 0; i < start_variables.size(); ++i) {
2337  const std::string var_name = absl::StrCat(name, i);
2338  array->push_back(
2339  MakeFixedDurationIntervalVar(start_variables[i], duration, var_name));
2340  }
2341 }
2342 
2343 // This method fills the vector with interval variables built with
2344 // the corresponding start variables.
2345 void Solver::MakeFixedDurationIntervalVarArray(
2346  const std::vector<IntVar*>& start_variables,
2347  const std::vector<int64_t>& durations, const std::string& name,
2348  std::vector<IntervalVar*>* array) {
2349  CHECK(array != nullptr);
2350  CHECK_EQ(start_variables.size(), durations.size());
2351  array->clear();
2352  for (int i = 0; i < start_variables.size(); ++i) {
2353  const std::string var_name = absl::StrCat(name, i);
2354  array->push_back(MakeFixedDurationIntervalVar(start_variables[i],
2355  durations[i], var_name));
2356  }
2357 }
2358 
2359 void Solver::MakeFixedDurationIntervalVarArray(
2360  const std::vector<IntVar*>& start_variables,
2361  const std::vector<int>& durations, const std::string& name,
2362  std::vector<IntervalVar*>* array) {
2363  CHECK(array != nullptr);
2364  CHECK_EQ(start_variables.size(), durations.size());
2365  array->clear();
2366  for (int i = 0; i < start_variables.size(); ++i) {
2367  const std::string var_name = absl::StrCat(name, i);
2368  array->push_back(MakeFixedDurationIntervalVar(start_variables[i],
2369  durations[i], var_name));
2370  }
2371 }
2372 
2373 void Solver::MakeFixedDurationIntervalVarArray(
2374  const std::vector<IntVar*>& start_variables,
2375  const std::vector<int>& durations,
2376  const std::vector<IntVar*>& performed_variables, const std::string& name,
2377  std::vector<IntervalVar*>* array) {
2378  CHECK(array != nullptr);
2379  array->clear();
2380  for (int i = 0; i < start_variables.size(); ++i) {
2381  const std::string var_name = absl::StrCat(name, i);
2382  array->push_back(MakeFixedDurationIntervalVar(
2383  start_variables[i], durations[i], performed_variables[i], var_name));
2384  }
2385 }
2386 
2387 void Solver::MakeFixedDurationIntervalVarArray(
2388  const std::vector<IntVar*>& start_variables,
2389  const std::vector<int64_t>& durations,
2390  const std::vector<IntVar*>& performed_variables, const std::string& name,
2391  std::vector<IntervalVar*>* array) {
2392  CHECK(array != nullptr);
2393  array->clear();
2394  for (int i = 0; i < start_variables.size(); ++i) {
2395  const std::string var_name = absl::StrCat(name, i);
2396  array->push_back(MakeFixedDurationIntervalVar(
2397  start_variables[i], durations[i], performed_variables[i], var_name));
2398  }
2399 }
2400 
2401 // Variable Duration Interval Var
2402 
2403 IntervalVar* Solver::MakeIntervalVar(int64_t start_min, int64_t start_max,
2404  int64_t duration_min, int64_t duration_max,
2405  int64_t end_min, int64_t end_max,
2406  bool optional, const std::string& name) {
2407  return RegisterIntervalVar(RevAlloc(new VariableDurationIntervalVar(
2408  this, start_min, start_max, duration_min, duration_max, end_min, end_max,
2409  optional, name)));
2410 }
2411 
2412 void Solver::MakeIntervalVarArray(int count, int64_t start_min,
2413  int64_t start_max, int64_t duration_min,
2414  int64_t duration_max, int64_t end_min,
2415  int64_t end_max, bool optional,
2416  const std::string& name,
2417  std::vector<IntervalVar*>* const array) {
2418  CHECK_GT(count, 0);
2419  CHECK(array != nullptr);
2420  array->clear();
2421  for (int i = 0; i < count; ++i) {
2422  const std::string var_name = absl::StrCat(name, i);
2423  array->push_back(MakeIntervalVar(start_min, start_max, duration_min,
2424  duration_max, end_min, end_max, optional,
2425  var_name));
2426  }
2427 }
2428 
2429 // Synced Interval Vars
2430 IntervalVar* Solver::MakeFixedDurationStartSyncedOnStartIntervalVar(
2431  IntervalVar* const interval_var, int64_t duration, int64_t offset) {
2432  return RegisterIntervalVar(
2433  RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart(
2434  interval_var, duration, offset)));
2435 }
2436 
2437 IntervalVar* Solver::MakeFixedDurationStartSyncedOnEndIntervalVar(
2438  IntervalVar* const interval_var, int64_t duration, int64_t offset) {
2439  return RegisterIntervalVar(
2440  RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd(interval_var,
2441  duration, offset)));
2442 }
2443 
2444 IntervalVar* Solver::MakeFixedDurationEndSyncedOnStartIntervalVar(
2445  IntervalVar* const interval_var, int64_t duration, int64_t offset) {
2446  return RegisterIntervalVar(
2447  RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart(
2448  interval_var, duration, CapSub(offset, duration))));
2449 }
2450 
2451 IntervalVar* Solver::MakeFixedDurationEndSyncedOnEndIntervalVar(
2452  IntervalVar* const interval_var, int64_t duration, int64_t offset) {
2453  return RegisterIntervalVar(
2454  RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd(
2455  interval_var, duration, CapSub(offset, duration))));
2456 }
2457 } // namespace operations_research
#define CHECK(condition)
Definition: base/logging.h:491
int64_t CapSub(int64_t x, int64_t y)
int64_t min
Definition: alldiff_cst.cc:139
Rev< int > performed
void LinkVarExpr(Solver *const s, IntExpr *const expr, IntVar *const var)
#define CHECK_GE(val1, val2)
Definition: base/logging.h:702
const int FATAL
Definition: log_severity.h:32
IntExpr * BuildSafeEndExpr(IntervalVar *var, int64_t unperformed_value)
Definition: sched_expr.cc:195
#define CHECK_GT(val1, val2)
Definition: base/logging.h:703
const std::string name
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
IntExpr * BuildStartExpr(IntervalVar *var)
Definition: sched_expr.cc:155
A Demon is the base element of a propagation queue.
#define LOG(severity)
Definition: base/logging.h:416
Rev< int64_t > start_min
virtual int64_t Min() const =0
Handler handler_
Definition: interval.cc:429
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
Interval variables are often used in scheduling.
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
int64_t max
Definition: alldiff_cst.cc:140
static const int64_t kMinValidValue
The smallest acceptable value to be returned by StartMin()
bool in_process_
Definition: interval.cc:428
Definition: cleanup.h:22
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
Rev< int64_t > start_max
Rev< int64_t > end_max
int64_t CapAdd(int64_t x, int64_t y)
#define DCHECK_NE(val1, val2)
Definition: base/logging.h:887
Rev< int64_t > end_min
IntExpr * BuildSafeDurationExpr(IntervalVar *var, int64_t unperformed_value)
Definition: sched_expr.cc:190
static const int64_t kMaxValidValue
The largest acceptable value to be returned by EndMax()
std::function< void(Solver *)> Action
The class IntVar is a subset of IntExpr.
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:698
IntExpr * BuildEndExpr(IntervalVar *var)
Definition: sched_expr.cc:175
IntExpr * BuildSafeStartExpr(IntervalVar *var, int64_t unperformed_value)
Definition: sched_expr.cc:185
#define DCHECK(condition)
Definition: base/logging.h:885
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:886
static const char kMirrorOperation[]
Operations.
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
Collection of objects used to extend the Constraint Solver library.
const int64_t offset_
Definition: interval.cc:2108
IntVar * var
Definition: expr_array.cc:1874
virtual bool MustBePerformed() const =0
These methods query, set, and watch the performed status of the interval var.
IntExpr * BuildDurationExpr(IntervalVar *var)
Definition: sched_expr.cc:165
Solver::Action cleaner_
Definition: interval.cc:430
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
IntervalVar * interval
Definition: resource.cc:100
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:29