Mathematical Foundations of Computing, Lecture notes of Theory of Computation

A set of course notes for a first course in the mathematical foundations of computing. It covers topics such as sets, mathematical proof, functions, and cardinality. The notes are intended to teach students how to model problems mathematically, reason about them abstractly, and apply techniques to explore their properties. The document also discusses the fundamental nature of computation and introduces complexity theory. Mathematics underpins all of the endeavors in computer science, and this course provides a broad and deep introduction to the mathematics that lie at the heart of the field.

Typology: Lecture notes

2022/2023

Uploaded on 05/11/2023

tomcrawford
tomcrawford 🇺🇸

4.2

(15)

257 documents

1 / 369

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
q0
q1
q3
q1
q2
q1
q4
start
0
1
0
1
0, 1
(M) = ((0|1)*(00|11))
Mathematical Foundations of Computing
CS103
CS103
Preliminary Course Notes
Keith Schwarz
Fall 2013
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51
pf52
pf53
pf54
pf55
pf56
pf57
pf58
pf59
pf5a
pf5b
pf5c
pf5d
pf5e
pf5f
pf60
pf61
pf62
pf63
pf64

Partial preview of the text

Download Mathematical Foundations of Computing and more Lecture notes Theory of Computation in PDF only on Docsity!

q 0

q 1

q 3

q q 12

q q 14

start

ℒ(M) = ℒ((0|1) *(00|11))

Mathematical Foundations of Computing

CS103CS

Preliminary Course Notes Keith Schwarz Fall 201 3

Table of Contents

  • Chapter 0 Introduction
    • 0.1 How These Notes are Organized
    • 0.2 Acknowledgements
  • Chapter 1 Sets and Cantor's Theorem
    • 1.1 What is a Set?
    • 1.2 Operations on Sets
    • 1.3 Special Sets
    • 1.4 SetBuilder Notation
      • Filtering Sets
      • Transforming Sets
    • 1.5 Relations on Sets
      • Set Equality
      • Subsets and Supersets
        • The Empty Set and Vacuous Truths
    • 1.6 The Power Set
    • 1.7 Cardinality
      • What is Cardinality?
      • The Difficulty With Infinite Cardinalities
      • A Formal Definition of Cardinality
    • 1.8 Cantor's Theorem
      • How Large is the Power Set?
      • Cantor's Diagonal Argument
      • Formalizing the Diagonal Argument
      • Proving Cantor's Theorem
    • 1.9 Why Cantor's Theorem Matters
    • 1.10 The Limits of Computation
      • What Does This Mean?
    • 1.11 Chapter Summary
  • Chapter 2 Mathematical Proof
    • 2.1 What is a Proof?
      • Transitioning to ProofBased Mathematics
      • What Can We Assume?
    • 2.2 Direct Proofs
      • Proof by Cases
        • A Quick Aside: Choosing Letters
      • Proofs about Sets
      • Lemmas
      • Proofs with Vacuous Truths
    • 2.3 Indirect Proofs
      • Logical Implication
      • Proof by Contradiction
      • Rational and Irrational Numbers
      • Proof by Contrapositive
    • 2.4 Writing Elegant Proofs
      • Treat Proofs as Essays
      • Avoid Shorthand or Unnecessary Symbols
      • Write Multiple Drafts
      • Avoid “Clearly” and “Obviously”
    • 2.5 Chapter Summary
    • 2.6 Chapter Exercises
  • Chapter 3 Mathematical Induction
    • 3.1 The Principle of Mathematical Induction
      • The Flipping Glasses Puzzle
    • 3.2 Summations
      • Summation Notation
      • Summing Odd Numbers
      • Manipulating Summations
      • Telescoping Series
      • Products
    • 3.3 Induction and Recursion
      • Monoids and Folds ★
    • 3.4 Variants on Induction
      • Starting Induction Later
        • Why We Can Start Later ★
      • Fibonacci Induction ★
        • Climbing Down Stairs
        • Computing Fibonacci Numbers
    • 3.5 Strong Induction
      • The Unstacking Game
      • Variations on Strong Induction ★
      • A Foray into Number Theory
      • Why Strong Induction Works ★
    • 3.6 The WellOrdering Principle ★
      • Proof by Infinite Descent
      • Proving the WellOrdering Principle
        • An Incorrect Proof
        • A Correct Proof
    • 3.7 Chapter Summary
    • 3.8 Chapter Exercises
  • Chapter 4 Graph Theory
    • 4.1 Basic Definitions
      • Ordered and Unordered Pairs
      • A Formal Definition of Graphs
      • Navigating a Graph
    • 4.2 Graph Connectivity
      • Connected Components
      • 2EdgeConnected Graphs ★
      • Trees ★
        • Properties of Trees
      • Directed Connectivity
    • 4.3 DAGs
      • Topological Orderings
      • Condensations ★
    • 4.4 Matchings ★
      • Proving Berge's Theorem
    • 4.5 Chapter Summary
    • 4.6 Chapter Exercises
  • Chapter 5 Relations
    • 5.1 Basic Terminology
      • Tuples and the Cartesian Product
        • Cartesian Powers
      • A Formal Definition of Relations
      • Special Binary Relations
      • Binary Relations and Graphs
    • 5.2 Equivalence Relations
      • Equivalence Classes
      • Equivalence Classes and Graph Connectivity
    • 5.3 Order Relations
      • Strict Orders
      • Partial Orders
      • Hasse Diagrams
      • Preorders ★
        • Properties of Preorders
      • Combining Orderings ★
        • The Product Ordering
        • The Lexicographical Ordering
    • 5.4 WellOrdered and WellFounded Sets ★
      • WellOrders
        • Properties of WellOrdered Sets
      • WellFounded Orders
      • WellOrdered and WellFounded Induction
        • Application: The Ackermann Function
    • 5.5 Chapter Summary
    • 5.6 Chapter Exercises
  • Chapter 6 Functions and Cardinality
    • 6.1 Functions
      • Basic Definitions
      • Defining Functions
      • Functions with Multiple Inputs
      • A Rigorous Definition of a Function ★
    • 6.2 Injections, Surjections, and Bijections
      • Injections and Surjections
      • Images and Preimages ★
      • Bijections
    • 6.3 Transformations on Functions
      • Composing Functions
        • Composing Injections, Surjections, and Bijections
      • Inverse Functions
      • Compositions and Inverses
      • Inverses of Inverses
    • 6.4 Cardinality
      • Cardinalities Exist Between Sets
      • Equal Cardinalities
      • Countable Sets
        • ℤ is Countable
        • ℕ ² is Countable
      • Comparing Cardinalities
    • 6.5 Diagonalization
      • | ℕ| < | ℝ|
      • Cantor's Theorem
    • 6.6 Chapter Summary
    • 6.7 Chapter Exercises

Chapter 0 Introduction Computer science is the art of solving problems with computers. This is a broad definition that encom- passes an equally broad field. Within computer science, we find software engineering, bioinformatics, cryptography, machine learning, human-computer interaction, graphics, and a host of other fields. Mathematics underpins all of these endeavors in computer science. We use graphs to model complex problems, and exploit their mathematical properties to solve them. We use recursion to break down seem - ingly insurmountable problems into smaller and more manageable problems. We use topology, linear al- gebra, and geometry in 3D graphics. We study computation itself in computability and complexity the- ory, with results that have profound impacts on compiler design, machine learning, cryptography, com- puter graphics, and data processing. This set of course notes serves as a first course in the mathematical foundations of computing. It will teach you how to model problems mathematically, reason about them abstractly, and then apply a battery of techniques to explore their properties. It will teach you to prove mathematical truths beyond a shadow of a doubt. It will give you insight into the fundamental nature of computation and what can and cannot be solved by computers. It will introduce you to complexity theory and some of the most important prob- lems in all computer science. This set of course notes is intended to give a broad and deep introduction to the mathematics that lie at the heart of computer science. It begins with a survey of discrete mathematics – basic set theory and proof techniques, mathematic induction, graphs, relations, functions, and logic – then explores computability and complexity theory. No prior mathematical background is necessary. These course notes are designed to provide a secondary treatment of the material from Stanford's CS course. The topic organization roughly follows the presentation from CS103, albeit at a much deeper level. It is designed to supplement lectures from CS103 with additional exposition on each topic, broader examples, and more advanced applications and techniques. My hope is that there will be something for everyone. If you're interested in brushing up on definitions and seeing a few examples of the various techniques, feel free to read over the relevant parts of each chapter. If you want to see the techniques ap- plied to a variety of problems, look over the examples that catch your interest. If you want to see just how deep the rabbit hole goes, read over the entire chapter and work through all the starred exercises. 0.1 How These Notes are Organized The organization of this book into chapters is as follows:

  • Chapter One motivates our discussion of mathematics by giving a brief outline of set theory, con- cluding with Cantor's theorem , a profound and powerful result about the nature of infinity.
  • Chapter Two lays the groundwork for formal proofs by exploring several key proof techniques that we will use throughout the rest of these notes.
  • Chapter Three explores mathematical induction, a proof technique that we will use extensively when proving results about discrete structures, programs, and computation.
  • Chapter Four investigates mathematical structures called graphs that are useful for modeling complex problems. These structures will form the basis for many of the models of computation we will investigate later.
  • Chapter Five explores different ways in which objects often relate to one another and the mathe- matical structures of these relations.

Chapter 0: Introduction

  • Chapter Six revisits the material on set theory from the first chapter with a mathematically rigor- ous exploration of the properties of infinity.
  • Chapter Seven introduces a proof technique called the pigeonhole principle that superficially ap- pears quite simple, but which has profound implications for the limits of computation.
  • Chapter Eight explores formal logic and gives a more rigorous basis for the proof techniques de- veloped in the preceding chapters.
  • Chapter Nine introduces key concepts from computability theory , the study of what problems can and cannot be solved by a computer.
  • Chapter Ten introduces finite automata , regular expressions , and the regular languages. It serves as an introduction to the study of formal models of computations. These models have applica- tions throughout computer science
  • Chapter Eleven introduces pushdown automata and context-free grammars , more powerful for- malisms for describing computation.
  • Chapter Twelve introduces the Turing machine , an even more powerful model of computation that we suspect is the most powerful feasible computing machine that could ever be built.
  • Chapter Thirteen explores the power of the Turing machine by exploring what problems it can solve.
  • Chapter Fourteen provides examples of problems that are provably beyond our capability to solve with any type of computer.
  • Chapter Fifteen introduces reductions , a fundamental technique in computability and complexity theory for reasoning about the relative difficulties of problems.
  • Chapter Sixteen introduces complexity theory , the study of what problems can be computed given various resource constraints.
  • Chapter Seventeen introduces the complexity classes P and NP , which contain many problems of great practical and theoretical importance.
  • Chapter Eighteen explores the connection between the classes P and NP , which (as of 2012) is the single biggest open problem in all of theoretical computer science.
  • Chapter Nineteen goes beyond P and NP and explores alternative models of computation and their complexities.
  • Chapter Twenty concludes our treatment of the mathematical foundations of computing and sets the stage for further study on the subject. Some of the sections of these notes are marked with a ★symbol. These sections contain more advanced material that, while interesting, is not essential to understanding the course material. If you are interested in learning more about the topic, I would suggest reading through it. However, if you're pressed for time, feel free to skip these sections. Similarly, some of the chapter exercises are marked with the ★ symbol. These exercises are more diffi- cult than the other exercises. I highly recommend attempting at least one or two of the starred exercises from each chapter. If you're up for a real challenge, try working through all of them! This is a work-in-progress draft of what I hope will become a full set of course notes for CS103. Right now, the notes only cover up through the first six or seven lectures. I am hoping to expand that over the course of the upcoming months. Since this is a first draft, there are definitely going to be errors in here, whether they're typoz, grammatically problems, layout^ issues, and logic errors. If you find any errors, please

Chapter 1 Sets and Cantor's Theorem Our journey into the realm of mathematics begins with an exploration of a surprisingly nuanced concept: the set. Informally, a set is just a collection of things, whether it's a set of numbers, a set of clothes, a set of nodes in a network, or a set of other sets. Amazingly, given this very simple starting point, it is possi - ble to prove a result known as Cantor's Theorem that provides a striking and profound limit on what prob- lems a computer program can solve. In this introductory chapter, we'll build up some basic mathematical machinery around sets. Then, we will see how the simple notion of asking how big a set is can lead to in- credible and shocking results. 1.1 What is a Set? Let's begin with a simple definition: A set is an unordered collection of distinct elements. What exactly does this mean? Intuitively, you can think of a set as a group of things. Those things must be distinct, which means that you can't have multiple copies of the same object in a set. Additionally, those things are unordered, so there's no notion of a “first” thing in the group, a “second” thing in a group, etc. We need two additional pieces of terminology to talk about sets: An element is something contained within a set. To denote a set, we write the elements of the set within curly braces. For example, the set {1, 2, 3} is a set with three elements: 1, 2, and 3. The set { cat, dog } is a set containing the two elements “cat” and “dog.” Because sets are unordered collections, the order in which we list the elements of a set doesn't matter. This means that the sets {1, 2, 3}, {2, 1, 3}, and {3, 2, 1} are all descriptions of exactly the same set. Also, because sets are unordered collections of distinct elements , no element can appear more than once in the same set. In particular, this means that if we write out a set like {1, 1, 1, 1, 1}, it's completely equivalent to writing out the set {1}, since sets can't contain duplicates. Similarly, {1, 2, 2, 2, 3} and {3, 2, 1} are the same set, since ordering doesn't matter and duplicates are ignored. When working with sets, we are often interested in determining whether or not some object is an element of a set. We use the notation xS to denote that x is an element of the set S. For example, we would write that 1 ∈ {1, 2, 3}, or that cat ∈ { cat, dog }. If spoken aloud, you'd read x ∈ S as “ x is an element of S .” Similarly, we use the notation xS to denote that x is not an element of S. So, we would have 1 ∉ {2, 3, 4}, dog ∉ {1, 2, 3}, and ibex ∉ {cat, dog}. You can read xS as “ x is not an element of S .” Sets appear almost everywhere in mathematics because they capture the very simple notion of a group of things. If you'll notice, there aren't any requirements about what can be in a set. You can have sets of in- tegers, sets of real numbers, sets of lines, sets of programs, and even sets of other sets. Through the re - mainder of your mathematical career, you'll see sets used as building blocks for larger and more compli - cated objects.

contain anything (the fact that there's nothing in-between them!) However, in practice this notation is not used, and we use the special symbol Ø to denote the empty set. The empty set has the nice property that there's nothing in it, which means that for any object x that you ever find anywhere, x ∉ Ø. This means that the statement x ∈Ø is always false. Let's return to our earlier discussion of sets containing other sets. It's possible to build sets that contain the empty set. For example, the set { Ø } is a set with one element in it, which is the empty set. Thus we have that Ø ∈ { Ø }. More importantly, note that Ø and { Ø } are not the same set. Ø is a set that con- tains no elements, while { Ø } is a set that does indeed contain an element, namely the empty set. Be sure that you understand this distinction! 1.2 Operations on Sets Sets represent collections of things, and it's common to take multiple collections and ask questions of them. What do the collections have in common? What do they have collectively? What does one set have that the other does not? These questions are so important that mathematicians have rigorously de - fined them and given them fancy mathematical names. First, let's think about finding the elements in common between two sets. Suppose that I have two sets, one of US coins and one of chemical elements. This first set, which we'll call C , is C = { penny, nickel, dime, quarter, half-dollar, dollar } and the second set, which we'll call E , contains these elements: E = { hydrogen, helium, lithium, beryllium, boron, carbon, …, ununseptium } (Note the use of the ellipsis here. It's often acceptable in mathematics to use ellipses when there's a clear pattern present, as in the above case where we're listing the elements in order. Usually, though, we'll in- vent some new symbols we can use to more precisely describe what we mean.) The sets C and E happen to have one element in common: nickel, since nickel ∈ C and nickel ∈ E However, some sets may have a larger overlap. For example, consider the sets {1, 2, 3} and {1, 3, 5}. These sets have both 1 and 3 in common. Other sets, on the other hand, might not have anything in com - mon at all. For example, the sets {cat, dog, ibex} and {1, 2, 3} have no elements in common. Since sets serve to capture the notion of a collection of things, we might think about the set of elements that two sets have in common. In fact, that's a perfectly reasonable thing to do, and it goes by the name intersection : The intersection of two sets S and T , denoted ST , is the set of elements contained in both S and T. For example, {1, 2, 3} ∩ {1, 3, 5} = {1, 3}, since the two sets have exactly 1 and 3 in common. Using the set C of currency and E of chemical elements from earlier, we would say that CE = {nickel}. But what about the intersection of two sets that have nothing in common? This isn't anything to worry about. Let's take an example: what is {cat, dog, ibex} ∩ {1, 2, 3}? If we consider the set of elements

Chapter 1: Sets and Cantor's Theorem

common to both sets, we get the empty set Ø, since there aren't any common elements between the two sets. Graphically, we can visualize the intersection of two sets by using a Venn diagram , a pictorial representa- tion of two sets and how they overlap. You have probably encountered Venn diagrams before in popular media. These diagrams represent two sets as overlapping circles, with the elements common to both sets represented in the overlap. For example, if A = {1, 2, 3} and B = {3, 4, 5}, then we would visualize the sets as A B 1 2 4 5 3 Given a Venn diagram like this, the intersection AB is the set of elements in the intersection, which in this case is {3}. Just as we may be curious about the elements two sets have in common, we may also want to ask what el - ements two sets contain collectively. For example, given the sets A and B from above, we can see that, collectively, the two sets contain 1, 2, 3, 4, and 5. Mathematically, the set of elements held collectively by two sets is called the union : The union of two sets A and B , denoted AB , is the set of all elements contained in either of the two sets. Thus we would have that { 1 , 2 , 3 } ∪ { 3 , 4 , 5 } = { 1 , 2 , 3 , 4 , 5 } (here, I'm color-coding the numbers to in- dicate which sets they're from; we'll treat all numbers as the same regardless of their color). Note that, since sets are unordered collections of distinct elements, that it would also have been correct to write { 1 , 2 , 3 , 3 , 4 , 5 } as the union of the two sets, since { 1 , 2 , 3 , 4 , 5 } and { 1 , 2 , 3 , 3 , 4 , 5 } describe the same set. That said, to eliminate redundancy, typically we'd prefer to write out {1, 2, 3, 4, 5} since it gets the same message across in smaller space. The symbols for union ( ∪) and intersection (∩) are similar to one another, and it's often easy to get them confused. A useful mnemonic is that the symbol for union looks like a U, so you can think of the ∪nion of two sets. An important (but slightly pedantic) point is that ∪ can only be applied to two sets. This means that al- though {1, 2, 3} ∪ 4 might intuitively be the set {1, 2, 3, 4}, mathematically this statement isn't meaningful because 4 isn't a set. If we wanted to represent the set formed by taking the set {1, 2, 3} and adding 4 to it, we would rep - resent it by writing {1, 2, 3} ∪{4}

Chapter 1: Sets and Cantor's Theorem

Note that there are two different notations for set difference. In this book we'll use the minus sign to indi- cate set subtraction, but other authors use the slash for this purpose. You should be comfortable working with both. As an example of a set difference, {1, 2, 3} – {3, 4, 5} = {1, 2}, because 1 and 2 are in {1, 2, 3} but not {3, 4, 5}. Note, however, that {3, 4, 5} – {1, 2, 3} = {4, 5}, because 4 and 5 are in {3, 4, 5} but not {1, 2, 3}. Set difference is not symmetric. It's also possible for the difference of two sets to contain nothing at all, which would happen if everything in the first set is also contained in the second set. For instance, {1, 2, 3} – {1, 2, 3, 4} = Ø, since every element of {1, 2, 3} is also contained in {1, 2, 3, 4}. There is one final set operation that we will touch on for now. Suppose that you and I travel the world and each maintain a set of the places that we went. If we meet up to talk about our trip, we'd probably be most interested to tell each other about the places that one of us had gone but the other hadn't. Let's say that set A is the set of places I have been and set B is the set of places that you've been. If we take the set AB , this would give the set of places that I have been that you hadn't, and if you take the set BA it would give the set of places that you have been that I hadn't. These two sets, taken together, are quite in - teresting, because they represent fun places to talk about, since one of us would always be interested in hearing what the other had to say. Using just the operators we've talked about so far, we could describe this set as ( BA ) ∪ ( AB ). For simplicity, though, we usually define one final operation on sets that makes this concept easier to convey: the symmetric difference. The set symmetric difference of two sets A and B , denoted A Δ B , is the set of elements that are contained in exactly one of A or B , but not both. For example, {1, 2, 3} Δ {3, 4, 5} = {1, 2, 4, 5}, since 1 and 2 are in {1, 2, 3} but not {3, 4, 5} and 4 and 5 are in {3, 4, 5} but not {1, 2, 3}. 1.3 Special Sets So far, we have described sets by explicitly listing off all of their elements: for example, {cat, dog, ibex}, or {1, 2, 3}. But what if we wanted to consider a collection of things that is too big to be listed off this way? For example, consider all the integers, of which there are infinitely many. Could we gather them together into a set? What about the set of all possible English sentences, which is also infinitely huge? Can we make a set out of them? It turns out that the answer to both of these questions is “yes,” and sets can contain infinitely many ele - ments. But how would we describe such a set? Let's begin by trying to describe the set of all integers. We could try writing this set as {…, -2, -1, 0, 1, 2, … } which does indeed convey our intention. However, this isn't mathematically rigorous. For example, is this the set {…, -11, -7, -5, -3, -2, -1, 0, 1, 2, 3, 5, 7, 11, … } Or the set {…, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, … } Or even the set {… -16, -8, -4, -2, -1, 0, 1, 2, 3, 4, 5 …, }

When working with complex mathematics, it's important that we be precise with our notation. Although writing out a series of numbers with ellipses to indicate “and so on and so forth” might convey our inten- tions well in some cases, we might end up accidentally being ambiguous. To standardize terminology, mathematicians have invented a special symbol used to denote the set of all integers: the symbol ℤ. The set of all integers is denoted ℤ. Intuitively, it is the set {…, -2, -1, 0, 1, 2, …} For example, 0 ∈ ℤ, -137 ∈ ℤ, and 42 ∈ ℤ, but 1.37 ∉ ℤ, cat ∉ ℤ, and {1, 2, 3} ∉ ℤ. The in tegers are whole numbers, which don't have any fractional parts. When reading a statement like x ∈ ℤ aloud, it's perfectly fine to read it as “ x in Z,” but it's more common to read such a statement as “ x is an integer,” abstracting away from the set-theoretic definition to an (equivalent) but more readable version. Since ℤ really is the set of all integers, all of the set operations we've developed so far apply to it. For ex- ample, we could consider the set ℤ∩ {1, 1.5, 2, 2.5}, which is the set {1, 2}. We can also compute the union of ℤ and some other set. For example, ℤ ∪ {1, 2, 3} is the set ℤ, since 1 ∈ ℤ, 2 ∈ ℤ, and 3 ∈ ℤ. You might be wondering – why ℤ? This is from the German word “ Zahlen,” meaning “numbers.”*^ Much of modern mathematics has its history in Germany, so many terms that we'll encounter in the course of this book (for example, “Entscheidungsproblem”) come from German. Much older terms tend to come from Latin or Greek, while results from the 8th^ through 13th^ centuries are often Arabic (for example, “alge-

bra” derives from the title كتاب المختصر في حساب الجبر والمقابلة of a book written in the 9th^ century by Per-

sian mathematician al-Khwarizmi, whose name is the source of the word “algorithm.”) It's interesting to see how the languages used in mathematics align with major world intellectual centers. While in mathematics the integers appear just about everywhere, in computer science they don't arise as frequently as you might expect. Most languages don't allow for negative array indices. Strings can't have a negative number of characters in them. A loop never runs -3 times. More commonly, in computer sci- ence, we find ourselves working with just the numbers 0, 1, 2, 3, …, etc. These numbers are called the natural numbers , and represent answers to questions of the form “how many?” Because natural numbers are so ubiquitous in computing, the set of all natural numbers is particularly important: The set of all natural numbers , denoted ℕ, is the set ℕ = {0, 1, 2, 3, …} For example, 0 ∈ ℕ, 137 ∈ ℕ, but -3 ∉ ℕ, 1.1 ∉ ℕ, and {1, 2} ∉ ℕ. As with ℤ, we might read x ∈ ℕ as either “x in N” or as “ x is a natural number.” The natural numbers arise frequently in computing as ways of counting loop iterations, the number of nodes in a binary tree, the number of instructions executed by a program, etc. Before we move on, I should point out that while there is a definite consensus on what ℤis, there is not a universally-accepted definition of ℕ. Some mathematicians treat 0 as a natural number, while others do not. Thus you may find that some authors consider ℕ = {0, 1, 2, 3, … } while others treat ℕ as

  • A reader pointed out that the German words “Zahlen” (with an upper-case Z) and “zahlen” (with a lower-case z) actually have different meanings. “Zahlen” means “numbers,” while “zahlen” is the infinitive “to pay.”

This would be read as “the set of all x , where x is a real number and x is greater than 0.” Leaving the realm of pure mathematics, we could also consider a set like this one: { p | p is a legal Java program } If you'll notice, each of these sets is defined using the following pattern: { variable | conditions on that variable } Let's dissect each of the above sets one at a time to see what they mean and how to read them. First, we defined the set of even natural numbers this way: { n | n ∈ ℕ and n is even } Here, this definition says that this is the set formed by taking every choice of n where n ∈ ℕ (that is, n is a natural number) and n is even. Consequently, this is the set {0, 2, 4, 6, 8, …}. The set { x | x ∈ ℝ and x > 0 } can similarly be read off as “the set of all x where x is a real number and x is greater than zero,” which fil- ters the set of real numbers down to just the positive real numbers. Of the sets listed above, this set was the least mathematically precise: { p | p is a legal Java program } However, it's a perfectly reasonable way to define a set: we just gather up all the legal Java programs (of which there are infinitely many) and put them into a single set. When using set-builder notation, the name of the variable chosen does not matter. This means that all of the following are equivalent to one another: { x | x ∈ ℝ and x > 0 } { y | y ∈ ℝ and y > 0 } { z | z ∈ ℝ and z > 0 } Using set-builder notation, it's actually possible to define many of the special sets from the previous sec- tion in terms of one another. For example, we can define the set ℕ as follows: ℕ = { x | x ∈ ℤ and x ≥ 0 } That is, the set of all natural numbers (ℕ) is the set of all x such that x is an integer and x is nonnegative. This precisely matches our intuition about what the natural numbers ought to be. Similarly, we can define the set ℕ ⁺as ℕ⁺ = { n | n ∈ ℕ and n ≠ 0 } Since this describes the set of all n such that n is a nonzero natural number. So far, all of the examples above with set-builder notation have started with an infinite set and ended with an infinite set. However, set-builder notation can be used to construct finite sets as well. For example, the set { n | n ∈ ℕ, n is even, and n < 10 } has just five elements: 0, 2, 4, 6, and 8. To formalize our definition of set-builder notation, we need to introduce the notion of a predicate :

Chapter 1: Sets and Cantor's Theorem

A predicate is a statement about some object x that is either true or false. For example, the statement “ x < 0” is a predicate that is true if x is less than zero and false otherwise. The statement “ x is an even number” is a predicate that is true if x is an even number and is false otherwise. We can build far more elaborate predicates as well – for example, the predicate “ p is a legal Java program that prints out a random number” would be true for Java programs that print random numbers and false otherwise. Interestingly, it's not required that a predicate be checkable by a computer program. As long as a predicate always evaluates to either true or false – regardless of how we'd actually go about verifying which of the two it was – it's a valid predicate. Given our definition of a predicate, we can formalize the definition of set-builder notation here: The set { x | P ( x ) } is the set of all x such that P ( x ) is true. It turns out that allowing us to define sets this way can, in some cases, lead to paradoxical sets , sets that cannot possibly exist. We'll discuss this later on when we talk about Russell's Paradox. However, in practical usage, it's almost universally safe to just use this simple set-builder notation. 1.4.2 Transforming Sets You can think of this version of set-builder notation as some sort of filter that is used to gather together all of the objects satisfying some property. However, it's also possible to use set-builder notation as a way of applying a transformation to the elements of one set to convert them into a different set. For example, suppose that we want to describe the set of all perfect squares – that is, natural numbers like 0 = 02 , 1 = 12 , 4 = 2^2 , 9 = 3^2 , 16 = 4^2 , etc. Using set-builder notation, we can do so, though it's a bit awkward: { n | there is some m ∈ ℕ such that n = m^2 } That is, the set of all numbers n where, for some natural number m , n is the square of m. This feels a bit awkward and forced, because we need to describe some property that's shared by all the members of the set, rather than the way in which those elements are generated. As a computer programmer, you would probably be more likely to think about the set of perfect squares more constructively by showing how to build the set of perfect squares out of some other set. In fact, this is so common that there is a variant of set-builder notation that does just this. Here's an alternative way to define the set of all perfect squares: { n^2 | n ∈ ℕ } This set can be read as “the set of all n^2 , where n is a natural number.” In other words, rather than build- ing the set by describing all the elements in it, we describe the set by showing how to apply a transforma - tion to all objects matching some criterion. Here, the criterion is “ n is a natural number,” and the transfor- mation is “compute n^2 .” As another example of this type of notation, suppose that we want to build up the set of the numbers 0, ½, 1, 3 / 2 , 2, 5 / 2 , etc. out to infinity. Using the simple version of set-builder notation, we could write this set as { x | there is some n ∈ ℕ such that x = n / 2 } That is, this set is the set of all numbers x where x is some natural number divided by two. This feels forced, and so we might use this alternative notation instead: { n / 2 | n ∈ ℕ }