(* Code for Lecture 3: Recursion and Induction *) (* Author: Frank Pfenning *) (* power1 (n,k) = n^k for k >= 0 where 0^0 = 1 *) fun power1 (n:int, k:int) = if k = 0 then 1 else n * power1 (n, k-1); (* square (n) = n^2 for integers n *) fun square (n:int) = n * n; (* power2 (n,k) = n^k for k >= 0 where 0^0 = 1 *) fun power2 (n:int, k:int) = if k = 0 then 1 else if k mod 2 = 0 then square(power2(n, k div 2)) else n * square(power2(n, k div 2)); (* fib1 (n) = f_n, the nth Fibonacci number, n >= 0 *) (* This definition requires fib(n) calls to compute fib1(n) *) fun fib1 (n:int) = if n = 0 then 1 else if n = 1 then 1 else fib1(n-1) + fib1(n-2); (* fibb (n) = (f_n, f_(n-1)), n >= 1 *) (* This definition requires only n calls to compute fibb(n) *) fun fibb (1) = (1, 1) | fibb (n) = let val (f_1, f_2) = fibb (n-1) in (f_1 + f_2, f_1) end; (* fst : 'a * 'b -> 'a *) fun fst (x,y) = x; (* fib2 (n) = nth Fibonacci number, n >= 0 *) fun fib2 (n) = if n = 0 then 1 else fst (fibb (n)); (* Following definition relies on reals, which is dangerous because of rounding errors. Do not rely on this function! *) fun fib3 (n:int) = Real.round ((Math.pow((1.0+Math.sqrt(5.0))/2.0, real(n+1)) - Math.pow((1.0-Math.sqrt(5.0))/2.0, real(n+1))) / Math.sqrt(5.0));