To prove equality of two function definitions inductively - haskell

How do I do the induction to establish the statement moll n = doll n, with
moll 0 = 1 --(m.1)
moll n = moll ( n-1) + n --(m.2)
doll n = sol 0 n --(d.1)
where
sol acc 0 = acc +1 --(d.2)
sol acc n = sol ( acc + n) (n-1) -- ? (d.2)
I tried to prove the base case for n = 0
doll 0 = (d.2) = 1 = (m.1) = moll 0 , which is correct.
Now for n+1, show that
moll 2n = doll (n + 1)
=> doll (n + 1) = (d.2) = soll (acc + n + 1) n
But what now? How can I simplify it any further?

You've got a mistake in your n+1 step. I suspect this is because you're new to Haskell and its precedence rules.
moll (n+1) is not, as you write moll 2n - I'm assuming that by that you mean moll (2*n), since moll 2n is a haskell syntax error.
In any case, moll (n+1) is in fact moll n + n + 1, or, with extra parentheses added just to be explicit:
(moll n) + (n + 1)
That is, you apply moll to n and then you add n + 1 to the result of that.
From here you should be able to apply the induction hypothesis and go forward.
More explicitly, since you seem to still be having trouble:
moll (n+1) == (moll n) + (n + 1) (by m.2)
== (doll n) + (n + 1) (by induction hypot.)
== (sol 0 n) + (n + 1) (by d.1)
Now, as a lemma:
sol x n == (sol 0 n) + x
This can be proved by induction on n. It's obviously true for n equal to 0.
For the lemma's induction step:
sol x (n+1) == (sol (x + (n+1)) n) (By d.2, for (n+1) > 0)
== (sol 0 n) + (x + (n+1)) (By the induction hypot.)
== (sol 0 n) + (n+1) + x (This is just math; re-arranging)
== ((sol 0 n) + (n+1)) + x
== (sol (n+1) n) + x (By the induction hypot. again)
== (sol 0 (n+1)) + x (By d.2 again)
That second time I used the induction hypothesis may seem a bit odd, but remember that the induction hypothesis says:
sol x n == (sol 0 n) + x
For all x. Therefore, I can apply it to anything added to (sol 0 n), including n+1.
Now, back to the main proof, using our lemma:
moll (n+1) == (sol 0 n) + (n + 1) (we had this before)
== sol (n+1) n (by our lemma)
== sol 0 (n+1) (by d.2)
== doll (n+1) (by d.1)

Related

Tail recursion fibonacci derived from linear recursive version using Burstall & Darlington's folding/unfolding system

The inefficient (tree-recursive) fib(n) function calculates the n-th Fibonacci number. In Haskell:
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
Using the following identity:
gfib(n) = (fib(n), fib(n+1))
we could synthesize a linear recursive version:
fib n = fst (gfib n)
where gfib 0 = (0, 1)
gfib n = (b, a + b)
where (a, b) = gfib (n - 1)
On the other hand, there's a well-known tail-recursive version:
fib n = go n 0 1
where go 0 a b = a
go n a b = go (n - 1) b (a + b)
Now the question:
Is there a way to synthesize the tail-recursive version from the linear recursive one using the Burstall & Darlington's folding/unfolding technique? My goal is to understand how can I transform the lineal recursive program so the returning tuple were converted to two accumulating parameters so the resulting program were tail-recursive.
Context: functional programming, program synthesis/derivation, program transformation, induction
That transformation is called "accumulating" (e.g. in Algorithm Design in Haskell by Bird and Gibbons).
fib n = fst (go n)
where go 0 = (0, 1)
go n = (b, a + b)
where (a, b) = go (n - 1)
Accumulating:
fib n = fst (go n (0, 1))
where go 0 (a, b) = (a, b)
go n (a, b) = go (n - 1) (b, a + b)
Although it should be noted that in this case the accumulation is easy because it doesn't matter if you count up or down (n is not really used). But in general you should take care that the resulting function is still correct.
Then to get to your desired implementation you have to apply two more simple transformations:
Push in fst (I don't know if that's a common name):
fib n = go n (0, 1)
where go 0 (a, b) = a
go n (a, b) = go (n - 1) (b, a + b)
Currying:
fib n = go n 0 1
where go 0 a b = a
go n a b = go (n - 1) b (a + b)

Why does this recursive function for square-roots give the wrong result?

I made this tail-recursive function for computing square roots:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) (a + x/a)/2
For some reason, it gives the wrong result when n is greater than 1, meaning when it's asked to improve the approximation, a, more than once. It returns a number that's closer and closer to 0 as n grows. I tried implementing the same recursive formula in different ways like this:
sqrt x n = if n == 0 then 1 else (a + x/a)/2 where a = sqrt x (n - 1)
sqrt x = 1:map (\a -> (a + x/a)/2) (sqrt x)
And that all works fine. It's only the first example that doesn't work and I can't figure out why, as much as I try.
The expression:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) (a + x/a) / 2
is parsed as:
sqrt x n a = if n == 0 then a else (sqrt x (n - 1) (a + x/a)) / 2
So the sqrt x (n-1) (a+x/a) is seen as the numerator of a division by two. You should add brackets here:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) ((a + x/a) / 2)
With the given, fix, we can for example calculate the square root of five as:
Prelude> sqrt 5 10 1
2.23606797749979
According to Wikipedia, it is:
2.23606797749978969640917366873127623544061835961152572427089…
so this is already quite close.

Accumulator version of recursion

I have a example of accu version of recursion.
Normal recursion:
fib n = if n== 0 then 1 else if n==1 then 1 else fib(n-1) + fib (n-2)
Accu recursion:
fib n fibPOM n 1 1
fibPOM n f1 f2 = if n ==1 then f1 else fibPOM (n-1) (f1+f2) f1
And i must do the same with this(a^n recursion):
ff a n = if n==0 then 1 else if n==1 then a else a * ff a (n-1)
But i have no idea what i must do to get a^n accu recursion.
Here's a hint: add an accumulator argument acc
ff a n = ffACC a n (some initial accumulator value)
ffACC a n acc =
if n==0 then ...
else if n==1 then ...
else ...
Make sure that in each ... all the recursive calls are tail calls. That is, return ffACC (new a) (new n) (new acc), not something like value * ffACC ....
You start with an initial value 1: ff a n = ffAccu a n 1, then call the recursion as
ffAccu a n m = if n == 0 then m else (ffAccu a (n-1) (a*m))
(Note: The if then else construct might be written more cleanly by using pattern matching, as in
ffAccu a 0 m = m
ffAccu a n m = ffAccu a (n-1) (a*m)
)

Why is the following Haskell code hanging?

I'm new to Haskell. I was trying to solve the diophantine equation |x^y-y^x| is prime, using Haskell, for a given upper bound x, y < n.
So, I wrote this Haskell code:
-- list of primes
listprimesupto :: Integral a => a -> [a]
listprimesupto 1 = []
listprimesupto 2 = [2]
listprimesupto n = let halflstprimes = (listprimesupto (n `div` 2))
in halflstprimes++[i|i<-[((n `div` 2)+1)..n], (length [x|x<-halflstprimes, (i `mod` x) == 0])==0 ]
-- is prime?
is_prime :: Integral a => a -> Bool
is_prime 1 = False
is_prime n = let halflstprimes = (listprimesupto (n `div` 2))
in (length [x|x<-halflstprimes, (n `mod` x) == 0])==0
-- solve |x^y - y^x| == prime
xy_yx_p :: Integral t => t -> [(t, t)]
--xy_yx_p n = [(x,y)|x<-[2..n], y<-[2..n], x < y, (abs (x^y-y^x)) `elem` (listprimesupto (n^3))] -- version 1, works but upper limit too small
xy_yx_p n = [(x,y)|x<-[2..n], y<-[2..n], x < y, (let t=abs (x^y-y^x) in is_prime t)==True] -- version 2, hangs for n>3 ...
xy_yx_p n (version 2, uncommented) hangs for n > 3, in GHCi. Ctrl-C doesn't even work. I have to kill ghc from Activity Monitor (I'm on Mac).
Any idea what am I doing wrong in xy_yx_p? The other two functions seem to work fine.
Thanks in advance.
So, if it hangs for n = 4, what's so special about that case? Well, it's t. For x = 2 and y = 4, you will get
t = abs (2 ^ 4 - 4 ^ 2)
= abs (16 - 16 )
= abs 0
= 0
Therefore, you use 0 in is_prime, and thereby also in listprimesupto. This leads to a never ending recursion:
listprimesupto 0 = let halflstprimes = (listprimesupto (0 `div` 2))
in -- .....
So make sure that you handle non-positive inputs:
listprimesupto n | n <= 0 = []
is_prime n | n <= 1 = False

Mod Haskell Homework

My homework was to provide a function that computes 'x^y mod n' -for any n < (sqrt maxint32)
So I started by writing doing this:
modPow :: Int -> Int -> Int -> Int
modPow x y n = (x `mod` n) ^ (y `mod` n) `mod` n
Which seemed to work fine, for any number of n, although my next homework question involved using x^n mod n = x (Camichael numbers) and I could never get modPow to work.
So I made another modPow using pseudocode for mod exponentiation, -from wikipedia:
modPow2 :: Int -> Int -> Int -> Int
modPow2 x y n
= loopmod 1 1
where
loopmod count total = if count > y
then total
else loopmod (count+1) ((total*x) `mod` n)
Which now correctly produces the right answer for my next question, (x^n mod n = x) -for checking for Camichael numbers.
ALTHOUGH, modPow2 does not work for big numbers of 'y' (STACK-OVERFLOW!!)
How could I adjust modPow2 so it no longer gets a stackoverflow in the cases where y > 10,000 (but still less than sqrt of maxint 32 -which is around 46,000)
Or is there a fix on my original modPow so it works with x^n mod n = x? (I always do 560 561 561 as inputs and it gives me back 1 not 560 (561 is a carmichael number so should give 560 back)
Thanks alot.
Your formula for modPow is wrong, you can't just use y mod n as the exponent, it will lead to wrong results. For example:
Prelude> 2^10
1024
Prelude> 2^10 `mod` 10
4
Prelude> 2^(10 `mod` 10) `mod` 10
1
For a better modPow function you could use that x2n+1 = x2n ⋅ x and x2n = xn ⋅ xn and that for multiplication you actually can simply use the mod of the factors.
Where did you get your formula for modPow from?
(x ^ y) `mod` n = ((x `mod` n) ^ (y `mod` φ n)) `mod` n where φ is Euler's totient function.
This is probably because the argument total is computed lazily.
If you use GHC, you can make loopmod strict in total by placing a ! in frontof the argument, i.e.
loopmod count !total = ...
Another way would be to force evaluation of total like so: Replace the last line with
else if total == 0 then 0 else loopmod (count+1) ((total*x) `mod` n)
This does not change semantics (because 0*xis 0 anyway, so the reminder must be 0 also) and it forces hugs to evaluate total in every recursion.
If you are looking for implementation ( a^d mod n ) then
powM::Integer->Integer->Integer->Integer
powM a d n
| d == 0 = 1
| d == 1 = mod a n
| otherwise = mod q n where
p = powM ( mod ( a^2 ) n ) ( shiftR d 1 ) n
q = if (.&.) d 1 == 1 then mod ( a * p ) n else p

Resources