Module 4 – Class 1: Sets and Membership

Learning Objectives

  • Define sets, membership, the empty set and subset relations.
  • Prove set equality using double inclusion ($A \subseteq B$ and $B \subseteq A$).
  • Translate set concepts to Java's Set<T> interface.
  • Apply element-chasing proofs to verify set relationships.
  • Implement isSubset, union, intersection in Java and verify properties.

Concept Overview

What Is a Set?

A set is an unordered collection of distinct elements. Two sets are equal if and only if they contain the same elements.

$A = B \iff (\forall x : x \in A \leftrightarrow x \in B)$
Term Symbol Meaning
Membership $x \in A$ $x$ is an element of $A$
Empty set $\emptyset$ or $\{\}$ The set with no elements
Subset $A \subseteq B$ Every element of $A$ is in $B$
Proper subset $A \subset B$ $A \subseteq B$ and $A \neq B$
Set equality $A = B$ $A \subseteq B$ and $B \subseteq A$
Cardinality $|A|$ Number of elements in $A$

Roster and Set-Builder Notation

  • Roster notation: $A = \{1, 2, 3\}$
  • Set-builder notation: $A = \{x \in \mathbb{Z} \mid x > 0 \text{ and } x \leq 3\}$

Key Properties

  1. No duplicates: $\{1, 1, 2\} = \{1, 2\}$.
  2. No order: $\{1, 2, 3\} = \{3, 1, 2\}$.
  3. Sets can contain sets: $\{1, \{2, 3\}\}$ has two elements.

Subsets

$A \subseteq B$ means $\forall x : x \in A \rightarrow x \in B$.

To prove $A \subseteq B$: Take an arbitrary $x \in A$ and show $x \in B$.

To disprove $A \subseteq B$: Find a specific $x \in A$ with $x \notin B$ (counterexample).

Set Equality via Double Inclusion

To prove $A = B$:

  1. Show $A \subseteq B$ (every element of $A$ is in $B$).
  2. Show $B \subseteq A$ (every element of $B$ is in $A$).

Why this matters in CS:

  • Sets model collections of unique items: user IDs, permissions, states, visited nodes.
  • Database queries use set semantics (SQL DISTINCT, UNION, INTERSECT).
  • Type systems use subsets: "Integer is a subset of Number."

Formal Notation

Expression Meaning
$\{x \in S \mid P(x)\}$ Set of elements in $S$ satisfying predicate $P$
$A \subseteq B$ $\forall x (x \in A \rightarrow x \in B)$
$A = B$ $\forall x (x \in A \leftrightarrow x \in B)$
$\|A\|$ Number of elements in finite set $A$
$\emptyset$ The unique set with no elements

Worked Examples

Example 1: Proving a Subset Relationship

Claim: If $A = \{x \in \mathbb{Z} \mid x \text{ is divisible by } 6\}$ and $B = \{x \in \mathbb{Z} \mid x \text{ is divisible by } 3\}$, then $A \subseteq B$.

Proof. Let $x \in A$. Then $6 \mid x$, so $x = 6k$ for some $k \in \mathbb{Z}$. But $x = 6k = 3(2k)$, and since $2k \in \mathbb{Z}$, we have $3 \mid x$, so $x \in B$. Since $x$ was arbitrary, $A \subseteq B$. $\blacksquare$

Example 2: Disproving a Subset

Claim: $B \subseteq A$ (with $A$, $B$ as above).

Disproof. Counterexample: $9 \in B$ (since $3 \mid 9$) but $9 \notin A$ (since $6 \nmid 9$). So $B \not\subseteq A$. $\blacksquare$

Example 3: Set Equality by Double Inclusion

Claim: $\{x \in \mathbb{Z} \mid x^2 = x\} = \{0, 1\}$.

Proof.

  • ($\subseteq$): If $x^2 = x$, then $x^2 - x = 0$, so $x(x-1) = 0$, giving $x = 0$ or $x = 1$.
  • ($\supseteq$): $0^2 = 0$ ✓ and $1^2 = 1$ ✓.

Both inclusions hold, so the sets are equal. $\blacksquare$

Example 4: Empty Set Is a Subset of Every Set

Claim: $\emptyset \subseteq A$ for any set $A$.

Proof. We must show $\forall x (x \in \emptyset \rightarrow x \in A)$. Since $x \in \emptyset$ is always false, the implication is vacuously true. $\blacksquare$

Example 5: Connecting to Module 1 — Divisor Sets

Claim: For positive integer $n$, let $D(n) = \{d \in \mathbb{Z}^+ \mid d \text{ divides } n\}$. If $a \mid b$, then $D(a) \subseteq D(b)$.

Proof. Let $d \in D(a)$, so $d \mid a$. Since $a \mid b$, by transitivity of divisibility (Module 1, Class 2), $d \mid b$, so $d \in D(b)$. $\blacksquare$


Proof Techniques Spotlight

Element-Chasing

The standard technique for proving set relationships:

To prove $A \subseteq B$:

"Let $x \in A$. [Show that $x$ satisfies the conditions for membership in $B$.] Therefore $x \in B$."

To prove $A = B$:

"($\subseteq$): Let $x \in A$. ... Therefore $x \in B$.

($\supseteq$): Let $x \in B$. ... Therefore $x \in A$.

By double inclusion, $A = B$."

To prove $A \cap B \subseteq C$:

"Let $x \in A \cap B$. Then $x \in A$ and $x \in B$. [Use both facts to show $x \in C$.]"


Java Deep Dive

import java.util.*;
import java.util.stream.*;

public class SetMembershipLibrary {

    // --- Membership and Subset ---

    /**
     * Check whether every element of A is contained in B.
     * Implements: A ⊆ B ≡ ∀x (x ∈ A → x ∈ B)
     */
    public static <T> boolean isSubset(Set<T> a, Set<T> b) {
        for (T x : a) {
            if (!b.contains(x)) return false;
        }
        return true;
    }

    /**
     * Check set equality via double inclusion.
     * A = B iff A ⊆ B and B ⊆ A
     */
    public static <T> boolean setEquals(Set<T> a, Set<T> b) {
        return isSubset(a, b) && isSubset(b, a);
    }

    // --- Set Construction ---

    /**
     * Build a set from a predicate (set-builder notation).
     * { x ∈ universe | predicate(x) }
     */
    public static <T> Set<T> setBuilder(Set<T> universe,
                                         java.util.function.Predicate<T> predicate) {
        Set<T> result = new HashSet<>();
        for (T x : universe) {
            if (predicate.test(x)) result.add(x);
        }
        return result;
    }

    /**
     * Compute the set of positive divisors of n.
     * D(n) = { d ∈ Z+ | d divides n }
     * Connects to Module 1.
     */
    public static Set<Integer> divisorSet(int n) {
        Set<Integer> result = new TreeSet<>();
        for (int d = 1; d <= Math.abs(n); d++) {
            if (n % d == 0) result.add(d);
        }
        return result;
    }

    // --- Intersection and Union ---

    /**
     * A ∩ B = { x | x ∈ A and x ∈ B }
     * Returns a new set (does not mutate inputs).
     */
    public static <T> Set<T> intersection(Set<T> a, Set<T> b) {
        Set<T> result = new HashSet<>(a);
        result.retainAll(b);
        return result;
    }

    /**
     * A ∪ B = { x | x ∈ A or x ∈ B }
     * Returns a new set (does not mutate inputs).
     */
    public static <T> Set<T> union(Set<T> a, Set<T> b) {
        Set<T> result = new HashSet<>(a);
        result.addAll(b);
        return result;
    }

    /**
     * A \ B = { x | x ∈ A and x ∉ B }
     */
    public static <T> Set<T> difference(Set<T> a, Set<T> b) {
        Set<T> result = new HashSet<>(a);
        result.removeAll(b);
        return result;
    }

    // --- Verification Methods ---

    /**
     * Verify A ∩ B ⊆ A (a basic set identity).
     */
    public static <T> boolean verifyIntersectionSubset(Set<T> a, Set<T> b) {
        Set<T> inter = intersection(a, b);
        return isSubset(inter, a);
    }

    /**
     * Verify: if a | b then D(a) ⊆ D(b).
     * Connects divisibility (Module 1) with set theory.
     */
    public static boolean verifyDivisorSubset(int a, int b) {
        if (b % a != 0) return false;  // a does not divide b
        return isSubset(divisorSet(a), divisorSet(b));
    }

    // --- Demonstration ---

    public static void main(String[] args) {
        System.out.println("=== Set Membership Library ===\n");

        // Basic sets
        Set<Integer> a = new HashSet<>(Arrays.asList(1, 2, 3, 4));
        Set<Integer> b = new HashSet<>(Arrays.asList(2, 3, 4, 5, 6));
        Set<Integer> c = new HashSet<>(Arrays.asList(1, 2, 3));

        System.out.println("A = " + a);
        System.out.println("B = " + b);
        System.out.println("C = " + c);

        // Subset tests
        System.out.println("\nC ⊆ A? " + isSubset(c, a));       // true
        System.out.println("A ⊆ B? " + isSubset(a, b));         // false (1 ∉ B)

        // Set operations
        System.out.println("\nA ∩ B = " + intersection(a, b));   // {2,3,4}
        System.out.println("A ∪ B = " + union(a, b));            // {1,2,3,4,5,6}
        System.out.println("A \\ B = " + difference(a, b));      // {1}

        // Verify A ∩ B ⊆ A
        System.out.println("\nA ∩ B ⊆ A? " + verifyIntersectionSubset(a, b));

        // Set-builder notation
        Set<Integer> universe = IntStream.rangeClosed(1, 20)
                .boxed().collect(Collectors.toSet());
        Set<Integer> evens = setBuilder(universe, n -> n % 2 == 0);
        Set<Integer> divBy3 = setBuilder(universe, n -> n % 3 == 0);
        System.out.println("\nEvens in [1,20]: " + new TreeSet<>(evens));
        System.out.println("Div by 3 in [1,20]: " + new TreeSet<>(divBy3));
        System.out.println("Even ∩ DivBy3: " + new TreeSet<>(intersection(evens, divBy3)));

        // Divisor sets (connecting to Module 1)
        System.out.println("\nD(12) = " + divisorSet(12));
        System.out.println("D(6)  = " + divisorSet(6));
        System.out.println("6 | 12? " + (12 % 6 == 0));
        System.out.println("D(6) ⊆ D(12)? " + verifyDivisorSubset(6, 12));
    }
}

Historical Context

Georg Cantor (1845–1918) created set theory in the 1870s–1880s, defining a set as "a gathering together into a whole of definite, distinct objects of our perception or thought." His work on infinite sets (countable vs. uncountable) sparked a revolution in mathematics.

Ernst Zermelo and Abraham Fraenkel formalized set theory axiomatically (ZF/ZFC) in the early 20th century, addressing paradoxes like Russell's paradox ($\{x \mid x \notin x\}$).

In computer science, sets appear everywhere: hash sets, tree sets, bit vectors. Java's Set<T> interface directly mirrors the mathematical concept: contains() for $\in$, addAll() for $\cup$, retainAll() for $\cap$.


Slide-Ready Problem Sets

Slide Set A: Conceptual Questions

A1. Let $A = \{1, 2, 3\}$, $B = \{2, 3, 4\}$. Is $A \subseteq B$? Is $B \subseteq A$? Is $A = B$?

A2. How many subsets does $\{a, b, c\}$ have? List them all.

A3. True or false: $\emptyset \in \{1, 2, 3\}$. True or false: $\emptyset \subseteq \{1, 2, 3\}$.

A4. If $|A| = 5$ and $A \subseteq B$, what is the minimum possible value of $|B|$?

Slide Set B: Proof Problems

B1. Prove: If $A \subseteq B$ and $B \subseteq C$, then $A \subseteq C$ (transitivity of subset).

B2. Prove: $A \cap B \subseteq A$ for any sets $A$ and $B$.

B3. Prove or disprove: If $A \subseteq B$ and $A \subseteq C$, then $A \subseteq B \cap C$.

Slide Set C: Java Coding Problems

C1. Write a method <T> Set<T> symmetricDifference(Set<T> a, Set<T> b) that returns elements in exactly one of the two sets.

C2. Write a method that takes a List<Integer> and returns a Set<Integer> of duplicates.

C3. Implement divisorSet(int n) and verify that D(6) ⊆ D(12).


Full Problem Set

Discrete Math Problems

DM1. Let $A = \{1, 2, 3, 4, 5\}$, $B = \{3, 4, 5, 6, 7\}$. Compute $A \cap B$, $A \cup B$, $A \setminus B$, $B \setminus A$.

DM2. Prove by element-chasing: $A \cap (B \cup C) \supseteq (A \cap B) \cup (A \cap C)$.

DM3. Prove that $A \subseteq B$ if and only if $A \cap B = A$.

DM4. Let $E = \{n \in \mathbb{Z} \mid n \text{ is even}\}$ and $O = \{n \in \mathbb{Z} \mid n \text{ is odd}\}$. Prove $E \cap O = \emptyset$ and $E \cup O = \mathbb{Z}$.

DM5. Prove that $|\mathcal{P}(\emptyset)| = 1$ and identify the single element of $\mathcal{P}(\emptyset)$.

DM6. Prove: $A \setminus B = A \cap \overline{B}$ (where $\overline{B}$ is the complement of $B$ relative to a universal set $U$).

Java Programming Problems

JP1. Write a method boolean isSubset(Set<Integer> a, Set<Integer> b) and test with at least 5 pairs of sets.

JP2. Implement set-builder notation: Set<Integer> setBuilder(int low, int high, Predicate<Integer> p) returning all integers in $[\text{low}, \text{high}]$ satisfying $p$. Use it to build the set of primes less than 100.

JP3. Write a method that, given two sets $A$ and $B$, verifies the identity $|A \cup B| = |A| + |B| - |A \cap B|$ by computing both sides.

JP4. Implement divisorSet(int n) and write tests verifying: if $a | b$ then $D(a) \subseteq D(b)$. Test for $a = 6, b = 30$ and $a = 4, b = 12$.

JP5. Write a method that partitions a set of integers into two subsets: primes and composites (connecting to Module 1).

Bridge Problems

BR1. Prove mathematically that for positive integers $a$ and $b$, $D(\gcd(a,b)) = D(a) \cap D(b)$. Then write Java code to verify this for all pairs $(a,b)$ with $1 \leq a, b \leq 50$.

BR2. Prove: the set of all linear combinations $\{ax + by \mid x, y \in \mathbb{Z}\}$ equals the set of all multiples of $\gcd(a,b)$. Write a Java method that generates both sets for $a, b \leq 20$ and verifies equality (for sufficiently many values).


Solutions

Discrete Math Solutions

DM1. $A \cap B = \{3, 4, 5\}$. $A \cup B = \{1, 2, 3, 4, 5, 6, 7\}$. $A \setminus B = \{1, 2\}$. $B \setminus A = \{6, 7\}$.

DM2. Let $x \in (A \cap B) \cup (A \cap C)$. Then $x \in A \cap B$ or $x \in A \cap C$.

  • Case 1: $x \in A \cap B$. Then $x \in A$ and $x \in B$. Since $x \in B$, $x \in B \cup C$. So $x \in A \cap (B \cup C)$.
  • Case 2: $x \in A \cap C$. Then $x \in A$ and $x \in C \subseteq B \cup C$. So $x \in A \cap (B \cup C)$.

In both cases, $x \in A \cap (B \cup C)$. $\blacksquare$

DM3. ($\Rightarrow$): Assume $A \subseteq B$. Let $x \in A \cap B$, then $x \in A$, so $A \cap B \subseteq A$. Now let $x \in A$. Since $A \subseteq B$, $x \in B$, so $x \in A \cap B$. Thus $A \subseteq A \cap B$. By double inclusion, $A \cap B = A$.

($\Leftarrow$): Assume $A \cap B = A$. Let $x \in A$. Then $x \in A \cap B$ (since $A = A \cap B$), so $x \in B$. Thus $A \subseteq B$. $\blacksquare$

DM4. ($E \cap O = \emptyset$): Suppose $n \in E \cap O$. Then $2 | n$ and $n = 2k+1$. So $2 | (2k+1)$, meaning $2k+1 = 2m$, giving $1 = 2(m-k)$. But $|2(m-k)| \geq 2$ or $= 0$, so no integer satisfies this. Contradiction.

($E \cup O = \mathbb{Z}$): For any $n \in \mathbb{Z}$, by the quotient-remainder theorem (Module 2), $n = 2q + r$ where $r \in \{0, 1\}$. If $r = 0$, $n \in E$. If $r = 1$, $n \in O$. $\blacksquare$

DM5. $\mathcal{P}(\emptyset) = \{\emptyset\}$. It has exactly one element (the empty set itself is the only subset of the empty set). $|\mathcal{P}(\emptyset)| = 2^0 = 1$. $\blacksquare$

Java Solutions

JP2.

public static Set<Integer> setBuilder(int low, int high,
                                       Predicate<Integer> p) {
    Set<Integer> result = new TreeSet<>();
    for (int i = low; i <= high; i++) {
        if (p.test(i)) result.add(i);
    }
    return result;
}

// Primes less than 100
Set<Integer> primes = setBuilder(2, 99, n -> {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++)
        if (n % i == 0) return false;
    return true;
});

BR1.

// Verify D(gcd(a,b)) = D(a) ∩ D(b)
for (int a = 1; a <= 50; a++) {
    for (int b = 1; b <= 50; b++) {
        int g = gcd(a, b);
        Set<Integer> dGcd = divisorSet(g);
        Set<Integer> inter = intersection(divisorSet(a), divisorSet(b));
        assert dGcd.equals(inter)
            : "Failed for a=" + a + ", b=" + b;
    }
}

Module 4 – Class 2: Set Operations and Distributive Laws

Learning Objectives

  • Compute union, intersection, difference, complement and Cartesian product.
  • Prove the distributive laws using double inclusion and element-chasing.
  • Translate set operations to Java's HashSet methods.
  • Understand how set operations underlie database queries and search.
  • Verify set identities programmatically.

Concept Overview

Set Operations

Operation Notation Definition
Union $A \cup B$ $\{x \mid x \in A \text{ or } x \in B\}$
Intersection $A \cap B$ $\{x \mid x \in A \text{ and } x \in B\}$
Difference $A \setminus B$ $\{x \mid x \in A \text{ and } x \notin B\}$
Complement $\overline{A}$ or $A^c$ $\{x \in U \mid x \notin A\}$ (relative to universe $U$)
Symmetric Difference $A \triangle B$ $(A \setminus B) \cup (B \setminus A)$
Cartesian Product $A \times B$ $\{(a, b) \mid a \in A \text{ and } b \in B\}$

Core Identities

Commutative laws:

  • $A \cup B = B \cup A$
  • $A \cap B = B \cap A$

Associative laws:

  • $(A \cup B) \cup C = A \cup (B \cup C)$
  • $(A \cap B) \cap C = A \cap (B \cap C)$

Distributive laws:

  • $A \cap (B \cup C) = (A \cap B) \cup (A \cap C)$
  • $A \cup (B \cap C) = (A \cup B) \cap (A \cup C)$

De Morgan's laws for sets:

  • $\overline{A \cup B} = \overline{A} \cap \overline{B}$
  • $\overline{A \cap B} = \overline{A} \cup \overline{B}$

Absorption laws:

  • $A \cup (A \cap B) = A$
  • $A \cap (A \cup B) = A$

Cartesian Product

$A \times B = \{(a, b) \mid a \in A, b \in B\}$

$|A \times B| = |A| \cdot |B|$

In Java, the Cartesian product corresponds to nested loops.

Why this matters in CS:

  • Database joins are Cartesian products filtered by predicates.
  • SQL UNION, INTERSECT, EXCEPT map directly to $\cup$, $\cap$, $\setminus$.
  • Bitwise operations on bit masks implement set operations on sets of flags.

Formal Notation

Distributive law (first form):

$A \cap (B \cup C) = (A \cap B) \cup (A \cap C)$

Proof pattern: show $\text{LHS} \subseteq \text{RHS}$ and $\text{RHS} \subseteq \text{LHS}$.


Worked Examples

Example 1: Distributive Law — Full Proof

Claim: $A \cap (B \cup C) = (A \cap B) \cup (A \cap C)$

Proof.

($\subseteq$): Let $x \in A \cap (B \cup C)$. Then $x \in A$ and $x \in B \cup C$.

  • Case 1: $x \in B$. Then $x \in A$ and $x \in B$, so $x \in A \cap B \subseteq (A \cap B) \cup (A \cap C)$.
  • Case 2: $x \in C$. Then $x \in A$ and $x \in C$, so $x \in A \cap C \subseteq (A \cap B) \cup (A \cap C)$.

($\supseteq$): Let $x \in (A \cap B) \cup (A \cap C)$.

  • Case 1: $x \in A \cap B$. Then $x \in A$ and $x \in B \subseteq B \cup C$. So $x \in A \cap (B \cup C)$.
  • Case 2: $x \in A \cap C$. Then $x \in A$ and $x \in C \subseteq B \cup C$. So $x \in A \cap (B \cup C)$.

By double inclusion, $A \cap (B \cup C) = (A \cap B) \cup (A \cap C)$. $\blacksquare$

Example 2: De Morgan's Law for Sets

Claim: $\overline{A \cup B} = \overline{A} \cap \overline{B}$ (relative to universe $U$).

Proof.

($\subseteq$): Let $x \in \overline{A \cup B}$. Then $x \notin A \cup B$, so $x \notin A$ and $x \notin B$. Thus $x \in \overline{A}$ and $x \in \overline{B}$, giving $x \in \overline{A} \cap \overline{B}$.

($\supseteq$): Let $x \in \overline{A} \cap \overline{B}$. Then $x \notin A$ and $x \notin B$. So $x \notin A \cup B$, giving $x \in \overline{A \cup B}$. $\blacksquare$

Example 3: Set Difference Identity

Claim: $A \setminus (B \cup C) = (A \setminus B) \cap (A \setminus C)$.

Proof.

($\subseteq$): Let $x \in A \setminus (B \cup C)$. Then $x \in A$ and $x \notin B \cup C$. So $x \notin B$ and $x \notin C$. Thus $x \in A \setminus B$ and $x \in A \setminus C$, giving $x \in (A \setminus B) \cap (A \setminus C)$.

($\supseteq$): Let $x \in (A \setminus B) \cap (A \setminus C)$. Then $x \in A$, $x \notin B$, $x \notin C$. So $x \notin B \cup C$, giving $x \in A \setminus (B \cup C)$. $\blacksquare$

Example 4: Cartesian Product

Problem: Let $A = \{1, 2\}$, $B = \{a, b, c\}$. Compute $A \times B$ and $|A \times B|$.

$A \times B = \{(1,a), (1,b), (1,c), (2,a), (2,b), (2,c)\}$

$|A \times B| = 2 \cdot 3 = 6$

Example 5: Connecting Set Operations to Logic

Set Operation Logical Connective Java Operator
$A \cup B$ $P \vee Q$ a.addAll(b)
$A \cap B$ $P \wedge Q$ a.retainAll(b)
$\overline{A}$ $\neg P$ U.removeAll(a)
$A \setminus B$ $P \wedge \neg Q$ a.removeAll(b)

De Morgan's laws for sets follow from De Morgan's laws for logic (Module 3)!


Proof Techniques Spotlight

Double Inclusion with Case Analysis

Many set identity proofs require splitting into cases based on which sets an element belongs to. The pattern:

  1. Goal: Prove $X = Y$.
  2. ($\subseteq$): Take $x \in X$. Analyze cases from the definition of $X$.
  3. ($\supseteq$): Take $x \in Y$. Analyze cases from the definition of $Y$.

Tip: If a definition involves "or" (union), split into cases. If it involves "and" (intersection), use both facts together.


Java Deep Dive

import java.util.*;
import java.util.stream.*;

public class SetOperationsLibrary {

    // --- Core Operations (non-mutating) ---

    public static <T> Set<T> union(Set<T> a, Set<T> b) {
        Set<T> result = new HashSet<>(a);
        result.addAll(b);
        return result;
    }

    public static <T> Set<T> intersection(Set<T> a, Set<T> b) {
        Set<T> result = new HashSet<>(a);
        result.retainAll(b);
        return result;
    }

    public static <T> Set<T> difference(Set<T> a, Set<T> b) {
        Set<T> result = new HashSet<>(a);
        result.removeAll(b);
        return result;
    }

    public static <T> Set<T> complement(Set<T> a, Set<T> universe) {
        return difference(universe, a);
    }

    public static <T> Set<T> symmetricDifference(Set<T> a, Set<T> b) {
        return union(difference(a, b), difference(b, a));
    }

    /**
     * Cartesian product A × B.
     * Each pair is represented as a two-element list [a, b].
     */
    public static <S, T> Set<List<Object>> cartesianProduct(Set<S> a, Set<T> b) {
        Set<List<Object>> result = new HashSet<>();
        for (S x : a) {
            for (T y : b) {
                result.add(Arrays.asList(x, y));
            }
        }
        return result;
    }

    // --- Identity Verification ---

    /**
     * Verify distributive law: A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C)
     */
    public static <T> boolean verifyDistributive(Set<T> a, Set<T> b, Set<T> c) {
        Set<T> lhs = intersection(a, union(b, c));
        Set<T> rhs = union(intersection(a, b), intersection(a, c));
        return lhs.equals(rhs);
    }

    /**
     * Verify De Morgan: complement(A ∪ B) = complement(A) ∩ complement(B)
     */
    public static <T> boolean verifyDeMorgan(Set<T> a, Set<T> b, Set<T> universe) {
        Set<T> lhs = complement(union(a, b), universe);
        Set<T> rhs = intersection(complement(a, universe), complement(b, universe));
        return lhs.equals(rhs);
    }

    /**
     * Verify: A \ (B ∪ C) = (A \ B) ∩ (A \ C)
     */
    public static <T> boolean verifyDiffDistributive(Set<T> a, Set<T> b, Set<T> c) {
        Set<T> lhs = difference(a, union(b, c));
        Set<T> rhs = intersection(difference(a, b), difference(a, c));
        return lhs.equals(rhs);
    }

    /**
     * Verify inclusion-exclusion: |A ∪ B| = |A| + |B| - |A ∩ B|
     */
    public static <T> boolean verifyInclusionExclusion(Set<T> a, Set<T> b) {
        int lhs = union(a, b).size();
        int rhs = a.size() + b.size() - intersection(a, b).size();
        return lhs == rhs;
    }

    // --- Demonstration ---

    public static void main(String[] args) {
        System.out.println("=== Set Operations Library ===\n");

        Set<Integer> a = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
        Set<Integer> b = new HashSet<>(Arrays.asList(3, 4, 5, 6, 7));
        Set<Integer> c = new HashSet<>(Arrays.asList(5, 6, 7, 8, 9));
        Set<Integer> u = IntStream.rangeClosed(1, 10).boxed()
                .collect(Collectors.toSet());

        System.out.println("A = " + new TreeSet<>(a));
        System.out.println("B = " + new TreeSet<>(b));
        System.out.println("C = " + new TreeSet<>(c));
        System.out.println("U = " + new TreeSet<>(u));

        // Operations
        System.out.println("\nA ∪ B = " + new TreeSet<>(union(a, b)));
        System.out.println("A ∩ B = " + new TreeSet<>(intersection(a, b)));
        System.out.println("A \\ B = " + new TreeSet<>(difference(a, b)));
        System.out.println("A △ B = " + new TreeSet<>(symmetricDifference(a, b)));
        System.out.println("complement(A) = " + new TreeSet<>(complement(a, u)));

        // Verify identities
        System.out.println("\n--- Identity Verification ---");
        System.out.println("Distributive: " + verifyDistributive(a, b, c));
        System.out.println("De Morgan: " + verifyDeMorgan(a, b, u));
        System.out.println("Diff Distributive: " + verifyDiffDistributive(a, b, c));
        System.out.println("Inclusion-Exclusion: " + verifyInclusionExclusion(a, b));

        // Cartesian product
        Set<String> colors = new HashSet<>(Arrays.asList("R", "G", "B"));
        Set<Integer> sizes = new HashSet<>(Arrays.asList(1, 2));
        System.out.println("\nColors × Sizes = " + cartesianProduct(colors, sizes));
        System.out.println("|Colors × Sizes| = " + cartesianProduct(colors, sizes).size()
                + " (expected " + (colors.size() * sizes.size()) + ")");
    }
}

Historical Context

George Boole (1815–1864) developed Boolean algebra, which treats logical operations as algebraic operations on truth values. The deep parallel between set algebra and Boolean algebra was recognized by Boole himself and later by Augustus De Morgan.

De Morgan's laws were originally stated for propositions (Module 3, Class 1), but they translate directly to sets:

  • Logic: $\neg(P \wedge Q) \equiv \neg P \vee \neg Q$
  • Sets: $\overline{A \cap B} = \overline{A} \cup \overline{B}$

This parallel is not a coincidence — both propositional logic and set algebra are instances of Boolean algebra, an algebraic structure with two binary operations satisfying the same axioms.

SQL (1970s) adopted set semantics from relational algebra, which Edgar Codd based directly on set theory and first-order logic.


Slide-Ready Problem Sets

Slide Set A: Conceptual Questions

A1. Let $A = \{1,2,3\}$, $B = \{2,3,4\}$, $C = \{3,4,5\}$. Compute $A \cap (B \cup C)$ and $(A \cap B) \cup (A \cap C)$. Are they equal?

A2. Compute $|A \times B|$ where $A = \{x, y\}$ and $B = \{1, 2, 3, 4\}$.

A3. If $U = \{1,\ldots,10\}$ and $A = \{2,4,6,8,10\}$, what is $\overline{A}$?

Slide Set B: Proof Problems

B1. Prove: $A \cup (A \cap B) = A$ (absorption law).

B2. Prove: $A \triangle B = B \triangle A$ (symmetric difference is commutative).

B3. Prove: $A \setminus B = A \cap \overline{B}$.

Slide Set C: Java Coding Problems

C1. Write a method verifying the second distributive law: $A \cup (B \cap C) = (A \cup B) \cap (A \cup C)$.

C2. Generate all elements of $\{0,1\} \times \{0,1\} \times \{0,1\}$ (all 3-bit strings).

C3. Write a program that generates random sets $A, B, C \subseteq \{1,\ldots,20\}$ and verifies both distributive laws.


Full Problem Set

Discrete Math Problems

DM1. Prove the second distributive law: $A \cup (B \cap C) = (A \cup B) \cap (A \cup C)$.

DM2. Prove both De Morgan's laws for sets using element-chasing.

DM3. Prove: $A \triangle B = (A \cup B) \setminus (A \cap B)$.

DM4. Prove: $|A \times B| = |A| \cdot |B|$ for finite sets.

DM5. Prove: $A \setminus (B \cap C) = (A \setminus B) \cup (A \setminus C)$.

DM6. For sets $A$, $B$, $C$, prove or disprove: $A \times (B \cup C) = (A \times B) \cup (A \times C)$.

Java Programming Problems

JP1. Implement all six set operations (union, intersection, difference, complement, symmetricDifference, cartesianProduct) with non-mutating methods and test each.

JP2. Write a method that takes three sets and verifies all identities listed in the concept overview (commutative, associative, distributive, De Morgan, absorption).

JP3. Implement a BitSetOps class that represents sets as BitSet objects and implements union (OR), intersection (AND), complement (FLIP), and difference. Compare performance with HashSet for sets $\subseteq \{0, \ldots, 999\}$.

JP4. Write a method Set<List<Integer>> cartesianPower(Set<Integer> s, int n) that computes $S^n = S \times S \times \cdots \times S$ ($n$ times). Use it to enumerate all $n$-digit strings from a given alphabet.

JP5. Model a simple database query: given a List<Map<String, Object>> (list of records), implement SELECT ... WHERE as set filtering, UNION and INTERSECT using set operations.

Bridge Problems

BR1. Using Module 1's divisibility and Module 4's set theory, prove: $D(\text{lcm}(a,b)) = D(a) \cup D(b)$ (where $D(n)$ is the divisor set). Verify in Java for $1 \leq a, b \leq 30$.

BR2. Prove that De Morgan's laws for sets are equivalent to De Morgan's laws for propositional logic (Module 3). Write a Java program that demonstrates this equivalence by evaluating both the set version and the logical version on corresponding inputs.


Solutions

Discrete Math Solutions

DM1. $A \cup (B \cap C) = (A \cup B) \cap (A \cup C)$

($\subseteq$): Let $x \in A \cup (B \cap C)$.

  • Case 1: $x \in A$. Then $x \in A \cup B$ and $x \in A \cup C$, so $x \in (A \cup B) \cap (A \cup C)$.
  • Case 2: $x \in B \cap C$. Then $x \in B$ and $x \in C$. So $x \in A \cup B$ and $x \in A \cup C$, giving $x \in (A \cup B) \cap (A \cup C)$.

($\supseteq$): Let $x \in (A \cup B) \cap (A \cup C)$. Then $x \in A \cup B$ and $x \in A \cup C$.

  • If $x \in A$: then $x \in A \cup (B \cap C)$. ✓
  • If $x \notin A$: from $x \in A \cup B$, $x \in B$; from $x \in A \cup C$, $x \in C$. So $x \in B \cap C$, giving $x \in A \cup (B \cap C)$. ✓

$\blacksquare$

DM3. $A \triangle B = (A \cup B) \setminus (A \cap B)$

($\subseteq$): Let $x \in A \triangle B = (A \setminus B) \cup (B \setminus A)$.

  • Case 1: $x \in A \setminus B$. Then $x \in A$ (so $x \in A \cup B$) and $x \notin B$. Since $x \notin B$, $x \notin A \cap B$. So $x \in (A \cup B) \setminus (A \cap B)$.
  • Case 2: $x \in B \setminus A$. Symmetric argument.

($\supseteq$): Let $x \in (A \cup B) \setminus (A \cap B)$. Then $x \in A \cup B$ and $x \notin A \cap B$.

  • Since $x \in A \cup B$: $x \in A$ or $x \in B$.
  • Since $x \notin A \cap B$: not ($x \in A$ and $x \in B$).
  • If $x \in A$: then $x \notin B$ (otherwise $x \in A \cap B$). So $x \in A \setminus B$.
  • If $x \in B$: then $x \notin A$. So $x \in B \setminus A$.

Either way, $x \in A \triangle B$. $\blacksquare$

DM6. True. $A \times (B \cup C) = (A \times B) \cup (A \times C)$.

($\subseteq$): Let $(a, x) \in A \times (B \cup C)$. Then $a \in A$ and $x \in B \cup C$.

  • If $x \in B$: $(a, x) \in A \times B \subseteq (A \times B) \cup (A \times C)$.
  • If $x \in C$: $(a, x) \in A \times C \subseteq (A \times B) \cup (A \times C)$.

($\supseteq$): Let $(a, x) \in (A \times B) \cup (A \times C)$.

  • If $(a, x) \in A \times B$: $a \in A$, $x \in B \subseteq B \cup C$, so $(a, x) \in A \times (B \cup C)$.
  • If $(a, x) \in A \times C$: similarly. $\blacksquare$

Java Solutions

JP3. (BitSet implementation)

public class BitSetOps {
    private BitSet bits;
    private int universeSize;

    public BitSetOps(int universeSize) {
        this.bits = new BitSet(universeSize);
        this.universeSize = universeSize;
    }

    public BitSetOps union(BitSetOps other) {
        BitSetOps result = copy();
        result.bits.or(other.bits);
        return result;
    }

    public BitSetOps intersection(BitSetOps other) {
        BitSetOps result = copy();
        result.bits.and(other.bits);
        return result;
    }

    public BitSetOps complement() {
        BitSetOps result = copy();
        result.bits.flip(0, universeSize);
        return result;
    }

    public BitSetOps difference(BitSetOps other) {
        BitSetOps result = copy();
        result.bits.andNot(other.bits);
        return result;
    }

    private BitSetOps copy() {
        BitSetOps c = new BitSetOps(universeSize);
        c.bits = (BitSet) this.bits.clone();
        return c;
    }
}

BR1.

for (int a = 1; a <= 30; a++) {
    for (int b = 1; b <= 30; b++) {
        int lcm = a * b / gcd(a, b);
        Set<Integer> dLcm = divisorSet(lcm);
        Set<Integer> dUnion = union(divisorSet(a), divisorSet(b));
        assert dLcm.equals(dUnion)
            : "Failed for a=" + a + ", b=" + b;
    }
}

Module 4 – Class 3: Power Sets, Indexed Families and Partitions

Learning Objectives

  • Define and compute power sets, proving $|\mathcal{P}(A)| = 2^{|A|}$.
  • Represent indexed families of sets and compute their unions and intersections.
  • Define partitions and connect them to equivalence classes (Module 5 preview).
  • Implement power set generation using recursion and bit masks in Java.
  • Apply subset enumeration and partitioning to algorithmic problems.

Concept Overview

Power Sets

The power set of $A$, written $\mathcal{P}(A)$, is the set of all subsets of $A$.

$\mathcal{P}(A) = \{S \mid S \subseteq A\}$

Example: $\mathcal{P}(\{1, 2\}) = \{\emptyset, \{1\}, \{2\}, \{1, 2\}\}$

Theorem: If $|A| = n$, then $|\mathcal{P}(A)| = 2^n$.

Proof by induction on $n$:

  • Base: $n = 0$. $A = \emptyset$, $\mathcal{P}(\emptyset) = \{\emptyset\}$. $|\mathcal{P}(\emptyset)| = 1 = 2^0$. ✓
  • Inductive step: Assume $|\mathcal{P}(S)| = 2^k$ for any set $S$ with $|S| = k$. Let $|A| = k + 1$ and pick $a \in A$. Let $A' = A \setminus \{a\}$, so $|A'| = k$. Every subset of $A$ either contains $a$ or doesn't:
  • Subsets not containing $a$: subsets of $A'$, of which there are $2^k$.
  • Subsets containing $a$: each is $S \cup \{a\}$ for some $S \subseteq A'$, so there are $2^k$.
  • Total: $2^k + 2^k = 2^{k+1}$. $\blacksquare$

Indexed Families of Sets

An indexed family $\{A_i\}_{i \in I}$ assigns a set $A_i$ to each index $i$ in an index set $I$.

$\bigcup_{i \in I} A_i = \{x \mid \exists i \in I : x \in A_i\}$
$\bigcap_{i \in I} A_i = \{x \mid \forall i \in I : x \in A_i\}$

In Java: Map<K, Set<V>> represents an indexed family.

Partitions

A partition of set $A$ is a collection of non-empty subsets $\{A_1, A_2, \ldots, A_k\}$ such that:

  1. Pairwise disjoint: $A_i \cap A_j = \emptyset$ for $i \neq j$.
  2. Cover $A$: $A_1 \cup A_2 \cup \cdots \cup A_k = A$.

Examples:

  • $\{E, O\}$ where $E$ = even integers and $O$ = odd integers is a partition of $\mathbb{Z}$.
  • Congruence classes modulo $m$ partition $\mathbb{Z}$ into $m$ classes (connects to Module 2).

Key connection: Every equivalence relation on $A$ induces a partition of $A$ into equivalence classes, and every partition determines an equivalence relation. (Module 5 will formalize this.)

Why this matters in CS:

  • Subset enumeration (power sets) appears in backtracking, SAT solvers, and combinatorial optimization.
  • Partitions model equivalence classes, graph components, union-find structures.
  • Indexed families represent grouping operations (SQL GROUP BY, Map-Reduce).

Formal Notation

Notation Meaning
$\mathcal{P}(A)$ Power set: all subsets of $A$
$\{A_i\}_{i \in I}$ Indexed family of sets
$\bigcup_{i \in I} A_i$ Union of all sets in the family
$\bigcap_{i \in I} A_i$ Intersection of all sets in the family
Partition Disjoint cover of a set

Worked Examples

Example 1: Power Set Computation

Problem: Compute $\mathcal{P}(\{a, b, c\})$.

Solution:

$\mathcal{P}(\{a,b,c\}) = \{\emptyset, \{a\}, \{b\}, \{c\}, \{a,b\}, \{a,c\}, \{b,c\}, \{a,b,c\}\}$

$|\mathcal{P}(\{a,b,c\})| = 2^3 = 8$. ✓

Example 2: Power Set via Bit Masks

Each subset of $\{a_0, a_1, \ldots, a_{n-1}\}$ corresponds to an $n$-bit integer where bit $i$ indicates whether $a_i$ is included.

For $\{a, b, c\}$:

Binary Decimal Subset
000 0 $\emptyset$
001 1 $\{a\}$
010 2 $\{b\}$
011 3 $\{a,b\}$
100 4 $\{c\}$
101 5 $\{a,c\}$
110 6 $\{b,c\}$
111 7 $\{a,b,c\}$

Example 3: Indexed Family

Problem: Let $A_i = \{i, i+1, i+2\}$ for $i \in \{1, 2, 3\}$. Compute $\bigcup_{i=1}^{3} A_i$ and $\bigcap_{i=1}^{3} A_i$.

$A_1 = \{1, 2, 3\}$, $A_2 = \{2, 3, 4\}$, $A_3 = \{3, 4, 5\}$.

$\bigcup = \{1, 2, 3, 4, 5\}$. $\bigcap = \{3\}$.

Example 4: Partition by Congruence Classes

Problem: Partition $\{0, 1, 2, \ldots, 11\}$ by congruence modulo 3.

$[0]_3 = \{0, 3, 6, 9\}$, $[1]_3 = \{1, 4, 7, 10\}$, $[2]_3 = \{2, 5, 8, 11\}$.

Verification: pairwise disjoint (no overlaps) and union = $\{0, \ldots, 11\}$. ✓

This directly connects to Module 2's congruence classes!

Example 5: Partition into Primes and Composites

Partition $\{2, 3, \ldots, 20\}$ into primes and composites:

  • Primes: $\{2, 3, 5, 7, 11, 13, 17, 19\}$
  • Composites: $\{4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20\}$

Disjoint? Yes (no number is both prime and composite). Cover? Yes ($|\text{Primes}| + |\text{Composites}| = 8 + 11 = 19 = |\{2, \ldots, 20\}|$). ✓


Proof Techniques Spotlight

Counting via Bijections

To prove $|\mathcal{P}(A)| = 2^n$, we established a bijection between subsets of $A$ and $n$-bit strings. In general:

If there is a bijection $f : X \rightarrow Y$ between finite sets, then $|X| = |Y|$.

This is a powerful counting technique that we'll use more in Module 7.

Partition Arguments

To prove a collection $\{A_1, \ldots, A_k\}$ is a partition:

  1. Show each $A_i \neq \emptyset$.
  2. Show $A_i \cap A_j = \emptyset$ for $i \neq j$ (often by assuming $x \in A_i \cap A_j$ and deriving $i = j$).
  3. Show $\bigcup A_i = A$.

Java Deep Dive

import java.util.*;
import java.util.stream.*;

public class PowerSetLibrary {

    // --- Power Set Generation ---

    /**
     * Generate the power set using bit masks.
     * Time: O(n · 2^n), Space: O(n · 2^n).
     * Each integer from 0 to 2^n - 1 represents one subset.
     */
    public static <T> Set<Set<T>> powerSetBitMask(List<T> elements) {
        int n = elements.size();
        Set<Set<T>> result = new HashSet<>();

        for (int mask = 0; mask < (1 << n); mask++) {
            Set<T> subset = new HashSet<>();
            for (int i = 0; i < n; i++) {
                if ((mask & (1 << i)) != 0) {
                    subset.add(elements.get(i));
                }
            }
            result.add(subset);
        }
        return result;
    }

    /**
     * Generate the power set recursively.
     * Base: P({}) = {{}}
     * Step: For element a, P(A) = P(A\{a}) ∪ { S ∪ {a} | S ∈ P(A\{a}) }
     */
    public static <T> Set<Set<T>> powerSetRecursive(List<T> elements) {
        Set<Set<T>> result = new HashSet<>();
        if (elements.isEmpty()) {
            result.add(new HashSet<>());  // { {} }
            return result;
        }

        T first = elements.get(0);
        List<T> rest = elements.subList(1, elements.size());
        Set<Set<T>> subsetsOfRest = powerSetRecursive(rest);

        for (Set<T> subset : subsetsOfRest) {
            result.add(new HashSet<>(subset));          // without first
            Set<T> withFirst = new HashSet<>(subset);
            withFirst.add(first);                        // with first
            result.add(withFirst);
        }
        return result;
    }

    // --- Indexed Families ---

    /**
     * Compute the union of all sets in a family.
     * ⋃_{i ∈ I} A_i
     */
    public static <K, V> Set<V> familyUnion(Map<K, Set<V>> family) {
        Set<V> result = new HashSet<>();
        for (Set<V> set : family.values()) {
            result.addAll(set);
        }
        return result;
    }

    /**
     * Compute the intersection of all sets in a family.
     * ⋂_{i ∈ I} A_i
     */
    public static <K, V> Set<V> familyIntersection(Map<K, Set<V>> family) {
        Iterator<Set<V>> iter = family.values().iterator();
        if (!iter.hasNext()) return new HashSet<>();
        Set<V> result = new HashSet<>(iter.next());
        while (iter.hasNext()) {
            result.retainAll(iter.next());
        }
        return result;
    }

    // --- Partitions ---

    /**
     * Partition a set of integers by their remainder modulo m.
     * Returns congruence classes [0]_m, [1]_m, ..., [m-1]_m.
     * Connects to Module 2.
     */
    public static Map<Integer, Set<Integer>> partitionByMod(Set<Integer> s, int m) {
        Map<Integer, Set<Integer>> partition = new TreeMap<>();
        for (int i = 0; i < m; i++) {
            partition.put(i, new TreeSet<>());
        }
        for (int x : s) {
            int cls = Math.floorMod(x, m);
            partition.get(cls).add(x);
        }
        // Remove empty classes (they might not appear in s)
        partition.entrySet().removeIf(e -> e.getValue().isEmpty());
        return partition;
    }

    /**
     * Partition by predicate: elements satisfying p go to "true",
     * others go to "false".
     */
    public static <T> Map<Boolean, Set<T>> partitionByPredicate(
            Set<T> s, java.util.function.Predicate<T> p) {
        Map<Boolean, Set<T>> result = new HashMap<>();
        result.put(true, new HashSet<>());
        result.put(false, new HashSet<>());
        for (T x : s) {
            result.get(p.test(x)).add(x);
        }
        return result;
    }

    /**
     * Verify that a collection of sets forms a valid partition.
     */
    public static <T> boolean isPartition(Set<T> whole, Collection<Set<T>> parts) {
        // Check pairwise disjoint
        List<Set<T>> list = new ArrayList<>(parts);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).isEmpty()) return false;
            for (int j = i + 1; j < list.size(); j++) {
                Set<T> inter = new HashSet<>(list.get(i));
                inter.retainAll(list.get(j));
                if (!inter.isEmpty()) return false;
            }
        }
        // Check cover
        Set<T> union = new HashSet<>();
        for (Set<T> part : parts) union.addAll(part);
        return union.equals(whole);
    }

    // --- Demonstration ---

    public static void main(String[] args) {
        System.out.println("=== Power Set Library ===\n");

        // Power set
        List<Integer> elems = Arrays.asList(1, 2, 3);
        Set<Set<Integer>> ps = powerSetBitMask(elems);
        System.out.println("P({1,2,3}) has " + ps.size() + " subsets:");
        for (Set<Integer> s : ps) {
            System.out.println("  " + s);
        }

        // Verify: recursive matches bit-mask
        Set<Set<Integer>> psRec = powerSetRecursive(elems);
        System.out.println("\nRecursive method matches bit-mask? " + ps.equals(psRec));

        // Indexed family
        Map<Integer, Set<Integer>> family = new TreeMap<>();
        for (int i = 1; i <= 3; i++) {
            Set<Integer> ai = new TreeSet<>();
            for (int j = i; j <= i + 2; j++) ai.add(j);
            family.put(i, ai);
        }
        System.out.println("\nIndexed family: " + family);
        System.out.println("Union: " + familyUnion(family));
        System.out.println("Intersection: " + familyIntersection(family));

        // Partition by mod
        Set<Integer> nums = IntStream.rangeClosed(0, 11).boxed()
                .collect(Collectors.toSet());
        Map<Integer, Set<Integer>> modPart = partitionByMod(nums, 3);
        System.out.println("\nPartition of {0..11} by mod 3: " + modPart);
        System.out.println("Valid partition? " +
                isPartition(nums, modPart.values()));

        // Partition: primes vs composites
        Set<Integer> range = IntStream.rangeClosed(2, 20).boxed()
                .collect(Collectors.toSet());
        Map<Boolean, Set<Integer>> primePartition = partitionByPredicate(
                range, n -> isPrime(n));
        System.out.println("\nPrimes: " + new TreeSet<>(primePartition.get(true)));
        System.out.println("Composites: " + new TreeSet<>(primePartition.get(false)));
        System.out.println("Valid partition? " +
                isPartition(range, primePartition.values()));
    }

    static boolean isPrime(int n) {
        if (n < 2) return false;
        for (int i = 2; i * i <= n; i++)
            if (n % i == 0) return false;
        return true;
    }
}

Historical Context

Cantor's Power Set Theorem (1891) proved that for any set $A$, there is no surjection from $A$ onto $\mathcal{P}(A)$. For finite sets, this simply says $2^n > n$. For infinite sets, it implies there are different "sizes" of infinity — the power set of the natural numbers is uncountably infinite (the same size as the real numbers).

The concept of partitions links to equivalence classes, formalized by mathematicians in the early 20th century. In CS, the Union-Find data structure (Tarjan, 1975) efficiently maintains partitions with near-constant-time operations.

Power set enumeration ($2^n$ subsets) is the basis of exponential-time algorithms in complexity theory, including brute-force solutions to NP-complete problems like the subset sum problem.


Slide-Ready Problem Sets

Slide Set A: Conceptual Questions

A1. How many elements does $\mathcal{P}(\{1,2,3,4,5\})$ have?

A2. Is $\{1\} \in \mathcal{P}(\{1,2,3\})$? Is $1 \in \mathcal{P}(\{1,2,3\})$?

A3. Name three ways to partition $\{1,2,3,4,5,6\}$ into exactly two non-empty parts.

Slide Set B: Proof Problems

B1. Prove by induction: $|\mathcal{P}(A)| = 2^{|A|}$ for finite sets.

B2. Prove: congruence classes modulo $m$ form a partition of $\mathbb{Z}$.

B3. Prove: if $\{A_1, \ldots, A_k\}$ is a partition of $A$, then $\sum_{i=1}^{k} |A_i| = |A|$.

Slide Set C: Java Coding Problems

C1. Generate the power set of $\{1,2,3,4\}$ and count subsets of each size. Verify: $\sum_{k=0}^{4} \binom{4}{k} = 16$.

C2. Partition a list of strings by their first letter.

C3. Implement isPartition and test with valid and invalid partitions.


Full Problem Set

Discrete Math Problems

DM1. List all elements of $\mathcal{P}(\{a, b, c, d\})$. How many subsets of size 2 are there?

DM2. Prove by induction: $|\mathcal{P}(A)| = 2^{|A|}$.

DM3. Prove: If $A \subseteq B$, then $\mathcal{P}(A) \subseteq \mathcal{P}(B)$.

DM4. Prove that the congruence classes $[0]_m, [1]_m, \ldots, [m-1]_m$ form a partition of $\mathbb{Z}$.

DM5. Let $f: A \rightarrow B$ be a function. Define $A_b = \{a \in A \mid f(a) = b\}$ for each $b \in B$. Prove that $\{A_b \mid b \in B, A_b \neq \emptyset\}$ is a partition of $A$. (Preview of Module 5.)

DM6. Prove: $\mathcal{P}(A \cap B) = \mathcal{P}(A) \cap \mathcal{P}(B)$.

DM7. Prove or disprove: $\mathcal{P}(A \cup B) = \mathcal{P}(A) \cup \mathcal{P}(B)$.

Java Programming Problems

JP1. Implement power set generation using both bit masks and recursion. Verify both produce the same result for sets of sizes 0 through 6.

JP2. Write a method List<Set<Integer>> subsetsOfSize(List<Integer> elements, int k) that returns all $k$-element subsets. Verify that the count matches $\binom{n}{k}$.

JP3. Implement Map<Integer, Set<Integer>> partitionByMod(Set<Integer> s, int m) and verify using isPartition.

JP4. Write a subset sum solver: given a set $S$ of integers and a target $t$, enumerate all subsets of $S$ whose sum equals $t$. Use power set generation.

JP5. Implement a general groupBy method: <T, K> Map<K, Set<T>> groupBy(Set<T> s, Function<T, K> classifier) that partitions $s$ by the classifier function.

Bridge Problems

BR1. Implement the subset sum solver from JP4. For a set $S$ with $|S| = n$, the solver checks $2^n$ subsets. Measure the runtime for $n = 10, 15, 20, 25$ and plot the growth. Explain why this is exponential and relate to $|\mathcal{P}(S)| = 2^n$.

BR2. Recall from Module 2 that congruence modulo $m$ is an equivalence relation. Implement a method that takes a set of integers and a modulus $m$, partitions the set by congruence classes, and then verifies: (a) each class is non-empty, (b) classes are pairwise disjoint, (c) their union equals the original set, (d) all elements in a class have the same remainder mod $m$.


Solutions

Discrete Math Solutions

DM2. See proof in Concept Overview above. $\blacksquare$

DM3. Assume $A \subseteq B$. Let $S \in \mathcal{P}(A)$, so $S \subseteq A$. Since $A \subseteq B$, by transitivity of $\subseteq$, $S \subseteq B$, so $S \in \mathcal{P}(B)$. $\blacksquare$

DM4. Let $a, b \in \mathbb{Z}$. If $a \in [i]_m \cap [j]_m$, then $a \equiv i \pmod{m}$ and $a \equiv j \pmod{m}$, so $i \equiv j \pmod{m}$. Since $0 \leq i, j < m$, this means $i = j$. So classes are pairwise disjoint. Every $a \in \mathbb{Z}$ satisfies $a \equiv r \pmod{m}$ for some $r \in \{0, \ldots, m-1\}$ (by quotient-remainder, Module 2), so $a \in [r]_m$. Thus the classes cover $\mathbb{Z}$. $\blacksquare$

DM6. ($\subseteq$): Let $S \in \mathcal{P}(A \cap B)$. Then $S \subseteq A \cap B$, so $S \subseteq A$ and $S \subseteq B$, giving $S \in \mathcal{P}(A)$ and $S \in \mathcal{P}(B)$, i.e., $S \in \mathcal{P}(A) \cap \mathcal{P}(B)$.

($\supseteq$): Let $S \in \mathcal{P}(A) \cap \mathcal{P}(B)$. Then $S \subseteq A$ and $S \subseteq B$, so $S \subseteq A \cap B$, giving $S \in \mathcal{P}(A \cap B)$. $\blacksquare$

DM7. False. Counterexample: $A = \{1\}$, $B = \{2\}$. Then $\{1, 2\} \in \mathcal{P}(A \cup B)$ but $\{1, 2\} \notin \mathcal{P}(A) = \{\emptyset, \{1\}\}$ and $\{1, 2\} \notin \mathcal{P}(B) = \{\emptyset, \{2\}\}$. So $\{1, 2\} \notin \mathcal{P}(A) \cup \mathcal{P}(B)$. $\blacksquare$

Java Solutions

JP2.

public static List<Set<Integer>> subsetsOfSize(List<Integer> elements, int k) {
    List<Set<Integer>> result = new ArrayList<>();
    generateSubsets(elements, k, 0, new HashSet<>(), result);
    return result;
}

private static void generateSubsets(List<Integer> elements, int k,
        int start, Set<Integer> current, List<Set<Integer>> result) {
    if (current.size() == k) {
        result.add(new HashSet<>(current));
        return;
    }
    if (start >= elements.size()) return;
    // Include elements[start]
    current.add(elements.get(start));
    generateSubsets(elements, k, start + 1, current, result);
    current.remove(elements.get(start));
    // Exclude elements[start]
    generateSubsets(elements, k, start + 1, current, result);
}

JP4.

public static List<Set<Integer>> subsetSum(List<Integer> elements, int target) {
    List<Set<Integer>> solutions = new ArrayList<>();
    int n = elements.size();
    for (int mask = 0; mask < (1 << n); mask++) {
        Set<Integer> subset = new HashSet<>();
        int sum = 0;
        for (int i = 0; i < n; i++) {
            if ((mask & (1 << i)) != 0) {
                subset.add(elements.get(i));
                sum += elements.get(i);
            }
        }
        if (sum == target) solutions.add(subset);
    }
    return solutions;
}

1 / 1