Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have an expression where I want to replace L but not L[_]

For example, the following doesn't work and

sub = {L :> 2};
L + L[tilde] /. sub
(* 2 + 2[tilde], but I want 2 + L[tilde]*)

Is there a simple variation on the substitution pattern for this to work? I tried things like sub = {L_Symbol :> 2} but couldn't figure it out.

share|improve this question
    
Strongly related: (25538) –  Mr.Wizard Sep 25 '13 at 20:33

2 Answers 2

up vote 20 down vote accepted

You can use

Replace[L + L[tilde], L -> 2, {0, Infinity}, Heads -> False]

in this case. Heads -> False is the default, so you don't need to specify it explicitly.

See here for the difference between Replace and ReplaceAll.


Regarding your question about whether it can be done using patterns only, with ReplaceAll or ReplaceRepeated:

First notice that an L -> ... replacement will replace every occurrence of L, regardless of whether it's in a head or not. How can we prevent it from acting on L[_]? The answer: by replacing L[_] before L -> ... has a chance to act:

L + L[tilde] /. {e : L[_] :> e, L -> 2}

Note the ordering of rules: e : L[_] :> e comes first, so it's applied first. Once it's applied, the following rule(s) won't change its result.


Edit from Mr.Wizard

I like to use rule precedence for these kinds of things. (Second method above.) Assuming that we wish to skip L[1,2] as well as L[1] we can use a shorter and faster pattern:

L + L[tilde] /. {x_L :> x, L :> 2}
2 + L[tilde]

Other examples:

A major difference between this method and Replace is that ReplaceAll and Replace traverse the expression in a different order. See (9233). Because of this the rule precedence method will skip expressions with the head L and everything inside them. This may or may not be desirable. The method should be selected based on the specific behavior you desire.

share|improve this answer
    
Thanks. Is there a way to do it with patterns alone? I end up using this substitution in a bunch of places with a ReplaceRepeated and a union of rules, etc. and the //. notation is pretty convenient. –  jlperla Sep 25 '13 at 18:52
    
@jlperla See my edit. If you don't have a very good reason to use the same symbol both as a head and as a "free" symbol, I'd recommend simply not to do it. –  Szabolcs Sep 25 '13 at 18:57
    
I hear you, but I think I have a decent enough reason for notation. Can I add on a predicate to test if it is a head? I tried adding a predicate like HeadQ[x_] := MatchQ[Head[x], Symbol] and then tried the substitution as sub = {L?HeadQ :> 2}, but that didn't work. –  jlperla Sep 25 '13 at 19:02
    
@jlperla No, I'm fairly sure that this is not possible. The pattern itself is not aware of its surroundings (but the function doing the replacement might be, e.g. the Heads option in several functions). When choosing notation, keep in mind that it has to be suitable both for the computer and for the human reader, not only the human reader. –  Szabolcs Sep 25 '13 at 19:03
    
Thanks! This seems to work beautifully, including with a Union and a rule to replace L[tilde]. And screw the computer! I have actually gotten a beautiful whiteboard output from code given to me in: mathematica.stackexchange.com/questions/30884/… –  jlperla Sep 25 '13 at 19:08

Here is an alternative solution, which is less elegant than the one by Szabolcs, but more in the spirit of your questions about querying the surrounding environment:

MapIndexed[
   If[#2 === {} || Last[#2] != 0, Replace[#, L -> 2], #] &, 
   L + L[tilde], 
   {0,Infinity}
]

Basically, it tests whether or not the expression is a head. If it is, the element is left unchanged, while if it is not, the replacement is performed.

Note that this solution, as written, has a significant flaw that it will not work inside held expressions, while Szabolcs's solution is free of this limitation. The present one can be modified to also be able to do it, but the code will be more complex.On the other hand, here you do know where in the expression you are, for any given match. Therefore, in principle, you can perform more complex queries, not directly possible by Szabolcs's method - such as e.g. querying parent heads etc.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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