1 / 22

A LISP interepreter for the Lambda Calculus Functional Programming

A LISP interepreter for the Lambda Calculus Functional Programming. Academic Year 2005-2006 Alessandro Cimatti cimatti@itc.it. Homework. Write a program to normalize expressions for lambda calculus Suggested steps: Define the ADT for lambda terms constructors recognizers

gage
Download Presentation

A LISP interepreter for the Lambda Calculus Functional Programming

An Image/Link below is provided (as is) to download presentation 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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A LISP interepreter for the Lambda CalculusFunctional Programming Academic Year 2005-2006 Alessandro Cimatti cimatti@itc.it

  2. Homework • Write a program to normalize expressions for lambda calculus • Suggested steps: • Define the ADT for lambda terms • constructors • recognizers • Define substitution primitive • Define recognizer for redex’s • Define beta-reduction rule • Define the normalizer: • recursively traverse the term looking for redex, and reduce • careful with infinite looping!! • Some remarks • homework due by december 20 • oh, it’s today  • try to use recursive definitions • homework is closely related to course project!!!

  3. Syntax • Expressions have the following syntax • e is either • x a variable • λx.e a lambda abstraction • e1 e2 application • Notation • for variables we use x, y, z, w • for expressions we use e, e’, e1, e2, ...

  4. The ADT for Expressions ; The ADT for expressions ; ; e ::= v | l | a ; v ::= symbolp ; a ::= ( e e ) ; l ::= ( lam v e ) ; (defun mk-v (sym) sym) (defun is-v (e) (symbolp e)) (defun mk-l (v b) (list 'lam v b)) (defun is-l (e) (and (consp e) (= (length e) 3) (equal 'lam (first e)) (is-v (second e)))) (defun l-get-v (l) (second l)) (defun l-get-b (l) (third l)) (defun mk-a (f a) (list f a)) (defun is-a (e) (and (consp e) (= (length e) 2))) (defun a-get-f (a) (first a)) (defun a-get-a (a) (second a))

  5. Generalized Recognizer ; takes arbitrary sexp in input ; (defun is-e (e) (cond ((is-v e) t) ((is-a e) (and (is-e (a-get-f e)) (is-e (a-get-a e)))) ((is-l e) (and (is-e (l-get-v e)) (is-e (l-get-b e)))) (t nil)))

  6. Free variables • The set of free variables in e, denoted as FV(e), is defined as • FV(x) = { x } • FV(e1 e2) = FV(e1) U FV(e2) • FV(λx.e) = FV(e) – { x } • e is a closed λ-term iff FV(e) is empty

  7. Free variables ; Return the free variables of an expression ; (defun fv (e) (cond ((is-v e) (list e)) ((is-a e) (append (fv (a-get-f e)) (fv (a-get-a e)))) ((is-l e) (remove (l-get-v e) (fv (l-get-b e)))) (t (error "Unknown lambda term type")))) (defun free-in (v e) (member v (fv e)))

  8. Alpha Renaming • λ-terms are equivalent up to renaming of bound variables • all occurrences of x are replaced by y • The rule of α-conversion • λx.e ≡αλy.[y/x]e • provided that y is not free in e • For instance, • λx.x ≡αλy.y • λx.y x ≡αλz.y z • But not • λx.y x ≡αλy.y y

  9. Equivalence up to Alpha-conversion (defun alpha-equivalent (e1 e2) (alpha-equivalent1 e1 e2 nil nil)) (defun alpha-equivalent1 (e1 e2 rpl1 rpl2) (cond ((is-v e1) (and (is-v e2) (let ((new1 (cdr (assoc e1 rpl1))) (new2 (cdr (assoc e2 rpl2)))) (if (and (null new1) (null new2)) (equal e1 e2) (equal new1 new2))))) ((is-a e1) (and (is-a e2) (alpha-equivalent1 (a-get-f e1) (a-get-f e2) rpl1 rpl2) (alpha-equivalent1 (a-get-a e1) (a-get-a e2) rpl1 rpl2))) ((is-l e1) (and (is-l e2) (let* ((new (freshvar)) (old1 (l-get-v e1)) (old2 (l-get-v e2)) (newrpl1 (cons (cons old1 new) rpl1)) (newrpl2 (cons (cons old2 new) rpl2))) (alpha-equivalent1 (l-get-b e1) (l-get-b e2) newrpl1 newrpl2))))))

  10. Substitution: [e’ / x] e • Replace free occurrences of x in e with e’ • No problem when free variables are replaced by term that “does not clash” • [λz.z w / x] λy.x = λy.λz.z w • However, there may be a problem if there is name capture/clash • [λz.z w / x] λx.x is not the same as λx.λz.z w • replacement of a bound variable! • [λz.z w / x] λw.x is not the same as λw.λz.z w • free variable w is now bound!

  11. Definition of Substitution • [e’/x]x = e’ • [e’/x]y = y • [e’/x](e1 e2) = ([e’/x]e1) ([e’/x] e2) • [e’/x](λx.e) = λx.e • [e’/x](λy.e) = λy.e if x not in FV(e) • [e’/x](λy.e) = λy.[e’/x]e if x in FV(e), y not in FV(e’) • [e’/x](λy.e) = λz.[e’/x][z/y]e if x in FV(e), y in FV(e’)

  12. Substitution (defun subst-with-in (x e1 exp) (cond ((is-v exp) (if (equal x exp) e1 exp)) ((is-a exp) (mk-a (subst-with-in x e1 (a-get-f exp)) (subst-with-in x e1 (a-get-a exp)))) ((is-l exp) ; say exp is (lam y e) (let ((y (l-get-v exp)) (e (l-get-b exp))) (cond ((equal x y) exp) ((not (free-in x e)) exp) ((and (free-in x e) (not (free-in y e1))) (mk-l y (subst-with-in x e1 e))) ((and (free-in x e) (free-in y e1)) (let ((z (freshvar))) (mk-l z (subst-with-in x e1 (subst-with-in y z e))))))))))

  13. Beta Reduction • An application whose LHS is an abstraction • An expression of the form ((λx. e1) e2) • is called redex (reducible expression) • A redex evaluates to the body of the abstraction with parameter substitution • Examples • (λx.(x y)) z →β z y • (λx. y) z →β y • (λx.x x) y →β y y • (λx.x x) (λx.x x) →β (λx.x x) (λx.x x) • Beta-reduction • (λx. e1) e2 →β[e2/x]e1

  14. Beta Reduction (defun is-rdx (e) (and (is-a e) (is-l (a-get-f e)))) (defun rdx-get-v (rdx) (l-get-v (a-get-f rdx))) (defun rdx-get-b (rdx) (l-get-b (a-get-f rdx))) (defun rdx-get-a (rdx) (a-get-a rdx)) ; Beta reduce: (a (l v e) e1) ==> [e1 / v] e (defun beta-reduce (rdx) (subst-with-in (rdx-get-v rdx) (rdx-get-a rdx) (rdx-get-b rdx))) ; Beta reduce if possible (defun beta-reduce-if-redex (e) (if (is-rdx e) (beta-reduce e) e))

  15. Properties of Beta Reduction • If e1 → β e2, then • (e e1) →β (e e2) • (e1 e) →β (e2 e) • (λx.e1) →β (λx.e2) • The transitive closure of →β • e1 →β e2 →β ... →β en • e1 reduces to en • The induced equivalence relation is denoted ≡β

  16. β-Normal Form • A λ-term is in β-normal form if it does not have any redex as subexpression • meaning: there is no way to apply beta reduction • A λ-term e has a β-normal form if for some e’ • e ≡β e’ • e’ is a β-normal form • Some λ-terms do not have any normal form: • (λx.xx)(λx.xx) →β [(λx.xx)/x]xx = (λx.xx)(λx.xx) • Intuition? • loop for ever

  17. Beta Reduction (outer) ; Iterate beta reduction on outermost redex ; (defun beta-reduce-outer (e &optional (lim 100)) (cond ((< lim 0) e) ((is-rdx e) (beta-reduce-outer (beta-reduce e) (- lim 1))) ((is-v e) e) ((is-a e) (mk-a (beta-reduce-outer (a-get-f e)) (beta-reduce-outer (a-get-a e)))) ((is-l e) (mk-l (l-get-v e) (beta-reduce-outer (l-get-b e))))))

  18. Beta Reduction (inner) ; Iterate beta reduction on inntermost redex ; (defun beta-reduce-inner (e &optional (lim 100)) (cond ((< lim 0) e) ((is-v e) e) ((is-a e) (beta-reduce-if-redex (mk-a (beta-reduce-inner (a-get-f e) lim) (beta-reduce-inner (a-get-a e) lim)))) ((is-l e) (mk-l (l-get-v e) (beta-reduce-inner (l-get-b e) lim)))))

  19. Beta Normalization (defun beta-normalize-outer (e &optional (lim 100)) (beta-normalize-param e 'beta-reduce-outer lim)) (defun beta-normalize-inner (e &optional (lim 100)) (beta-normalize-param e 'beta-reduce-inner lim)) (defun beta-normalize-param (e fn &optional (lim 100)) (let* ((res (apply fn (list e lim))) (use-alpha-equivalent t) (stop (if use-alpha-equivalent (alpha-equivalent res e) (equal res e))) (if stop res ; fix point reached (beta-normalize-param res fn))))

  20. Properties of Lambda Calculus • If e has a normal form, then this is unique (up to renaming) • The β-reduction satisfies the so-called Church-Rosser property • if e reduces to e1 and e reduces to e2 • then there exists e3 such that • e1 reduces to e3 and e2 reduces to e3 • Confluence

  21. Top level normalization ; try with the two different strategies ; and compare results ; (defun beta-normalize (e) (let ((res-inner (beta-normalize-inner e 10)) (res-outer (beta-normalize-outer e 10))) (if (alpha-equivalent res-outer res-inner) (progn (format t "All right!~%") (format t "Inner: ~A~%" res-inner) (format t "Outer: ~A~%" res-outer)) (progn (format t "Uh oh... results not equivalent!!!") (format t "Inner: ~A~%" res-inner) (format t "Outer: ~A~%" res-outer) (error "error in beta-normalize")))))

  22. Additional Remarks • no distinction between loaded code and submitted code • lisp is not case sensitive, use dashes • AGetVversus a-get-v • use comments (from ; to eol) and indentation • submit also the test cases you used to test your program • if you don’t have any, this is not a good sign... • normalization has to look for redexes on all the term, not only at top level • (x (x ((lambda y y) x))) has a redex • no need to be destructive unless clearly identified bottleneck! • no (quit) at end of file, otherwise interpreter is exited

More Related