;; The first three lines of this file were inserted by DrScheme. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-advanced-reader.ss" "lang")((modname |32.1|) (read-case-sensitive #t) (teachpacks ((lib "draw.ss" "teachpack" "htdp") (lib "arrow.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "draw.ss" "teachpack" "htdp") (lib "arrow.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))))) ;A SchemeData (a representation of a Scheme expression) is either ;1. a number, ;2. a symbol, ;3. an operator structure, or ;4. a function structure. (define-struct add (left right)) (define-struct sub (left right)) (define-struct mul (left right)) (define-struct div (left right)) ;An operator is a structure ;(make-operator left right) ;where operator is replaced by one of the four operators: ;1. add (addition) ;2. sub (subtraction) ;3. mul (multiplication) ;4. div (division) ;and left and right are SchemeData. ; ;An operator structure ;(make-operator left right) ;represents the expression ;(operator left right) ;in Scheme. (define-struct function (name arg)) ;A function is a structure ;(make-function name arg) ;where name is a symbol and arg is a SchemeData. ; ;A function structure ;(make-function name arg) ;represents the expression ;(name arg) (define-struct definition (function parameter body)) ;A definition is a structure ;(make-definition function parameter body) ;where function and parameter are symbols and body is a SchemeData. ;numeric? : SchemeData -> boolean ;Given a-data, determine if the expression it ;represents is numeric. That is, ;numeric? evaluates true if the SchemeData lacks symbols, ;which represents an expression which ;lacks variables. (define (numeric? a-data) (cond [(number? a-data) true] [(add? a-data) (and (numeric? (add-left a-data)) (numeric?(add-right a-data)))] [(sub? a-data) (and (numeric? (sub-left a-data)) (numeric? (sub-right a-data)))] [(mul? a-data) (and (numeric? (mul-left a-data)) (numeric? (mul-right a-data)))] [(div? a-data) (and (numeric? (div-left a-data)) (numeric? (div-right a-data)))] [else false])) ;evaluate-expression : SchemeData -> number ;Given a-data, evaluates the numeric expression it represents ;and returns the value. (define (evaluate-expression a-data) (cond [(number? a-data) a-data] [(add? a-data) (+ (evaluate-expression (add-left a-data)) (evaluate-expression (add-right a-data)))] [(sub? a-data) (- (evaluate-expression (sub-left a-data)) (evaluate-expression (sub-right a-data)))] [(mul? a-data) (* (evaluate-expression (mul-left a-data)) (evaluate-expression (mul-right a-data)))] [(div? a-data) (/ (evaluate-expression (div-left a-data)) (evaluate-expression (div-right a-data)))])) ;subst : symbol number SchemeData -> SchemeData ;Given the representation of a variable V (symbol), ;the number N, and a SchemeData which represents an expression, ;produce a new SchemeData representing an expression ;where all occurrences of the variable V (symbol) ;have been replaced with the number N. (define (subst V N a-data) (cond [(number? a-data) a-data] [(symbol? a-data) (cond [(symbol=? a-data V) N] [else a-data])] [(add? a-data) (make-add (subst V N (add-left a-data)) (subst V N (add-right a-data)))] [(sub? a-data) (make-sub (subst V N (sub-left a-data)) (subst V N (sub-right a-data)))] [(mul? a-data) (make-mul (subst V N (mul-left a-data)) (subst V N (mul-right a-data)))] [(div? a-data) (make-div (subst V N (div-left a-data)) (subst V N (div-right a-data)))] [else a-data])) ;evaluate-with-one-def : SchemeData definition -> number ;Given an-exp and P, evaluate the argument an-exp, substitute that for the parameter in P, and then evaluate the body of P. (define (evaluate-with-one-def an-exp P) (cond [(and (definition? P) (numeric? an-exp)) (evaluate-expression (subst (definition-parameter P) (evaluate-expression an-exp) (definition-body P)))] [else (error 'evaluate-with-one-def "unexpected error")])) ;evaluate-with-defs : SchemeData list-of-definitions -> list-of-numbers ;Given an-exp and defs, evaluate an-exp, substitute this value in the body for each definition in the list-of-definitions in place of each one's parameter and evaluate the resulting body. (define (evaluate-with-defs an-exp defs) (cond [(empty? defs) empty] [(cons? defs) (cons (evaluate-with-one-def an-exp (first defs)) (evaluate-with-defs an-exp (rest defs)))])) ;test-evaluate SchemeData list-of-definitions list-of-numbers -> boolean ;Given an-exp, defs, and expected-result, evaluate an-exp, substitute it for the parameter for the body of each of the function definitions in defs, evaluate the resulting expressions, and compare that with expected-result. Return true if the two list-of-numbers are identical, false otherwise. (define (test-evaluate an-exp defs expected-result) (equal? (evaluate-with-defs an-exp defs) expected-result))