Homework 6
Recursive Functions and Language Processing
Due: Monday, March 9, at 11:59 PM
Introduction
Opening Paragraph
This assignment asks you to write even more recursive functions in Racket. The goals of this assignment are to gain more experience with common recursion patterns and to begin applying them to programming language topics.
Template Source Files
Download the zipped directory
hw06.zip.
It contains templates for your solutions and two files of
helper functions.
-
homework06.rkt, a template file for your function definitions -
homework06-tests.rkt, a template file for your test cases -
syntax-procs.rkt, a file containing syntax procedures for the little language we are studying -
occurs-procs.rkt, a file containing two functions we wrote for processing expressions in the little language
Please use the given names as the names of the files you
submit, and do not modify the provide or
require clauses in any of the files.
With provide, you must define all five
functions. If you don't have time to solve a problem, define
a function that takes the correct number of arguments and
returns a legal default value, such as 0,
#f, or '().
Keep the two files of helper functions in the folder with your solutions and tests. You will not modify or submit these files.
Do Not Use...
To solve these problems, you do not need any Racket features beyond the things we have learned in class and the things discussed in this assignment. In order to practice the new skills we are learning, do not use...
-
... any of Racket's primitive higher-order functions,
including
map,apply, andfilter. -
...
flatten,reverse, or any Racket function that converts a list argument to another datatype. Process the list one element at a time. -
... a
letexpression or an internaldefinein any function.
You do not need an interface procedure or an accumulator variable to solve any of these problems. You can determine the answer for each case directly from its parts.
Organizing Code
Put your solutions in homework06.rkt.
Put any helper functions you write for a problem after the
main function of your solution.
Put your tests in homework06-tests.rkt.
For each problem, write at least three Rackunit expressions
to test your solution. Depending on the type of value that
the function produces, use check-equal? or
check-true/check-false. You may use my examples
as one of your tests. Be sure that you test other key cases,
too.
Test only the public functions. Helper functions are not visible outside your solution module.
Data Definitions
The problems refer to these inductive data definitions:
<binary-tree> ::= <number>
| (<number> <binary-tree> <binary-tree>)
<prefix-exp> ::= (<operator> <number-exp> <number-exp>)
<number-exp> ::= <number>
| <prefix-exp>
<exp> ::= <varref>
| (lambda (<var>) <exp>)
| (<exp> <exp>)
As discussed
in class,
use the syntax procedures for the little language. They are
defined in
syntax-procs.rkt:
exp? varref? lambda? lambda->param lambda->body app? app->proc app->arg
Problems
-
Write a structurally recursive function named
(tree-min bin-tree)that takes as an argument a binary treebin-tree.
tree-minreturns the smallest value in the tree. For example:> (tree-min '(8 (13 11 (5 24 6)) (15 (12 10 14) 20))) 5
You will find Racket's primitive functionminuseful here. -
Write a structurally recursive function named
(tree-contains? n bin-tree)that takes two arguments, a numbernand a binary treebin-tree.
(tree-contains? n bin-tree)returns#tifnoccurs anywhere inbin-tree, and#fotherwise. For example:> (tree-contains? 8 '(7 (12 8 6) (4 3 9))) #t
-
Write a mutually recursive function named
(count-operators prefix-exp)that takes one argument, a binary expression in prefix notation.
count-operatorsreturns the number of operators inprefix-exp. For example:> (count-operators '(* (+ 4 5) (+ 7 6))) 3
count-operatorsmust be mutually recursive with the functioncount-operators-ne, which returns the number of operators in a number expression. -
Write a structurally recursive function named
(count-lambdas exp)that takes as input an expression in the little language from class.
count-lambdasreturns the number oflambdaexpressions that appear inexp. For example:> (count-lambdas '(f (lambda (x) x))) 1 > (count-lambdas '(lambda (x) (lambda (z) z))) 2 -
Write a structurally recursive function named
(declared-vars exp)that takes as input an expression in the little language from class.
declared-varsreturns a list of all the variables declared inexp. Recall that onlylambdaexpressions can create a variable. For example:> (declared-vars '(lambda (y) (x y))) (y) > (declared-vars '((lambda (x) (lambda (z) z)) (lambda (x) y) )) (x z x) ;; duplicates are allowedEach case ofdeclared-varswill return a list of symbols. In the app case, you will need to combine two lists into one. For this, you will want to use Racket's primitive functionappend.> (append '(w x) (y z)) (w x y z)
Deliverables
By the due time and date, use the course submission system to submit the following files electronically:
-
homework06.rkt, the source file containing your function definitions -
homework06-tests.rkt, the source file containing your test cases
Be sure that your submission follows the submission requirements. Be sure to use the specified name for your file. This enables the auto-grader to find and run your code.