University of Virginia, Department of Computer Science CS200: Computer Science, Spring 2003

Notes: Wednesday 16 April 2003

• Office hours: Wednesday, after class - 3:45; Thursday 10am-10:45am; Thursday 4-5pm.
• Friday, 18 April: Exam 2 out
• Wednesday, 23 April: Exam 2 Due
• 28 April (9am): Problem Set 8 Due

Lambda Calculus Review
term ::= variable | term term | ( term ) | λ variable . term

Alpha Reduction: (renaming variables)

λ y . Mα λ v . M [y |→ v]) where v does not occur in M.
We can can change the name of a lambda variable, but replacing all occurances of the variable in the body term with a new name that does not appear in the body term.

Beta Reduction: (substitution)

x . M) Nβ M [ x |→ N ]
Fixed Points

Set: unordered collection of values
Domain: structured collection of values

Function: a set of input-output pairs.

The inputs are elements of the input domain (Di) and the outputs are elements of the output domain (Do.

The function is an element of the domain DiDo

A function is completely defined if the set of intput-output pairs it defines contains one element for every element in the input domain.

Fixed Point: A fixed point of a function f: DD is an element d of D such that f d = d.

The least fixed point is the fixed point found by starting with bottom (the weakest element of D) and iteratively applying f until a value is found such that fn + 1 bottom = fn bottom. Then fn bottom is the least fixed point. If D is a function domain, bottom is the function map that is defined for no inputs.

Factorial Code
Code: fixedpoints.ss

Note that we are evaluating the definitions using the standard Scheme evaluator. This evaluator is eager, so its evaluation rules are quite different from the lambda calculus reduction rules. We cannot use the lambda caluculus definition of if, since it depends on lazy evaluation. Hence, we cheat in the code and use the underlying if special form and use true? to convert the true we defined into underlying #t. Otherwise, we can do everything with just lambda calculus.

```(define true (lambda (x) (lambda (y) x)))
(define false (lambda (x) (lambda (y) y)))

;;; Because we are using the underlying eager scheme, we
;;; can't really used this if.  Instead, we need to
;;; use the if special form instead, with true? to
;;; test for the lambda-calculus true.

(define (true? p) (eq? p true))

(define cons
(lambda (x)
(lambda (y)
(lambda (z)
((z x) y)))))

(define car (lambda (p) (p true)))
(define cdr (lambda (p) (p false)))
(define null (lambda (x) true))
(define null? (lambda (x) (x (lambda (y)
(lambda (z)
false)))))

(define zero? null?)
(define pred cdr)
(define succ (lambda (n) ((cons false) n)))

(define zero null)
(define n1 (succ zero))
(define n2 (succ n1))
(define n3 (succ n2))
(define n4 (succ n3))
(define n5 (succ n4))
(define n6 (succ n5))

(define sub
(lambda (x)
(lambda (y)
(if (true? (zero? y)) x ((sub (pred x)) (pred y))))))

(lambda (x)
(lambda (y)
(if (true? (zero? x)) y ((add (pred x)) (succ y))))))

(define mul
(lambda (x)
(lambda (y)
(if (true? (zero? x))
zero
((add y) ((mul (pred x)) y))))))

;;; Our equal? will produce strange (but non-true) results if x > y
(define equal? (lambda (x) (lambda (y) (zero? ((sub x) y)))))

(define fact
(lambda (n)
((lambda (f) ((f f) n))
(lambda (f)
(lambda (k)
(if (true? ((equal? k) n1))
n1
((mul k) ((f f) (pred k)))))))))

;;; This is just for display (so its okay to use standard Scheme primitives)
(define show-number
(lambda (n) (if (true? (zero? n)) 0 (+ 1 (show-number (pred n))))))
```