NOT (A AND B) = NOT A OR NOT B, not NOT A AND NOT B
NOT (A AND B) equals NOT A OR NOT B (“not both”), not NOT A AND NOT B, which equals NOT (A OR B) (“neither”). NOT (A AND B) and NOT A AND NOT B differ on two of the four rows, and the engine's equivalence check names the first of them as the counterexample.
The table below sets the two side by side. On the row A = FALSE, B = TRUE, NOT (A AND B) is TRUE (they are not both true) while NOT A AND NOT B is FALSE (B is true); the row A = TRUE, B = FALSE is the mirror image. The equivalence verdict is “not equivalent”, with A = FALSE, B = TRUE replayed as the counterexample, and the two rows that differ are marked.
The correct expansion is De Morgan's law: NOT (A AND B) is NOT A OR NOT B. The operator flips when the negation moves inside. People drop the flip because the negation looks like it distributes the way multiplication does over a sum, and in ordinary algebra it would; in Boolean algebra the dual law applies instead.
In code the slip hides in refactoring: if (!(isAdmin && isOwner)) rewritten as if (!isAdmin && !isOwner) quietly stops rejecting the users who are one but not the other. In policy text, “not both a member and banned” is often written as “not a member and not banned” by someone paraphrasing in a hurry. A truth table, or the equivalence checker, catches it in one step.
right := NOT (A AND B) · outputwrong := NOT A AND NOT B · output Truth table
They differ on this row: #1, #2
| # | A | B | right | wrong |
|---|---|---|---|---|
| 0 | FALSE | FALSE | TRUE | TRUE |
| 1 | FALSE | TRUE | TRUE | FALSE |
| 2 | TRUE | FALSE | TRUE | FALSE |
| 3 | TRUE | TRUE | FALSE | FALSE |
Plain-language reading
Beginnerright is true exactly when the following condition does not hold:
1. both A and B are true
In every other case, right is false.
About the operators:
- NOT reverses a value: true becomes false and false becomes true.
- AND is true only when all of its parts are true.
Intermediateright is true exactly when the following condition does not hold:
1. both A and B are true
In every other case, right is false.
Advancedright is true exactly when the following condition does not hold [negation ¬]:
1. both A and B are true [conjunction ∧]
In every other case, right is false.
Formal notation: ¬(A ∧ B)
The common slip
Pushing NOT through AND without changing AND to OR. The result is the “neither” formula, which is stricter than “not both”: it is TRUE on only one row instead of three.
Questions
Is the same mistake possible with OR?
Yes, in the other direction: NOT (A OR B) is NOT A AND NOT B, not NOT A OR NOT B. The pitfall page on “neither nor” covers that half, and the De Morgan law page proves both.
How do I check my own rewrite?
Put the original and the rewrite into the equivalence checker. It reports “equivalent” on every row, or the first row on which they differ with the values of both formulas.
Related
Worked examples
- The De Morgan slip: NOT (A AND B) vs NOT A AND NOT B
- De Morgan in code: !(a && b) refactored to !a || !b, verified
Tools
- Logical equivalence checker: two expressions, exact verdict, counterexample
- Truth table generator: any Boolean expression, up to 12 variables, with intermediate columns
Practice
See also
- De Morgan's laws: NOT (A AND B) = NOT A OR NOT B, with proof and examples
- “Neither A nor B” is NOT A AND NOT B
- The De Morgan slip: NOT (A AND B) vs NOT A AND NOT B
- De Morgan in code: !(a && b) refactored to !a || !b, verified
- Lesson 6: De Morgan’s laws (intermediate, 12 min)
- Logical equivalence checker: two expressions, exact verdict, counterexample
Pitfalls
Generated from the Tangibool engine, semantics tangibool-semantics/1, engine 1.0.0, build . Every table, map, simplification and verdict on these pages was computed by the Tangibool engine when the site was built, and every claim was re-checked by the same exact checker the app uses. Limits are stated where they apply. © 2026 Foreranger LTD.