Haskell implementation of the familiar Fibonacci function
fibSlow n
| n == 0 = 1 --fib.1
| n == 1 = 1 --fib.2
| otherwise = fibSlow(n-1) + fibSlow(n-2) --fib.3
What is the induction proof of correctness for fibSlow?
To prove correctness of a function on the natural numbers by induction, you would show that it's correct for certain base cases, and then that it's correct for higher values of the parameter given the assumption that it's correct for lower ones. So you'd verify first that fibSlow 0 = 1, and then that fibSlow 1 = 1, and then that for n > 1, fibSlow n is equal to the (n-1)th fibonacci number plus the (n-2)th fibonacci number. Here you get to assume that those numbers are fibSlow (n-1) and fibSlow (n-2), since fibSlow is correct for all inputs less than n by the inductive hypothesis.
This might seem all rather trivial... because it is! The whole point of such an example in Haskell is that you can write code that's obviously correct. When you go to prove it correct, the proof just writes itself and amounts to looking at the code and noting that it clearly says exactly what you're trying to prove. This is one of the nice properties of a declarative language like Haskell.
Apologies I haven't formally seen this kind of material for a while, so you're probably best looking at other sources if this is homework.
I think you want to show the existence of a monotone function which describes the "progress" of the recursion. This case should be pretty simple: the argument itself is monotonically decreasing. For a nonnegative n, the recursive call will be made with a lesser n', and that n' will never be less than zero.
You can also use power induction to argue the function is defined on all n. You have declared it defined on 0 and 1, and it suffices to say that if it's defined on n and n+1, then it's defined on n+2. This is obvious by the definition of the recursive call.
I think you might be able to read up on some formalities in Jech's Set Theory book, in the Ordinals chapter.
Related
I was recently reading an article on string hashing. We can hash a string by converting a string into a polynomial.
H(s1s2s3 ...sn) = (s1 + s2*p + s3*(p^2) + ··· + sn*(p^n−1)) mod M.
What are the constraints on p and M so that the probability of collision decreases?
A good requirement for a hash function on strings is that it should be difficult to find a
pair of different strings, preferably of the same length n, that have equal fingerprints. This
excludes the choice of M < n. Indeed, in this case at some point the powers of p corresponding
to respective symbols of the string start to repeat.
Similarly, if gcd(M, p) > 1 then powers of p modulo M may repeat for
exponents smaller than n. The safest choice is to set p as one of
the generators of the group U(ZM) – the group of all integers
relatively prime to M under multiplication modulo M.
I am not able to understand the above constraints. How selecting M < n and gcd(M,p) > 1 increases collision? Can somebody explain these two with some examples? I just need a basic understanding of these.
In addition, if anyone can focus on upper and lower bounds of M, it will be more than enough.
The above facts has been taken from the following article string hashing mit.
The "correct" answers to these questions involve some amount of number theory, but it can often be instructive to look at some extreme cases to see why the constraints might be useful.
For example, let's look at why we want M ≥ n. As an extreme case, let's pick M = 2 and n = 4. Then look at the numbers p0 mod 2, p1 mod 2, p2 mod 2, and p3 mod 2. Because there are four numbers here and only two possible remainders, by the pigeonhole principle we know that at least two of these numbers must be equal. Let's assume, for simplicity, that p0 and p1 are the same. This means that the hash function will return the same hash code for any two strings whose first two characters have been swapped, since those characters are multiplied by the same amount, which isn't a desirable property of a hash function. More generally, the reason why we want M ≥ n is so that the values p0, p1, ..., pn-1 at least have the possibility of being distinct. If M < n, there will just be too many powers of p for them to all be unique.
Now, let's think about why we want gcd(M, p) = 1. As an extreme case, suppose we pick p such that gcd(M, p) = M (that is, we pick p = M). Then
s0p0 + s1p1 + s2p2 + ... + sn-1pn-1 (mod M)
= s0M0 + s1M1 + s2M2 + ... + sn-1Mn-1 (mod M)
= s0
Oops, that's no good - that makes our hash code exactly equal to the first character of the string. This means that if p isn't coprime with M (that is, if gcd(M, p) ≠ 1), you run the risk of certain characters being "modded out" of the hash code, increasing the collision probability.
How selecting M < n and gcd(M,p) > 1 increases collision?
In your hash function formula, M might reasonably be used to restrict the hash result to a specific bit-width: e.g. M=216 for a 16-bit hash, M=232 for a 32-bit hash, M=2^64 for a 64-bit hash. Usually, a mod/% operation is not actually needed in an implementation, as using the desired size of unsigned integer for the hash calculation inherently performs that function.
I don't recommend it, but sometimes you do see people describing hash functions that are so exclusively coupled to the size of a specific hash table that they mod the results directly to the table size.
The text you quote from says:
A good requirement for a hash function on strings is that it should be difficult to find a pair of different strings, preferably of the same length n, that have equal fingerprints. This excludes the choice of M < n.
This seems a little silly in three separate regards. Firstly, it implies that hashing a long passage of text requires a massively long hash value, when practically it's the number of distinct passages of text you need to hash that's best considered when selecting M.
More specifically, if you have V distinct values to hash with a good general purpose hash function, you'll get dramatically less collisions of the hash values if your hash function produces at least V2 distinct hash values. For example, if you are hashing 1000 values (~210), you want M to be at least 1 million (i.e. at least 2*10 = 20-bit hash values, which is fine to round up to 32-bit but ideally don't settle for 16-bit). Read up on the Birthday Problem for related insights.
Secondly, given n is the number of characters, the number of potential values (i.e. distinct inputs) is the number of distinct values any specific character can take, raised to the power n. The former is likely somewhere from 26 to 256 values, depending on whether the hash supports only letters, or say alphanumeric input, or standard- vs. extended-ASCII and control characters etc., or even more for Unicode. The way "excludes the choice of M < n" implies any relevant linear relationship between M and n is bogus; if anything, it's as M drops below the number of distinct potential input values that it increasingly promotes collisions, but again it's the actual number of distinct inputs that tends to matter much, much more.
Thirdly, "preferably of the same length n" - why's that important? As far as I can see, it's not.
I've nothing to add to templatetypedef's discussion on gcd.
If w : {1...L} → {0,1} is a binary string, the complement of w, denoted wC, is a string of length L defined by: wc(i) = 1 - w(i). The reverse of w, denoted wR, is the string of the length L defined by wR(i) = w(L + 1 - i). Use these definitions to give careful proof that, for every binary string x, (xC)R = (xR)C.
I have no idea how to start this question. I don't really want a direct answer I'd like to learn how to do this question by induction for future questions
If the solution I see is the simplest one, then it's a quite comprehensive exercise.
I suggest you start by proving a the following lemmas:
Lemma 1: (w0)C=(wC)1
Lemma 2: (w0)R=0(wR)
Both Lemma 1 and 2 can be proven by induction on the length of w. Doing it strictly by the given rules is tedious, but not very hard.
Argue that the following lemmas hold as well by the same argument
Lemma 1b: (w1)C=wC0
Lemma 2b: (w1)R=1(wR)
With those lemmas in place, you should be able to tackle the original problem of showing (xC)R=(xR)C.
Do an induction over L (i.e. the length of the word). The base case should be trivial. In the inductive step you'll end up with something like
Induction hypothesis
(uC)R=(uR)C.
Left to show:
((u0)C)R=((u0)R)C
and (by analogy)
((u1)C)R=((u1)R)C
Solving this step will involve the lemmas above.
I'm trying to create a modulus function within haskell using primtive recursive functions. I know it's possible (because it's on the list of example functions on wikipedia)
And I know how i'd logically do it too.. But I just can't implement it!
IE, the logic is (not primtive recursion or haskell)
function mod(a, b){
while(a > b)
a -= b
return a;
}
Which I can define using recursion (again not haskel)
function mod(a, b){
if(a < b) return a;
return mod(a - b, b);
}
But I just can't seem to implement it using primitive recursive functions. I bit which I can't do is the logic of a < b
I think to really solve my problem I need some sort of defined logic such as (again not haskel)
reduce(a, b)
= a >= b -> a-b
otherwise x
If anyone could help me with any part of this i'd really appreciate it, thanks
Edit::
I thought of potentially defining a modulus function making use of dividing, ie mod(a, b) = a - (a/b) * b, but since my primitive recursive function for divide relies on modulo I can't do it haha
Take a look at this for some pointers: http://www.proofwiki.org/wiki/Quotient_and_Remainder_are_Primitive_Recursive
Also note that the wikipedia definition is somewhat narrow. Any function built up by induction over a single finite data structure is primitive recursive, though it takes a bit to show that this translates into the tools given in wikipedia. And note that we can represent the naturals in the classic peano style. You don't have to do this of course, but it makes reasoning about induction much more natural. See the agda wiki for a citation of this notion of primitive recursion: http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.Totality#Primitiverecursion
The following page also has what I think is a somewhat clearer exposition of primitive recursion: http://plato.stanford.edu/entries/recursive-functions/#1.3
The solution to this is
mod(0, y)
= zero(y)
mod(x, 0)
= zero(x)
mod(x + 1, y)
= mult3(succ(mod(x, y)), sign(y), notsign(eq(mod(x, y), diff(y, 1))))
I have used many recursive functions now but still have trouble getting my head around how such a function exactly works (i'm familiar with the second line (i.e. | n==0 = 1) but am not so familiar with the final line (i.e. | n>0 = fac (n-1) * n)).
fac :: Int -> Int
fac n
| n==0 = 1
| n>0 = fac (n-1) * n
Recursive algorithms are very closely linked to mathematical induction. Perhaps studying one will help you better understand the other.
You need to keep two key principles in mind when using recursion:
Base Case
Inductive Step
The Inductive Step is often the most difficult piece, because it assumes that everything it relies upon has already been computed correctly. Making this leap of faith can be difficult (at least it took me a while to get the hang of it), but it is only because we've got preconditions on our functions; those preconditions (in this case, that n is a non-negative integer) must be specified so that the inductive step and base case are always true.
The Base Case is also sometimes difficult: say, you know that the factorial N! is N * (N-1)!, but how exactly do you handle the first step on the ladder? (In this case, it is easy, define 0! := 1. This explicit definition provides you with a way to terminate the recursive application of your Inductive Step.)
You can see your type specification and guard patterns in this function are providing the preconditions that guarantee the Inductive Step can be used over and over again until it reaches the Base Case, n == 0. If the preconditions can't be met, recursive application of the Inductive Step would fail to reach the Base Case, and your computation would never terminate. (Well, it would when it runs out of memory. :)
One complicating factor, especially with functional programming languages, is the very strong desire to re-write all 'simple' recursive functions, as you have here, with variants that use Tail Calls or Tail Recursion.
Because this function calls itself, and then performs another operation on the result, you can build a call-chain like this:
fac 3 3 * fac 2
fac 2 2 * fac 1
fac 1 1 * fac 0
fac 0 1
fac 1 1
fac 2 2
fac 3 6
That deep call stack takes up memory; but a compiler that notices that a function doesn't change any state after making a recursive call can optimize away the recursive calls. These kinds of functions typically pass along an accumulator argument. A fellow stacker has a very nice example: Tail Recursion in Haskell
factorial 1 c = c
factorial k c = factorial (k-1) (c*k)
This very complicated change :) means that the previous call chain is turned into this:
fac 3 1 fac 2 3
fac 2 3 fac 1 6
fac 1 6 6
(The nesting is there just for show; the runtime system wouldn't actually store details of the execution on the stack.)
This runs in constant memory, regardless of the value of n, and thus this optimization can convert 'impossible' algorithms into 'possible' algorithms. You'll see this kind of technique used extensively in functional programming, much as you'd see char * frequently in C programming or yield frequently in Ruby programming.
When you write | condition = expression it introduces a guard. The guards are tried in order from top to bottom until a true condition is found, and the corresponding expression is the result of your function.
This means that if n is zero, the result is 1, otherwise if n > 0 the result is fac (n-1) * n. If n is negative you get an incomplete pattern match error.
Once you've determined which expression to use, it's just a matter of substituting in the recursive calls to see what's going on.
fac 4
(fac 3) * 4
((fac 2) * 3) * 4
(((fac 1) * 2) * 3) * 4
((((fac 0) * 1) * 2) * 3) * 4
(((1 * 1) * 2) * 3) * 4
((1 * 2) * 3) * 4
(2 * 3) * 4
6 * 4
24
Especially for more complicated cases of recursion, the trick to save mental health is not to follow recursive calls, but just assume that they "do the right thing". E.g. in your fac example, you want to compute fac n. Imagine you already have the result fac (n-1). Then it's trivial to calculate fac n: just multiply it by n. But the magic of induction is that this reasonig actually works (as long as you provide a proper base case in order to terminate recursion). So e.g. for Fibonacci numbers, just look what the base case is, and assume that you are able to calculate the function for all numbers smaller then n:
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
See? You want to calculate fib n. It's easy if you would know fib (n-1) and fib (n-2). But you can simply assume you are able to calculate them, and that the "deeper levels" of recursion do the "right thing". So just use them, it will work.
Note that there are much better ways to write this function, as currently many values are recalculated very often.
BTW: The "best" way to write fac would be fac n = product [1..n].
whats throwing you? maybe the guards (the |) are confusing things.
You can think of the guards loosely as a chain of ifs, or a switch statement (difference being only one can run, and it directly evaluates to a result. does NOt perform a series of tasks, and certainly no side-effects. just evaluates to a value)
To pan imperative-like seudo-code....
Fac n:
if n == 0: return 1
if n > 0: return n * (result of calling fac w/ n decreased by one)
The call tree by other poster looks like it could be helpful. do yourself a favor and really walk through it
I am doing question 12 of project euler where I must find the first triangle number with 501 divisors. So I whipped up this with Haskell:
divS n = [ x | x <- [1..(n)], n `rem` x == 0 ]
tri n = (n* (n+1)) `div` 2
divL n = length (divS (tri n))
answer = [ x | x <- [100..] , 501 == (divL x)]
The first function finds the divisors of a number.
The second function calculates the nth triangle number
The 3rd function finds the length of the list that are the divisors of the triangle number
The 4th function should return the value of the triangle number which has 501 divisors.
But so far this run for a while without returning a result. Is the answer very large or do I need some serious optimisation to make this work in a realistic amount of time?
You need to use properties of divisor function: http://en.wikipedia.org/wiki/Divisor_function
Notice that n and n + 1 are always coprime, so that you can get d(n * (n + 1) / 2) by multiplying previously computed values.
It is probably faster to prime-factorise the number and then use the factorisation to find the divisors, than using trial division with all numbers <= sqrt(n).
The Sieve of Eratosthenes is a classical way of finding primes, which may be modified slightly to find the number of divisors of each natural number. Instead of just marking each non-prime as "not prime", you could make a list of all the primes dividing each number.
You can then use those primes to compute the complete set of divisors, or just the number of them, since that is all you need.
Another variation would be to mark not just multiples of primes, but multiples of all natural numbers. Then you could simply use a counter to keep track of the number of divisors for each number.
You also might want to check out The Genuine Sieve of Eratosthenes, which explains why
trial division is way slower than the real sieve.
Last off, you should look carefully at the different kinds of arrays in Haskell. I think it is probably easier to use the ST monad to implement the sieve, but it might be possible to achieve the correct complexity using accumArray, if you can make sure that your update function is strict. I have never managed to get this to work though, so you are on your own here.
If you were using C instead of Haskell, your function would still take much time.
To make it faster you will need to improve the algorithm, using suggestions from the above answers. I suggest to change the title and question description accordingly. Following that I'll delete this comment.
If you wish, I can spoil the problem by sharing my solution.
For now I'll give you my top-level code:
main =
print .
head . filter ((> 500) . length . divisors) .
map (figureNum 3) $ [1..]
The algorithmic improvement lies in the divisors function. You can further improve it using rawicki's suggestion, but already this takes less than 100ms.
Some optimization tips:
check for divisors between 1 and sqrt(n). I promise you won't find any above that limit (except for the number itself).
don't build a list of divisors and count the list, but count them directly.