# Is there a function which tests whether a Boolean expression is an inequality?

For something I am doing in Mathematica, it would be very helpful to have a function f[] which, when applied to an atomic Boolean expression, returns True if the Boolean expression is an inequality, and returns false if the Boolean expression is not an inequality.

For example:

f[0 == 1] ought to be False, since 0 == 1 is not an inequality.

f[0 != 1] ought to be True, since 0 != 1 is an inequality.

What is the best to define such a function f[] in Mathematica? I had hoped it would already exist, with a name like InequalityQ[], but I have not been able to find such a function already defined in Mathematica.

Thanks for your help.

• How about TrueQ ? !Mathematica graphics Commented May 27, 2023 at 19:25
• I believe TrueQ tests for whether an expression is true, not whether the expression is an inequality. For example, TrueQ[0==0] would return True, while for the function f[] that I am asking for, we would have f[0==0] return False. Commented May 27, 2023 at 19:27
• Ah, so you mean you want to check if expression has literally != in it? The problem is that Mathematica immediately evaluates 1 != 0 to True. So your expression will not actually have != left in it (this assumes ofcourse that the values are all numerical). For symbols, you can check if the Head is Unequal , i.e. Head[x != y] == Unequal gives True Commented May 27, 2023 at 19:30
• try ClearAll[f]; SetAttributes[f, HoldFirst]; f[exp_] := MemberQ[Head[Unevaluated[exp]]]@{Unequal, Less, Greater}?
– kglr
Commented May 27, 2023 at 19:35
• What is an "atomic Boolean expression"? Can you give an example please? I have trouble imagining a Boolean expression that is atomic in Mathematica. Commented May 27, 2023 at 19:42

It would be nice to know why you think you need this, because it seems very strange. Short answer is "no", there is no InequalityQ. But we could define our own. I'll actually define two functions to handle different meanings of "inequality".

SetAttributes[{UnequalQ, InequalityQ}, HoldAll];
UnequalQ[expr_] := Unequal === Head[Unevaluated[expr]];
InequalityQ[expr_] := MemberQ[{Unequal, Less, Greater}, Head[Unevaluated[expr]]]


Trying them out:

UnequalQ[1 != 2] (* True *)
InequalityQ[1 != 2] (* True *)
InequalityQ[a < b] (* True *)
InequalityQ[a <= b] (* False *)
InequalityQ[a == b] (* False *)
UnequalQ[a == b] (* False *)


But this is pretty close to useless, because you can't apply it to any expressions that could evaluate before being handled by our functions. For example:

UnequalQ /@ {1 != 2}
(* {False} *)


You also can't use them for expressions where you might want partial evaluation:

MyExpr = a != b;
UnequalQ[MyExpr]
(* False *)


So, unless you're going to explicitly hold every expression somehow, or you're just going to explicitly type the (in)equalities in full as arguments, this isn't very useful. You might as well just use your eyeballs.

• Thank you. This appears to be the same approach suggested in comments by kglr before your post, though. A small modification of kglr's approach worked quite well for me. Is it considered proper etiquette on this site to accept your answer? I have seen question-askers encourage people who answer in comments to post their comments as answers so they can get "credit" in the form of an accepted answer, so I am not sure what I ought to do. Commented May 28, 2023 at 1:20
• You asked about the purpose of InequalityQ[]. It is quite natural in birational geometry: you have an quasi-affine algebraic set defined by a large family of polynomial constraints (equalities and inequalities, e.g. output of Reduce[]). Satisfying a polynomial inequality is an open condition in the Zariski topology, so if you only care about the birational equivalence class of the algebraic set, you can simply omit all those inequalities satisfied in a positive-codimension subset. For high-dimensional problems this can yield dramatic improvement in run-time for later calculations. Commented May 28, 2023 at 1:25
• I don't have an answer to your etiquette question. As far as I can tell it's all over the place whether something ends up as a comment or answer and whether answers get accepted or not. I don't care about getting the reputation points. If @kglr wants to write up an answer and you'd prefer to accept that one, I'll delete my answer. FWIW, I didn't plagiarize. Commented May 28, 2023 at 2:37
• As for your explanatory comment, what I gather is that you have boolean expressions that don't resolve to True or False because they use undefined symbols. In that case you don't even need the HoldAll attribute, and all you need to do is look at the heads of the expressions. I think you threw off a lot of us by using 0 != 1 as your example. Commented May 28, 2023 at 2:42
• I have accepted your answer. Thanks again. As for your second comment: I am sorry my injudicious choice of example muddied the waters. Commented May 31, 2023 at 13:10