Recursion To understand recursion one must first understand

  • Slides: 31
Download presentation
Recursion To understand recursion, one must first understand recursion. cs 3180(Prasad) L 14 Recur+Clojure

Recursion To understand recursion, one must first understand recursion. cs 3180(Prasad) L 14 Recur+Clojure 1

Specifying Incremental Work 0 -> f(0) 1 -> f(1) D 1 . . .

Specifying Incremental Work 0 -> f(0) 1 -> f(1) D 1 . . . n n+1 cs 3180(Prasad) Dn -> f(n) -> f(n+1) L 14 Recur 2

Divide and Conquer Problem Subproblem 1 decomposition Subproblem 2 recursion primitive Subsolution 1 Subsolution

Divide and Conquer Problem Subproblem 1 decomposition Subproblem 2 recursion primitive Subsolution 1 Subsolution 2 composition Solution cs 3180(Prasad) L 14 Recur 3

Cartesian Product > (cart 2 '(1 2) '(a b)) ( (1 a) (1 b)

Cartesian Product > (cart 2 '(1 2) '(a b)) ( (1 a) (1 b) (2 a) (2 b) ) > (cart 2 '(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) ) cs 3180(Prasad) L 14 Recur 4

Divide and Conquer (cart 2 '(a b) '(1)) (couple ' a '(1)) car/cdr (cart

Divide and Conquer (cart 2 '(a b) '(1)) (couple ' a '(1)) car/cdr (cart 2 '(b) '(1)) recursion “primitive” ((a 1)) ((b 1)) append ((a 1) (b 1)) cs 3180(Prasad) L 14 Recur 5

Different Problems; Same pattern cs 3180(Prasad) L 14 Recur 6

Different Problems; Same pattern cs 3180(Prasad) L 14 Recur 6

Scheme Definition (define (cart 2 x y) (if (null? x) '() (append (couple (car

Scheme Definition (define (cart 2 x y) (if (null? x) '() (append (couple (car x) y) (cart 2 (cdr x) y) ) (define (couple a y) (if (null? y) '() (cons (list a (car y)) (couple a (cdr y)) ) cs 3180(Prasad) L 14 Recur 7

Alternate Syntax : lambda (define cart 2 (lambda (x y) (if (null? x) '()

Alternate Syntax : lambda (define cart 2 (lambda (x y) (if (null? x) '() (append (couple (car x) y) (cart 2 (cdr x) y) ) ) (define couple (lambda (a y) (if (null? y) '() (cons (list a (car y)) (couple a (cdr y)) ) ) cs 3180(Prasad) L 14 Recur 8

Clojure Syntax (defn couple [a y] (if (empty? y) '() (cons (list a (first

Clojure Syntax (defn couple [a y] (if (empty? y) '() (cons (list a (first y)) (couple a (rest y)) ))) (defn cart 2 [x y] (if (empty? x) '() (concat (couple (first x) y) (cart 2 (rest x) y) ))) cs 3180(Prasad) L 14 Recur 9

Powerset > (powerset '(2)) ( ( ) (2) ) > (powerset '(1 2) )

Powerset > (powerset '(2)) ( ( ) (2) ) > (powerset '(1 2) ) ( (1) (1 2) () (2) ) > (powerset '(0 1 2)) ( (0 1) (0 1 2) (0 2) (1 2) () (2) ) Subsets of {0, 1, 2} with 0 are equinumerous with subsets of {0, 1, 2} without 0. cs 3180(Prasad) L 14 Recur 10

(define (powerset s) (if (null? s) '(()) (append (ins (car s) (powerset (cdr s))

(define (powerset s) (if (null? s) '(()) (append (ins (car s) (powerset (cdr s)) ) )) (define (ins a ss) (if (null? ss) '() (cons a (car ss)) (ins a (cdr ss)) ) )) cs 3180(Prasad) L 14 Recur 11

Alternate Syntax : let (define (powerset s) (if (null? s) '(()) (let ( (aux

Alternate Syntax : let (define (powerset s) (if (null? s) '(()) (let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux ) ) )) (define (ins a ss) (if (null? ss) '() (cons a (car ss)) (ins a (cdr ss)) ) )) cs 3180(Prasad) L 14 Recur 12

Clojure Syntax (defn ins [a ss] (if (empty? ss) '() (cons a (first ss))

Clojure Syntax (defn ins [a ss] (if (empty? ss) '() (cons a (first ss)) (ins a (rest ss)) ) )) (defn powerset [s] (if (empty? s) '(()) (let [aux (powerset (rest s))] (concat (ins (first s) aux ) ) )) cs 3180(Prasad) L 14 Recur 13

Related problems; Different Patterns cs 3180(Prasad) L 14 Recur 14

Related problems; Different Patterns cs 3180(Prasad) L 14 Recur 14

Remove-First-Top. Level (define (rm-fst-top sym lis) (if (null? lis) '() (if (eq? sym (car

Remove-First-Top. Level (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) Linear recursion cs 3180(Prasad) L 14 Recur 15

Alternate Syntax : if => cond (define (rm-fst-top sym lis) (cond ( (null? lis)

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) Linear recursion cs 3180(Prasad) L 14 Recur 16

Remove-All-Top. Level (define (rm-all-top sym lis) (cond ( (null? lis) '()) ( (eq? sym

Remove-All-Top. Level (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)) = > (rm-all-top ' (b a) '(b (b a) a b a)) (b (b a) b) = (b (b a) a b a) • Linear recursion cs 3180(Prasad) L 14 Recur 17

Remove-All-Expression-Top. Level (define (rm-all-top exp lis) (cond ( (null? lis) '()) ( (equal? exp

Remove-All-Expression-Top. Level (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 cs 3180(Prasad) L 14 Recur 18

Remove-All (define (rm-all sym ll) (cond ( (null? ll) '()) ( (symbol? (car ll))

Remove-All (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 cs 3180(Prasad) L 14 Recur 19

rm-all : Structural recursion • Empty list (Basis case) (rm-all 'a '()) • First

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))) cs 3180(Prasad) L 14 Recur 20

Insertion sort (Note: creates a sorted copy) (define (insert n lon) (cond ((null? lon)

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. cs 3180(Prasad) L 14 Recur 21

Clojure Syntax (defn insert [n lon] (cond (empty? lon) (list n) (> n (first

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. cs 3180(Prasad) L 14 Recur 22

Subset (uses OR and AND instead of IF) (define (subset? ss s) (or (null?

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 cs 3180(Prasad) L 14 Recur 23

Anonymous functions and list membership test in Clojure > ( (fn [x y] (+

Anonymous functions and list membership test in Clojure > ( (fn [x y] (+ x y)) 25 30) 55 > ( #(+ %1 %2) 25 30) %2 55 > (some #(= 5 %) '(5 30)) true > (some #(= 5 %) '(15 30)) nil cs 3180(Prasad) L 14 Recur 24

Subset in Clojure (cf. case sensitive Scheme) (defn subset? [ss s] (or (empty? ss)

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)) true cs 3180(Prasad) L 14 Recur 25

Expression evaluation : A simple syntax directed translation expr -> x | y |

Expression evaluation : A simple syntax directed translation expr -> x | y | -> (+ expr -> (if expr z expr) Write a recursive definition for a function ops that counts the number of “+”s. cs 3180(Prasad) L 14 Recur 26

(define (ops e) ; e is assumed to be a symbol or a list

(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 (cadddr e)))) (else (display 'ILLEGAL)) ) ) cs 3180(Prasad) L 14 Recur 27

(defn third [x] (second (rest x))) (defn ops [e] ; Clojure code "e is

(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 )) cs 3180(Prasad) L 14 Recur 28

(Alternative Scheme syntax with member and case-construct (not equivalent)) (define (ops e) ; e

(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 (cadddr e))) ) (else (display 'ILLEGAL))) ) )) cs 3180(Prasad) L 14 Recur 29

Examples (ops 'x) 0 (ops '(+ y z)) 1 (ops '(if x (+ y

Examples (ops 'x) 0 (ops '(+ y z)) 1 (ops '(if x (+ y z) (+ x z))) 2 cs 3180(Prasad) L 14 Recur 30

(Alternative syntax in Clojure (not equivalent or robust)) (defn ops [e] ; e is

(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)) (ops (last e))) (println 'ILLEGAL))) ) ) cs 3180(Prasad) L 14 Recur 31