Presentation is loading. Please wait.

Presentation is loading. Please wait.

To understand recursion, one must first understand recursion.

Similar presentations


Presentation on theme: "To understand recursion, one must first understand recursion."— Presentation transcript:

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


Download ppt "To understand recursion, one must first understand recursion."

Similar presentations


Ads by Google