Google OR-Tools: ortools/constraint_solver/interval.cc Source File

1

2

3

4

5

6

7

8

9

10

11

12

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"

29

30#if defined(_MSC_VER)

31#pragma warning(disable : 4351 4355 4804 4805)

32#endif

33

35

36

37

38

39

40

48

49

50

52 std::numeric_limits<int64_t>::max() >> 2;

54

55namespace {

56enum IntervalField { START, DURATION, END };

57

58IntervalVar* NullInterval() { return nullptr; }

59

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

67 MirrorIntervalVar(const MirrorIntervalVar&) = delete;

68 MirrorIntervalVar& operator=(const MirrorIntervalVar&) = delete;

69 ~MirrorIntervalVar() override {}

70

71

72

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

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

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

112

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 {

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

138

139

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

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

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

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

246

247

248

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_));

261 }

262 return start_expr_;

263 }

264 IntExpr* DurationExpr() override {

265 if (duration_expr_ == nullptr) {

266 solver()->SaveValue(reinterpret_cast<void**>(&duration_expr_));

268 }

269 return duration_expr_;

270 }

271 IntExpr* EndExpr() override {

272 if (end_expr_ == nullptr) {

273 solver()->SaveValue(reinterpret_cast<void**>(&end_expr_));

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

301

302

303

304

305

306

307

308

309

310

311

312

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

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 {

340 underlying());

341 }

342

343 std::string DebugString() const override {

344 return absl::StrFormat("IntervalVarRelaxedMax(%s)",

345 underlying()->DebugString());

346 }

347};

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

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

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 {

390 underlying());

391 }

392

393 std::string DebugString() const override {

394 return absl::StrFormat("IntervalVarRelaxedMin(%s)",

395 underlying()->DebugString());

396 }

397};

398

399

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(); }

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

466 if (m <= min_.Value()) {

467 return;

468 }

469

470 if (m > max_.Value()) {

471 var_->SetPerformed(false);

472 return;

473 }

474 if (var_->InProcess()) {

475

476 if (m > postponed_max_) {

477 var_->SetPerformed(false);

478 }

479 if (m > postponed_min_) {

480 postponed_min_ = m;

481 }

482 } else {

483

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

505 if (m < postponed_min_) {

506 var_->SetPerformed(false);

507 }

508 if (m < postponed_max_) {

509 postponed_max_ = m;

510 }

511 } else {

512

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

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

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()) {

555 delayed_range_demons_.PushIfNotTop(solver(),

557 } else {

558 range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(demon));

559 }

560 }

561 }

562

563 virtual void WhenBound(Demon* const demon) {

564 if (!Bound()) {

566 delayed_bound_demons_.PushIfNotTop(solver(),

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

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());

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

634

635

636

637

638

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

649 NumericalRev<int64_t> min_;

650 NumericalRev<int64_t> max_;

651 BaseIntervalVar* const var_;

652

653

654 int64_t postponed_min_;

655 int64_t postponed_max_;

656

657

658 int64_t previous_min_;

659 int64_t previous_max_;

660

661 SimpleRevFIFO<Demon*> bound_demons_;

662 SimpleRevFIFO<Demon*> delayed_bound_demons_;

663

664 SimpleRevFIFO<Demon*> range_demons_;

665 SimpleRevFIFO<Demon*> delayed_range_demons_;

666 IntVar* cast_var_;

667};

668

669

670

671class PerformedVar : public BooleanVar {

672 public:

673

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

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 ||

693 (value_ != kUnboundBooleanVarValue && v != value_)) {

694 solver()->Fail();

695 }

696 if (var_->InProcess()) {

697 if (postponed_value_ != kUnboundBooleanVarValue &&

698 v != postponed_value_) {

699 solver()->Fail();

700 } else {

701 postponed_value_ = v;

702 }

703 } else if (value_ == kUnboundBooleanVarValue) {

704 previous_value_ = kUnboundBooleanVarValue;

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

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

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 {

830 }

831 IntExpr* SafeDurationExpr(int64_t unperformed_value) override {

833 }

834 IntExpr* SafeEndExpr(int64_t unperformed_value) override {

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

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

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

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

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

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 {

1430 }

1431 IntExpr* SafeDurationExpr(int64_t unperformed_value) override {

1433 }

1434 IntExpr* SafeEndExpr(int64_t unperformed_value) override {

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 {

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

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

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

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 {

2028 }

2029 IntExpr* SafeDurationExpr(int64_t unperformed_value) override {

2031 }

2032 IntExpr* SafeEndExpr(int64_t unperformed_value) override {

2034 }

2035

2036 private:

2037 void Push() override {

2038 DCHECK(!in_process_);

2039 if (performed_.Max() == 1) {

2040

2041

2042

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

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

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

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

2164

2165

2166 IntExpr* SafeStartExpr(int64_t unperformed_value) override {

2168 }

2169 IntExpr* SafeDurationExpr(int64_t unperformed_value) override {

2171 }

2172 IntExpr* SafeEndExpr(int64_t unperformed_value) override {

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

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

2223

2224

2225 IntExpr* SafeStartExpr(int64_t unperformed_value) override {

2227 }

2228 IntExpr* SafeDurationExpr(int64_t unperformed_value) override {

2230 }

2231 IntExpr* SafeEndExpr(int64_t unperformed_value) override {

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}

2246

2247

2248

2251 RevAlloc(new MirrorIntervalVar(this, interval_var)));

2252}

2253

2256 return interval_var;

2257 } else {

2259 RevAlloc(new IntervalVarRelaxedMax(interval_var)));

2260 }

2261}

2262

2265 return interval_var;

2266 } else {

2268 RevAlloc(new IntervalVarRelaxedMin(interval_var)));

2269 }

2270}

2271

2278

2280 const std::string& name) {

2281 return RevAlloc(new FixedInterval(this, start, duration, name));

2282}

2283

2285 int64_t start_max,

2286 int64_t duration,

2287 bool optional,

2288 const std::string& name) {

2289 if (start_min == start_max && !optional) {

2291 } else if (!optional) {

2293 this, start_min, start_max, duration, name)));

2294 }

2296 this, start_min, start_max, duration, optional, name)));

2297}

2298

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);

2308 start_min, start_max, duration, optional, var_name));

2309 }

2310}

2311

2313 int64_t duration,

2314 const std::string& name) {

2315 CHECK(start_variable != nullptr);

2316 CHECK_GE(duration, 0);

2318 new StartVarPerformedIntervalVar(this, start_variable, duration, name)));

2319}

2320

2321

2322

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*>(

2333 this, start_variable, duration, performed_variable, name))));

2335 this, interval, start_variable, performed_variable)));

2336 return interval;

2337 } else if (performed_variable->Min() == 1) {

2339 this, start_variable, duration, name)));

2340 }

2341 return nullptr;

2342}

2343

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(

2353 }

2354}

2355

2356

2357

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);

2368 durations[i], var_name));

2369 }

2370}

2371

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);

2382 durations[i], var_name));

2383 }

2384}

2385

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);

2396 start_variables[i], durations[i], performed_variables[i], var_name));

2397 }

2398}

2399

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);

2410 start_variables[i], durations[i], performed_variables[i], var_name));

2411 }

2412}

2413

2414

2415

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) {

2421 this, start_min, start_max, duration_min, duration_max, end_min, end_max,

2422 optional, name)));

2423}

2424

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

2444 IntervalVar* const interval_var, int64_t duration, int64_t offset) {

2446 RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart(

2447 interval_var, duration, offset)));

2448}

2449

2451 IntervalVar* const interval_var, int64_t duration, int64_t offset) {

2453 RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd(interval_var,

2454 duration, offset)));

2455}

2456

2458 IntervalVar* const interval_var, int64_t duration, int64_t offset) {

2460 RevAlloc(new FixedDurationIntervalVarStartSyncedOnStart(

2461 interval_var, duration, CapSub(offset, duration))));

2462}

2463

2465 IntervalVar* const interval_var, int64_t duration, int64_t offset) {

2467 RevAlloc(new FixedDurationIntervalVarStartSyncedOnEnd(

2468 interval_var, duration, CapSub(offset, duration))));

2469}

2470}

virtual bool Bound() const

Returns true if the min and the max of the expression are equal.

virtual int64_t Min() const =0

virtual void WhenEndRange(Demon *d)=0

static const int64_t kMaxValidValue

The largest acceptable value to be returned by EndMax().

virtual void WhenStartRange(Demon *d)=0

void WhenAnything(Demon *d)

Attaches a demon awakened when anything about this interval changes.

Definition interval.cc:2272

static const int64_t kMinValidValue

The smallest acceptable value to be returned by StartMin().

virtual void WhenDurationRange(Demon *d)=0

virtual void WhenPerformedBound(Demon *d)=0

virtual bool MustBePerformed() const =0

static const char kRelaxedMinOperation[]

static const char kMirrorOperation[]

Operations.

static const char kRelaxedMaxOperation[]

IntervalVar * MakeMirrorInterval(IntervalVar *interval_var)

Definition interval.cc:2249

IntervalVar * MakeFixedDurationStartSyncedOnEndIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)

Definition interval.cc:2450

void MakeIntervalVarArray(int count, int64_t start_min, int64_t start_max, int64_t duration_min, int64_t duration_max, int64_t end_min, int64_t end_max, bool optional, absl::string_view name, std::vector< IntervalVar * > *array)

Definition interval.cc:2425

IntervalVar * MakeIntervalVar(int64_t start_min, int64_t start_max, int64_t duration_min, int64_t duration_max, int64_t end_min, int64_t end_max, bool optional, const std::string &name)

Definition interval.cc:2416

@ VAR_PRIORITY

VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.

IntervalVar * MakeFixedDurationEndSyncedOnStartIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)

Definition interval.cc:2457

void MakeFixedDurationIntervalVarArray(int count, int64_t start_min, int64_t start_max, int64_t duration, bool optional, absl::string_view name, std::vector< IntervalVar * > *array)

Definition interval.cc:2299

IntervalVar * MakeFixedDurationIntervalVar(int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string &name)

Definition interval.cc:2284

std::function< void(Solver *)> Action

IntervalVar * MakeFixedInterval(int64_t start, int64_t duration, const std::string &name)

Creates a fixed and performed interval.

Definition interval.cc:2279

IntervalVar * RegisterIntervalVar(IntervalVar *var)

IntervalVar * MakeIntervalRelaxedMax(IntervalVar *interval_var)

Definition interval.cc:2254

IntervalVar * MakeFixedDurationEndSyncedOnEndIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)

Definition interval.cc:2464

IntervalVar * MakeFixedDurationStartSyncedOnStartIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)

Definition interval.cc:2443

IntervalVar * MakeIntervalRelaxedMin(IntervalVar *interval_var)

Definition interval.cc:2263

void AddConstraint(Constraint *c)

Adds the constraint 'c' to the model.

For infeasible and unbounded see Not checked if options check_solutions_if_inf_or_unbounded and the If options first_solution_only is false

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)

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)

void LinkVarExpr(Solver *s, IntExpr *expr, IntVar *var)

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)