22 #include "absl/container/flat_hash_map.h"
23 #include "absl/strings/str_format.h"
24 #include "absl/strings/str_join.h"
33 "Display all trace information, even if the modifiers has no effect");
38 class TraceIntVar :
public IntVar {
40 TraceIntVar(Solver*
const solver, IntVar*
const inner)
41 : IntVar(solver), inner_(inner) {
42 if (inner->HasName()) {
43 set_name(inner->name());
48 ~TraceIntVar()
override {}
50 int64_t Min()
const override {
return inner_->Min(); }
52 void SetMin(int64_t m)
override {
53 if (m > inner_->Min()) {
54 solver()->GetPropagationMonitor()->SetMin(inner_, m);
59 int64_t Max()
const override {
return inner_->Max(); }
61 void SetMax(int64_t m)
override {
62 if (m < inner_->Max()) {
63 solver()->GetPropagationMonitor()->SetMax(inner_, m);
68 void Range(int64_t* l, int64_t* u)
override { inner_->Range(l, u); }
70 void SetRange(int64_t l, int64_t u)
override {
71 if (l > inner_->Min() || u < inner_->Max()) {
73 solver()->GetPropagationMonitor()->SetValue(inner_, l);
76 solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
77 inner_->SetRange(l, u);
82 bool Bound()
const override {
return inner_->Bound(); }
84 bool IsVar()
const override {
return true; }
86 IntVar* Var()
override {
return this; }
88 int64_t
Value()
const override {
return inner_->Value(); }
90 void RemoveValue(int64_t v)
override {
91 if (inner_->Contains(v)) {
92 solver()->GetPropagationMonitor()->RemoveValue(inner_, v);
93 inner_->RemoveValue(v);
97 void SetValue(int64_t v)
override {
98 solver()->GetPropagationMonitor()->SetValue(inner_, v);
102 void RemoveInterval(int64_t l, int64_t u)
override {
103 solver()->GetPropagationMonitor()->RemoveInterval(inner_, l, u);
104 inner_->RemoveInterval(l, u);
107 void RemoveValues(
const std::vector<int64_t>& values)
override {
108 solver()->GetPropagationMonitor()->RemoveValues(inner_, values);
109 inner_->RemoveValues(values);
112 void SetValues(
const std::vector<int64_t>& values)
override {
113 solver()->GetPropagationMonitor()->SetValues(inner_, values);
114 inner_->SetValues(values);
117 void WhenRange(Demon* d)
override { inner_->WhenRange(d); }
119 void WhenBound(Demon* d)
override { inner_->WhenBound(d); }
121 void WhenDomain(Demon* d)
override { inner_->WhenDomain(d); }
123 uint64_t Size()
const override {
return inner_->Size(); }
125 bool Contains(int64_t v)
const override {
return inner_->Contains(v); }
127 IntVarIterator* MakeHoleIterator(
bool reversible)
const override {
128 return inner_->MakeHoleIterator(reversible);
131 IntVarIterator* MakeDomainIterator(
bool reversible)
const override {
132 return inner_->MakeDomainIterator(reversible);
135 int64_t OldMin()
const override {
return inner_->OldMin(); }
137 int64_t OldMax()
const override {
return inner_->OldMax(); }
139 int VarType()
const override {
return TRACE_VAR; }
141 void Accept(ModelVisitor*
const visitor)
const override {
142 IntExpr*
const cast_expr =
143 solver()->CastExpression(
const_cast<TraceIntVar*
>(
this));
144 if (cast_expr !=
nullptr) {
145 visitor->VisitIntegerVariable(
this, cast_expr);
152 std::string DebugString()
const override {
return inner_->DebugString(); }
154 IntVar* IsEqual(int64_t constant)
override {
155 return inner_->IsEqual(constant);
158 IntVar* IsDifferent(int64_t constant)
override {
159 return inner_->IsDifferent(constant);
162 IntVar* IsGreaterOrEqual(int64_t constant)
override {
163 return inner_->IsGreaterOrEqual(constant);
166 IntVar* IsLessOrEqual(int64_t constant)
override {
167 return inner_->IsLessOrEqual(constant);
171 IntVar*
const inner_;
174 class TraceIntExpr :
public IntExpr {
176 TraceIntExpr(Solver*
const solver, IntExpr*
const inner)
177 : IntExpr(solver), inner_(inner) {
178 CHECK(!inner->IsVar());
179 if (inner->HasName()) {
180 set_name(inner->name());
184 ~TraceIntExpr()
override {}
186 int64_t Min()
const override {
return inner_->Min(); }
188 void SetMin(int64_t m)
override {
189 solver()->GetPropagationMonitor()->SetMin(inner_, m);
193 int64_t Max()
const override {
return inner_->Max(); }
195 void SetMax(int64_t m)
override {
196 solver()->GetPropagationMonitor()->SetMax(inner_, m);
200 void Range(int64_t* l, int64_t* u)
override { inner_->Range(l, u); }
202 void SetRange(int64_t l, int64_t u)
override {
203 if (l > inner_->Min() || u < inner_->Max()) {
204 solver()->GetPropagationMonitor()->SetRange(inner_, l, u);
205 inner_->SetRange(l, u);
209 bool Bound()
const override {
return inner_->Bound(); }
211 bool IsVar()
const override {
212 DCHECK(!inner_->IsVar());
216 IntVar* Var()
override {
return solver()->RegisterIntVar(inner_->Var()); }
218 void WhenRange(Demon* d)
override { inner_->WhenRange(d); }
220 void Accept(ModelVisitor*
const visitor)
const override {
227 std::string DebugString()
const override {
return inner_->DebugString(); }
230 IntExpr*
const inner_;
233 class TraceIntervalVar :
public IntervalVar {
235 TraceIntervalVar(Solver*
const solver, IntervalVar*
const inner)
236 : IntervalVar(solver,
""), inner_(inner) {
237 if (inner->HasName()) {
238 set_name(inner->name());
241 ~TraceIntervalVar()
override {}
243 int64_t StartMin()
const override {
return inner_->StartMin(); }
245 int64_t StartMax()
const override {
return inner_->StartMax(); }
247 void SetStartMin(int64_t m)
override {
248 if (inner_->MayBePerformed() && (m > inner_->StartMin())) {
249 solver()->GetPropagationMonitor()->SetStartMin(inner_, m);
250 inner_->SetStartMin(m);
254 void SetStartMax(int64_t m)
override {
255 if (inner_->MayBePerformed() && (m < inner_->StartMax())) {
256 solver()->GetPropagationMonitor()->SetStartMax(inner_, m);
257 inner_->SetStartMax(m);
261 void SetStartRange(int64_t mi, int64_t ma)
override {
262 if (inner_->MayBePerformed() &&
263 (mi > inner_->StartMin() || ma < inner_->StartMax())) {
264 solver()->GetPropagationMonitor()->SetStartRange(inner_, mi, ma);
265 inner_->SetStartRange(mi, ma);
269 int64_t OldStartMin()
const override {
return inner_->OldStartMin(); }
271 int64_t OldStartMax()
const override {
return inner_->OldStartMax(); }
273 void WhenStartRange(Demon*
const d)
override { inner_->WhenStartRange(d); }
275 void WhenStartBound(Demon*
const d)
override { inner_->WhenStartBound(d); }
277 int64_t EndMin()
const override {
return inner_->EndMin(); }
279 int64_t EndMax()
const override {
return inner_->EndMax(); }
281 void SetEndMin(int64_t m)
override {
282 if (inner_->MayBePerformed() && (m > inner_->EndMin())) {
283 solver()->GetPropagationMonitor()->SetEndMin(inner_, m);
284 inner_->SetEndMin(m);
288 void SetEndMax(int64_t m)
override {
289 if (inner_->MayBePerformed() && (m < inner_->EndMax())) {
290 solver()->GetPropagationMonitor()->SetEndMax(inner_, m);
291 inner_->SetEndMax(m);
295 void SetEndRange(int64_t mi, int64_t ma)
override {
296 if (inner_->MayBePerformed() &&
297 (mi > inner_->EndMin() || ma < inner_->EndMax())) {
298 solver()->GetPropagationMonitor()->SetEndRange(inner_, mi, ma);
299 inner_->SetEndRange(mi, ma);
303 int64_t OldEndMin()
const override {
return inner_->OldEndMin(); }
305 int64_t OldEndMax()
const override {
return inner_->OldEndMax(); }
307 void WhenEndRange(Demon*
const d)
override { inner_->WhenEndRange(d); }
309 void WhenEndBound(Demon*
const d)
override { inner_->WhenStartBound(d); }
311 int64_t DurationMin()
const override {
return inner_->DurationMin(); }
313 int64_t DurationMax()
const override {
return inner_->DurationMax(); }
315 void SetDurationMin(int64_t m)
override {
316 if (inner_->MayBePerformed() && (m > inner_->DurationMin())) {
317 solver()->GetPropagationMonitor()->SetDurationMin(inner_, m);
318 inner_->SetDurationMin(m);
322 void SetDurationMax(int64_t m)
override {
323 if (inner_->MayBePerformed() && (m < inner_->DurationMax())) {
324 solver()->GetPropagationMonitor()->SetDurationMax(inner_, m);
325 inner_->SetDurationMax(m);
329 void SetDurationRange(int64_t mi, int64_t ma)
override {
330 if (inner_->MayBePerformed() &&
331 (mi > inner_->DurationMin() || ma < inner_->DurationMax())) {
332 solver()->GetPropagationMonitor()->SetDurationRange(inner_, mi, ma);
333 inner_->SetDurationRange(mi, ma);
337 int64_t OldDurationMin()
const override {
return inner_->OldDurationMin(); }
339 int64_t OldDurationMax()
const override {
return inner_->OldDurationMax(); }
341 void WhenDurationRange(Demon*
const d)
override {
342 inner_->WhenDurationRange(d);
345 void WhenDurationBound(Demon*
const d)
override {
346 inner_->WhenDurationBound(d);
349 bool MustBePerformed()
const override {
return inner_->MustBePerformed(); }
351 bool MayBePerformed()
const override {
return inner_->MayBePerformed(); }
353 void SetPerformed(
bool value)
override {
354 if ((
value && !inner_->MustBePerformed()) ||
355 (!
value && inner_->MayBePerformed())) {
356 solver()->GetPropagationMonitor()->SetPerformed(inner_,
value);
357 inner_->SetPerformed(
value);
361 bool WasPerformedBound()
const override {
362 return inner_->WasPerformedBound();
365 void WhenPerformedBound(Demon*
const d)
override {
366 inner_->WhenPerformedBound(d);
369 IntExpr* StartExpr()
override {
return inner_->StartExpr(); }
370 IntExpr* DurationExpr()
override {
return inner_->DurationExpr(); }
371 IntExpr* EndExpr()
override {
return inner_->EndExpr(); }
372 IntExpr* PerformedExpr()
override {
return inner_->PerformedExpr(); }
373 IntExpr* SafeStartExpr(int64_t unperformed_value)
override {
374 return inner_->SafeStartExpr(unperformed_value);
376 IntExpr* SafeDurationExpr(int64_t unperformed_value)
override {
377 return inner_->SafeDurationExpr(unperformed_value);
379 IntExpr* SafeEndExpr(int64_t unperformed_value)
override {
380 return inner_->SafeEndExpr(unperformed_value);
383 void Accept(ModelVisitor*
const visitor)
const override {
384 inner_->Accept(visitor);
387 std::string DebugString()
const override {
return inner_->DebugString(); }
390 IntervalVar*
const inner_;
395 class PrintTrace :
public PropagationMonitor {
413 explicit Context(
int start_indent)
444 explicit PrintTrace(Solver*
const s) : PropagationMonitor(s) {
445 contexes_.push(Context());
448 ~PrintTrace()
override {}
452 void BeginInitialPropagation()
override {
454 DisplaySearch(
"Root Node Propagation");
457 void EndInitialPropagation()
override {
459 DisplaySearch(
"Starting Tree Search");
462 void BeginNextDecision(DecisionBuilder*
const b)
override {
463 DisplaySearch(absl::StrFormat(
"DecisionBuilder(%s)",
b->DebugString()));
465 contexes_.top().in_decision_builder =
true;
469 void EndNextDecision(DecisionBuilder*
const b, Decision*
const d)
override {
470 contexes_.top().in_decision_builder =
false;
474 void BeginFail()
override {
475 contexes_.top().Clear();
476 while (!contexes_.top().TopLevel()) {
478 LOG(INFO) << Indent() <<
"}";
481 absl::StrFormat(
"Failure at depth %d", solver()->SearchDepth()));
484 bool AtSolution()
override {
486 absl::StrFormat(
"Solution found at depth %d", solver()->SearchDepth()));
490 void ApplyDecision(Decision*
const decision)
override {
492 absl::StrFormat(
"ApplyDecision(%s)", decision->DebugString()));
494 contexes_.top().in_decision =
true;
497 void RefuteDecision(Decision*
const decision)
override {
498 if (contexes_.top().in_objective) {
500 contexes_.top().in_objective =
false;
503 absl::StrFormat(
"RefuteDecision(%s)", decision->DebugString()));
505 contexes_.top().in_decision =
true;
508 void AfterDecision(Decision*
const decision,
bool direction)
override {
510 contexes_.top().in_decision =
false;
513 void EnterSearch()
override {
514 if (solver()->SolveDepth() == 0) {
515 CHECK_EQ(1, contexes_.size());
516 contexes_.top().Clear();
518 PrintDelayedString();
521 DisplaySearch(
"Enter Search");
524 void ExitSearch()
override {
525 DisplaySearch(
"Exit Search");
526 CHECK(contexes_.top().TopLevel());
527 if (solver()->SolveDepth() > 1) {
532 void RestartSearch()
override { CHECK(contexes_.top().TopLevel()); }
536 void BeginConstraintInitialPropagation(
537 Constraint*
const constraint)
override {
539 absl::StrFormat(
"Constraint(%s)", constraint->DebugString()));
540 contexes_.top().in_constraint =
true;
543 void EndConstraintInitialPropagation(Constraint*
const constraint)
override {
545 contexes_.top().in_constraint =
false;
548 void BeginNestedConstraintInitialPropagation(
549 Constraint*
const parent, Constraint*
const nested)
override {
550 PushDelayedInfo(absl::StrFormat(
"Constraint(%s)", nested->DebugString()));
551 contexes_.top().in_constraint =
true;
553 void EndNestedConstraintInitialPropagation(Constraint*
const,
554 Constraint*
const)
override {
556 contexes_.top().in_constraint =
false;
561 void BeginDemonRun(Demon*
const demon)
override {
563 contexes_.top().in_demon =
true;
564 PushDelayedInfo(absl::StrFormat(
"Demon(%s)", demon->DebugString()));
568 void EndDemonRun(Demon*
const demon)
override {
570 contexes_.top().in_demon =
false;
575 void StartProcessingIntegerVariable(IntVar*
const var)
override {
576 PushDelayedInfo(absl::StrFormat(
"StartProcessing(%s)",
var->DebugString()));
579 void EndProcessingIntegerVariable(IntVar*
const var)
override {
583 void PushContext(
const std::string&
context)
override {
587 void PopContext()
override { PopDelayedInfo(); }
591 void SetMin(IntExpr*
const expr, int64_t new_min)
override {
593 absl::StrFormat(
"SetMin(%s, %d)", expr->DebugString(), new_min));
596 void SetMax(IntExpr*
const expr, int64_t new_max)
override {
598 absl::StrFormat(
"SetMax(%s, %d)", expr->DebugString(), new_max));
601 void SetRange(IntExpr*
const expr, int64_t new_min,
602 int64_t new_max)
override {
603 DisplayModification(absl::StrFormat(
"SetRange(%s, [%d .. %d])",
604 expr->DebugString(), new_min, new_max));
609 void SetMin(IntVar*
const var, int64_t new_min)
override {
611 absl::StrFormat(
"SetMin(%s, %d)",
var->DebugString(), new_min));
614 void SetMax(IntVar*
const var, int64_t new_max)
override {
616 absl::StrFormat(
"SetMax(%s, %d)",
var->DebugString(), new_max));
619 void SetRange(IntVar*
const var, int64_t new_min, int64_t new_max)
override {
620 DisplayModification(absl::StrFormat(
"SetRange(%s, [%d .. %d])",
621 var->DebugString(), new_min, new_max));
624 void RemoveValue(IntVar*
const var, int64_t
value)
override {
626 absl::StrFormat(
"RemoveValue(%s, %d)",
var->DebugString(),
value));
629 void SetValue(IntVar*
const var, int64_t
value)
override {
631 absl::StrFormat(
"SetValue(%s, %d)",
var->DebugString(),
value));
634 void RemoveInterval(IntVar*
const var, int64_t imin, int64_t imax)
override {
635 DisplayModification(absl::StrFormat(
"RemoveInterval(%s, [%d .. %d])",
636 var->DebugString(), imin, imax));
639 void SetValues(IntVar*
const var,
640 const std::vector<int64_t>& values)
override {
641 DisplayModification(absl::StrFormat(
"SetValues(%s, %s)",
var->DebugString(),
642 absl::StrJoin(values,
", ")));
645 void RemoveValues(IntVar*
const var,
646 const std::vector<int64_t>& values)
override {
647 DisplayModification(absl::StrFormat(
"RemoveValues(%s, %s)",
649 absl::StrJoin(values,
", ")));
654 void SetStartMin(IntervalVar*
const var, int64_t new_min)
override {
656 absl::StrFormat(
"SetStartMin(%s, %d)",
var->DebugString(), new_min));
659 void SetStartMax(IntervalVar*
const var, int64_t new_max)
override {
661 absl::StrFormat(
"SetStartMax(%s, %d)",
var->DebugString(), new_max));
664 void SetStartRange(IntervalVar*
const var, int64_t new_min,
665 int64_t new_max)
override {
666 DisplayModification(absl::StrFormat(
"SetStartRange(%s, [%d .. %d])",
667 var->DebugString(), new_min, new_max));
670 void SetEndMin(IntervalVar*
const var, int64_t new_min)
override {
672 absl::StrFormat(
"SetEndMin(%s, %d)",
var->DebugString(), new_min));
675 void SetEndMax(IntervalVar*
const var, int64_t new_max)
override {
677 absl::StrFormat(
"SetEndMax(%s, %d)",
var->DebugString(), new_max));
680 void SetEndRange(IntervalVar*
const var, int64_t new_min,
681 int64_t new_max)
override {
682 DisplayModification(absl::StrFormat(
"SetEndRange(%s, [%d .. %d])",
683 var->DebugString(), new_min, new_max));
686 void SetDurationMin(IntervalVar*
const var, int64_t new_min)
override {
688 absl::StrFormat(
"SetDurationMin(%s, %d)",
var->DebugString(), new_min));
691 void SetDurationMax(IntervalVar*
const var, int64_t new_max)
override {
693 absl::StrFormat(
"SetDurationMax(%s, %d)",
var->DebugString(), new_max));
696 void SetDurationRange(IntervalVar*
const var, int64_t new_min,
697 int64_t new_max)
override {
698 DisplayModification(absl::StrFormat(
"SetDurationRange(%s, [%d .. %d])",
699 var->DebugString(), new_min, new_max));
702 void SetPerformed(IntervalVar*
const var,
bool value)
override {
704 absl::StrFormat(
"SetPerformed(%s, %d)",
var->DebugString(),
value));
707 void RankFirst(SequenceVar*
const var,
int index)
override {
709 absl::StrFormat(
"RankFirst(%s, %d)",
var->DebugString(),
index));
712 void RankNotFirst(SequenceVar*
const var,
int index)
override {
714 absl::StrFormat(
"RankNotFirst(%s, %d)",
var->DebugString(),
index));
717 void RankLast(SequenceVar*
const var,
int index)
override {
719 absl::StrFormat(
"RankLast(%s, %d)",
var->DebugString(),
index));
722 void RankNotLast(SequenceVar*
const var,
int index)
override {
724 absl::StrFormat(
"RankNotLast(%s, %d)",
var->DebugString(),
index));
727 void RankSequence(SequenceVar*
const var,
const std::vector<int>& rank_first,
728 const std::vector<int>& rank_last,
729 const std::vector<int>& unperformed)
override {
730 DisplayModification(absl::StrFormat(
731 "RankSequence(%s, forward [%s], backward[%s], unperformed[%s])",
732 var->DebugString(), absl::StrJoin(rank_first,
", "),
733 absl::StrJoin(rank_last,
", "), absl::StrJoin(unperformed,
", ")));
736 void Install()
override {
738 if (solver()->SolveDepth() <= 1) {
739 solver()->AddPropagationMonitor(
this);
743 std::string DebugString()
const override {
return "PrintTrace"; }
746 void PushDelayedInfo(
const std::string& delayed) {
747 if (absl::GetFlag(FLAGS_cp_full_trace)) {
748 LOG(INFO) << Indent() << delayed <<
" {";
751 contexes_.top().delayed_info.push_back(Info(delayed));
755 void PopDelayedInfo() {
756 if (absl::GetFlag(FLAGS_cp_full_trace)) {
758 LOG(INFO) << Indent() <<
"}";
760 CHECK(!contexes_.top().delayed_info.empty());
761 if (contexes_.top().delayed_info.back().displayed &&
762 !contexes_.top().TopLevel()) {
764 LOG(INFO) << Indent() <<
"}";
766 contexes_.top().delayed_info.pop_back();
771 void CheckNoDelayed() { CHECK(contexes_.top().delayed_info.empty()); }
773 void PrintDelayedString() {
774 const std::vector<Info>& infos = contexes_.top().delayed_info;
775 for (
int i = 0; i < infos.size(); ++i) {
776 const Info& info = infos[i];
777 if (!info.displayed) {
778 LOG(INFO) << Indent() << info.message <<
" {";
781 contexes_.top().delayed_info[i].displayed =
true;
786 void DisplayModification(
const std::string& to_print) {
787 if (absl::GetFlag(FLAGS_cp_full_trace)) {
788 LOG(INFO) << Indent() << to_print;
790 PrintDelayedString();
791 if (contexes_.top().in_demon || contexes_.top().in_constraint ||
792 contexes_.top().in_decision_builder || contexes_.top().in_decision ||
793 contexes_.top().in_objective) {
795 LOG(INFO) << Indent() << to_print;
806 CHECK(contexes_.top().TopLevel());
807 DisplaySearch(absl::StrFormat(
"Objective -> %s", to_print));
809 contexes_.top().in_objective =
true;
814 void DisplaySearch(
const std::string& to_print) {
815 const int solve_depth = solver()->SolveDepth();
816 if (solve_depth <= 1) {
817 LOG(INFO) << Indent() <<
"######## Top Level Search: " << to_print;
819 LOG(INFO) << Indent() <<
"######## Nested Search(" << solve_depth - 1
820 <<
"): " << to_print;
824 std::string Indent() {
825 CHECK_GE(contexes_.top().indent, 0);
826 std::string output =
" @ ";
827 for (
int i = 0; i < contexes_.top().
indent; ++i) {
833 void IncreaseIndent() { contexes_.top().indent++; }
835 void DecreaseIndent() {
836 if (contexes_.top().indent > 0) {
837 contexes_.top().indent--;
841 void PushNestedContext() {
846 std::stack<Context> contexes_;
855 return RevAlloc(
new TraceIntExpr(
this, expr));
880 return s->
RevAlloc(
new PrintTrace(s));
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::pair< double, double > Range
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")