CMPSC 520: FOUNDATIONS OF PROGRAMMING LANGUAGES Administration: syllabus online: http://www.cse.psu.edu/~hannan/520 Assignments: 4-5, written, some programming Exams: None, but a final project/Assignment History of Imperative Languages (No Foundations) Functional & Logic Programming Languages (Standard ML, Scheme, Prolog, lambda Prolog, Elf) We will study: - Logical foundations of these languages including: o Lambda Calculi (Untyped, Implicitly typed, Explicitly typed, etc.) o Natural Deduction o Sequent Calculus A. Church (1932) develops lambda calculus as part of a general theory of functions and logic, intended as a foundation for mathematics. (Inconsistent) Kleene & Rosser (1935) proved that all recursive functions can be represented in the lambda calculus Turing (1937) proved that exactly the functions computable by a Turing machine can be represented in the lambda calculus Functional Programming - Representing computable functions as lambda terms Type-Free Calculus (1932) - Every expression (considered as a function) can be applied to every expression Typed Calculus (Curry 1934, Church 1940) - types assigned to lambda terms. Curry - terms are those of the type-free theory - each term has a set of possible types. - "Descriptive", Implicit Types, Standard ML Church - terms are annotated version of the type-free terms; each term has a unique type. - "Prescriptive", Explicit Types, Pascal Type-Free Lambda Calculus: Two basic operations: Application: F.A or just FA Abstraction: if M == M'[x] is an expression depending on x, then \x.M'[x] denotes the mapping x |-> M'[x] I.e., for each term x, associate the term M'[x] (\x.x^2 + 1)3 = 3^2+1 = 10 (\x.M)N = M[x:=N] (or M[N/x]) (beta) Variables: V ::= x|y|z|... Terms: Lambda ::= V|\V.Lambda|Lambda Lambda We could add constants: C ::= c|c'|... FM1..Mn stands for... \x1...xn.M stands for ... Free and Bound variables: FV(x) = {x} ... BV(x) = {} ... The abstraction \x.M binds the free occurrences of x in M. Closed/Combinator Alpha conversion/Renaming M[x/y] == \x.M = \y.(M[x/y]) Substitution: M[N/x] or M[x:=N] Conventions: Assume free and bound variables distinct. Substitution Lemma: Let M,N,L in Lambda. Assume x!=y and x not free in L. Then M[x:=N][y:=L] = M[y:=L][x:=N[y:=L]] Proof: Exercise. Beta Equality: Eta: Logical Axioms and Rules: Refl, Sym, Trans, Cong1, Cong2, Xi If M = N is provable using these rules we write \ |- M=N Do Some Examples. Representing Recursion in the \-calculus THEOREM (Fixed point theorem) 1. For all F, there exists an X such that FX = X 2. There is a fixed point combinator Y such that for all F, F(YF) = YF PROOF: 1. Define W = \x.F(xx) and X = WW. Then X = WW = (\x.F(xx))W = F(WW) = FX 2. Define Y = \f.(\x.f(xx))(\x.f(xx)) By proof of 1: note that YF = (\x.F(xx))(\x.F(xx)) = X Corollary: Given a term C =C[f.x] possible containing f and x free, then there exists F. for all X, FX =C[F,X] (C[F,X] = C[f:=F][x:=X]) Proof: We can construct F by assuming it has the required property and calculating back: for all X, FX = C[F,X] <= Fx = C[F,x] <= F = \x.C[F,x] <= F = (\f\x.C[f,x])F <= F = Y(\f\x.C[f,x]) This also holds for more arguments: exists F, all xvec, F(xvec) = C(F,xvec) Exercise: Using these results, construct terms F and G such that for all X,Y: FX = XF GXY = YG(YXG) Lambda Definability DEFINITION: 1. For F,M in Lambda, F^0(M) = M F^n+1 = F(F^n(M)) 2. The Church Numerals c0, c1, c2 are defined as cn = \f\x.f^n(x) PROPOSITION: (J. Barkley Rosser) Define A+ = \nmfy.ng(mgy) A* = \nmg.n(mg) A_exp = \nm.mn Then for all n,m in Nat, 1. A+ cn cm = c_(n+m) 2. A* cn cm = c_(n*m) 3. Aexp cn cm = c_(n^m) except for m=0 Lemma: 1. (cn x)^m(y) = x^{n*m}(y); 2. (cn)^m(x) = c_{n^m}(x), for m>0 Proof: 1. By induction on m. m=0: LHS = y = RHS Assume (1) correct for m. Then (cn x)^{m+1}(y) = cn x((cn x)^m(y)) = cn x(x^{n*m}(y)) by IH = x^n(x^{n*m}(y)) = (x^{n+n*m}(y)) = (x^{n*(m+1)}(y)) 2. By induction on m>0 m=1: then LHS = cn x = RHS Assume (2) correct for m. Then cn^{m+1}(x) = cn(cn^m(x)) = cn(c_{n^m}(x)) by IH = \y.(c_{n^m}(x))^n (y) = \y.x^{n^m * n}(y) = (\f\y.f^{n^m * n}(y)) x = c_{n^(m+1)} x Now proof of the proposition: 1. By induction on m. 2. Use the lemma (1). 3. By the lemma (2) we have for m>0 Aexp cn cm = cm cn = \x.cn^m(x) = \x.c_{n^m}x = c_{n^m} TRUTH VALUES AND CONDITIONALS: DEFINITION: 1. true = \x\y.x, false = \x\y.y 2. If B is a Boolean (ie either true or false) then if B then P else Q can be represented by BPQ. DEFINITION: For M,N in Lambda, write [M,N] = \z.zMN Then: [M,N]true = M [M,N]false = N Hence, [M,N] provides an ordered pair. DEFINITION: 1. A numeric function is a map f:N^p -> N for some p. 2. A numeric function f with p arguments is called lambda definable if for some combinator F, Fc_{n1}...c_{np} = c_{f(n1,...,np)} (*) for all n1,...,np in N. If (*) holds, then f is said to be lambda-defined by F. DEFINITION: 1. The initial function are the numeric functions U_r^i, S+, Z defined by: U_r^i(x1,...,x_r) = x_i, 1<=i<=r S+(n) = n+1 Z(n) = 0 2. Let P(n) be a numeric relation. mu m.P(m) denotes the least number m such that P(m) holds if there is such a number; otherwise undefined. DEFINITION: Given a function g of m arguments and m functions h1,...,hm, each of m arguments, the composition f o (g1,...,gm) of f and g1,...,gm is the function h of m arguments such that for all x1,...,xm in N, h(x1,...,xm) = g(h1(x1,...,xm),...hm(x1,...,xm)) DEFINITION: Given a function g of m arguments and a function h of m+2 arguments, the function f of m+1 arguments is defined by primitive recursion from f and g iff the following hold: for all x1,...,xm,y in N, f(0,x1,...,xm) = g(x1,...,xm) f(k+1,x1,...,xm) = h(f(k,x1,...,xm),k,x1,...,xm) NOTE: in the special case of n=0: f(0) = m f(k+1) = h(f(k),k) Examples: Factorial, Addition DEFINITION: Given a function g of m+1 arguments, the function f of m>0 arguments is defined by minimalization from g iff the following holds: for all x1,...,xm in N, (1) f(x1,...,xm) is defined iff there is some y in N such that g(x1,...,xm,z) is defined for all z<=y and g(x1,...,xm,y) = 0; (2) If f(x1,...,xm) is defined then f(x1,...,xm) is equal to the least y satisfying (1). I.e., f(x1,...,xm) = y iff g(x1,...,xm) = 0 and for all z0 follows similarly) So G = c_{f(0)}. Define T = \p.[S+ (p true), H (p false) (p true)] = \p.(\z.z(\n\f\x.f(nfx) (p \x\y.x)) (H (p \x\y.y) (p \x\y.x))) Then for all k one has T([c_k,c_{f(k)} = [fS+ c_k, H c_{f(k)} c_k] = [c_{k+1},c_{f(k+1)}] By induction on k it follows that [c_k,c_{f(k)}] = T^k[c_0,c_{f(0)}] Therefore, c_{f(k)} = c_k T [c_0, c_{f(0)}] false and f can be \-defined by F = \k.k T [c_0,G] false LEMMA: The \-definable functions are closed under minimalization. PROOF: Let f be defined by f(x1,..,xm) = mu k[g(x1,...xm,k)=0]. Let g be \-defined by G. Define zero = \n.n(true false)true Then zero c0 = true zero c_{n+1} = false By results from fixed points (Given a term C[f,x] there exists F. for all X, FX = C[F,X]) there exists a term H such that H x1...xm y = if (zero(G x1...xm y)) then y else H x1...xm (S+ y) Let F = \x1...\xm.H x1...xm c0. Then F \-defines f: F c_x1...c_xm = H c_x1...c_xm c0 = c0 if G c_x1...c_xm c0 = c0 = H c_x1...c_xm c1 else; = c1 if G c_x1...c_xm c1 = c0 = H c_x1...c_xm c2 else; = c2 if G c_x1...c_xm c2 = c0 ... THEOREM: All recursive functions are \-definable.