Google OR-Tools: ortools/constraint_solver/trace.cc Source File
22#include "absl/flags/flag.h"
24#include "absl/strings/str_format.h"
25#include "absl/strings/str_join.h"
31 "Display all trace information, even if the modifiers has no effect");
36class TraceIntVar : public IntVar {
38 TraceIntVar(Solver* const solver, IntVar* const inner)
39 : IntVar(solver), inner_(inner) {
43 CHECK_NE(inner->VarType(), TRACE_VAR);
48 int64_t Min() const override { return inner_->Min(); }
50 void SetMin(int64_t m) override {
52 solver()->GetPropagationMonitor()->SetMin(inner_, m);
57 int64_t Max() const override { return inner_->Max(); }
59 void SetMax(int64_t m) override {
61 solver()->GetPropagationMonitor()->SetMax(inner_, m);
66 void Range(int64_t* l, int64_t* u) override { inner_->Range(l, u); }
68 void SetRange(int64_t l, int64_t u) override {
69 if (l > inner_->Min() || u < inner_->Max()) {
71 solver()->GetPropagationMonitor()->SetValue(inner_, l);
74 solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
80 bool Bound() const override { return inner_->Bound(); }
82 bool IsVar() const override { return true; }
84 IntVar* Var() override { return this; }
86 int64_t Value() const override { return inner_->Value(); }
88 void RemoveValue(int64_t v) override {
90 solver()->GetPropagationMonitor()->RemoveValue(inner_, v);
95 void SetValue(int64_t v) override {
96 solver()->GetPropagationMonitor()->SetValue(inner_, v);
100 void RemoveInterval(int64_t l, int64_t u) override {
101 solver()->GetPropagationMonitor()->RemoveInterval(inner_, l, u);
102 inner_->RemoveInterval(l, u);
105 void RemoveValues(const std::vector<int64_t>& values) override {
106 solver()->GetPropagationMonitor()->RemoveValues(inner_, values);
107 inner_->RemoveValues(values);
110 void SetValues(const std::vector<int64_t>& values) override {
111 solver()->GetPropagationMonitor()->SetValues(inner_, values);
112 inner_->SetValues(values);
115 void WhenRange(Demon* d) override { inner_->WhenRange(d); }
117 void WhenBound(Demon* d) override { inner_->WhenBound(d); }
119 void WhenDomain(Demon* d) override { inner_->WhenDomain(d); }
121 uint64_t Size() const override { return inner_->Size(); }
123 bool Contains(int64_t v) const override { return inner_->Contains(v); }
125 IntVarIterator* MakeHoleIterator(bool reversible) const override {
126 return inner_->MakeHoleIterator(reversible);
129 IntVarIterator* MakeDomainIterator(bool reversible) const override {
130 return inner_->MakeDomainIterator(reversible);
133 int64_t OldMin() const override { return inner_->OldMin(); }
135 int64_t OldMax() const override { return inner_->OldMax(); }
137 int VarType() const override { return TRACE_VAR; }
139 void Accept(ModelVisitor* const visitor) const override {
140 IntExpr* const cast_expr =
141 solver()->CastExpression(const_cast<TraceIntVar*>(this));
142 if (cast_expr != nullptr) {
143 visitor->VisitIntegerVariable(this, cast_expr);
150 std::string DebugString() const override { return inner_->DebugString(); }
152 IntVar* IsEqual(int64_t constant) override {
153 return inner_->IsEqual(constant);
156 IntVar* IsDifferent(int64_t constant) override {
157 return inner_->IsDifferent(constant);
160 IntVar* IsGreaterOrEqual(int64_t constant) override {
161 return inner_->IsGreaterOrEqual(constant);
164 IntVar* IsLessOrEqual(int64_t constant) override {
165 return inner_->IsLessOrEqual(constant);
172class TraceIntExpr : public IntExpr {
174 TraceIntExpr(Solver* const solver, IntExpr* const inner)
175 : IntExpr(solver), inner_(inner) {
182 ~TraceIntExpr() override {}
184 int64_t Min() const override { return inner_->Min(); }
186 void SetMin(int64_t m) override {
187 solver()->GetPropagationMonitor()->SetMin(inner_, m);
191 int64_t Max() const override { return inner_->Max(); }
193 void SetMax(int64_t m) override {
194 solver()->GetPropagationMonitor()->SetMax(inner_, m);
198 void Range(int64_t* l, int64_t* u) override { inner_->Range(l, u); }
200 void SetRange(int64_t l, int64_t u) override {
201 if (l > inner_->Min() || u < inner_->Max()) {
202 solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
207 bool Bound() const override { return inner_->Bound(); }
209 bool IsVar() const override {
214 IntVar* Var() override { return solver()->RegisterIntVar(inner_->Var()); }
216 void WhenRange(Demon* d) override { inner_->WhenRange(d); }
218 void Accept(ModelVisitor* const visitor) const override {
225 std::string DebugString() const override { return inner_->DebugString(); }
231class TraceIntervalVar : public IntervalVar {
233 TraceIntervalVar(Solver* const solver, IntervalVar* const inner)
234 : IntervalVar(solver, ""), inner_(inner) {
239 ~TraceIntervalVar() override {}
241 int64_t StartMin() const override { return inner_->StartMin(); }
243 int64_t StartMax() const override { return inner_->StartMax(); }
245 void SetStartMin(int64_t m) override {
246 if (inner_->MayBePerformed() && (m > inner_->StartMin())) {
247 solver()->GetPropagationMonitor()->SetStartMin(inner_, m);
252 void SetStartMax(int64_t m) override {
253 if (inner_->MayBePerformed() && (m < inner_->StartMax())) {
254 solver()->GetPropagationMonitor()->SetStartMax(inner_, m);
259 void SetStartRange(int64_t mi, int64_t ma) override {
260 if (inner_->MayBePerformed() &&
261 (mi > inner_->StartMin() || ma < inner_->StartMax())) {
262 solver()->GetPropagationMonitor()->SetStartRange(inner_, mi, ma);
263 inner_->SetStartRange(mi, ma);
267 int64_t OldStartMin() const override { return inner_->OldStartMin(); }
269 int64_t OldStartMax() const override { return inner_->OldStartMax(); }
271 void WhenStartRange(Demon* const d) override { inner_->WhenStartRange(d); }
273 void WhenStartBound(Demon* const d) override { inner_->WhenStartBound(d); }
275 int64_t EndMin() const override { return inner_->EndMin(); }
277 int64_t EndMax() const override { return inner_->EndMax(); }
279 void SetEndMin(int64_t m) override {
280 if (inner_->MayBePerformed() && (m > inner_->EndMin())) {
281 solver()->GetPropagationMonitor()->SetEndMin(inner_, m);
286 void SetEndMax(int64_t m) override {
287 if (inner_->MayBePerformed() && (m < inner_->EndMax())) {
288 solver()->GetPropagationMonitor()->SetEndMax(inner_, m);
293 void SetEndRange(int64_t mi, int64_t ma) override {
294 if (inner_->MayBePerformed() &&
295 (mi > inner_->EndMin() || ma < inner_->EndMax())) {
296 solver()->GetPropagationMonitor()->SetEndRange(inner_, mi, ma);
297 inner_->SetEndRange(mi, ma);
301 int64_t OldEndMin() const override { return inner_->OldEndMin(); }
303 int64_t OldEndMax() const override { return inner_->OldEndMax(); }
305 void WhenEndRange(Demon* const d) override { inner_->WhenEndRange(d); }
307 void WhenEndBound(Demon* const d) override { inner_->WhenStartBound(d); }
309 int64_t DurationMin() const override { return inner_->DurationMin(); }
311 int64_t DurationMax() const override { return inner_->DurationMax(); }
313 void SetDurationMin(int64_t m) override {
314 if (inner_->MayBePerformed() && (m > inner_->DurationMin())) {
315 solver()->GetPropagationMonitor()->SetDurationMin(inner_, m);
316 inner_->SetDurationMin(m);
320 void SetDurationMax(int64_t m) override {
321 if (inner_->MayBePerformed() && (m < inner_->DurationMax())) {
322 solver()->GetPropagationMonitor()->SetDurationMax(inner_, m);
323 inner_->SetDurationMax(m);
327 void SetDurationRange(int64_t mi, int64_t ma) override {
328 if (inner_->MayBePerformed() &&
329 (mi > inner_->DurationMin() || ma < inner_->DurationMax())) {
330 solver()->GetPropagationMonitor()->SetDurationRange(inner_, mi, ma);
331 inner_->SetDurationRange(mi, ma);
335 int64_t OldDurationMin() const override { return inner_->OldDurationMin(); }
337 int64_t OldDurationMax() const override { return inner_->OldDurationMax(); }
339 void WhenDurationRange(Demon* const d) override {
340 inner_->WhenDurationRange(d);
343 void WhenDurationBound(Demon* const d) override {
344 inner_->WhenDurationBound(d);
347 bool MustBePerformed() const override { return inner_->MustBePerformed(); }
349 bool MayBePerformed() const override { return inner_->MayBePerformed(); }
351 void SetPerformed(bool value) override {
352 if ((value && !inner_->MustBePerformed()) ||
353 (!value && inner_->MayBePerformed())) {
354 solver()->GetPropagationMonitor()->SetPerformed(inner_, value);
355 inner_->SetPerformed(value);
359 bool WasPerformedBound() const override {
360 return inner_->WasPerformedBound();
363 void WhenPerformedBound(Demon* const d) override {
364 inner_->WhenPerformedBound(d);
367 IntExpr* StartExpr() override { return inner_->StartExpr(); }
368 IntExpr* DurationExpr() override { return inner_->DurationExpr(); }
369 IntExpr* EndExpr() override { return inner_->EndExpr(); }
370 IntExpr* PerformedExpr() override { return inner_->PerformedExpr(); }
371 IntExpr* SafeStartExpr(int64_t unperformed_value) override {
372 return inner_->SafeStartExpr(unperformed_value);
374 IntExpr* SafeDurationExpr(int64_t unperformed_value) override {
375 return inner_->SafeDurationExpr(unperformed_value);
377 IntExpr* SafeEndExpr(int64_t unperformed_value) override {
378 return inner_->SafeEndExpr(unperformed_value);
381 void Accept(ModelVisitor* const visitor) const override {
385 std::string DebugString() const override { return inner_->DebugString(); }
388 IntervalVar* const inner_;
396 explicit Info(const std::string& m) : message(m), displayed(false) {}
406 in_constraint(false),
407 in_decision_builder(false),
408 in_decision(false),
409 in_objective(false) {}
411 explicit Context(int start_indent)
412 : initial_indent(start_indent),
415 in_constraint(false),
416 in_decision_builder(false),
417 in_decision(false),
418 in_objective(false) {}
420 bool TopLevel() const { return initial_indent == indent; }
426 in_decision_builder = false;
439 std::vector<Info> delayed_info;
442 explicit PrintTrace(Solver* const s) : PropagationMonitor(s) {
443 contexes_.push(Context());
450 void BeginInitialPropagation() override {
452 DisplaySearch("Root Node Propagation");
455 void EndInitialPropagation() override {
457 DisplaySearch("Starting Tree Search");
460 void BeginNextDecision(DecisionBuilder* const b) override {
461 DisplaySearch(absl::StrFormat("DecisionBuilder(%s)", b->DebugString()));
463 contexes_.top().in_decision_builder = true;
467 void EndNextDecision(DecisionBuilder* const b, Decision* const d) override {
468 contexes_.top().in_decision_builder = false;
472 void BeginFail() override {
474 while (!contexes_.top().TopLevel()) {
476 LOG(INFO) << Indent() << "}";
479 absl::StrFormat("Failure at depth %d", solver()->SearchDepth()));
482 bool AtSolution() override {
484 absl::StrFormat("Solution found at depth %d", solver()->SearchDepth()));
488 void ApplyDecision(Decision* const decision) override {
490 absl::StrFormat("ApplyDecision(%s)", decision->DebugString()));
492 contexes_.top().in_decision = true;
495 void RefuteDecision(Decision* const decision) override {
496 if (contexes_.top().in_objective) {
498 contexes_.top().in_objective = false;
501 absl::StrFormat("RefuteDecision(%s)", decision->DebugString()));
503 contexes_.top().in_decision = true;
506 void AfterDecision(Decision* const decision, bool direction) override {
508 contexes_.top().in_decision = false;
511 void EnterSearch() override {
512 if (solver()->SolveDepth() == 0) {
513 CHECK_EQ(1, contexes_.size());
519 DisplaySearch("Enter Search");
522 void ExitSearch() override {
523 DisplaySearch("Exit Search");
524 CHECK(contexes_.top().TopLevel());
525 if (solver()->SolveDepth() > 1) {
530 void RestartSearch() override { CHECK(contexes_.top().TopLevel()); }
534 void BeginConstraintInitialPropagation(
535 Constraint* const constraint) override {
537 absl::StrFormat("Constraint(%s)", constraint->DebugString()));
538 contexes_.top().in_constraint = true;
541 void EndConstraintInitialPropagation(Constraint* const constraint) override {
543 contexes_.top().in_constraint = false;
546 void BeginNestedConstraintInitialPropagation(
547 Constraint* const parent, Constraint* const nested) override {
548 PushDelayedInfo(absl::StrFormat("Constraint(%s)", nested->DebugString()));
549 contexes_.top().in_constraint = true;
551 void EndNestedConstraintInitialPropagation(Constraint* const,
552 Constraint* const) override {
554 contexes_.top().in_constraint = false;
557 void RegisterDemon(Demon* const demon) override {}
559 void BeginDemonRun(Demon* const demon) override {
561 contexes_.top().in_demon = true;
562 PushDelayedInfo(absl::StrFormat("Demon(%s)", demon->DebugString()));
566 void EndDemonRun(Demon* const demon) override {
568 contexes_.top().in_demon = false;
573 void StartProcessingIntegerVariable(IntVar* const var) override {
574 PushDelayedInfo(absl::StrFormat("StartProcessing(%s)", var->DebugString()));
577 void EndProcessingIntegerVariable(IntVar* const var) override {
581 void PushContext(const std::string& context) override {
585 void PopContext() override { PopDelayedInfo(); }
589 void SetMin(IntExpr* const expr, int64_t new_min) override {
591 absl::StrFormat("SetMin(%s, %d)", expr->DebugString(), new_min));
594 void SetMax(IntExpr* const expr, int64_t new_max) override {
596 absl::StrFormat("SetMax(%s, %d)", expr->DebugString(), new_max));
599 void SetRange(IntExpr* const expr, int64_t new_min,
600 int64_t new_max) override {
601 DisplayModification(absl::StrFormat("SetRange(%s, [%d .. %d])",
602 expr->DebugString(), new_min, new_max));
607 void SetMin(IntVar* const var, int64_t new_min) override {
609 absl::StrFormat("SetMin(%s, %d)", var->DebugString(), new_min));
612 void SetMax(IntVar* const var, int64_t new_max) override {
614 absl::StrFormat("SetMax(%s, %d)", var->DebugString(), new_max));
617 void SetRange(IntVar* const var, int64_t new_min, int64_t new_max) override {
618 DisplayModification(absl::StrFormat("SetRange(%s, [%d .. %d])",
619 var->DebugString(), new_min, new_max));
622 void RemoveValue(IntVar* const var, int64_t value) override {
624 absl::StrFormat("RemoveValue(%s, %d)", var->DebugString(), value));
627 void SetValue(IntVar* const var, int64_t value) override {
629 absl::StrFormat("SetValue(%s, %d)", var->DebugString(), value));
632 void RemoveInterval(IntVar* const var, int64_t imin, int64_t imax) override {
633 DisplayModification(absl::StrFormat("RemoveInterval(%s, [%d .. %d])",
634 var->DebugString(), imin, imax));
637 void SetValues(IntVar* const var,
638 const std::vector<int64_t>& values) override {
639 DisplayModification(absl::StrFormat("SetValues(%s, %s)", var->DebugString(),
640 absl::StrJoin(values, ", ")));
643 void RemoveValues(IntVar* const var,
644 const std::vector<int64_t>& values) override {
645 DisplayModification(absl::StrFormat("RemoveValues(%s, %s)",
647 absl::StrJoin(values, ", ")));
652 void SetStartMin(IntervalVar* const var, int64_t new_min) override {
654 absl::StrFormat("SetStartMin(%s, %d)", var->DebugString(), new_min));
657 void SetStartMax(IntervalVar* const var, int64_t new_max) override {
659 absl::StrFormat("SetStartMax(%s, %d)", var->DebugString(), new_max));
662 void SetStartRange(IntervalVar* const var, int64_t new_min,
663 int64_t new_max) override {
664 DisplayModification(absl::StrFormat("SetStartRange(%s, [%d .. %d])",
665 var->DebugString(), new_min, new_max));
668 void SetEndMin(IntervalVar* const var, int64_t new_min) override {
670 absl::StrFormat("SetEndMin(%s, %d)", var->DebugString(), new_min));
673 void SetEndMax(IntervalVar* const var, int64_t new_max) override {
675 absl::StrFormat("SetEndMax(%s, %d)", var->DebugString(), new_max));
678 void SetEndRange(IntervalVar* const var, int64_t new_min,
679 int64_t new_max) override {
680 DisplayModification(absl::StrFormat("SetEndRange(%s, [%d .. %d])",
681 var->DebugString(), new_min, new_max));
684 void SetDurationMin(IntervalVar* const var, int64_t new_min) override {
686 absl::StrFormat("SetDurationMin(%s, %d)", var->DebugString(), new_min));
689 void SetDurationMax(IntervalVar* const var, int64_t new_max) override {
691 absl::StrFormat("SetDurationMax(%s, %d)", var->DebugString(), new_max));
694 void SetDurationRange(IntervalVar* const var, int64_t new_min,
695 int64_t new_max) override {
696 DisplayModification(absl::StrFormat("SetDurationRange(%s, [%d .. %d])",
697 var->DebugString(), new_min, new_max));
700 void SetPerformed(IntervalVar* const var, bool value) override {
702 absl::StrFormat("SetPerformed(%s, %d)", var->DebugString(), value));
705 void RankFirst(SequenceVar* const var, int index) override {
707 absl::StrFormat("RankFirst(%s, %d)", var->DebugString(), index));
710 void RankNotFirst(SequenceVar* const var, int index) override {
712 absl::StrFormat("RankNotFirst(%s, %d)", var->DebugString(), index));
715 void RankLast(SequenceVar* const var, int index) override {
717 absl::StrFormat("RankLast(%s, %d)", var->DebugString(), index));
720 void RankNotLast(SequenceVar* const var, int index) override {
722 absl::StrFormat("RankNotLast(%s, %d)", var->DebugString(), index));
725 void RankSequence(SequenceVar* const var, const std::vector<int>& rank_first,
726 const std::vector<int>& rank_last,
727 const std::vector<int>& unperformed) override {
728 DisplayModification(absl::StrFormat(
729 "RankSequence(%s, forward [%s], backward[%s], unperformed[%s])",
730 var->DebugString(), absl::StrJoin(rank_first, ", "),
731 absl::StrJoin(rank_last, ", "), absl::StrJoin(unperformed, ", ")));
736 if (solver()->SolveDepth() <= 1) {
737 solver()->AddPropagationMonitor(this);
741 std::string DebugString() const override { return "PrintTrace"; }
744 void PushDelayedInfo(const std::string& delayed) {
745 if (absl::GetFlag(FLAGS_cp_full_trace)) {
746 LOG(INFO) << Indent() << delayed << " {";
749 contexes_.top().delayed_info.push_back(Info(delayed));
754 if (absl::GetFlag(FLAGS_cp_full_trace)) {
756 LOG(INFO) << Indent() << "}";
758 CHECK(!contexes_.top().delayed_info.empty());
759 if (contexes_.top().delayed_info.back().displayed &&
760 !contexes_.top().TopLevel()) {
762 LOG(INFO) << Indent() << "}";
764 contexes_.top().delayed_info.pop_back();
769 void CheckNoDelayed() { CHECK(contexes_.top().delayed_info.empty()); }
771 void PrintDelayedString() {
772 const std::vector<Info>& infos = contexes_.top().delayed_info;
773 for (int i = 0; i < infos.size(); ++i) {
774 const Info& info = infos[i];
776 LOG(INFO) << Indent() << info.message << " {";
779 contexes_.top().delayed_info[i].displayed = true;
784 void DisplayModification(const std::string& to_print) {
785 if (absl::GetFlag(FLAGS_cp_full_trace)) {
786 LOG(INFO) << Indent() << to_print;
789 if (contexes_.top().in_demon || contexes_.top().in_constraint ||
790 contexes_.top().in_decision_builder || contexes_.top().in_decision ||
791 contexes_.top().in_objective) {
793 LOG(INFO) << Indent() << to_print;
804 CHECK(contexes_.top().TopLevel());
805 DisplaySearch(absl::StrFormat("Objective -> %s", to_print));
807 contexes_.top().in_objective = true;
812 void DisplaySearch(const std::string& to_print) {
813 const int solve_depth = solver()->SolveDepth();
815 LOG(INFO) << Indent() << "######## Top Level Search: " << to_print;
817 LOG(INFO) << Indent() << "######## Nested Search(" << solve_depth - 1
823 CHECK_GE(contexes_.top().indent, 0);
824 std::string output = " @ ";
825 for (int i = 0; i < contexes_.top().indent; ++i) {
831 void IncreaseIndent() { contexes_.top().indent++; }
834 if (contexes_.top().indent > 0) {
839 void PushNestedContext() {
840 const int initial_indent = contexes_.top().indent;
841 contexes_.push(Context(initial_indent));
844 std::stack<Context> contexes_;
878 return s->RevAlloc(new PrintTrace(s));
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
virtual IntVar * Var()=0
Creates a variable from the expression.
virtual int VarType() const
static const char kTraceOperation[]
static const char kExpressionArgument[]
static const char kTrace[]
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
IntVar * RegisterIntVar(IntVar *var)
Registers a new IntVar and wraps it inside a TraceIntVar if necessary.
Definition trace.cc:860
IntExpr * RegisterIntExpr(IntExpr *expr)
Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary.
Definition trace.cc:848
IntervalVar * RegisterIntervalVar(IntervalVar *var)
Definition trace.cc:869
bool InstrumentsVariables() const
Returns whether we are tracing variables.
For infeasible and unbounded see Not checked if options check_solutions_if_inf_or_unbounded and the If options first_solution_only is false
std::pair< double, double > Range
std::function< int64_t(const Model &)> Value(IntegerVariable v)
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
PropagationMonitor * BuildPrintTrace(Solver *s)
Definition trace.cc:877
std::string DebugString() const
ABSL_FLAG(bool, cp_full_trace, false, "Display all trace information, even if the modifiers has no effect")