Programming Languages (CSC-302 99S)


Exam 4: Final Examination

This page may be found online at http://www.math.grin.edu/~rebelsky/Courses/CS302/99S/Handouts/exam.04.html.

Distributed: Monday, May 10, 1999
Due: 5 p.m., Friday, May 21, 1999 No extensions!

Purpose

The final examination is intended primarily as a make-up exam. It can replace one other exam or homework grade. (It will, of course, replace your lowest such grade.)

Policies

There are five questions on this exam. Each has equal point value, although each may take a different amount of time for you to complete.

If you are confused by any question, do not hesitate to ask me for clarification. I will reserve time at the start of classes next week for questions. In addition, you can speak to me individually. I may not be available at the time you are working on the exam. If it's a reasonable hour (before 10 p.m. and after 8 a.m.), feel free to try to call me in the office (269-4410) or at home (236-7445). Email is also a reasonable way to contact me.

This examination is open book, open notes, open mind, open computer, open Web. Feel free to use any and all resources available to you except for other people and answer keys. That is, you should not consult other students, other faculty, or anyone else. (If someone outside of Grinnell has already created a Web page that answers your question and is not an answer key, that's okay; however, you can't ask someone to create such a page.) In addition, while you can look at the pages I've created for this and other courses, you should not refer any pages that are clearly answer keys to homework assignments or exams. You may not discuss the exam with anyone until after you have received a grade in the course.

As always, you are expected to turn in your own work. If you find ideas in a book or on the Web, be sure to cite them appropriately.

This is a take-home examination. It is likely to take you about ten hours. You may use any time or times you deem appropriate to complete the exam, provided you return it to me by the due date. No late exams will be accepted. I may make a solution key available soon after the exam.

Answer all of your questions electronically. That is, you must write all of your answers on the computer and print them out. Please put your answers in the same order that the problems appear in.

I will give partial credit for partially correct answers. You ensure the best possible grade for yourself by highlighting your answer and including a clear set of work that you used to derive the answer.


Problems

1. Increment Expressions in SIMPLE

Some languages, such as C, C++, and Java, provide pre- and post-increment operators that update their parameter and then return a value. For example, ++x adds 1 to x and returns the new value. Similarly, x++ adds 1 to x and returns the old value.

Consider the accompanying description of the semantics of SIMPLE. What changes would we need to make to the SIMPLE semantics to accommodate the preincrement and postincrement operators?

After summarizing the changes, write the complete new semantics.

2. Polynomials in FP

In many endeavors, it is useful to have a type to represent polynomials over a single variable. In FP, it is not possible to define new types, but it is possible to represent them using sequences of pairs. Each pair contains a multiplier and an exponent.

In this representation, the polynomial term 8*X2 might be represented as <8 2> and the polynomial term 5*Y23 might be represented as <5 23>.

Putting it together, the single-variable polynomial X3 + 4*X2 + 86*X + 21 might be represented as

<<1 3> <4 2> <86 1> <21 0>>

A. Addition

Write an FP function, polyadd that adds two single-variable polynomials, both of which use this representation. Make sure to include examples that show how your function works.

B. Evaluation

Write an FP function, polyeval which takes a single-variable polynomial and a value as parameters and evaluates the polynomial using the particular value as the value of the polynomial variable.

C. Improving the Representation

Describe an appropriate representation we could use for polynomials over multiple variables, such as X2 + 4XY + 3Y2. Note that our implementation of FP does not permit symbolic or string variables, so you should indicate how to accommodate that restriction.

3. Simplified Integers, Revisited

You may recall that on exam 3, we explored the creation of ``integers'' in Prolog using three basic forms:

We were able to create constructors which compared, canonicalized, and added integers in these forms. In this problem, you will continue your exploration of such integers.

A. Negation

Write an appropriate opposite(X,Y) predicate that holds if Y is ``negative X''. Your predicate should be able to determine whether two values are opposites. It should also generate Y from X.

Note that the two arguments to opposite need not be in exactly the opposite forms. For example, your predicate should work correctly in all of the following cases (as well as similar cases).

You may not use fromInt or toInt.

B. Subtraction

Write an appropriate subtract(Operand1,Operand2,Result) predicate that holds if Result results from subtracting Operand2 from Operand1.

Your predicate should be able to generate Result and to determine if Result is the difference.

You may not use fromInt or toInt.

C. Multiplication

Write an appropriate multiply(Operand1,Operand2,Result) predicate that holds result results from multiplying Operand2 and Operand1.

Your predicate should be able to generate Result and to determine if Result is the product.

You may not use fromInt or toInt.

4. Gabble: A Guarded Block Language

Sarah and Steven Strawdike, reflecting on the purposes of control structures, believe that we have control structures primarily because their ``limited entry, limited exit'' policy helps ensure that the preconditions for each block of code are met. They therefore suggest that we bring the preconditions to the forefront and have designed a language that does just that.

In their language, Gabble, programs consist of collections of guarded blocks, where each guarded block is a sequence of input, output, and/or assignment statements with one associated guard (predicate) for the whole block. There are no other explicit control structures: no loops, no conditionals, no functions, no exceptions, nothing besides guarded blocks and sequencing. Blocks cannot be nested.

The execution model in Gabble language is ``if one guard holds, the corresponding block is executed; if multiple guards hold, one of the corresponding blocks is executed; if no guards hold, the program terminates''.

When pressed for further details, they note that Gabble permits only four kinds of values: booleans, integers, strings, and heterogeneous lists. They say ``all the normal functions for operating on booleans, integers, strings, and lists are built in (as are appropriate operators that return boolean values)''. You also learn that it is not necessary to declare variables; any variable that has not yet been assigned to has the value undefined (which also acts like false). At the start of a program, all variables have the value undefined. You can use readInt, readString, and atEndOfFile for input. You can use writeInt and writeString for output.

The syntax of Gabble is somewhat like the syntax of C, Java, and C++, except that parenthesized guards precede braces.

Here is a sample Gabble program that echos the user's input. Because there is only one guarded block, the program terminates when the end of file is reached.

/* If input remains, read something and print it. */
(!atEndOfFile()) 
  {
    readString(x);
    writeString(x);
  }

Here is a sample Gabble program that reads in two values, stores them in x and y and then prints out the larger of the two.

/* Read the two values. */
(readValues == undefined)
  {
    readInt(x);
    readInt(y);
    readValues = true;
  }
/** Print the larger. */
(readValues && !done && x >= y)
  {
    writeInt(x);
    done = true;
  }
(readValues && !done && y >= x)
  {
    writeInt(y);
    done = true;
  }

Here is another sample Gabble program that does something similar.

/* Read the two values. */
(x == undefined && !atEndOfFile())
  {
    readInt(x);
  }
(y == undefined && !atEndOfFile())
  {
    readInt(y);
  }
/* Print the larger. */
(x != undefined && y != undefined && x >= y && done==undefined)
  {
    writeInt(x);
    done = true;
  }
(x != undefined && y != undefined && y >= x && done==undefined)
  {
    writeInt(y);
    done = true;
  }

Here is a sample Gabble program that counts the number of odd and even inputs and then prints out the counts. Variable x is used for the input, and is set to undefined when input is needed.

/* Make sure our counter variables are defined. */
(evens == undefined)
  {
    evens = 0;
  }
(odds == undefined)
  {
    odds = 0;
  }
/* Read input when necessary. */
(!atEndOfFile() && x==undefined)
  {
    readInt(x);
  }
/* Increment our counters. */
(evens!=undefined && x!=undefined && x%2 == 0)
  {
    ++evens;
    x = undefined;
  } 
(odds!=undefined && x!=undefined && x%2 == 0)
  {
    ++odds;
    x = undefined;
  } 
/* Prepare for the end of the program. */
(atEndOfFile() && done==undefined)
  {
    writeString("Evens: ");
    writeInt(evens);
    writeString("Odds: ");
    writeInt(odds);
    done = true;
  }

A. Understanding

What is the difference (if any) between the two programs that read two integers and compute the maximum?

B. More Understanding

In the ``count evens and odds'' program,

C. Minimum

Write a Gabble program that reads in a list of integers, computes the minimum value in the list, and outputs the result.

D. Permute

Write a Gabble program that reads in five strings and prints out some permutation of the strings. It should be possible for your program to print any permutation (as long as Gabble can decide ``randomly'' between blocks to execute when multiple guards hold).

E. Exceptions

How might you implement a construct similar to exceptions in Gabble?

F. Functions

It is worth considering how to implement constructs similar to functions in a language like Gabble. Before giving a general mechanism, it is appropriate to consider how we might translate a few recursive functions. Rewrite each of the following recursive functions in Gabble.

function factorial(int n)
  if n == 0 then
    return 1
  else 
    return n * factorial(n-1)
  end if
end factorial
function exp(x, n)
  if (n == 0) then
    return 1
  else if (n % 2 == 0) then
    tmp = exp(x, n/2)
    return tmp*tmp
  else
    return x*exp(x,n-1)
  end if
end exp
function foolish(int x, int y)
  if ((x == 0) || (y == 0))
    return 1
  else
    return foolish(x-1,y-2) + foolish(x-3,y-1)
  end if
end foolish

G. Critique

In a few sentences, critique the design of Gabble according to the standard criteria for evaluating languages or anything else you deem appropriate. Note that a critique can be positive as well as negative.


History


Disclaimer Often, these pages were created ``on the fly'' with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.

This page may be found at http://www.math.grin.edu/~rebelsky/Courses/CS302/99S/Handouts/exam.04.html

Source text last modified Sun May 9 08:35:18 1999.

This page generated on Sun May 9 08:41:50 1999 by SiteWeaver. Validate this page's HTML.

Contact our webmaster at rebelsky@math.grin.edu