Download presentation
Presentation is loading. Please wait.
Published byOliver Endresen Modified over 5 years ago
1
To understand recursion, one must first understand recursion.
RECURSIVE STRUCTURE: Sub-problem must resemble the original problem Tree -> subtrees; List -> sublists; Expressions -> subexpressions (transformations: traversals, evaluation, code generation, …) E.g., f : EXPR -> int CORRECT DECOMPOSITION: (f ‘(+ e1 e2)) -> (+ (f ‘e1) (f ‘e2)) WRONG FORMULATION: > (f ‘(e1 e2)) Requires f to handle expressions, plus unnessary inputs such as lists of expressions, empty list, etc. Creates unnecessary work with complicated logic While explaining program code, focus is on problem solving and not on data structure creation, low-level manipulation, and destruction. => DECLARATIVE PROGRAMMING cs3180(Prasad) L14Recur+Clojure
2
Specifying Incremental Work
D1 1 -> f(1) ... n -> f(n) Dn n > f(n+1) cs3180(Prasad) L14Recur
3
Divide and Conquer Problem decomposition Subproblem1 Subproblem2
primitive recursion Subsolution1 Subsolution2 composition Solution cs3180(Prasad) L14Recur
4
Cartesian Product > (cart2 '(1 2) '(a b))
( (1 a) (1 b) (2 a) (2 b) ) > (cart2 '(0 1 2) '(a b)) ( (0 a) (0 b) (1 a) (1 b) (2 a) (2 b) ) > (couple ' 1 '(b c)) ( (1 b) (1 c) ) > (couple ' 1 '(a b c)) ( (1 a) (1 b) (1 c) ) cs3180(Prasad) L14Recur
5
Divide and Conquer (cart2 '(a b) '(1)) car/cdr (couple ' a '(1))
(cart2 '(b) '(1)) “primitive” recursion ((a 1)) ((b 1)) append ((a 1) (b 1)) cs3180(Prasad) L14Recur
6
Different Problems; Same pattern
cs3180(Prasad) L14Recur
7
Scheme Definition (define (cart2 x y) (if (null? x) '()
(append (couple (car x) y) (cart2 (cdr x) y) ) (define (couple a y) (if (null? y) '() (cons (list a (car y)) (couple a (cdr y)) cs3180(Prasad) L14Recur
8
Alternate Syntax : lambda
(define cart2 (lambda (x y) (if (null? x) '() (append (couple (car x) y) (cart2 (cdr x) y) ) (define couple (lambda (a y) (if (null? y) '() (cons (list a (car y)) (couple a (cdr y)) cs3180(Prasad) L14Recur
9
Clojure Syntax (defn couple [a y] (if (empty? y) '()
(cons (list a (first y)) (couple a (rest y)) ) ) ) (defn cart2 [x y] (if (empty? x) '() (concat (couple (first x) y) (cart2 (rest x) y) (couple ' (1) '(a ("abc") c)) (((1) a) ((1) ("abc")) ((1) c)) (cart2 ' (1 2 3) '(a b c)) ((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c)) cs3180(Prasad) L14Recur
10
Powerset > (powerset '(2)) ( ( ) (2) ) > (powerset '(1 2) )
( ( ) (2) ) > (powerset '(1 2) ) ( (1) (1 2) () (2) ) > (powerset '(0 1 2)) ( (0 1) (0 1 2) (0) (0 2) (1) (1 2) () (2) ) Subsets of {0,1,2} with 0 are equinumerous with subsets of {0,1,2} without 0. cs3180(Prasad) L14Recur
11
(define (powerset s) (if (null? s) '(()) (append (ins (car s)
(powerset (cdr s)) ) )) (define (ins a ss) (if (null? ss) '() (cons (cons a (car ss)) (ins a (cdr ss)) > (powerset '(0 1 2)) ((0 1 2) (0 1) (0 2) (0) (1 2) (1) (2) ()) (define (powerset s) (if (null? s) (list ()) (let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux) aux ) )) cs3180(Prasad) L14Recur
12
Alternate Syntax : let (define (powerset s) (if (null? s) '(())
(let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux) aux ) )) (define (ins a ss) (if (null? ss) '() (cons (cons a (car ss)) (ins a (cdr ss)) > (powerset '(0 1 2)) ((0 1 2) (0 1) (0 2) (0) (1 2) (1) (2) ()) (define (powerset s) (if (null? s) (list ()) (let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux) aux ) )) cs3180(Prasad) L14Recur
13
Clojure Syntax (defn ins [a ss] (if (empty? ss) '()
(cons (cons a (first ss)) (ins a (rest ss)) ) )) (defn powerset [s] (if (empty? s) '(()) (let [aux (powerset (rest s))] (concat (ins (first s) aux) aux > (powerset '(0 1 2)) ((0 1 2) (0 1) (0 2) (0) (1 2) (1) (2) ()) cs3180(Prasad) L14Recur
14
Related problems; Different Patterns
cs3180(Prasad) L14Recur
15
Remove-First-TopLevel
(define (rm-fst-top sym lis) (if (null? lis) '() (if (eq? sym (car lis)) (cdr lis) (cons (car lis) (rm-fst-top sym (cdr lis)) ) > (rm-fst-top 'a '(b (b a) a b a)) = (b (b a) b a) Linear recursion cs3180(Prasad) L14Recur
16
Alternate Syntax : if => cond
(define (rm-fst-top sym lis) (cond ( (null? lis) '()) ( (eq? sym (car lis)) (cdr lis) ) ( else (cons (car lis) (rm-fst-top sym (cdr lis)) ) > (rm-fst-top 'a '(b (b a) a b a)) = (b (b a) b a) Linear recursion cs3180(Prasad) L14Recur
17
Remove-All-TopLevel Linear recursion
(define (rm-all-top sym lis) (cond ( (null? lis) '()) ( (eq? sym (car lis)) (rm-all-top sym (cdr lis) ) ) ( else (cons (car lis) (rm-all-top sym (cdr lis))) ) > (rm-all-top 'a '(b (b a) a b a)) = (b (b a) b) > (rm-all-top ' (b a) '(b (b a) a b a)) = (b (b a) a b a) Linear recursion cs3180(Prasad) L14Recur
18
Remove-All-Expression-TopLevel
(define (rm-all-top exp lis) (cond ( (null? lis) '()) ( (equal? exp (car lis)) (rm-all-top exp (cdr lis) ) ) ( else (cons (car lis) (rm-all-top exp (cdr lis)))) ) > (rm-all-top ' (b a) '(b (b a) a b a)) = (b a b a) Linear recursion cs3180(Prasad) L14Recur
19
Remove-All > (rm-all ' a '(b (b a) a b a)) = (b (b) b)
(define (rm-all sym ll) (cond ( (null? ll) '()) ( (symbol? (car ll)) (if (eq? sym (car ll)) ( rm-all sym (cdr ll) ) ( cons (car ll) (rm-all sym (cdr ll)) ) ) ) (else (cons (rm-all sym (car ll)) (rm-all sym (cdr ll)) > (rm-all ' a '(b (b a) a b a)) = (b (b) b) Double recursion cs3180(Prasad) L14Recur
20
rm-all : Structural recursion
Empty list (Basis case) (rm-all 'a '()) First – Atom (Recursive case) (rm-all 'a '(a b c a)) (rm-all 'a '(b b c a)) First - Nested list (Recursive case) (rm-all 'a '((a b c) d (a))) (rm-all 'a '(b (a b c) d (a))) cs3180(Prasad) L14Recur
21
Insertion sort (Note: creates a sorted copy)
(define (insert n lon) (cond ((null? lon) (list n)) ((> n (car lon)) (cons (car lon) (insert n (cdr lon)))) (else (cons n lon)) ) (define (ins-sort lon) (if (null? lon) '() (insert (car lon) (ins-sort (cdr lon))) Precondition: second arg to insert ordered. Postcondition: insert returns an ordered list. cs3180(Prasad) L14Recur
22
Clojure Syntax (defn insert [n lon] (cond (empty? lon) (list n)
(> n (first lon)) (cons (first lon) (insert n (rest lon))) :true (cons n lon)) ) (defn ins-sort [lon] (if (empty? lon) '() (insert (first lon) (ins-sort (rest lon))) Precondition: second arg to insert ordered. Postcondition: insert returns an ordered list. > (ins-sort '( )) ( ) cs3180(Prasad) L14Recur
23
Subset (uses OR and AND instead of IF)
(define (subset? ss s) (or (null? ss) (and (member (car ss) s) (subset? (cdr ss) s) ) ) ) 1=> (subset? '(a b c) '(A p 1 C 2 B q r)) #t 2=> (subset? '(a b c) '(p)) #f cs3180(Prasad) L14Recur
24
Anonymous functions and list membership test in Clojure
> ( (fn [x y] (+ x y)) 25 30) 55 > ( #(+ %1 %2) 25 30) > (some #(= 5 %) '(5 30)) true > (some #(= 5 %) '(15 30)) nil ```’’’’’ cs3180(Prasad) L14Recur
25
Subset in Clojure (cf. case sensitive Scheme)
(defn subset? [ss s] (or (empty? ss) (and (some #(= (first ss) %) s) (subset? (rest ss) s) ) ) ) > (subset? '() '(A p 1 C 2 B q r)) true > (subset? '(a b c) '(A p 1 C 2 B q r)) nil > (subset? '(a b c) '(p a c b)) > (defn in? "true if seq contains elm" [seq elm] (some #(= elm %) seq)) #'sandbox20469/in? > (in? '( 1 2 3) 1) true > (in? '( 1 2 3) 4) nil cs3180(Prasad) L14Recur
26
Expression evaluation : A simple syntax directed translation
expr -> x | y | z expr -> (+ expr expr) expr -> (if expr expr expr) Write a recursive definition for a function ops that counts the number of “+”s. cs3180(Prasad) L14Recur
27
; e is assumed to be a symbol or a list (cond ((symbol? e) 0)
(define (ops e) ; e is assumed to be a symbol or a list (cond ((symbol? e) 0) ((eq? (car e) '+) (+ 1 (ops (cadr e)) (ops (caddr e))) ) ((eq? (car e) 'if) (+ (ops (cadr e)) (ops (caddr e)) (ops (cadddr e)))) (else (display 'ILLEGAL)) ) (ops 'x) (ops ' (+ y z)) (ops ' (if x (+ y z) (+ x z))) cs3180(Prasad) L14Recur
28
(defn third [x] (second (rest x))) (defn ops [e] ; Clojure code
"e is assumed to be a symbol or a list" (cond (symbol? e) 0 (= (first e) '+) (+ 1 (ops (second e)) (ops (third e)) ) (= (first e) 'if) (+ (ops (second e)) (ops (third e)) (ops (last e))) true 'ILLEGAL )) (defn third [x] (second (rest x))) (defn fourth [x] (third (rest x))) (ops 'x) (ops ' (+ y z)) (ops ' (if x (+ y z) (+ x z))) cs3180(Prasad) L14Recur
29
; e is assumed to be a symbol or a list (if (member e '(x y z)) 0
(Alternative Scheme syntax with member and case-construct (not equivalent)) (define (ops e) ; e is assumed to be a symbol or a list (if (member e '(x y z)) 0 (if (symbol? e) (display 'ILLEGAL) (case (car e) ((+) (+ 1 (ops (cadr e)) (ops (caddr e))) ) ((if) (+ (ops (cadr e)) (ops (caddr e)) (ops (cadddr e))) ) (else (display 'ILLEGAL))) ) )) (ops 'x) (ops ' (+ y z)) (ops ' (if x (+ y z) (+ x z))) cs3180(Prasad) L14Recur
30
(ops 'x) 0 (ops '(+ y z)) 1 (ops '(if x (+ y z) (+ x z))) 2
Examples (ops 'x) 0 (ops '(+ y z)) 1 (ops '(if x (+ y z) (+ x z))) 2 cs3180(Prasad) L14Recur
31
(Alternative syntax in Clojure (not equivalent or robust))
(defn ops [e] ;e is assumed to legal (if (some #(= e %) '(x y z)) 0 (if (symbol? e) (println 'ILLEGAL) (case (first e) (+) (+ 1 (ops (second e)) (ops (last e))) (if) (+ (ops (second e)) (ops (third e)) (println 'ILLEGAL))) ) ) > (ops '(a)) ILLEGAL > (ops '(if x (+ y z) a)) java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number Thrown if ILLEGAL symbol returned > (println 'ILLEGAL) nil > > (ops '(if x nil a)) java.lang.NullPointerException > > (ops '(case x nil a)) cs3180(Prasad) L14Recur
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.