Title: P1249945260aRHmG
1Lecture 10
2Review from previous lecture
3Symbol a primitive type
- constructors (quote alpha)
- Selectors none
- Methods
- symbol? anytype -gt boolean
- eq?
- (symbol? (quote x)) gt t
4Symbol a primitive type (Cont.)
- (define foo (quote alpha))
- (define foo1 (quote alpha))
foo
alpha
foo1
foo2
foo2
A symbol with a given name exists only once !
(define foo2 (quote foo2))
We have to quote symbols to distinguish them from
variable names
5Syntactic Sugar.
-
- Expression
Rewrites to - 1. (quote (a b)) (list (quote a)(quote b))
- 2. (quote ()) nil
- 3. (quote 2) 2
- 4. (1 (b c)) (quote (1 (b c)))
- (list (quote 1) (quote (b c)))
- (list 1 (quote (b c)))
- (list 1 (list (quote b) (quote c)))
- (1 (b c))
6Manipulating lists and trees of symbols
symbolic diffrentiation
7Symbolic differentiation
(deriv ltexprgt ltwith-respect-to-vargt) gt
ltnew-exprgt
The expressions we deal with xy x5 2x (x5)
2 x y
(xy) dx 1 (2x(x5) 2xy ) dx 2(x5) 2x
2y
For now we allow only addition and multiplication
8Step 1 Representing expressions.
Use list of symbols. There are still few
possible lists one can think of For example, we
can represent 2x5 as (2 x 5) or (2 x 5)
We shall use a list structure corresponding to
the same prefix notation used by scheme in
combinations. ( ( 2 x) 5)
9Step 1 Legal Expressions- formal
Expr SimpleExpr CompoundExpr SimpleExpr
number symbol CompoundExpr ( OPERATOR, Expr,
Expr ) OPERATOR
10Example
(deriv ltexprgt ltwith-respect-to-vargt) gt
ltnew-exprgt
Want deriv to be such that
(deriv '( x 3) 'x) gt 1 (deriv '( ( x
y) 4) 'x) gt y (deriv '( x x) 'x) gt (
x x) (deriv 7 'x) gt 0 (deriv 'x 'x)
gt 1
11Step 2 Abstraction The underlying interface
- Constructors
- make-product
- make-sum
- Methods
- number?
- variable?
- sum-expr?
- product-expr?
- Selectors
- addend
- augend
12Step 3 Breaking the problem to smaller
subproblems
- Base case (corresponds to SimpleExpr)
- deriv number dx 0
- deriv variable dx 1 if variable is the same as
x 0 otherwise - Induction step (corresponds to CompoundExpr)
- (fg) f g
- (fg) f g g f
13Step 4 An algorithm assuming an
abstract interface.
- (define (deriv expr var)
- (cond
- ((number? expr) 0)
- ((variable? expr) (if (eq? expr var) 1 0))
- ((sum-expr? expr)
- (make-sum (deriv (addend expr) var)
- (deriv (augend expr) var)))
-
- (else (error "unknown expression" expr)))
14Step 4 An algorithm assuming an
abstract interface.
- (define deriv (lambda (expr var)
- (cond
- ((number? expr) 0)
- ((variable? expr) (if (eq? expr var) 1 0))
- ((sum-expr? expr)
- (make-sum (deriv (addend expr) var)
- (deriv (augend expr) var)))
- ((product-expr? expr)
- (make-sum
- (make-product (augend expr)
- (deriv (addend
expr) var)) - (make-product (addend expr)
- (deriv (augend
expr) var))) - (else (error "unknown expression" expr))))
15Step 5 The underlying interface constructors
and selectors.
We define the constructors (define (make-sum e1
e2) (list ' e1 e2)) (define (make-product e1 e2)
(list ' e1 e2))
And the selectors (define (addend expr) (cadr
expr)) (define (augend expr) (caddr expr))
16Step 5 The underlying interface methods.
(define (sum-expr? expr) (and (pair? expr)
(eq? (car expr) ')))
(define (product-expr? expr) (and (pair?
expr) (eq? (car expr) )))
(define (variable? expr) (and (not (pair?
expr)) (symbol? expr)))
17Writing, Debuging, Testing
(deriv 5 x) ? 0 (deriv x x) ? 1 (deriv x y)
? 0
(deriv ( x y) x) ? ( 1 0) (deriv ( x y)
z) ? ( 0 0)
(deriv '( ( x y) (- x y)) 'x) ? unknown
expression (- x y)
(deriv '( ( x y) ( x ( -1 y))) 'x) ? ( (
( x ( -1 y)) ( 1 0)) ( ( x y) ( 1 ( ( y
0) ( -1 0)))))
18We would like to simplify expressions.
Instead of the expression ( ( ( x ( -1 y))
( 1 0)) ( ( x y) ( 1 ( ( y 0) ( -1
0))))) We would like to have 2x
What should we change?
How easy is it to make the change?
19We change make-sum and make-product
(define (make-sum a1 a2) (cond ((and (number?
a1) ( a1 0)) a2) ((and (number? a2) (
a2 0)) a1) ((and (number? a1) (number?
a2)) ( a1 a2)) (else (list ' a1 a2))))
(define (make-product a1 a2) (cond ((and
(number? a1) ( a1 0)) 0) ((and (number?
a2) ( a2 0)) 0) ((and (number? a1) ( a1
1)) a2) ((and (number? a2) ( a2 1)) a1)
((and (number? a1) (number? a2)) ( a1
a2)) (else (list a1 a2))))
Its easier to change a well-written code.
20Testing again..
(deriv '( ( x y) ( x ( -1 y))) 'x) ? ( (
x ( -1 y)) ( x y))
This is an improvement. There is still a long
way to go.
21Allowing (- x y)
- (define deriv (lambda (expr var)
- (cond
- ((number? expr) 0)
- ((variable? expr) (if (eq? expr var) 1 0))
- ((sum-expr? expr)
- (make-sum (deriv (addend expr) var)
- (deriv (augend expr) var)))
- ((minus-expr? expr)
- (make-minus (deriv (addend expr) var)
- (deriv (augend expr) var)))
- ((product-expr? expr)
- . . . .
- (else (error "unknown expression" expr))))
22Allowing (- x y)
(define (make-minus a1 a2) (cond ((and (number?
a1) (number? a2)) (- a1 a2)) ((and
(number? a2) ( a2 0)) a1) (else (list -
a1 a2))))
(define (minus-expr? expr) (and (pair? expr)
(eq? (car expr) -)))
23Allowing xk, . ,1/x, (ln x)
(define (ln-expr? expr) (and (pair? expr)
(eq? (car expr) ln)))
(define deriv (lambda (expr var) (cond
((minus-expr? expr) ((ln-expr? expr)
)..)
24Allowing ( x y z w) ( x y z
w)
How about the following change
(define (addend expr) (cadr expr)) (define
(augend expr) (let ((first (car expr))
(second (cadr expr)) (rest (cddr
expr))) (cond ((gt (length rest) 1) (cons first
rest)) (( (length rest) 1) (car
rest)))))
25Testing..
gt (deriv '( x y z w a b c x y z e r t ) 'y) 2 gt
(deriv '( x y z w a b c x y z e r t ) 'f) 0
gt (deriv '( x y z w x t y ) 't) ( x ( y ( z
( w ( x y))))) gt (deriv '( x y z w x t y)
'x) ( ( y z w x t y) ( x ( y ( z ( w ( t
y))))))
26Guidelines
- Carefully think about
- the problem
- type of data
- The algorithm.
- Identify
- Constructors
- Selectors,
- And the methods you need from your data.
- Use data abstractions.
- Respect abstraction barriers.
- Avoid nested if expressions, complicated
procedures and always use good names.
27Text Searching
Text '(n n e e a b a b a a b f l e a c v b x v
c c c c v v v a a)
Pattern '(a b a a b f)
Want to find all occurences of the pattern in the
text
Text '(n n e e a b a b a a b f l e a c v b x v
c c c c v v v a a)
(find-pattern '(a b) '(a b a b)) ? (0 2)
28Brute force solution
(define (begins-with-pattern? p t) (cond
((null? p) t) ((null? t) f)
((eq? (car p) (car t))
(begins-with-pattern? (cdr p) (cdr t)))
(else f))) (define (naive-find-pattern p t j)
(cond ((null? t) '()) ((begins-with-patter
n? p t) (cons j (naive-find-pattern p
(cdr t) ( 1 j)))) (else
(naive-find-pattern p (cdr t) ( 1
j))))) (define (find-pattern p t)
(naive-find-pattern p t 0))
29This is inefficient..
Text abaabghab . . . .
Pattern abaabf
abaabghab . . . .
abaabf
abaabf
Knowing the pattern and the mismatch position we
could figure that the next possible alignment is
with the forth char
abaabghab . . . .
abaabf
abaabf
30Look only at the pattern
Prepare a table of shifts
abaabf
abaabf
Shifts(5) 2 Shifts(i) Which char. to compare
next if the mismatch occurs at i
abaabf
abaabf
Shifts(4) 1
31Look only at the pattern
abaabf
abaabf
Shifts(3) 1
abaabf
abaabf
Shifts(2) 0
abaabf
abaabf
Shifts(1) 0
abaabf
abaabf
Shifts(6) 0
32Look only at the pattern
Shifts(0) -1
Shifts(1) 0
Shifts(2) 0
Shifts(3) 1
Shifts(4) 0
Shifts(5) 2
Shifts(6) 0
Text abaabghabakabaabffgab . . . .
Pattern abaabf
abaabghabakabaabffgab . . . .
abaabf
abaabf
abaabf
abaabf
abaabf
abaabf
abaabf
abaabf
abaabf
abaabf
abaabf
33In Scheme
(define (find-pattern-kmp p i t j m shifts)
(cond ((null? t) '()) ((eq? (list-ref p i)
(car t)) (if ( i (- m 1)) (cons
(- j (- m 1)) (find-pattern-kmp
p (list-ref shifts m)
(cdr t) ( j 1) m shifts))
(find-pattern-kmp p ( 1 i) (cdr
t) ( 1 j) m shifts))) (else (if ( i
0) (find-pattern-kmp p 0 (cdr t) ( 1 j)
m shifts) (find-pattern-kmp p
(list-ref shifts i) t j m shifts))))) (define
(kmp p t) (find-pattern-kmp p 0 t 0 (length p)
(find-shifts p 1)))