Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Reasoning›Predicate Logic and Quantifiers

Advanced Logical Systems

Predicate Logic and Quantifiers

Predicate logic extends propositional logic by introducing variables, predicates, and quantifiers to express statements about objects and their relationships. It matters because it allows precise modeling of complex real-world scenarios, such as database queries or mathematical proofs, where simple true/false statements are insufficient. You reach for it when you need to reason about properties of objects, their interactions, or generalizations across groups, such as in algorithm correctness or formal verification.

From Propositions to Predicates

Propositional logic deals with whole statements that are either true or false, like 'The sky is blue.' However, it cannot express relationships between objects or properties of specific elements. Predicate logic solves this by breaking statements into predicates (functions that return true or false) and terms (objects or variables). For example, the statement 'x is greater than 5' can be written as G(x, 5), where G is a predicate representing the 'greater than' relationship. This shift allows us to talk about properties of individual objects or groups of objects, which is essential for modeling real-world systems. Predicates can take any number of arguments, enabling flexible representations of relationships, such as 'Person A is friends with Person B' or 'Function f is continuous at point x.' The key insight is that predicates are not standalone truths but depend on the values of their variables, which is why they are often called 'propositional functions.'

# Define a predicate for 'x is greater than y'
def is_greater(x, y):
    return x > y

# Test the predicate with specific values
print(is_greater(7, 5))  # Output: True
print(is_greater(3, 5))  # Output: False

# Predicates can represent relationships, like 'x is a friend of y'
def is_friend(person_a, person_b):
    friends = {('Alice', 'Bob'), ('Bob', 'Charlie')}
    return (person_a, person_b) in friends

print(is_friend('Alice', 'Bob'))  # Output: True
print(is_friend('Alice', 'Charlie'))  # Output: False

Introducing Quantifiers: Universal and Existential

Quantifiers allow us to express statements about entire sets of objects without enumerating them individually. The universal quantifier (∀) means 'for all' and is used to assert that a predicate holds true for every element in a domain. For example, 'All humans are mortal' can be written as ∀x (Human(x) → Mortal(x)). The existential quantifier (∃) means 'there exists' and asserts that at least one element in the domain satisfies the predicate, such as 'There exists a human who is a philosopher' (∃x (Human(x) ∧ Philosopher(x))). These quantifiers are powerful because they let us generalize or specify without listing every case. The universal quantifier is often paired with implication (→), as it states a condition that must hold for all elements, while the existential quantifier is paired with conjunction (∧), as it asserts the existence of an element with multiple properties. Understanding the scope of quantifiers is critical: the order of quantifiers can change the meaning of a statement entirely, such as ∀x ∃y Loves(x, y) ('Everyone loves someone') versus ∃y ∀x Loves(x, y) ('There is someone whom everyone loves').

# Universal quantifier: Check if all elements in a list satisfy a predicate
def for_all(elements, predicate):
    return all(predicate(x) for x in elements)

# Existential quantifier: Check if at least one element satisfies a predicate
def exists(elements, predicate):
    return any(predicate(x) for x in elements)

# Example predicates
def is_even(x):
    return x % 2 == 0

def is_positive(x):
    return x > 0

numbers = [2, 4, 6, 8]
print(for_all(numbers, is_even))  # Output: True (all numbers are even)
print(exists(numbers, is_positive))  # Output: True (at least one number is positive)

# Order of quantifiers matters
def loves_everyone(person, people):
    return for_all(people, lambda p: f"{person} loves {p}")

def someone_loved_by_all(people):
    return exists(people, lambda p: for_all(people, lambda q: f"{q} loves {p}"))

people = ['Alice', 'Bob']
print(loves_everyone('Alice', people))  # Output: False (unless Alice loves everyone)
print(someone_loved_by_all(people))  # Output: False (unless someone is loved by all)

Translating Natural Language to Predicate Logic

Translating natural language into predicate logic requires identifying the domain, predicates, and quantifiers in a statement. Start by determining the domain of discourse, which is the set of objects the statement refers to. For example, in 'All birds can fly,' the domain is 'birds.' Next, identify the predicates: 'can fly' is a unary predicate (takes one argument), while 'is taller than' is a binary predicate. Quantifiers are often implicit in natural language, so you must infer whether a statement is universal ('all,' 'every') or existential ('some,' 'there exists'). For instance, 'Some students passed the exam' translates to ∃x (Student(x) ∧ PassedExam(x)). Negations can complicate translations: 'Not all students passed' is equivalent to ∃x (Student(x) ∧ ¬PassedExam(x)), not ¬∀x (Student(x) → PassedExam(x)). This is because the negation of a universal quantifier is an existential quantifier with a negated predicate. Practice is key: break statements into smaller parts, identify the logical structure, and then combine them using quantifiers and connectives. Common pitfalls include misplacing quantifiers or confusing implications with conjunctions, so always verify that the translation captures the original meaning.

# Translate 'All programmers enjoy coding' to predicate logic
def all_programmers_enjoy_coding(people):
    # Domain: people
    # Predicate: is_programmer(x), enjoys_coding(x)
    return for_all(people, lambda x: not is_programmer(x) or enjoys_coding(x))

def is_programmer(person):
    programmers = {'Alice', 'Bob'}
    return person in programmers

def enjoys_coding(person):
    return True  # Assume all programmers enjoy coding for this example

people = ['Alice', 'Bob', 'Charlie']
print(all_programmers_enjoy_coding(people))  # Output: True

# Translate 'Some cats are black' to predicate logic
def some_cats_are_black(animals):
    # Domain: animals
    # Predicate: is_cat(x), is_black(x)
    return exists(animals, lambda x: is_cat(x) and is_black(x))

def is_cat(animal):
    cats = {'Whiskers', 'Mittens'}
    return animal in cats

def is_black(animal):
    black_animals = {'Mittens'}
    return animal in black_animals

animals = ['Whiskers', 'Mittens', 'Rover']
print(some_cats_are_black(animals))  # Output: True

Nested Quantifiers and Scope

Nested quantifiers occur when multiple quantifiers are used in the same statement, and their order critically affects the meaning. For example, ∀x ∃y Loves(x, y) means 'For every person x, there exists a person y such that x loves y,' while ∃y ∀x Loves(x, y) means 'There exists a person y such that for every person x, x loves y.' The first statement is weaker (it allows different y for each x), while the second is stronger (it requires a single y loved by all x). To reason about nested quantifiers, work from the inside out: first interpret the innermost quantifier, then the next, and so on. This approach helps avoid confusion, especially with mixed quantifiers (universal and existential). For instance, ∀x ∃y (Parent(x, y) ∧ Ancestor(y, z)) means 'For every x, there exists a y such that x is a parent of y, and y is an ancestor of z.' The scope of a quantifier is the part of the formula it applies to, and variables outside its scope are free variables. In nested quantifiers, the inner quantifier can depend on the outer one, but not vice versa. This dependency is why swapping quantifiers changes the meaning: ∀x ∃y P(x, y) is not equivalent to ∃y ∀x P(x, y).

# Nested quantifiers: ∀x ∃y (x < y) in a list of numbers
def all_less_than_some(numbers):
    # For every x in numbers, there exists a y in numbers such that x < y
    return for_all(numbers, lambda x: exists(numbers, lambda y: x < y))

# Nested quantifiers: ∃y ∀x (x < y) in a list of numbers
def some_greater_than_all(numbers):
    # There exists a y in numbers such that for all x in numbers, x < y
    return exists(numbers, lambda y: for_all(numbers, lambda x: x < y))

numbers = [1, 2, 3]
print(all_less_than_some(numbers))  # Output: True (for each x, there's a y > x)
print(some_greater_than_all(numbers))  # Output: False (no single y is greater than all x)

# Example with predicates: ∀x ∃y (Friend(x, y))
def everyone_has_a_friend(people):
    # For every person x, there exists a person y such that x is friends with y
    return for_all(people, lambda x: exists(people, lambda y: is_friend(x, y)))

def is_friend(person_a, person_b):
    friends = {('Alice', 'Bob'), ('Bob', 'Alice'), ('Bob', 'Charlie')}
    return (person_a, person_b) in friends

people = ['Alice', 'Bob', 'Charlie']
print(everyone_has_a_friend(people))  # Output: True (Alice has Bob, Bob has Alice/Charlie, Charlie has Bob)

Reasoning with Quantifiers: Proofs and Counterexamples

Reasoning with quantifiers involves constructing proofs or counterexamples to validate statements. For universal statements (∀x P(x)), a proof requires showing that P(x) holds for every x in the domain, while a counterexample requires finding a single x where P(x) is false. For existential statements (∃x P(x)), a proof requires exhibiting a specific x where P(x) holds, while a counterexample requires showing that P(x) is false for all x. For example, to disprove 'All prime numbers are odd,' you only need to find the counterexample 2 (a prime number that is even). When dealing with nested quantifiers, proofs often require constructing objects that satisfy multiple conditions. For instance, to prove ∀x ∃y (x < y), you must show that for every x, you can find a y (which may depend on x) that satisfies the condition. Conversely, to disprove ∃y ∀x (x < y), you must show that no single y works for all x. Proofs in predicate logic often use strategies like direct proof, proof by contradiction, or induction. For example, to prove 'There is no largest integer,' you assume the opposite (∃x ∀y (y ≤ x)) and derive a contradiction by showing that x + 1 is larger than x. Counterexamples are equally powerful: they can quickly invalidate a universal claim, saving time and effort.

# Prove or disprove: 'All even numbers greater than 2 are not prime'
# Universal statement: ∀x (Even(x) ∧ x > 2 → ¬Prime(x))

def is_even(x):
    return x % 2 == 0

def is_prime(x):
    if x < 2:
        return False
    for i in range(2, int(x ** 0.5) + 1):
        if x % i == 0:
            return False
    return True

def all_even_gt2_not_prime(numbers):
    # Check if for all x in numbers, if x is even and > 2, then x is not prime
    return for_all(numbers, lambda x: not (is_even(x) and x > 2) or not is_prime(x))

numbers = [2, 3, 4, 5, 6, 7, 8]
print(all_even_gt2_not_prime(numbers))  # Output: True (no counterexample found)

# Disprove: 'There exists a largest even number'
# Existential statement: ∃x ∀y (Even(y) → y ≤ x)
# Counterexample: Show that for any even x, there exists an even y > x
def no_largest_even_exists(max_candidate):
    # For any even x, y = x + 2 is even and larger
    return is_even(max_candidate + 2) and (max_candidate + 2) > max_candidate

print(no_largest_even_exists(100))  # Output: True (102 is even and larger than 100)

Key points

  • Predicate logic extends propositional logic by introducing variables and predicates to express properties of objects and their relationships, enabling more nuanced reasoning.
  • The universal quantifier (∀) asserts that a predicate holds for all elements in a domain, while the existential quantifier (∃) asserts that at least one element satisfies the predicate.
  • Translating natural language to predicate logic requires identifying the domain, predicates, and quantifiers, and carefully handling negations and implications to preserve meaning.
  • The order of nested quantifiers matters: ∀x ∃y P(x, y) is not equivalent to ∃y ∀x P(x, y), as the former allows y to depend on x, while the latter requires a single y for all x.
  • To prove a universal statement (∀x P(x)), you must show P(x) holds for every x in the domain, while a single counterexample suffices to disprove it.
  • To prove an existential statement (∃x P(x)), you must exhibit a specific x where P(x) holds, while disproving it requires showing P(x) is false for all x.
  • Nested quantifiers require reasoning from the inside out, interpreting the innermost quantifier first and working outward to understand the statement's meaning.
  • Counterexamples are powerful tools for disproving universal claims, as they can invalidate a statement with minimal effort by finding a single exception.

Common mistakes

  • Mistake: Confusing the order of quantifiers (∀x∃y vs ∃y∀x). Why it's wrong: The order of quantifiers changes the meaning entirely. ∀x∃y means 'for every x, there exists a y,' while ∃y∀x means 'there exists a y such that for all x.' Fix: Carefully analyze the intended meaning and ensure the quantifier order matches the logical statement.
  • Mistake: Misapplying negation to quantifiers (e.g., ¬∀x P(x) ≡ ∃x ¬P(x)). Why it's wrong: Forgetting De Morgan's laws for quantifiers leads to incorrect logical equivalences. Fix: Remember that ¬∀x P(x) is equivalent to ∃x ¬P(x) and ¬∃x P(x) is equivalent to ∀x ¬P(x).
  • Mistake: Assuming a variable is free when it is bound by a quantifier. Why it's wrong: This leads to incorrect interpretations of formulas, especially in nested quantifiers. Fix: Always check if a variable is within the scope of a quantifier before treating it as free.
  • Mistake: Overlooking domain restrictions in quantified statements. Why it's wrong: Quantifiers apply only within a specified domain, and ignoring this can lead to false conclusions. Fix: Explicitly define the domain of discourse for each quantified variable.
  • Mistake: Treating implications (→) as biconditionals (↔) in quantified statements. Why it's wrong: Implications are one-directional, while biconditionals require mutual truth. Fix: Distinguish between 'if' (→) and 'if and only if' (↔) in logical statements.

Interview questions

What is predicate logic, and how does it differ from propositional logic?

Predicate logic, also known as first-order logic, is an extension of propositional logic that allows us to reason about objects, their properties, and relationships between them. Unlike propositional logic, which deals with whole statements that are either true or false, predicate logic introduces predicates, quantifiers, and variables to express more complex ideas. For example, in propositional logic, we might say 'It is raining' as a single statement. In predicate logic, we can say 'For all x, if x is a person, then x gets wet when it rains,' using predicates like 'is a person' and quantifiers like 'for all.' This added expressiveness makes predicate logic far more powerful for formal reasoning in mathematics, computer science, and philosophy.

Explain the two main quantifiers in predicate logic and provide an example of each.

The two main quantifiers in predicate logic are the universal quantifier, denoted by ∀, and the existential quantifier, denoted by ∃. The universal quantifier ∀ means 'for all' or 'for every,' and it is used to state that a predicate holds true for every element in a given domain. For example, ∀x (Person(x) → Mortal(x)) means 'For every x, if x is a person, then x is mortal.' The existential quantifier ∃ means 'there exists' or 'for some,' and it is used to state that there is at least one element in the domain for which the predicate holds true. For example, ∃x (Person(x) ∧ Happy(x)) means 'There exists an x such that x is a person and x is happy.' These quantifiers are fundamental for expressing generalizations and specific instances in formal reasoning.

How would you translate the English sentence 'Some students did not pass the exam' into predicate logic?

To translate the sentence 'Some students did not pass the exam' into predicate logic, we first identify the predicates and quantifiers involved. We can define two predicates: Student(x) meaning 'x is a student' and PassedExam(x) meaning 'x passed the exam.' The phrase 'some students' suggests the use of the existential quantifier ∃, and 'did not pass' is the negation of PassedExam(x). Putting this together, the translation is: ∃x (Student(x) ∧ ¬PassedExam(x)). This reads as 'There exists an x such that x is a student and x did not pass the exam.' The key here is recognizing that 'some' implies existence, and 'did not pass' requires negating the predicate for passing the exam.

Compare the use of universal quantification with implication versus conjunction. Why is implication often preferred in formal reasoning?

In predicate logic, universal quantification can be combined with either implication (→) or conjunction (∧), but implication is far more common and useful in formal reasoning. For example, consider the statement 'All humans are mortal.' Using implication, this is written as ∀x (Human(x) → Mortal(x)), which means 'For every x, if x is human, then x is mortal.' Using conjunction, it would be ∀x (Human(x) ∧ Mortal(x)), which incorrectly means 'For every x, x is human and x is mortal.' The conjunction version is problematic because it claims that *everything* in the domain is both human and mortal, which is not what we intend. Implication, on the other hand, correctly states that *if* something is human, *then* it is mortal, without making claims about non-human objects. This makes implication the preferred choice for expressing general rules or properties in formal reasoning.

Explain how you would prove the validity of the argument: 'All birds can fly. Tweety is a bird. Therefore, Tweety can fly.' using predicate logic.

To prove the validity of this argument using predicate logic, we first formalize the premises and conclusion. Let Bird(x) mean 'x is a bird' and CanFly(x) mean 'x can fly.' The premises are: 1) ∀x (Bird(x) → CanFly(x)) ('All birds can fly') and 2) Bird(Tweety) ('Tweety is a bird'). The conclusion is CanFly(Tweety) ('Tweety can fly'). The proof proceeds as follows: From the first premise, we apply universal instantiation to substitute Tweety for x, yielding Bird(Tweety) → CanFly(Tweety). We then use the second premise, Bird(Tweety), to apply modus ponens, which gives us CanFly(Tweety). This shows that the conclusion logically follows from the premises, proving the argument's validity. The key steps are universal instantiation and modus ponens, which are fundamental rules of inference in predicate logic.

How would you express the statement 'There is exactly one person who is the president' in predicate logic? Explain the reasoning behind your translation.

To express 'There is exactly one person who is the president' in predicate logic, we need to capture two ideas: existence and uniqueness. First, we use the existential quantifier ∃ to state that there is at least one person who is the president: ∃x (Person(x) ∧ President(x)). However, this alone does not guarantee uniqueness. To ensure there is exactly one such person, we add a second part stating that for any other y, if y is also the president, then y must be identical to x. This is written as ∀y (President(y) → y = x). Combining these, the full translation is: ∃x (Person(x) ∧ President(x) ∧ ∀y (President(y) → y = x)). This reads as 'There exists an x such that x is a person and x is the president, and for all y, if y is the president, then y is equal to x.' The first part ensures existence, while the second part ensures uniqueness by ruling out any other distinct individuals who might also be the president.

All Reasoning interview questions →

Check yourself

1. Which of the following correctly expresses 'Every student has a teacher they admire' in predicate logic?

  • A.∀x (Student(x) → ∃y (Teacher(y) ∧ Admires(x, y)))
  • B.∃y (Teacher(y) ∧ ∀x (Student(x) → Admires(x, y)))
  • C.∀x ∃y (Student(x) ∧ Teacher(y) ∧ Admires(x, y))
  • D.∃y ∀x (Student(x) → Teacher(y) ∧ Admires(x, y))
Show answer

A. ∀x (Student(x) → ∃y (Teacher(y) ∧ Admires(x, y)))
The correct answer is the first option because it states that for every student x, there exists a teacher y such that x admires y. The second option incorrectly suggests there is one teacher admired by all students. The third option misplaces the quantifiers and uses ∧ instead of →. The fourth option is similar to the second and also incorrect.

2. What is the negation of the statement 'For every integer x, there exists an integer y such that x + y = 0'?

  • A.There exists an integer x such that for every integer y, x + y ≠ 0
  • B.For every integer x, there does not exist an integer y such that x + y = 0
  • C.There exists an integer x and an integer y such that x + y ≠ 0
  • D.For every integer x, and for every integer y, x + y ≠ 0
Show answer

A. There exists an integer x such that for every integer y, x + y ≠ 0
The correct answer is the first option because the negation of ∀x∃y P(x, y) is ∃x∀y ¬P(x, y). The second option negates the inner quantifier incorrectly. The third option is not a proper negation. The fourth option is overly strong and incorrect.

3. Consider the statement 'Some cats are black.' Which of the following is logically equivalent to its negation?

  • A.No cats are black
  • B.All cats are not black
  • C.There are no black cats
  • D.Not all cats are black
Show answer

B. All cats are not black
The correct answer is the second option because the negation of 'Some cats are black' (∃x (Cat(x) ∧ Black(x))) is 'All cats are not black' (∀x (Cat(x) → ¬Black(x))). The first and third options are equivalent to the correct answer but less precise. The fourth option is not the negation of the original statement.

4. Which of the following statements is true if the domain is all real numbers and P(x) is 'x > 0'?

  • A.∀x P(x) → ∃x P(x)
  • B.∃x P(x) → ∀x P(x)
  • C.∀x P(x) ∧ ∃x ¬P(x)
  • D.∃x P(x) ∧ ∀x ¬P(x)
Show answer

A. ∀x P(x) → ∃x P(x)
The correct answer is the first option because if all x are greater than 0, then there certainly exists an x greater than 0. The second option is false because the existence of a positive x does not imply all x are positive. The third option is a contradiction. The fourth option is also a contradiction.

5. What is the correct interpretation of the statement '∃x (P(x) ∧ ∀y (Q(y) → R(x, y)))'?

  • A.There exists an x such that P(x) is true, and for all y, if Q(y) is true, then R(x, y) is true
  • B.For all y, Q(y) is true, and there exists an x such that P(x) and R(x, y) are true
  • C.There exists an x such that P(x) is true, and R(x, y) is true for some y where Q(y) is true
  • D.For all x, P(x) is true, and there exists a y such that Q(y) implies R(x, y)
Show answer

A. There exists an x such that P(x) is true, and for all y, if Q(y) is true, then R(x, y) is true
The correct answer is the first option because the statement says there exists an x satisfying P(x), and for every y, if Q(y) holds, then R(x, y) holds. The second option misplaces the quantifiers. The third option incorrectly suggests R(x, y) holds for some y, not all. The fourth option changes the quantifier scope incorrectly.

Take the full Reasoning quiz →

← PreviousEthical Reasoning and Moral DilemmasNext →Modal Logic: Possibility and Necessity

Reasoning

36 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app