Reduce applied to vectors doesn't work right?

Reduce[{x,0}=={0,0}, x]


gives x==0 as it should, but

Reduce[{x,0}!={0,0}, x]


gives False, which indicates no solution and seems incorrect. What is going on?

Update: I reported the issue to Mathematica; they replied that they know about it and are working on a solution.

Update 2: The above bug is only present in Mathematica 10.0 and 10.1. Mathematica 9.x and 10.2 behave as expected.

• Latter works fine for me on 9.x Win: x!=0 result... – ciao May 31 '15 at 6:49
• @ciao Interesting .... Seems that it doesn't on 10.x I got the same results in the question... – Bichoy May 31 '15 at 6:51
• Something might have changed in the implementation of Equal or Reduce. – Bichoy May 31 '15 at 6:52
• But I believe the 9.x behavior is the correct logical behavior. A list shouldn't be expanded like that. – Bichoy May 31 '15 at 6:57
• Axel, that is interesting behavior indeed. Bichoy has an interesting explanation for what may be happening. I just wanted to suggest that LogicalExpand behaves in the way that you expected Reduce to behave, i.e. LogicalExpand[{x, 0} != {0, 0}] gives x != 0. – MarcoB May 31 '15 at 7:20

From Mathematica documentation:

Reduce[{exp1,expr2,...},vars] is equivalent to Reduce[expr1 && expr2 && ..., var]

Thus, one explanation is that Reduce[{x,0}!={0,0}, x] is being expanded as if {x,0}!={0,0} is the same as {x !=0, 0 != 0}**. Hence, the second expression in Reduce returns False because 0 != 0 reduces to False.

To work around that, another level of listing might be applied:

Reduce[{{x,0}}!= {{0,0}}, x]


which yields x != 0 as expected.

**I did check the documentation for Equal (==), and I couldn't find such behavior documented (I was expecting to find that Equal is Listable for example, but this is not shown by Attributes[Equal]). This behavior might be specific only to Reduce.

• The double list trick is very useful, thanks! The explanation seems plausible; it's curious though that Reduce[{1,0}!={0,0}] gives True! – Axel Boldt May 31 '15 at 8:28
• Reduce[{x,0}!={0,1},x] and Reduce[{x,0,0}!={0,0,1},x] also correctly give True! – Axel Boldt May 31 '15 at 9:03
• @AxelBoldt, you are welcome. There is definitely something wrong with Mathematica here. I think you should report to Wolfram as a bug, or ask for their explanation. Also the fact that this behavior was not in 9.x (check ciao comment on the question, makes it feel more like a bug. – Bichoy May 31 '15 at 15:19
• Proof of the expansion assumption: Reduce[{x, y} != {0, 0}] yields y != 0 && x != 0. Next, fill in y->0. – Sjoerd C. de Vries May 31 '15 at 15:53
• I don't agree that this is a bug, though it's inconsistent behavior over the versions for sure. Nowhere in the documentation is it stated that equations of vectors are possible and should be interpreted in vector terms. I agree that the expansion interpretation isn't documented either. I believe that the current change in behavior may be caused by the addition of the possibility to use geometric region constraints, where we now can say {x,y} $\in$ Circle which may have caused elements like {x,y} to be parsed differently than before. – Sjoerd C. de Vries May 31 '15 at 16:13

A long comment on @Bichoy's answer, which seems quite correct: Reduce first applies Thread on the "vector" (in)equality and the lists are combined with And as pointed out.

Trace[
Reduce[{x, 0} == {0, 0}, x],
TraceInternal -> True]
(*
{Reduce[{x, 0} == {0, 0}, x], {$MessageList = {}, {}}, {Thread[{x, 0} == {0, 0}], {x == 0, 0 == 0}, {0 == 0, True}, {x == 0, True}}, {$MessageList, {}},
{x == 0 && True, And[x == 0], x == 0}, ..., x == 0}
*)

Trace[
Reduce[{x, 0} != {0, 0}, x],
TraceInternal -> True]
(*
{Reduce[{x, 0} != {0, 0}, x], {$MessageList = {}, {}}, {Thread[{x, 0} != {0, 0}], {x != 0, 0 != 0}, {0 != 0, False}, {x != 0, False}}, {$MessageList, {}},
{x != 0 && False, False}, ..., False}
*)


But Reduce applies Thread only once. On Bichoy's insightful workaround, it then compares the elements of the lists with Or:

Trace[
Reduce[{{x, 0}} != {{0, 0}}, x],
TraceInternal -> True]
(*
{Reduce[{{x, 0}} == {{0, 0}}, x], {\$MessageList = {}, {}},
{Thread[{{x, 0}} != {{0, 0}}], {{x, 0} != {0, 0}}}, ...,
{x != 0 || 0 != 0, {0 != 0, False}, Or[x != 0], x != 0}, ...}
*)


Executing the same commands on V9 shows that Reduce does not apply Thread, but compares lists using And for Equal and Or for Unequal (similar to the preceding example).

It seems like a change that will break things, but it's not mentioned on the Reduce documentation page. Perhaps the change should be added to Incompatible Changes since Mathematica Version 7? or Will Version 9 functions all work in Version 10?

• very nice! I got the intuition about what was going on, but could never verify it. BTW, how do I find more about the options of Trace? TraceInternal -> True doesn't seem to be in Trace documentation. (Should we start a new question about Trace and expand on the details of that?) – Bichoy Jun 1 '15 at 1:12
• – Michael E2 Jun 1 '15 at 1:23