# 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. Jun 13, 2016 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"? Jun 13, 2016 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)? Jun 13, 2016 at 4:06
• Btw: MatchQ[x y, HoldPattern[(x | y) (x | y)]]
– Kuba
Jun 13, 2016 at 8:22
• For more info, the reason @Kuba 's method works is to avoid the problem march mentioned. Jun 13, 2016 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]] &. Jun 13, 2016 at 21:06
• @rcollyer. Or MatchQ[#, a_ b_ | a_^2 /; And[Or[a == x, a == y], Or[b == x, b == y]]] &. Jun 13, 2016 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]}
`
• ...this turned out to be an XY problem. Why didn't you ask about this to begin with? Jun 14, 2016 at 5:39