Inductive Sets of Data

1 / 27

# Inductive Sets of Data - PowerPoint PPT Presentation

Inductive Sets of Data. Programming Language Essentials 2nd edition Chapter 1.2 Recursively Specified Programs. Recursion. recursion can lead to divide-and-conquer: solution for a small problem 'by hand'.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about 'Inductive Sets of Data' - minowa

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Inductive Sets of Data
• Programming Language Essentials
• 2nd edition
• Chapter 1.2 Recursively Specified Programs
Recursion
• recursion can lead to divide-and-conquer:
• solution for a small problem 'by hand'.
• solution for a bigger problem by recursively invoking the solution for smaller problems.
• Examples:
• Factorial.
• Greatest common divisor (Euclid).
• Tower of Hanoi.
• Quicksort.
Recursively Specified Programs
• patterned after proof by induction.
• to compute xn:
• e(0, x) = 1, because x0 is 1.
• e(n, x) = x * e(n-1, x), because xn is x * xn-1.
• induction proves that e(n,x) is xn:
• (0) Hypothesis: e(k, x) is xk.
• (1) true for k=0, see above.
• (2) assume true up to k. Consider e(k+1, x).
• This is x * e(k, x) by definition, x * xk by assumption, and therefore xk+1.
Recursively Specified Programs (2)
• to compute xn:
• e(0, x) = 1, because x0 is 1.
• e(n, x) = x * e(n-1, x), because xn is x * xn-1.
• (define e
• (lambda (n x)
• (if (zero? n)
• 1
• (* x
• (e (- n 1) x)
• ) ) ) )
count-nodes
• bintree: 'Number'
• | '(' 'Symbol' bintree bintree ')'
• (define count-nodes
• (lambda (bintree)
• (if (number? bintree)
• 1
• 1
• ) ) ) )
Deriving Programs from BNF
• l-of-nums: '()'
• l-of-nums: '(' 'Number' '.' l-of-nums ')'
• pattern program after data (structural induction)
• one procedure for one nonterminal
• (define list-of-numbers?
• (lambda (x)
• (if (null? x)
• #t
• (and (pair? x)
• (number? (car x))
• (list-of-numbers? (cdr x))
• ) ) ) )
Proof by Induction
• (0) Hypothesis: l-of-n? works on lists of length k.
• (1) k=0: empty list, l-of-n? returns true. ok.
• (2) assume true up to k. Consider k+1.
• By grammar, car must be a number and cdr a list of numbers.
• cdr of list of k+1 elements has k elements, i.e.,
• l-of-n? can be applied. ok.
• proof does not discover that pair? is necessary
• because proof assumes list arguments
nth-elt
• like list-ref, returns 0..th element of list.
• (define nth-elt
• (lambda (list n)
• (if (null? list)
• (error 'nth-elt "List too short."
• (+ n 1) "elements")
• (if (zero? n)
• (car list)
• (nth-elt (cdr list) (- n 1))
• ) ) ) )
error
• http://srfi.schemers.org/
• lists Scheme Request for Implementation
• \$ scheme48

> ,open srfi-23

• Newly accessible in user: (error)

> (define nth-elt …

> (nth-elt '(1 2 3) -4)

• Error: nth-elt
• "List too short."
• -6
• "elements"
list-length
• like length, returns number of elements in list
• (define list-length
• (lambda (list)
• (if (null? list)
• 0
• (+ 1 (list-length (cdr list)))
• ) ) )
fragile vs. robust
• fragile procedures do not check the types of their arguments.
• (define list-length ; robust version
• (lambda (list)
• (if (list? list)
• (if (null? list)
• 0
• (+ 1 (list-length (cdr list)))
• )
• (error 'list-length
• "Not a list:" list)
• ) ) )
remove-first
• returns list without first occurrence of symbol
• list: '()' | '(' symbol '.' list ')'
• (define remove-first ; fragile
• (lambda (symbol list)
• (if (null? list)
• list
• ) ) )
remove-first
• returns list without first occurrence of symbol
• list: '()' | '(' symbol '.' list ')'
• (define remove-first ; fragile
• (lambda (symbol list)
• (if (null? list)
• list
• (if (eqv? (car list) symbol)
• (cdr list)
• ) ) ) )
remove-first
• returns list without first occurrence of symbol
• list: '()' | '(' symbol '.' list ')'
• (define remove-first ; fragile
• (lambda (symbol list)
• (if (null? list)
• list
• (if (eqv? (car list) symbol)
• (cdr list)
• (cons (car list)
• (remove-first symbol (cdr list))
• ) ) ) ) )
remove
• returns list without all occurrences of symbol
• list: '()' | '(' symbol '.' list ')'
• (define remove ; fragile
• (lambda (symbol list)
• (if (null? list)
• list
• (if (eqv? (car list) symbol)
• (remove symbol (cdr list))
• (cons (car list)
• (remove symbol (cdr list))
• ) ) ) ) )
subst
• returns s-list with any old replaced by new
• > (subst 'a 'b '((b c) (b () d)))
• '((a c) (a () d))
• s-list: '(' symbol-expression* ')'
• symbol-expression: 'Symbol' | s-list
• s-list: '()'
• | '(' symbol-expression '.' s-list ')'
• symbol-expression: 'Symbol' | s-list
• pair avoids need for another rule
subst
• s-list: '()'
• | '(' symbol-expression '.' s-list ')'
• (define subst ; fragile
• (lambda (new old slist)
• (if (null? slist)
• slist
• (cons
• (subst-se new old (car slist))
• (subst new old (cdr slist))
• ) ) ) )
subst-se
• symbol-expression: 'Symbol' | s-list
• (define subst-se
• (lambda (new old se)
• (if (symbol? se)
• (if (eqv? se old) new se)
• (subst new old se)
• ) ) )
• mutual recursion
• divide-and-conquer because of grammar
subst
• (define subst ; fragile
• (lambda (new old slist)
• (define symbol-expression ; local procedure
• (lambda (se) ; shares parameters
• (if (symbol? se)
• (if (eqv? se old) new se)
• (subst new old se)
• ) ) )
• (if (null? slist)
• slist
• (cons
• (symbol-expression (car slist))
• (subst new old (cdr slist))
• ) ) ) )
notate-depth
• returns s-list with symbols annotated for depth
• > (notate-depth '((b c) (b () d)))
• '(((b 1) (c 1)) ((b 1) () (d 1)))
• notate-depth: s-list
• s-list: '()'
• | '(' symbol-expression '.' s-list ')'
• symbol-expression: 'Symbol' | s-list
• notate-depth needed to mark start at level zero
notate-depth
• notate-depth: s-list
• (define notate-depth ; fragile
• (lambda (slist)
• (s-list slist 0)
• ) )
notate-depth
• s-list: '()'
• | '(' symbol-expression '.' s-list ')'
• (define notate-depth
• (lambda (slist)
• (define s-list
• (lambda (slist d)
• (if (null? slist)
• slist
• (cons
• (symbol-expression (car slist) d)
• (s-list (cdr slist) d)
• ) ) ) )
• (s-list slist 0)
• ) )
notate-depth
• symbol-expression: 'Symbol' | s-list
• (define notate-depth
• (lambda (slist)
• (define s-list …
• (define symbol-expression
• (lambda (se d)
• (if (symbol? se)
• (list se d)
• (s-list se (+ d 1))
• ) ) )
• (s-list slist 0)
• ) )
notate-depth
• (define notate-depth
• (lambda (slist)
• (define s-list
• (lambda (slist d)
• (if (null? slist)
• slist
• (cons
• (symbol-expression (car slist) d)
• (s-list (cdr slist) d)
• ) ) ) )
• (define symbol-expression
• (lambda (se d)
• (if (symbol? se)
• (list se d)
• (s-list se (+ d 1))
• ) ) )
• (s-list slist 0)
• ) )
Other Patterns of Recursion
• l-of-nums: '()'
• l-of-nums: '(' 'Number' '.' l-of-nums ')'
• compute sum by structural induction:
• (define list-sum
• (lambda (x)
• (if (null? x)
• 0
• (+ (car x))
• (list-sum (cdr x))
• ) ) ) )
Other Patterns of Recursion (2)
• vector is not suitable for structural induction, so:
• (define vector-sum
• (lambda (v)
• (partial-vector-sum v (vector-length v))
• ) )
• (define partial-vector-sum
• (lambda (v n)
• (if (zero? n)
• 0
• (+ (vector-ref v (- n 1)) ; last
• (partial-vector-sum v (- n 1))
• ) ) ) )
Other Patterns of Recursion (3)
• (define vector-sum
• (lambda (v)
• (letrec
• ((partial-vector-sum
• (lambda (n)
• (if (zero? n)
• 0
• (+ (vector-ref v (- n 1)) ; last
• (partial-vector-sum (- n 1))
• ))) ) )
• (partial-vector-sum (vector-length v))
• ) ) )
• proof by induction on vector length