# Canonical forms: minterms and maxterms

*The two standard ways to write any truth table as gates*

Canonical forms are the two standard ways to write a logic function straight from its truth table: the sum of minterms (a canonical SOP, one AND term per 1-row, all ORed) and the product of maxterms (a canonical POS, one OR term per 0-row, all ANDed), each of which maps directly onto a two-level gate circuit.

Group: Gates
URL: https://digiwleea.wleeaf.dev/learn/canonical-forms/

A [truth table](https://digiwleea.wleeaf.dev/learn/truth-tables/) fully specifies a function, and [boolean algebra](https://digiwleea.wleeaf.dev/learn/boolean-algebra/) lets you write it as an expression. But the same function can be written countless ways, so which expression do you start from? There are two **canonical** (standard, one-and-only) forms you can read mechanically off any truth table, and each turns directly into a two-level gate circuit. They are the reliable bridge from a table to hardware, and the starting point that [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/) minimization shrinks.

## Minterms and maxterms

A **minterm** is a single AND of every input, each input appearing once, either true or inverted. With `n` inputs there is one minterm per row of the truth table, and it is `1` for **exactly that one row**. A **maxterm** is its mirror: a single OR of every input, true or inverted, that is `0` for exactly one row. They are numbered by the binary value of the row they pick out:

- **Minterm `m_i`**: AND of all inputs, written inverted wherever that input is `0` in row `i`. For three inputs, row `5 = 101` gives `m5 = A·B'·C` (it is `1` only when `A=1, B=0, C=1`).
- **Maxterm `M_i`**: OR of all inputs, written inverted wherever that input is `1` in row `i`. Row `5 = 101` gives `M5 = A' + B + C'` (it is `0` only when `A=1, B=0, C=1`).

> **TIP:** Notice the inversion rule flips between the two. For a **minterm** you invert the inputs that are `0` (so the AND can reach `1` on that row). For a **maxterm** you invert the inputs that are `1` (so the OR can reach `0` on that row). They are exact complements: `m_i' = M_i`. The minterm that is `1` on a row and the maxterm that is `0` on the same row are negatives of each other, which is just De Morgan's law applied to one term.

A concrete way to picture it: a minterm is a precise **full address**. `m5 = A·B'·C` matches exactly one input combination (`101`), the way `221B Baker Street` matches exactly one house. The canonical SOP is then a **guest list**: name every address where the output should be `1`, OR them together, and the circuit admits precisely those rows. The canonical POS is the bouncer's **reject list**: name every address where the output should be `0` (each as a maxterm), AND them together, and the circuit blocks exactly those rows and lets everyone else through. Same door, described by who gets in versus who gets turned away.

## Two ways to read a function off its table

Because each minterm fires on exactly one row, you can build any function by **ORing the minterms of its `1`-rows**: the result is `1` on precisely those rows and `0` everywhere else. That is the **canonical sum of products (SOP)**, written with the sum symbol `Sigma`. Dually, ANDing the **maxterms of its `0`-rows** gives `0` on exactly those rows: the **canonical product of sums (POS)**, written with the product symbol `Pi`. Take this 3-input function `F = A + B·C`:

| A | B | C | F |
| --- | --- | --- | --- |
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 |

_F = A + B·C: 1 whenever A is 1, or both B and C are 1. The 1-rows are 3, 4, 5, 6, 7 (the on-set); the 0-rows are 0, 1, 2 (the off-set). SOP reads the 1-rows, POS reads the 0-rows._

Reading the **1**-rows (`3, 4, 5, 6, 7`) gives the canonical SOP; reading the **0**-rows (`0, 1, 2`) gives the canonical POS:

```
SOP:  F = Sigma m(3,4,5,6,7) = A'BC + AB'C' + AB'C + ABC' + ABC
```

```
POS:  F = Pi M(0,1,2) = (A+B+C)(A+B+C')(A+B'+C)
```

> **KEY:** Both expressions compute the identical function `F = A + B·C`, they just describe it from opposite sides: SOP lists every way to be `1`, POS lists every way to be `0`. The set of minterm indices (the **on-set** `{3,4,5,6,7}`) and the set of maxterm indices (the **off-set** `{0,1,2}`) are **complementary**: together they are every row, with no overlap. That is the SOP/POS conversion rule: to switch forms, just swap to the indices you did not use. A third bucket, the **don't-care set**, holds rows whose output you genuinely do not care about (impossible or unused inputs); you may assign each a `1` or `0` later to make the circuit smaller.

## Each form is a two-level circuit

The shapes map straight to gates. A canonical **SOP** is a layer of [AND](https://digiwleea.wleeaf.dev/learn/and/) gates (one per minterm) feeding a single [OR](https://digiwleea.wleeaf.dev/learn/or/): a two-level **AND-OR** circuit. A canonical **POS** is a layer of OR gates feeding a single AND: a two-level **OR-AND** circuit. The simplest famous example is [XOR](https://digiwleea.wleeaf.dev/learn/xor/), whose `1`-rows are `01` and `10`, so its canonical SOP is `F = A'B + AB'`: two ANDs into an OR.

_Circuit diagram: The canonical sum of products for XOR, F = A'B + AB', as a two-level AND-OR circuit: one AND per minterm (m1 = A'B and m2 = AB'), both feeding an OR. Open it in the lab and sweep the four rows; F is 1 exactly when the inputs differ._

## NAND-NAND and NOR-NOR: the same circuit in one gate type

Real chips prefer to build everything from one universal gate. A two-level AND-OR converts into an all-[NAND](https://digiwleea.wleeaf.dev/learn/nand/) circuit (**NAND-NAND**) by a move called **bubble pushing**: put an inversion bubble on the output of each AND and a matching bubble on each input of the OR. The two bubbles on every wire cancel, so the function is unchanged, but an AND with an output bubble is a NAND, and an OR with input bubbles is also a NAND (by [De Morgan's law](https://digiwleea.wleeaf.dev/learn/boolean-algebra/), `A'+B' = (AB)'`). So every gate becomes a NAND. The dual move turns a two-level OR-AND (POS) into an all-[NOR](https://digiwleea.wleeaf.dev/learn/nor/) circuit, **NOR-NOR**.

_Circuit diagram: The same XOR, now NAND-NAND: F = NAND(NAND(A',B), NAND(A,B')). Every AND and the final OR of the SOP became a NAND by bubble pushing. Open it in the lab: its truth table is identical to the AND-OR version above (0,1,1,0), built from one universal gate type._

> **WARN:** **Common mistakes.** Get the inversion rule backwards and the whole term is wrong: a **minterm** inverts the inputs that are `0`, a **maxterm** inverts the inputs that are `1`. Read SOP off the `1`-rows and POS off the `0`-rows, not the other way round. And a canonical form is **complete, not minimal**: the canonical SOP for `F = A + B·C` has five long product terms, but the function is really just `A + B·C` (two terms). Canonical forms are where you *start*; a [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/) is how you make them small.

How do you compare two circuits for the same function? Two cheap **cost metrics**: the **gate count** (how many gates) and the **literal count** (how many input appearances across the whole expression, counting each inverted variable too). The canonical SOP above has 5 AND gates plus an OR and costs 15 literals (five 3-literal product terms); the minimized `A + B·C` is one OR plus one AND and costs 3 literals. Same truth table, far less hardware. Minimization is the art of lowering those counts.

**Q (Try it):** A 2-input function `F(A,B)` is `1` only on rows `00` and `11` (the inputs are equal). Write its canonical sum of minterms (`Sigma`) and its canonical product of maxterms (`Pi`). Which named gate is this?

**A:** The `1`-rows are `0 = 00` and `3 = 11`, so the canonical SOP is `F = Sigma m(0,3) = A'B' + AB`. The `0`-rows are `1 = 01` and `2 = 10`, so the canonical POS is `F = Pi M(1,2) = (A + B')(A' + B)`. The on-set `{0,3}` and off-set `{1,2}` are complementary, as expected. `F` is `1` exactly when `A` equals `B`, so this is [XNOR](https://digiwleea.wleeaf.dev/learn/xnor/), the equality gate.

> **KEY:** Canonical forms are the guaranteed route from a [truth table](https://digiwleea.wleeaf.dev/learn/truth-tables/) to a working circuit: pick SOP or POS, read it off the table, and wire the two-level (or NAND-NAND) result. Every later block, from the [adder](https://digiwleea.wleeaf.dev/learn/fulladder/) to the [ALU](https://digiwleea.wleeaf.dev/learn/alu/), is ultimately a canonical form that has been minimized. The next lesson, [Karnaugh maps](https://digiwleea.wleeaf.dev/learn/karnaugh/), is exactly that minimization step: it takes the bloated canonical SOP and groups its terms by eye into the smallest AND-OR circuit.

### FAQ

**Q:** What is the difference between a minterm and a maxterm?

**A:** A **minterm** is an AND of every input (each true or inverted) that is `1` for exactly one row of the truth table; a **maxterm** is an OR of every input that is `0` for exactly one row. They are complements: `m_i' = M_i`. You build a canonical SOP by ORing the minterms of the `1`-rows, and a canonical POS by ANDing the maxterms of the `0`-rows.

**Q:** What is the difference between canonical SOP and canonical POS?

**A:** Canonical SOP (sum of products, `Sigma`) ORs one minterm per `1`-row and builds as a two-level AND-OR circuit. Canonical POS (product of sums, `Pi`) ANDs one maxterm per `0`-row and builds as a two-level OR-AND circuit. Both describe the identical function, from opposite sides: SOP lists every way to be `1`, POS every way to be `0`.

**Q:** How do you convert between SOP and POS?

**A:** The minterm indices (the on-set) and the maxterm indices (the off-set) are complementary: together they cover every row with no overlap. So to switch forms, list the indices you did **not** use. If `F = Sigma m(3,4,5,6,7)` for three inputs, then `F = Pi M(0,1,2)`, because `0,1,2` are the rows missing from the minterm list.

**Q:** What is a NAND-NAND circuit?

**A:** A NAND-NAND circuit is a two-level AND-OR (canonical SOP) rebuilt entirely from NAND gates. By bubble pushing (De Morgan's law), an AND with an inverted output is a NAND and an OR with inverted inputs is also a NAND, and the added inversions cancel, so the function is unchanged. The dual, NOR-NOR, rebuilds a POS circuit from NOR gates. Both let a design use a single universal gate.
