Skip to content

Commit

Permalink
Improve TraceEvaluation ...
Browse files Browse the repository at this point in the history
* Show return values
* Show rewrite rules
  • Loading branch information
rocky committed Dec 14, 2024
1 parent f0da957 commit 6005173
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 10 deletions.
10 changes: 8 additions & 2 deletions mathics/builtin/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,17 @@ def eval(self, expr, evaluation: Evaluation, options: dict):
curr_trace_evaluation = evaluation.definitions.trace_evaluation
curr_time_by_steps = evaluation.definitions.timing_trace_evaluation

old_evaluation_hook = mathics.eval.tracing.trace_evaluate_on_call
old_evaluation_call_hook = mathics.eval.tracing.trace_evaluate_on_call
old_evaluation_return_hook = mathics.eval.tracing.trace_evaluate_on_return

mathics.eval.tracing.trace_evaluate_on_call = (
mathics.eval.tracing.print_evaluate
)

mathics.eval.tracing.trace_evaluate_on_return = (
mathics.eval.tracing.print_evaluate
)

evaluation.definitions.trace_evaluation = True
evaluation.definitions.timing_trace_evaluation = (
options["System`ShowTimeBySteps"] is SymbolTrue
Expand All @@ -397,7 +402,8 @@ def eval(self, expr, evaluation: Evaluation, options: dict):
evaluation.definitions.trace_evaluation = curr_trace_evaluation
evaluation.definitions.timing_trace_evaluation = curr_time_by_steps

mathics.eval.tracing.trace_evaluate_on_call = old_evaluation_hook
mathics.eval.tracing.trace_evaluate_on_call = old_evaluation_call_hook
mathics.eval.tracing.trace_evaluate_on_return = old_evaluation_return_hook


class TraceEvaluationVariable(Builtin):
Expand Down
44 changes: 38 additions & 6 deletions mathics/eval/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@ def print_evaluate(expr, evaluation, status: str, fn: Callable, orig_expr=None):
method when TraceActivate["evaluate" -> True]
"""

# Test and dispose of various situations where showing information
# is pretty useless:
# Showing the return value of a ListExpression literal is
# useless.
if evaluation.definitions.timing_trace_evaluation:
evaluation.print_out(time.time() - evaluation.start_time)

# Test and dispose of various situations where showing information
# is pretty useless: evaluating a Symbol is the Symbol.
# Showing the return value of a ListExpression literal is
# also useless.
from mathics.core.symbols import Symbol, SymbolConstant

if isinstance(expr, Symbol) and not isinstance(expr, SymbolConstant):
return

if (
status == "Returning"
and hasattr(expr, "is_literal")
Expand All @@ -39,8 +44,35 @@ def print_evaluate(expr, evaluation, status: str, fn: Callable, orig_expr=None):
):
return

if orig_expr == expr:
# If the two expressions are the same, there is no point in
# repeating the output.
return

indents = " " * evaluation.recursion_depth
evaluation.print_out(f"{indents}{status} {fn.__qualname__}(): {expr}")

if orig_expr is not None:
if fn.__name__ == "rewrite_apply_eval_step":
assert isinstance(expr, tuple)
if orig_expr != expr[0]:
if status == "Returning":
if expr[1]:
status = "Rewriting"
arrow = " -> "
else:
return
else:
arrow = " = "
return

evaluation.print_out(
f"{indents}{status}: {expr[0]}" + arrow + str(expr)
)
else:
evaluation.print_out(f"{indents}{status}: {orig_expr} = " + str(expr))

elif fn.__name__ != "rewrite_apply_eval_step":
evaluation.print_out(f"{indents}{status} {fn.__qualname__}(): {expr}")
return


Expand Down Expand Up @@ -122,7 +154,7 @@ def call_event_print(event: TraceEvent, fn: Callable, *args) -> bool:
"""
A somewhat generic function to show an event-traced call.
"""
if type(fn) == type or inspect.ismethod(fn) or inspect.isfunction(fn):
if isinstance(type(fn), type) or inspect.ismethod(fn) or inspect.isfunction(fn):
name = f"{fn.__module__}.{fn.__qualname__}"
else:
name = str(fn)
Expand Down
10 changes: 8 additions & 2 deletions test/builtin/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
"""
Unit tests for mathics.builtin.trace
"""

from inspect import isfunction
from test.helper import evaluate
from typing import Callable

import pytest

import mathics.eval.tracing
from mathics.core.evaluation import Evaluation
from mathics.core.interrupt import AbortInterrupt

trace_evaluation_calls = 0
Expand All @@ -20,13 +22,17 @@ def test_TraceEvaluation():
old_recursion_limit = evaluate("$RecursionLimit")
old_evaluation_hook = mathics.eval.tracing.print_evaluate

def counting_print_evaluate(expr, evaluation, status: str, orig_expr=None) -> bool:
def counting_print_evaluate(
expr, evaluation: Evaluation, status: str, fn: Callable, orig_expr=None
) -> bool:
"""
A replacement for mathics.eval.tracing.print_evaluate() that counts the
number of evaluation calls.
"""
global trace_evaluation_calls
trace_evaluation_calls += 1
assert status in ("Evaluating", "Returning")
assert isfunction(fn), "Expecting 4th argument to be a function"
return False

try:
Expand Down

0 comments on commit 6005173

Please sign in to comment.