10
$\begingroup$

If I type e1 := 3 x + 2 (1 + y) z // TreeForm, I get an expression tree. If I then type e1 /. x -> 3, I get another prefectly correct expression tree.

Is there a way that I can get TreeForm's formatting to keep the nodes in the same location after the transformation?

$\endgroup$
2

4 Answers 4

7
$\begingroup$

The simplest way to do what you'd like to do seems to be this:

e1 /. x -> "3"

enter image description here

Head["3"]
String 

Replacing x by a string "3" prevents evaluating a part of the expression including Times[3, x].

A bit more tricky way yielding the same result would be this:

e1 /. x -> String["3"][[1]]
$\endgroup$
6
$\begingroup$

I liked a response that got deleted. If all you want is the cosmetic look, and do not care if the expression is actually altered, here is something I use to make expressions "inert". The idea is to replace numeric functions with their string names.

inertify[expr_Hold] := 
 Module[{xx}, 
  xx[Release[
     expr /. f_Symbol /; MemberQ[Attributes[f], NumericFunction] :> 
       ToString[f]]] /. xx -> Hold]

Here is the example.

e1 := 3 x + 2 (1 + y) z

In[227]:= e2 = inertify[Hold[Evaluate[e1]]]

Out[227]= Hold["Plus"["Times"[3, x], "Times"[2, "Plus"[1, y], z]]]

In[228]:= TreeForm[First@e2 /. x -> 3]

enter image description here

$\endgroup$
3
  • 2
    $\begingroup$ I had to look up Release on the documentation. Old habits die hard? $\endgroup$ Commented Jun 7, 2012 at 21:12
  • $\begingroup$ I liked the response too ;-) but since the question was to get exactly the same structure I deleted it. I tried first something else with Unevaluated and didn't understand why this did not work. It seems Rojo has the answer. $\endgroup$
    – halirutan
    Commented Jun 8, 2012 at 4:08
  • $\begingroup$ @halirutan I gave Rojo's an upvote. I would have for yours as well, were it not deleted. Unevaluated is a tricky beast, because one does not have control over when those might get stripped in internal code. As for "exactly" the same structure, yours came quite close and the question left unstated whether renaming, or an extra "wrapper" level, might be acceptable. (Absent such guidance, the appropriate assumption is perhaps that neither is acceptable. But it seems sensible to offer possibilities slightly outside the scope of specification in such cases.) $\endgroup$ Commented Jun 8, 2012 at 14:52
6
$\begingroup$

Seems TreeForm leaks evaluation when formatting, but wrapping an extra Unevaluated seems to solve it. So

e1 := 3 x + 2 (1 + y) z // Unevaluated // Unevaluated // TreeForm

Now it all seems to work

$\endgroup$
4
  • $\begingroup$ Nice one... +1. $\endgroup$
    – halirutan
    Commented Jun 8, 2012 at 4:10
  • $\begingroup$ That looks familiar. :^) $\endgroup$
    – Mr.Wizard
    Commented Jun 8, 2012 at 8:03
  • $\begingroup$ The various solutions are helpful, but what I want is for "TreeForm's formatting to keep the nodes in the same location after the transformation". In other words, the leftmost "Times" would be replaced by "3" but all the nodes would be in the same location. (What I really want is also to delete the left two leaves which now contain "3", so that the tree undergoes a one-step evaluation after 3 is substituted to x but with the nodes that are left (i.e. all the nodes except the left two leaves) in the same place on the screen. But I did not ask for that.) $\endgroup$ Commented Jun 8, 2012 at 16:02
  • $\begingroup$ In the previous comment I should have said "The leftmost Times should have been changed to 9. $\endgroup$ Commented Jun 9, 2012 at 2:22
4
$\begingroup$

Does this work for you:

Unprotect@TreeForm
SetAttributes[TreeForm, HoldFirst]
TreeForm[e1 /. x -> 3]

Mathematica graphics

It has a superfluous TreeForm at the root ... maybe there is a way to remove that?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.