x(1). !x(1) x.set(1) - uni koblenz-landaulaemmel/paradigms1011/resource… · programming paradigms...
TRANSCRIPT
x = 1 let x = 1 in ...
x(1).
!x(1) x.set(1)
Implementing Lambda Calculi in Prolog
Ralf Lämmel
Programming Paradigms and Formal Semantics
<1h
Resources: Some of the slides of this lecture were derived from [Järvi], with permission of the original author, by copy & paste or by selection, annotation, or rewording. [Järvi] is in turn based on [Pierce] as the underlying textbook.
[Järvi] Slides by J. Järvi: “Programming Languages”, CPSC 604 @ TAMU (2009)[Pierce] B.C. Pierce: Types and Programming Languages, MIT Press, 2002
© Ralf Lämmel, 2009-2011 unless noted otherwise
Table of contents
• Untyped NB
• Typed NB
• Untyped lambda calculus
• Applied, untyped lambda calculus
• Applied, typed lambda calculus
192
Objective: compare grammar- and rule-based formalization
with the corresponding Prolog encodings / implementation.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Syntax of NB
194
More than one syntactic category
Language NB
t ::= terms:v valueif t1 then t2 else t3 conditionalsucc t successorpred t predecessoriszero t test for zero
v ::= values:true constant truefalse constant falsenv numeric value
nv ::= numeric values:0 zero valuesucc nv successor value
54 / 58
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Syntax of NB
195
term(V) :- value(V).term(if(T1,T2,T3)) :- term(T1), term(T2), term(T3).term(succ(T)) :- term(T).term(pred(T)) :- term(T).term(iszero(T)) :- term(T).
value(true).value(false).value(NV) :- nvalue(NV).
nvalue(zero).nvalue(succ(NV)) :- nvalue(NV).
Prolog
We are faithful to the distinction of the
syntactical categories.
© Ralf Lämmel, 2009-2011 unless noted otherwise
NB: sample terms
196
Prolog
if(iszero(pred(succ(zero))),zero,succ(succ(zero))).
if(iszero(zero),iszero(succ(zero)),true).
supposed to evaluate to 0
supposed to evaluate to false
© Ralf Lämmel, 2009-2011 unless noted otherwise
Evaluation rules of NB(SOS)
197
Types for NB
Reminder NB evaluation rules
E-Iszerot → t �
iszero t → iszero t �
E-IszeroZeroiszero 0→ true
E-IszeroSucciszero (succ nv)→ false
E-Succt → t �
succ t → succ t �
E-Predt → t �
pred t → pred t �
E-PredZeropred 0→ 0
E-PredSuccpred (succ nv)→ nv
E-IfTrueif true then t2 else t3 → t2
E-IfFalseif false then t2 else t3 → t3
E-Ift1 → t �
1
if t1 then t2 else t3 → if t �1 then t2 else t3
14 / 28
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
Exercise: what happens to our
type system when we omit
the rule?
© Ralf Lämmel, 2009-2011 unless noted otherwise
Evaluation rules of NB(SOS)
198
Prolog
% eval(pred(zero),zero).eval(pred(succ(NV)),NV) :- nvalue(NV).eval(succ(T1),succ(T2)) :- eval(T1,T2).eval(pred(T1),pred(T2)) :- eval(T1,T2).eval(iszero(zero),true).eval(iszero(succ(NV)),false) :- nvalue(NV).eval(iszero(T1),iszero(T2)) :- eval(T1,T2).eval(if(true,T2,_),T2).eval(if(false,_,T3),T3).eval(if(T1,T2,T3),if(T4,T2,T3)) :- eval(T1,T4).
Disfavoredsemantics
Note: appearances of metavariables in SOS translate into tests for
values.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Reflexive, transitive closure
199
Prolog
manysteps(V,V) :- value(V).
manysteps(T1,V) :- eval(T1,T2), manysteps(T2,V).
This is like ➝* in the formal setup, and the predicate works for any language
with a binary reduction relation eval/2.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Composing everything
200
:- [...]. % Import syntax and semantics:- [...]. % Import main predicate
:- current_prolog_flag(argv,Argv), ( append(_,['--',Input],Argv), main(Input), halt; true ).
Prolog
Hence, we can invoke the language processor from the command-line prompt.
© Ralf Lämmel, 2009-2011 unless noted otherwise 201
Prolog
main(Input) :- see(Input), read(Term), seen, format('Input term: ~w~n',[Term]), manysteps(Term,X), show(X,Y), format('Value of term: ~w~n',[Y]).
show(zero,0) :- !.show(succ(X),Z) :- !, show(X,Y), Z is Y + 1.show(X,X).
© Ralf Lämmel, 2009-2011 unless noted otherwise
Running the NB interpreter
202
$ swipl -q -f main.pro -- ../samples/sample1.nb Input term: if(iszero(pred(succ(zero))),zero,succ(succ(zero)))Value of term: 0$
© Ralf Lämmel, 2009-2011 unless noted otherwise
Types in NB
204
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.Types for NB
NB typing rules
First, we need a few new syntactic formsT ::= types:
Bool the Boolean typeNat the type of numeric values
And typing rules:
T-Truetrue : Bool
T-Falsefalse : Bool
T-Ift1 : Bool t2 : T t3 : Tif t1 then t2 else t3 : T
T-Zero0 : Nat
T-Succt : Nat
succ t : Nat
T-Predt : Nat
pred t : Nat
T-Iszerot : Nat
iszero t : Bool
15 / 28
© Ralf Lämmel, 2009-2011 unless noted otherwise
NB typing rules
205
Types for NB
NB typing rules
First, we need a few new syntactic formsT ::= types:
Bool the Boolean typeNat the type of numeric values
And typing rules:
T-Truetrue : Bool
T-Falsefalse : Bool
T-Ift1 : Bool t2 : T t3 : Tif t1 then t2 else t3 : T
T-Zero0 : Nat
T-Succt : Nat
succ t : Nat
T-Predt : Nat
pred t : Nat
T-Iszerot : Nat
iszero t : Bool
15 / 28
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
© Ralf Lämmel, 2009-2011 unless noted otherwise
NB typing rules
206
Prolog
welltyped(true,bool).welltyped(false,bool).welltyped(zero,nat).welltyped(succ(T),nat) :- welltyped(T,nat).welltyped(pred(T),nat) :- welltyped(T,nat).welltyped(iszero(T),bool) :- welltyped(T,nat).welltyped(if(T1,T2,T3),T) :- welltyped(T1,bool), welltyped(T2,T), welltyped(T3,T).
1:1 mapping
© Ralf Lämmel, 2009-2011 unless noted otherwise
Conditional evaluationfor typed NB
207
main(Input) :- see(Input), read(Term), seen, format('Input term: ~w~n',[Term]), welltyped(Term, Type), format('Type of term: ~w~n',[Type]), manysteps(Term,X), show(X,Y), format('Value of term: ~w~n',[Y]).
Prolog
© Ralf Lämmel, 2009-2011 unless noted otherwise
Formalization of the lambda calculus
• Syntax
• Evaluation
209
Summarizing
Summarizing the system
The grammar and (small-step) operational semantics oflambda-calculus
Syntax
t ::=xλx .tt t
v ::=λx .t
Evaluation rules (call-by-name)
t1 → t1�
t1 t2 → t1� t2
t → t �
v t → v t �
(λx .t) v → [v/x ]t
→ is the smallest binary relation onterms satisfying the rules
34 / 36
Summarizing
Summarizing the system
The grammar and (small-step) operational semantics oflambda-calculus
Syntax
t ::=xλx .tt t
v ::=λx .t
Evaluation rules (call-by-name)
t1 → t1�
t1 t2 → t1� t2
t → t �
v t → v t �
(λx .t) v → [v/x ]t
→ is the smallest binary relation onterms satisfying the rules
34 / 36
Summarizing
Summarizing the system
The grammar and (small-step) operational semantics oflambda-calculus
Syntax
t ::=xλx .tt t
v ::=λx .t
Evaluation rules (call-by-name)
t1 → t1�
t1 t2 → t1� t2
t → t �
v t → v t �
(λx .t) v → [v/x ]t
→ is the smallest binary relation onterms satisfying the rules
34 / 36
Terms
Values (normal forms)
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Syntax of the untyped lambda calculus
210
Prolog
term(var(X)) :- variable(X).term(app(T1,T2)) :- term(T1), term(T2).term(lam(X,T)) :- variable(X), term(T).
value(lam(X,T)) :- variable(X), term(T).
variable(X) :- atom(X).Variables are Prolog atoms.
© Ralf Lämmel, 2009-2011 unless noted otherwise
λ: sample term
211
Prolog
app(app(app( % TEST (if-then-else) lam(l,lam(m,lam(n,app(app(var(l),var(m)),var(n))))), % Church Boolean True lam(t,lam(f,var(t)))), % Church Numeral 0 lam(s,lam(z,var(z)))), % Church Numeral 1 lam(s,lam(z,app(var(s),var(z))))).
We illustrate Church Booleans and numerals. That is, we use a conditional (TEST) to select
either C0 or C1.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Evaluation rules of the untyped lambda calculus
212
Prolog
eval(app(T1,T2),app(T3,T2)) :- eval(T1,T3).
eval(app(V,T1),app(V,T2)) :- value(V), eval(T1,T2).
eval(app(lam(X,T1),V),T2) :- value(V), substitute(V,X,T1,T2).
Substitution (as needed for beta reduction) is the
interesting part--both in the formal setting. and in Prolog.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Substitution
213
Introduction
Inductive definition of substitution in λ calculus
[N/x ]x = N[N/x ]y = y , y any variable different from x[N/x ](M1 M2) = ([N/x ]M1) ([N/x ]M2)
[N/x ](λx .M) = λx .M[N/x ](λy .M) = λy .([N/x ]M), y not free in N
Alpha renaming can be applied freely, variables drawn from the infinitepool of variable namesExamples:
[z/x ]x[z/x ](λx .x x)
[z/x ](λy .y x)
[z/x ](λz .x z)
12 / 36
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
Introduction
Variable binding — precise definition
FV(M) defines the set of free variables in the term M
FV(x) = {x}FV(MN) = FV(M) ∪ FV(N)
FV(λx .M) = FV(M) \ {x}
Spot free and bound occurrences here:
(λx .y)(λy .y)
λx .(λy .x y)y
Combinator — a term with no free variables (also closed term)9 / 36
© Ralf Lämmel, 2009-2011 unless noted otherwise
Substitution 1/3
214
Prolog
substitute(N,X,var(X),N).
substitute(_,X,var(Y),var(Y)) :- \+ X == Y.
substitute(N,X,app(M1,M2),app(M3,M4)) :- substitute(N,X,M1,M3), substitute(N,X,M2,M4).
substitute(_,X,lam(X,M),lam(X,M)).
The simple cases
© Ralf Lämmel, 2009-2011 unless noted otherwise
Substitution 2/3
215
Prolog
substitute(N,X,lam(Y,M1),lam(Y,M2)) :- \+ X == Y, freevars(N,Xs), \+ member(Y,Xs), substitute(N,X,M1,M2).
Push down substitution into the body of the lambda abstraction if
its bound variable Y does not occur freely in the target
expression N.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Substitution 3/3
216
Prolog
substitute(N,X,lam(Y,M1),lam(Z,M3)) :- \+ X == Y, freevars(N,Xs), member(Y,Xs), freshvar(Xs,Z), substitute(var(Z),Y,M1,M2), substitute(N,X,M2,M3).
If Y occurs freely in N, then we need to perform alpha
conversion for Y. Hence, we find a fresh variable and
convert the body M1 before we continue with the original
substitution.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Free variables
217
Prolog
freshvar(Xs,X) :- freshvar(Xs,X,0).
freshvar(Xs,N,N) :- \+ member(N,Xs).
freshvar(Xs,X,N1) :- member(N1,Xs), N2 is N1 + 1, freshvar(Xs,X,N2).
We use numbers as generated variables. We find the smallest number X that is not in Xs.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Syntax of the applied, untyped lambda calculus
219
Prolog
:- multifile term/1.:- ['../untyped/term.pro'].:- ['../../nb/untyped/term.pro'].
:- multifile value/1.:- ['../untyped/value.pro'].:- ['../../nb/untyped/value.pro'].
We merge the syntax of NB and lambda calculus. In this manner, we get an applied
lambda calculus (with all the applied bits of NB).
© Ralf Lämmel, 2009-2011 unless noted otherwise
λ: sample term
220
Prolog
app(app( % Twice function lam(f,lam(x,app(var(f),app(var(f),var(x))))), % Increment function lam(x,succ(var(x)))), % 2 succ(succ(zero))).
evaluates to 4
© Ralf Lämmel, 2009-2011 unless noted otherwise
λ: sample term
221
Prolog
app(app(
% CBV fixed point combinator lam(f,app( lam(x,app(var(f),lam(y,app(app(var(x),var(x)),var(y))))), lam(x,app(var(f),lam(y,app(app(var(x),var(x)),var(y))))))),
% iseven lam(e,lam(x,if( iszero(var(x)), true, if( iszero(pred(var(x))), false, app(var(e),pred(pred(var(x))))))))),
% Argument to be tested succ(succ(succ(zero)))
).
We construct the recursive iseven function and apply it to 3.
evaluates to false
© Ralf Lämmel, 2009-2011 unless noted otherwise
Evaluation rulesthe applied, untyped lambda calculus
222
Prolog
:- multifile eval/2.:- multifile substitute/4.:- multifile freevars/2.:- ['../untyped/eval.pro'].:- ['../../nb/untyped/eval.pro'].:- ['substitute.pro'].:- ['freevars.pro'].
Essentially, we merge the evaluation rules for NB and the untyped lambda calculus. However, we also need to
upgrade substitution to cope with NB’s construct.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Substitution for applied part
223
Prolog
substitute(_,_,true,true).substitute(_,_,false,false).substitute(_,_,zero,zero).substitute(N,X,succ(T1),succ(T2)) :- substitute(N,X,T1,T2).substitute(N,X,pred(T1),pred(T2)) :- substitute(N,X,T1,T2).substitute(N,X,iszero(T1),iszero(T2)) :- substitute(N,X,T1,T2).substitute(N,X,if(T1a,T2a,T3a),if(T1b,T2b,T3b)) :- substitute(N,X,T1a,T1b), substitute(N,X,T2a,T2b), substitute(N,X,T3a,T3b).
This is all trivial code. We simply push substitution
into NB’s terms.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Free variables for applied part
224
Prolog
freevars(true,[]).freevars(false,[]).freevars(zero,[]).freevars(succ(T),FV) :- freevars(T,FV).freevars(pred(T),FV) :- freevars(T,FV).freevars(iszero(T),FV) :- freevars(T,FV).freevars(if(T1,T2,T3),FV) :- freevars(T1,FV1), freevars(T2,FV2), freevars(T3,FV3), union(FV1,FV2,FV12), union(FV12,FV3,FV).
This is all trivial code. We simply traverse (and
union) over NB’s terms.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Revised syntax
• Lambda abstractions are annotated with types:
λx : T.t
• Grammar of types:
T ::= bool
nat
T→T
226
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
© Ralf Lämmel, 2009-2011 unless noted otherwise 227
:- ['../applied/term.pro'].:- ['../applied/value.pro'].
term(lam(X,A,T)) :- variable(X), type(A), term(T).term(fix(T)) :- term(T).
value(lam(X,A,T)) :- variable(X), type(A), term(T).
type(bool).type(nat).type(fun(A1,A2)) :- type(A1), type(A2).
The untyped version is no longer to be used.
Prolog
Build on top of untyped applied lambda calculus.
Revised syntax
© Ralf Lämmel, 2009-2011 unless noted otherwise
Typing rules for simply-typed lambda calculus
228
Adding types to lambda-calculus
Typing rules for simply-typed lambda calculus
x , y , z , f , g range over variabless, t, u range over termsS , T , U range over types
T-Variablex : T ∈ Γ
Γ � x : T
T-AbstractionΓ, x : T � u : U
Γ � λx : T .u : T → U
T-ApplicationΓ � t : U → T Γ � u : U
Γ � t u : T
11 / 42
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
© Ralf Lämmel, 2009-2011 unless noted otherwise 229
Prolog
:- ensure_loaded('../../shared/map.pro').
welltyped(G,var(X),A) :- member((X,A),G).
welltyped(G,app(T1,T2),B) :- welltyped(G,T1,fun(A,B)), welltyped(G,T2,A).
welltyped(G1,lam(X,A,T),fun(A,B)) :- update(G1,X,A,G2), welltyped(G2,T,B).
Typing rules for simply-typed lambda calculus
© Ralf Lämmel, 2009-2011 unless noted otherwise
Lifted typing rules of NB
230
Prolog
welltyped(T,A) :- welltyped([],T,A).
welltyped(_,true,bool).welltyped(_,false,bool).welltyped(_,zero,nat).welltyped(G,succ(T),nat) :- welltyped(G,T,nat).welltyped(G,pred(T),nat) :- welltyped(G,T,nat).welltyped(G,iszero(T),bool) :- welltyped(G,T,nat).welltyped(G,if(T1,T2,T3),T) :- welltyped(G,T1,bool), welltyped(G,T2,T), welltyped(G,T3,T).
We had to rewrite the typing rules for NB to incorporate the
typing context.
© Ralf Lämmel, 2009-2011 unless noted otherwise
Small-step semantics
231
Adding types to lambda-calculus
Evaluation rules
Syntax
t ::=x | v | t tv ::=λx :T .t | true | falseT ::=bool|T �T
t = terms, v = value, T = type
Evaluation rules
t1 → t1�
t1 t2 → t1� t2
t → t �
v t → v t �
(λx :T .t) v → [v/x ]t
→ is the smallest binary relationon terms satisfying the rules
Note again that evaluation rules do not bother with types!Type checker’s task to reject programs that try to apply rules formeaningless typesThis corresponds (to some extent) to language implementations
14 / 42
Types play no role in the semantics.
© Ralf Lämmel, 2009-2011 unless noted otherwise
:- ['../applied/eval.pro'].
eval(lam(X,_,T),lam(X,T)).substitute(N,X,lam(Y,_,M),T) :- substitute(N,X,lam(Y,M),T).freevars(lam(X,_,M),FV) :- freevars(lam(X,M),FV).
Update on evaluation rules
232
“Type erasure” for lambdas
Prolog
Build on top of untyped applied lambda calculus.
© Ralf Lämmel, 2009-2011 unless noted otherwise
The fix construct
233
Syntax fix.
t ::= ... | fix t
Aside: general recursion
The fix operator
We discussed the fix point operator (Y-combinator, fix), and showedits definition in untyped lambda calculusJust like self-application, fix cannot be typed in simply-typed lambdacalculusSimple fix: add fix as a primitive
fix (λx : T .t)→ [(fix (λx : T .t))/x ] t
t → t �
fix t → fix t �
Γ � t : T → TΓ � fix t : T
16 / 50
Typing rule
Aside: general recursion
The fix operator
We discussed the fix point operator (Y-combinator, fix), and showedits definition in untyped lambda calculusJust like self-application, fix cannot be typed in simply-typed lambdacalculusSimple fix: add fix as a primitive
fix (λx : T .t)→ [(fix (λx : T .t))/x ] t
t → t �
fix t → fix t �
Γ � t : T → TΓ � fix t : T
16 / 50
Aside: general recursion
The fix operator
We discussed the fix point operator (Y-combinator, fix), and showedits definition in untyped lambda calculusJust like self-application, fix cannot be typed in simply-typed lambdacalculusSimple fix: add fix as a primitive
fix (λx : T .t)→ [(fix (λx : T .t))/x ] t
t → t �
fix t → fix t �
Γ � t : T → TΓ � fix t : T
16 / 50
Evaluation rules
This slide is derived from Jaakko Järvi’s slides for his course ”Programming Languages”, CPSC 604 @ TAMU.
Since fixed point combinators are not typeable in this calculus, we
need fix instead.
© Ralf Lämmel, 2009-2011 unless noted otherwise 234
The fix constructProlog
welltyped(G,fix(T),A) :- welltyped(G,T,fun(A,A)).
Typing rule
Evaluation rules
eval(fix(T1),fix(T2)) :- eval(T1,T2).eval(fix(lam(X,T1)),T2) :- substitute(fix(lam(X,T1)),X,T1,T2).substitute(N,X,fix(T1),fix(T2)) :- substitute(N,X,T1,T2).freevars(fix(T),FV) :- freevars(T,FV).
© Ralf Lämmel, 2009-2011 unless noted otherwise
• Summary: Prolog likes Lambdas.✦ Evaluation rules are easily implemented.✦ Typing rules, ditto.✦ Language composition and extension works fine.
• Prepping: See the 3 lectures on λ-calculi.• Lab: λ-calculi in Prolog• Outlook:
✦ Another domain for calculi: distribution.✦ Functional programming with Haskell.
235