open atlas
↑ Back to track
Logic, from zero LOGIC · 02 · 02

Quantifiers: for-all, there-exists, and why 'all tests pass' can lie

∀ means every case, ∃ means at least one. Negation swaps them — not-all equals exists-a-counterexample — and quantifier order changes what a sentence promises. In code: .every() and .some(), where .every() on an empty array is true — 'all tests pass' can mean 'no tests ran'.

LOGIC Foundations ◷ 16 min
Level
FoundationsJuniorMiddleSenior

The CI banner is green: “All tests pass.” The release goes out, and within an hour checkout is broken in three countries. The investigation takes a humiliating turn: a refactor had renamed the test directory, the runner’s glob matched zero files, and the suite ran nothing. The pipeline’s check was literally results.every(t => t.passed) — and .every() on an empty array returns true. “All zero tests passed” is, by the cold rules of logic, a true statement. Nobody had asked the other question, the one a single character would have answered: did at least one test run?

Goal

After this lesson you can distinguish ∀ from ∃, apply both quantifier negation laws mechanically, explain why .every() on an empty array is true, describe what happens when quantifier order changes, and write the two-part CI check that prevents the green-banner incident.

1

∀ claims every case; ∃ claims at least one. A quantified statement talks about a whole collection. There are exactly two quantifiers. (“for all”) claims a property holds for every member: ∀t P(t) — every test passed. (“there exists”) claims a property holds for at least one member: ∃t P(t) — some test passed. Every spec sentence you have ever read is built from these two: “all requests must be authenticated” is ∀; “an admin can override the limit” is ∃; “every order has at least one line item” is ∀ wrapped around ∃.

2

The burden of proof is opposite for the two quantifiers. To establish a ∀ you must check every case — but to demolish one, a single counterexample suffices. To establish an ∃ you need just one witness — but to demolish it you must sweep the entire collection. This asymmetry is why testing can prove the presence of bugs (one failing case demolishes ”∀ inputs, the code is correct”) but never their absence: no finite pile of passing tests establishes a ∀ over an infinite input space.

3

Negation swaps the quantifier and negates the inside. The negation of “every user has a verified email” is not “every user has an unverified email.” It is “some user does not have a verified email” — one counterexample. Formally: ¬∀x P(x) ≡ ∃x ¬P(x), and symmetrically ¬∃x P(x) ≡ ∀x ¬P(x). Mechanically: a negation slides inward through a quantifier by flipping it — ∀ becomes ∃, ∃ becomes ∀ — and negating the body. In code: !items.every(isValid) means “some item is invalid,” not “all items are invalid.”

4

Quantifier order changes the meaning of a sentence. When a sentence stacks two quantifiers, their order matters. Compare: ∀ service ∃ engineer — every service has an on-call engineer (possibly different per service). ∃ engineer ∀ service — there exists one engineer who is on call for every service (single point of failure). The later quantifier is allowed to depend on the earlier one. The implication is one-way: ∃∀ implies ∀∃ (if one engineer covers everything, every service is covered), never the reverse.

Quantifier negation laws — and their code counterparts
LogicMeaningCode equivalent
¬∀x P(x)Not all have property P!arr.every(P)
∃x ¬P(x)Some element lacks Parr.some(x => !P(x))
¬∃x P(x)No element has P!arr.some(P)
∀x ¬P(x)Every element lacks Parr.every(x => !P(x))
Worked example

Fix the green-banner incident using both quantifiers.

The broken check:

const suiteIsGreen = results.every(t => t.passed);  // true on empty!

This is a ∀ claim: “all tests passed.” On an empty array it is vacuously true.

The fix pairs a ∀ check with an ∃ check:

const suiteIsGreen = results.length > 0 && results.every(t => t.passed);
// ∃ question:  at least one test ran  (results.length > 0)
// ∀ question:  all of them passed     (results.every(...))

The ∃ question (results.length > 0) demolishes the vacuous case: an empty array fails it immediately, so the AND short-circuits to false — the banner goes red when nothing ran.

Similarly, “no test failed” and “all tests passed” are the same claim over a non-empty suite but diverge on the empty one:

!results.some(t => !t.passed)  // ¬∃ — true vacuously on empty
results.every(t => t.passed)   // ∀  — true vacuously on empty
results.length > 0 && results.every(t => t.passed)  // safe
Why this works

Why does .every() on an empty array return true, instead of something safer? Because mathematics needs ¬∀ = ∃¬ to hold always, with no exceptions for empty collections. “All members of the empty set are purple” has no counterexample — there is no member that fails to be purple — so by the negation law it must count as true. Logicians call this vacuous truth. The convention keeps the algebra clean — and quietly demands that engineers ask ∃ questions (“did anything run?”) alongside ∀ questions (“did everything pass?”).

Practice 0 / 5

The spec says 'every request carries a trace id'. To disprove this, how many counterexamples do you need? Type a number.

What is the negation of '∀x P(x)'? Type the formula.

Is !items.every(isValid) the same as items.every(i => !isValid(i))? Type yes or no.

'∀ service ∃ engineer' vs '∃ engineer ∀ service' — which implies the other?

[].every(x => x > 0) in JavaScript — is this true or false?

Check yourself
Quiz

The spec says: every request carries a trace id. QA wants to disprove this claim. What exactly must they produce?

Recap

Quantifiers are the two ways a sentence can talk about a whole collection: ∀ (“for all”) claims the property holds for every member and is demolished by a single counterexample, while ∃ (“there exists”) claims at least one witness and is demolished only by sweeping the entire set. Negation swaps the two as it slides inward: ¬∀ = ∃¬ (not-all-pass means some-test-fails, never all-fail) and ¬∃ = ∀¬ (no-test-fails means every-test-passes). In code, .every() is ∀ and .some() is ∃, and .every() on an empty array is vacuously true — the price of keeping the negation law exception-free. The cure is pairing every ∀ check with the ∃ question results.length > 0, and pairing every universal claim in a spec with the questions “over exactly which set?” and “was that set non-empty?” Order matters when quantifiers stack: ∀s ∃e (each service has its own on-call) versus ∃e ∀s (one human covers everything), with implication running only from ∃∀ to ∀∃.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 5 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.