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:ys
Since 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 max
andfoldr1 f (x:xs) = f x $ foldr1 f xs
for non-emptyxs
. Definition of some other things are less clear -max y z
the definition ofmax
is 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 outmax
for greaterx
. (Then you'd also need to cover the cases for negativex
andy
in 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
max
in a particular way.Suppose, we want to prove the latter. Assume
x == Z
ok, now assume
x == S m
So, 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.