3.(a) (NOT TRUE) == (Lx.(((IF x) FALSE) TRUE) TRUE) => (((IF TRUE) FALSE) TRUE) => (((Lc.Le1.Le2.((c e1) e2) TRUE) FALSE) TRUE) => ((Le1.Le2.((TRUE e1) e2) FALSE) TRUE) => (Le2.((TRUE FALSE e2) TRUE) => ((TRUE FALSE) TRUE) == ((Lx.Ly.x FALSE TRUE) => (Ly.FALSE TRUE) => FALSE ((OR FALSE) FALSE) == ((Lx.Ly.(((IF x) TRUE) y) FALSE) FALSE) => (((IF FALSE) TRUE) FALSE) == (((Lc.Lx.Ly.((c x) y) FALSE) TRUE) FALSE) => ((Lx.Ly.((FALSE x) y) FALSE) TRUE) => (Ly.((FALSE TRUE) y) FALSE) => ((FALSE TRUE) FALSE) == ((Lx.Ly.y TRUE) FALSE) => (Ly.y FALSE) => FALSE 3.(b) X eq Y is true when X and Y are both true, or when X and Y are both false. Therefore we have: ((OR A) B) where A is ((AND x) y) B is ((AND (NOT x)) (NOT y)) We must then define AND, as follows: AND = Lx.Ly.(((IF x) y) FALSE) Altogether we get EQ = Lx.Ly.((OR ((AND x) y) ((AND (NOT x)) (NOT y)) 3.(c) Applicative order: all occurrences of the function expression's bound variables in the function's body is replaced by the VALUE of the argument expression. Normal order: all occurrences of the function expression's bound variable are replaced with the UNEVALUATED argument expression. In applicative order we may gain an efficiency in that we may only need to evaluate an argument once, and then substitute it in many times, whereas in normal order we may then evaluate an argument expression many times. However, it can be shown that if a function application does reduce to some minimal form it is guaranteed to do so under normal order reduction, but applicative order might never reach this minimal form. The minimal form is called normal form. 3.(d) If orelse and andalso used applicative order both operands would be evaluated before the operator was applied. For example X andalso Y would require that X be evaluated, then Y evaluated, then andalso applied. Clearly, if X evaluated to FALSE then we need not evaluate Y. In the orelse case, X orelse Y, we need only evaluate Y when X evaluates to FALSE. Therefore lazy evaluation gives us a possible efficiency. However ... it is not only an efficiency, it is also an necessity. We can consider IF x THEN y as being equivalent to (not x) andalso y If we used applicative order (call by value) we would always evaluate y, and we do not want to do this.