Lab 2 Higher order functions and pattern matching 2.1 HIGHER ORDER FUNCTIONS

advertisement
AI - Lisp / Lab 2 - Higher order functions and pattern matching
7
Lab 2
Higher order functions and pattern matching
2.1 HIGHER ORDER FUNCTIONS
A higher order function is a function which takes another function as argument or returns a function as value.
Exercise 2.1a Define a function acc1st with arguments n and fn, where n should be a positive integer
and fn a numeric function with one argument. The function acc1st shall accumulate the results from fn
applied on the n first integer [1..n]:
acc1st ( n, fn ) =
n
∑i = 1 fn ( i )
(acc1st 10 #'-)
=> -55
; -1 + -2 + -3 + -4 + -5 + -6 + -7 + -8 + -9 + -10
(acc1st 5 #'(lambda (x) (* x x)))
=> 55
; 12+22+32+42+52
Exercise 2.1b. Define a function filter with two arguments, a predicate function (given a truth value as
result) pred-fn with one argument. The function works as a filter, which is applied on every element in a
straight list. The function filter shall return a new list with the filtered elements:
(filter #'numberp '(a b 4 c 9 3 d))
=> (4 9 3)
(filter
#'(lambda (x) (or (eq x 'a) (eq x 'b)))
'(a b c d a d b c c b a))
=> (a b a b b a)
ASSIGNMENT 2A - PASCAL’S TRIANGLE
Define a higher order function generate-list, which creates a list with n elements which starts with a
given start element and the rest of the elements will be computed by a given function.
(generate-list start-element
function-to-compute-next-element
number-of-elements)
(generate-list 10 #’(lambda (n) (- n 2)) 5)
=> (10 8 6 4 2)
; decrease next element with 2
(generate-list ’(a b c d e f) #’rest 3)
=> ((a b c d e f) (b c d e f) (c d e f))
8
AI - Lisp / Lab 2 - Higher order functions and pattern matching
Use this higher order function to define a function pascal, which computes the Pascal’s triangle which
stores the binomial coefficients. Pascal’s triangle for 6 rows is as follows:
1
1
1
1
1
1
1
2
3
4
5
1
3
6
10
1
4
10
1
5
1
The numbers in the next row are constructed from the previous ones by adding the two numbers on the row
over it. A row starts and ends with the value 1.
Represent the triangle as a list of lists.
(pascal 6)
=> ((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1) (1 5 10 10 5 1))
2.2 PATTERN MATCHING
In pattern matching we want to see if a pattern matches data of some kind. We will here match lists and we
introduce here two pattern symbols & for matching one arbitrary element and -- for matching a segment
consisting of zero, one or more elements.
pattern
list
result
(a & b)
(a & b)
(a & b)
(a & b)
(a & b)
(a x b)
(a y b)
(a b)
(a b c)
(a x y b)
match
match
no match
no match
no match
(a -- b)
(a -- b)
(a -- b)
(a -- b)
(a b)
(a x b)
(a x y b)
(a x b c)
match
match
match
no match
(& b -- c & d)
(a b x y c z d)
match
(a -- b c)
(a x b y b c)
match
A simple pattern matcher is the following:
(defun patmatch (l pat)
(cond
((endp pat) (endp l))
; end of list and pattern?
((eq (first pat) '--)
; segment pattern?
(cond
((patmatch l (rest pat)) t) ; does the rest match?
((endp l) nil)
; failed, the segment pattern
; match the rest of the list
(t (patmatch (rest l) pat)))) ; let the segment pattern
; take the next element
((endp l) nil)
; no more elements to match against
((eq (first pat) '&)
; match an arbitrary element
(patmatch (rest l) (rest pat)))
((eql (first pat) (first l)) ; exact match
(patmatch (rest l) (rest pat)))
(t nil))))
; no match at all, failed
AI - Lisp / Lab 2 - Higher order functions and pattern matching
9
Exercise 2.2a. Implement the patmatch function. Trace it and run a number of test examples. The difficult
part to understand is the matching of the segment pattern and how it does "back-tracking". Test the above
examples. Check also the termination conditions. Does this match?
(patmatch ’(--) ’())
(patmatch ’(-- -- --) ’())
Test also the following example:
(patmatch ’(a x b y b c) ’(a -- b c))
Here we start to match the element a. The the segment pattern will be in action. First try to match the rest
of the pattern with the list. Does (x b y b c) match the pattern (b c). No, x does not match b. Back up
and let the segment pattern match one more element, now the element x. Match the rest of the list (b y b
c) with the rest of the pattern (b c). The first element matches, but then it does not match. Back up and
let the segment also include b. We go on and also let y be included in the segment pattern. The the rest of
the list (b c) matches the rest of the pattern (b c). The final result is that it matches. Test it and follow
it by trace.
ASSIGNMENT 2B - PATTERN MATCHING IN A SMALL DATA BASE
We will here create a small data base to store for example information about books. We represent the data
base as a list of records, where every record is a list of some kind of information. For simplicity this information may be put in some order in the record. A data base of books could look like this:
( ((author (anders haraldsson)) (title (programmering i lisp))
(year 1993) (place (room (left 4))))
((author (anders haraldsson)) (title (programmering i pascal))
(year 1979) (place (room (left 2))))
((author (nils nilsson)) (title (artificial intelligence))
(year 1999) (place (library (pu 1573)))) ... )
We need a function find-books which takes a pattern and returns all books fulfilling this pattern.
Find all books by haraldsson:
(find-books ’((author (& haraldsson)) --))
=> (((author (anders haraldsson)) (title (programmering i lisp))
(year 1993) (place (room (left 4))))
((author (anders haraldsson)) (title (programmering i pascal))
(year 1979) (place (room (left 2)))) )
Find all books with a title containing programmering?
(find-books ’(-- (title (-- programmering --)) --))
=> (((author (anders haraldsson)) (title (programmering i lisp))
(year 1993) (place (room (left 4))))
((author (anders haraldsson)) (title (programmering i pascal))
(year 1979) (place (room (left 2)))))
What we now need is a pattern matcher which takes a pattern and a list of an arbitrary structure, not only
a straight list as the function patmatch handles above. Extend patmatch so it can handle arbitrary lists
(dotted pair is not necessary). The pattern symbol & will in this case match a lit element, either a symbol
or a list.
We will also introduce more pattern symbols. We want to match numbers in a given interval and we want
to write (< n) and (> n). We will also have a pattern (not pattern) to say that we have a pattern
which we will not match. Observe that the not symbol takes a pattern, so we can not use a symbol here.
10
AI - Lisp / Lab 2 - Higher order functions and pattern matching
Find all books written after 1985 by anders haraldsson?
(find-books ’((author (anders haraldsson)) & (year (> 1985)) --))
=> (((author (anders haraldsson)) (title (programmering i lisp))
(year 1993) (place (room (left 4)))))
Find all books by anders haraldsson with a title which does not end with lisp?
(find-books ’((author (anders haraldsson))
(title (not (-- lisp))) --)))
=> (((author (anders haraldsson)) (title (programmering i pascal))
(year 1979) (place (room (left 2)))))
Download