Lesson 6: De Morgan’s laws (intermediate, 12 min)
How to move a NOT through AND and OR without changing the meaning: negating a conjunction gives a disjunction of negations, and the other way round. Four steps, intermediate level, about twelve minutes, ending in negation normal form.
Push NOT through AND and OR correctly: negating a conjunction gives a disjunction of negations, and vice versa.
The first step negates a door rule: NOT (has_key AND knows_code) is NOT has_key OR NOT knows_code, the door stays shut when either is missing. The second negates an OR: NOT (member OR invited) is NOT member AND NOT invited, neither one nor the other. The third step is the classic slip, NOT A AND NOT B offered as the negation of A AND B, shown wrong on a specific row. The fourth applies the laws repeatedly to NOT ((A OR B) AND C), reaching NOT (A OR B) OR NOT C and then (NOT A AND NOT B) OR NOT C, where every NOT sits on an input.
The lesson carries five verified claims: both laws, the slip's non-equivalence, and the two rewriting steps of the nested example. The exercises ask you to push NOT inward in two expressions, to find the assignment that exposes the slip, and to classify NOT (A OR B) <-> (NOT A AND NOT B), which is a tautology because the law holds on every row.
Negation normal form, the end point of the fourth step, is the first stage of the engine's normal-form converter and of its NAND-only and NOR-only constructions; the De Morgan law page proves both identities and the pitfall pages on “not over AND” and “neither nor” are the two halves in isolation.
Do this lesson interactively in the app
Steps
1. NOT over AND
A door opens with the key and the code. It stays shut when that is not the case: NOT (has_key AND knows_code).
By De Morgan, this is the same as NOT has_key OR NOT knows_code: the door stays shut if either part is missing. The AND becomes an OR when the NOT moves inside.
stays_shut := NOT (has_key AND knows_code) · outputrewritten := NOT has_key OR NOT knows_code · output has_key: the person has the key; knows_code: the person knows the code;
| # | has_key | knows_code | stays_shut | rewritten |
|---|---|---|---|---|
| 0 | FALSE | FALSE | TRUE | TRUE |
| 1 | FALSE | TRUE | TRUE | TRUE |
| 2 | TRUE | FALSE | TRUE | TRUE |
| 3 | TRUE | TRUE | FALSE | FALSE |
Compare stays_shut with rewritten: the checker proves them equivalent.
equivalent stays_shut / rewritten · holds
2. NOT over OR
“Neither a member nor invited” is NOT (member OR invited).
De Morgan’s second law: this equals NOT member AND NOT invited. The OR becomes an AND: neither … nor means that both are missing.
neither := NOT (member OR invited) · outputboth_missing := NOT member AND NOT invited · output member: the person is a member; invited: the person has an invitation;
| # | member | invited | neither | both_missing |
|---|---|---|---|---|
| 0 | FALSE | FALSE | TRUE | TRUE |
| 1 | FALSE | TRUE | FALSE | FALSE |
| 2 | TRUE | FALSE | FALSE | FALSE |
| 3 | TRUE | TRUE | FALSE | FALSE |
Make neither TRUE. In how many of the four rows is it TRUE?
equivalent neither / both_missing · holds
3. The classic slip
It is tempting to “distribute” the NOT without flipping the operator, but NOT (A AND B) is not NOT A AND NOT B.
They disagree, for example, when A=TRUE, B=FALSE: the first gives TRUE, the slip gives FALSE. Whenever you move a NOT inside, swap AND and OR.
correct := NOT (A AND B) · outputslip := NOT A AND NOT B · output | # | A | B | correct | slip |
|---|---|---|---|---|
| 0 | FALSE | FALSE | TRUE | TRUE |
| 1 | FALSE | TRUE | TRUE | FALSE |
| 2 | TRUE | FALSE | TRUE | FALSE |
| 3 | TRUE | TRUE | FALSE | FALSE |
Set A=TRUE, B=FALSE and compare correct with slip.
not-equivalent correct / slip · holds
4. Pushing NOT all the way in
Apply the laws repeatedly to reach negation normal form, where NOT sits directly on inputs:
NOT ((A OR B) AND C) → NOT (A OR B) OR NOT C → (NOT A AND NOT B) OR NOT C.
Each step is an equivalence, so the result is equivalent to the original, and Tangibool confirms it with an exact check.
original := NOT ((A OR B) AND C) · outputmiddle := NOT (A OR B) OR NOT C · outputpushed_in := (NOT A AND NOT B) OR NOT C · output | # | A | B | C | original | middle | pushed_in |
|---|---|---|---|---|---|---|
| 0 | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE |
| 1 | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE |
| 2 | FALSE | TRUE | FALSE | TRUE | TRUE | TRUE |
| 3 | FALSE | TRUE | TRUE | FALSE | FALSE | FALSE |
| 4 | TRUE | FALSE | FALSE | TRUE | TRUE | TRUE |
| 5 | TRUE | FALSE | TRUE | FALSE | FALSE | FALSE |
| 6 | TRUE | TRUE | FALSE | TRUE | TRUE | TRUE |
| 7 | TRUE | TRUE | TRUE | FALSE | FALSE | FALSE |
Compare original with pushed_in, then try an intermediate step of your own.
equivalent original / middle · holdsequivalent original / pushed_in · holds
Exercises
- Rewrite
NOT (member OR invited)so thatNOTapplies only to single inputs. (write-equivalent) - Push the
NOTinNOT (A AND (B OR NOT C))all the way to the inputs. (write-equivalent) - Show that the slip really is wrong: find an assignment where
correctandslipdiffer. (find-assignment) - Classify
NOT (A OR B) <-> (NOT A AND NOT B). (classify)
Do this lesson interactively in the app
Questions
Do the laws work on three or more operands?
Yes: NOT (A AND B AND C) is NOT A OR NOT B OR NOT C, the whole chain flips at once. The engine applies the law to the n-ary gate in one step.
What is negation normal form for?
It is the shape every normal-form conversion starts from, and the shape in which a formula is easiest to read aloud: each NOT applies to one input. The fourth step produces it by hand; the converter does it for you.
Related
Laws
Tools
Practice
See also
- De Morgan's laws: NOT (A AND B) = NOT A OR NOT B, with proof and examples
- NOT (A AND B) = NOT A OR NOT B, not NOT A AND NOT B
- “Neither A nor B” is NOT A AND NOT B
- De Morgan in practice: NOT (A AND B) rewritten and verified
- The De Morgan slip: NOT (A AND B) vs NOT A AND NOT B
- Negation normal form: meaning and examples
- Lesson 7: Simplification laws (intermediate, 12 min)
- Lesson 10: Normal forms: DNF, CNF, minterms, and maxterms (advanced, 15 min)
Lessons
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.