I'm trying to understand how Mathematica thinks about the results of Set
. Suppose we perform LHS = RHS
. I'm focusing on when Mathematica considers LHS
to be fully evaluated and when it decides to evaluate LHS
again later.
Discussion and Examples
Suppose I do the following:
(* First example *)
ClearAll[ LHS, f, F ];
LHS = f[x]; (* f[x] *)
f[x_] := F[x]
LHS
(* F[x] *)
This is what I would have expected to happen -- LHS
is re-evaluated at the end.
Now, the following works a bit differently:
(* Second example *)
ClearAll[LHS, f, F, changeQ];
changeQ[x_] := False
f[x_?changeQ] := F[x]
LHS = f[x];
changeQ[x] := True
LHS
(* f[x] *)
Apparently Mathematica decided not to re-evaluate LHS
at the end, otherwise it would evaluate to F[x]
. This is a case where LHS
and f[x]
evaluate to different quantities.
Interestingly enough, swapping the order of two lines in the above changes the outcome:
(* Third example *)
ClearAll[LHS, f, F, changeQ];
changeQ[x_] := False
LHS = f[x];
f[x_?changeQ] := F[x]
changeQ[x] := True
LHS
(* F[x] *)
Swapping the order made LHS
re-evaluate at the end, just like in the first example.
This leads me to more formally pose and tentatively answer the question:
Question
Suppose, for some choice of initialCode
and additionalCode
, we perform
initialCode
LHS = f[x]; (* f[x] *)
additionalCode
LHS
Assuming that LHS
originally evaluated to f[x]
,
For what types of
additionalCode
(and possiblyinitialCode
) does the final evaluation ofLHS
yield something different from evaluatingf[x]
?If
LHS
andf[x]
evaluate to different values (as is the case at the end of the second example above), is it possible to somehow "force"LHS
to evaluate in the same way asf[x]
?
Tentative Answer to Question 1
(Based on evidence from above examples)
LHS
will re-evaluate whenadditionalCode
gives a down value tof
(See 1st and 3rd examples above)LHS
will not re-evaluate in general. (See 2nd example above, where a down value was given to a different function,changedQ
.)
Follow Up
Assuming the tentative answer is along the right track, I'm looking for two things:
- How does Mathematica 'know' when to re-evaluate
LHS
? I'm particularly interested in the vocabulary used to describe the process. - Are there any other conditions under which
LHS
re-evaluates? - Is there a generic way to force
LHS
to re-evaluate? (This is similar to the second question above.)
Of course, I'd welcome any suggestions for good references on this.
Answer
Behavior you're describing is briefly mentioned in last paragraph of "Controlling Infinite Evaluation" tutorial and very similar example is shown in documentation of Update function.
It's related to how Mathematica optimizes evaluation, how it decides that expression has not changed since last evaluation and whether it needs to be re-evaluated.
For what types of
additionalCode
(and possiblyinitialCode
) does the final evaluation ofLHS
yield something different from evaluatingf[x]
?
If evaluation of f[x]
, before evaluating additionalCode
, depends on Condition
or PatternTest
and evaluation of additionalCode
changes some symbols in such a way that results of said Condition
or PatternTest
changes. Then evaluation of LHS
will give different result than evaluation of f[x]
after additionalCode
was evaluated.
I don't know details of internal optimizations and above answer is based on what I recall from my experience, it's not backed up by any definite reference nor by conclusive experiments with Mathematica.
If
LHS
andf[x]
evaluate to different values (as is the case at the end of the second example above), is it possible to somehow "force"LHS
to evaluate in the same way asf[x]
?
Yes, evalute Update[f]
after evaluation of additionalCode
:
(* Second example *)
ClearAll[LHS, f, F, changeQ];
changeQ[x_] := False
f[x_?changeQ] := F[x]
LHS = f[x];
changeQ[x] := True
Update[f]
LHS
(* F[x] *)
How does Mathematica 'know' when to re-evaluate
LHS
? I'm particularly interested in the vocabulary used to describe the process.Are there any other conditions under which
LHS
re-evaluates?
Daniel Lichtblau shed some light on this in answer to "Mathematica execution-time bug: symbol names" post.
Is there a generic way to force LHS to re-evaluate? (This is similar to the second question above.)
Yes, use Update function. If you know which symbols where affected, pass them to Update
, otherwise call Update[]
without arguments.
Comments
Post a Comment