21 #include "absl/container/flat_hash_map.h" 22 #include "absl/strings/str_format.h" 23 #include "absl/strings/str_join.h" 32 "Display all trace information, even if the modifiers has no effect");
37 class TraceIntVar :
public IntVar {
39 TraceIntVar(Solver*
const solver, IntVar*
const inner)
40 : IntVar(solver), inner_(inner) {
41 if (inner->HasName()) {
42 set_name(inner->name());
47 ~TraceIntVar()
override {}
49 int64_t Min()
const override {
return inner_->Min(); }
51 void SetMin(int64_t m)
override {
52 if (m > inner_->Min()) {
53 solver()->GetPropagationMonitor()->SetMin(inner_, m);
58 int64_t Max()
const override {
return inner_->Max(); }
60 void SetMax(int64_t m)
override {
61 if (m < inner_->Max()) {
62 solver()->GetPropagationMonitor()->SetMax(inner_, m);
67 void Range(int64_t* l, int64_t* u)
override { inner_->Range(l, u); }
69 void SetRange(int64_t l, int64_t u)
override {
70 if (l > inner_->Min() || u < inner_->Max()) {
72 solver()->GetPropagationMonitor()->SetValue(inner_, l);
75 solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
76 inner_->SetRange(l, u);
81 bool Bound()
const override {
return inner_->Bound(); }
83 bool IsVar()
const override {
return true; }
85 IntVar* Var()
override {
return this; }
87 int64_t
Value()
const override {
return inner_->Value(); }
89 void RemoveValue(int64_t v)
override {
90 if (inner_->Contains(v)) {
91 solver()->GetPropagationMonitor()->RemoveValue(inner_, v);
92 inner_->RemoveValue(v);
96 void SetValue(int64_t v)
override {
97 solver()->GetPropagationMonitor()->SetValue(inner_, v);
101 void RemoveInterval(int64_t l, int64_t u)
override {
102 solver()->GetPropagationMonitor()->RemoveInterval(inner_, l, u);
103 inner_->RemoveInterval(l, u);
106 void RemoveValues(
const std::vector<int64_t>& values)
override {
107 solver()->GetPropagationMonitor()->RemoveValues(inner_, values);
108 inner_->RemoveValues(values);
111 void SetValues(
const std::vector<int64_t>& values)
override {
112 solver()->GetPropagationMonitor()->SetValues(inner_, values);
113 inner_->SetValues(values);
116 void WhenRange(Demon* d)
override { inner_->WhenRange(d); }
118 void WhenBound(Demon* d)
override { inner_->WhenBound(d); }
120 void WhenDomain(Demon* d)
override { inner_->WhenDomain(d); }
122 uint64_t Size()
const override {
return inner_->Size(); }
124 bool Contains(int64_t v)
const override {
return inner_->Contains(v); }
126 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
127 return inner_->MakeHoleIterator(reversible);
130 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
131 return inner_->MakeDomainIterator(reversible);
134 int64_t OldMin()
const override {
return inner_->OldMin(); }
136 int64_t OldMax()
const override {
return inner_->OldMax(); }
138 int VarType()
const override {
return TRACE_VAR; }
140 void Accept(ModelVisitor*
const visitor)
const override {
141 IntExpr*
const cast_expr =
142 solver()->CastExpression(const_cast<TraceIntVar*>(
this));
143 if (cast_expr !=
nullptr) {
144 visitor->VisitIntegerVariable(
this, cast_expr);
151 std::string DebugString()
const override {
return inner_->DebugString(); }
153 IntVar* IsEqual(int64_t constant)
override {
154 return inner_->IsEqual(constant);
157 IntVar* IsDifferent(int64_t constant)
override {
158 return inner_->IsDifferent(constant);
161 IntVar* IsGreaterOrEqual(int64_t constant)
override {
162 return inner_->IsGreaterOrEqual(constant);
165 IntVar* IsLessOrEqual(int64_t constant)
override {
166 return inner_->IsLessOrEqual(constant);
170 IntVar*
const inner_;
173 class TraceIntExpr :
public IntExpr {
175 TraceIntExpr(Solver*
const solver, IntExpr*
const inner)
176 : IntExpr(solver), inner_(inner) {
177 CHECK(!inner->IsVar());
178 if (inner->HasName()) {
179 set_name(inner->name());
183 ~TraceIntExpr()
override {}
185 int64_t Min()
const override {
return inner_->Min(); }
187 void SetMin(int64_t m)
override {
188 solver()->GetPropagationMonitor()->SetMin(inner_, m);
192 int64_t Max()
const override {
return inner_->Max(); }
194 void SetMax(int64_t m)
override {
195 solver()->GetPropagationMonitor()->SetMax(inner_, m);
199 void Range(int64_t* l, int64_t* u)
override { inner_->Range(l, u); }
201 void SetRange(int64_t l, int64_t u)
override {
202 if (l > inner_->Min() || u < inner_->Max()) {
203 solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
204 inner_->SetRange(l, u);
208 bool Bound()
const override {
return inner_->Bound(); }
210 bool IsVar()
const override {
215 IntVar* Var()
override {
return solver()->RegisterIntVar(inner_->Var()); }
217 void WhenRange(Demon* d)
override { inner_->WhenRange(d); }
219 void Accept(ModelVisitor*
const visitor)
const override {
226 std::string DebugString()
const override {
return inner_->DebugString(); }
229 IntExpr*
const inner_;
232 class TraceIntervalVar :
public IntervalVar {
234 TraceIntervalVar(Solver*
const solver, IntervalVar*
const inner)
235 : IntervalVar(solver,
""), inner_(inner) {
236 if (inner->HasName()) {
237 set_name(inner->name());
240 ~TraceIntervalVar()
override {}
242 int64_t StartMin()
const override {
return inner_->StartMin(); }
244 int64_t StartMax()
const override {
return inner_->StartMax(); }
246 void SetStartMin(int64_t m)
override {
247 if (inner_->MayBePerformed() && (m > inner_->StartMin())) {
248 solver()->GetPropagationMonitor()->SetStartMin(inner_, m);
249 inner_->SetStartMin(m);
253 void SetStartMax(int64_t m)
override {
254 if (inner_->MayBePerformed() && (m < inner_->StartMax())) {
255 solver()->GetPropagationMonitor()->SetStartMax(inner_, m);
256 inner_->SetStartMax(m);
260 void SetStartRange(int64_t mi, int64_t ma)
override {
261 if (inner_->MayBePerformed() &&
262 (mi > inner_->StartMin() || ma < inner_->StartMax())) {
263 solver()->GetPropagationMonitor()->SetStartRange(inner_, mi, ma);
264 inner_->SetStartRange(mi, ma);
268 int64_t OldStartMin()
const override {
return inner_->OldStartMin(); }
270 int64_t OldStartMax()
const override {
return inner_->OldStartMax(); }
272 void WhenStartRange(Demon*
const d)
override { inner_->WhenStartRange(d); }
274 void WhenStartBound(Demon*
const d)
override { inner_->WhenStartBound(d); }
276 int64_t EndMin()
const override {
return inner_->EndMin(); }
278 int64_t EndMax()
const override {
return inner_->EndMax(); }
280 void SetEndMin(int64_t m)
override {
281 if (inner_->MayBePerformed() && (m > inner_->EndMin())) {
282 solver()->GetPropagationMonitor()->SetEndMin(inner_, m);
283 inner_->SetEndMin(m);
287 void SetEndMax(int64_t m)
override {
288 if (inner_->MayBePerformed() && (m < inner_->EndMax())) {
289 solver()->GetPropagationMonitor()->SetEndMax(inner_, m);
290 inner_->SetEndMax(m);
294 void SetEndRange(int64_t mi, int64_t ma)
override {
295 if (inner_->MayBePerformed() &&
296 (mi > inner_->EndMin() || ma < inner_->EndMax())) {
297 solver()->GetPropagationMonitor()->SetEndRange(inner_, mi, ma);
298 inner_->SetEndRange(mi, ma);
302 int64_t OldEndMin()
const override {
return inner_->OldEndMin(); }
304 int64_t OldEndMax()
const override {
return inner_->OldEndMax(); }
306 void WhenEndRange(Demon*
const d)
override { inner_->WhenEndRange(d); }
308 void WhenEndBound(Demon*
const d)
override { inner_->WhenStartBound(d); }
310 int64_t DurationMin()
const override {
return inner_->DurationMin(); }
312 int64_t DurationMax()
const override {
return inner_->DurationMax(); }
314 void SetDurationMin(int64_t m)
override {
315 if (inner_->MayBePerformed() && (m > inner_->DurationMin())) {
316 solver()->GetPropagationMonitor()->SetDurationMin(inner_, m);
317 inner_->SetDurationMin(m);
321 void SetDurationMax(int64_t m)
override {
322 if (inner_->MayBePerformed() && (m < inner_->DurationMax())) {
323 solver()->GetPropagationMonitor()->SetDurationMax(inner_, m);
324 inner_->SetDurationMax(m);
328 void SetDurationRange(int64_t mi, int64_t ma)
override {
329 if (inner_->MayBePerformed() &&
330 (mi > inner_->DurationMin() || ma < inner_->DurationMax())) {
331 solver()->GetPropagationMonitor()->SetDurationRange(inner_, mi, ma);
332 inner_->SetDurationRange(mi, ma);
336 int64_t OldDurationMin()
const override {
return inner_->OldDurationMin(); }
338 int64_t OldDurationMax()
const override {
return inner_->OldDurationMax(); }
340 void WhenDurationRange(Demon*
const d)
override {
341 inner_->WhenDurationRange(d);
344 void WhenDurationBound(Demon*
const d)
override {
345 inner_->WhenDurationBound(d);
348 bool MustBePerformed()
const override {
return inner_->MustBePerformed(); }
350 bool MayBePerformed()
const override {
return inner_->MayBePerformed(); }
352 void SetPerformed(
bool value)
override {
353 if ((
value && !inner_->MustBePerformed()) ||
354 (!
value && inner_->MayBePerformed())) {
355 solver()->GetPropagationMonitor()->SetPerformed(inner_,
value);
356 inner_->SetPerformed(
value);
360 bool WasPerformedBound()
const override {
361 return inner_->WasPerformedBound();
364 void WhenPerformedBound(Demon*
const d)
override {
365 inner_->WhenPerformedBound(d);
368 IntExpr* StartExpr()
override {
return inner_->StartExpr(); }
369 IntExpr* DurationExpr()
override {
return inner_->DurationExpr(); }
370 IntExpr* EndExpr()
override {
return inner_->EndExpr(); }
371 IntExpr* PerformedExpr()
override {
return inner_->PerformedExpr(); }
372 IntExpr* SafeStartExpr(int64_t unperformed_value)
override {
373 return inner_->SafeStartExpr(unperformed_value);
375 IntExpr* SafeDurationExpr(int64_t unperformed_value)
override {
376 return inner_->SafeDurationExpr(unperformed_value);
378 IntExpr* SafeEndExpr(int64_t unperformed_value)
override {
379 return inner_->SafeEndExpr(unperformed_value);
382 void Accept(ModelVisitor*
const visitor)
const override {
383 inner_->Accept(visitor);
386 std::string DebugString()
const override {
return inner_->DebugString(); }
389 IntervalVar*
const inner_;
394 class PrintTrace :
public PropagationMonitor {
412 explicit Context(
int start_indent)
443 explicit PrintTrace(Solver*
const s) : PropagationMonitor(s) {
444 contexes_.push(Context());
447 ~PrintTrace()
override {}
451 void BeginInitialPropagation()
override {
453 DisplaySearch(
"Root Node Propagation");
456 void EndInitialPropagation()
override {
458 DisplaySearch(
"Starting Tree Search");
461 void BeginNextDecision(DecisionBuilder*
const b)
override {
462 DisplaySearch(absl::StrFormat(
"DecisionBuilder(%s)",
b->DebugString()));
464 contexes_.top().in_decision_builder =
true;
468 void EndNextDecision(DecisionBuilder*
const b, Decision*
const d)
override {
469 contexes_.top().in_decision_builder =
false;
473 void BeginFail()
override {
474 contexes_.top().Clear();
475 while (!contexes_.top().TopLevel()) {
480 absl::StrFormat(
"Failure at depth %d", solver()->SearchDepth()));
483 bool AtSolution()
override {
485 absl::StrFormat(
"Solution found at depth %d", solver()->SearchDepth()));
489 void ApplyDecision(Decision*
const decision)
override {
491 absl::StrFormat(
"ApplyDecision(%s)", decision->DebugString()));
493 contexes_.top().in_decision =
true;
496 void RefuteDecision(Decision*
const decision)
override {
497 if (contexes_.top().in_objective) {
499 contexes_.top().in_objective =
false;
502 absl::StrFormat(
"RefuteDecision(%s)", decision->DebugString()));
504 contexes_.top().in_decision =
true;
507 void AfterDecision(Decision*
const decision,
bool direction)
override {
509 contexes_.top().in_decision =
false;
512 void EnterSearch()
override {
513 if (solver()->SolveDepth() == 0) {
515 contexes_.top().Clear();
517 PrintDelayedString();
520 DisplaySearch(
"Enter Search");
523 void ExitSearch()
override {
524 DisplaySearch(
"Exit Search");
525 CHECK(contexes_.top().TopLevel());
526 if (solver()->SolveDepth() > 1) {
531 void RestartSearch()
override {
CHECK(contexes_.top().TopLevel()); }
535 void BeginConstraintInitialPropagation(
536 Constraint*
const constraint)
override {
538 absl::StrFormat(
"Constraint(%s)", constraint->DebugString()));
539 contexes_.top().in_constraint =
true;
542 void EndConstraintInitialPropagation(Constraint*
const constraint)
override {
544 contexes_.top().in_constraint =
false;
547 void BeginNestedConstraintInitialPropagation(
548 Constraint*
const parent, Constraint*
const nested)
override {
549 PushDelayedInfo(absl::StrFormat(
"Constraint(%s)", nested->DebugString()));
550 contexes_.top().in_constraint =
true;
552 void EndNestedConstraintInitialPropagation(Constraint*
const,
553 Constraint*
const)
override {
555 contexes_.top().in_constraint =
false;
560 void BeginDemonRun(Demon*
const demon)
override {
562 contexes_.top().in_demon =
true;
563 PushDelayedInfo(absl::StrFormat(
"Demon(%s)", demon->DebugString()));
567 void EndDemonRun(Demon*
const demon)
override {
569 contexes_.top().in_demon =
false;
574 void StartProcessingIntegerVariable(IntVar*
const var)
override {
575 PushDelayedInfo(absl::StrFormat(
"StartProcessing(%s)",
var->DebugString()));
578 void EndProcessingIntegerVariable(IntVar*
const var)
override {
582 void PushContext(
const std::string&
context)
override {
586 void PopContext()
override { PopDelayedInfo(); }
590 void SetMin(IntExpr*
const expr, int64_t new_min)
override {
592 absl::StrFormat(
"SetMin(%s, %d)", expr->DebugString(), new_min));
595 void SetMax(IntExpr*
const expr, int64_t new_max)
override {
597 absl::StrFormat(
"SetMax(%s, %d)", expr->DebugString(), new_max));
600 void SetRange(IntExpr*
const expr, int64_t new_min,
601 int64_t new_max)
override {
602 DisplayModification(absl::StrFormat(
"SetRange(%s, [%d .. %d])",
603 expr->DebugString(), new_min, new_max));
608 void SetMin(IntVar*
const var, int64_t new_min)
override {
610 absl::StrFormat(
"SetMin(%s, %d)",
var->DebugString(), new_min));
613 void SetMax(IntVar*
const var, int64_t new_max)
override {
615 absl::StrFormat(
"SetMax(%s, %d)",
var->DebugString(), new_max));
618 void SetRange(IntVar*
const var, int64_t new_min, int64_t new_max)
override {
619 DisplayModification(absl::StrFormat(
"SetRange(%s, [%d .. %d])",
620 var->DebugString(), new_min, new_max));
623 void RemoveValue(IntVar*
const var, int64_t
value)
override {
625 absl::StrFormat(
"RemoveValue(%s, %d)",
var->DebugString(),
value));
628 void SetValue(IntVar*
const var, int64_t
value)
override {
630 absl::StrFormat(
"SetValue(%s, %d)",
var->DebugString(),
value));
633 void RemoveInterval(IntVar*
const var, int64_t imin, int64_t imax)
override {
634 DisplayModification(absl::StrFormat(
"RemoveInterval(%s, [%d .. %d])",
635 var->DebugString(), imin, imax));
638 void SetValues(IntVar*
const var,
639 const std::vector<int64_t>& values)
override {
640 DisplayModification(absl::StrFormat(
"SetValues(%s, %s)",
var->DebugString(),
641 absl::StrJoin(values,
", ")));
644 void RemoveValues(IntVar*
const var,
645 const std::vector<int64_t>& values)
override {
646 DisplayModification(absl::StrFormat(
"RemoveValues(%s, %s)",
648 absl::StrJoin(values,
", ")));
653 void SetStartMin(IntervalVar*
const var, int64_t new_min)
override {
655 absl::StrFormat(
"SetStartMin(%s, %d)",
var->DebugString(), new_min));
658 void SetStartMax(IntervalVar*
const var, int64_t new_max)
override {
660 absl::StrFormat(
"SetStartMax(%s, %d)",
var->DebugString(), new_max));
663 void SetStartRange(IntervalVar*
const var, int64_t new_min,
664 int64_t new_max)
override {
665 DisplayModification(absl::StrFormat(
"SetStartRange(%s, [%d .. %d])",
666 var->DebugString(), new_min, new_max));
669 void SetEndMin(IntervalVar*
const var, int64_t new_min)
override {
671 absl::StrFormat(
"SetEndMin(%s, %d)",
var->DebugString(), new_min));
674 void SetEndMax(IntervalVar*
const var, int64_t new_max)
override {
676 absl::StrFormat(
"SetEndMax(%s, %d)",
var->DebugString(), new_max));
679 void SetEndRange(IntervalVar*
const var, int64_t new_min,
680 int64_t new_max)
override {
681 DisplayModification(absl::StrFormat(
"SetEndRange(%s, [%d .. %d])",
682 var->DebugString(), new_min, new_max));
685 void SetDurationMin(IntervalVar*
const var, int64_t new_min)
override {
687 absl::StrFormat(
"SetDurationMin(%s, %d)",
var->DebugString(), new_min));
690 void SetDurationMax(IntervalVar*
const var, int64_t new_max)
override {
692 absl::StrFormat(
"SetDurationMax(%s, %d)",
var->DebugString(), new_max));
695 void SetDurationRange(IntervalVar*
const var, int64_t new_min,
696 int64_t new_max)
override {
697 DisplayModification(absl::StrFormat(
"SetDurationRange(%s, [%d .. %d])",
698 var->DebugString(), new_min, new_max));
701 void SetPerformed(IntervalVar*
const var,
bool value)
override {
703 absl::StrFormat(
"SetPerformed(%s, %d)",
var->DebugString(),
value));
706 void RankFirst(SequenceVar*
const var,
int index)
override {
708 absl::StrFormat(
"RankFirst(%s, %d)",
var->DebugString(),
index));
711 void RankNotFirst(SequenceVar*
const var,
int index)
override {
713 absl::StrFormat(
"RankNotFirst(%s, %d)",
var->DebugString(),
index));
716 void RankLast(SequenceVar*
const var,
int index)
override {
718 absl::StrFormat(
"RankLast(%s, %d)",
var->DebugString(),
index));
721 void RankNotLast(SequenceVar*
const var,
int index)
override {
723 absl::StrFormat(
"RankNotLast(%s, %d)",
var->DebugString(),
index));
726 void RankSequence(SequenceVar*
const var,
const std::vector<int>& rank_first,
727 const std::vector<int>& rank_last,
728 const std::vector<int>& unperformed)
override {
729 DisplayModification(absl::StrFormat(
730 "RankSequence(%s, forward [%s], backward[%s], unperformed[%s])",
731 var->DebugString(), absl::StrJoin(rank_first,
", "),
732 absl::StrJoin(rank_last,
", "), absl::StrJoin(unperformed,
", ")));
735 void Install()
override {
737 if (solver()->SolveDepth() <= 1) {
738 solver()->AddPropagationMonitor(
this);
742 std::string DebugString()
const override {
return "PrintTrace"; }
745 void PushDelayedInfo(
const std::string& delayed) {
746 if (absl::GetFlag(FLAGS_cp_full_trace)) {
747 LOG(
INFO) << Indent() << delayed <<
" {";
750 contexes_.top().delayed_info.push_back(Info(delayed));
754 void PopDelayedInfo() {
755 if (absl::GetFlag(FLAGS_cp_full_trace)) {
759 CHECK(!contexes_.top().delayed_info.empty());
760 if (contexes_.top().delayed_info.back().displayed &&
761 !contexes_.top().TopLevel()) {
765 contexes_.top().delayed_info.pop_back();
770 void CheckNoDelayed() {
CHECK(contexes_.top().delayed_info.empty()); }
772 void PrintDelayedString() {
773 const std::vector<Info>& infos = contexes_.top().delayed_info;
774 for (
int i = 0; i < infos.size(); ++i) {
775 const Info& info = infos[i];
776 if (!info.displayed) {
777 LOG(
INFO) << Indent() << info.message <<
" {";
780 contexes_.top().delayed_info[i].displayed =
true;
785 void DisplayModification(
const std::string& to_print) {
786 if (absl::GetFlag(FLAGS_cp_full_trace)) {
787 LOG(
INFO) << Indent() << to_print;
789 PrintDelayedString();
790 if (contexes_.top().in_demon || contexes_.top().in_constraint ||
791 contexes_.top().in_decision_builder || contexes_.top().in_decision ||
792 contexes_.top().in_objective) {
794 LOG(
INFO) << Indent() << to_print;
805 CHECK(contexes_.top().TopLevel());
806 DisplaySearch(absl::StrFormat(
"Objective -> %s", to_print));
808 contexes_.top().in_objective =
true;
813 void DisplaySearch(
const std::string& to_print) {
814 const int solve_depth = solver()->SolveDepth();
815 if (solve_depth <= 1) {
816 LOG(
INFO) << Indent() <<
"######## Top Level Search: " << to_print;
818 LOG(
INFO) << Indent() <<
"######## Nested Search(" << solve_depth - 1
819 <<
"): " << to_print;
823 std::string Indent() {
824 CHECK_GE(contexes_.top().indent, 0);
825 std::string output =
" @ ";
826 for (
int i = 0; i < contexes_.top().indent; ++i) {
832 void IncreaseIndent() { contexes_.top().indent++; }
834 void DecreaseIndent() {
835 if (contexes_.top().indent > 0) {
836 contexes_.top().indent--;
840 void PushNestedContext() {
845 std::stack<Context> contexes_;
854 return RevAlloc(
new TraceIntExpr(
this, expr));
879 return s->
RevAlloc(
new PrintTrace(s));
static const char kTrace[]
IntervalVar * RegisterIntervalVar(IntervalVar *const var)
Registers a new IntervalVar and wraps it inside a TraceIntervalVar if necessary.
#define CHECK_GE(val1, val2)
IntVar * RegisterIntVar(IntVar *const var)
Registers a new IntVar and wraps it inside a TraceIntVar if necessary.
PropagationMonitor * BuildPrintTrace(Solver *const s)
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
bool InstrumentsVariables() const
Returns whether we are tracing variables.
IntExpr * RegisterIntExpr(IntExpr *const expr)
Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary.
std::vector< Info > delayed_info
std::function< int64_t(const Model &)> Value(IntegerVariable v)
virtual IntVar * Var()=0
Creates a variable from the expression.
Interval variables are often used in scheduling.
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
ABSL_FLAG(bool, cp_full_trace, false, "Display all trace information, even if the modifiers has no effect")
virtual void Install()
Registers itself on the solver such that it gets notified of the search and propagation events.
The class IntVar is a subset of IntExpr.
The class IntExpr is the base of all integer expressions in constraint programming.
#define CHECK_EQ(val1, val2)
T * RevAlloc(T *object)
Registers the given object as being reversible.
#define DCHECK(condition)
Collection of objects used to extend the Constraint Solver library.
static const char kExpressionArgument[]
GurobiMPCallbackContext * context
static const char kTraceOperation[]
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
#define CHECK_NE(val1, val2)