Functional Programming Through Lambda Calculus: Exercises (Chapter 3)
An Introduction to Functional Programming Through Lambda Calculus
Exercise 3.1
Define a λ calculus representation for implication:
def implies = λx.λy...Show that the definition satisfies the truth table for all boolean values of x and y.
IMPLIES is a binary operator of the form:
<operand> -> <operand>
It can be modelled using the conditional expression:
X ? Y : TRUE
So we can define IMPLIES as:
def implies = λx.λy.(((cond y) true) x)
Which simplies to:
=> λx.λy.(((λe1.λe2.λs.((s e1) e2) y) true) x)
=> λx.λy.(λs.((s y) true) x)
=> λx.λy.((x y) true)
Demonstrations
False False
=> implies false false
=> λx.λy.((x y) true) false) false
=> ((false false) true)
=> true
False True
=> implies false true
=> λx.λy.((x y) true) false) true
=> ((false true) true)
=> true
True False
=> implies true false
=> λx.λy.((x y) true) true) false
=> ((false true) false)
=> false
True True
=> implies true true
=> λx.λy.((x y) true) true) true
=> ((true true) true)
=> true
Exercise 3.2
Define a λ calculus representation for equivalance:
def equiv = λx.λy...Show that the definition satisfies the truth table for all boolean values of x and y.
EQUIV is a binary operator of the form:
<operand> ≡ <operand>
It can be modelled using the conditional expression:
NOT X ? NOT Y : Y
So we can define EQUIV as:
def equiv = λx.λy.((((not cond) (not y)) y) x)
Which simplifies to:
=> λx.λy.(((not x) (not y)) y)
Demonstrations
False False
=> equiv false false
=> λx.λy.(((not x) (not y)) y) false false
=> (((not false) (not false)) false)
=> (((λx.((x false) true) false) (λx.((x false) true) false)) false)
=> ((((false false) true) ((false false) true)) false)
=> ((true true) false)
=> true
False True
=> equiv false true
=> ...
=> (((not false) (not true)) true)
=> ((true false) false)
=> false
True False
=> equiv true false
=> ...
=> (((not true) (not false)) false)
=> ((false true) false)
=> false
True True
=> equiv true true
=> ...
=> (((not true) (not true)) true)
=> ((false false) true)
=> true
Exercise 3.3
For each of the following pairs, show that functions (i) and (ii) are equivalent for all boolean values of their arguments.
(a)
(i) λx.λy.(and (not x) (not y))
(ii) λx.λy.(not (or x y))
False False
(i)
=> (and (not false) (not false))
=> ((and true) true)
=> true
(ii)
=> (not (or false) false)
=> (not false)
=> true
This exercise is essentially just to evaluate the λ expressions so I don’t think there’s much value at this point in doing the rest.
Exercise 3.4
Show that:
λx.(succ (pred x))and:
λx.(pred (succ x))are equivalent for arbitrary non-zero integer arguments. Explain why they are not equivalent for a zero argument.
They aren’t equivalent for a zero argument because pred zero is defined as being zero instead of some representation of negative 1, since the succ and pred functions are only defined so far for the set of natural numbers.
To get the successor of the predesseor of a number is just to substract and then add 1. If the function can’t actually subtract 1 then its effect is just to add 1.
One
λx.(succ (pred x))
=> (λx.(succ (pred x)) one)
=> (succ (pred one))
=> (succ zero)
=> one
λx.(pred (succ x))
=> (λx.(pred (succ x)) one)
=> (pred (succ one))
=> (pred two)
=> one
Zero
λx.(succ (pred x))
=> (λx.(succ (pred x)) zero)
=> (succ (pred zero))
=> (succ zero)
=> one
λx.(pred (succ x))
=> (λx.(pred (succ x)) zero)
=> (pred (succ zero))
=> (pred one)
=> zero