Presentation is loading. Please wait.

Presentation is loading. Please wait.

Functional Programming Universitatea Politehnica Bucuresti 2007-2008 Adina Magda Florea

Similar presentations


Presentation on theme: "Functional Programming Universitatea Politehnica Bucuresti 2007-2008 Adina Magda Florea"— Presentation transcript:

1 Functional Programming Universitatea Politehnica Bucuresti 2007-2008 Adina Magda Florea http://turing.cs.pub.ro/fp_08

2 Lecture No. 6 Abstract data types in Scheme Structures in Scheme A unification algorithm

3 1. Abstract DT We can construct abstract data types, which are data types that represent higher-level concepts and use procedures to implement the operations. Use Scheme vectors to represent points, with each point represented as a small vector, with a slot for the x field and a slot for the y field. A constructor procedure make-point, which will create ("construct") a point object and initialize its x and y fields. ; a point is represented as a three-element vector, with the 0th ; slot holding the symbol point, the 1st slot representing ; the x field,, and the 2nd slot representing the y field. (define (make-point x y) (vector 'point x y))

4 Abstract DT (define (make-point x y) (vector 'point x y)) (define p1 (make-point 2 3)) p1 => #(point 2 3)

5 Abstract DT a predicate point? for testing whether an object is a point record. ; check to see if something is a point by checking to see if it's ; a vector whose 0th slot holds the symbol point. (define (point? obj) (and (vector? obj) (eq? (vector-ref obj 0) 'point))) (point? p1) => #t

6 accessor procedures to get and set the x and y fields of our points ; accessors to get and set the value of a point's x field. (define (point-x obj) (vector-ref obj 1)) (define (point-x-set! obj value) (vector-set obj 1 value)) ; accessors to get and set the value of a point's y field. (define (point-y obj) (vector-ref obj 2)) (define (point-y-set! obj) (vector-set! obj 2 value))

7 This isn't perfect - we should probably test to make sure an object is a point before operating on it as a point. For example, point-x should be more like this: (define (point-x obj) (if (point? obj) (vector-ref obj 1) (error "attempt to apply point-x to a non-point")))

8 Abstract DT We have defined an abstract data type in Scheme, by hand, using procedural abstraction. Doing this for every abstract data type is very tedious, so it would be good to automate the process and provide a declarative interface to it. We'd like to be able to write something like this: (define-struct point x y) and have Scheme automatically construct the constructor, type predicate, and accessor procedures for us.

9 2. Structures in Scheme PLT MzScheme A new structure type can be created with: (define-struct s (field ···) [inspector-expr]) (define-struct (s t) (field ···) [inspector-expr]) - s, t, and each field are identifiers. - inspector-expr - produce an inspector or #f. A define-struct expression creates: struct:s, a structure type descriptor value that represents the new datatype. This value is rarely used directly. make-s - a constructor procedure that takes n arguments and returns a new structure value.

10 Structures in Scheme (define-struct s (field ···) [inspector-expr]) (define-struct (s t) (field ···) [inspector-expr]) s? - a predicate procedure that returns #t for a value constructed by make-s (or the constructor for a subtype) and #f for any other value. s-field - for each field, an accessor procedure that takes a structure value and extracts the value for field. set-s-field! - for each field, a mutator procedure that takes a structure and a new field value. The field value in the structure is destructively updated with the new value, and void is returned. s - a syntax binding that encapsulates information about the structure type declaration. This binding is used to define subtypes

11 Structures in Scheme (define-struct cons-cell (car cdr)) (define x (make-cons-cell 1 2)) (cons-cell? x) => #t (cons-cell-car x) => 1 (set-cons-cell-car! x 5) (cons-cell-car x) => 5 (define-struct student (name marks)) (define stud1 (make-student "jack" (make-vector 3 10))) (student-name stud1) => "jack" (student-marks stud1) => #(10 10 10)

12 Structures in Scheme Each time a define-struct expression is evaluated, a new structure type is created with distinct constructor, predicate, accessor, and mutator procedures. If the same define-struct expression is evaluated twice, instances created by the constructor returned by the first evaluation will answer #f to the predicate returned by the second evaluation.

13 (define-struct cons-cell (car cdr)) (define x (make-cons-cell 1 2)) (cons-cell? x) ; => #t (cons-cell-car x) ; => 1 (set-cons-cell-car! x 5) (cons-cell-car x) ; => 5 (define orig-cons-cell? cons-cell?) (define-struct cons-cell (car cdr)) (define y (make-cons-cell 1 2)) (cons-cell? y) ; => #t (cons-cell? x) ; => #f, cons-cell? now checks for a different type (orig-cons-cell? x) ; => #t (orig-cons-cell? y) ; => #f

14 3. A unification algorithm Unification is a pattern-matching technique used in automated theorem proving, type- inference systems, computer algebra, and logic programming, e.g., Prolog

15 Expression unification Substitution  Unifier Most general unifier  Expression Unification algorithm

16

17

18 Implementation in Scheme For the purposes of the program, a symbolic expression can be a variable, a constant, or a function application. Variables are represented by Scheme symbols, e.g., x; A function application is represented by a list with the function name in the first position and its arguments in the remaining positions, e.g., (f x); Constants are represented by zero-argument functions, e.g., (a).

19 Implementation in Scheme The algorithm presented here finds the mgu for two terms, if it exists, using a continuation passing style approach to recursion on subterms. The procedure unify takes two terms and passes them to a help procedure, uni, along with an initial (identity) substitution, a success continuation, and a failure continuation. The success continuation returns the result of applying its argument, a substitution, to one of the terms, i.e., the unified result. The failure continuation simply returns its argument, a message. Because control passes by explicit continuation within unify (always with tail calls), a return from the success or failure continuation is a return from unify itself.

20 Implementation in Scheme Substitutions are procedures. Whenever a variable is to be replaced by another term, a new substitution is formed from the variable, the term, and the existing substitution. Given a term as an argument, the new substitution replaces occurrences of its saved variable with its saved term in the result of invoking the saved substitution on the argument expression. Intuitively, a substitution is a chain of procedures, one for each variable in the substitution. The chain is terminated by the initial, identity substitution.

21 Implementation in Scheme (unify 'x 'y) y (unify '(f x y) '(g x y)) "clash" (unify '(f x (h)) '(f (h) y)) (f (h) (h)) (unify '(f (g x) y) '(f y x)) "cycle" (unify '(f (g x) y) '(f y (g x))) (f (g x) (g x)) (unify '(f (g x) y) '(f y z)) (f (g x) (g x))

22 Implementation in Scheme (define unify #f) (let () ;; occurs? returns true if and only if u occurs in v (define occurs? (lambda (u v) (and (pair? v) (let f ((l (cdr v))) (and (pair? l) (or (eq? u (car l)) (occurs? u (car l)) (f (cdr l))))))))

23 Implementation in Scheme ;; sigma returns a new substitution procedure ;; extending :: s by the substitution of u with v (define sigma (lambda (u v s) (lambda (x) (let f ((x (s x))) (if (symbol? x) (if (eq? x u) v x) (cons (car x) (map f (cdr x))))))))

24 ;; try-subst tries to substitute u for v but may require a ;; full unification if (s u) is not a variable, and it may ;; fail if it sees that u occurs in v. (define try-subst (lambda (u v s ks kf) (let ((u (s u))) (if (not (symbol? u)) (uni u v s ks kf) (let ((v (s v))) (cond ((eq? u v) (ks s)) ((occurs? u v) (kf "cycle")) (else (ks (sigma u v s)))))))))

25 ;; uni attempts to unify u and v with a continuation-passing ;; style that returns a substitution to the success argument ;; ks or an error message to the failure argument kf. The ;; substitution itself is represented by a procedure from ;; variables to terms. (define uni (lambda (u v s ks kf) (cond ((symbol? u) (try-subst u v s ks kf)) ((symbol? v) (try-subst v u s ks kf)) ((and (eq? (car u) (car v)) (= (length u) (length v))) (let f ((u (cdr u)) (v (cdr v)) (s s)) (if (null? u) (ks s) (uni (car u) (car v) s (lambda (s) (f (cdr u) (cdr v) s)) kf)))) (else (kf "clash")))))

26 ;; unify shows one possible interface to uni, where ; ;; the initial substitution is the identity procedure ;; the initial success continuation returns ;; the unified term, and the initial failure ;; continuation returns the error message. (set! unify (lambda (u v) (uni u v (lambda (x) x) (lambda (s) (s u)) (lambda (msg) msg)))))


Download ppt "Functional Programming Universitatea Politehnica Bucuresti 2007-2008 Adina Magda Florea"

Similar presentations


Ads by Google