Discrete Mathematics YMT211 · Fall 2026 Assoc. Prof. Ferhat Uçar
04 Predicate Logic Monday, October 12, 2026

Predicates and Quantifiers

Statements with variables: predicates, domains, “for all” and “there exists”, translating English into logic and back, and negating quantified statements correctly.

Learning objectives

By the end of this week you can:

  • 1 Explain why propositional logic cannot express “every” and “some”, and what a predicate adds.
  • 2 Evaluate a predicate P(x) for a given value, and say why P(x) alone is not a proposition.
  • 3 Decide the truth value of ∀x P(x) and ∃x P(x) over a given domain, using a counterexample or a witness.
  • 4 Explain how the domain changes the truth value of the same statement.
  • 5 Translate English sentences into predicate logic and back, using the rule “∀ goes with →, ∃ goes with ∧”.
  • 6 Negate quantified statements correctly with De Morgan's laws for quantifiers.
  • 7 Write ∀ and ∃ over finite data in Python with all() and any(), and recognize them in SQL.

★ the wow moment

SQL is predicate logic with a nicer keyboard.

SELECT … WHERE EXISTS (…) is ∃, and SQL has no FOR ALL at all: databases write “every student has taken Java” as NOT EXISTS a student WHERE NOT java, that is, ¬∃x(S(x) ∧ ¬J(x)). That is De Morgan's law for quantifiers, the topic of this week, running millions of times per second in every database you will ever use.

Why we need more than propositions

Here is a famous argument, more than two thousand years old:

All humans are mortal. Socrates is a human. Therefore, Socrates is mortal.

Everybody agrees it is correct. Now try to write it in the propositional logic of weeks 2 and 3. The best we can do is three unrelated letters: pp = “all humans are mortal”, qq = “Socrates is a human”, rr = “Socrates is mortal”. The argument becomes p,q  ∴  rp, q \;\therefore\; r, and nothing in pp and qq forces rr. Propositional logic cannot see inside a sentence. It does not know that “all humans” talks about Socrates.

The same problem shows up in software every day:

  • “Every request is authenticated.”
  • “Some server in the cluster is overloaded.”
  • “No user has two active sessions.”

With 10,000 users we would need 10,000 separate propositions, one per user. What we really want is to write a statement once, with a variable, and say “for all of them” or “for some of them”. That is exactly what predicate logic adds, with two new ingredients: predicates and quantifiers.

Predicates

Take P(x)P(x): “x>3x > 3”.

StatementProposition?Truth value
P(x)P(x): x>3x > 3no, xx is unknownnone yet
P(4)P(4): 4>34 > 3yestrue
P(2)P(2): 2>32 > 3yesfalse

In plain words: a predicate is a yes/no question with a blank. “Is ___ greater than 3?” has no answer until you fill in the blank.

If you program, you already know predicates. A predicate is simply a function that returns a boolean:

def P(x):                  # P(x): "x > 3"
    return x > 3

def is_valid_ipv4(s):      # V(s): "s is a valid IPv4 address"
    parts = s.split(".")
    return len(parts) == 4 and all(p.isdigit() and 0 <= int(p) <= 255 for p in parts)

P(4)                       # True
is_valid_ipv4("256.1.1.1") # False

Predicates with several variables

A predicate can have more than one blank. The number of variables is its arity.

  • Q(x,y)Q(x, y): “x=y+3x = y + 3”. Then Q(5,2)Q(5, 2) is true and Q(1,2)Q(1, 2) is false.
  • L(x,y)L(x, y): “xx loves yy”. L(Ada,Mathematics)L(\text{Ada}, \text{Mathematics}) is, we hope, true.
  • T(s,c)T(s, c): “student ss has taken course cc”, a predicate a university database answers thousands of times a day.

Building with connectives

Everything from weeks 2 and 3 still works: once the blanks are filled, the results are propositions and we can combine them with ¬,∧,∨,→,↔\neg, \land, \lor, \to, \leftrightarrow. Let P(x)P(x) be “x>0x > 0”.

ExpressionValue
P(3)∨P(−1)P(3) \lor P(-1)true ∨ false = true
P(3)∧P(−1)P(3) \land P(-1)true ∧ false = false
P(3)→P(−1)P(3) \to P(-1)true → false = false
P(3)→¬P(−1)P(3) \to \neg P(-1)true → true = true
Answer

D(12)→E(12)D(12) \to E(12) is true → true = true. E(6)→D(6)E(6) \to D(6) is true → false = false: 6 is even but not divisible by 4.

The domain

Before we can say “for all xx” we must answer: all xx from where? That set is the domain (also called the universe of discourse), written UU or DD.

The domain is not a detail. It decides the answer:

StatementDomainTrue or false?
“every xx satisfies x2≥xx^2 \ge x”integers Z\mathbb{Z}true
“every xx satisfies x2≥xx^2 \ge x”real numbers R\mathbb{R}false: x=0.5x = 0.5 gives 0.25<0.50.25 < 0.5
“some xx satisfies x2=2x^2 = 2”rational numbers Q\mathbb{Q}false (2\sqrt 2 is irrational, week 7)
“some xx satisfies x2=2x^2 = 2”real numbers R\mathbb{R}true: x=2x = \sqrt 2

The universal quantifier ∀

The symbol ∀\forall is an upside-down A, for All. It reads “for all”, “for every”, “for each” or “for any”.

That x=3x = 3 has a name.

The asymmetry is the key to this whole topic:

  • To show ∀x P(x)\forall x\, P(x) is false: find one counterexample. Easy.
  • To show ∀x P(x)\forall x\, P(x) is true: you must cover every element. With a finite domain, check them all; with an infinite domain you need an argument, a proof (week 7). A thousand examples that work prove nothing about the thousand-and-first.

∀ is a loop, and a big AND

How would a computer evaluate ∀x P(x)\forall x\, P(x) over a finite domain? It loops:

def for_all(domain, P):
    for x in domain:
        if not P(x):
            return False      # counterexample found: stop immediately
    return True               # survived every element

Python has this built in: all(P(x) for x in domain). It also stops at the first false value. When the domain is finite, say U={1,2,3}U = \{1, 2, 3\}, the loop is just a long conjunction:

∀x P(x)  ≡  P(1)∧P(2)∧P(3)\forall x\, P(x) \;\equiv\; P(1) \land P(2) \land P(3)

The existential quantifier ∃

The symbol ∃\exists is a backwards E, for Exists. It reads “there exists”, “there is”, “for some” or “at least one”.

The asymmetry is now reversed: proving ∃\exists true needs one example; proving ∃\exists false needs you to rule out every element.

def exists(domain, P):
    for x in domain:
        if P(x):
            return True       # witness found: stop immediately
    return False              # nobody worked

That is any(P(x) for x in domain), and over a finite domain it is a long disjunction:

∃x P(x)  ≡  P(1)∨P(2)∨P(3)\exists x\, P(x) \;\equiv\; P(1) \lor P(2) \lor P(3)

The two quantifiers side by side

∀x P(x)\forall x\, P(x)∃x P(x)\exists x\, P(x)
Read asfor every xxthere is an xx
True whenP(x)P(x) is true for every xxP(x)P(x) is true for at least one xx
False whenthere is an xx with P(x)P(x) falseP(x)P(x) is false for every xx
Shown true byan argument covering all xxone witness
Shown false byone counterexamplean argument covering all xx
Finite domainP(x1)∧P(x2)∧…P(x_1) \land P(x_2) \land \dotsP(x1)∨P(x2)∨…P(x_1) \lor P(x_2) \lor \dots
Pythonall(...)any(...)

Reading quantified formulas correctly

Precedence

∀\forall and ∃\exists bind more tightly than every connective. So

∀x P(x)∨Q(x)means(∀x P(x))∨Q(x),not∀x (P(x)∨Q(x)).\forall x\, P(x) \lor Q(x) \quad\text{means}\quad \big(\forall x\, P(x)\big) \lor Q(x), \qquad\text{not}\quad \forall x\,\big(P(x) \lor Q(x)\big).

When the quantifier should cover more, use parentheses. In this course we always write the parentheses, and you should too.

Bound and free variables

In ∃x (x+y=1)\exists x\,(x + y = 1) the variable xx is bound by the quantifier, while yy is free: nothing tells us its value. A formula with a free variable is still a predicate (a question with a blank), not a proposition. It becomes a proposition when every variable is either bound or given a value: ∃x (x+2=1)\exists x\,(x + 2 = 1) is true over the integers (x=−1x = -1).

The scope of a quantifier is the part of the formula it covers, usually the parenthesis right after it. A bound variable can be renamed without changing the meaning, exactly like a loop variable in code: ∀x P(x)\forall x\, P(x) and ∀y P(y)\forall y\, P(y) say the same thing.

Restricted domains, and the golden rule

Mathematics constantly quantifies over part of a domain: “every negative number”, “some prime number”, “every student in this class”. There is a short notation:

∀x<0   (x2>0)∃z>0   (z2=2)\forall x < 0\;\, (x^2 > 0) \qquad\qquad \exists z > 0\;\, (z^2 = 2)

What do these mean in plain predicate logic? Read them slowly.

  • “Every negative xx has x2>0x^2 > 0” means: for every xx, if xx is negative, then x2>0x^2 > 0.
  • “Some positive zz has z2=2z^2 = 2” means: there is a zz that is positive and has z2=2z^2 = 2.
∀x<0  (x2>0)  ≡  ∀x (x<0→x2>0)∃z>0  (z2=2)  ≡  ∃z (z>0∧z2=2)\forall x < 0\;(x^2 > 0) \;\equiv\; \forall x\,\big(x < 0 \to x^2 > 0\big) \qquad \exists z > 0\;(z^2 = 2) \;\equiv\; \exists z\,\big(z > 0 \land z^2 = 2\big)

This gives the single most useful rule of the week.

The rule is not a convention. The other two combinations say something different, and the next section shows exactly why.

Seeing it with real data

Our domain is eight people. Some are students in this class (SS), some have taken Java (JJ). Pick a statement with the buttons, then click the S and J values to change the data and watch what happens. Pay attention to the two statements marked ✗.

quantifier lab · domain = the 8 people below S(x): x is a student in this class · J(x): x has taken Java

x S(x) J(x) body loop

Click any S or J value to flip it, and watch the verdict change.

Python

SQL

What the lab shows, in words:

  • ∀x (S(x)→J(x))\forall x\,(S(x) \to J(x)), “every student has taken Java”. For people who are not students, S(x)S(x) is false, so S(x)→J(x)S(x) \to J(x) is automatically true (week 2: a promise with a false hypothesis is never broken). The implication filters: only the students are tested. This is the correct translation.
  • ∀x (S(x)∧J(x))\forall x\,(S(x) \land J(x)) says “everyone is a student in this class and has taken Java”. Kerem, Mert and Lina are not students, so it is false even when every student took Java. Wrong translation: it accidentally claims that the whole domain consists of students.
  • ∃x (S(x)∧J(x))\exists x\,(S(x) \land J(x)), “some student has taken Java”, needs one person who is both. Correct translation.
  • ∃x (S(x)→J(x))\exists x\,(S(x) \to J(x)) is true as soon as there is any non-student, since the implication is vacuously true for them. It says almost nothing. Wrong translation. Try it: select it and flip every student’s J to 0. Nobody in the class has taken Java, yet the formula stays true, held up by Kerem, Mert or Lina.

Translating English into logic

Translation is a skill, and a recipe helps.

Worked example: one sentence, two domains

“Every student in this class has taken a course in Java.”

  • Domain = students in this class. Everybody in the domain is already a student, so no S(x)S(x) is needed: ∀x J(x)\forall x\, J(x).
  • Domain = all people. Now we must filter: ∀x (S(x)→J(x))\forall x\,(S(x) \to J(x)).

Both are correct; they differ only because the domains differ. A narrower domain gives a shorter formula, a wider domain needs the filter.

A dictionary of sentence patterns

EnglishLogic
All A are B.∀x (A(x)→B(x))\forall x\,(A(x) \to B(x))
Some A are B.∃x (A(x)∧B(x))\exists x\,(A(x) \land B(x))
No A is B.¬∃x (A(x)∧B(x))\neg\exists x\,(A(x) \land B(x))   ≡  ∀x (A(x)→¬B(x))\;\equiv\; \forall x\,(A(x) \to \neg B(x))
Not all A are B.¬∀x (A(x)→B(x))\neg\forall x\,(A(x) \to B(x))   ≡  ∃x (A(x)∧¬B(x))\;\equiv\; \exists x\,(A(x) \land \neg B(x))
Some A are not B.∃x (A(x)∧¬B(x))\exists x\,(A(x) \land \neg B(x))
Only A are B.∀x (B(x)→A(x))\forall x\,(B(x) \to A(x))
Everything is A.∀x A(x)\forall x\, A(x)
Nothing is A.¬∃x A(x)\neg\exists x\, A(x)   ≡  ∀x ¬A(x)\;\equiv\; \forall x\, \neg A(x)

Practice with a strange island

Lewis Carroll style, from the lecture slides. The domain is all creatures; F(x)F(x): xx is a fleegle, S(x)S(x): xx is a snurd, T(x)T(x): xx is a thingamabob. Cover the right column and translate first.

EnglishLogic
Everything is a fleegle.∀x F(x)\forall x\, F(x)
Nothing is a snurd.¬∃x S(x)  ≡  ∀x ¬S(x)\neg\exists x\, S(x) \;\equiv\; \forall x\, \neg S(x)
All fleegles are snurds.∀x (F(x)→S(x))\forall x\,(F(x) \to S(x))
Some fleegles are thingamabobs.∃x (F(x)∧T(x))\exists x\,(F(x) \land T(x))
No snurd is a thingamabob.¬∃x (S(x)∧T(x))  ≡  ∀x (S(x)→¬T(x))\neg\exists x\,(S(x) \land T(x)) \;\equiv\; \forall x\,(S(x) \to \neg T(x))
If any fleegle is a snurd, then it is also a thingamabob.∀x ((F(x)∧S(x))→T(x))\forall x\,\big((F(x) \land S(x)) \to T(x)\big)

The last one hides a trap: “any” here means every. “If any fleegle is a snurd, then it is also a thingamabob” is a rule about each fleegle-snurd, so it is universal.

Specifications from systems

Engineers write requirements in exactly this form. Let L(m,y)L(m, y): message mm is larger than yy megabytes, C(m)C(m): message mm is compressed, A(u)A(u): user uu is active, V(n)V(n): network link nn is available.

RequirementLogic
Every mail message larger than one megabyte will be compressed.∀m (L(m,1)→C(m))\forall m\,\big(L(m, 1) \to C(m)\big)
If a user is active, at least one network link will be available.∀u (A(u)→∃n V(n))\forall u\,\big(A(u) \to \exists n\, V(n)\big)

The second one already contains two quantifiers, one inside the other. Nested quantifiers are next week’s topic.

The lions argument

Another classic from the slides. Domain: all creatures. P(x)P(x): xx is a lion, Q(x)Q(x): xx is fierce, R(x)R(x): xx drinks coffee.

SentenceLogic
All lions are fierce.∀x (P(x)→Q(x))\forall x\,(P(x) \to Q(x))
Some lions do not drink coffee.∃x (P(x)∧¬R(x))\exists x\,(P(x) \land \neg R(x))
Therefore, some fierce creatures do not drink coffee.∃x (Q(x)∧¬R(x))\exists x\,(Q(x) \land \neg R(x))

Is the argument valid? Take the lion that does not drink coffee (the witness of line 2). By line 1 it is fierce. So it is a fierce creature that does not drink coffee, a witness for line 3. In week 6 we will turn this kind of reasoning into formal rules of inference.

From logic back to English

Going the other way is just as important: you must be able to read a formula. Let the domain be all students in your school, C(x)C(x): xx has a computer, F(x,y)F(x, y): xx and yy are friends.

∀x (C(x)∨∃y (C(y)∧F(x,y)))\forall x\,\Big(C(x) \lor \exists y\,\big(C(y) \land F(x, y)\big)\Big)

Word by word: “for every student xx, either xx has a computer, or there is a student yy who has a computer and is a friend of xx.” Now say it like a human: “Every student either has a computer or has a friend who has one.” A good translation sounds like a sentence a person would actually say.

Negating quantified statements

Your manager says: “Every test passed.” You find one failing test. What is the exact opposite of the manager’s claim?

  • Not “no test passed”. That is far too strong.
  • It is: “some test did not pass.” One failing test is enough.

That is the whole idea, written as two laws.

Why are they called De Morgan’s laws? Over a finite domain {1,2,3}\{1, 2, 3\}, ∀\forall is a big ∧ and ∃\exists is a big ∨, so the first law is literally week 3’s De Morgan:

¬(P(1)∧P(2)∧P(3))  ≡  ¬P(1)∨¬P(2)∨¬P(3)\neg\big(P(1) \land P(2) \land P(3)\big) \;\equiv\; \neg P(1) \lor \neg P(2) \lor \neg P(3)
NegationEquivalent toTrue when
¬∀x P(x)\neg\forall x\, P(x)∃x ¬P(x)\exists x\, \neg P(x)at least one xx makes P(x)P(x) false
¬∃x P(x)\neg\exists x\, P(x)∀x ¬P(x)\forall x\, \neg P(x)every xx makes P(x)P(x) false

Negating restricted statements, step by step

The negation must keep the filter, so it combines De Morgan for quantifiers with week 3’s ¬(p→q)≡p∧¬q\neg(p \to q) \equiv p \land \neg q.

Answers
  1. ∃x (x2≤x)\exists x\,(x^2 \le x): “some number is at least as large as its own square.” Over the integers it is true, with witnesses x=0x = 0 and x=1x = 1.
  2. ∀x (x2≠2)\forall x\,(x^2 \ne 2): “no number squares to 2”. True over Q\mathbb{Q}, false over R\mathbb{R}.
  3. “Some request is not authenticated.” With R(x)R(x): xx is a request and A(x)A(x): xx is authenticated: ¬∀x (R(x)→A(x))≡∃x (R(x)∧¬A(x))\neg\forall x\,(R(x) \to A(x)) \equiv \exists x\,(R(x) \land \neg A(x)).

Equivalences, and two traps

Two distributive laws hold for quantifiers:

∀x (P(x)∧Q(x))  ≡  ∀x P(x)∧∀x Q(x)∃x (P(x)∨Q(x))  ≡  ∃x P(x)∨∃x Q(x)\forall x\,\big(P(x) \land Q(x)\big) \;\equiv\; \forall x\, P(x) \land \forall x\, Q(x) \qquad\qquad \exists x\,\big(P(x) \lor Q(x)\big) \;\equiv\; \exists x\, P(x) \lor \exists x\, Q(x)

“Everyone is tall and smart” says the same as “everyone is tall, and everyone is smart.” Fine. But the other two combinations fail:

Quantifiers in code and data

You will meet ∀ and ∃ every day as a software engineer, usually without the symbols.

Python. all() is ∀\forall and any() is ∃\exists, both with short-circuiting:

grades = {"Ada": 92, "Can": 78, "Deniz": 45}

all(g >= 50 for g in grades.values())     # ∀: did everyone pass?  → False
any(g >= 90 for g in grades.values())     # ∃: did anyone get an A? → True
not any(g < 0 for g in grades.values())   # ¬∃ ≡ ∀¬: no negative grades → True

Note one subtle point: all([]) is True and any([]) is False. A ∀ statement over an empty domain is vacuously true (there is no counterexample), and an ∃ statement over an empty domain is false (there is no witness).

SQL. A WHERE clause is a predicate, and EXISTS is ∃\exists. SQL has no FOR ALL. To ask “has every student taken Java?”, a database uses this week’s law, ∀x (S→J)≡¬∃x (S∧¬J)\forall x\,(S \to J) \equiv \neg\exists x\,(S \land \neg J):

SELECT NOT EXISTS (
  SELECT * FROM people
  WHERE is_student AND NOT took_java
) AS every_student_took_java;

Testing. A unit test checks one example: an ∃-style piece of evidence. Property-based testing states a ∀ property and lets the computer hunt for a counterexample:

from hypothesis import given, strategies as st

@given(st.lists(st.integers()))
def test_sorting_keeps_length(xs):        # ∀ lists xs: len(sorted(xs)) == len(xs)
    assert len(sorted(xs)) == len(xs)

If the property is false, Hypothesis prints a counterexample, and usually the smallest one it can find.

A look ahead: nested quantifiers

Many real statements need two quantifiers, one inside the other. “Every user has a password” is ∀u ∃p  Has(u,p)\forall u\, \exists p\; \text{Has}(u, p). And the order matters enormously: “for every number there is a bigger one” (∀x ∃y  y>x\forall x\, \exists y\; y > x, true) is very different from “there is a number bigger than every number” (∃y ∀x  y>x\exists y\, \forall x\; y > x, false). That is the whole of week 5.

Summary

  • A predicate P(x)P(x) is a statement with a variable: a yes/no question with a blank. It becomes a proposition when the blank is filled.
  • Always fix the domain; the same statement can be true in one domain and false in another.
  • ∀x P(x)\forall x\, P(x): true for every xx. Disproved by one counterexample. Over finite data it is a big ∧ and all().
  • ∃x P(x)\exists x\, P(x): true for at least one xx. Proved by one witness. Over finite data it is a big ∨ and any().
  • Golden rule: ∀ goes with →, ∃ goes with ∧. ∀x (A∧B)\forall x\,(A \land B) and ∃x (A→B)\exists x\,(A \to B) are the two classic mistakes.
  • Negation: swap the quantifier and push ¬ inside. ¬∀x (A→B)≡∃x (A∧¬B)\neg\forall x\,(A \to B) \equiv \exists x\,(A \land \neg B) and ¬∃x (A∧B)≡∀x (A→¬B)\neg\exists x\,(A \land B) \equiv \forall x\,(A \to \neg B).
  • ∀ distributes over ∧ and ∃ over ∨, but not the other way round.

Practice

Answers
  1. ∀x (C(x)→G(x))\forall x\,(C(x) \to G(x)).
  2. ∃x (C(x)∧¬P(x))\exists x\,(C(x) \land \neg P(x)).
  3. ∀x (C(x)→P(x))\forall x\,(C(x) \to P(x)). Being in this class requires knowing Python: “only Python-knowers are in the class” means “if in the class, then knows Python”.
  4. ¬∀x (C(x)→G(x))≡∃x (C(x)∧¬G(x))\neg\forall x\,(C(x) \to G(x)) \equiv \exists x\,(C(x) \land \neg G(x)): “some student in this class has no GitHub account.”
  5. “No student in this class knows neither Python nor has a GitHub account”, or more naturally: “every student in this class knows Python or has a GitHub account.” Check: ¬∃x (C∧¬P∧¬G)≡∀x (C→(P∨G))\neg\exists x\,(C \land \neg P \land \neg G) \equiv \forall x\,(C \to (P \lor G)).
  6. (a) True for all integers: if n≤0n \le 0 then n2≥0≥nn^2 \ge 0 \ge n, and if n≥1n \ge 1 then n2=n⋅n≥nn^2 = n \cdot n \ge n. (b) True, witness n=2n = 2: 4=2+24 = 2 + 2 (also n=−1n = -1). (c) True: if n=2kn = 2k then n2=4k2=2(2k2)n^2 = 4k^2 = 2(2k^2) is even. This last one is our first real proof; week 7 does many more.

Before the lab

Lab 3 puts this week into code: you will evaluate ∀ and ∃ statements over a real student–course dataset with all() and any(), find witnesses and counterexamples automatically, and check De Morgan’s laws for quantifiers on data.

In industry

  • Databases

    WHERE clauses are predicates; EXISTS and NOT EXISTS are quantifiers. Query optimizers rewrite queries with exactly the equivalences on this page.

  • Access control

    Cloud permission systems answer questions like “does there exist a policy that allows this request?” and “for every request from this role, is access denied?”.

  • Testing

    Unit tests check a few examples (∃). Property-based testing (Hypothesis in Python) tries thousands of random inputs to hunt for a counterexample to a ∀ statement.

  • Specifications

    Requirements like “every message larger than 1 MB is compressed” are ∀ statements. Writing them in logic exposes ambiguity before any code is written.

Lab 3: Quantifiers over Real Data

Write ∀ and ∃ as loops, find counterexamples and witnesses, answer questions about a class of students with the golden rule, and put De Morgan's laws for quantifiers into code.

due Fri, Oct 16 · 23:59 · 100 points · open now

Go deeper

Tags:predicatepropositional functionquantifieruniversalexistentialforallexistsdomaincounterexamplewitnessnegationDe MorganSQLallany