#Experiments in lambda calculus #SET UP ident = lambda x:x #Booleans true = lambda x:lambda y:x false = lambda x:lambda y:y And = lambda x:lambda y:x(y)(x) #Church Numerals zero = lambda x: lambda y:y one = lambda x: lambda y:x(y) two = lambda x: lambda y:x(x(y)) #Note not our usual order! three = lambda x: lambda y:x(x(x(y))) succ = lambda x: lambda y: lambda z:y(x(y)(z)) #Pairing pair = lambda x: lambda y: lambda z: z(x)(y) first = lambda x:x(true) second = lambda x: x(false) #Arithmetic add = lambda m: lambda n:lambda u: lambda v:m(u)(n(u)(v)) #TESTS #Testing helpers. In Python we cannot reduce lambda expressions to #some normal form, so to test that we are getting the right thing, #we will apply them to some arguments so as to get a result that is #a Python boolean, or a Python int, or a Python tuple. #Note that these next two functions are not pure lambda calculus! inc = lambda x:x+1 tuplize = lambda x: lambda y: (x,y) #To test something that should give a boolean result, apply it to #(True)(False). For instance, here is how we test that Not(true) is false #and Not(false) is true. print( Not(true)(True)(False)) print( Not(false)(True)(False)) #To test something that should give a numeral as a result, apply it to #(inc)(0) For example, here is how we test that three is the right thing-- #It should print 3. (It does) print(three(inc)(0)) #To test something that should return a pair, apply it to tuplize.__ print(pair(3)(4)(tuplize)) #test addition print (add(three)(two)(inc)(0)) print (add(three)(zero)(inc)(0)) print (multiply(three)(two)(inc)(0)) print (multiply(three)(succ(three))(inc)(0)) print (multiply(three)(zero)(inc)(0)) #test factorial print (factorial(zero)(inc)(0)) print (factorial(one)(inc)(0)) print (factorial(two)(inc)(0)) print (factorial(three)(inc)(0)) print (factorial(succ(three))(inc)(0))