Exercises
Exercise: exp [✭✭]
Prove that exp x (m + n) = exp x m * exp x n
, where
let rec exp x n =
if n = 0 then 1
else x * exp x (n - 1)
Proceed by induction on m
.
Exercise: fibi [✭✭✭]
Prove that forall n >= 1, fib n = fibi n (0, 1)
, where
let rec fib n =
if n = 1 then 1
else if n = 2 then 1
else fib (n - 2) + fib (n - 1)
let rec fibi n (prev, curr) =
if n = 1 then curr
else fibi (n - 1) (curr, prev + curr)
Proceed by induction on n
, rather than trying to apply the theorem
about converting recursion into iteration.
Exercise: expsq [✭✭✭]
Prove that expsq x n = exp x n
, where
let rec expsq x n =
if n = 0 then 1
else if n = 1 then x
else (if n mod 2 = 0 then 1 else x) * expsq (x * x) (n / 2)
Proceed by strong induction on n
. Function expsq
implements
exponentiation by repeated squaring, which results in more efficient
computation than exp
.
Exercise: mult [✭✭]
Prove that forall n, mult n Z = Z
by induction on n
, where:
let rec mult a b =
match a with
| Z -> Z
| S k -> plus b (mult k b)
Exercise: append nil [✭✭]
Prove that forall lst, lst @ [] = lst
by induction on lst
.
Exercise: rev dist append [✭✭✭]
Prove that reverse distributes over append, i.e., that
forall lst1 lst2, rev (lst1 @ lst2) = rev lst2 @ rev lst1
, where:
let rec rev = function
| [] -> []
| h :: t -> rev t @ [h]
(That is, of course, an inefficient implemention of rev
.) You will need
to choose which list to induct over. You will need the previous exercise
as a lemma, as well as the associativity of append
, which was proved in the
notes above.
Exercise: rev involutive [✭✭✭]
Prove that reverse is an involution, i.e., that
forall lst, rev (rev lst) = lst
.
Proceed by induction on lst
. You will need the previous exercise as a lemma.
Exercise: reflect size [✭✭✭]
Prove that forall t, size (reflect t) = size t
by induction on t
, where:
let rec size = function
| Leaf -> 0
| Node (l, v, r) -> 1 + size l + size r
Exercise: propositions [✭✭✭✭]
In propositional logic, we have propositions, negation, conjunction, disjunction, and implication. The following BNF describes propositional logic formulas:
p ::= atom
| ~ p (* negation *)
| p /\ p (* conjunction *)
| p \/ p (* disjunction *)
| p -> p (* implication *)
atom ::= <identifiers>
For example, raining /\ snowing /\ cold
is a proposition stating that it is
simultaneously raining and snowing and cold (a weather condition known
as Ithacating).
Define an OCaml type to represent the AST of propositions. Then state the induction principle for that type.
Exercise: list spec [✭✭✭]
Design an OCaml interface for lists that has nil
, cons
, append
,
and length
operations. Design the equational specification. Hint:
the equations will look strikingly like the OCaml implementations of
@
and List.length
.
Exercise: bag spec [✭✭✭✭]
A bag or multiset is like a blend of a list and a set: like a set, order does not matter; like a list, elements may occur more than once. The number of times an element occurs is its multiplicity. An element that does not occur in the bag has multiplicity 0. Here is an OCaml signature for bags:
module type Bag = sig
type 'a t
val empty : 'a t
val is_empty : 'a t -> bool
val insert : 'a -> 'a t -> 'a t
val mult : 'a -> 'a t -> int
val remove : 'a -> 'a t -> 'a t
end
Categorize the operations in the Bag
interface as generators, manipulators,
or queries. Then design an equational specification for bags. For the remove
operation, your specification should cause at most one occurrence of an element
to be removed. That is, the multiplicity of that value should decrease
by at most one.