I am looking for a simple, robust way to evaluate an expression only one step, and return the result in a held form.
The definition of a single step is ambiguous, and this itself is probably worthy of exploration. Some interpretations will raise the question of what should be returned. I am specifically thinking of capturing the right-hand side of function definitions and rules. Another view would be the first evaluation step that transforms the entire input expression.
Examples of desired output:
x = 1; y = 1;
q := 1 + 2 x + 3 y
(* step[q] -----> HoldForm[1 + 2 x + 3 y] *)
val = 1;
f[x_] /; x < 5 := ("X < 5"; val)
f[_, y_] := y val
f[x_] := f[x - 1]
(* step[ f[3] ] -----> HoldForm["X < 5"; val] *)
(* step[ f[3, 4] ] -----> HoldForm[4 val] *)
(* step[ f[5] ] -----> HoldForm[f[5 - 1]] *)
For an internal function:
x = 7; y = 4;
(* step[ Mod[x Pi, y] ] -----> HoldForm[ Mod[7 Pi, 4] ] *)
(* step[ Mod[7 Pi, 4] ] -----> HoldForm[ 7 Pi - Quotient[7 Pi, 4] 4 ] *)
each because that is the first step in Trace
that transforms the entire expression.
I realize that for user-defined functions it is possible to manipulate *Values
manually, but finding and matching all possible *Values
is complicated, and I am looking for a universal approach using something like TraceScan
. Trace
keeps track of the level of evaluation with brackets, but TraceScan
does not appear to provide this information to its given functions. It would be possible to use Trace
and then extract the desired step afterward, but I want something that does not carry out the rest of the evaluation.
Answer
I believe I have found the solution I was seeking. It returns the first step that transforms the entire expression, and it does so without further evaluation.
The P = (P =
part is to skip the untransformed expression.
SetAttributes[step, HoldAll]
step[expr_] :=
Module[{P},
P = (P = Return[#, TraceScan] &) &;
TraceScan[P, expr, TraceDepth -> 1]
]
I hope that this function will be as helpful to others as I expect it will be to me.
Comments
Post a Comment