[UMN logo]

CSCI 5106: Programming Languages
Spring 2006, University of Minnesota
Homework 3


Posted: Feb 14, 2006
Due: Before class on Feb 23, 2006


Problem 1

The RAM program that is shown on page 6 of the text is intended to read in a sequence of integers and to write out the sequence with adjacent duplicates removed. This problem requires you to consider the issue of developing a conviction that this program does the right thing simply by introspecting on the text of the program. In particular:
  1. Explain very briefly the general methodology you would use to develop an argument for the correctness of the program. You might find the discussion on pages 61-63 useful in this process.

  2. Apply this methodology explicitly to this case to provide an argument for the correctness of the RAM program.

  3. Compare the difficulty of this task with that of explaining the correctness of the program on page 68. If the former is more difficult, identify, as precisely and briefly as you can, the source of the difficulty.
In doing this problem, it is important that you first to crystallize your thoughts as clearly as you can and then write only a few sentences as an answer to each part. An important criterion in evaluation will be the correctness and the crispness of the insights you offer concerning reasoning about programs and how well you are able to capture the essence of the RAM program.


Problem 2

  1. Draw the flow diagram and the tree representing the abstract syntax for the following schematic program fragment assuming that <alpha>, <beta>, <gamma>, and <delta> represent atomic statement that <A>, <B> and <C> represent boolean expressions, that we write semicolons to indicate the end of a statement as in the language C and that we bracket a sequence of statements with begin and end to convert it into a single statement:
         while <A do
         begin
            if <C>  
            then <gamma>;
            else repeat <delta>; until <B>;
            <beta>;
         end;
         <alpha>;
    

  2. Label each subtree representing a non-atomic statement in the abstract syntax tree and draw labelled boxes around portions of the flow diagram that correspond to each of these subtrees. How many edges go into and out of each of these boxes?

  3. Suppose that the last statement in the program schema above is replaced by
         l: <alpha>;
    
    where l represents a label and <gamma> is replaced by
          goto l
    
    Draw the abstract syntax tree and the flow diagram for the resulting program.

  4. Is it possible to describe a correspondence between subparts of the abstract syntax tree and the flow diagram for the new program in the way you have done for the earlier program? If your answer is yes, present the correspondence. If it is no, explain briefly why not.


Problem 3

Problem 3.3 (c) in the book. Note that what is meant by ``they evaluate their second argument only if necessary'' is that this argument is not evaluated if there is enough information available from the first argument to already determine the value of the overall expression.


Problem 4

Assume that l and m are labels and that <alpha>, <beta>, <gamma>, <delta>, <eta> and <nu> are atomic actions in the schematic program fragment that appears below. This fragment contains goto statements. Transform it into a program fragment that has an equivalent behavior, that does not contain goto statements and that, in fact, only uses if-then-else, while-do, repeat-until and sequencing constructs over the atomic statements. You may use new assignment statements and new boolean variables if you need these. Note that the atomic actions can affect the values of variables so you must be careful about when boolean expressions such as <E1>, <E2>, etc., are evaluated. Try to be systematic in the way you transform the original program so as to ensure that you really do obtain an equivalent program at the end.
   l: <alpha>;
   if <E1> then goto m;
   <beta>;
   if <E2> then goto l;
   <delta>;
   m: <gamma>;
   if <E3> then goto l;
   <eta>;
   if <E4> then goto m;
   <nu>;


Problem 5. We will describe in class a procedure for translating the abstract syntax representation of a simple arithmetic expression into low-level instructions that evaluate that expression. This translation procedure is designed for left-to-right innermost evaluation of expressions and is based eventually on the process used to evaluate such expressions using a stack when they are written in postfix form. We will subsequently adapt this procedure to handle certain forms of outermost evaluation such as that required to implement the short-circuit evaluation of or expressions under the rules

T or <beta>  --->  T
F or <beta>  --->  <beta>
The symbols F and T in these rules stand for the values false and true, and <beta> stands for an arbitrary expression.

Suppose now that we want to use the following different set of rules for evaluating or expressions:

   <beta> or T   --->   T
   T or <beta>   --->   T
   F or F   --->  F
Discuss the problems that arise in adapting our procedure to produce low-level instructions that implement outermost evaluation with respect to this set of rules. Can you think of special hardware or software support that you can use to overcome these problems?

Note: Remember that, under an outermost evaluation scheme, at any point in a computation, the highest node in the tree representation of an expression that can be rewritten using a rule must be rewritten.


Problem 6

We have considered in class a procedure for translating the abstract syntax representation of simple arithmetic expressions involving binary operators into low-level instructions that evaluate that expressions. This procedure uses a postfix based scheme for evaluating expressions, with the collection of registers functioning as a stack. State a general principle that determines the height of this stack of registers (alternatively, the number of registers needed for evaluating the expression) as a function of the abstract syntax tree. You might find it useful to consider the translation/evaluation of a sequence of expressions such as
   ((((a * b) + c) + d) * e) + f
   a * ((b + (c + d) * e) + f)
   a + (b * (c + (d * (e + f))))
   ((a + b) * c) + (d + (e * f))
in doing this problem.

Hint: Think of casting the register count into a function that is recursive over the structure of the expression to be translated. Distinguish between left and right branches in the abstract syntax tree since these have different effects on the number of registers needed.


Last updated on Feb 14, 2006 by gopalan@cs.umn.edu