One of the excercises in "Thinking Functionally With Haskell" is about making a program more efficient using the fusion law. I am having some trouble trying to replicate the answer.
A part of the calculation requires that you transform maximum (xs ++ map (x+) xs) to max (maximum xs) (x + maximum xs) through equational reasoning.
maximum is defined as foldr1 max and as I don't know many rules surrounding foldr1 I'm stuck on even the first part which is to transform foldr1 max (xs ++ map (x+) xs) to max (foldr1 max xs) (foldr1 max (map (x+) xs)) so that's the first thing I'd like to understand.
Once we get past that, the next part seems harder i.e. transforming foldr1 max (map (x+) xs) to x + foldr1 max xs. Intuitively it makes sense; if you are finding the maximum value of a bunch of numbers that all have 'x' added to them then that's the same as finding the maximum of all the numbers before 'x' was added and adding 'x' to the result.
The only thing I've found to help me in this second stage is this stack overflow answer where the answer is basically given to you (if you assume p = q) with no individual easy to understand steps as you normally see with equational reasoning.
So please could someone show me the steps to do the transformation ?
This can be seen by induction.
Suppose,
xs == []. Both expressions are true, since both yielderror.Suppose,
xs == [y]Next, we will need a proof of commutativity of
maximum:maximum (xs++(y:ys)) == max y (maximum (xs++ys))- you will notice this is needed, if you skip this proof and go straight to the proof ofmaximum (y:ys ++ map(x+)(y:ys))- one step there requires to move(x+y)from the middle of the listys++(x+y):map(x+)ys.Suppose,
xs==[]:Suppose,
xs==x:xx:Ok, now get back to proving the original statement. Now, suppose
xs == y:ysSince you asked also about induction and how to see a certain thing can be proven by induction, here's some more.
You can see some of the steps are "by definition" - we know they are true by looking at how the function is written. For example,
maximum = foldr1 maxandfoldr1 f (x:xs) = f x $ foldr1 f xsfor non-emptyxs. Definition of some other things are less clear -max y zthe definition ofmaxis not shown; yet, it can be shown by induction thatmax (x+y)(x+z) == x+max y z. Here one would start with the definition ofmax 0 y == y, then how to work outmaxfor greaterx. (Then you'd also need to cover the cases for negativexandyin a similar way.)For example, natural numbers are zero and any successor of a natural number. You see, here we don't have any comparison defined, nothing. So, the properties of addition, subtraction, max, etc, stem from the definition of the functions:
Then, because we don't have comparison of Nats yet, have to define
maxin a particular way.Suppose, we want to prove the latter. Assume
x == Zok, now assume
x == S mSo, you see, it is important to know the definitions, important to prove the simplest case, and important to use the proof for the simpler case in the slightly more complex case.