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.

Suppose I have an expression of the form

a b c d + x y z

The FullForm of this is

Plus[Times[a,b,c,d], Times[x,y,z]]

Now suppose I want to set all expressions containing the product b*c to zero. The naive way of doing this is

a b c d + x y z /. Times[___, b, c, ___] -> 0

However, this doesn't work - nothing is replaced.

(Background info: I'm expanding some term using Series, and would like to cancel out all products dx*dy, so that only first-order terms remain.)

Even more confusing: if I don't use Times but a generic function f it works - even when I assign all the attributes of Times to f!

f;
SetAttributes[f, #]& /@ Attributes[Times];
Attributes[f]
f[a, b, c, d] /. f[___, b, c, ___] -> 0

==>
{Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected}
0

(If you evaluate this use a new kernel, as f will be Protected.)

So: how do I replace expressions containing some product*?

*: Assuming the order of the arguments is known. Don't worry about the fact that the expression for b might be on the left of the one for a; solving this would be another question.

share|improve this question
    
Feel free to roll back the question title... –  Yves Klett Dec 3 '12 at 11:08
add comment

2 Answers

up vote 11 down vote accepted

Ok, here is the why: patterns do evaluate, just like other expressions. Therefore:

Times[___, b, c, ___]

gives

(*  b c ___^2  *)

even before the pattern-matching is attempted. In this form, the pattern of course does not match. Use HoldPattern to prevent that:

a b c d+x y z/.HoldPattern[Times[___,b,c,___]]->0

(* x y z *)
share|improve this answer
    
@YvesKlett Yes, because the two named underscores are syntactically different. So, the pattern does evaluate, but no non-trivial transformation (like raising to a power) can be applied,thus it remains valid for the replacement. –  Leonid Shifrin Dec 3 '12 at 11:17
    
just saw the ___^2 part and deleted the comment - reading helps! –  Yves Klett Dec 3 '12 at 11:18
add comment

Is this ok ?

expr = a b c d + x y z;
Replace[expr, Times[before___, b, c, after___] -> zero, Infinity] 
(* x y z + zero *)

The main point is that the rest of the factors should be named; this works too :

a b c d + x y z /. Times[before___, b, c, after___] -> 0
share|improve this answer
    
Can you explain why the named pattern works? –  Yves Klett Dec 3 '12 at 10:58
    
No, never had this issue, I always put names. I hope the experts will have an explanation. –  b.gatessucks Dec 3 '12 at 11:03
add comment

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.