# Replacing product expressions - named vs. unnamed pattern?

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.

-
Feel free to roll back the question title... –  Yves Klett Dec 3 '12 at 11:08

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 *)

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

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

-
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