OR-Tools  8.0
trace.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include <algorithm>
15 #include <cmath>
16 #include <stack>
17 #include <string>
18 #include <utility>
19 
20 #include "absl/container/flat_hash_map.h"
21 #include "absl/strings/str_format.h"
22 #include "absl/strings/str_join.h"
25 #include "ortools/base/logging.h"
26 #include "ortools/base/map_util.h"
29 
31  cp_full_trace, false,
32  "Display all trace information, even if the modifiers has no effect");
33 
34 namespace operations_research {
35 namespace {
36 // ---------- Code Instrumentation ----------
37 class TraceIntVar : public IntVar {
38  public:
39  TraceIntVar(Solver* const solver, IntVar* const inner)
40  : IntVar(solver), inner_(inner) {
41  if (inner->HasName()) {
42  set_name(inner->name());
43  }
44  CHECK_NE(inner->VarType(), TRACE_VAR);
45  }
46 
47  ~TraceIntVar() override {}
48 
49  int64 Min() const override { return inner_->Min(); }
50 
51  void SetMin(int64 m) override {
52  if (m > inner_->Min()) {
53  solver()->GetPropagationMonitor()->SetMin(inner_, m);
54  inner_->SetMin(m);
55  }
56  }
57 
58  int64 Max() const override { return inner_->Max(); }
59 
60  void SetMax(int64 m) override {
61  if (m < inner_->Max()) {
62  solver()->GetPropagationMonitor()->SetMax(inner_, m);
63  inner_->SetMax(m);
64  }
65  }
66 
67  void Range(int64* l, int64* u) override { inner_->Range(l, u); }
68 
69  void SetRange(int64 l, int64 u) override {
70  if (l > inner_->Min() || u < inner_->Max()) {
71  if (l == u) {
72  solver()->GetPropagationMonitor()->SetValue(inner_, l);
73  inner_->SetValue(l);
74  } else {
75  solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
76  inner_->SetRange(l, u);
77  }
78  }
79  }
80 
81  bool Bound() const override { return inner_->Bound(); }
82 
83  bool IsVar() const override { return true; }
84 
85  IntVar* Var() override { return this; }
86 
87  int64 Value() const override { return inner_->Value(); }
88 
89  void RemoveValue(int64 v) override {
90  if (inner_->Contains(v)) {
91  solver()->GetPropagationMonitor()->RemoveValue(inner_, v);
92  inner_->RemoveValue(v);
93  }
94  }
95 
96  void SetValue(int64 v) override {
97  solver()->GetPropagationMonitor()->SetValue(inner_, v);
98  inner_->SetValue(v);
99  }
100 
101  void RemoveInterval(int64 l, int64 u) override {
102  solver()->GetPropagationMonitor()->RemoveInterval(inner_, l, u);
103  inner_->RemoveInterval(l, u);
104  }
105 
106  void RemoveValues(const std::vector<int64>& values) override {
107  solver()->GetPropagationMonitor()->RemoveValues(inner_, values);
108  inner_->RemoveValues(values);
109  }
110 
111  void SetValues(const std::vector<int64>& values) override {
112  solver()->GetPropagationMonitor()->SetValues(inner_, values);
113  inner_->SetValues(values);
114  }
115 
116  void WhenRange(Demon* d) override { inner_->WhenRange(d); }
117 
118  void WhenBound(Demon* d) override { inner_->WhenBound(d); }
119 
120  void WhenDomain(Demon* d) override { inner_->WhenDomain(d); }
121 
122  uint64 Size() const override { return inner_->Size(); }
123 
124  bool Contains(int64 v) const override { return inner_->Contains(v); }
125 
126  IntVarIterator* MakeHoleIterator(bool reversible) const override {
127  return inner_->MakeHoleIterator(reversible);
128  }
129 
130  IntVarIterator* MakeDomainIterator(bool reversible) const override {
131  return inner_->MakeDomainIterator(reversible);
132  }
133 
134  int64 OldMin() const override { return inner_->OldMin(); }
135 
136  int64 OldMax() const override { return inner_->OldMax(); }
137 
138  int VarType() const override { return TRACE_VAR; }
139 
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);
145  } else {
146  visitor->VisitIntegerVariable(this, ModelVisitor::kTraceOperation, 0,
147  inner_);
148  }
149  }
150 
151  std::string DebugString() const override { return inner_->DebugString(); }
152 
153  IntVar* IsEqual(int64 constant) override { return inner_->IsEqual(constant); }
154 
155  IntVar* IsDifferent(int64 constant) override {
156  return inner_->IsDifferent(constant);
157  }
158 
159  IntVar* IsGreaterOrEqual(int64 constant) override {
160  return inner_->IsGreaterOrEqual(constant);
161  }
162 
163  IntVar* IsLessOrEqual(int64 constant) override {
164  return inner_->IsLessOrEqual(constant);
165  }
166 
167  private:
168  IntVar* const inner_;
169 };
170 
171 class TraceIntExpr : public IntExpr {
172  public:
173  TraceIntExpr(Solver* const solver, IntExpr* const inner)
174  : IntExpr(solver), inner_(inner) {
175  CHECK(!inner->IsVar());
176  if (inner->HasName()) {
177  set_name(inner->name());
178  }
179  }
180 
181  ~TraceIntExpr() override {}
182 
183  int64 Min() const override { return inner_->Min(); }
184 
185  void SetMin(int64 m) override {
186  solver()->GetPropagationMonitor()->SetMin(inner_, m);
187  inner_->SetMin(m);
188  }
189 
190  int64 Max() const override { return inner_->Max(); }
191 
192  void SetMax(int64 m) override {
193  solver()->GetPropagationMonitor()->SetMax(inner_, m);
194  inner_->SetMax(m);
195  }
196 
197  void Range(int64* l, int64* u) override { inner_->Range(l, u); }
198 
199  void SetRange(int64 l, int64 u) override {
200  if (l > inner_->Min() || u < inner_->Max()) {
201  solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
202  inner_->SetRange(l, u);
203  }
204  }
205 
206  bool Bound() const override { return inner_->Bound(); }
207 
208  bool IsVar() const override {
209  DCHECK(!inner_->IsVar());
210  return false;
211  }
212 
213  IntVar* Var() override { return solver()->RegisterIntVar(inner_->Var()); }
214 
215  void WhenRange(Demon* d) override { inner_->WhenRange(d); }
216 
217  void Accept(ModelVisitor* const visitor) const override {
218  visitor->BeginVisitIntegerExpression(ModelVisitor::kTrace, this);
219  visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
220  inner_);
221  visitor->EndVisitIntegerExpression(ModelVisitor::kTrace, this);
222  }
223 
224  std::string DebugString() const override { return inner_->DebugString(); }
225 
226  private:
227  IntExpr* const inner_;
228 };
229 
230 class TraceIntervalVar : public IntervalVar {
231  public:
232  TraceIntervalVar(Solver* const solver, IntervalVar* const inner)
233  : IntervalVar(solver, ""), inner_(inner) {
234  if (inner->HasName()) {
235  set_name(inner->name());
236  }
237  }
238  ~TraceIntervalVar() override {}
239 
240  int64 StartMin() const override { return inner_->StartMin(); }
241 
242  int64 StartMax() const override { return inner_->StartMax(); }
243 
244  void SetStartMin(int64 m) override {
245  if (inner_->MayBePerformed() && (m > inner_->StartMin())) {
246  solver()->GetPropagationMonitor()->SetStartMin(inner_, m);
247  inner_->SetStartMin(m);
248  }
249  }
250 
251  void SetStartMax(int64 m) override {
252  if (inner_->MayBePerformed() && (m < inner_->StartMax())) {
253  solver()->GetPropagationMonitor()->SetStartMax(inner_, m);
254  inner_->SetStartMax(m);
255  }
256  }
257 
258  void SetStartRange(int64 mi, int64 ma) override {
259  if (inner_->MayBePerformed() &&
260  (mi > inner_->StartMin() || ma < inner_->StartMax())) {
261  solver()->GetPropagationMonitor()->SetStartRange(inner_, mi, ma);
262  inner_->SetStartRange(mi, ma);
263  }
264  }
265 
266  int64 OldStartMin() const override { return inner_->OldStartMin(); }
267 
268  int64 OldStartMax() const override { return inner_->OldStartMax(); }
269 
270  void WhenStartRange(Demon* const d) override { inner_->WhenStartRange(d); }
271 
272  void WhenStartBound(Demon* const d) override { inner_->WhenStartBound(d); }
273 
274  int64 EndMin() const override { return inner_->EndMin(); }
275 
276  int64 EndMax() const override { return inner_->EndMax(); }
277 
278  void SetEndMin(int64 m) override {
279  if (inner_->MayBePerformed() && (m > inner_->EndMin())) {
280  solver()->GetPropagationMonitor()->SetEndMin(inner_, m);
281  inner_->SetEndMin(m);
282  }
283  }
284 
285  void SetEndMax(int64 m) override {
286  if (inner_->MayBePerformed() && (m < inner_->EndMax())) {
287  solver()->GetPropagationMonitor()->SetEndMax(inner_, m);
288  inner_->SetEndMax(m);
289  }
290  }
291 
292  void SetEndRange(int64 mi, int64 ma) override {
293  if (inner_->MayBePerformed() &&
294  (mi > inner_->EndMin() || ma < inner_->EndMax())) {
295  solver()->GetPropagationMonitor()->SetEndRange(inner_, mi, ma);
296  inner_->SetEndRange(mi, ma);
297  }
298  }
299 
300  int64 OldEndMin() const override { return inner_->OldEndMin(); }
301 
302  int64 OldEndMax() const override { return inner_->OldEndMax(); }
303 
304  void WhenEndRange(Demon* const d) override { inner_->WhenEndRange(d); }
305 
306  void WhenEndBound(Demon* const d) override { inner_->WhenStartBound(d); }
307 
308  int64 DurationMin() const override { return inner_->DurationMin(); }
309 
310  int64 DurationMax() const override { return inner_->DurationMax(); }
311 
312  void SetDurationMin(int64 m) override {
313  if (inner_->MayBePerformed() && (m > inner_->DurationMin())) {
314  solver()->GetPropagationMonitor()->SetDurationMin(inner_, m);
315  inner_->SetDurationMin(m);
316  }
317  }
318 
319  void SetDurationMax(int64 m) override {
320  if (inner_->MayBePerformed() && (m < inner_->DurationMax())) {
321  solver()->GetPropagationMonitor()->SetDurationMax(inner_, m);
322  inner_->SetDurationMax(m);
323  }
324  }
325 
326  void SetDurationRange(int64 mi, int64 ma) override {
327  if (inner_->MayBePerformed() &&
328  (mi > inner_->DurationMin() || ma < inner_->DurationMax())) {
329  solver()->GetPropagationMonitor()->SetDurationRange(inner_, mi, ma);
330  inner_->SetDurationRange(mi, ma);
331  }
332  }
333 
334  int64 OldDurationMin() const override { return inner_->OldDurationMin(); }
335 
336  int64 OldDurationMax() const override { return inner_->OldDurationMax(); }
337 
338  void WhenDurationRange(Demon* const d) override {
339  inner_->WhenDurationRange(d);
340  }
341 
342  void WhenDurationBound(Demon* const d) override {
343  inner_->WhenDurationBound(d);
344  }
345 
346  bool MustBePerformed() const override { return inner_->MustBePerformed(); }
347 
348  bool MayBePerformed() const override { return inner_->MayBePerformed(); }
349 
350  void SetPerformed(bool value) override {
351  if ((value && !inner_->MustBePerformed()) ||
352  (!value && inner_->MayBePerformed())) {
353  solver()->GetPropagationMonitor()->SetPerformed(inner_, value);
354  inner_->SetPerformed(value);
355  }
356  }
357 
358  bool WasPerformedBound() const override {
359  return inner_->WasPerformedBound();
360  }
361 
362  void WhenPerformedBound(Demon* const d) override {
363  inner_->WhenPerformedBound(d);
364  }
365 
366  IntExpr* StartExpr() override { return inner_->StartExpr(); }
367  IntExpr* DurationExpr() override { return inner_->DurationExpr(); }
368  IntExpr* EndExpr() override { return inner_->EndExpr(); }
369  IntExpr* PerformedExpr() override { return inner_->PerformedExpr(); }
370  IntExpr* SafeStartExpr(int64 unperformed_value) override {
371  return inner_->SafeStartExpr(unperformed_value);
372  }
373  IntExpr* SafeDurationExpr(int64 unperformed_value) override {
374  return inner_->SafeDurationExpr(unperformed_value);
375  }
376  IntExpr* SafeEndExpr(int64 unperformed_value) override {
377  return inner_->SafeEndExpr(unperformed_value);
378  }
379 
380  void Accept(ModelVisitor* const visitor) const override {
381  inner_->Accept(visitor);
382  }
383 
384  std::string DebugString() const override { return inner_->DebugString(); }
385 
386  private:
387  IntervalVar* const inner_;
388 };
389 
390 // ---------- PrintTrace ----------
391 
392 class PrintTrace : public PropagationMonitor {
393  public:
394  struct Info {
395  explicit Info(const std::string& m) : message(m), displayed(false) {}
396  std::string message;
397  bool displayed;
398  };
399 
400  struct Context {
401  Context()
402  : initial_indent(0),
403  indent(0),
404  in_demon(false),
405  in_constraint(false),
406  in_decision_builder(false),
407  in_decision(false),
408  in_objective(false) {}
409 
410  explicit Context(int start_indent)
411  : initial_indent(start_indent),
412  indent(start_indent),
413  in_demon(false),
414  in_constraint(false),
415  in_decision_builder(false),
416  in_decision(false),
417  in_objective(false) {}
418 
419  bool TopLevel() const { return initial_indent == indent; }
420 
421  void Clear() {
423  in_demon = false;
424  in_constraint = false;
425  in_decision_builder = false;
426  in_decision = false;
427  in_objective = false;
428  delayed_info.clear();
429  }
430 
432  int indent;
433  bool in_demon;
438  std::vector<Info> delayed_info;
439  };
440 
441  explicit PrintTrace(Solver* const s) : PropagationMonitor(s) {
442  contexes_.push(Context());
443  }
444 
445  ~PrintTrace() override {}
446 
447  // ----- Search events -----
448 
449  void BeginInitialPropagation() override {
450  CheckNoDelayed();
451  DisplaySearch("Root Node Propagation");
452  IncreaseIndent();
453  }
454  void EndInitialPropagation() override {
455  DecreaseIndent();
456  DisplaySearch("Starting Tree Search");
457  }
458 
459  void BeginNextDecision(DecisionBuilder* const b) override {
460  DisplaySearch(absl::StrFormat("DecisionBuilder(%s)", b->DebugString()));
461  IncreaseIndent();
462  contexes_.top().in_decision_builder = true;
463  }
464 
465  // After calling DecisionBuilder::Next, along with the returned decision.
466  void EndNextDecision(DecisionBuilder* const b, Decision* const d) override {
467  contexes_.top().in_decision_builder = false;
468  DecreaseIndent();
469  }
470 
471  void BeginFail() override {
472  contexes_.top().Clear();
473  while (!contexes_.top().TopLevel()) {
474  DecreaseIndent();
475  LOG(INFO) << Indent() << "}";
476  }
477  DisplaySearch(
478  absl::StrFormat("Failure at depth %d", solver()->SearchDepth()));
479  }
480 
481  bool AtSolution() override {
482  DisplaySearch(
483  absl::StrFormat("Solution found at depth %d", solver()->SearchDepth()));
484  return false;
485  }
486 
487  void ApplyDecision(Decision* const decision) override {
488  DisplaySearch(
489  absl::StrFormat("ApplyDecision(%s)", decision->DebugString()));
490  IncreaseIndent();
491  contexes_.top().in_decision = true;
492  }
493 
494  void RefuteDecision(Decision* const decision) override {
495  if (contexes_.top().in_objective) {
496  DecreaseIndent();
497  contexes_.top().in_objective = false;
498  }
499  DisplaySearch(
500  absl::StrFormat("RefuteDecision(%s)", decision->DebugString()));
501  IncreaseIndent();
502  contexes_.top().in_decision = true;
503  }
504 
505  void AfterDecision(Decision* const decision, bool direction) override {
506  DecreaseIndent();
507  contexes_.top().in_decision = false;
508  }
509 
510  void EnterSearch() override {
511  if (solver()->SolveDepth() == 0) {
512  CHECK_EQ(1, contexes_.size());
513  contexes_.top().Clear();
514  } else {
515  PrintDelayedString();
516  PushNestedContext();
517  }
518  DisplaySearch("Enter Search");
519  }
520 
521  void ExitSearch() override {
522  DisplaySearch("Exit Search");
523  CHECK(contexes_.top().TopLevel());
524  if (solver()->SolveDepth() > 1) {
525  contexes_.pop();
526  }
527  }
528 
529  void RestartSearch() override { CHECK(contexes_.top().TopLevel()); }
530 
531  // ----- Propagation events -----
532 
533  void BeginConstraintInitialPropagation(
534  Constraint* const constraint) override {
535  PushDelayedInfo(
536  absl::StrFormat("Constraint(%s)", constraint->DebugString()));
537  contexes_.top().in_constraint = true;
538  }
539 
540  void EndConstraintInitialPropagation(Constraint* const constraint) override {
541  PopDelayedInfo();
542  contexes_.top().in_constraint = false;
543  }
544 
545  void BeginNestedConstraintInitialPropagation(
546  Constraint* const parent, Constraint* const nested) override {
547  PushDelayedInfo(absl::StrFormat("Constraint(%s)", nested->DebugString()));
548  contexes_.top().in_constraint = true;
549  }
550  void EndNestedConstraintInitialPropagation(Constraint* const,
551  Constraint* const) override {
552  PopDelayedInfo();
553  contexes_.top().in_constraint = false;
554  }
555 
556  void RegisterDemon(Demon* const demon) override {}
557 
558  void BeginDemonRun(Demon* const demon) override {
559  if (demon->priority() != Solver::VAR_PRIORITY) {
560  contexes_.top().in_demon = true;
561  PushDelayedInfo(absl::StrFormat("Demon(%s)", demon->DebugString()));
562  }
563  }
564 
565  void EndDemonRun(Demon* const demon) override {
566  if (demon->priority() != Solver::VAR_PRIORITY) {
567  contexes_.top().in_demon = false;
568  PopDelayedInfo();
569  }
570  }
571 
572  void StartProcessingIntegerVariable(IntVar* const var) override {
573  PushDelayedInfo(absl::StrFormat("StartProcessing(%s)", var->DebugString()));
574  }
575 
576  void EndProcessingIntegerVariable(IntVar* const var) override {
577  PopDelayedInfo();
578  }
579 
580  void PushContext(const std::string& context) override {
581  PushDelayedInfo(context);
582  }
583 
584  void PopContext() override { PopDelayedInfo(); }
585 
586  // ----- IntExpr modifiers -----
587 
588  void SetMin(IntExpr* const expr, int64 new_min) override {
589  DisplayModification(
590  absl::StrFormat("SetMin(%s, %d)", expr->DebugString(), new_min));
591  }
592 
593  void SetMax(IntExpr* const expr, int64 new_max) override {
594  DisplayModification(
595  absl::StrFormat("SetMax(%s, %d)", expr->DebugString(), new_max));
596  }
597 
598  void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) override {
599  DisplayModification(absl::StrFormat("SetRange(%s, [%d .. %d])",
600  expr->DebugString(), new_min, new_max));
601  }
602 
603  // ----- IntVar modifiers -----
604 
605  void SetMin(IntVar* const var, int64 new_min) override {
606  DisplayModification(
607  absl::StrFormat("SetMin(%s, %d)", var->DebugString(), new_min));
608  }
609 
610  void SetMax(IntVar* const var, int64 new_max) override {
611  DisplayModification(
612  absl::StrFormat("SetMax(%s, %d)", var->DebugString(), new_max));
613  }
614 
615  void SetRange(IntVar* const var, int64 new_min, int64 new_max) override {
616  DisplayModification(absl::StrFormat("SetRange(%s, [%d .. %d])",
617  var->DebugString(), new_min, new_max));
618  }
619 
620  void RemoveValue(IntVar* const var, int64 value) override {
621  DisplayModification(
622  absl::StrFormat("RemoveValue(%s, %d)", var->DebugString(), value));
623  }
624 
625  void SetValue(IntVar* const var, int64 value) override {
626  DisplayModification(
627  absl::StrFormat("SetValue(%s, %d)", var->DebugString(), value));
628  }
629 
630  void RemoveInterval(IntVar* const var, int64 imin, int64 imax) override {
631  DisplayModification(absl::StrFormat("RemoveInterval(%s, [%d .. %d])",
632  var->DebugString(), imin, imax));
633  }
634 
635  void SetValues(IntVar* const var, const std::vector<int64>& values) override {
636  DisplayModification(absl::StrFormat("SetValues(%s, %s)", var->DebugString(),
637  absl::StrJoin(values, ", ")));
638  }
639 
640  void RemoveValues(IntVar* const var,
641  const std::vector<int64>& values) override {
642  DisplayModification(absl::StrFormat("RemoveValues(%s, %s)",
643  var->DebugString(),
644  absl::StrJoin(values, ", ")));
645  }
646 
647  // ----- IntervalVar modifiers -----
648 
649  void SetStartMin(IntervalVar* const var, int64 new_min) override {
650  DisplayModification(
651  absl::StrFormat("SetStartMin(%s, %d)", var->DebugString(), new_min));
652  }
653 
654  void SetStartMax(IntervalVar* const var, int64 new_max) override {
655  DisplayModification(
656  absl::StrFormat("SetStartMax(%s, %d)", var->DebugString(), new_max));
657  }
658 
659  void SetStartRange(IntervalVar* const var, int64 new_min,
660  int64 new_max) override {
661  DisplayModification(absl::StrFormat("SetStartRange(%s, [%d .. %d])",
662  var->DebugString(), new_min, new_max));
663  }
664 
665  void SetEndMin(IntervalVar* const var, int64 new_min) override {
666  DisplayModification(
667  absl::StrFormat("SetEndMin(%s, %d)", var->DebugString(), new_min));
668  }
669 
670  void SetEndMax(IntervalVar* const var, int64 new_max) override {
671  DisplayModification(
672  absl::StrFormat("SetEndMax(%s, %d)", var->DebugString(), new_max));
673  }
674 
675  void SetEndRange(IntervalVar* const var, int64 new_min,
676  int64 new_max) override {
677  DisplayModification(absl::StrFormat("SetEndRange(%s, [%d .. %d])",
678  var->DebugString(), new_min, new_max));
679  }
680 
681  void SetDurationMin(IntervalVar* const var, int64 new_min) override {
682  DisplayModification(
683  absl::StrFormat("SetDurationMin(%s, %d)", var->DebugString(), new_min));
684  }
685 
686  void SetDurationMax(IntervalVar* const var, int64 new_max) override {
687  DisplayModification(
688  absl::StrFormat("SetDurationMax(%s, %d)", var->DebugString(), new_max));
689  }
690 
691  void SetDurationRange(IntervalVar* const var, int64 new_min,
692  int64 new_max) override {
693  DisplayModification(absl::StrFormat("SetDurationRange(%s, [%d .. %d])",
694  var->DebugString(), new_min, new_max));
695  }
696 
697  void SetPerformed(IntervalVar* const var, bool value) override {
698  DisplayModification(
699  absl::StrFormat("SetPerformed(%s, %d)", var->DebugString(), value));
700  }
701 
702  void RankFirst(SequenceVar* const var, int index) override {
703  DisplayModification(
704  absl::StrFormat("RankFirst(%s, %d)", var->DebugString(), index));
705  }
706 
707  void RankNotFirst(SequenceVar* const var, int index) override {
708  DisplayModification(
709  absl::StrFormat("RankNotFirst(%s, %d)", var->DebugString(), index));
710  }
711 
712  void RankLast(SequenceVar* const var, int index) override {
713  DisplayModification(
714  absl::StrFormat("RankLast(%s, %d)", var->DebugString(), index));
715  }
716 
717  void RankNotLast(SequenceVar* const var, int index) override {
718  DisplayModification(
719  absl::StrFormat("RankNotLast(%s, %d)", var->DebugString(), index));
720  }
721 
722  void RankSequence(SequenceVar* const var, const std::vector<int>& rank_first,
723  const std::vector<int>& rank_last,
724  const std::vector<int>& unperformed) override {
725  DisplayModification(absl::StrFormat(
726  "RankSequence(%s, forward [%s], backward[%s], unperformed[%s])",
727  var->DebugString(), absl::StrJoin(rank_first, ", "),
728  absl::StrJoin(rank_last, ", "), absl::StrJoin(unperformed, ", ")));
729  }
730 
731  void Install() override {
732  SearchMonitor::Install();
733  if (solver()->SolveDepth() <= 1) {
734  solver()->AddPropagationMonitor(this);
735  }
736  }
737 
738  std::string DebugString() const override { return "PrintTrace"; }
739 
740  private:
741  void PushDelayedInfo(const std::string& delayed) {
742  if (FLAGS_cp_full_trace) {
743  LOG(INFO) << Indent() << delayed << " {";
744  IncreaseIndent();
745  } else {
746  contexes_.top().delayed_info.push_back(Info(delayed));
747  }
748  }
749 
750  void PopDelayedInfo() {
751  if (FLAGS_cp_full_trace) {
752  DecreaseIndent();
753  LOG(INFO) << Indent() << "}";
754  } else {
755  CHECK(!contexes_.top().delayed_info.empty());
756  if (contexes_.top().delayed_info.back().displayed &&
757  !contexes_.top().TopLevel()) {
758  DecreaseIndent();
759  LOG(INFO) << Indent() << "}";
760  } else {
761  contexes_.top().delayed_info.pop_back();
762  }
763  }
764  }
765 
766  void CheckNoDelayed() { CHECK(contexes_.top().delayed_info.empty()); }
767 
768  void PrintDelayedString() {
769  const std::vector<Info>& infos = contexes_.top().delayed_info;
770  for (int i = 0; i < infos.size(); ++i) {
771  const Info& info = infos[i];
772  if (!info.displayed) {
773  LOG(INFO) << Indent() << info.message << " {";
774  IncreaseIndent();
775  // Marks it as displayed.
776  contexes_.top().delayed_info[i].displayed = true;
777  }
778  }
779  }
780 
781  void DisplayModification(const std::string& to_print) {
782  if (FLAGS_cp_full_trace) {
783  LOG(INFO) << Indent() << to_print;
784  } else {
785  PrintDelayedString();
786  if (contexes_.top().in_demon || contexes_.top().in_constraint ||
787  contexes_.top().in_decision_builder || contexes_.top().in_decision ||
788  contexes_.top().in_objective) {
789  // Inside a demon, constraint, decision builder -> normal print.
790  LOG(INFO) << Indent() << to_print;
791  } else {
792  // Top level, modification pushed by the objective. This is a
793  // hack. The SetMax or SetMin done by the objective happens in
794  // the RefuteDecision callback of search monitors. We cannot
795  // easily differentiate that from the actual modifications done
796  // by the Refute() call itself. To distinguish that, we force
797  // the print trace to be last in the list of monitors. Thus
798  // modifications that happens at the top level before the
799  // RefuteDecision() callbacks must be from the objective.
800  // In that case, we push the in_objective context.
801  CHECK(contexes_.top().TopLevel());
802  DisplaySearch(absl::StrFormat("Objective -> %s", to_print));
803  IncreaseIndent();
804  contexes_.top().in_objective = true;
805  }
806  }
807  }
808 
809  void DisplaySearch(const std::string& to_print) {
810  const int solve_depth = solver()->SolveDepth();
811  if (solve_depth <= 1) {
812  LOG(INFO) << Indent() << "######## Top Level Search: " << to_print;
813  } else {
814  LOG(INFO) << Indent() << "######## Nested Search(" << solve_depth - 1
815  << "): " << to_print;
816  }
817  }
818 
819  std::string Indent() {
820  CHECK_GE(contexes_.top().indent, 0);
821  std::string output = " @ ";
822  for (int i = 0; i < contexes_.top().indent; ++i) {
823  output.append(" ");
824  }
825  return output;
826  }
827 
828  void IncreaseIndent() { contexes_.top().indent++; }
829 
830  void DecreaseIndent() {
831  if (contexes_.top().indent > 0) {
832  contexes_.top().indent--;
833  }
834  }
835 
836  void PushNestedContext() {
837  const int initial_indent = contexes_.top().indent;
838  contexes_.push(Context(initial_indent));
839  }
840 
841  std::stack<Context> contexes_;
842 };
843 } // namespace
844 
845 IntExpr* Solver::RegisterIntExpr(IntExpr* const expr) {
846  if (InstrumentsVariables()) {
847  if (expr->IsVar()) {
848  return RegisterIntVar(expr->Var());
849  } else {
850  return RevAlloc(new TraceIntExpr(this, expr));
851  }
852  } else {
853  return expr;
854  }
855 }
856 
857 IntVar* Solver::RegisterIntVar(IntVar* const var) {
858  if (InstrumentsVariables() && var->VarType() != TRACE_VAR) { // Not already a
859  // trace var.
860  return RevAlloc(new TraceIntVar(this, var));
861  } else {
862  return var;
863  }
864 }
865 
866 IntervalVar* Solver::RegisterIntervalVar(IntervalVar* const var) {
867  if (InstrumentsVariables()) {
868  return RevAlloc(new TraceIntervalVar(this, var));
869  } else {
870  return var;
871  }
872 }
873 
875  return s->RevAlloc(new PrintTrace(s));
876 }
877 } // namespace operations_research
var
IntVar * var
Definition: expr_array.cc:1858
integral_types.h
map_util.h
in_objective
bool in_objective
Definition: trace.cc:437
in_decision_builder
bool in_decision_builder
Definition: trace.cc:435
message
std::string message
Definition: trace.cc:396
logging.h
value
int64 value
Definition: demon_profiler.cc:43
in_demon
bool in_demon
Definition: trace.cc:433
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
int64
int64_t int64
Definition: integral_types.h:34
constraint_solveri.h
index
int index
Definition: pack.cc:508
operations_research::RegisterDemon
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
Definition: demon_profiler.cc:460
context
GurobiMPCallbackContext * context
Definition: gurobi_interface.cc:439
in_constraint
bool in_constraint
Definition: trace.cc:434
constraint_solver.h
operations_research::TRACE_VAR
@ TRACE_VAR
Definition: constraint_solveri.h:132
initial_indent
int initial_indent
Definition: trace.cc:431
DEFINE_bool
DEFINE_bool(cp_full_trace, false, "Display all trace information, even if the modifiers has no effect")
uint64
uint64_t uint64
Definition: integral_types.h:39
operations_research::sat::Value
std::function< int64(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1406
operations_research::PropagationMonitor
Definition: constraint_solveri.h:1854
delayed_info
std::vector< Info > delayed_info
Definition: trace.cc:438
in_decision
bool in_decision
Definition: trace.cc:436
b
int64 b
Definition: constraint_solver/table.cc:43
indent
int indent
Definition: trace.cc:432
displayed
bool displayed
Definition: trace.cc:397
commandlineflags.h
operations_research::BuildPrintTrace
PropagationMonitor * BuildPrintTrace(Solver *const s)
Definition: trace.cc:874