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

Relations: ordered pairs and the grid of who relates to whom

An ordered pair remembers order: (a, b) is not (b, a). The cartesian product A × B is the grid of every pair, and a relation is whichever subset of the grid holds. Foreign keys, === and follows graphs are relations — reflexive, symmetric, transitive tell them apart.

LOGIC Foundations ◷ 15 min
Level
FoundationsJuniorMiddleSenior

A junior engineer inherited a social app with a table called follows(follower_id, followee_id) and a bug report: “my follower list shows people I follow, not people who follow me.” The query read WHERE follower_id = :me — and returned the accounts me follows, because the first column is the one doing the following. Swapping two column names fixed it. Nothing about sets prepared you for this bug: a set has no first or second, so the previous two lessons cannot even express “Ana follows Bob but Bob does not follow Ana”. To say that, you need a pair where position carries meaning — and once you have ordered pairs, “follows”, “is less than”, “references via foreign key”, even === all turn out to be the same mathematical object: a set of ordered pairs, a subset of a grid.

Goal

After this lesson you can define an ordered pair and explain why position matters, build the cartesian product A × B and count its size, define a relation as a subset of a product, check the reflexive, symmetric and transitive properties, and run the three-element drill on a concrete relation.

1

An ordered pair (a, b) makes position meaningful. Unlike a set, where {a, b} = {b, a}, an ordered pair satisfies (a, b) = (c, d) only when a = c and b = d. So (1, 2) ≠ (2, 1). You use ordered pairs constantly: coordinates (x, y), key-value entries, rows (follower_id, followee_id). The hook bug was precisely an ordered-pair bug: the row (ana, bob) means “ana follows bob”, and reading columns backwards reverses every arrow in the graph.

2

The cartesian product A × B is the set of all ordered pairs (a, b) with a from A and b from B. Picture a grid: A labels the rows, B labels the columns, every cell is one pair. The count is |A × B| = |A| · |B|. With A = {1, 2, 3} and B = {x, y, z, w}: 3 × 4 = 12 pairs. A forgotten JOIN condition in SQL hands you precisely this grid.

const a = [1, 2, 3];
const b = ["x", "y", "z", "w"];
const grid = a.flatMap((m) => b.map((n) => [m, n]));
grid.length;   // 12 = 3 × 4
3

A relation from A to B is any subset of A × B. The grid lists every pair that could be related; the relation keeps the pairs that actually are. To say “a relates to b”, check (a, b) ∈ R — a membership question. A follows table over users {ana, bob, cara} is some subset of the 9-cell grid users × users. The empty relation (nobody follows anybody) and the full grid (everybody follows everybody) are both legal extremes.

4

Three pair-by-pair checks reveal a relation’s character. When R ⊆ A × A:

  • Reflexive — (x, x) ∈ R for all x. “x ≤ x” — yes. “x is x’s own ancestor” — no.
  • Symmetric — (x, y) ∈ R implies (y, x) ∈ R. Mutual friendship — yes. Follows — famously no.
  • Transitive — (x, y) ∈ R and (y, z) ∈ R imply (x, z) ∈ R. Ancestor-of — yes. Follows — no.

A function is the special relation where each element of A appears as a first coordinate in exactly one pair — one output per input. Most stored relations — follows, foreign keys, tags — are many-to-many and not functions.

Worked example

Three-element drill on A = {1, 2, 3}, R = {(1,1), (2,2), (1,2), (2,1)}.

  • Reflexive? Need (1,1), (2,2), (3,3). Missing (3,3) → not reflexive. One absent self-pair is enough to fail.
  • Symmetric? (1,2) has (2,1) ✓; self-pairs are their own reverses ✓ → symmetric.
  • Transitive? (1,2) then (2,1) needs (1,1) ✓; (2,1) then (1,2) needs (2,2) ✓ → transitive.

This is a real debugging technique: property checks on small relations validate assumptions before code relies on them.

Edge cases

Is === reflexive? Almost — but NaN === NaN is false by the IEEE 754 standard, making === on numbers not reflexive. This single missing self-pair has real consequences: array.indexOf(NaN) never finds it (indexOf uses ===), while array.includes(NaN) does (includes uses SameValueZero, which treats NaN as equal to itself).

Practice 0 / 5

|A| = 5 and |B| = 3. How many pairs are in A × B? Type the number.

Is (2, 1) the same ordered pair as (1, 2)? Answer yes or no.

R = {(1,1),(2,2),(3,3)} on {1,2,3}. Is R reflexive? Answer yes or no.

R = {(1,2),(2,1)} on {1,2,3}. Is R reflexive? Answer yes or no.

R = {(1,2),(2,3)} on {1,2,3}. Is R transitive? (1,2) and (2,3) are both in R — what pair must also be in R for transitivity? Write it as (x,y).

Check yourself
Quiz

|A| = 3 and |B| = 4. How many pairs are in A × B, and what exactly is a relation from A to B?

Recap

An ordered pair (a, b) makes position meaningful — (a, b) ≠ (b, a). The cartesian product A × B collects all |A| · |B| possible pairs into a grid — 3 × 4 makes 12, and a forgotten JOIN condition hands you precisely this. A relation is any subset of the grid: the definition that turns “related” into a membership question, (a, b) ∈ R. Foreign-key tables store relations row by row; === defines one by its true pairs. On a single set, three pair-by-pair checks classify a relation: reflexive (every self-pair present), symmetric (every arrow reversed), transitive (arrows chain). The three-element drill makes the checks mechanical. Functions are not the general case but the special one: a relation where every input appears as a first coordinate exactly once — most stored relations are many-to-many.

Practice

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

recallapplystretch0 of 5 done

Something unclear?

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

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

Trademarks belong to their respective owners. Editorial reference only.