(define (reduce-once E)
  (cond ((not (pair? E)) #f)
	((lambda-expression? E) #f)
	((lambda-expression? (operator E))
	 (subst (operand E)
		(argument (operator E))
		(body (operator E))))
	(else
	 (let ((reduced-operator
		(reduce-once (operator E))))
	   (if reduced-operator
	       `(,reduced-operator ,(operand E))
	       (let ((reduced-operand 
		      (reduce-once (operand E))))
		 (if reduced-operand
		     `(,(operator E) ,reduced-operand)
		     #f)))))))
(define (reduce E)
  (let ((reduced-expression (reduce-once E)))
    (if reduced-expression
	(reduce reduced-expression)
	E)))
(define (lambda-expression? E)
  (and (pair? E)
       (eq? (type E) 'lambda)))
(define (free? x E)
  (cond ((null? E) #t)
	((pair? E)
	 (if (eq? (type E) 'lambda)
	     (if (eq? (argument E) x)
		 #f
		 (free? x (body E)))
	     (or (free? x (operator E))
		 (free? x (operand E)))))
	(else
	 (eq? E x))))
(define (subst M x E)
  (cond ((eq? E x) M)
	((not (pair? E)) E)
	((lambda-expression? E)
	 (let ((y (argument E))
	       (E* (body E)))
	   (if (or (eq? x y) (not (free? x E*)))
	       E
	       (if (not (free? y M))
		 `(lambda (,y) ,(subst M x E*))
		 (let ((z (gensym)))
		   `(lambda (,z)
		      ,(subst M x (subst z y E*))))))))
	(else
	 (list (subst M x (operator E))
	       (subst M x (operand E))))))
(define operator car)
(define operand cadr)
(define type car)
(define argument caadr)
(define body caddr)
(define true
  `(lambda (x)
     (lambda (y)
       x)))
(define false
  `(lambda (x)
     (lambda (y)
       y)))
(define kons
  `(lambda (x)
     (lambda (y)
       (lambda (f)
	 ((f x) y)))))
(define kar
  `(lambda (f)
     (f ,true)))
(define kdr
  `(lambda (f)
     (f ,false)))
(define nil
  `(lambda (x) ,true))
(define nil?
  `(lambda (f)
     (f (lambda (x)
	  (lambda (y)
	    ,false)))))
(define (lambda->sexpr E)
  (cond ((symbol? E) E)
	((zero? (reduce `(((,nil? ,E) 0) 1))) ())
	(else
	 (cons (lambda->sexpr (reduce `(,kar ,E)))
	       (lambda->sexpr (reduce `(,kdr ,E)))))))
(define succ
  `(lambda (x)
     ((,kons x) ,nil)))
(define pred kar)
(define (number->lambda n)
  (if (= n 0)
      nil
      `(,succ ,(number->lambda (- n 1)))))
(define (lambda->number E)
  (if (zero? (reduce `(((,nil? ,E) 0) 1)))
      0
      (+ 1 (lambda->number (reduce `(,pred ,E))))))
;; (u)
(define foo
  `((,kons u) ,nil))
;; (u v w)
(define bar
  `((,kons u) ((,kons v) ((,kons w) ,nil))))
(define f
  `(lambda (f)
     (lambda (x)
       (((,nil? x) ,nil) ((,kons (,kar x)) (f (,kdr x)))))))
;; An expression which can copy nil...
;; (lambda->sexpr (reduce `((,f ,what!?) ,nil))) => ()
;; `((,f ,what!?) ,nil) =>
;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) ,nil) =>
;; `(((,nil? ,nil) ,nil) ((,kons (,kar ,nil)) (,what!? (,kdr ,nil)))) =>
;; `((,true ,nil) ((,kons (,kar ,nil)) (,what!? (,kdr ,nil)))) =>
;; ,nil
;; but fails on lists of length 1 or greater.
;; (lambda->sexpr (reduce `(,(,f ,what!?) ,foo))) =>  What!? No PeZ!
;; `((,f ,what!?) ,foo) =>
;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) ,foo) =>
;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) (,what!? (,kdr ,foo)))) =>
;; `((,false ,nil) ((,kons (,kar ,foo)) (,what!? (,kdr ,foo)))) =>
;; `((,kons (,kar ,foo)) (,what!? (,kdr ,foo))) =>  What!? No PeZ!
 ;; An expression which can copy lists of length 1...
;; (lambda->sexpr (reduce `(,f (,f ,what!?)) ,foo)) => (u)
;; `((,f (,f ,what!?)) ,foo) =>
;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) ((,f ,what!?) (,kdr x))))) ,foo) =>
;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo)))) =>
;; `((,false ,nil) ((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo)))) =>
;; `((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo))) =>
;; `((,kons u) ((,f ,what!?) (,kdr ,foo))) =>
;; `((,kons u) ((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) (,kdr foo)) =>
;; `((,kons u) (((,nil? (,kdr foo)) ,nil) ((,kons (,kar (,kdr foo))) (,what!? (,kdr (,kdr foo))))) =>
;; `((,kons u) ((,true ,nil) ((,kons (,kar (,kdr foo))) (,what!? (,kdr (,kdr foo))))) =>
;;  ((,kons u) ,nil)
;; but fails on lists of length 2 or greater.
;; (lambda->sexpr (reduce `(,f (,f ,what!?)) ,bar)) => What!? No PeZ!
;; An expression which can copy lists of length 3 or less.
;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,nil))) => ()
;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,foo))) => (u)
;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,bar))) => (u v w)
;; An expression which can copy lists of length 1...
;; (lambda->sexpr (reduce `(,f (,f ,what!?)) ,foo)) => (u)
;; `((,f (,f ,what!?)) ,foo) =>
;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) ((,f ,what!?) (,kdr x))))) ,foo) =>
;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo)))) =>
;; `((,false ,nil) ((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo)))) =>
;; `((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo))) =>
;; `((,kons u) ((,f ,what!?) (,kdr ,foo))) =>
;; `((,kons u) ((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) (,kdr foo)) =>
;; `((,kons u) (((,nil? (,kdr foo)) ,nil) ((,kons (,kar (,kdr foo))) (,what!? (,kdr (,kdr foo))))) =>
;; `((,kons u) ((,true ,nil) ((,kons (,kar (,kdr foo))) (,what!? (,kdr (,kdr foo))))) =>
;;  ((,kons u) ,nil)
;; but fails on lists of length 2 or greater.
;; (lambda->sexpr (reduce `(,f (,f ,what!?)) ,bar)) => What!? No PeZ!
;; An expression which can copy lists of length 3 or less.
;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,nil))) => ()
;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,foo))) => (u)
;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,bar))) => (u v w)
 ;; An expression of infinite length which can copy any list.
;; `(,f ...(,f (,f (,f ,what!?)))...)
;; Let there be Y...
(define Y
  '(lambda (f)
     ((lambda (g) (f (g g)))
      (lambda (g) (f (g g))))))
;; Reducing (,Y ,f) once...
;; `(,Y ,f) => `((lambda (g) (,f (g g))) (lambda (g) (,f (g g))))
;; Let's give this expression a name...
(define pez `((lambda (g) (,f (g g))) (lambda (g) (,f (g g)))))
;; An expression of infinite length which can copy any list.
;; `(,f ...(,f (,f (,f ,what!?)))...)
;; Let there be Y...
(define Y
  '(lambda (f)
     ((lambda (g) (f (g g)))
      (lambda (g) (f (g g))))))
;; Reducing (,Y ,f) once...
;; `(,Y ,f) => `((lambda (g) (,f (g g))) (lambda (g) (,f (g g))))
;; Let's give this expression a name...
(define pez `((lambda (g) (,f (g g))) (lambda (g) (,f (g g)))))
 ;; Reducing pez yields...
;; pez =
;; `((lambda (g) (,f (g g))) (lambda (g) (,f (g g)))) =>
;; `(,f ((lambda (g) (,f (g g))) (lambda (g) (,f (g g))))) =
;; `(,f ,pez) =>
;; `(lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x)))))
;; Note: Because pez => `(,f ,pez) it is called a "fixed-point" of f.
;; Let's see how (,Y ,f) copies a list of length 1...
;; `((,Y ,f) ,foo) =>
;; `(,pez ,foo) =>
;; Pez! Give me an f!
;; `((,f ,pez) ,foo) =>
;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) ,foo) =>
;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) (,pez (,kdr ,foo)))) =>
;; `((,false ,nil) ((,kons (,kar ,foo)) (,pez (,kdr ,foo)))) =>
;; `((,kons (,kar ,foo)) (,pez (,kdr ,foo))) =>
;; `((,kons u) (,pez (,kdr ,foo))) => 
;; Pez! Give me an f!
;; `((,kons u) ((,f ,pez) (,kdr ,foo))) => 
;; `((,kons u) ((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) (,kdr ,foo)) =>
;; `((,kons u) (((,nil? (,kdr foo)) ,nil) ((,kons (,kar (,kdr ,foo))) (,pez (,kdr (,kdr ,foo)))))) =>
;; `((,kons u) ((,true ,nil) ((,kons (,kar (,kdr ,foo))) (,pez (,kdr (,kdr ,foo)))))) =>
;; `((,kons u) ,nil)
;; It follows that (,Y ,f) is an expression of finite length which can copy any list!!
;; (lambda->sexpr (reduce `((,Y ,f) ,bar))) => (u v w)
(define plus
  `(lambda (x)
     (,Y (lambda (f)
	   (lambda (y)
 	     (((,nil? y) x) (,succ (f (,pred y)))))))))
(define times
  `(lambda (x)
     (,Y (lambda (f)
	   (lambda (y)
	     (((,nil? (,pred y)) x) ((,plus x) (f (,pred y)))))))))
;; Reducing pez yields...
;; pez =
;; `((lambda (g) (,f (g g))) (lambda (g) (,f (g g)))) =>
;; `(,f ((lambda (g) (,f (g g))) (lambda (g) (,f (g g))))) =
;; `(,f ,pez) =>
;; `(lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x)))))
;; Note: Because pez => `(,f ,pez) it is called a "fixed-point" of f.
;; Let's see how (,Y ,f) copies a list of length 1...
;; `((,Y ,f) ,foo) =>
;; `(,pez ,foo) =>
;; Pez! Give me an f!
;; `((,f ,pez) ,foo) =>
;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) ,foo) =>
;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) (,pez (,kdr ,foo)))) =>
;; `((,false ,nil) ((,kons (,kar ,foo)) (,pez (,kdr ,foo)))) =>
;; `((,kons (,kar ,foo)) (,pez (,kdr ,foo))) =>
;; `((,kons u) (,pez (,kdr ,foo))) => 
;; Pez! Give me an f!
;; `((,kons u) ((,f ,pez) (,kdr ,foo))) => 
;; `((,kons u) ((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) (,kdr ,foo)) =>
;; `((,kons u) (((,nil? (,kdr foo)) ,nil) ((,kons (,kar (,kdr ,foo))) (,pez (,kdr (,kdr ,foo)))))) =>
;; `((,kons u) ((,true ,nil) ((,kons (,kar (,kdr ,foo))) (,pez (,kdr (,kdr ,foo)))))) =>
;; `((,kons u) ,nil)
;; It follows that (,Y ,f) is an expression of finite length which can copy any list!!
;; (lambda->sexpr (reduce `((,Y ,f) ,bar))) => (u v w)
(define plus
  `(lambda (x)
     (,Y (lambda (f)
	   (lambda (y)
 	     (((,nil? y) x) (,succ (f (,pred y)))))))))
(define times
  `(lambda (x)
     (,Y (lambda (f)
	   (lambda (y)
	     (((,nil? (,pred y)) x) ((,plus x) (f (,pred y)))))))))