6
$\begingroup$

I (think I) understand the difference between == (semantic) and === (syntactic). So when comparing != and =!= I was expecting a similar difference. So can anyone explain why the third line in this code gives a different result than the other three lines?

Sin[g[u]] /. f_[x__] /; f == Sin -> {f, x}
Sin[g[u]] /. f_[x__] /; f === Sin -> {f, x}
Sin[g[u]] /. f_[x__] /; f != Tan -> {f, x}
Sin[g[u]] /. f_[x__] /; f =!= Tan -> {f, x}
$\endgroup$
  • $\begingroup$ So you're question really is just why doesn't Sin != Tan evaluate to True? $\endgroup$ – Michael E2 Aug 13 '17 at 21:42
  • $\begingroup$ @MichaelE2 If that is what is going on, then that is my question $\endgroup$ – GambitSquared Aug 13 '17 at 21:43
  • $\begingroup$ Yes, the pattern replacement does not happen because Sin != Tan does not evaluate to True. That's an answer to one question, I suppose. Another question is why doesn't Sin != Tan evaluate. I suppose symbols do not have a fixed value: try Block[{Sin = Tan}, Sin != Tan]. (The exact circumstances for == and != to evaluate are a little vague to me.) $\endgroup$ – Michael E2 Aug 13 '17 at 21:46
  • 1
    $\begingroup$ Strange (minor) exceptions: Note that if x has no value, x != x returns False even though it is not guaranteed to be false: It's not False if x is set to Indeterminate, Undefined, or a value that changes every time x is evaluated -- maybe there are other cases. Similarly for ==. The case x != x is covered in the docs (False if the two sides are "identical"), but it seems inconsistent with "Unequal returns True if elements are guaranteed unequal...." $\endgroup$ – Michael E2 Aug 14 '17 at 10:40
  • 1
    $\begingroup$ @Michael, I suppose this is a bit similar to IEEE's convention that NaN is not equal to itself. $\endgroup$ – J. M. is away Aug 14 '17 at 19:26
12
$\begingroup$

The Sin!=Tan rule is unevaluated, since there is not enough data to decide whether Sin and Tan may yield the same information. If they're not given arguments they're simply symbols. And != doesn't check for exact symbol equivalence, from the documentation "Unequal returns True if elements are guaranteed unequal, and otherwise stays unevaluated."

Evaluate: Sin!=Tan on its own and you get back unevaluated Sin!=Tan. There's not enough information for Mathematica to decide if the Symbols may yield something that is equivalent, so it stays unevaluated and thus doesn't trigger the conditional on the rule.

You may be confused because you know Sin[x] and Tan[x] mean different things. (Though recognize Sin[0]==Tan[0]).

Note: Sin=!=Tan absolutely evaluates to True as they are not the exact same symbol. UnsameQ returns True unless the expressions on the lhs and rhs are strictly identical. (documentation)

$\endgroup$
12
$\begingroup$

Mathematica is a symbolic language. In practice, this often means that you can write expressions that cannot be immediately computed without triggering any errors.

In other languages x+1 makes no sense if x has no numerical value. In Mathematica x+1 simply stays unevaluated until x gets a value.

This applies to == as well. In a!=b, a and b are considered mathematical variables. It can't be decided whether a!=b is True or False until you give explicit values to a and b.

All this means that you must be careful when using constructs that expect a True or False value. You could accidentally be passing in a value that is neither True nor False and still not trigger an error, the same way as x+1 does not trigger an error despite x not having a value. Different constructs behave differently in this situation, but the two typical approaches are:

  • Treat anything that isn't True as False. This is the case with Condition and explains your results. Sin != Tan is not True. It just stays unevaluated, therefore it is treated as False by Condition.

  • Simply do not evaluate. This is the case e.g. with If:

     If[x == y, 1, 2]
     (* If[x == y, 1, 2] *)
    

    If in fact has a fourth argument which lets you explicitly handle values that are neither true nor false.

Other approaches to deal with this consequence of the symbolic nature of the language is to have functions which always evaluate to True or False, no matter what their argument. Functions with names ending in Q are almost always like this. === is called SameQ, and it always evaluates. DirectedGraphQ also always evaluates: if you pass in a non-graph value, it returns False (you can think of it like this: something that is not a graph cannot be a directed graph). A very common mistake is to assume that some functions stay unevaluated in the same way as x+1 when in fact they don't, e.g. EvenQ[x] or OddQ[x] immediately evaluate to False if x has no value.

There is also a function, TrueQ, that serves to explicitly convert anything not True to False.

$\endgroup$
  • 2
    $\begingroup$ If == and != always evaluated, we'd never be able to use them in Solve[], Reduce[], etc. $\endgroup$ – J. M. is away Aug 14 '17 at 8:14
  • 2
    $\begingroup$ "If in fact has a third argument..." I think you mean 4th argument, but good point nonetheless. $\endgroup$ – Sjoerd Smit Aug 14 '17 at 8:40
  • $\begingroup$ @SjoerdSmit Thanks! I didn't count the first one :-) $\endgroup$ – Szabolcs Aug 14 '17 at 8:47
  • $\begingroup$ Not giving an explicit value is not a problem with Sin==Sin, this evaluates to True... $\endgroup$ – GambitSquared Aug 14 '17 at 11:10
  • 2
    $\begingroup$ @ImreVégh I don't understand your point. Is it not clear that this is True regardless of the symbol's value? $\endgroup$ – Szabolcs Aug 14 '17 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.