Discrete Mathematics for Computer Scientists -- Exercises Week 6 - Structural InductionDIT980, HT 2015
Home | Schedule | Assignments | Exercises | Exam | AboutFire | Forum | TimeEdit | Links | 2014
Exercises Week 6 - Structural Induction - Answers

Here are some answers for the exercises.


Exercises

1. To prove: x `elem` (xs ++ ys) = (x `elem` xs) || (x `elem` ys), for all x,xs,ys.

Proof: by structural induction over xs.

base case: xs = [].

    x `elem` (xs ++ ys)        

= x `elem` ([] ++ ys)       -- xs = []

= x `elem` ys       -- defn. ++

= False || x `elem` ys       -- defn. ||

= (x `elem` []) || x `elem` ys       -- defn. elem

= (x `elem` xs) || x `elem` ys       -- xs = []

step case: xs = a:as.

1. I.H.: x `elem` (as ++ ys) = (x `elem` as) || (x `elem` ys), for all x,ys

2. Look at the following:

    x `elem` (xs ++ ys)        

= x `elem` ((a:as) ++ ys)       -- xs = a:as

= x `elem` (a : (as ++ ys)       -- defn. ++

= x == a || (x `elem` (as ++ ys))       -- defn. elem

= x == a || ((x `elem` as) || (x `elem` ys))       -- I.H.

= (x == a || (x `elem` as)) || (x `elem` ys)       -- || is associative

= (x `elem` (a:as)) || (x `elem` ys)       -- defn. elem

= (x `elem` xs) || (x `elem` ys)       -- xs = a:as

Which is what we had to prove.


2. To prove: length (rev xs) = length xs, for all xs.

Proof: by structural induction over xs.

base case: xs = [].

    length (rev xs)        

= length (rev [])       -- xs = []

= length []       -- defn. rev

= length xs       -- xs = []

step case: xs = a:as.

1. I.H.: length (rev as) = length as

2. Look at the following:

    length (rev xs)        

= length (rev (a:as))       -- xs = a:as

= length (rev as ++ [a])       -- defn. rev

= length (rev as) + length [a]       -- length/++ lemma

= length as + length [a]       -- I.H.

= length as + 1       -- defn. length

= 1 + length as       -- + commutative

= length (a:as)       -- defn. length

= length xs       -- xs = a:as

Which is what we had to prove.


3. To prove: x `elem` rev xs = x `elem` xs, for all x,xs.

Proof: by structural induction over xs.

base case: xs = [].

    x `elem` rev xs        

= x `elem` rev []       -- xs = []

= x `elem` []       -- defn. rev

= x `elem` xs       -- xs = []

step case: xs = a:as.

1. I.H.: x `elem` rev as = x `elem` as, for all x.

2. Look at the following:

    x `elem` rev xs        

= x `elem` rev (a:as)       -- xs = a:as

= x `elem` (rev as ++ [a])       -- defn. rev

= (x `elem` rev as) || (x `elem` [a])       -- exercise 1.

= (x `elem` as) || (x `elem` [a])       -- I.H.

= (x `elem` [a]) || (x `elem` as)       -- || commutative

= x == a || (x `elem` as)       -- defn. elem

= x `elem` (a:as)       -- defn. elem

= x `elem` xs       -- xs = a:as

Which is what we had to prove.


4. To prove: x `elem` xs ==> length xs > 0, for all x,xs

Proof: by case split on xs.

case 1: xs = [].

    x `elem` xs ==> length xs > 0        

= x `elem` [] ==> length [] > 0       -- xs = []

= False ==> length [] > 0       -- defn. elem

= True       -- basic logic

case 2: xs = a:as.

    x `elem` xs ==> length xs > 0        

= x `elem` (a:as) ==> length (a:as) > 0       -- xs = a:as

= x `elem` (a:as) ==> (1 + length as) > 0       -- defn. length

= x `elem` (a:as) ==> True       -- basic arithmetic, length as >= 0

= True       -- basic logic

Which is what we had to prove.


5. To prove: take (length xs) xs = xs, for all xs.

Proof: by structural induction over xs.

base case: xs = [].

    take (length xs) xs        

= take (length []) []       -- xs = []

= take 0 []       -- defn. length

= []       -- defn. take

= xs       -- xs = []

step case: xs = a:as.

1. I.H.: take (length as) as = as.

2. Look at the following:

    take (length xs) xs        

= take (length (a:as)) (a:as)       -- xs = a:as

= take (1 + length as) (a:as)       -- defn. length

= a : take (1 + length as - 1) as       -- defn. take, length as >= 0

= a : take (length as) as       -- basic arithmetic

= a : as       -- I.H.

= xs       -- xs = a:as

Which is what we had to prove.


6. To prove: even x = not (odd x), for all x.

Proof: by structural induction over x.

base case: x = Zero.

    even x        

= even Zero       -- x = Zero

= True       -- defn. even

= not False       -- defn. not

= not (odd Zero)       -- defn. odd

= not (odd x)       -- x = Zero

step case: x = Succ a.

1. I.H.: even a = not (odd a).

2. Look at the following:

    even x        

= even (Succ a)       -- x = Succ a

= not (even a)       -- defn. even

= not (not (odd a))       -- I.H.

= odd a       -- basic logic

= not (odd (Succ a))       -- defn. odd

= not (odd x)       -- x = Succ a

Which is what we had to prove.


7. To prove: plus x Zero = x, for all x.

Proof: by structural induction over x.

base case: x = Zero.

    plus x Zero        

= plus Zero Zero       -- x = Zero

= Zero       -- defn. plus

= x       -- x = Zero

step case: x = Succ a.

1. I.H.: plus a Zero = a.

2. Look at the following:

    plus x Zero        

= plus (Succ a) Zero       -- x = Succ a

= Succ (plus a Zero)       -- defn. plus

= Succ a       -- I.H.

= x       -- x = Succ a

Which is what we had to prove.


8. To prove: even (plus x x), for all x.

Proof: by structural induction over x.

base case: x = Zero.

    even (plus x x)        

= even (plus Zero Zero)       -- x = Zero

= even Zero       -- defn. plus

= True       -- defn. even

step case: x = Succ a.

1. I.H.: even (plus a a).

2. Look at the following:

    even (plus x x)        

= even (plus (Succ a) (Succ a))       -- x = Succ a

= even (Succ (plus a (Succ a)))       -- defn. plus

= not (even (plus a (Succ a)))       -- defn. even

= not (even (Succ (plus a a)))       -- helper lemma (see below)

= not (not (even (plus a a)))       -- defn. even

= even (plus a a)       -- basic logic

= True       -- I.H.

Which is what we had to prove.

We also need to prove the helper lemma:

To prove: plus x (Succ y) = Succ (plus x y), for all x,y.

Proof: by structural induction over x.

base case: x = Zero.

    plus x (Succ y)        

= plus Zero (Succ y)       -- x = Zero

= Succ y       -- defn. plus

= Succ (plus Zero y)       -- defn. plus

= Succ (plus x y)       -- x = Zero

step case: x = Succ a.

1. I.H.: plus a (Succ y) = Succ (plus a y), for all y.

2. Look at the following:

    plus x (Succ y)        

= plus (Succ a) (Succ y)       -- x = Succ a

= Succ (plus a (Succ y))       -- defn. plus

= Succ (Succ (plus a y))       -- I.H.

= Succ (plus (Succ a) y)       -- defn. plus

= Succ (plus x y)       -- x = Succ a

Which is what we had to prove.


9. To prove: size p = length (flatten p), for all p.

Proof: by structural induction over p.

base case: p = Empty.

    size p        

= size Empty       -- p = Empty

= 0       -- defn. size

= length []       -- defn. length

= length (flatten Empty)       -- defn. flatten

= length (flatten p)       -- p = Empty

step case: p = Node a v w.

1. I.H.:

size v = length (flatten v), and

size w = length (flatten w)

2. Look at the following:

    size p        

= size (Node a v w)       -- p = Node a v w

= 1 + size v + size w       -- defn. size

= 1 + length (flatten v) + length (flatten w)       -- I.H. * 2

= length (flatten v ++ [a] ++ flatten w)       -- length/++ lemma * 2

= length (flatten (Node a v w))       -- defn. flatten

= length (flatten p)       -- p = Node a v w

Which is what we had to prove.


10. To prove: flatten (swap p) = rev (flatten p), for all p.

Proof: by structural induction over p.

base case: p = Empty.

    flatten (swap p)        

= flatten (swap Empty)       -- p = Empty

= flatten Empty       -- defn. swap

= []       -- defn. flatten

= rev []       -- defn. rev

= rev (flatten Empty)       -- defn. flatten

= rev (flatten p)       -- p = Empty

step case: p = Node a v w.

1. I.H.:

flatten (swap v) = rev (flatten v), and

flatten (swap w) = rev (flatten w)

2. Look at the following:

    flatten (swap p)        

= flatten (swap (Node a v w))       -- p = Node a v w

= flatten (Node a (swap w) (swap v))       -- defn. swap

= flatten (swap w) ++ [a] ++ flatten (swap v)       -- defn. flatten

= rev (flatten w) ++ [a] ++ rev (flatten v)       -- I.H. * 2

= rev (flatten w) ++ rev [a] ++ rev (flatten v)       -- defn. rev

= rev ([a] ++ flatten w) ++ rev (flatten v)       -- rev/++ lemma

= rev (flatten v ++ [a] ++ flatten w)       -- rev/++ lemma

= rev (flatten (Node a v w))       -- defn. flatten

= rev (flatten p)       -- p = Node a v w

Which is what we had to prove.


11. To prove: flatten (spine xs) = xs, for all xs.

Proof: by structural induction over xs.

base case: xs = [].

    flatten (spine xs)        

= flatten (spine [])       -- xs = []

= flatten Empty       -- defn. spine

= []       -- defn. flatten

= xs       -- xs = []

step case: xs = a:as.

1. I.H.: flatten (spine as) = as.

2. Look at the following:

    flatten (spine xs)        

= flatten (spine (a:as))       -- xs = a:as

= flatten (Node a Empty (spine as))       -- defn. spine

= flatten Empty ++ [a] ++ flatten (spine as)       -- defn. flatten

= [] ++ [a] ++ flatten (spine as)       -- defn. flatten

= a : flatten (spine as)       -- defn. ++

= a : as       -- I.H.

= xs       -- xs = a:as

Which is what we had to prove.