New Semester
Started
Get
50% OFF
Study Help!
--h --m --s
Claim Now
Question Answers
Textbooks
Find textbooks, questions and answers
Oops, something went wrong!
Change your search query and then try again
S
Books
FREE
Study Help
Expert Questions
Accounting
General Management
Mathematics
Finance
Organizational Behaviour
Law
Physics
Operating System
Management Leadership
Sociology
Programming
Marketing
Database
Computer Network
Economics
Textbooks Solutions
Accounting
Managerial Accounting
Management Leadership
Cost Accounting
Statistics
Business Law
Corporate Finance
Finance
Economics
Auditing
Tutors
Online Tutors
Find a Tutor
Hire a Tutor
Become a Tutor
AI Tutor
AI Study Planner
NEW
Sell Books
Search
Search
Sign In
Register
study help
business
management and artificial intelligence
Paradigms Of Artificial Intelligence Programming Case Studies In Common Lisp 1st Edition Peter Norvig - Solutions
Does this make the rules easier to read?
Exercise 6.1 [m] Go back and change the ELIZA rules to use the abbreviation facility.
We would use this facility as follows:> (pat-match-abbrev '?x* '(?* ?XI) + (?* ?X)> (pat-match-abbrev '?y* '(?* ?y)) + (?* ?Y)> (setf axyd (expand-pat-match-abbrev '(a ?x* ?y* dl)) +(A (?* ?XI (?* ?Y) Dl> (pat-match axyd '(a b c dl) + ((?Y B C) (?XI)
"Expand out all pattern matching abbreviations in pat."(cond ((and (symbolp pat) (get pat 'expand-pat-match-abbrev)))((atom pat) pat)(t (cons (expand-pat-match-abbrev (first pat))(expand-pat-match-abbrev (rest pat))))))
"Define symbol as a macro standing fbr a pat-match pattern."(setf (get symbol 'expand-pat-match-abbrev)(expand-pat-match-abbrev expansion))(defun expand-pat-match-abbrev (pat)
(defun pat-match-abbrev (symbol expansion)
The syntax we have defined for patterns has two virtues: first, the syntax is very general, so it is easy to extend. Second, the syntax can be easily manipulated by pat - ma tc h. However, there is one drawback: the syntax is a little verbose, and some may find it ugly. Compare the following two
Here are two examples using ?f .i The first succeeds because (+ 3 4) is indeed 7, and the second fails because (> 3 4 is false.> (pat-match '(?x ?op ?y i s ?z (?if (eql (?op ?x ?y) ?z)))'(3 + 4 i s 7))((?Z . 7) (?Y . 4) (?OP . +) (?X . 3))> (pat-match '(?x ?op ?y (?if (?op ?x ?y)))'(3 > 4))NIL
The pattern looks l i k e ((?if code) . r e s t ) . "(and (progv (mapcar #'car bindings)(mapcar #'cdr bindings)(eval (second (fi r s t pattern) 1)(pat-match (rest pattern) input bindings)))
"Test an arbitrary expression involving variables.
Finally, we supply the function to test an arbitrary piece of Lisp code. It does this by evaluating the code with the bindings implied by the binding list. This is one of the few cases where it is appropriate to call eval : when we want to give the user unrestricted access to the Lisp
"Match zero or one element of input."( l e t ((var (second ( f i r s t pattern) 1)(pat (rest pattern)))(or (pat-match (cons var pat) input bindings)(pat-match pat input bindings))))
Given segment -match, it is easy to define the function to match one-or-more elements and the function to match zero-or-one element:(defun segment-match+ (pattern input bindings)"Match one or more elements of input."(segment-match pattern input bindings 1))(defun segment-match? (pattern input
(pat-match '(a (?* ?XI (?* ?y) ?x ?y)' ( a b c d (b C) (dl)) ((?Y Dl (?X B C))
In the first example below, the segment variable ?x matches the sequence (b c 1. In the second example, there are two segment variables in a row. The first successful match is achieved with the first variable, ?x, matching the empty sequence, and the second one, ?y, matching ( b c 1.> (pat-match
Now the segment-pattern matching functions. segment -match is similar to the version presented as part of ELIZA. The difference is in how we determine pos, the position of the first element of the input that could match the next element of the pattern after the segment variable. In ELIZA, we
"Succeed if none of the patterns match the input.This will never bind any variables."(if (match-or patterns input bindings)fai 1 bindings 1)
"Succeed if any one of the patterns match the input."(if (null patterns)fai 1(let ((new-bindings (pat-match (first patterns)input bindings)))(if (eq new-bindings fail)(match-or (rest patterns) input bindings)new-bindings))))(defun match-not (patterns input bindings)
"Succeed if all the patterns match the input."(cond ((eq bindings fail) fail)((null patterns) bindings) .(t (match-and (rest patterns) input(pat-match (first patterns) input bindings)))))(defun match-or (patterns input bindings)
The last thing to do is define the individual matching functions. First, the singlepattern matching functions:(defun match-is (var-and-pred input bindings)"Succeed and bind var if the input satisfies pred, where var-and-pred is the list (var pred)."(1 et* ((var (first var-and-pred)(pred (second
i f it i s a symbol that has one."(when (symbolp x) (get x 'single-match)))
i f it i s a symbol t h a t has one. "(when (symbolp x) ( g e t x 'segment-match)))(defun singl e-match-fn (x)"Get the single-match function f o r x,
"Get the segment-match function f o r x,
"Call the r i g h t function f o r t h i s kind of single p a t t e r n ."(funcall (single-match-fn ( f i r s t p a t t e r n ) )( r e s t pattern) input bindings))(defun segment-match-fn (x)
"Call the r i g h t function f o r t h i s kind o f segment p a t t e r n ."(funcall (segment-match-fn ( f i r s t ( f i r s t p a t t e r n ) ) )p a t t e r n i n p u t bindings))(defun single-matcher (pattern input bindings)
" I s t h i s a singl e-matchi ng pattern?E.g. (?is x predicate) (?and . patterns) (?or . p a t t e r n s ) ."(and (consp pattern)(single-match-fn ( f i r s t p a t t e r n ) ) ) )(defun segment-matcher ( p a t t e r n i n p u t bindings)
" I s t h i s a segment-matching pattern l i k e ((?* var) . p a t ) ?"(and (consp pattern) (consp ( f i r s t p a t t e r n ) )(symbolp ( f i r s t ( f i r s t p a t t e r n ) ) )(segment-match-fn ( f i r s t ( f i r s t p a t t e r n ) ) ) ) )(defun single-pattern- p ( p a t t e r n )
With the table defined, we need to do two things. First, define the "glue" that holds the table together: the predicates and action-taking functions. A function that looks upadata-drivenfunctionandcallsit(suchass egment -mat cher andsi ngl e-mat cher )is called a dispatch function.(defun
value of each property will be the name of a function that implements the match.Here are the table entries to implement the grammar listed previously:( s e t f (get ' ? i s 'single-match) 'match-is)( s e t f (get '?or 'single-match) 'match-or)( s e t f . (get '?and 'single-match) 'match-and)( s e t
property lists are an appropriate choice. We will have two tables, represented by the segment -match property and the s i ngl e -ma tc h property of symbols like ?*. The
There are many ways to implement tables in Common Lisp, as discussed in section 3.6, page 73. In this case, the keys to the table will be symbols (like ?*), and it is fine if the representation of the table is distributed across memory. Thus,
This style of programming, where pattern/action pairs are stored in a table, is called data-driven programming. It is a very flexible style that is appropriate for writing extensible systems.
The solution to this dilemma is to write one version of segment - pattern - p and segment-matcher, once and for all, but to have these functions refer to a table of pattern/action pairs. The table would say "if you see ?* in the pattern, then use the function segment-match," and so on. Then
The next step is to define the predicates that recognize generalized segment and single-element patterns, and the matching functions that operate on them. We could implement segmen t -matcher and s i ngl e -matcher withcase statements that consider all possible cases. However, that would make it
"Does VAR match input? Uses (or updates) and returns bindings."( l e t ((binding (get-binding var bindings)))(cond ((not binding) (extend-bindings var input bindings))((equal input (binding-val binding) bindings)(t f a i l ) ) ) )
( b i n d i n g - v a l (get-binding var bindings)))(defun extend- bi ndi ngs (var val bindings"Add a (var . value) pair t o a binding l i s t ."(cons (make-binding var val);; Once we add a "r e a l" binding,;; we can get r i d of the dummy no-bindings( i f (eq bindings no-bindings)ni 1 bi ndi
(cdr binding)(defun make-binding (var val) (cons var val))(defun lookup (var bindings)"Get the value part (for var) from a binding l i s t ."
(defun binding-var (binding)"Get the variable part of a single binding."( c a r b i n d i n g ) )(defun binding- val (binding)"Get the value part o f a single binding."
(and (symbolp x) (equal (char (symbol-name x) 0) #\?)I)(defun get-binding (var bindings)"Find a ( v a r i a b l e . value) p a i r i n a binding l i s t ."(assoc var bindings))
For completeness, we repeat here the necessary constants and low-level functions from ELIZA:(defconstant f a i l n i l "Indicates pat-match f a i l u r e ")(defconstant no-bindings '((t . t))"Indicates pat-match success, with no v a r i a b l e s .")(defun variable-p (x)" Is x a variable (a symbol
( (eql pattern input bindings((segment-pattern-p pattern)(segment-matcher p a t t e r n i n p u t bindings))( ( s i n g l e - p a t t e r n - p pattern) . , ***(single-matcher p a t t e r n i n p u t bindings)) ; ***((and (consp pattern) (consp i n p u t ) )(pat-match ( r e s t pattern) ( r e s t
(cond ((eq bindings f a i l ) f a i l )( ( v a r i a b l e - p pattern)(match-variable p a t t e r n i n p u t bindings))
"Match pattern against input i n the context o f t h e bindings"
Despite the added complexity, all patterns can still be classified into five cases.The pattern must be either a variable, constant, a (generalized) segment pattern, a (generalized) single-element pattern, or a cons of two patterns. The following definition of pat -match reflects the five cases
When the description of a problem gets this complicated, it is a good idea to attempt a more formal specification. The following table describes a grammar of patterns, using the same grammar rule format described in chapter 2.pat + var match any one expression constant match just this atom
The next pattern uses ?not to insure that two parts are not equal:> (pat-match '(?x /= (?not ?XI) '(3 /= 4)) =. ((?X . 3))The segment matching notation we have seen before. It is augmented to allow for three possibilities: zero or more expressions; one or more expressions; and zero or one
2~altnern ative would be to reserve the question mark for variables only and use another notation for these match operators. Keywords would be a good choice, such as : and, : or, : i s, etc.
Here is an example of an ?and pattern that checks if an expression is both a number and odd:> (pat-match '(x = (?and (?is ?n numberp) (?is ?n oddp)))'(x = 3))((?N . 3))
Another useful feature is to allow the user to specify an arbitrary predicate that a match must satisfy. The notation (?is ?n numberp) could be used to match any expression that is a number and bind it to the variable ?n. This would look like:> (pat-match '(x = (?is ?n numberp)) '(x = 34)) ((?n .
The problem in designing a "general" tool is deciding what features to provide.We can try to define features that might be useful, but it is also a good idea to make the list of features open-ended, so that new ones can be easily added when needed.Features can be added by generalizing or
6.2 A Pattern-Matching Tool The pat-match function was a pattern matcher defined specifically for the ELIZA program. Subsequent programs will need pattern matchers too, and rather than write specialized matchers for each new program, it is easier to define one general h he macro handl er - case is
This version also allows the prompt to be either a string or a function of no arguments that will be called to print the prompt. The function prompt-generator, for example, returns a function that will print prompts of the form C11, C21, and so forth.(defun i n t e r a c t i v e - i n t e r p r e t
The followingversionof i nteracti ve-i nterpreter adds twonewfeatures. First, it uses the macro handl er-case1 to handle errors. This macro evaluates its first argument, and normally just returns that value. However, if an error occurs, the subsequent arguments are checked for an error condition
The other difference shows up in what's called maintenance. Suppose we find a missing feature in the definition of the interactive interpreter. One such omission is that the 1 oop has no exit. I have been assuming that the user can terminate the loop by hitting some interrupt (or break, or abort)
There are two differences between the formal and informal approaches. First, they look different. If the abstraction is a simple one, as this one is, then it is probably easier to read an expression that has the loop explicitly written out than to read one that calls i n t e r a c t i ve - i n
"Read an expression, transform it, and print the result."( 1 oop(print prompt(print (funcall transformer (read)))))This function could then be used in writing each new interpreter:(defun lisp 0(interactive-interpreter '> #'eval))(defun eliza 0(interactive-interpreter 'eliza>#'(lambda (x) (flatten
The formal alternative is to create an abstraction, in the form of functions and perhaps data structures, and refer explicitly to that abstraction in each new applicationin other words, to capture the abstraction in the form df a useable software tool. The interpreter pattern could be abstracted
The informal alternative is to treat the pattern as a cliche or idiom that will occur frequently in our writing of programs but will vary from use to use. When we want to write a new program, we remember writing or reading a similar one, go back and look at the first program, copy the relevant
There are two ways to make use of recurring patterns like this: formally and informally.
The important point is not whether one line of code can be considered an implementation of Lisp; it is to recognize common patterns of computation. Both el i za and 1 i sp can be seen as interactive interpreters that read some input, transform or evaluate the input in some way, print the result,
It may seem facetious to say those four symbols and eight parentheses constitute a Lisp interpreter. When we write that line, have we really accomplished anything?One answer to that question is to consider what we would have to do to write a Lisp(or Pascal) interpreter in Pascal. We would need a
The top level of a Lisp system has historically been called the "read-eval-print loop."Most modern Lisps print a prompt before reading input, so it should really be called the "prompt-read-eval-print loop," but there was no prompt in some early systems like MacLisp, so the shorter name stuck. If we
Many other applications use this pattern, including Lisp itself. The top level of Lisp could be defined as:(defun l i s p 0(1 oop( p r i n t '>I( p r i n t (eval ( r e a d ) ) ) ) )
6.1 An Interactive Interpreter Tool The structure of the function el i za is a common one. It is repeated below:(defun eliza 0"Respond to user input using pattern matching rules."( 1 oop(print 'el iza>)(print (flatten (use-eliza-rules ( r e a d ) ) ) ) ) )
Those patterns will be abstracted out to form reusable software tools that will prove helpful in subsequent chapters.
I n chapters 4 and 5 we were concerned with building two particular programs, GPS and ELIZA.In this chapter, we will reexamine those two programs to discover some common patterns.
(Do you feel strongly about discussing such t h i n g s ? ) ) ) )Building Software Tools Man is a tool-using animal. . . .Without tools he is nothing, with tools he is all.-Thomas Carlyle (1 795-1 88 1 )
(What does t h a t suggest t o you?) (Please continue) (Go on)
(Very i n t e r e s t i n g ) (I am not sure I understand you f u l l y )
(Did you t h i n k they might not be ?y)(Possibly they are ?y))(((?* ?x))
(You do not seem q u i t e c e r t a i n ) )(((?* ?x) are (?* ?y))
(What comes t o your mind when you ask t h a t ? ) )(((?* ?XI perhaps (?* ?y))
(What i s it you r e a l l y want t o know?) (What do you think?)
(Why do you ask?) (Does that question i n t e r e s t you?)
(What incident are you thinking of?) ( R e a l l y - - always))(((?* ?XI what (?* ?y))
(Can you t h i n k of a s p e c i f i c example) (When?)
(Who f o r example?) (You are thinking of a special person))(((?* ?XI always (?* ?y))
(Can you be more s p e c i f i c ? ) )(((?* ?XI everyone (?* ?y))( s u r e l y n o t everyone) (Can you t h i n k of anyone i n p a r t i c u l a r ? )
(Why not?) (You are being a b i t negative)(Are you saying "NO" j u s t t o be negative?))(((?* ?XI someone (?* ?y))
(You seem q u i t e p o s i t i v e ) (You are sure) (I understand))(((?* ?XI no (?* ?y))
(Do you believe I don't ?y) (Perhaps I w i l l ?y i n good time))(((?* ?XI yes (?* ?y))
(Should you ?y yourself?)
(Perhaps i n your fantasy we ?y each other))(((?* ?XI why don't you (?* ?y))
(What other feelings do you have?))(((?* ?XI I (?* ?y) you (?* ?z))
(Do you o f t e n f e e l ?y ?)I(((?* ?XI I f e l t (?* ?y))
(Maybe you could ?y now) (What i f you could ?y ?)(((?* ?XI I feel (?* ?y))
(Perhaps I was ?y) (What do you think?) (What i f I had been ?y))(((?* ?XI I can't (?* ?y))
(Does t h a t reason seem t o explain anything else?))(((?* ?XI were you (?* ?y))
( I s that the real reason?) (What other reasons might there be?)
(What makes you t h i n k I am ?y ?I)(((?* ?XI because (?* ?y))
(Perhaps I am ?y i n your f a n t a s i e s ) )(((?* ?XyIo u are (?* ?y))
(Would you prefer i f I weren't ?y)
(Why are you interested i n whether I am ?y or not?)
(Why do you say "AM?") (I don't understand t h a t ) )(((?* ?XI are you (?* ?y))
(What would it mean i f you were ?y))(((?* ?XI am (?* ?y))
(Do you believe you are ?y) (Would you want t o be ?y)(You wish I would t e l l you you are ?y)
( I n what way are you ?y) (Do you want t o be ?y ?)I(((?* ?XI am I (?* ?y))
(What would it mean i f you were ?y))(((?* ?XI I am (?* ?y)>
(What i f you were ?y ?) (Do you t h i n k you were ?y)
(Why do you t e l l me you were ?y now?))(( (?* ?XI was I (?* ?y))
Showing 1800 - 1900
of 4756
First
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Last
Step by Step Answers