| Paste number 52910: | lambda & combinator conversion |
| Pasted by: | faxathisia |
| When: | 4 years, 1 month ago |
| Share: | Tweet this! | http://paste.lisp.org/+14TQ |
| Channel: | #lispcafe |
| Paste contents: |
;; v ::= <variable>
(define v
(lambda (s)
(symbol? s)))
;; t ::= <v>
;; | (lambda <v> <t>)
;; | (<t> <t>)
(define lambda?
(lambda (s)
(and (= (length s) 3)
(equal? 'lambda (list-ref s 0)))))
(define lambda-var
(lambda (s)
(list-ref s 1)))
(define lambda-body
(lambda (s)
(list-ref s 2)))
(define application?
(lambda (s)
(equal? (length s) 2)))
(define t
(lambda (s)
(or (v s)
(and (lambda? s)
(v (lambda-var s))
(t (lambda-body s)))
(and (application? s)
(t (list-ref s 0))
(t (list-ref s 1))))))
;; c ::= s
;; | k
;; | (<c> <c>)
(define c
(lambda (s)
(or (equal? s 's)
(equal? s 'k)
(and (application? s)
(c (list-ref s 0))
(c (list-ref s 1))))))
;; L[I] = λx.x
;; L[K] = λx.λy.x
;; L[C] = λx.λy.λz.(x z y)
;; L[B] = λx.λy.λz.(x (y z))
;; L[S] = λx.λy.λz.(x z (y z))
;; L[(E1 E2)] = (L[E1] L[E2])
;;
;; -- http://www.angelfire.com/tx4/cus/combinator/birds.html
(define i-combinator ;; Idiot
'(lambda x
x))
(define k-combinator ;; Kestrel
'(lambda x
(lambda y
x)))
(define c-combinator ;; Cardinal
'(lambda x
(lambda y
(lambda z
((x z) y)))))
(define d-combinator ;; Dove
'(lambda x
(lambda y
(lambda z
(lambda w
((x y) (z w)))))))
(define b-combinator ;; Bluebird
'(lambda x
(lambda y
(lambda z
(x (y z))))))
(define s-combinator ;; Starling
'(lambda x
(lambda y
(lambda z
((x z) (y z))))))
(define l-convert
(lambda (s)
(cond ((equal? s 'i) i-combinator)
((equal? s 'k) k-combinator)
((equal? s 'c) c-combinator)
((equal? s 'd) d-combinator)
((equal? s 'b) b-combinator)
((equal? s 's) s-combinator)
((application? s)
(list (l-convert (list-ref s 0))
(l-convert (list-ref s 1))))
(else (error "l-convert: Invalid combinator term")))))
;; T[V] => V
;; T[(E1 E2)] => (T[E1] T[E2])
;; T[λx.E] => (K T[E]) (if x is not free in E)
;; T[λx.x] => I
;; T[λx.λy.E] => T[λx.T[λy.E]] (if x is free in E)
;; T[λx.(E1 E2)] => (S T[λx.E1] T[λx.E2])
(define free?
(lambda (v t)
(cond ((symbol? t) (equal? v t))
((lambda? t) (and (not (equal? v (lambda-var t)))
(free? v (lambda-body t))))
((application? t) (or (free? v (list-ref t 0))
(free? v (list-ref t 1)))))))
(define t-convert
(lambda (s)
(cond ((v s) s)
((= (length s) 2)
(list (t-convert (list-ref s 0))
(t-convert (list-ref s 1))))
((and (lambda? s)
(not (free? (lambda-var s)
(lambda-body s))))
`(k ,(t-convert (lambda-body s))))
((and (lambda? s)
(equal? (lambda-var s)
(lambda-body s)))
`i)
((and (lambda? s)
(lambda? (lambda-body s))
(free? (lambda-var s)
(lambda-body (lambda-body s))))
(t-convert
`(lambda ,(lambda-var s)
,(t-convert
(lambda-body s)))))
((and (lambda? s)
(application? (lambda-body s)))
`((s ,(t-convert
`(lambda ,(lambda-var s)
,(list-ref (lambda-body s) 0))))
,(t-convert
`(lambda ,(lambda-var s)
,(list-ref (lambda-body s) 1))))))))
This paste has no annotations.