# Remove all "not equal" clauses from an expression

I am banging my head against the following question: how can I have Mathematica take

cond = 2 a >= 3 b && 70 a >= 19 && 20 a != 13;


and eliminate all the "not equal" clauses, returning:

cond = 2 a >= 3 b && 70 a >= 19;


?

Some background to my question. I am manipulating expressions that are list of inequalities, e.g.

cond = 2 a > 3 b && 70 a > 19 && 20 a != 13;


I need to convert such expressions to weaker forms, which geometrically corresponds to closure of the region. Replacing strict inequalities by weak is easy:

cond = cond /.{Less -> LessEqual, Greater -> GreaterEqual};


But I also need to remove all the "not equal" clauses, and I can't understand how to do this, or how I could even search for this in the documentation. Would any kind soul around here be able to help me? I found that I can do:

Select[cond, Head[#] == Unequal &]


which returns "20 a != 13". But then I'm stuck. I want the rest of the expression, not the "not equal" clause itself!

Thank you!

• Does DeleteCases[..., _Unequal] do the job? Sep 29, 2014 at 20:29
• And try DeleteCases[cond, _Unequal, {0, -1}] if not. Sep 29, 2014 at 20:32
• Or DeleteCases[cond, HoldPattern[Unequal[__]]]
– Bill
Sep 29, 2014 at 20:33
• A more meaningful substitution: /. _Unequal -> True. It should work in any boolean expression, e.g. a > 5 || a != b. Sep 29, 2014 at 20:38
• All of these work! Thanks, everyone. I wish I had enough "reputation" to upvote comments! Sep 30, 2014 at 15:09

cond = 2 a >= 3 b && 70 a >= 19 && 20 a != 13;


Replace the symbol Unequal with something else (which better be a function):

Replace[cond, Unequal -> (True &), {0, Infinity}, Heads -> True]
Replace[cond, Unequal -> (## &[] &), {0, Infinity}, Heads -> True]
cond /. Unequal -> (True &)
cond /. Unequal -> (## &[] &)
Block[{Unequal = (True &)}, cond]
Block[{Unequal = (## &[] &)}, cond]


Replace stuff with Head Unequal with something else:

Replace[cond, _Unequal :> (## &[]), {0, Infinity}] (* or _Unequal :> Sequence[] *)
cond /. _Unequal :> (## &[])
cond /. _Unequal :> (True)
DeleteCases[cond, _Unequal]


all give

2 a >= 3 b && 70 a >= 19

Replace[cond, {LessEqual -> Less, GreaterEqual -> Greater, Unequal -> (True &)},
cond /. {LessEqual -> Less, GreaterEqual -> Less, Unequal -> (True &)}

2 a<3 b&&70 a<19

• Rule/RuleDelayed have SequenceHold, so no need to use ## &[]--you can just as well write Sequence[]. I do prefer replacing it with True, though, particularly as this cannot introduce problems when the expression is only subjected to partial evaluation. Sep 29, 2014 at 21:36
• Thank you @Oleksansr. WFIW, while ##&[] and ##&[]& worked for _Unequal and Unequal, respectively, (similarly, for True and True&), i noticed Sequence[] and Sequence[]& did not.
– kglr
Sep 29, 2014 at 22:18
• Thanks! This is great. I can now not only solve my specific problem, but I have 10 slightly different ways of doing this, which gives me a much better understanding of what's happening behind the scenes in Mathematica's world. For someone like me who "grew up" on C/C++ and then MatLab, it's very confusing at first. Sep 30, 2014 at 15:08
• @Michael, thank you for the Accept. Welcome to mma.se.
– kglr
Sep 30, 2014 at 15:09

I believe the rule you' want is

Unequal[a_, b_] -> Sequence[]


I tried Unequal[__] -> Sequence[] but it didn't seem to work.

When mathematica sees Sequence[args] inside of some other head, it knows to splice args in place into the arguments of that head. In this case, Sequence[] has no arguments, and so Mathematica replaces Unequal clauses with nothing, effectively deleting it.

• This is because Unequal[__] evaluates to True. Try _Unequal or HoldPattern[_ != _] instead. Sep 29, 2014 at 20:34
• Cool, thanks for the insight. I didn't know about this Sequence thing. Sep 30, 2014 at 15:10
• @Michael, sure thing! Sep 30, 2014 at 17:42
• @Mr.Wizard, aha! That explains a few pattern-matching mysteries I've experienced! +1. Sep 30, 2014 at 17:43
Delete[cond, Position[cond, _Unequal]]

• This works, too! Thanks! Sep 30, 2014 at 15:10