Two sets have the same cardinality when there is a bijection between them. The natural numbers and the even numbers have the same cardinality (both countably infinite). But the real numbers have strictly larger cardinality. Cantor proved this with his diagonal argument.
Finite cardinality
Two finite sets have the same cardinality when they have the same number of elements. A bijection between them pairs each element of one with exactly one element of the other.
Scheme
; Two finite sets with the same cardinality
(define A (list 12345))
(define B (list 1020304050))
; A bijection: f(x) = 10*x
(define (f x) (* 10 x))
(display "Bijection from A to B:") (newline)
(for-each (lambda (x)
(display x) (display " -> ") (display (f x)) (newline))
A)
(display "|A| = ") (display (length A)) (newline)
(display "|B| = ") (display (length B))
Countably infinite sets
A set is countably infinite if there is a bijection with the natural numbers. The even numbers are countable: n maps to 2n. The integers are countable: 0, 1, -1, 2, -2, 3, -3, ... . The rationals are countable (by a more clever listing). Countable infinity is the "smallest" infinity.
Scheme
; The even numbers are countably infinite.; Bijection: n -> 2n (from N to evens)
(define (nat-to-even n) (* 2 n))
(define (even-to-nat e) (/ e 2))
(display "N -> Evens:") (newline)
(define (show-pairs n limit)
(if (> n limit) (display "...")
(begin
(display n) (display " -> ") (display (nat-to-even n))
(display " ")
(show-pairs (+ n 1) limit))))
(show-pairs 08) (newline)
; The integers are countably infinite.; Listing: 0, 1, -1, 2, -2, 3, -3, ...
(define (nat-to-int n)
(if (= 0 (modulo n 2))
(/ n 2)
(- (/ (+ n 1) 2))))
(display "N -> Z:") (newline)
(define (show-ints n limit)
(if (> n limit) (display "...")
(begin
(display n) (display "->") (display (nat-to-int n))
(display " ")
(show-ints (+ n 1) limit))))
(show-ints 08)
Python
# Countable sets: bijections from N# N -> Evensprint("N -> Evens:", [(n, 2*n) for n inrange(8)])
# N -> Integers: 0, 1, -1, 2, -2, ...def nat_to_int(n):
return n // 2if n % 2 == 0else -(n + 1) // 2print("N -> Z: ", [(n, nat_to_int(n)) for n inrange(9)])
Cantor's diagonal argument
Theorem: the real numbers in [0, 1] are uncountable. Proof by contradiction: suppose we can list all reals r1, r2, r3, ... . Construct a new real d whose n-th digit differs from the n-th digit of rn. Then d is not in the list (it differs from every rn at position n). This contradicts the assumption that the list was complete.
Scheme
; Cantor's diagonal argument (simulated with finite strings).; Given a "list" of decimal expansions, construct a number not on the list.
(define r1 (list 51703))
(define r2 (list 39284))
(define r3 (list 74156))
(define r4 (list 00629))
(define r5 (list 83077))
(define rows (list r1 r2 r3 r4 r5))
; Extract the diagonal: position n from row n
(define (diagonal rows)
(define (go rs i)
(if (null? rs) (list)
(cons (list-ref (car rs) i)
(go (cdr rs) (+ i 1)))))
(go rows 0))
; Flip each digit (add 1 mod 10, avoiding 0 and 9 for cleanliness)
(define (flip d) (modulo (+ d 1) 10))
(define diag (diagonal rows))
(define anti-diag (map flip diag))
(display "Diagonal: ") (display diag) (newline)
(display "Anti-diagonal: ") (display anti-diag) (newline)
(display "This number differs from every row at the diagonal position.")
The continuum hypothesis
Cantor showed |N| is less than |R|. Is there a set with cardinality strictly between them? The continuum hypothesis says no. Godel (1940) showed it is consistent with ZFC. Cohen (1963) showed its negation is also consistent. The question is undecidable from the standard axioms of set theory.
Scheme
; The cardinality hierarchy:; |N| = aleph_0 (countably infinite); |R| = 2^(aleph_0) (uncountably infinite); |P(R)| = 2^(2^(aleph_0)) (even larger);; Cantor's theorem: |S| < |P(S)| for any set S.; No set can biject with its power set.; Demonstrate with finite sets:
(define (power-set s)
(if (null? s) (list (list))
(let ((rest (power-set (cdr s))))
(append rest
(map (lambda (sub) (cons (car s) sub)) rest)))))
(define (check n)
(define s (list))
(define (make-set i) (if (> i n) (list) (cons i (make-set (+ i 1)))))
(let ((s (make-set 1)))
(display "|S|=") (display (length s))
(display " |P(S)|=") (display (length (power-set s)))
(display " |S| < |P(S)|? ") (display (< (length s) (length (power-set s))))
(newline)))
(check 1)
(check 2)
(check 3)
(check 4)
(check 5)
; Always |S| < |P(S)|. Cantor proved this for all sets, finite or infinite.