Reputation: 53850
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
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
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
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