3
$\begingroup$

Regarding TraceDepth with TraceDepth->3,it seems that {{{fib[1]}}} is also 3 level deep, but the output of the code below does not include this expression.Could I know the reason?

According to Doc concerning Trace;

You can set the option TraceDepth->n to tell Trace to include only lists nested at most n levels deep. In this way, you can often pick out the "big steps" in a computation, without seeing the details.

fib[n_] := fib[n - 1] + fib[n - 2] fib[0] = fib[1] = 1; Trace[fib[3], fib[_]] (* {fib[3],{fib[2],{fib[1]},{fib[0]}},{fib[1]}} *)(* There is {{{fib[1]}}} *) Trace[fib[3], fib[_],TraceDepth->3] (* {fib[3],{fib[2],{fib[0]}},{fib[1]}} *)(* {{{fib[1]}}} not included? *) 
$\endgroup$
4
  • 1
    $\begingroup$ On "14.2.1 for Mac OS X ARM (64-bit) (March 16, 2025)", I got {fib[3],{fib[2],{fib[0]}},{fib[1]}}. $\endgroup$ Commented Aug 13 at 6:26
  • $\begingroup$ Thank you for your reply; I have just added comment (* *) to show clearly {{{fib[1]}}} is missing when TraceDepth->3 $\endgroup$ Commented Aug 13 at 7:22
  • 1
    $\begingroup$ fib[0] should be zero and not 1. (this is not related to why you do not see fib[1] in the trace) $\endgroup$ Commented Aug 13 at 8:45
  • 2
    $\begingroup$ Btw, you get much performance if you do memoziation. As in fib[0]=0; fib[1]=1; fib[n_]:=fib[n]=fib[n-1]+fib[n-2] $\endgroup$ Commented Aug 13 at 8:51

2 Answers 2

3
$\begingroup$

TL;DR

This appears to be a bug... either in the documentation or within the implementation of Trace.

Discussion

The output of Trace[fib[3], _fib] is:

{fib[3],{fib[2],{fib[1]},{fib[0]}},{fib[1]}} 

The first occurrence of fib[1] clearly appears at the same level as fib[0], namely level 3. So both should appear with TraceDepth->3, if the documentation quoted in the OP is to be believed. But they do not.

{fib[3],{fib[2],{fib[0]}},{fib[1]}} 

The documentation for TraceDepth also states:

By setting TraceDepth, you can make Trace and related functions skip over "inner" parts of a computation, making their operation more efficient.

This suggests that the filtering is occurring during evaluation rather simply dropping deep terms from the final constructed list. The actual evaluation sequence (shown below) is quite complex. Perhaps a heuristic is being used to estimate the level in the final result? And the heuristic is not exact?

tree showing trace sequence

So we have:

Expression Level in
Result List
TraceDepth
Level
Evaluation
Depth
fib[0] 3 3 7
fib[1] 2, 3 2, 4 4, 7

In the absence of a further clarifying remark in the documentation, I would consider this to be a bug.


If it is crucial to analyze call chains like these, then TraceScan can be used to get more detailed evaluation information. See, for example, The clearest way to represent Mathematica's evaluation sequence.

$\endgroup$
2
  • $\begingroup$ Thank you for your reply and handy OpenView[] usage; Interestingly, fib[0] is included in Trace[fib[3], fib[_],TraceDepth->3], but not fib[1], although, fib[0] and fib[1] are siblings as can be clearly seen from the tree structure you supplied and also your OpenView[] show[{expr_, steps___}] := OpenerView[{expr, Column[show /@ {steps}]}] show[x_] := x Trace[fib[3]]//show So.. for the moment my naive guess is that if there are siblings, it seems that only the one with the earliest one is selected $\endgroup$ Commented Aug 14 at 5:48
  • 1
    $\begingroup$ @Soon You are right... I failed to notice that and my original response was incorrect. After much experimentation, I have come to the conclusion that this is a bug. I have revised my response accordingly. $\endgroup$ Commented Aug 14 at 18:45
3
$\begingroup$

I have long noticed that TraceDepth is not the same as limiting TraceLevel:

Trace[fib[3], _fib /; TraceLevel[] <= 3, TraceDepth -> 3] Trace[fib[3], _fib, TraceDepth -> 3] (* {fib[3],{fib[2]},{fib[1]}} {fib[3],{fib[2],{fib[0]}},{fib[1]}} *) 

I have no explanation for the discrepancy.

A way to visualize the levels of Trace[]:

mark = Replace[#, List[y__] :> mark /@ "\[FivePointedStar]"[y]] &; Hold[#] &@mark@Trace[fib[3]] /. HoldForm[x_] :> x // ExpressionTree[#, "Atoms", Heads -> True] & // TreeChildren // Last // Tree[#, TreeElementStyle -> pos_ :> Lighter[ColorData[98][Length@pos], 0.7]] & 

exression tree of Trace[] output

Each level has a different color. The star indicates the beginning of the evaluation of an expression. The first star has a TraceLevel[] of 2. I have been unable to obtain a TraceLevel[] of 1.


Another way to see the trace:

TraceScan[ CellPrint[ExpressionCell[ Row[{Row[{Indent[5 (TraceLevel[] - 2)], "Trace <", TraceLevel[], ">: "}, BaseStyle -> {Bold, Darker@Lighter@Blend[{Red, Magenta}]}], FullForm /@ #1}], "Output" , CellMargins -> {{66, 6}, {0, 0}} ]] &, fib[3], _fib]; 

trace lines labeled by trace level

$\endgroup$
1
  • $\begingroup$ Thank you for your use case of TraceLevel[] and ExpressionTree[];(※For the purpose of debugging, I've learned that observing a tree structure or an indented table format, instead of using the rather opaque TraceDepth option, is recommended) $\endgroup$ Commented Aug 19 at 1:41

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.