17#include "absl/strings/str_format.h"
29const char* kUnaryNames[] = {
30 "ENDS_AFTER",
"ENDS_AT",
"ENDS_BEFORE",
"STARTS_AFTER",
31 "STARTS_AT",
"STARTS_BEFORE",
"CROSS_DATE",
"AVOID_DATE",
34const char* kBinaryNames[] = {
35 "ENDS_AFTER_END",
"ENDS_AFTER_START",
"ENDS_AT_END",
36 "ENDS_AT_START",
"STARTS_AFTER_END",
"STARTS_AFTER_START",
37 "STARTS_AT_END",
"STARTS_AT_START",
"STAYS_IN_SYNC"};
39class IntervalUnaryRelation :
public Constraint {
41 IntervalUnaryRelation(Solver*
const s, IntervalVar*
const t, int64_t d,
43 : Constraint(s), t_(t), d_(d), rel_(rel) {}
44 ~IntervalUnaryRelation()
override {}
48 void InitialPropagate()
override;
50 std::string DebugString()
const override {
51 return absl::StrFormat(
"(%s %s %d)", t_->DebugString(), kUnaryNames[rel_],
55 void Accept(ModelVisitor*
const visitor)
const override {
64 IntervalVar*
const t_;
69void IntervalUnaryRelation::Post() {
71 Demon* d = solver()->MakeConstraintInitialPropagateCallback(
this);
76void IntervalUnaryRelation::InitialPropagate() {
117 return RevAlloc(
new IntervalUnaryRelation(
this, t, d, r));
123class IntervalBinaryRelation :
public Constraint {
128 :
Constraint(s), t1_(t1), t2_(t2), rel_(rel), delay_(delay) {}
129 ~IntervalBinaryRelation()
override {}
131 void Post()
override;
133 void InitialPropagate()
override;
135 std::string DebugString()
const override {
136 return absl::StrFormat(
"(%s %s %s)", t1_->DebugString(), kBinaryNames[rel_],
140 void Accept(ModelVisitor*
const visitor)
const override {
149 IntervalVar*
const t1_;
150 IntervalVar*
const t2_;
152 const int64_t delay_;
155void IntervalBinaryRelation::Post() {
157 Demon* d = solver()->MakeConstraintInitialPropagateCallback(
this);
164void IntervalBinaryRelation::InitialPropagate() {
236 return RevAlloc(
new IntervalBinaryRelation(
this, t1, t2, r, 0));
242 return RevAlloc(
new IntervalBinaryRelation(
this, t1, t2, r, delay));
248class TemporalDisjunction :
public Constraint {
250 enum State { ONE_BEFORE_TWO, TWO_BEFORE_ONE, UNDECIDED };
252 TemporalDisjunction(Solver*
const s, IntervalVar*
const t1,
253 IntervalVar*
const t2, IntVar*
const alt)
254 : Constraint(s), t1_(t1), t2_(t2), alt_(alt), state_(UNDECIDED) {}
255 ~TemporalDisjunction()
override {}
257 void Post()
override;
258 void InitialPropagate()
override;
259 std::string DebugString()
const override;
264 void Decide(State s);
267 void Accept(ModelVisitor*
const visitor)
const override {
277 IntervalVar*
const t1_;
278 IntervalVar*
const t2_;
283void TemporalDisjunction::Post() {
284 Solver*
const s = solver();
291 if (alt_ !=
nullptr) {
298void TemporalDisjunction::InitialPropagate() {
299 if (alt_ !=
nullptr) {
302 if (alt_ !=
nullptr && alt_->
Bound()) {
310std::string TemporalDisjunction::DebugString()
const {
312 (out = absl::StrFormat(
"TemporalDisjunction(%s, %s", t1_->
DebugString(),
314 if (alt_ !=
nullptr) {
315 absl::StrAppendFormat(&out,
" => %s", alt_->
DebugString());
321void TemporalDisjunction::TryToDecide() {
326 Decide(TWO_BEFORE_ONE);
328 Decide(ONE_BEFORE_TWO);
333void TemporalDisjunction::RangeDemon1() {
335 case ONE_BEFORE_TWO: {
341 case TWO_BEFORE_ONE: {
353void TemporalDisjunction::RangeDemon2() {
356 case ONE_BEFORE_TWO: {
362 case TWO_BEFORE_ONE: {
375void TemporalDisjunction::RangeAlt() {
377 if (alt_->
Value() == 0) {
378 Decide(ONE_BEFORE_TWO);
380 Decide(TWO_BEFORE_ONE);
384void TemporalDisjunction::Decide(State s) {
387 if (state_ != UNDECIDED && state_ != s) {
390 solver()->SaveValue(
reinterpret_cast<int*
>(&state_));
392 if (alt_ !=
nullptr) {
393 if (s == ONE_BEFORE_TWO) {
407 return RevAlloc(
new TemporalDisjunction(
this, t1, t2, alt));
412 return RevAlloc(
new TemporalDisjunction(
this, t1, t2,
nullptr));
#define DCHECK_NE(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
A constraint is the main modeling object.
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
The class IntVar is a subset of IntExpr.
virtual int64_t Value() const =0
This method returns the value of the variable.
Interval variables are often used in scheduling.
virtual void SetEndMax(int64_t m)=0
void WhenAnything(Demon *const d)
Attaches a demon awakened when anything about this interval changes.
virtual void SetStartMax(int64_t m)=0
virtual void SetStartRange(int64_t mi, int64_t ma)=0
virtual bool MustBePerformed() const =0
These methods query, set, and watch the performed status of the interval var.
virtual void SetEndMin(int64_t m)=0
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
virtual int64_t StartMin() const =0
These methods query, set, and watch the start position of the interval var.
virtual int64_t EndMax() const =0
virtual void SetStartMin(int64_t m)=0
virtual bool MayBePerformed() const =0
virtual void SetEndRange(int64_t mi, int64_t ma)=0
virtual int64_t StartMax() const =0
static const char kIntervalArgument[]
static const char kTargetArgument[]
static const char kIntervalUnaryRelation[]
static const char kValueArgument[]
static const char kIntervalDisjunction[]
static const char kRelationArgument[]
static const char kLeftArgument[]
static const char kRightArgument[]
static const char kIntervalBinaryRelation[]
std::string DebugString() const override
Constraint * MakeIntervalVarRelationWithDelay(IntervalVar *const t1, BinaryIntervalRelation r, IntervalVar *const t2, int64_t delay)
This method creates a relation between two interval vars.
UnaryIntervalRelation
This enum is used in Solver::MakeIntervalVarRelation to specify the temporal relation between an inte...
@ ENDS_BEFORE
t ends before d, i.e. End(t) <= d.
@ AVOID_DATE
STARTS_AFTER or ENDS_BEFORE, i.e.
@ ENDS_AFTER
t ends after d, i.e. End(t) >= d.
@ STARTS_BEFORE
t starts before d, i.e. Start(t) <= d.
@ STARTS_AT
t starts at d, i.e. Start(t) == d.
@ ENDS_AT
t ends at d, i.e. End(t) == d.
@ STARTS_AFTER
t starts after d, i.e. Start(t) >= d.
@ CROSS_DATE
STARTS_BEFORE and ENDS_AFTER at the same time, i.e.
BinaryIntervalRelation
This enum is used in Solver::MakeIntervalVarRelation to specify the temporal relation between the two...
@ ENDS_AFTER_END
t1 ends after t2 end, i.e. End(t1) >= End(t2) + delay.
@ ENDS_AFTER_START
t1 ends after t2 start, i.e. End(t1) >= Start(t2) + delay.
@ STAYS_IN_SYNC
STARTS_AT_START and ENDS_AT_END at the same time.
@ ENDS_AT_END
t1 ends at t2 end, i.e. End(t1) == End(t2) + delay.
@ STARTS_AT_END
t1 starts at t2 end, i.e. Start(t1) == End(t2) + delay.
@ ENDS_AT_START
t1 ends at t2 start, i.e. End(t1) == Start(t2) + delay.
@ STARTS_AFTER_END
t1 starts after t2 end, i.e. Start(t1) >= End(t2) + delay.
@ STARTS_AFTER_START
t1 starts after t2 start, i.e. Start(t1) >= Start(t2) + delay.
@ STARTS_AT_START
t1 starts at t2 start, i.e. Start(t1) == Start(t2) + delay.
Constraint * MakeTemporalDisjunction(IntervalVar *const t1, IntervalVar *const t2, IntVar *const alt)
This constraint implements a temporal disjunction between two interval vars t1 and t2.
Constraint * MakeIntervalVarRelation(IntervalVar *const t, UnaryIntervalRelation r, int64_t d)
This method creates a relation between an interval var and a date.
T * RevAlloc(T *object)
Registers the given object as being reversible.
Collection of objects used to extend the Constraint Solver library.
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)