Leave expression tree formatting the same when a replacement rule is applied

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?

-
–  Mr.Wizard Jun 8 '12 at 8:04
SixWingedSeraph, please start accepting answers for some of your questions. –  Mr.Wizard Jun 8 '12 at 8:07

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

e1 /. x -> "3"


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]]

-

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]


-
I had to look up Release on the documentation. Old habits die hard? –  Michael Wijaya Jun 7 '12 at 21:12
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. –  halirutan Jun 8 '12 at 4:08
@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.) –  Daniel Lichtblau Jun 8 '12 at 14:52

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

-
Nice one... +1. –  halirutan Jun 8 '12 at 4:10
That looks familiar. :^) –  Mr.Wizard Jun 8 '12 at 8:03
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.) –  SixWingedSeraph Jun 8 '12 at 16:02
In the previous comment I should have said "The leftmost Times should have been changed to 9. –  SixWingedSeraph Jun 9 '12 at 2:22
Unprotect@TreeForm

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