; Problem 1. Programming with symbols and lists. ; You can use a list to represent a dictionary as follows. Each element ; in a dictionary is a list with two elements. The first element is a ; symbol giving the name being defined. The second element is its ; definition, and can be any value. ; Problem 1A. ; Write a function (dictionary? a) which returns #t if a is a dictionary ; as so defined, and #f otherwise. For example, you should have ; (dictionary? 7) -> #f ; (dictionary? '(x y z)) -> #f ; (dictionary? '((x) (7 15) (y z w))) -> #f ; (dictionary? '((x a) (y 7) (z (f x y)))) -> #t ; Hints. You can answer this problem with code that examines the ; structure of the data. It is OK if the same symbol gets two different ; definitiosn in the dictionary. Scheme includes built-in functions ; that may be useful, including (list? a) which checks if a is a list, ; (symbol? a) which checks if a is a symbol, (null? a) which checks is a ; is the empty list and (length a) which returns the number of elements ; in a if a is a list. ; The easiest way to implement this is with a helper function. ; The helper function tests if an item has the form of ; an entry in the dictionary. (define (entry? elt) (and (list? elt) (= (length elt) 2) (symbol? (car elt)))) ; Now we define dictionary as a list all of whose elements ; are entries. (define (dictionary? a) (cond [(null? a) #t] [(not (pair? a)) #f] [else (and (entry? (car a)) (dictionary? (cdr a)))])) ; Problem 1B. ; Write a function (lookup d t) which returns the first value associated ; with symbol t in dictionary d. If t is not defined, return #f. For ; example, you should have: ; (lookup '((x a) (y 7) (z (f x y))) 'y) -> 7 ; (lookup '((x a) (y 7) (z (f x y))) 'w) -> #f ; Hints. You can answer this problem with code that examines the ; structure of the data. You can assume that d is a dictionary. ; Remember the Scheme built-in function eq? to test if two symbols are ; the same. (define (lookup dict elt) (if (null? dict) #f (let* ((head (car dict)) (key (list-ref head 0)) (val (list-ref head 1))) (if (eq? key elt) val (lookup (cdr dict) elt))))) ; Problem 1C. ; Write a function (add-to-dict d t v) which returns a new dictionary d' ; just like d except that when you do (lookup d' t) you get the value v. ; For example: ; (lookup (add-to-dict '((x a) (y 7) (z (f x y))) 'y '8) 'y) -> 8 ; (lookup (add-to-dict '((x a) (y 7) (z (f x y))) 'y '8) 'x) -> a ; Hints. You can use cons to make this dictionary. (define (add-to-dict d t v) (cons (list t v) d)) ; Problem 2. Evaluation. ; Consider the program "interp-struct.scm" as extended with split. Make ; two changes. ; Instead of using a number to represent a variable, use a ; symbol. You probably want to change the structure for a variable and ; the structure for split to make the name of the information more ; mnemonic. ; Instead of using a list of values to give values for variables, use a ; dictionary as you have just defined it. ;;; CODE BELOW INTERPOLATES INTERP-STRUCT-WITH-SPLIT. ;;; CHANGES MARKED WITH ;**** ;;; Helper function: "apply binary operator" (define (abo truth-table x y) (cond [(and (eq? x 'L) (eq? y 'L)) (list-ref truth-table 0)] [(and (eq? x 'L) (eq? y 'H)) (list-ref truth-table 1)] [(and (eq? x 'H) (eq? y 'L)) (list-ref truth-table 2)] [(and (eq? x 'H) (eq? y 'H)) (list-ref truth-table 3)])) ; create a list just like l ; except to replace the nth element of l with e (define (subst l n e) (let ((this (if (null? l) 'L (car l))) (next (if (null? l) '() (cdr l)))) (if (= 0 n) (cons e next) (cons this (subst next (- n 1) e))))) ;;; An implementation of abstract syntax using define-struct in DrScheme ; This line and (make-inspector) below tells DrScheme to ; show a visual representation of the contents of structures (print-struct #t) ; The line below defines: make-variable variable? variable-sym ;*** variable is now represented by a symbol (define-struct variable (sym) (make-inspector)) ; The line below defines: make-binary binary? binary-left binary-op binary-right (define-struct binary (left op right) (make-inspector)) ; The line below defines: make-negate negate? negate-sub (define-struct negate (sub) (make-inspector)) ; The line below defines: make-split split? split-sym split-val split-expr ;*** new variable is now represented by a symbol (define-struct split (sym val expr) (make-inspector)) ;;; An interpreter of logical formulas that operates through abstract syntax (define (interp-op op) (cond [(eq? op 'and) '(L L L H)] [(eq? op 'or ) '(L H H H)])) ;*** b->dict (define (interp a dict) (cond [(variable? a) (lookup dict (variable-sym a))] [(binary? a) (abo (interp-op (binary-op a)) (interp (binary-left a) dict) (interp (binary-right a) dict))] [(negate? a) (if (eq? (interp (negate-sub a) dict) 'H) 'L 'H)] [(split? a) (interp (split-expr a) (add-to-dict dict (split-sym a) (interp (split-val a) dict)))])) ;**** variables become x, y, z instead of 0 1 2 (define testex (make-split 'z (make-negate (make-binary (make-variable 'x) 'and (make-variable 'y))) (make-binary (make-binary (make-variable 'x) 'and (make-variable 'z)) 'or (make-binary (make-variable 'y) 'and (make-variable 'z))))) ;**** sample call (define (test) (interp testex '((x H) (y L)))) ; Problem 3. XML. ; In describing the interpretation of referential noun phrases, ; linguists sometimes want to give three kinds of information: ; - does the noun phrase introduce a novel entity or does it pick out an ; entity that the hearer could already reasonably infer exists? ; - what is the index of the noun phrase? that is, what is the ; discourse referent that the noun phrase evokes - or equivalently ; what was the first noun phrase in the discourse that evoked this ; entity. ; - what is the real-world referent that the phrase is about? ; For example, in this discourse: ; A local soldier is among nearly two dozen American troops killed ; in Iraq since Saturday. Alpine resident Sgt. Joseph Perry, 23, was ; killed Monday when his patrol was attacked, officials said. ; (KNSD San Diego News, Thursday, October 5, 2006) ; There are these noun phrases: ; A local soldier - novel - index #1 - about the person Joseph Perry ; two dozen American troops - novel - index #2 - unspecified reference ; Iraq - not novel - index #3 - about the place Iraq ; Saturday - not novel - index #4 - about Saturday, Sep 30, 2006 ; Alpine resident Joseph Perry - not novel - index #1 - JP ; Monday - not novel - index #5 - about Monday, Oct 2, 2006 ; his patrol - not novel - index #6 - unspecified reference ; his - not novel - index #1 - JP ; officials - novel - index #7 - unspecified reference ; Problem 3A. ; Describe an XML representation that captures this kind of information, ; and mark up the sample text with your representation. ; SEE RELATED FILE SAMPLE-TEXT.XML. ; Problem 3B. ; Show the Scheme SXML corresponding to the marked-up sample text. (define sample-sxml '(*TOP* (text (np (@ (type "novel") (referent "Joseph Perry") (index "1")) "\nA local soldier\n") "\nis among \n" (np (@ (type "novel") (referent "Unspecified") (index "2")) "\nnearly two dozen American troops \nkilled in \n" (np (@ (type "not-novel") (referent "Iraq") (index "3")) "Iraq") "\nsince \n" (np (@ (type "not-novel") (referent "9/30/06") (index "4")) "Saturday")) (np (@ (type "not-novel") (referent "Joseph Perry") (index "1")) "\nAlpine resident Sgt. Joseph Perry, 23,") "\nwas killed\n" (np (@ (type "not-novel") (referent "10/02/06") (index "5")) "Monday") "\nwhen \n" (np (@ (type "not-novel") (referent "Unspecified") (index "6")) (np (@ (type "not-novel") (referent "Joseph Perry") (index "1")) "his") " \npatrol") "\nwas attacked, \n" (np (@ (type "novel") (referent "Unspecified") (index "7")) "officials") "\nsaid.\n"))) ; Write a function that takes such an SXML expression and an index, and ; returns a list of all the noun phrases in the expression with that ; index. Intuitively, if you pass index #1 and the SXML expression, you ; will get a list with the noun phrases for "A local soldier", "Alpine ; resident Joseph Perry", and "his". ;; HELPER FUNCTION TO TEST NP (define (match-np? sxml-elt index) ;; is this an np? (and (list? sxml-elt) (> (length sxml-elt) 2) (eq? (list-ref sxml-elt 0) 'np) ;; does it have an attribute list? (let ((attr (list-ref sxml-elt 1))) (and (pair? attr) (eq? (car attr) '@) ; is the index, if any, what's needed? (let ((my-index (lookup (cdr attr) 'index))) (and my-index (string=? my-index index))))))) ; THERE IS A SIMPLE WAY TO DO THIS USING APPEND. ;; This turns out to be O(N^2) (define (get-np-elts sxml-list index) (if (null? sxml-list) '() (append (get-nps (car sxml-list) index) (get-np-elts (cdr sxml-list) index)))) (define (get-nps sxml index) (let ((subnps (if (pair? sxml) (get-np-elts sxml index) '()))) (if (match-np? sxml index) (cons sxml subnps) subnps))) ; There is another way of doing this with an accumulator. ; It is O(n). ; The hint describes how to build this... ; It turns out to be easier to build the list in reverse ; order. ; To complete this function, you will need to write an auxiliary ; function. Your auxiliary function should take an index, a subtree to ; look at, and the noun phrases seen so far, and should return a larger ; list of noun phrases seen so far, including those in the present ; subtree. You will need the function string=? to compare index values. (define (fast-get-nps-aux sxml index sofar) (let ((next (if (match-np? sxml index) (cons sxml sofar) sofar))) (if (pair? sxml) (fast-get-np-elts sxml index next) next))) (define (fast-get-np-elts sxml index sofar) (if (null? sxml) sofar (fast-get-np-elts (cdr sxml) index (fast-get-nps-aux (car sxml) index sofar)))) (define (fast-get-nps sxml index) (reverse (fast-get-nps-aux sxml index '())))