It can't. Ternary's UNKNOWN can't either — that means "no information." When two customers disagree you have too much information, not too little. desclog2 gives you four values instead of two.
pip install git+https://github.com/auraz/desclog2
from desclog2 import Quaternary
WINTER = Quaternary.O1
SUMMER = Quaternary.O2
WINTER & SUMMER # N — no tire is winter-only AND summer-only
WINTER | SUMMER # B — but all-season tires fit either
~WINTER # O2 — opposite season
Boolean models a coin: heads or tails. Ternary adds a midpoint for "haven't flipped yet." Neither models the case where someone says heads and someone else says tails — and you have to write that down in one field.
That field is B (both said something) or N (neither said anything). They're different states. Conflating them, like ternary does, loses real information.
| B | both axes hold — "either works" |
| N | neither axis holds — "impossible" |
| O1 | one option from a binary choice |
| O2 | the opposite option |
Two pairs of opposites: B ↔ N and O1 ↔ O2. Negation swaps both pairs. No value is privileged as "true."
Every other four-valued logic library I found uses a 16-entry lookup table for AND and another for OR. desclog2 doesn't. Each value is a complex number:
N = 0
O1 = 1
O2 = i
B = 1 + i
Operations are arithmetic on the components:
AND = complex(a.real * b.real, a.imag * b.imag) # component-wise multiply
OR = complex(max(a.real, b.real), max(a.imag, b.imag))
NOT = (1 + 1j) - a
That's the entire algebra. The truth tables below are derived, not declared:
| & | B | N | O1 | O2 |
|---|---|---|---|---|
| B | B | N | O1 | O2 |
| N | N | N | N | N |
| O1 | O1 | N | O1 | N |
| O2 | O2 | N | N | O2 |
| | | B | N | O1 | O2 |
|---|---|---|---|---|
| B | B | B | B | B |
| N | B | N | O1 | O2 |
| O1 | B | O1 | O1 | B |
| O2 | B | O2 | B | O2 |
| a | ~a |
|---|---|
| B | N |
| N | B |
| O1 | O2 |
| O2 | O1 |
Every strategy 2x2 — BCG, Eisenhower, value/effort, risk/reward — is a Quaternary in disguise. The four cells map exactly:
| low effort | high effort | |
|---|---|---|
| high value | B · Quick Win | O2 · Big Bet |
| low value | O1 · Fill-in | N · Time Sink |
Strategy books treat these as taxonomies. desclog2 lets you compose them. Score a feature on two matrices, intersect with &:
| feature | value × effort | risk × reward | combined (&) |
|---|---|---|---|
| auth rewrite | B (Quick Win) | O2 (high reward, high risk) | O2 |
| theme picker | O1 (Fill-in) | N (low both) | N |
| billing v2 | O2 (Big Bet) | B (low risk, high reward) | O2 |
Reading the result: B & O2 = O2 means the feature still wins on the reward axis, but high risk drags it out of the Quick Win cell. O1 & N = N means a fill-in with no upside is just a time sink. The algebra collapses two scores into one composite quadrant.
That composition didn't exist as a first-class operation in any strategy tool I checked. Lowy & Hood's The Power of the 2x2 Matrix (2004) catalogs 55 matrices but stops at narrative method. Roger Martin's "integrative thinking" (HBR 2007) describes holding opposing models at once — that's the value B — but never formalizes it. Bohanec's DEX (1990) comes closest in MCDM but uses ordinal categories, not pairs of opposites. The bridge between four-valued logic and 2x2 strategy matrices appears to be unmade.
Close, but not the same. Nuel Belnap's four-valued logic (1977) and Ginsberg/Fitting's bilattice theory (1988, 1991) cover the same four values under the names true, false, both, neither. The differences:
~both = both, ~neither = neither. desclog2's NOT flips both pairs. ~B = N.For modeling database knowledge states, Belnap is the right framework. For modeling product requirements with two equally-weighted axes — winter/summer, cheap/quality, dad-says/mom-says — the symmetric framing fits better.
pip install git+https://github.com/auraz/desclog2
python -c "from desclog2 import Quaternary as Q; print(Q.O1 | Q.O2)"
# B
Oleksandr Kryklia · April 2026 · Happy to answer questions about the encoding or the algebra. Open an issue.