Sergei Basharov
Sergei Basharov

Reputation: 53850

How to make sure that two logic and comparison operations are equal?

I see a logical and comparison operation in the code and I feel like it can be simplified.

Simply put, it looks like:

if (!a || !(b || c)) {...}

But I think it's the same as

if (!a || !b || !c) {...}

How should I do in this situation? I suppose I can see more operations like this in existing code I have to deal with. Are there rules to simplify/optimize such operation aside from manual checking?

Upvotes: 0

Views: 44

Answers (3)

MattClarke
MattClarke

Reputation: 1647

As a general technique for approaching this type of boolean refactoring, if you don't trust your own ability to construct truth tables, how about writing some code along these lines:

for a in {true, false}
  for b in {true, false}
    for c in {true, false}
      if (!a || !(b || c)) <> (!a || !b || !c)
      then exit with message "Not equivalent"
    end
  end
end

The if condition can of course be replaced with whatever two expressions you are trying to test.

Upvotes: 0

starmole
starmole

Reputation: 5068

The question is if !(b || c) us the same as !b || !c. Try a simple truth table:

b   c  !(b||c)  !b||!c
0   0    1         1
0   1    0         1
1   0    0         1
1   1    0         0

So they are not the same.

Upvotes: 0

Paul
Paul

Reputation: 141839

You can apply DeMorgan's law to get:

if (!a || (!b && !c)) {...}

Which, because of && having higher precedence than ||, is the same as:

if (!a || !b && !c) {...}

However that whole conditions seems very negative, and it is almost always easier to read positive conditions, perhaps it would be better written as:

// This is the negation of your condition after applying DeMorgan's law
if ( a && (b || c) ) {
    // return or throw error
}

... // What you would've done in the if statement

Upvotes: 1

Related Questions