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));
#define CHECK_EQ(val1, val2)
#define CHECK_GE(val1, val2)
#define CHECK_NE(val1, val2)
#define DCHECK(condition)
The class IntExpr is the base of all integer expressions in constraint programming.
virtual IntVar * Var()=0
Creates a variable from the expression.
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
The class IntVar is a subset of IntExpr.
Interval variables are often used in scheduling.
static const char kTraceOperation[]
static const char kTrace[]
static const char kExpressionArgument[]
virtual void Install()
Registers itself on the solver such that it gets notified of the search and propagation events.
IntExpr * RegisterIntExpr(IntExpr *const expr)
Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
IntVar * RegisterIntVar(IntVar *const var)
Registers a new IntVar and wraps it inside a TraceIntVar if necessary.
bool InstrumentsVariables() const
Returns whether we are tracing variables.
T * RevAlloc(T *object)
Registers the given object as being reversible.
IntervalVar * RegisterIntervalVar(IntervalVar *const var)
Registers a new IntervalVar and wraps it inside a TraceIntervalVar if necessary.
GurobiMPCallbackContext * context
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Collection of objects used to extend the Constraint Solver library.
PropagationMonitor * BuildPrintTrace(Solver *const s)
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
std::vector< Info > delayed_info
ABSL_FLAG(bool, cp_full_trace, false, "Display all trace information, even if the modifiers has no effect")