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