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