# MatchQ[x y, (x | y) (x | y)] returns False

MatchQ[x y, (x | y) (x | y)]


It returns false. Why?

I want to eliminate terms like x^2, y^2, z^2, x y, x z, y z.

• I think because (x | y) (x | y) evaluates to (x | y)^2, which doesn't match your expression. – march Jun 13 '16 at 4:04
• What do you mean by "I want to eliminate terms like x^2, y^2, z^2, x y, x z, y z"? – xzczd Jun 13 '16 at 4:04
• Does MatchQ[#, _^2 | a_ b_] & /@ {x^2, y^2, z^2, x y, x z, y z} do what you want? Your post needs more information, because there is an inconsistency between the terms you want to eliminate and the patterns you are making. Do you want to eliminate any second-degree monomial? Or do you want to eliminate any second-order monomial that involves x or y? (or x or y and nothing else)? – march Jun 13 '16 at 4:06
• Btw: MatchQ[x y, HoldPattern[(x | y) (x | y)]] – Kuba Jun 13 '16 at 8:22
• For more info, the reason @Kuba 's method works is to avoid the problem march mentioned. – QuantumDot Jun 13 '16 at 9:19

If you Trace the evaluation sequence of this expression, you get the following:

Trace@MatchQ[x y, (x | y) (x | y)]
(* {{(x|y) (x|y), (x|y)^2}, MatchQ[x y, (x|y)^2], False} *)


This shows that (x|y) (x|y) gets evaluated to (x|y)^2 before the pattern matching occurs, and x y doesn't match (x|y)^2, although x^2 and y^2 will:

MatchQ[#, (x | y) (x | y)] & /@ {x^2, y^2, z^2, x y, x z, y z}
(* {True, True, False, False, False, False} *)


If you really want all of the expressions in that list above to match, I would do something like

MatchQ[#, a_ b_ | a_^2] & /@ {x^2, y^2, z^2, x y, x z, y z}
(* {True, True, True, True, True, True} *)

• If the user wants to capture only x and y, a little work is required: MatchQ[#, a_ (b_ /; MatchQ[b, x | y]) | a_^2 /; MatchQ[a, x | y]] &. – rcollyer Jun 13 '16 at 21:06
• @rcollyer. Or MatchQ[#, a_ b_ | a_^2 /; And[Or[a == x, a == y], Or[b == x, b == y]]] &. – march Jun 13 '16 at 21:07

I guess what you want is to create a function that can match something like $x x$ or $x y$ in a simple way.

f = Function[{t, l}, With[{pat = Alternatives @@ l},MatchQ[Unevaluated@t, HoldPattern[pat pat]]],HoldFirst];
f[x x, {x, y, z}]
f[x z, {x, y, z}]


Also, I think you would love to use something like Map:

f[#, {x, y, z}] & /@ (Unevaluated /@Unevaluated[{x x, x y, y y, z y}])


Can this help?

Thank you everyone!

Eventually I found the solution at Dropping Higher Order Terms in symbolic evaluation.

The one using

Normal[Series[expr /. Thread[vars -> t*vars], {t, 0, 10}]] /. t -> 1


My final code (for getting the components of the Riemann tensor of a certain weak gravitational field) became.

Needs["GREATER2"];
X = {t, x, y, w};
ds2 = -(1 + 2 \[Phi][t, x, y, w]) dt^2 + (1 - 2 \[Phi][t, x, y, w]) (dx^2 + dy^2 + dw^2);
Gdd = Metric[ds2, X];
termPattern = Join[{\[Phi][t, x, y, w]}, Flatten[D[\[Phi][t, x, y, w], {{t, x, y, w}, 1}]], Flatten[D[\[Phi][t, x, y, w], {{t, x, y, w}, 2}]]];
Result = Raise[Riemann[Gdd, X], 1, Gdd];
ResultFirstOrder = Normal[Series[Result /. Thread[termPattern -> i*termPattern], {i, 0, 1}]] /. {i -> 1, \[Phi]_[t, x, y, w] -> \[Phi]}
`