If Condition Simplification

Viewed 157

I'm refactoring a code snippet in which I see the following condition that I wonder whether it's simplified.

data.RecordId != 0 || (data.RecordId == 0 && data.SerialNum == "0000")

Isn't data.RecordId == 0 || data.SerialNum == "0000" same of that?

If it is possible, how come? Could you detailed?

7 Answers

yes, it's possible, assuming you had a typo (!= not ==)...

let Wolfram Alpha explain:

https://www.wolframalpha.com/input/?i=simplify%3A+R+%21%3D+0+%7C%7C+%28R+%3D%3D+0+%26%26+S%3D%3D+0000%29

R!=0 ∨ (R = 0 ∧ S = 0)

is simplyfied as:

R!=0 ∨ S = 0

the explaination step by step:

https://en.wikipedia.org/wiki/Boolean_algebra#Laws Distributivity of ∨ over ∧ says:

x v (y ∧ z) = (x ∨ y) ∧ (x ∨ z)

in you case:

R! ∨ (R ∧ S) = (R! ∨ R) ∧ (R! ∨ S)

where (R! ∨ R) is always true and you can ommit it as the 1st operand in the and logic:

R! ∨ (R ∧ S) = true ∧ (R! ∨ S)

R! ∨ (R ∧ S) =  (R! ∨ S)

voilá

But I see another kind of runtime difference that deals with the shortcut evaluation of &&:

if data.RecordId == 0 is false in the longer expression, it will not evaluate the right part with data.SerialNum, which can avoid getting a null ref.

You could just say:

data.RecordId != 0 || data.SerialNum == "0000"

The data.RecordId == 0 check is unnecessary, we've already determined that data.RecordId != 0 doesn't hold, so it follows that data.RecordId == 0 is true. Remember that boolean conditions are evaluated from left to right, and they short-circuit: in the case of an ||, evaluation stops if the first condition is true.

Another way to look at it is by using boolean logic, symbolically your expression can be represented and simplified as follows:

1. ¬p ∨ (p ∧ q)
2. (¬p ∨ p) ∧ (¬p ∨ q)
3. true ∧ (¬p ∨ q)
4. ¬p ∨ q
  • p represents the condition data.RecordId == 0
  • q represents the condition data.SerialNum == "0000"
  • In line 1 we apply the distributive property
  • In line 2 we apply the identity that states that ¬p ∨ p is always true
  • In line 3 we apply the identity that says that true ∧ p is p
  • And that's how we arrive at the simplification of line 4
if(data.RecordId != 0)

then

(data.RecordId == 0)

will be true. so no need to mention that just

data.RecordId != 0 || data.SerialNum == "0000"

is enough.

Well, for

data.RecordId != 0 || (data.RecordId == 0 && data.SerialNum == "0000")
  • If data.RecordId != 0 we return true.
  • If data.RecordId != 0 fails, the only option is data.RecordId == 0 and thus check for it is redundant

So we can drop data.RecordId == 0:

data.RecordId != 0 || (data.SerialNum == "0000")

Or

data.RecordId != 0 || data.SerialNum == "0000"

Yes, it could be

data.RecordId != 0 || data.SerialNum == "0000"

But, from your condition 1, data.SerialNum == "0000" should be validated only when data.RecordId == 0 is true. What if data.RecordId is other than 0.

So, this one is correct for the above case

data.RecordId != 0 || (data.RecordId == 0 && data.SerialNum == "0000")

Well, simple explanation is like:

When we got data.RecordId != 0 || (data.RecordId==0 ...) the first part (data.RecordId != 0) says anything except 0 means true. if it is not, then we will go for second part (data.RecordId==0) and definitely when we are here, value of data.RecordId would be 0 and means always true. (because we check everything except 0 in first part of condition).
So then the only valuable part of second condition is data.SerialNum == "0000 and the we would have

data.RecordId != 0 || data.SerialNum == "0000"

No it would not necessarily by the same as ==0 is checking for int value and "0000" is checking for string value

Related