Review Quiz 2 ============= Solution to the tic-tac-toe problem. In the first step, there are 9 different moves possible. In the next step, 8 different moves. In the ith step, if the game has not finished yet, 9-i+1 different moves possible. So total number of possible games is at most 9!. Noting that at least 5 moves are required before a player wins, there are at least 9*8*7*6*5 different games possible. The above is assuming that we distinguish between symmetric positions on the tic-tac-toe board. If one takes into account symmetries (as a computer would, for efficiency), the number of different possible games is a small fraction of the above. For instance, in the first move, there are only 3 possibilities. In the second move, there are only 2-4 possibilities, depending on the choice of the first move. Saddleback Search ================= Connect with the notion of efficiency. Introduction to program invariants. Importance of program correctness. Interpreters & compilers ======================== Can we solve all problems? What do we mean by this? Need to specify a model for machine and language for writing solutions. Well, this is precisely what we do in programming. Programming is synonymous with computing. A programming language creates a virtual machine for the programmer. Different languages offer different levels of abstraction. Low-level language: Machine code, just a sequence of binary bits. Directly invoking the circuitry in the machine. Assembly-level language: Higher level, machine instructions rather than just bits. Also, can refer to register locations. Needs a translator to convert assembly code into machine code. Higher-level languages all need translators. The programmer enters instructions in the language, either one at a time or in a sequence and these instructions are executed by the virtual machine. Program ---> Virtual Machine ----> Output Data ---> The virtual machine could be implemented in several ways. Program ---> Compiler ----> Object code ---> Output Data ---------------------> Program ---> Interpreter ---> Output Data ------> Example of interpreters ======================= (1) The Unix shell is a command interpreter. It accepts a command that satisfies certain rules and executes it according to the semantics of the command. (2) A Web browser is an interpreter for HTML. It accepts an HTML file and displays it according to the semantics of HTML. (3) Matlab, Mathematica, and Maple are three programs for interpreting various kinds of mathematical expressions. (4) A graphical user interface (GUI) interprets user inputs (in the form of button clicks and text entered into text boxes) and translates the commands into functions of the core program. Interpreter for Arithmetic Expressions ====================================== We consider a simple language for writing arithmetic expressions. The language is defined by its syntax and semantics. The syntax consists of the rules for generating valid statements in the language (also referred to as production rules). The semantics defines the meaning (or behavior) of programs written in the language. In this example, a program in the language is a single statement that can be produced using one of two rules: R0: ==> num R1: ==> op where num is any real number and op is a binary operator -- chosen from {+,-,*,/,^}. The semantics of the language is given by the value() function. R0: ==> num value() = num R1: ==> op value() = value obtained by applying op to value() and value() Our goal is to write an interpreter for the language. We need to (a) determine whether a given statement is valid and (b) compute the value of a valid statement. For both the parts, we need to be able to parse a given statement according to the production rules. Fortunately, our rules are such that there is no ambiguity. If the statement is a valid one, then there is only one way to parse it. We generate a parse tree for the statement. The parse tree also suggests an easy method for evaluating a valid statement. Example: * 5 + - * 6 7 5 + 8 9