The following writeup follows the notes by Lance Fortnow in http://oldblog.computationalcomplexity.org/media/ladner.pdf Ladner's Theorem: If P=/=NP then there exist NP intermediate languages. Proof: Let (M_i)_i be an enumeration of polytime Turing machines, ie M_i is a deterministic Turing machine running in time <= (n+2)^i and P = {L(M_i) | i:N}. Notice that for every polynomial p(n) there exists i such that p(n) <= (n+2)^i. Similarly, let (f_i)_i be an enumeration of all polytime computable functions where again f_i(x) runs in time <= (|x|+2)^i so that in particular |f_i(x)|<=(|x|+2)^i. We seek a language A such that 1) A:NP For each i: 2.i) A =/= L(M_i), 3.i) the function f_i is not a reduction SAT <= A, ie for each i there exists x such that either x:SAT and f_i(x) not in A or x not in SAT and f_i(x) in A The conditions 2.i together ensure that A is not in P The conditions 3.i together ensure that A is not NP-hard. We build A in the form A = {x | x:SAT & f(|x|) even} where f(n) can be computed in time polynomial in n. This will guarantee A:NP since A <= SAT. We define f recursively by f(0)=f(1)=2 and if f(k) is defined for all k<=n then f(n+1) is given as follows: We introduce the abbreviation A_f = {x | x:SAT & f(|x|) even} where f stands for the current function in the recursion. 1) If (2+log log n)^f(n) >= log n then f(n+1)=f(n). Eventually, we will leave case 1 because (2+x)^d (for fixed d) grows slower than 2^x. Otherwise, ie if (2+log log n)^f(n) < log n, then 2) if f(n)=2i for some i then we make sure that condition 2.i will be satisfied: Check whether there exists an x with |x| <= log log n such that either a) M_i(x) accepts and x not in A_f or b) M_i(x) rejects and x in A_f If such x exists then f(n+1)=f(n)+1 else f(n+1)=f(n). We show below that we will eventually get out of this case as well. 3) if f(n)=2i+1 for some i then we make sure that condition 3.i will be satisfied: Check whether there exists an x with |x| <= log log n such that either a) x in SAT and f_i(x) not in A_f b) x not in SAT and f_i(x) in A_f If such x exists then f(n+1)=f(n)+1 else f(n+1)=f(n). As before, we will eventually find such x. This completes the recursive definition of f and hence A = A_f. We begin now by checking that all calls to f within A_f will be on arguments for which f is already defined. Indeed, in case 2 we call f on arguments |x| with |x| <= log log n <= n thus we're fine. In case 3 we call f also on arguments |f_i(x)| with |x|<=log n. We then have |f_i(x)| <= (2+|x|)^i <= (2+log log n)^f(n) < log n <= n, so again it is ok. This ensures that the definition of f terminates. We now bound the runtime of f(n). Suppose we find a polynomial p(n) bounding the time it takes to compute f(n+1) from f(i) for i<=n. Then, by setting up a table for f we can compute f itself in time sum_{i=1}^n p(i) which is again a polynomial in n (of degree deg(p)+1). Let us thus show that such a polynomial exists. In case 1 this is obvious. In case 2 we need to consider O(2^(log log n)) = O(log n) many different inputs x of length <= log log n. For each of those we have to run M_i which takes time (2+|x|)^i <= (2 + log log n)^i < log n each and also perform a SAT test which takes time O(2^|x|) = O(2^log log n) = O(log n). Thus, we need time O((log n)^2) for all this. In case 3 the situation is similar, but the SAT tests are run on inputs of size (2+|x|)^i thus requiring time O(2^(2+log log n)^i) = O(2^log n) = O(n) which is again polynomial in n. Finally, we must argue that unless P=NP indeed A is different from each L(M_i) and none of the f_i is a reduction from SAT to A. By construction of A this is the case if f(n)=2i and f(n)=2i+1, respectively. So, we must argue that, indeed, the range of f covers all natural numbers >= 2. This is tantamount to showing that each case is eventually left as announced above. For case 1 we have already argued this. For case 2, suppose that f(n)=2i for all n>=n0 so we are stuck in case 2. This means that f(i) is odd for only finitely many i so that L(M_i) differs from SAT on only finitely many inputs (those x for which f(|x|) is odd). That, however, would imply SAT in P since L(M_i):P thus P=NP. Suppose, on the other hand, f(n)=2i+1 for all n>=n0 so we are stuck in case 3. In this situation, A will be a finite set and f_i : SAT <= A which again would imply P=NP because every finite set is in P.