CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 1
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 1
CSCI 2210: Programming in Lisp
ANSI Common Lisp, Chapters 5-10
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 2
Progn
• Progn• Creates a block of code
• Expressions in body are evaluated
• Value of last is returned(if ( < x 0) ( progn (forma t t "X is l ess than z ero ") (forma t t "and m ore than on e statemen t ") (forma t t "needs to be exec uted in th e IF") (- x) ))
• Prog1• Same as progn, except value of f irst expression is returned
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 3
Block
• Like a progn with• A name
• An "emergency exit"–return-from - Returns from a named block–return - Returns from a block named NIL
• Examples> (bl ock head ( f ormat t " Here we go " ) ( r eturn-fro m head 'id ea) ( f ormat t " We'll neve r see this" ) )
Here we go.IDEA
> (bl ock nil (r eturn 27))27
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 2
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 4
Implicit use of Blocks
• Some Lisp constructs implicitly use blocks• All i teration constructs use a block named NIL (note return)
> ( dol ist (x '( a b c d e) ) ( f ormat t " ~A " x) ( i f ( eql x ' c) (retur n 'done)))
A B CDONE
• Defun uses a block with same name as the function> ( def un foo () ( r eturn-fro m foo 27))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 5
Iteration
• DOTIMES (Review)( doti mes (<coun t er> <uppe r -bound> <f i nal-resul t >) <b ody>)
–Example( doti mes (i 5) ( print i)) ;; prints 0 1 2 3 4
• DOLIST( doli s t (<eleme nt> <list- of-elements > <final-r esult>) <b ody>)
–Example( doli s t ( elem ' ( a b c d)) (print ele m)) ;; pri nts a b c d
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 6
Example of DOLIST
• Given a list of ages of people, how many adults?–List of ages
> ( se t f ages '( 3 4 17 21 22 34 2 7))
–Adult defined as: >= 21 years old> ( def un adultp (age) (>= age 21))
–Using Count-if( defu n count-ad ult (ages) (count-if # 'adultp ages))
–Using dolist( defu n count-ad ult (ages &aux ( nadul t 0)) ( dolist (age ages nadu l t ) (if ( adul t p age) ( setf nadult ( + 1 nadul t )))))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 3
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 7
Example (cont.)
• Get the ages of the first two adults( defu n first-tw o-adults ( ages & aux ( nadult 0) ( adults ni l )) ( dolist (age ages) (if ( adul t p age) ( progn ( setf nad ult (+ nadu l t 1)) (push age adults) (if (= nadult 2) (re t urn adult s ))))))
• Notes• PROGN (and PROG1) are like C/C++ Blocks { … }
> (pr og1 ( setf a 'x) ( set f b 'y) ( se t f c 'z))X
> ( pr ogn ( setf a 'x) ( set f b 'y) ( se t f c 'z))Z
• RETURN exits the DOLIST block–Note: does not necessarily return from the procedure!–Takes an optional return value
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 8
DO
• DO is more general than DOLIST or DOTIMES• Example
( defu n do- expt ( m n) ;; Return M^N (d o ((result 1) ;; Bind variab l e ‘Result ’ to 1 (expone nt n)) ;; Bind variab l e ‘Expone nt’ to N (( zerop exponent) r esult) ;; t est and r eturn valu e ( setf re s ult (* m r esult)) ;; Body ( setf ex ponent (- exponent 1) ) ;; Body
• Equivalent C/C++ definitionint do_expt ( in t m, int n) { in t result, exponent; fo r (result= 1,exponent =n; (expone nt != 0); ) { result = m * result ; exponent = exponent - 1; } re t urn resul t ;}
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 9
DO Template
• Full DO Template (There is also a DO*)(DO ( (<p1> <i1 > <u1>) (<p2> <i2 > <u2>) … (< pN> < iN > <uN>) ) ( <term-tes t > <a1> <a2> … < aN> <result> ) < body> )
• Rough equivalent in C/C++for ( <p1>=<i1> , <p2>=<i2 >,…,< pN>=<i N>; //Note : Lisp=par allel !(<term-t est>); // C/C++ has a “continua t ion-test” <p1>=<u1> , <p2>=<u2 >,…,< pN>=<uN>) { <b ody>}<a1>; <a2>; … ; < aN>;<resu l t>; // No t e: (DO…) i n Lisp eva l uates to <result>// No t e: <p1>,< p2>,…,< pN> are now re s tored to original v alues
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 4
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 10
Do-expt, Loop
• Here is another (equivalent) definition of do-expt( defu n do- expt ( m n) (d o ((result 1 (* m re s ult)) (expone nt n (- ex ponent 1))) (( zerop exponent) r esult) ;; Note t hat there is no body ! ) )
• Loop• An infinite loop, terminated only by a (return)
(loop (pr i nt '(Say uncle)) (if (equal (r ead) 'uncl e) (return) ) )
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 11
Multiple Values
• We said each lisp expression returns a value• Actually, can return zero or more values (i.e. multiple values)
> (ro und 7.6) ; Round ret urns two va l ues8-0.4
> ( se t f a (roun d 7.6))8 ; Setf expects only one value, so it takes the first (8)
> a8
• How can you get all values?> (mu l tiple-val ue-list (r ound 7.6))
(8 -0.4)> (mu l tiple-val ue- setq ( i ntpart dif ) (round 7. 6))
8> int part
8> dif
-0.4
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 12
Generating Multiple Values
• How? Use val ues> (va l ues 1 2 3 ) ; Genera t es 3 retur n values
123
> ( def un uncons ( aList ) ( v alues (fir s t aList ) ( rest aLis t )))UNCONS
> ( unc ons '(A B C))A(B C)
> (fo r mat t "He l lo World" )" Hello World"NIL
> ( def un format - without-r eturn (out s tr &rest args ) ( apply #'fo r mat out s t r args ) ( v alues)) ; A funct i on with no return va l ue!
FORMAT-WITHOUT-RETURN> (fo r mat-witho ut-return t "Hello")
Hello>
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 5
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 13
Functions about functions
• FBOUNDP - Is a symbol the name of a function?> ( fb oundp '+)
T
• SYMBOL-FUNCTION - returns function> (sy mbol-funct i on '+)
#<Compiled-Function + 17B4E>> ( se t f (symbol - function ' sqr ) #'(la mbda (x) ( * x x)))
#<Interpreted-Function SQR>> ( def un sqr (x ) (* x x)) ; this is equivalent to above
SQR
• Defun and symbol-function define global functions• Local functions can be defined using LABELS
> ( def un add3 ( x ) ( l abels ((a dd1 (x) (+ x 1)) (a dd2 (x) (+ x 2))) (add1 (ad d2 x))))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 14
Closures
• Want a function that can save some values forfuture access/update• Can use global variables for this
> ( se t f *number - of-hits* 0) ; Global variable
0> ( def un increm ent-hits ( ) ( incf *nu mber-of-hi t s*))
INCREMENT-HITS> (in c rement-hi t s)
1> (in c rement-hi t s)
2
• But, what if someone clobbers the variable?> ( se t f *number - of-hits* " This varia ble is now a string" )
" This variable is now a string"> (in c rement-hi t s)
Error: '*number-of-hits* ' is not of the expected type: NUMBER
• Want something like "static" variables in C/C++.
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 15
Closures (continued)
• One use of closures is to implement 'static' variables safely
• Closure -- Combination of a function and environment–Environment can include values of variables
> (le t ((number - of-hits 0 ) ) ( defun incr ement-hits () ( incf n umber-of-h i ts)))
INCREMENT-HITS–number - of-hits is a free variable– It is a lexical variable (has scope)–A function that refers to a free lexical variable is called a closure
• Multiple functions can share the same environment> (le t ((number - of-hits 0 ) ) ( defun incr ement-hits ( ) ( incf number-of-hi t s)) ( defun rese t -hit-coun t er() ( setf number-of - hits 0))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 6
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 16
Closures (cont)
• Example 1> ( def un make-a dder (n) ; returns fu nction to add n to x # ' (lambda ( x ) (+ x n) ) )> ( se t f add3 (m ake-adder 3)) ; retur ns functio n to add 3
#<Interpreted function C0EBF6>> ( fu ncall add3 2) ; Call function a dd3 with a r gument 2
5> ( se t f (symbol - function ' add3-b) (m ake-adder 3))> (ad d3-b 5)
8
• Example 2 - Returns an "opposite" function> ( def un our-co mplement ( f ) # ( lambda (& r est args ) (not (ap ply f args ) )))> ( mapcar (our- c omplement # 'oddp ) '( 1 2 3 4))
(NIL T NIL T)
• Tip of the iceberg in terms of possibilities
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 17
Trace
• Format(trac e <procedu r e-name>)
• Example> ( def un factor i al (x) (i f (<= x 1) 1 (factori al (- x 1) ) ))> (tr ace factor i al)
• Causes entry, exit, parameter, and return values to be printed–For EACH procedure being traced
> (fa c torial 3); 1> FACTORIAL called with arg: 3; | 2> FACTORIAL call ed with arg: | 2; | | 3> FACTORIAL called with arg: | | 1; | |3< FACTORIAL returns value: | | 1; | 2< FACTORIAL returns value: | 2; 1< FACTORIAL returns value: 66
• Untrace stops tracing a procedure: (untrace <procedure-name>)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 18
Print, Read
• Print• Example
> (pr i nt '(A B) )
• Evaluates a single argument–Can be a constant (ex. 100), a variable (x), or any single expression
• Prints its value on a new line
• Returns the value printed
• Read - reads a single expression• Example:
> (re ad)20 23 ( A B) C20 ; ; Note: On l y the 20 i s read; re s t is igno r ed> ( pr ogn (print 'Enter-te mperature) ( read))Enter - temperatu r e 2020
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 7
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 19
Format
• Format• Allows more elegant printing
> ( pr ogn (print "Enter te mperature: " ) (read))"Ente r temperat ure: " 3232
> ( pr ogn (forma t t "~%Ent er temperat ure: ") (r ead))Enter temperatu r e: 3232
–The second parameter (t) is the output buffer (T=stdout)–The character “~” signifies that a control character follows–The character “%” signifies a newline (Lisp: “~%” C: “ \n”)–The characters “~a” tells Lisp to substitute the next value
print f ("The va l ue is ( % d, %d )", x , y); /* A C stmt */> (fo r mat t "Th e value is ( ~a, ~a ) " x y) ;; Lisp way> (fo r mat t "Th e value is ( ~10a, ~a )" x y) ; Can get f ancy
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 20
Streams
• Write output to a file (e.g. knowledge base)• Prototype of with-open-file
(with - open-file (<stream name> <file sp ecification > :directi on <:input or :output >) …)
• Example> ( se t f fact-da t abase ' ((It is r aining) (It is p ouring) (The old man is sn oring)))> (wi t h-open-fi l e (my-fil e ” myfile . l s p” :direc t ion :outp ut) (print fa c t-databas e my-file))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 21
My-Trace-Load
• Redefine the built-in Lisp “Load” function• Example of Built In function
> (lo ad "a. lsp " )
• Additional requirements–Want to print each expression that is read in.–Want to print the value returned by the expression
• Definition( defu n my-trace - load (fil ename & aux next- expr next-resul t ) ( with-open - file (f f i lename :di r ection :i nput) (do ((ne x t- expr (r ead f nil) ( read f ni l ))) ((no t next- exp r )) (form at t "~%~% Evaluating ' ~a'" next - expr ) ( setf next-resu l t ( eval ne x t- expr )) (form at t "~% Returned: '~a'" nex t -result)) ) )
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 8
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 22
Read-Line, Read-Char
• Read-Line• Reads an individual li ne (terminated by a carriage return)
• Returns it as a character string> (re ad-line)He l lo World
“ Hello World”
• Read-Char• Reads an individual character
• Returns it as a character> (re ad-char)x
#\x ;; This is Lisp notation for the character ‘ x’
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 23
Symbols
• We've used symbols as names for things• A symbol is much more than just a name
• Includes: name, package, value, function, plist (Property List)
• A symbol is a "substantial object"
• Some functions for manipulating symbols• symbol- name, symbol- pl i st , intern,…
• Details are in Chapter 8 of textbook
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 24
Symbol Names
• By default Lisp symbol names are upper case> (sy mbol-name ' abc )
" ABC"
• Can use "|" to delimit symbol names> (li s t '| abc |) ; n o conversio n
" abc"> (li s t '|Lisp 1.5| '|| ' | abc | '|ABC | )
(|Lisp 1.5| || |abc| ABC) ; Note that only ABC doesn't have delimiter (default)
• Intern creates new symbols> (se t (intern ' |5.1/5)|) 999)
999> |5. 1/5)|
999
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 9
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 25
Packages
• Package• A name space for symbols
• Large programs use multiple packages> ( def package " MY-APPLICA TION" ;; Creates n ew package ( : use "COMMON-LISP" " MY-UTILITIE S") ;; Oth er package s ( : nicknames "APP") ( : export "W I N" "LOSE" "DRAW")) ; ; Symbols exported
#<The MY-APPLICATION package>> (in - package m y -applicat i on) ;; Set s this to be default
• New symbols are (by default) created in defaultpackage• The default package, when Lisp is started is COMMON-LISP-
USER
• The COMMON-LISP packages is automatically used
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 26
Numbers
• Number crunching is one of Lisp's strengths• Many data types, automatically converted from one to another
• Many numeric functions
• Example: Factorial program was easier in Lisp (no overflow!)
• Four distinct types–Types: Integer, Floating Point Number, Ratio, and Complex Number–Examples: 100, 123.45, 3/2, #c(a b) ; #c(a b) = a+bi–Predicates: integerp, floatp, ratiop, complexp
• Basic rules for automatic conversion–If function receives floating point #'s, generally returns floating point #'s– If a ratio divides evenly (for example, 4/2), it will be converted to integer– If complex # has an imaginary part of zero, converted to a real
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 27
Subset of Type HierarchyS u b s et o f Typ e H ierarc h y
C om p lex
B it
F ixnu m B ig n u m
In teg er R atio
R at ion al
L on g -flo atD ou b le- flo atS in g le -floatS h or t-floa t
F loa t
R ea l
N u m b e r
T
Lisp Expression Return Value( set f a 1 2) ; 12( t ype a ' bi t ) ; NI L( t ype a ' f i xnum) ; T( t ype a ' i nt eger ) ; T( i nt eger p a) ; T( r at i onal p a) ; T( r eal p a) ; T( number p a) ; T
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 10
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 28
More on Numbers
• Conversion–(float) (truncate) (floor) (ceili ng) (round) …
> ( mapcar #'flo at '(1 2/3 .5))(1.0 0.6667 0.5)
• Comparison–Use = to compare for equality (also, <,<=, >, >=, /=)
> (= 4 4.0)T
• Other Misc. functions–Max–Min–(expt x n) = X^n–(exp x) = E^x–(log x n) = logn X; N is optional (default = natural log)–sqrt, sin, cos, tan
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 29
Eval
• Eval - Evaluates an expression and returns its value> ( ev al '(+ 1 2 3))
6
• Top-level is also called the read-eval-print loop• Reads expression, evaluates it, prints value, loops back
> ( def un our- to plevel () (loop (form at t "%~> " ) (prin t ( eval (r ead))))
• Eval• Inefficient - slower than running compiled code
• Expression is evaluated without a lexical context
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 30
Macros
• Macros• A common way to write programs that write programs• Defmacr o is used to define macros
• Example: A macro to set its argument to NIL> ( def macro nil ! (x) ( l ist 'setf x nil))> (ni l ! A) ;; Expands to ( setf A NI L), is the n evaluate d
NIL
• macro-e xpand-1 Generates macro expansion (not eval'ed)> ( mac roexpand - 1 '(nil! A ) )
(SETF A NIL)T
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 11
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 31
Macros
• Typical procedure call (defun)• Evaluate arguments
• Call procedure
• Bind arguments to variables inside the procedure
• Macro procedure (defmacro)• Macros do not evaluate their arguments
• When a macro is evaluated, an intermediate form is produced
• The intermediate form is evaluated, producing a value
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 32
Example: Manually Define Pop
• Review of the built in operation “Pop”:• Implements Stack data structure “Pop” operation
> ( se t f a '(1 2 3 4 5))> (po p a)
1> a
(2 3 4 5)
• How would you emulate this using other functions?–Attempt 1: Remove the element “1” from A
> ( se t f a (rest a))(2 3 4 5) ;; A is set correctly to (2 3 4 5), but we want “1” to be returned
–Attempt 2: Remove first element AND return it> (pr og1 (first a) ( setf a (rest a)) )
–Attempt 3: Write a Lisp expression that generates above expression> (li s t 'prog1 ( list 'fir s t a) ( list 'set f a (list ' rest a)))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 33
Our-Pop, using Macro
• Convert Lisp expression into a macro (Our-Pop)> ( def macro our - pop (stac k ) ( list 'pro g1 (lis t 'first s t ack) (lis t 'setf st ack (list ' r est stack ) )))
–Note similarity to Defun
• Example Call> (OU R-POP a)
• Notes–The parameter “A” is NOT evaluated–“A” is substituted for stack wherever the variable stack appears
(list 'prog1 ( list 'fir s t a) ( list 'set f a (list ' rest a)))
–Intermediate form is generated(prog 1 (first a ) ( setf a ( rest a)))
–Intermediate form is evaluatedA is set to (rest A); the first element is returned
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 12
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 34
Our-Pop using Defun
• Why doesn’t this (defun) work the same way?> ( def un our-po p (stack) ( prog1 (fi r st stack) ( setf stac k (rest st ack))))> ( se t f a '(1 2 3 4 5))> (ou r -pop a)
1> a
(1 2 3 4 5)
• Reason: Lisp passes parameters “by-value”–The value of A is COPIED into the variable “stack”–Any changes to the variable “stack” are done to the COPY, and NOT the
original variable A–When the function returns, the original value of A is unchanged
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 35
Significance of Eval Steps
• Macro evaluation has several steps (as noted)–The parameter “A” is NOT evaluated–“A” is substituted for stack wherever the variable stack appears– Intermediate form is generated– Intermediate form is evaluated
• Note that A is evaluated at step 4 above (not step 1)• Why does this matter?
–Answer: For the same reason that it matters in C/C++ macros–You may not want arguments evaluated at all–Or, you may want them evaluated multiple times–Macros give this f lexibilit y
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 36
Backquotes
• Significance of Evaluation Steps (cont)• Consider
> ( def macro our - if-macro ( conditiona l then-par t else-par t ) ( l ist 'if c onditional then-part else-part) )> ( def un our-if - fun (cond i tional the n-part els e-part) ( i f conditi onal then- part else-p art))> (if (= 1 2) ( print "Equ al") (print "Not Equa l "))
–Lisp evaluates all parameters of OUR-IF-FUN before function is called
• Backquote Mechanism• Forward quotes: Entire next expression is not evaluated
> ( def un temp ( ) ( setf a ' (a b c d e ) ))
• Backquote: Next expression is not evaluated (with exceptions)> ( def un temp ( ) ( setf a ` (a b c d e ) ))> ( def un temp ( x ) ( setf a `(a b c d e ,x))
–The “ ,x” expression is evaluated; the value of X is used.
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 13
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 37
Backquotes (cont.)
• Exceptions - Backquote evaluates the following• ,variable - Evaluates the value of the variable
> ( se t f x '(h i j))> ( se t f a `(a b c ,x e f) )
(A B C (H I J) E F)
• ,@variable - Splices the elements of a l ist> ( se t f a `(a b c ,@x e f ) )
(A B C H I J E F)
• Backquotes simplify macro development> ( def macro our - if-macro ( conditiona l then-par t else-par t ) ( l ist 'if c onditional then-part else-part) ) ;; old w ay> ( def macro our - if-macro ( conditiona l then-par t else-par t ) ` ( if ,condi t ional ,th en-part ,el s e-part))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 38
Backquotes simplify macros
• Original version of our-pop> ( def macro our - pop (stac k ) ( list 'pro g1 (lis t 'first s t ack) (lis t 'setf st ack (list ' r est stack ) )))
• Our-pop redefined using backquotes> ( def macro our - pop (stac k ) ` (prog1 (f i rst ,stac k ) ( setf ,s t ack (rest ,stack))) )
–Syntax is much closer to the intermediate form
• Macros can be defined with following parameters• Optional (&optional)
• Rest (& rest)
• Key (&key)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 39
Macro Design
• Macro: take a number n, evaluate its body n times• Example call
> ( nt i mes 10 ( pr inc "."))……….NIL
• First attempt (incorrect)> ( def macro nti mes (n &re s t body) ` ( do ((x 0 ( + x 1))) ((>= x ,n)) ,@body))
• For example call , within body of macro–n bound to 10–body bound to ((princ "."))
(do ( ( x 0 (+ x 1))) ( ( >= x 10)) ( princ ".") )
–Macro works for example. Why is it incorrect?
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 14
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 40
Inadvertent Variable Capture
• Consider• Initialize x to 10, increment it 5 times
> (le t ((x 10)) ( ntimes 5 ( s etf x (+ x 1))) x )
10
• Expected value: 15
• Why? Look at expansion> (le t ((x 10)) ( do ((x 0 ( + x 1))) ((>= x 5)) ( setf x (+ x 1))) x )
• X is used in let and in the iteration–setf increments iteration variable!
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 41
Gensym Gives New Symbol
• Gensym• Generates a new (uninterned) symbol
> ( def macro nti mes (n &re s t body) ; Still inco r rect thou gh ( l et ((g ( gensym))) `(do ((,g 0 (+ ,g 1 ) )) ((>= ,g ,n)) ,@body ) ))
• The value of symbol G is a newly generated symbol–How does this avoid the problem?–What if the call has a variable G?
• Look at the expansion of(let ( (x 10)) ( ntimes 5 ( s etf x (+ x 1))) x )
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 42
Expansion of ntimes (2)
• Substitute for N and BODY> (le t ((x 10)) ( let ((g ( gensym))) `(do ((,g 0 (+ ,g 1 ) )) ((>= ,g ,5)) ,@(( se t f x (+ x 1))))) x )
• Generate intermediate form> (le t ((x 10)) ( do ((#:G34 0 (+ #:G3 4 1))) ((>= #:G34 5)) ( setf x (+ x 1)) ) x )
• Evaluate15
• This works for our example … but ...
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 15
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 43
Multiple Evaluation• What happens when we want to debug…
> (le t ((x 10) ( niteratio n 3)) ( ntimes nit eration ( setf x (+ x 1))) x )
13
• To debug, insert a print expression> (le t ((x 10) ( niteratio n 3)) ( ntimes (pr i nt nitera t ion ) ( setf x (+ x 1) ) ) x )
333313
• The argument is evaluated multiple times–Apparent when argument causes side-effects–What if the argument was a (setf …)
• Non-intuitive: Expect argument to be evaluated only once.
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 44
Avoiding Multiple Evaluation
• Solution is to copy value when you get into macro• Use copy when needed within macro
> ( def macro nti mes (n &re s t body) ( l et ((g ( gensym)) (h ( gensym))) `(let ((, h ,n)) (do (( , g 0 (+ ,g 1))) (( >= ,g ,h)) ,@b ody))))
• This is correct> (le t ((x 10) ( niteratio n 3)) ( ntimes (pr i nt nitera t ion ) ( setf x (+ x 1) ) ) x )
313
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 45
Expansion of Ntimes (Final)
• Pprint is a useful function for Pretty PRINTingexpressions
> ( ppr int ( macr oexpand -1 ' ( ntimes ( print nite r ation ) ( se t f x (+ x 1)))))
(LET ((#:G93 (PRINT NITERATION))) (DO ((#:G92 0 (+ #:G92 1))) ((>= #:G92 #:G93)) (SETF X (+ X 1))))
• Problems of Multiple Evaluation and InadvertentVariable Capture• Examples of errors that can occur when working with macros
• Errors are common in Lisp as well as languages like C/C++
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 16
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 46
Multiple Evaluation in Pop
• Looking back at our Pop macro• It suffers from multiple evaluation
• We can't use same technique, though–Need to get the first AND do a setf to change the value
> ( def macro our - pop (stac k ) ` (prog1 (f i rst ,stac k ) ( setf ,s t ack (rest ,stack))) )
• Textbook solution avoids multiple evaluation• Page 301• Uses a function get- setf -expansion to get to inner
details of setf
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 47
Case Study: Expert Systems
• Overview of using Lisp for• Symbolic Pattern Matching
• Rule Based Expert Systems and Forward Chaining
• Backward Chaining and PROLOG
• Motivational example• Given:
–A set of Facts–A set of Rules
• Desired result–Answer complex questions and queries
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 48
Smart Animal Guessing• Facts about an animal named “Joey”
–F1. (Joey’ s mother has feathers)–F2. (Joey does not f ly)–F3. (Joey swims)–F4. (Joey is black and white)–F5. (Joey lives in Antarctica)
• Rules about animals in general–R1. If (animal X has feathers) THEN (animal X is a bird)–R2. If (animal X is a bird) and (animal X swims) and (animal X does not
fly) and (animal X is black and white) THEN (animal is a penguin)–R3. If (animal X’s mother Z) THEN (animal X Z)
Exampl e: if (an i mal X’s m other has f eathers) then ( animal X h as feathers )
–R4. If (animal X Z) THEN (animal’ s mother Z)
• Notes–By combining the facts and rules, we can deduce that Joey is a penguin,
and that the Joey’ s mother is a penguin.
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 17
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 49
Symbolic Pattern Matching
• Symbolic pattern matching example• Match F1 with the IF part of R1
–F1. (Joey’ s mother has feathers)–R1. If (animal X has feathers) THEN (animal X is a bird)
• The expression (Joey’s mother has feathers)matches the pattern (animal X has feathers).
• The association (animal X = Joey’s mother) is implied
• In general• Symbolic pattern matching
–matching an ordinary expression (e.g. fact) to a pattern expression
• Unification: more advanced version of pattern matching–match two pattern expressions to see if they can be made identical–Find all substitutions that lead to this
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 50
Rule Based Expert System
• Rule Based Expert Systems• Once the pattern matching step is done, then we know that Rule
R1 can be combined with fact F1–F1. (Joey’ s mother has feathers)–R1. If (animal X has feathers) THEN (animal X is a bird)
• The association (animal X = Joey’s mother), along with thesecond part of the rule (animal X is a bird) leads to a derivedfact:–(Joey’ s mother is a bird)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 51
Forward Chaining
• Basic philosophy:• Given a set of rules R and a set of facts F, what new facts (DF)
can be derived?–DF1: Joey has feathers (R3,F1)–DF2: Joey’s mother is a bird (R1, F1)–DF3: Joey is a bird (R1,DF1) [or, (R3,DF2)]–DF4: Joey’s mother does not f ly (R4, F2)–DF5: Joey’s mother swims (R4, F3)–DF6: Joey’s mother is black and white (R4, F4)–DF7: Joey’s mother lives in Antarctica (R4, F5)–DF8: Joey is a penguin (R2, DF3, F2, F3, F4)–DF9: Joey’s mother is a penguin (R4, DF8) or (R2, DF2, DF5, DF4, DF6)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 18
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 52
Backward Chaining
• Basic philosophy• Can a statement (e.g. Joey is a penguin) be proven given the
current set of facts and rules?
• Work backwards, to determine what facts, if true, can prove thatJoey is a penguin (or prove that Joey is not a penguin).–B1. R2: (Joey is a penguin) IF (a) Joey is a bird; (b) Joey swims; (c) Joey
does not fly; and (d) Joey is black and white–B2. R1: (Joey is a bird) IF (Joey has feathers)–B4. R3: (Joey has feathers) IF (Joey’s mother has feathers)–DF1. (Joey has feathers), since we know (Joey’s mother has feathers (F1)–DF2. (Joey is a bird), since we know (Joey has feathers) (DF1)–DF3. (Joey is a penguin), since (a), (b), (c), and (d) are known to be true
(DF2, F3, F2, F4 respectively)
• The fact (Joey is a penguin) can be derived
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 53
Does this apply in the real world?• Given a clinical specimen, need to know what tests to perform?
–Example facts about a specific patient specimen (to test whether a personhas Syphili s):F1. A utomated Reagin Test result is Reactive, Titer=8F2. Mi croheme Agglutinati on Test is Non-Reacti v eF3. S pecimen is from a pr egnant woma nF4. P r ior histo r y indicat es a result of Reacti v e, Titer= 2F5. P r ior test was perfor med 12 mont hs ago
–Example rulesR1. I F (Autom ated Reagi n Test is R eactive, T i ter >= 4) A ND ( Micro heme Agglu t ination Te s t is Non- Reactive) T HEN (Rapid Plasma Reagin test m ust be per f ormed)R2. I F (Speci men is fro m a pregnan t woman) T HEN ( Micro heme Agglu t ination Te s t must be performed )R3. I F (Speci men is fro m a pregnan t woman) T HEN (Autom ated Reagi n Test must be perfor med twice)
–Sample questions:What t ests need to be per f ormed? (Fo r ward chai ning)Shoul d we do th e RPR test ? (Backward chaining)Is th e specimen considere d abnormal? (Backward chaining)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 54
Lisp
• Lisp is a good language for implementing expertsystems.• Concise programs
• Flexible processing of l ists
• Basic implementations are shown in chapters 24-27
• Other applications of expert systems• Mathematics: Calculus, geometry
• Computer configuration, electronic circuits
• Evaluate geological formations, planned investments
• Diagnosis of infections
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 19
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 55
Building an Expert System
• Knowledge representation• how to represent facts, patterns, rules
• how to represent sets of these
• Build a pattern matcher
• Build the inference engine• Forward Chaining
• and/or Backward Chaining
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 56
Implementing Pattern Matching
• Want a procedure to match patterns• Input
–Animal X has feathers (pattern)((? X ) has feat hers) ; U s es (? Var ) for patte r n variabl e
–Joey’s mother has feathers (regular expression or Fact)((mot her Joey) has feathe r s)
• Returns–Mapping between pattern variables
( (X ( mother Jo ey)) )
• Example call> (ma t ch '((? X ) has feat hers) '((mot her Joey) has feather s ) )
((X (mother Joey)))> (ma t ch '((? X ) has (? Z ) ) '(Joey has feath ers)))
((X Joey) (Z feathers))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 57
Return values of Match
• Return value is a set of variable bindings–Example
((X Joey) (Z feathers))–General Form
( (var1 value1) (var2 value2) … (varN valueN) )
• What if the two patterns don’ t match?–First attempt: On failure, return NIL
> (ma t ch '((? X ) has feat hers)) '(Jo ey does no t fly))NIL
• But consider...> (ma t ch '(Joey has feath ers) '(Joey has feath ers)))
–This matches, but there is no need to bind any variables.–So, need to return SUCCESS with a list of zero variable bindings: ( )
NIL <-- NIL = ( )
• Need to differentiate between failed match and match with novariable bindings
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 20
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 58
Return values of Match (cont.)
• Approach taken by Winston/Horn• Note: This is NOT the only way to do it
–NIL = Success, empty list of pattern variables–FAIL = Symbol returned when the pattern and datum don’t match
• Examples> (ma t ch '((? X ) has feat hers) '((mo t her Joey) has feath ers))
((X (mother Joey)))> (ma t ch '((? X ) has (? Z ) ) '(Joey h as feather s )))
((X Joey) (Z feathers))> (ma t ch '((? X ) has feat hers)) '(Jo ey does no t fly))
FAIL> (ma t ch '(Joey has feath ers) '(Joey has feath ers)))
NIL ; Treated as an empty list
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 59
Match Function Definition
• Function definition for MATCH: 4 basic branches;; Ca l culates a nd returns bindings ( i f success f ul);; Or , returns ' FAIL( defu n match (p d &option al bindings ) ;; 1. If P a nd D are b oth atoms, ;; If the y ’re equal , it’s a ma t ch, other wise FAIL ;; e. g. (match ' FEATHERS ' FEATHERS) ;; 2. If P i s a patter n variable ;; Assign the value of D to th e pattern v ariable i n P ;; e. g. (match ' (? X) 'JOE Y) ;; sh ould assig n the value JOEY to t he variabl e X ;; 3. If P a nd D are b oth Lists ;; Recurs i vely solv e for match es ;; e. g. (match ' (A B (? X) (D E)) '( A B C (D E ) )) ;; sh ould recur s ively call match on ( A vs . A) ;; (B vs . B) (( ? X) vs . C) ((D E) vs . (D E)) ;; 4. Any ot her case ( e.g. atom vs . list, e t c.) ;; FA I L)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 60
Match: Case 1, Case 4
• Part 1:• Build up Cond infrastructure
• Implement case 1 (P and D are both atoms)
• Implement case 4 (Everything Else)( defu n match (p d &option al bindings ) ( cond ((and ( atom p) ( atom d)) ;; Ca s e 1: Both p and d ar e atoms ;; If P and D a r e equal: M atch. Retu r n binding s ;; Ot herwise, r eturn FAIL (if ( eql p d) b i ndings 'FA I L)) (…Case 2…) (…Case 3…) (t ;; Ca s e 4: Any other case. Return F AIL 'FAIL ) ))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 21
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 61
Match: Case 3
• Case 3 (P and D are lists and need to be solved recursively)–Algorithm
;; A) Match the first pai r , to get n ew binding s;; B) If first pair faile d,;; C) return fail;; D) Otherw i se, using the bindin gs returne d;; by step (A), match rema i ning pair s
–Code( defu n match (p d &option al bindings ) ( cond (…Case 1…) (…Case 2…) ((and ( listp p) ( listp d)) ; P and D are both L i sts ;; Re c ursively s olve for m atches (let ( (result (match (f i rst p) (fi r st d) bin dings))) ; ( A) (if ( eq 'fail r esult) ; ( B) ' FAIL ; ( C) ( match (re s t p) (rest d) result ) ))) ; ( D) (…Case 4…) ) )
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 62
Match, Case 2
• Case 2: P is a variable, D is a piece of data• Example: P=(? X); D=Joey
• Make the binding (X Joey)
• Add it to the bindings already defined–Old Bindings: ( (A apple) (B banana) )–After adding: ( (X Joey) (A apple) (B banana) )
• Code for adding a new binding to a list of bindings( defu n add-bind i ng (p d b i ndings) (c ons (list ( second p) d) binding s ))
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 63
Match, Case 2 (continued)
• Note:–Before adding a binding, need to check if the binding already exists– If binding exists, it should match previous binding
• Example 1> (ma t ch '((? X ) (? Y) im plies (? X) (? Z)) (Joey smokes im plies Joey ( will get c ancer)))
( (X Joey) (Y smokes) (Z (will get cancer)))NOT((X Joey) (Y smokes) (X Joey) (Z (will get cancer)))
–When the algorithm finds (X Joey), no new binding should be created
• Example 2> (ma t ch '((? X ) (? Y) im plies (? X) (? Z)) (Joey smokes im plies Mary ( will get c ancer)))
FAIL–This should fail because X cannot be bound to both Joey and Mary–When the algorithm finds (X Joey) while trying to bind (X Mary), the
routine should return FAIL
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta 22
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 64
Match, Case 2 (continued)
–Example 1(matc h '(? X) ' J oey '((X Joe y ) (Y smok es) (Z (wil l get canc er)))
–Example 2(matc h '(? X) ' Mary '((X Joe y ) (Y smok es) (Z (wil l get canc er)))
–Example 3(matc h '(? X) ' J oey '((Y smo k es) (Z (w i ll get can c er)))
–Algorithm;; 1. Check if v ariable i s already b ound;; 2. If bound, try to ma t ch the val ue of the v ariable;; to the da t um;; 3. If bou nd and the binding ma t ches, ret urn bindin g;; (nothi ng new nee ds to be do ne). (Exa mple 1);; 4. If bou nd and the binding do esn’t matc h, return FAIL;; (Examp l e 2);; 5. If not bo und, add a binding (E x ample 3)
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 4.ppt 65
Match, Case 2 (continued)
–Find-binding: Uses Assoc> (fi nd-binding '(? X) '( ( X Joey) (Y smokes) ( Z (will ge t …)))
(X Joey)–Match
( defu n match (p d &option al bindings ) ( cond (…Case 1…) ((and ( listp p) ( eq (second p) '?)) ; Is p=~ ( ? X) (let ( binding ( f ind-bindin g p bindin gs)) ; (1 ) (if binding ; (2 ) (match (s econd bindi ng) d bind i ngs) ; (3 , 4) (add-bind i ng p d bin dings) ; (5 ) ))) (…Case 3…) (…Case 4…) ))