[Instructions] [Search] [Current] [Syllabus] [Links] [Handouts] [Outlines] [Assignments] [Labs]
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!
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.)
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.
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.
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*X^{2} might be
represented as <8 2>
and the polynomial term
5*Y^{23} might be represented as <5 23>
.
Putting it together, the single-variable polynomial X^{3} + 4*X^{2} + 86*X + 21 might be represented as
<<1 3> <4 2> <86 1> <21 0>>
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.
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.
Describe an appropriate representation we could use for polynomials over multiple variables, such as X^{2} + 4XY + 3Y^{2}. Note that our implementation of FP does not permit symbolic or string variables, so you should indicate how to accommodate that restriction.
You may recall that on exam 3, we explored the creation of ``integers'' in Prolog using three basic forms:
zero
succ(X)
, which represents X+1
pred(X)
, which represents X-1
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.
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).
opposite(pred(succ(pred(zero))), succ(zero))
opposite(succ(zero), pred(pred(succ(zero))))
opposite(pred(pred(succ(succ(zero)))), zero)
You may not use fromInt
or toInt
.
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
.
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
.
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; }
What is the difference (if any) between the two programs that read two integers and compute the maximum?
In the ``count evens and odds'' program,
x
to undefined
after
incrementing the counters?
done
serve?
evens!=undefined
from the guard from incrementing the evens?
Write a Gabble program that reads in a list of integers, computes the minimum value in the list, and outputs the result.
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).
How might you implement a construct similar to exceptions in Gabble?
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
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
[Instructions] [Search] [Current] [Syllabus] [Links] [Handouts] [Outlines] [Assignments] [Labs]
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