
Discrete math with computers_3
.pdf
C.4. INDUCTION |
391 |
So the theorem holds by list induction.
17.
Proof. Induction over xs. The base case is
reverse (reverse [ ])
=reverse [ ]
=[ ]
For the inductive case, assume for some xs that reverse (reverse xs) = xs. Then
reverse (reverse (x : xs))
=reverse (reverse xs++[x])
=reverse [x]++reverse (reverse xs)
=[x]++xs
=x : xs
18.Consider, for example, the infinite list nats = [0, 1, 2, 3, . . .]. This is easily defined in Haskell, with the expression [0..]. Notice that nats is not an infinite loop; a computation requiring only a finite portion of it will terminate. On the other hand, any computation requiring all of nats will go into an infinite loop; thus length nats will never terminate. This is expressed by saying length nats =, where the symbol (pronounced ‘bottom’) denotes an undefined value (either an infinite loop or an error).
Now consider the equation reverse (reverse nats) = nats. The left-hand side of the equation is not just a vague, intuitive statement that might be interpreted as leaving a list unchanged. It has a specific meaning that can (and must) be determined by equational reasoning using the definition of reverse.
The outermost application of reverse must begin by determining which of the two defining equations is relevant; it does this by performing a case analysis on its argument (which is reverse nats) to decide whether this is the empty list [] or a non-empty list in the form x:xs.
reverse (reverse (nats 0))
= case reverse (nats 0) of
[ ] → [ ]
x : xs → reverse xs++[x]
Now the computer must evaluate reverse (nats 0) far enough to decide whether it is the empty list, or a cons expression. This evaluation proceeds as follows:
392 APPENDIX C. SOLUTIONS TO SELECTED EXERCISES
reverse (nats 0)
=reverse (0 : nats 1)
=reverse (nats 1)++[0]
=reverse (1 : nats 2)++[0]
=(reverse (nats 2)++[1])++[0]
This evaluation is never going to terminate. The computer will just keep generating larger and larger natural numbers, constructing ever bigger expressions, but it will never actually figure out whether the original value reverse (nats 0) is empty! Hence no information at all can be obtained from evaluating
reverse (reverse (nats 0)).
To summarise, we know that:
reverse (reverse (nats 0)) = nats 0 =
A consequence of this, which might be surprising, is that reverse . reverse = id.
19.
Base case:
length (concat xss)
={ xss = [] } length (concat [])
={ (concat).[] }
length []
=
0
True,as the empty list has no elements, thus its length is 0 Inductive case:
length(concat xss)
={ xss = ys : yss } length (concat (ys : yss))
={ (concat).(:) }
length (ys ++ concat yss) = { (length).theorem }
length ys + length (concat yss)
True, as length ys delivers the length of the first element in xss, and under the induction assumption P (n), length (concat yss) delivers the length of the remaining elements in xss.
C.4. INDUCTION |
393 |
20.
Assume that the list xs is of type [Bool], that it has n + 1 elements, and that True is an element of xs.
We will prove that
P (n) ≡ or xs = True
Base case:
or xs
={ xs = [True] } or [True]
={ (:) }
or (True: [])
={ definition of or } foldr (||) False (True: [])
={ (foldr).(:) }
True || (foldr (||) False []) = { || commutative }
(foldr (||) False []) || True
= { || null }
True
Inductive case:
or xs
={ definition of or } foldr (||) False xs
={ xs = y : ys }
foldr (||) False (y : ys) = { (foldr).(:) }
y || (foldr (||) False (ys)) There are two cases:
Case 1: y = True
True || (foldr (||) False (ys)) = { || commutative }
(foldr (||) False (ys)) || True
= { || null }
True
Case 2: True is in ys
394 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
y || (foldr () False (ys))
={ induction assumption } y || True
={ || null }
True
21.
Assume that the list xs is of type Bool, that it has n + 1 elements, and that all elements of xs are True.
We will prove that
P (n) ≡ and xs = True
Base case:
and xs
={ definition of and } foldr (&&) True xs
={ xs = [True] }
foldr (&&) True [True] = { (:) }
foldr (&&) True (True: []) = { (foldr).(:) }
True && (foldr (&&) True [])
={ (foldr).[] } True && True
={ && identity }
True
Inductive case:
and xs
={ definition of and } foldr (&&) True xs
={ xs = True: ys } foldr (&&) True (True: ys)
={ (foldr).(:) }
True (&&) (foldr (&&) True ys)
={ inductive assumption }
True && True
={ && identity }
True
22.
maximum :: [Ord] -> Ord
maximum xs = foldr (max) y ys where xs = y:ys
396 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
firstElements xs = map (firstElement) xs
25.
Assume that the finite list xss is of type [[a]] and that it has length n. We prove that
P (n) ≡ concat xss = foldr (++) [] xss
Base case:
concat xss
={ xss = [] } concat []
={ (concat).[] }
[]
={ (foldr).[] } foldr (++) [] []
={ xss = [] } foldr (++) [] xss
Inductive case:
concat xss
={ xss = ys : yss } concat ys : yss
={ (concat).(:) }
ys ++ concat yss
={ induction assumption } foldr (++) [] (ys : yss)
={ xss = ys : yss } foldr (++) [] xss
26.
(&&)::Bool -> Bool -> Bool
and :: [Bool] -> Bool and = foldr (&&) True
27.
and ([False] ++ xs)
={ ++.(:) } and (False : xs)
={ and.(:) }
foldr (&&) True (False : xs) = {foldr.(:)}
False && (foldr (&&) True xs) = { && null }
False
C.5. TREES |
397 |
C.5 Trees
1.
data Tree1
= Tree1Leaf
| Tree1Node Char Integer Tree1 Tree1 Tree1
2.
data Tree2
= Tree2Leaf
| Tree2Node Integer [Tree2]
4.
inorderf :: (a->b) -> BinTree a -> [b] inorderf f BinLeaf = []
inorderf f (BinNode x t1 t2) =
inorderf f t1 ++ [f x] ++ inorderf f t2
8.
mapTree :: (a->b) -> BinTree a -> BinTree b mapTree f BinLeaf = BinLeaf
mapTree f (BinNode a t1 t2) =
BinNode (f a) (mapTree f t1) (mapTree f t2)
9.
concatTree :: Tree [a] -> [a] concatTree Tip = [] concatTree (Node as t1 t2) =
concatTree t1 ++ as ++ concatTree t2
10.
zipTree |
:: Tree a -> Tree b -> Maybe [(a,b)] |
||
zipTree |
Tip |
t2 |
= Nothing |
zipTree |
t1 |
Tip |
= Nothing |
zipTree |
(Node a t1 t2) |
(Node b t3 t4) |
|
= case (zipTree t1 t3) of |
|||
Nothing -> Nothing |
|
||
Just lst1 -> |
|
||
case (zipTree t2 |
t4) of |
||
|
Nothing -> Nothing |
||
|
Just lst2 -> Just (lst1 ++ [(a,b)] ++ lst2) |
398 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
11. The function traverses the two trees together. If either tree (or both) is empty, then the empty list is returned. If both trees are nonempty, then their top elements a and b are combined by computing f a b, and the function traverses the subtrees recursively.
zipWithTree ::
(a -> b -> c) -> Tree a -> Tree b -> [c] zipWithTree f Tip t2 = []
zipWithTree f t1 Tip = []
zipWithTree f (Node a t1 t2) (Node b t3 t4)
=zipWithTree f t1 t3
++[f a b]
++zipWithTree f t2 t4
12.A straightforward approach just uses existing functions:
appendTree1 :: BinTree a -> [a] -> [a] appendTree1 t ks = inorder t ++ ks
However, this solution builds a list of data from the tree and then recopies this data during the concatenation. The solution can be made more e cient using a continuation list:
appendTree2 :: BinTree a -> [a] -> [a] appendTree2 BinLeaf ks = ks appendTree2 (BinNode x t1 t2) ks =
appendTree2 t1 (x : appendTree2 t2 ks)
C.6 Propositional Logic
1. The answer is a question. If someone were to ask the computer named “Bob” whether it would answer “yes” to the question “Does this bus go to the airport?”, would the computer named “Bob” answer “yes”?
These are the cases to consider.
•Case PfAir : Suppose the computer named “Bob” is a properly functioning computer and the bus is going to the airport. Then the computer would answer “yes” if it were asked the question posed within the question the computer is asked. So, the correct answer to the question is “yes”, and, since the computer functions properly, that is the answer it gives.
•Case TwAir : Suppose the computer named “Bob” contains twisted logic and the bus is going to the airport. Then the computer would answer “no” if it were asked the question posed within the question the computer is asked. So, the correct answer to the question is “no”, and, since the computer is twisted, the answer it gives is “yes”. So far, so good. You
C.6. PROPOSITIONAL LOGIC |
399 |
get the answer “yes” if the bus is going to the airport, no matter which kind of computer Bob is.
•Case PfAin: Suppose the computer named “Bob” is a properly functioning computer and the bus is not going to the airport. Then the computer would answer “no” if it were asked the question posed within the question the computer is asked. So, the correct answer to the question is “no”, and, since the computer functions properly, that is the answer it gives.
•Case TwAin: Suppose the computer named “Bob” contains twisted logic and the bus is not going to the airport. Then the computer would answer “yes” if it were asked the question posed within the question the computer is asked. So, the correct answer to the question is “yes”, and, since the computer is twisted, the answer it gives is “no”.
So you get the answer “no” if the bus is not going to the airport and the answer “yes” if it is going to the airport, regardless of whether Bob is a properly functioning computer or a computer with twisted logic.
Another Solution. Would the computer named “Bob” give the answer “yes” to one and only one of the following two questions?
•Q1. Does the computer named Bob have twisted logic?
•Q2. Is this bus going to the airport?
The first solution was based on the logical operation “implication”. This solution is based on “exclusive or”.
•Case PfAirXor : Suppose the computer named “Bob” is a properly functioning computer and the bus is going to the airport. Then the computer would answer “yes” because that is the correct answer to the question about the number of “yes” answers to the Q-questions (“no” for Q1 and “yes” for Q2).
•Case TwAirXor : Suppose the computer named “Bob” contains twisted logic and the bus is going to the airport. Then the computer would answer “yes” because the computer named “Bob” would answer “no” to Q1 (because the correct answer is “yes”) and “no” to Q2 (because the correct answer is “yes”). Since the answer to neither Q1 nor Q2 is “yes”, the correct answer to the question about the number of “yes” answers to the Q-questions is “no”, which means the computer, which is twisted, would answer “yes”. For the airport bus, the answer is “yes”, no matter which type of computer Bob is.
•Case PfAinXor : Suppose the computer named “Bob” is a properly functioning computer and the bus is not going to the airport. Then the computer would answer “no” to Q1 and “no” to Q2, and since the answer to neither question is “yes”, the properly functioning computer gives
400 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
the answer “no” to the question about how many of the Q-questions have the answer “yes”.
•Case TwAinXor : Suppose the computer named “Bob” contains twisted logic and the bus is not going to the airport. Then the computer would answer “no” to Q1 (since the correct answer is “yes”) and “yes” to Q2 (since the correct answer is “no”). That means the correct answer to the question about the number of “yes” answers to the Q-questions is “yes”. Bob, being twisted, answers “no”.
For the airport bus, the answer is “no’, no matter which type of computer Bob is. Therefore, if the computer answers “yes”, the first bus is going to the airport. If the computer answers “no”, the first bus is not going to the airport, so wait for the second bus.
Both solutions require the computers to know all the bus schedules and their own names. The solution based on exclusive or requires, additionally, the computer named “Bob” to know whether it contains a twisted logic circuit. Bob can get by without this bit of knowledge in the case of the solution based on implication because it can simply feed the questions through its own circuits, observe the answers internally, then run the answer to the larger question through the normal output device.
4.
(True P ) Q
• True is a WFF.
• P is a WFF, therefore True P is a WFF.
• Q is a WFF. Since True P and Q are WFFs, True P Q is a WFF.
P |
Q |
True P |
(True P ) Q |
True |
True |
True |
True |
True |
False |
True |
True |
False |
True |
False |
True |
False |
False |
False |
False |
The proposition is satisfiable but not a tautology.
5.
•P , Q, and R are WFFs.
•Since P , Q, and R are WFFs, P Q, P R, and Q R are WFFs.
•Since P and Q R are WFFs, P (Q R) is a WFF.