• Handouts
A.1. Find a diagram illustrating proposition 2 of book VII of Euclid's Elements, either in a published edition of that work or on line. Make a hard copy. On your copy, label each line segment mentioned in the text of Euclid's proof with a natural number giving its length, in such a way that the account given in the proof accurately describes the arithmetic operations and results.
A.2. Using mathematical induction, prove the correctness of Euclid's algorithm -- either Euclid's version of it, or the Scheme definition shown at the end of the handout. Which is easier?
A.3. Describe the Algol 60 compound statement (see page 5 of the handout on Backus-Naur form) in unextended BNF.
A.4. The basic form of Java for-statement is the one shown in the
example on page 6 of the handout on Backus-Naur form. Recent versions of Java also support an "enhanced"
form of the for-statement, with the concrete syntax
<for-stmt> ::= for ( <type> <identifier> : <expr> ) <stmt>
Revise the data type definition for for-stmt so that it supports
both basic and enhanced forms (as variants).
A.5. The variable-declaration part of a Pascal program, procedure
definition, or function definition consists of the keyword var
followed by one or more declarations, each consisting of one or more
identifiers (separated by commas), a colon, and either an identifier or a
constructed type. Each declaration is terminated by a semicolon.
Translate this description into one or more BNF rules. (You can assume
that the category <constructed-type> is defined elsewhere.) Then
write a data type definition for it.
A.6. A grammar for the Lua programming language, expressed in extended BNF, can be found at the end of the Lua 5.1 reference manual). Construct data type definitions for the syntactic categories defined there.
Note that the manual's authors use square brackets to enclose optional components and curly braces to enclose components that can be repeated any number of times. So the extended BNF rule that they write as
funcname ::= Name {`.' Name} [`:' Name]
would, if written using the BNF conventions adopted in the handout, appear as
<funcname> ::= <name> {. <name>}* {: <name>}?
A.7. The ARITHMETIC language is implemented in six Scheme files: expval.scm, tokens.scm, and syntax-trees.scm, which define the shared data types for expressed and denoted values, lexical tokens, and abstract syntax trees, respectively; and scanner.scm, parser.scm, and interpreter.scm, which respectively carry out the lexical analysis, parsing proper, and evaluation of programs in the language.
For each of the following proposed changes or improvements in the ARITHMETIC language, describe the changes, if any, that one would have to make in each of the six Scheme files in order to implement it. Then choose one of the proposed changes, implement it, and test the resulting code.
sub, instead of the minus sign as the symbol
for a subtraction operation.if-expressions; if the value of such an expression is 0, then the
alternative is selected (i.e., 0 counts as false), while if it is any
non-zero value, the consequent is selected.<expression> ::= +
( <expression> , <expression> ).|, is encountered in the text of a program, then it and everything that
follows it, up to and including the next vertical bar, is considered a
comment and discarded.A.8. The concrete syntax that ARITHMETIC uses for subtraction doesn't match the usual mathematical conventions, in which subtraction is an infix operator:
<expression> ::= <expression> - <expression>
But using this concrete syntax in ARITHMETIC would have complicated the
parser and forced other troublesome modifications in the syntax. Explain
why. (Hint: Construct an example, using the infix syntax, in which the
minuend is an if-expression.)
A.9. Add a new kind of expression to ARITHMETIC, one that includes two
subexpressions, each having a number as value. When evaluated, an
expression of this new kind should determine whether its subexpressions
have equal values, returning (bool-val #t) if they do and (bool-val #f) if not. Choose a concrete syntax that harmonizes with the
existing syntax. Implement and test your design.
A.10. In the PROC program presented in exercise 3.23 of the textbook (page 81), examine each occurrence of an identifier and state whether it is a declaration or a reference. In addition, state the lexical address of each reference.
A.11. Use the λ-calculus axioms and rules of inference to
prove that (^n.^f.^x.(f ((n f) x)) ^g.^y.(g (g y))) = ^f.^x.(f
(f (f x))) (or, in other words, that the successor of two is three!).
A.12. By hand, evaluate the λ-calculus expression (((^x.^y.^z.((z ^w.y) x) u) v) ^x.^y.y) by performing as many successive
beta-reductions on it as possible. You may choose any evaluation order.
A.13. In an abnormal-order evaluator for the λ-calculus, we choose always to reduce the rightmost maximal beta-redex in the current expression, and we keep reducing until no more beta-redexes remain. Implement an abnormal-order evaluator for LAMBDA. Give an example of a LAMBDA expression that has a normal form, but runs forever in the abnormal-order evaluator.
A.14. Give an example of a LAMBDA expression that terminates with a normal form in a normal-order evaluator, terminates but does not yield a normal form in an applicative-order evaluator without partial evaluation, and does not terminate in an applicative-order evaluator with partial evaluation.
A.15. Modify the implementation of the run procedure in the
normal-form evaluator for LAMBDA so that it not only returns the normal
form of each expression that it is given, but also displays, as a side
effect, the number of beta-reductions that the evaluator performed in
reaching that normal form.
A.16. An arithmetic predicate in the λ-calculus is
a function that returns either true or false when given any
Church numeral (in other words, the application of the function to the
Church numeral is always beta-reducible to true or to false).
Define and test a function minarg that takes any arithmetic
predicate f and returns the Church numeral for the least natural
number n that satisfies f (that is, the least one for
which the application is beta-reducible to true). It is all right,
and indeed desirable, for there to be no normal form when minarg is
applied to an arithmetic predicate that returns false for every Church numeral.
A.17. In the λ-calculus, define and test a ``binary''
function equal? that tests whether two given Church numerals
represent the same number. In other words, ((equal? m) n) should be
beta-reducible to true when the same Church numeral is substituted
for both m and n, but to false when different Church
numerals are dropped in.
A.18. In the λ-calculus, define and test a ``binary''
function append that constructs and returns the result of
concatenating two given lists.
A.19. Write an expression in EXPLICIT-REFS that has, as its value, a (curried) procedure that takes two references as arguments, exchanges the values stored in those references, and returns the true Boolean value.
A.20. How many values can the Icon expression not (0 to 5)
generate, and what are those values? Why do Griswold and Griswold describe
not as a "control structure" (p. 23) rather than an operator?
A.21. Complete the following Icon program so that it prints out all the Pythagorean triples (a, b, c) of positive integers less than or equal to 25 -- the triples such that a2 + b2 = c2.
procedure main()
every (YOUR EXPRESSION HERE) do
write("(", a, ", ", b, ", ", c, ")")
end
A.22. Add a not-expression to the GENERATORS language, with the
syntax
not <expression>
When evaluated, a not-expression should fail if its subexpression
succeeds and should succeed (once), producing the value 0, if its
subexpression fails.
A.23. Read chapters 7 and 8 of The Icon programming language, then write (1) an Icon procedure that takes one argument, an integer greater than or equal to 2, and succeeds if that integer is prime but fails if it is not; (2) an expression that generates all the "twin primes," i.e., pairs of prime numbers differing by 2; and (3) a program that prints out the first hundred twin-prime pairs. Use two-element lists to represent pairs.
A.24. Read chapter 7 of The Icon programming language, then
add to GENERATORS (1) a list data type, as in exercise 3.9 of Friedman and
Wand, and (2) a unary element operator, with the syntax
element ( <expression> )
that generates the elements of a given list. (For instance, the expression
every print(element(ls)) do fail should print out the elements of
ls.)
A.25. Read chapter 7 of The Icon programming language, then add to GENERATORS (1) a repeated-alternation operator like the one Griswold and Griswold describe on pages 94 and 95, with the syntax
regenerate <expression>
and (2) a limited-generation operator like the one that Griswold and Griswold describe on pages 93 and 94, with the syntax
stopafter <expression> for <expression>
where the first expression, which must have a numeric value, imposes the
maximum number of values that can be recovered from the second expression's
result sequence. Note that the order in which the subexpression appear in
a stopafter-expression is the opposite of the order in which they
appear in Icon's limited-generation expressions.
Two other notes:
(1) A repeated-alternation expression fails immediately if its subexpression fails immediately.
(2) Do not allow control backtracking from the second subexpression of a
stopafter-expression into the first one.