
Where are we? We've added S-expressions (and booleans) to Impcore CS301 We've seen how to use them to implement sets Session 5 dictionaries We've introduced lambda and the idea of first- class functions 1 2 Where are we going? Lambda A look at how functions can be treated as values Creates unnamed function A long look at how to exploit first-class functions (lambda (x) (* x 3)) ... the function that multiplies its argument by 3 In (lambda (x) (+ x y)) ... x is bound, but y is free 3 4 Uses of lambda Nested functions for Define nested functions using letrec mutual recursion Pass functions as parameters From problem set 2: (define preord (t) Return functions as results (letrec ((pre* (lambda (ts) Store them in data structures (if (null? ts '() (append (preord (car ts)) (pre* (cdr ts)))))) ) (if (leaf? t) (list1 t) (cons (label t) (pre* (cdr t)))))) 5 6 Nested functions Implementing nesting Free variables Easy: keep stack of "displays" at run time (define contig-sublist? (l1 l2) not the call stack! (letrec location of free variable known at compile time ((prefix (lambda (f s) (if (null? f) #t Familiar "static scoping" rule (if (null? s) #f (if (equal? (car f) (car s)) (prefix (cdr f) (cdr s)) (prefix l1 (cdr s)))))))) (prefix l1 l2))) Free variable l1 used to "reset" the search! 7 8 Functions as arguments Implementation (define twice (f x) (f (f x))) Still straightforward: n and m are on the call stack while the lambda is being called in twice (define nsq*m(n m) At runtime, maintain links backward in the call (twice (lambda (x) (* n x)) stack to find the values of free variables m)) -> (nsq*m 3 2) 18 What are the bound and free variables? 9 10 Lambda: the great escape Example Things are different when we return functions as -> (define mult-by (n) (lambda (x) (* n x))) results or store them in data structures! mult-by -> ((mult-by 3) 4) The free variables "escape" their original 12 environment Question: after (mult-by 3)returns, what does n mean? Now we need closures: in our interpreters a In a naive implementation the parameter context is gone! lambda evaluates to a pair containing the code ...thus closures! and the current environment 11 12 Application: Function Application: currying composition -> (define put-head (x) ((curry cons) x)) put-head (define o (f g) -> (val put-a (put-head 'a)) (lambda (x) (f (g x)))) <procedure> -> (put-a '(b c d)) -> (val caddr (o car (o cdr cdr))) (a b c d) <procedure> -> (put-a '(b l e)) -> (caddr '(a b c d)) (a b l e) c 13 14 "own variables" H-O functions in the (define lock-box (key open) (lambda (k) standard basis (if (equal? k key) (if open Besides compose and curry... (begin (set open #f) '(you have locked the box)) (begin (set open #t) '(you have unlocked the box))) '(that is not the right key)))) Applying predicates to lists via filter, exists?, all? -> (val box1 (lock-box 42 #f)) <procedure> -> (val box2 (lock-box 7 #t)) Transforming lists via map <procedure> -> (box1 42) (you have unlocked the box) General list catamorphisms foldl and foldr -> (box1 42) (you have locked the box) -> (box2 42) (that is not the right key) -> (box2 7) (you have locked the box -> (box2 7) (you have unlocked the box) 15 16 Predicates The list transformer map Predicate: a function that returns a boolean Apply a function of one argument to each element (val pos ((curry <) 0)) -> (map pos '(-3 3 -4 4 -1 0 5)) -> (filter pos '(-3 3 -4 4 -1 0 5)) (#f #t #f #t #f #f #t) (3 4 5) -> (map Let's implement filter on the board (lambda (x) (cons x '())) '(a b c)) ((a) (b) (c)) 17 18 Fold operators Using fold As a result of (define countall (x xs) (foldl (foldr f z '(1 2 3)) (lambda (y sum) (+ sum (if (equal? x y) ... the input 1 (if (pair? y) (cons 1 (cons 2 (cons 3 '()))) (countall x y) ... is transformed into the value of 0)))) 0 xs)) (f 1 (f 2 (f 3 z ))) 19 20 Using fold Folding from the left As a result of (define preord (t) (if (leaf? t) (foldl f z '(1 2 3)) (list1 t) (cons (label t) ... the input (foldr (lambda (t l) (cons 1 (cons 2 (cons 3 '()))) (append (preord t) l)) ... is transformed into the value of '() (f 3 (f 2 (f 1 z ))) (cdr t))))) 21 22 !"#$# versus !"#$% Next time -> (foldr cons '() '(1 2 3)) Using higher-order functions (1 2 3) polymorphism continuations -> (foldl cons '() '(1 2 3)) (3 2 1) 23 24 Where are we? We've seen how Scheme's first-class functions can be used for local function definitions CS301 to pass functions as parameters Session 6 to return functions as results We've looked at the standard basis functions o curry all? exists? filter map foldl foldr 1 2 Where are we going? Polymorphism - the Higher-order functions for polymorphism problem Higher-order functions and continuation-passing Sets, yes, but sets of what? style -> (val emptyset ’()) -> (define member? (x s) (exists? ((curry equal?) x) s)) -> (define add-element (x s) (if (member? x s) s (cons x s))) -> (define union (s1 s2) (foldl add-element s1 s2)) -> (define set-from-list (l) (foldl add-element ’() l)) -> (union ’(1 2 3 4) ’(2 4 6 8)) (8 6 1 2 3 4) 3 4 Wanted: generality Equality for a-lists What if we want sets of a-lists? The right test: The predicate equal? isn't the right thing! (define sub-alist? (d1 d2) (all? (equal? '((U Thant)(I Ching)(E coli)) (lambda (pair) '((E coli)(I Ching)(U Thant))) (equal? (cadr pair) (find (car pair) d2))) d1)) #f (define =alist? (d1 d2) ...but that's what's used in member? (if (sub-alist? d1 d2) (sub-alist? d2 d1) #f)) 5 6 Clunky polymorphism Critique Redefine set ops to expect equality test as parameter We have to pass the equality predicate around wherever we use the set - wordy, awkward, and (define member? (x s eqfun) (exists? ((curry eqfun) x) s)) error-prone (define add-element (x s eqfun) Better idea: make the predicate part of the set (if (member? x s eqfun) s (cons x s))) ... But then we have to redefine all the set ops! And to use: (member x s =alist) (member y s' equal?) 7 8 Polymorphism version 2 Critique Represent set as pair of function and data (like a Now we can use the set without explicitly simple object in an OO language) mentioning the equality predicate - good! (define mk-set (eqfun elements) And there's no danger of using the wrong predicate (cons eqfun elements)) (define eqfun-of (set) (car set)) - good! (define elements-of (set) (cdr set)) But every set we have contains an extra cons cell - (val emptyset (lambda (eqfun) (mk-set eqfun ’()))) (define member? (x s) even when there are many sets and only a few (exists? ((curry (eqfun-of s)) x) (elements-of s))) (define add-element (x s) different equality predicates - which might be bad! (if (member? x s) s (mk-set (eqfun-of s) (cons x (elements-of s))))) To avoid the cons cell, package the set ops as a closure over the predicate 9 10 Polymorphism version 3 Critique (val mk-set-ops We got rid of the cons cell - good! (lambda (eqfun) (list2 But we might use the wrong set op for our set - ! (lambda (x s) bad! (exists? ((curry eqfun) x) s)) ! (lambda (x s) And we have to define named functions for each ! (if (exists? ((curry eqfun) x) s) s type of set - which we might not like. ! (cons x s)))))) (val al-nullset ’()) Later we'll study language features to give us real (val list-of-al-ops (mk-set-ops =alist?)) (val al-member? (car list-of-al-ops)) polymorphism directly. (val al-add-element (cadr list-of-al-ops)) 11 12 Continuation passing Continuations for errors Scheme's major innovation: the notion of A-list find confuses unbound keys with keys continuation bound to '() Full Scheme has a built-in construct for Clunky solution: special return values continuation handling: call/cc Elegant solution: client of find passes two The granddaddy of throwing/catching exceptions functions: a success continuation and a failure In uScheme we will program this explicitly with continuation higher-order functions 13 14 find with continuations Backtracking (define find-c (key alist success failure) We can use continuations to implement a (letrec backtracking search ((search (lambda (alist) ! (if (null? alist) ! (failure) ! (if (equal? key (caar alist)) ! ! (success (cadar alist)) ! ! (search (cdr alist))))))) (search alist))) (define find-default (key table default) (find-c key table (lambda (x) x) ! (lambda() default))) 15 16 The SAT problem A basic search module NP-complete, but lots of practical apps succeed, fail, and resume are continuations start succeed Problem: find an assignment of booleans to variables that satisfies a CNF formula fail resume Example formula: (x y z) (w y) (w z) ∨ ∨ ¬ ∧ ∨ ∧ ∨ succeed takes a resume continuation to allow Structure: conjuncts, disjuncts, literals backtracking in case of failure in later module Some satisfying assignments: Instantiate the module for each node of the search x T,y F,z T,w T tree { !→ !→ !→ !→ } x F,y T,z T,w F { !→ !→ !→ !→ } 17 18 Backtracking for SAT The disjunction solver To solve a conjunction: Now an empty list is UNsatisfiable! (define solve-conjunction (conjuncts cur fail succeed) (define solve-disjunct (disjuncts cur fail succeed) (if (null? conjuncts) (if (null? disjuncts) (succeed cur fail) (fail) (solve-disjunction (car conjuncts) cur fail (solve-literal (car disjuncts) cur (lambda (cur resume) (lambda () (solve-conjunction (cdr conjuncts) (solve-disjunct (cdr disjuncts) cur fail cur resume succeed))))) succeed)) On backtrack, fail succeed))) One satisfiable literal is all we need If the first conjunct is solved, continue with the rest of the conjuncts On backtrack, look at the rest of the disjuncts 19 20 Solving a literal Watch the backtracking: -> (one-solution f1) Bind if possible/needed
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages12 Page
-
File Size-