Natural Language Processing - Class 2 |
(defun( ) "doc" ) (defun last-name (name) "Select last name from a name represented as a list." (first (last name))) (last-name '(john r vandamme)) --> vandamme (last-name '(john quirk MD)) --> MD
(setf names '((john x ford) (peter p rabbit) (fabianna f wayne))) (mapcar #'last-name names) --> (ford rabbit wayne)#' from name of function to function object. mapcar primitive.
(defparameter *titles* '(Mr Mrs Miss Madam Ms Sir Dr Admiral Major General))
(defun first-name (name)
"Select first name from a list representing a name."
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))
(if )
(first-name '(Madam Major General Paula Jones)) --> Paula
(funcall #'+ 1 2) --> 3
(funcall #'+ '(1 2)) --> error (1 2) is not a number.
(lambda (parameter ...) body...): non atomic name of a function. ((lambda (x) (+ x 2)) 4) --> 6 (funcall #'(lambda (x) (* x 2)) 4) --> 8
/* Pascal */ ;;; Lisp a * (b + c) (* a (+ b c))With matrices:
var temp, result: matrix; (mult a (add b c)) add(b, c, temp); mult(a, temp, result); return(result);Write Pascal functions which allocate new matrices on the heap: mult(a, add(b, c)) but then cannot free the new matrices!
var a,b,c,x,y: matrix; x:=add(b,c); y:=mult(a,x); free(x); return(y);
Sentence --> Noun-Phrase + Verb-Phrase Noun-Phrase --> Article + Noun Verb-Phrase --> Verb + Noun-Phrase Article --> the, a ... Noun --> man, ball, woman, table... Verb --> hit, took, saw, liked...
(defun sentence () (append (noun-phrase) (verb-phrase))) (defun noun-phrase () (append (article) (noun))) (defun verb-phrase () (append (verb) (noun-phrase))) (defun article () (one-of '(the a))) (defun noun () (one-of '(man ball woman table))) (defun verb () (one-of '(hit took saw liked))) (defun one-of (set) "Pick one element of set and make a list of it." (list (random-elt set))) (defun random-elt (choices) "Choose an elt from a list at random" (elt choices (random (length choices)))) ;; (elt list index) index in [0..l-1] ;; (random n) --> integer between 0 and n-1 > (sentence) --> (the woman hit the ball) > (sentence) --> (the woman hit the man) > (sentence) --> (the ball saw the woman) > (noun-phrase) --> (the man) > (verb-phrase) --> (liked the woman)
Noun-phrase --> Article + Adj* + Noun + PP*
Adj* --> 0, Adj + Adj*
PP* --> 0, PP + PP*
PP --> prep + Noun-phrase
Adj --> big, little, blue, green
Prep --> to,in,by,with,...
(defun adj* ()
(if (= (random 2) 0)
nil
(append (adj) (adj*))))
(defun pp* ()
(if (random-elt '(t nil))
(append (pp) (pp*))
nil))
(defun noun-phrase () (append (article) (adj*) (noun) (pp*)))
(defun pp () (append (prep) (noun-phrase)))
(defun adj () (one-of '(big little blue green)))
(defun prep () (one-of '(to in by with on)))
;; BAD DEFINITIONS OF ADJ*
(defun adj* ()
(one-of '(nil (append (adj) (adj*)))))
(defun adj* ()
(one-of (list nil (append (adj) (adj*)))))
;;; (NORVIG Chap 2)
;;; ==============================
(defparameter *simple-grammar*
'((sentence -> (noun-phrase verb-phrase))
(noun-phrase -> (Article Noun))
(verb-phrase -> (Verb noun-phrase))
(Article -> the a)
(Noun -> man ball woman table)
(Verb -> hit took saw liked))
"A grammar for a trivial subset of English.")
(defvar *grammar* *simple-grammar*
"The grammar used by generate. Initially, this is
*simple-grammar*, but we can switch to other grammers.")
;;; ==============================
;;; Define how to manipulate this data
;;; Accessors for the Knowledge base.
(defun rule-lhs (rule)
"The left hand side of a rule."
(first rule))
(defun rule-rhs (rule)
"The right hand side of a rule."
(rest (rest rule)))
(defun rewrites (category)
"Return a list of the possible rewrites for this category."
(rule-rhs (assoc category *grammar*)))
;;; ==============================
;;; Use the knowledge base to solve the problem:
;;;
;;; That's all it takes!
(defun generate (phrase)
"Generate a random sentence or phrase"
(cond ((listp phrase)
(mappend #'generate phrase))
((rewrites phrase)
(generate (random-elt (rewrites phrase))))
(t (list phrase))))
;; A function to call fn on each element of the-list and return the append
;; of the results (note that mapcar returns the list of the results).
(defun mappend (fn the-list)
"Apply fn to each element of list and append the results."
(if (null the-list)
nil
(append (funcall fn (first the-list))
(mappend fn (rest the-list)))))
;;; ==============================
;;; Reuse the same code on a different knowledge base.
(defparameter *bigger-grammar*
'((sentence -> (noun-phrase verb-phrase))
(noun-phrase -> (Article Adj* Noun PP*) (Name) (Pronoun))
(verb-phrase -> (Verb noun-phrase PP*))
(PP* -> () (PP PP*))
(Adj* -> () (Adj Adj*))
(PP -> (Prep noun-phrase))
(Prep -> to in by with on)
(Adj -> big little blue green adiabatic)
(Article -> the a)
(Name -> Pat Kim Lee Terry Robin)
(Noun -> man ball woman table)
(Verb -> hit took saw liked)
(Pronoun -> he she it these those that)))
(setf *grammar* *bigger-grammar*)
;;; ==============================
;;; Reuse the same knowledge base to do something slightly different.
;;; In this case, return the parse tree of the generated sentence instead
;;; of just the sentence.
(defun generate-tree (phrase)
"Generate a random sentence or phrase,
with a complete parse tree."
(cond ((listp phrase)
(mapcar #'generate-tree phrase))
((rewrites phrase)
(cons phrase
(generate-tree (random-elt (rewrites phrase)))))
(t (list phrase))))
;;; ==============================
;;; Generate the whole language described by a grammar.
;;; Yet another use of the same knowledge base.
(defun generate-all (phrase)
"Generate a list of all possible expansions of this phrase."
(cond ((null phrase) (list nil))
((listp phrase)
(combine-all (generate-all (first phrase))
(generate-all (rest phrase))))
((rewrites phrase)
(mappend #'generate-all (rewrites phrase)))
(t (list (list phrase)))))
(defun combine-all (xlist ylist)
"Return a list of lists formed by appending a y to an x.
E.g., (combine-all '((a) (b)) '((1) (2)))
-> ((A 1) (B 1) (A 2) (B 2))."
(mappend #'(lambda (y)
(mapcar #'(lambda (x) (append x y)) xlist))
ylist))

For any question, contact me: yaeln@cs.bgu.ac.il
Back to course homepage
Last modified February 24, 2000