- Finite automata and regular expressions; practical applications, e.g. text editors
- Pushdown automata and context-free grammars; practical applications, e.g. parsing and compilers
- Turing machines as a general model of computers
- Introduction to unsolvability and the halting problem

**Design machines (e.g., finite automata, Turing machines) to solve specified problems.**

*The central goal of computer science is the design of algorithms to solve computational problems. The `machines' that we describe in this course are not physical machines; they are just ways to formally describe algorithms. We will also talk a bit about how to specify problems formally.***Design regular expressions and context-free grammars for a given formal language**

*A formal language is just a set of strings. We will see that they can be used to give formal specifications of computational problems. This part of the course looks at some ways to describe these languages in a compact way. Regular expressions and grammars are also useful in the design of programming languages and compilers, and in natural language understanding.***Explain why an object designed according to one of the above two bullets correctly meets its specification**

*Computer scientists should be able to design solutions for computational problems. But they must also be able to explain their solution to others. This goal of the course will help you develop your skills in doing this. You will find that proving that your solution is correct also helps you find mistakes in your solution.***Prove simple properties about models of computation (e.g., that the class of regular languages is closed under complement)**

*Here, we start to develop an overall theory of computing. Rather than thinking about one problem at a time, we look at the class of problems that can be solved by certain kinds of algorithms and prove properties about that class. This gives us deeper insight into how computers can solve problems.***Demonstrate limits of computing by proving that a problem is not solvable within a particular model of computation**

*This is one of the most important components of the course. It's important for a computer scientist to know the limitations of computers, to avoid wasting time on trying to solve a task that turns out to be impossible.***Show how one problem can be reduced to another**

*This is a skill that computer scientists use all the time. Instead of solving a problem from scratch, it helps if you can relate it to another problem that has already been solved, and then use the solution to that second problem to solve the original one.*

You learn by struggling with problems.
However, if you get too stuck or don't know how to begin,
**help is available**. Talk to your classmates (however; see the notes below about academic honesty regarding discussing assignment problems with others).
Go to office hours; the instructor and TA are there to help you!
You also learn by making mistakes and getting feedback about them.
Just make sure that you use the feedback to improve your understanding.

Groups of students can learn a lot by explaining their solutions to the suggested exercises from the textbook to one another and critiquing the solutions of others. After all, learning how to explain solutions clearly is one of the learning objectives of this course. Seeing where other students' solutions are unclear to you helps you make your own explanations clearer. Be aware that a problem may have many different correct solutions; just because someone's solution is different from yours doesn't necessarily mean that one of them is wrong.

It takes time to build new skills, so it helps if you work on exercises regularly: don't leave all the work to the days right before a test.

Sometimes students ask for more exercises with worked-out solutions. (The textbook has some, but maybe not enough.) There is a whole shelf of textbooks that cover the material of this course in the library (some are recommended below), and many have more examples or exercises with solutions.

The solutions you hand in should be the work of you and your partner (if you have one).
Thus, if you discuss an assignment problem with anyone other than your partner for that assignment,
you may discuss only the *general* approach to solving the problem,
not the details of the solution, and you should not take any written notes
away from such a discussion.
Also, you must list on the cover page of your solutions any people (besides your partner) with whom
you have discussed the problems.
While writing your solutions to hand in, you may look at the course textbook and your own lecture
notes, but no other outside sources.