translations slides

advertisement
the lambda calculus
David Walker
CS 441
the (untyped) lambda calculus
• a language of functions
e ::= x | \x.e | e1 e2
v ::= \x.e
• there are several different ways to evaluate lambda
calculus expressions
• so far, we’ve studied left-to-right, call-by-value:
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
• amazingly, despite it’s minimalism, the lambda
calculus is Turing complete and may serve as a
foundation for all computation
extending the lambda calculus
• lambda calculus with booleans:
e ::= x | true | false | test | \x.e | e1 e2
v ::= true | false | test | \x.e
e1 --> e1’
(test1)
test e1 e2 e3 --> test e1’ e2 e3
e2 --> e2’
(test2)
test v1 e2 e3 --> test v1 e2’ e3
e3 --> e3’
(test3)
test v1 v2 e3 --> test v1 v2 e3’
(test-false)
(test-true)
test true v2 v3 --> v2
test false v2 v3 --> v3
+ all the other lambda calculus rules
booleans: the translation
• from +boolean into pure :
target language
source language
values in the source language
always get translated into values
in the target language
translate(true) = \t.\f. t
translate(false) = \t.\f. f
translate(test) = \x.\y.\z. x y z
translate(x) = x
translate(\x.e) = \x.(translate(e))
translate(e1 e2) = translate(e1) translate(e2)
(b)
boolean translation
example:
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate(test true s1 s2) = (\x.\y.\z.x y z) (\x.\y.x) v1 v2
(where v1 = translate s1
and v2 = translate s2)
(b)
boolean translation
example:
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate(test true s1 s2) = (\x.\y.\z.x y z) (\x.\y.x) v1 v2
(where v1 = translate s1
and v2 = translate s2)
in the source language we have:
test true s1 s2 --> s1
(b)
boolean translation
example:
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate(test true s1 s2) = (\x.\y.\z.x y z) (\x.\y.x) v1 v2
(where v1 = translate s1
and v2 = translate s2)
in the source language we have:
test true s1 s2 --> s1
so in the target we want:
(\x.\y.\z.x y z) (\x.\y.x) v1 v2 --> v1
(b)
boolean translation
example:
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate(test true s1 s2) = (\x.\y.\z.x y z) (\x.\y.x) v1 v2
(where v1 = translate s1
and v2 = translate s2)
in the source language we have:
test true s1 s2 --> s1
so in the target we want:
(\x.\y.\z.x y z) (\x.\y.x) v1 v2 --> v1
(b)
boolean translation
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
Theorem (Translation Preserves Semantics):
If
s1 --> s2
(in the lambda calculus with booleans)
then
(translate(s1)) --> (translate(s2))
(in the pure lambda calc)
booleans
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 --> _____________
(b)
booleans
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
e1
((\x.\y.\z.x y z) (\x.\y.x)) v1) --> ___________
(app1)
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 --> _____________ v2
e1
e1’
booleans
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(b)
(\x.\y.\z.x y z) (\x.\y.x) --> ___________
(app1)
(\x.\y.\z.x y z) (\x.\y.x)) v1 --> ___________ v1
(app1)
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 --> _____________ v2
booleans
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(b)
\x.\y.\z.x y z (\x.\y.x) --> \y.\z.x y z [\x.\y.x / x]
((\x.\y.\z.x y z) (\x.\y.x)) v1) -->
v1
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 -->
(app1)
(app1)
v2
booleans
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(b)
\x.\y.\z.x y z (\x.\y.x) --> \y.\z.(\x.\y.x) y z
((\x.\y.\z.x y z) (\x.\y.x)) v1) -->
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 -->
(app1)
v1
(app1)
v2
booleans
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(b)
\x.\y.\z.x y z (\x.\y.x) --> \y.\z.(\x.\y.x) y z
(app1)
((\x.\y.\z.x y z) (\x.\y.x)) v1) --> (\y.\z.(\x.\y.x) y z) v1
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 -->
v2
(app1)
booleans
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(b)
(\x.\y.\z.x y z) (\x.\y.x) --> \y.\z.(\x.\y.x)
(app1)
((\x.\y.\z.x y z) (\x.\y.x)) v1) --> \y.\z.(\x.\y.x) v1
(((\x.\y.\z.x y z) (\x.\y.x)) v1) v2 --> \y.\z.(\x.\y.x) v1 v2
(app1)
booleans
translate(true) = \t.\f. t
translate(false) = \t.\f. f
translate(and) = \b.\c. b c (translate(false))
translate(x) = ...
translate(and true true) = (\b.\c. b c (\t.\f.f)) (\t.\f.t) (\t.\f.t)
booleans
translate(true) = \t.\f. t
translate(false) = \t.\f. f
translate(and) = \b.\c. b c (translate(false))
translate(x) = ...
translate(and true true) = (\b.\c. b c (\t.\f.f)) (\t.\f.t) (\t.\f.t)
===> wow is that ever tough to read ...
booleans
tru = \t.\f. t
fls = \t.\f. f
translate(and true true)
= a tru tru
= (\b.\c. b c fls) tru tru
a = \b.\c. b c fls
target language
expression
(ie: a and tru are
just meta-variables
I’m using to abbreviate
and make more
readable the translated
term)
booleans
tru = \t.\f. t
fls = \t.\f. f
a = \b.\c. b c fls
a tru tru
= (\b.\c. b c fls) tru tru
--> (\c.tru c fls) tru
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
booleans
tru = \t.\f. t
fls = \t.\f. f
a tru tru
= (\b.\c. b c fls) tru tru
--> (\c.tru c fls) tru
--> tru tru fls
a = \b.\c. b c fls
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
booleans
tru = \t.\f. t
fls = \t.\f. f
a tru tru
= (\b.\c. b c fls) tru tru
--> (\c.tru c fls) tru
--> tru tru fls
= (\t.\f. t) tru fls
a = \b.\c. b c fls
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
booleans
tru = \t.\f. t
fls = \t.\f. f
a tru tru
= (\b.\c. b c fls) tru tru
--> (\c.tru c fls) tru
--> tru tru fls
= (\t.\f. t) tru fls
-->(\f. tru) fls
a = \b.\c. b c fls
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
booleans
tru = \t.\f. t
fls = \t.\f. f
a tru tru
= (\b.\c. b c fls) tru tru
--> (\c.tru c fls) tru
--> tru tru fls
= (\t.\f. t) tru fls
-->(\f. tru) fls
--> tru
a = \b.\c. b c fls
(b)
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
if statements
(b)
e ::= x | v | e1 e2
| if e1 then e2 else e3
v ::= \x.e | true | false
e1 --> e1’
if e1 then e2 else e3 --> if e1’ then e2 else e3
if true then e2 else e3 --> e2
(if2)
(if3)
if false then e2 else e3 --> e3
(\x.e) v --> e [v/x]
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
(if1)
An Example
loop = (\x.x x) (\x.x x)
if (\x.x) true then \x.x else loop
--> if true then \x.x else loop
--> \x.x
booleans
• what is wrong with the following translation?
translate true = tru
translate false = fls
translate (if e1 then e2 else e3)
= test (translate e1) (translate e2) (translate e3)
translate (\x.e) = \x.(translate e)
translate (e1 e2) = (translate e1) (translate e2)
booleans
pure lambda terms:
tru = \t.\f.t
fls = \t.\f.f
tst = \x.\y.\z. x y z
• what is wrong with the following translation?
translate true = tru
translate false = fls
translate (if e1 then e2 else e3)
= tst (translate e1) (translate e2) (translate e3)
...
-- e2 and e3 will both be evaluated regardless
of whether e1 is true or false
-- the target program might not terminate
in some cases when the source program would
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
e2 --> e2’ (app2)
v e2 --> v e2’
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x)) --> tst tru (\x.x) ((\x.x x) (\x.x x))
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x)) --> tst tru (\x.x) ((\x.x x) (\x.x x))
(((\x.\y.\z. x y z) tru) (\x.x)) ((\x.x x) (\x.x x)) -->
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x)) --> tst tru (\x.x) ((\x.x x) (\x.x x))
(((\x.\y.\z. x y z) tru) (\x.x)) ((\x.x x) (\x.x x)) -->
((\y.\z. tru y z)
(\x.x)) ((\x.x x) (\x.x x)) -->
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x)) --> test tru (\x.x) ((\x.x x) (\x.x x))
(((\x.\y.\z. x y z) tru) (\x.x)) ((\x.x x) (\x.x x)) -->
((\y.\z. tru y z)
(\x.x)) ((\x.x x) (\x.x x)) -->
(( \z. tru (\x.x) z)
) ((\x.x x) (\x.x x)) -->
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x)) --> tst tru (\x.x) ((\x.x x) (\x.x x))
(((\x.\y.\z. x y z) tru) (\x.x)) ((\x.x x) (\x.x x)) -->
((\y.\z. tru y z)
(\x.x)) ((\x.x x) (\x.x x)) -->
(( \z. tru (\x.x) z)
) ((\x.x x) (\x.x x)) -->
(( \z. tru (\x.x) z)
) ((\x.x x) (\x.x x)) -->
(b)
(\x.e) v --> e [v/x]
example
e1 --> e1’
(app1)
e1 e2 --> e1’ e2
e2 --> e2’ (app2)
v e2 --> v e2’
translate (if (\x.x) true then \x.x else loop)
= tst translate((\x.x) true) (translate(\x.x)) (translate(loop))
= tst ((\x.x) tru) (\x.x) (loop)
= tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x))
tst ((\x.x) tru) (\x.x) ((\x.x x) (\x.x x)) --> tst tru (\x.x) ((\x.x x) (\x.x x))
(((\x.\y.\z. x y z) tru) (\x.x)) ((\x.x x) (\x.x x)) -->
((\y.\z. tru y z)
(\x.x)) ((\x.x x) (\x.x x)) -->
(( \z. tru (\x.x) z)
) ((\x.x x) (\x.x x)) -->
(( \z. tru (\x.x) z)
) ((\x.x x) (\x.x x)) -->
(( \z. tru (\x.x) z)
) ((\x.x x) (\x.x x)) --> ...
booleans
• we saw this translation didn’t work:
translate (if e1 then e2 else e3)
= tst (translate e1) (translate e2) (translate e3)
• we need to delay execution of e2, e3 until the
right time:
translate (true) = \x.\y.(x (\x.x))
translate (false) = \x.\y.(y (\x.x))
translate (if e1 then e2 else e3)
= (\x.\y.\z. x y z) (translate e1) (\w.translate e2) (\w.translate e3)
... other cases ...
pairs
• would like to encode the operations
– create e1 e2
– fst p
– sec p
• pairs will be functions
– when the function is used in the fst or sec
operation it should reveal its first or second
component respectively
pairs
create = \x.\y.\b. b x y
fst = \p. p tru
sec = \p. p fls
tru = \x.\y.x
fls = \x.\y.y
pairs
create = \x.\y.\b. b x y
fst = \p. p tru
sec = \p. p fls
fst (create tru fls)
= fst ((\x.\y.\b. b x y) tru fls)
tru = \x.\y.x
fls = \x.\y.y
pairs
create = \x.\y.\b. b x y
fst = \p. p tru
sec = \p. p fls
fst (create tru fls)
= fst ((\x.\y.\b. b x y) tru fls)
-->* fst (\b. b tru fls)
tru = \x.\y.x
fls = \x.\y.y
pairs
create = \x.\y.\b. b x y
fst = \p. p tru
sec = \p. p fls
fst (create tru fls)
= fst ((\x.\y.\b. b x y) tru fls)
-->* fst (\b. b tru fls)
= (\p.p tru) (\b. b tru fls)
tru = \x.\y.x
fls = \x.\y.y
pairs
create = \x.\y.\b. b x y
fst = \p. p tru
sec = \p. p fls
fst (create tru fls)
= fst ((\x.\y.\b. b x y) tru fls)
-->* fst (\b. b tru fls)
= (\p.p tru) (\b. b tru fls)
--> (\b. b tru fls) tru
tru = \x.\y.x
fls = \x.\y.y
pairs
create = \x.\y.\b. b x y
fst = \p. p tru
sec = \p. p fls
fst (create tru fls)
= fst ((\x.\y.\b. b x y) tru fls)
-->* fst (\b. b tru fls)
= (\p.p tru) (\b. b tru fls)
--> (\b. b tru fls) tru
--> tru tru fls
= (\x.\y.x) tru fls
--> (\y.tru) fls
--> tru
tru = \x.\y.x
fls = \x.\y.y
and we can go on...
•
•
•
•
•
•
numbers
arithmetic expressions (+, -, *,...)
lists, trees and datatypes
exceptions, loops, ...
...
the general trick:
– values will be functions – construct these
functions so that they return the appropriate
information when called by an operation
Download