Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Hedman. A First Course in Logic, 2004 (Oxford)

.pdf
Скачиваний:
140
Добавлен:
10.08.2013
Размер:
7.17 Mб
Скачать

320 Computability and complexity

The command ZERO Bn+1 is an abbreviation for the commands that set Bn+1 to zero. Line (6) moves the contents of Bn+1 to B1. We previously described programs for each of these operations. Likewise, if h is computable, then we can replace line (2) with a series of T ++ commands (see Exercise 7.8).

We conclude that every recursive function is T -computable.

7.4 Codes

We describe a process for coding and decoding T ++ programs as natural numbers. To each T ++ program P we assign a natural number called the code for P . Given the natural number, we can recover the entire program. Codes provide an invaluable tool for analyzing the set of T -computable functions. Using these codes, we shall be able to prove that every T -computable function is recursive. In light of this fact, the codes also lend insight into the recursive functions. The codes allow us to show, among other things, that the Ackermann function is recursive.

Prior to assigning codes to programs, we assign codes to individual commands. To each command we assign a natural number as follows:

Command

Number

 

 

Add i

4i

Rmv i

4i − 1

RmvP i

4i − 2

GOTO i

4i − 3

Each command corresponds to exactly one natural number and each natural number corresponds to exactly one command. In particular, 0 is the only nonnegative integer that does not correspond to some T ++ command. Let P be a T ++ program. We may view P as a finite sequence of natural numbers. Suppose that P corresponds to the sequence (n1, n2, . . . , nk). That is, ni is the number corresponding to command (i) of P (for i ≤ k = the length of P ). Let e = 2n1 3n2 5n3 · · · pnkk , where pk denotes the kth prime number. The program P uniquely determines the number e N. We refer to e as the code for P .

A given natural number e is the code for some T ++ program if and only if e is divisible by each of the first k primes (for some k) and no other primes. If e is the code for a program P , then we can recover this program by factoring e. This follows from the Fundamental Theorem of Arithmetic which states that every

Computability and complexity

321

natural number can be factored into primes in a unique manner. For example, the number 12 factors as 2231. This number corresponds to the T ++ program

(1)RmvP 1

(2)GOTO 1

having sequence (n1, n2) = (2, 1). The number 42 = 2 · 3 · 7 does not correspond to a program since it is divisible by 7 but not 5.

We assign a program Pe to each e in N {0}. If e is the code for a T ++ program, then let Pe denote this program. For those numbers that do not code a program, we assign a “default program.” We arbitrarily choose the one-lined program (1) GOTO 12 to be this program. So if e does not code a program, then, by default, Pe is (1) GOTO 12. Consider the list of programs P0, P1, P2, P3 , . . . .

Since every program has a code, this list includes every T ++ program.

For each k N, let ϕke denote the function Pe(k) (this notation helps distinguish the computable function from the program that computes the function). Consider the list of k-ary functions ϕk0 , ϕk1 , ϕk2 , ϕk3 , . . . . By Proposition 7.31, this list includes every recursive k-ary function on the non-negative integers.

With the notable exception of the program (1) GOTO 12, every T ++ program occurs exactly once in the list P0, P1, P2, . . . . The same cannot be said of the list of k-ary T -computable functions. Let f x) be a k-ary T -computable function. We show that f x) occurs as ϕke for infinitely many e.

Notation 2 Let f x) and gx) be partial functions. We write f x) $ gx) if the two functions have the same domain and f x) = gx) for any x¯ in this domain.

Proposition 7.32 If f x) is a T -computable k-ary function, then f x) $ ϕke x) for infinitely many e.

Proof To any program that computes f x), we can add extraneous commands to obtain another program that computes f x).

In particular, each recursive k-ary function occurs infinitely many times in the list ϕk0 , ϕk1 , ϕk2 , ϕk3 . . . . We next show that the recursive functions expend this list.

Theorem 7.33 Every T -computable function is recursive.

Proof Let f x) be a T -computable k-ary function. Then f x) is ϕke x) for some e N. Our goal is to show that ϕke is recursive.

For convenience, suppose that k = 1. (This assumption does not alter the essence of the proof.)

To compute ϕ1e(x), we set B1 equal to x and Bj equal to 0 for j > 1 and then run the program Pe. The T -machine executes the commands of Pe one-by-one in

322

Computability and complexity

the order determined by the program. We regard each executed command as a “step” of the computation. Suppose that the T -machine has completed n steps of the computation for some non-negative integer n.

Let bin(e, x, n, j) denote the value of bin Bj at this stage of the computation, and

let line(e, x, n) denote the line of the program that is to be executed next by the T -machine according to the program Pe.

We claim that the functions line(e, x, n) and bin(e, x, n, j) are primitive recursive. To verify this, we define these functions in a primitive recursive manner. For fixed values of e and x, we define the functions line(e, x, n) and bin(e, x, n, j) by induction on n. For each value of n, the function bin(e, x, n, j) is defined for all j.

When n = 0, the T -machine has not yet begun the computation. We have

line(e, x, 0) = 1, and

bin(e, x, 0, j) =

x if j = 1 0 otherwise

To determine line(e, x, n + 1) and bin(e, x, n + 1, j), we consider the line of the program previously executed, namely (line(e, x, n)), and examine the current contents bin(e, x, n, j) of bin Bj . Let Ln = line(e, x, n). Since there are four types of T ++ commands, there are four possibilities for Ln.

If line (Ln) of Pe is the command GOTO 12, then we set line(e, x, n+1) = 12 and bin(e, x, n + 1, j) = bin(e, x, n, j). Note that “line (Ln) of Pe is the command GOTO 12” means that the exponent on the Lthn prime in the prime factorization of e is the number 4 · 12 3 = 45 that corresponds to the command GOTO 12. Another way to express this is pf (e, Ln) = 45.

More generally, if pf (e, Ln) = 4i − 3 (corresponding to GOTO i), then

line(e, x, n + 1) = i and bin(e, x, n + 1, j) = bin(e, x, n, j) (for all j).

If pf (e, Ln) = 4i (corresponding to Add i), then

line(e, x, n + 1) = line(e, x, n) + 1, and

bin(e, x, n, j) + 1

if j = i

bin(e, x, n + 1, j) =

if j =i.

bin(e, x, n, j)

Computability and complexity

 

323

If pf (e, Ln) = 4i − 1 (corresponding to Rmv i), then

 

 

line(e, x, n + 1) = line(e, x, n) + 1, and

 

bin(e, x, n + 1, j) = bin(e, x, n, j)

 

1

if

j = i.

 

bin(e, x, n, j)

 

if

j = i

 

 

 

 

 

 

 

 

 

Finally, if pf (e, Ln) = 4i − 2 (corresponding to RmvP i), then

bin(e, x, n + 1, j) =

bin(e, x, n, j)

 

1

 

if j = i , and

 

 

bin(e, x, n, j)

 

 

if j = i

 

 

 

 

 

 

 

 

 

 

 

 

 

if bin(e, x, n, i) = 0

 

line(e, x, n) + 1

 

line(e, x, n + 1) =

line(e, x, n) 1

 

if bin(e, x, n, i) = 0 .

Thus, we define the functions bin(e, x, n, j) and line(e, x, n). To see that this definition is primitive recursive, we make three observations.

By Proposition 7.29, pf (e, Ln) is primitive recursive.

By Proposition 7.25, the above definitions by cases (including the cases based on the values of pf (e, Ln)) are primitive recursive.

The process of inductively defining the two functions simultaneously is primitive recursive. We leave this as Exercise 7.11.

We conclude that the functions bin(e, x, n, j) and line(e, x, n) are primitive recursive functions as claimed.

Our goal is to show that the function ϕ1e(x) is recursive. If the computation terminates, then ϕ1e(x) equals the value of bin(e, x, n, 1) for any n beyond the final step of the computation. Moreover, the computation terminates precisely when line(e, x, n) refers to a line of the program that does not exist. If Ln = line(e, x, n) is not a line of the program Pe, then pf (e, Ln) = 0. So the program terminates at step n if n is least such that pf (e, Ln) = 0. So we can define ϕ1e(x) from bin(e, x, n, j) and line(e, x, n) using unbounded search. Explicitly, for any e N:

ϕ1e(x) $ bin(e, x, y, 1), where y = usnpf (e, Ln); Ln = line(e, x, n).

That is, ϕ1e(x) is the composition bin(e, x, usnpf (e, line(e, x, n)), 1). Since this function is defined from primitive recursive functions using unbounded search, it is a recursive function. Since e was arbitrary, we conclude that every T -computable function is recursive.

Theorem 7.33 frees us from our restrictive programming language T ++. Whereas this choice of programming language was somewhat arbitrary, the resulting set of T -computable functions is not arbitrary. If we upgrade the T -machine so that it recognizes commands for adding and multiplying Bi and

324 Computability and complexity

Bj , then this will not provide any new computable functions. We may assume, without altering our concept of computability, that our programming language contains any number of commands for various recursive operations. This assumption may alter the concept of complexity. To define complexity classes in Section 7.7, we choose a particular extension of T ++.

The proof of Theorem 7.33 yields more than the statement of the theorem. Suppose we add a truly new feature to T ++. Consider the command Copy(i, Bj ) that sets Bc equal to Bi where c represents the contents of Bj . For example, if B1 equals 9 and B2 equals 5, then Copy(1, B2) sets B5 equal to 9 (the contents of B1 are “copied” to B5). This command o ers a versatility in writing programs that is found in virtually every programming language other than our contrived T ++. For example, this command allows us to write a program that, given input n in bin B1, sets bin Bn equal to 1 and then halts. This simple task cannot be performed by a T -machine operating on T ++ commands (try it).

Corollary 7.34 Suppose that T -machine (version 7.4) is an upgraded version of the T -machine that recognizes the command Copy(i, Bj ) as defined above for each i and j in N. The functions computable by this machine are precisely the T -computable functions.

Proof This can be proved in the same manner as Theorem 7.33. The coding must be changed to accommodate the new commands. The crux of the proof shows that the functions line(e, x, n) and bin(e, x, n, j) are primitive recursive. We can define these functions inductively as in the proof of Theorem 7.33 with the following addition.

If pf (e, Ln) is the code for the command Copy(i, Bj ), then

line(e, x, n + 1) = line(e, x, n) + 1, and

bin(e, x, n + 1, k) =

bin(e, x, n, i) if k = bin(e, x, n, j) bin(e, x, n, k) otherwise

The Church–Turing thesis implies that the computing power of T ++ cannot be improved upon. The previous corollary corroborates this. We next provide stronger evidence by showing that any function defined from recursive functions in an inductive manner (such as the Ackermann function) is itself recursive. We prove this as a consequence of Kleene’s Recursion theorem at the end of this section. Prior to proving this, we extract two further results from the proof of Theorem 7.33.

Corollary 7.35 (Kleene Normal Form) For every recursive function ϕke x), there exist two k + 2-ary primitive recursive functions f and g such that ϕke x) $ f (e, x¯, usng(e, x¯, n)).

Computability and complexity

325

Proof Let f (e, x¯, n) = bin(e, x¯, n, 1) and g(e, x¯, n) = pf (e, line(e, x¯, n)).

So not only is every computable function recursive, every computable function is a recursive function having a certain form. The definition of ϕke x) has only one occurrence of the unbounded search process. Since every recursive function is T -computable, every recursive function can be defined from the basic functions using primitive recursion, composition, and at most one application of unbounded search.

Corollary 7.36 The (k + 1)-ary function Uk defined by Uk(e, x¯) $ ϕke x) is recursive.

Proof By the proof of Theorem 7.33, Uk is the recursive function

bin(e, x¯, usnpf (e, line(e, x¯, n)), 1).

To prove Kleene’s Recursion theorem, we make use of the following lemma.

Lemma 7.37 For all natural numbers n and m, there exists a binary primitive recursive function Snm such that

Smn (e, x1, . . . , xm) = z implies ϕnz (y1, . . . , yn) $ ϕ(m+n)e(x1, . . . , xm, y1, . . . , yn).

Let us consider the content of this lemma prior to proving it. Suppose for simplicity that m = n = 1. Let f (x, y) be a recursive binary function. Then f (x, y) is the function ϕ2e(x, y) for some e. For each number a, let fa(x) denote the unary function defined by fa(y) $ f (a, y). Since f (x, y) is recursive, so is fa(y). So fa(y) is the function ϕ1z(y) for some z. The lemma states that there exists a function S11 that produces a code z for fa(y) given (e, a) as input. Moreover, this function is a primitive recursive function. If we replace x with an m-tuple x¯ and y with an n-tuple y¯, then we obtain the statement of the lemma in its full generality. This lemma is commonly referred to as the S–m–n Theorem.

Proof of Lemma 7.37 We prove this theorem for m = n = 1. The proof is the same for arbitrary m and n.

Let f (x, y) denote ϕ2e(x, y). To compute this function, we set bin B1 equal to x, bin B2 equal to y, and run the T ++ program Pe.

We now describe a T ++ program Pz that computes the function fa(y) $ f (a, y) for given a.

(1)MOVE B1 to B2

(2)Add 1

. . .

(a+1) Add 1

(a+2) Pe.

326

Computability and complexity

This program moves the contents of B1 to B2, then sets B1 equal to a, and then runs the program Pe that computes f (a, y). So this program computes the function fa(x).

Given a and e, the function S11(a, e) computes the code z for the above program. Clearly, this can be done for any given a and e and so S11(a, e) is a total function. We must show that it is primitive recursive.

Let E(a) be the code for the program represented by the first a + 1 “lines” of the program Pz. Since MOVE B1 to B2 is itself a program, it is more than one line. It is a subroutine. Let w be the number of lines in this subroutine and let

E(0) be its code. We define E(a) inductively by E(a + 1) = E(a)p4(a+w+1) (the exponent 4 corresponds to the command Add 1). This is a primitive recursive

definition of the function E(a).

We now describe how to compute z from a and e. Since e is a code for a program, e factors as e = pa11 pa22 · · · pakk for some k and nonzero a1 · · · ak. The code for the above program Pz is the following product:

z = E(a)pa1+ˆ1 wpa2+ˆ2 w · · · pakˆk+w,

where aˆj = aj + 4w if aj has the form 4i − 3 and aˆj = aj otherwise (for j = 1, . . . , k). This represents “shifting” the lines of the program Pe. This program constitutes lines (1 + w) through (k + w) of the program Pz. Because of this shift, any occurrence of the command GOTO i (having code 4i − 3) in Pe must be changed to GOTO i + w in Pz.

The definition of aˆj by cases is primitive recursive by Proposition 7.25. The prime factorization of e is primitive recursive by Proposition 7.29. Moreover, we have shown the function E(a) to be primitive recursive. We conclude that the function S11(e, a) = z, where z is as defined above, is primitive recursive.

Theorem 7.38 (Kleene’s Recursion theorem) Let f (y, x1, . . . , xk) be a (k + 1)-ary recursive function. For some number e, the k-ary function defined by

f (e, x , . . . , x

k

) is the same function as ϕk(x , . . . , x ).

 

 

 

 

1

 

 

 

 

e

1

k

 

 

 

 

Proof Consider the (k + 1)-ary function h defined as

 

 

 

 

 

 

 

h(y, x1, . . . , xk) $ f (Sn1 (y, y), x1, . . . , xk),

 

 

where S1

is as in Lemma 7.37. Since it is the composition of recursive functions,

n

 

 

 

 

 

 

 

 

 

 

 

 

h is recursive. So h $ ϕdk+1 for some d. Let e = Sn1 (d, d).

 

 

We

have

. , x )

$

f (S1 (d, d), x , . . . , x

 

) (by

our

choice of e)

f (e, x1, . .k+1 k

n

(by

1

k

 

of h

and d). By

$ h(d, x1, . . . , xk) $ ϕd

(d, x1, . . . , xk)

our definition

Lemma 7.37, ϕkd+1(d, x1, . . . , xk) $ ϕkz (x1, . . . , xk), where z = Sk1(d, d). By our definition of e, e = z and f (e, x1, . . . , xk) $ ϕke (x1, . . . , xk) as was required

to show.

Computability and complexity

327

Corollary 7.39 The Ackermann function A(x, y) is recursive.

Proof Let U2 be the ternary function defined by U2(e, x, y) $ ϕ2e(x, y). This function was shown to be recursive in Proposition 7.36. Using this function, we define another ternary function f as follows:

f (y, n, x) =

x + 1

 

if n = 0

 

U2(y, n − 1, 1)

 

if x = 0 and n > 0

 

 

 

 

 

 

 

 

 

 

 

 

(y, n − 1, U2

(y, n, x − 1))

otherwise.

 

U2

 

 

 

 

 

By Kleene’s Recursion theorem, there exists e N such that f (e, n, x) $ ϕ2e(n, x). It follows that

ϕ2(n, x) =

x2

 

if n = 0

 

 

 

 

+ 1

 

 

e

 

ϕe(n − 1, 1)

if x = 0 and n > 0

 

 

 

2

2

 

 

 

 

 

 

 

 

 

 

 

 

 

(n − 1, ϕe(n, x − 1)) otherwise.

 

 

 

 

ϕe

 

 

Comparing this with the definition of

A(, n, x) (Section

7.1.2), we

see

that A(n, x) =

ϕ2(n, x)

for all n and

x. Since ϕ2(n, x)

is recursive,

so

 

e

 

 

e

 

 

is A(n, x).

In a similar way, we can show that any given function defined from recursive functions in an inductive manner is itself recursive. This gives credence to our claim that every programmable function is recursive. For any specified programming language, we could prove this claim. We have done this for the contrived language T ++. To prove that the set of C++ computable functions is the same as the set of recursive functions, we would have to delve into the grammar of C++. The skeptical reader may pursue the details regarding this or any other programming language, but we do not. We accept our claim as fact and use the terms computable and recursive interchangeably.

7.5 Semi-decidable decision problems

We further study the subsets of N {0}. In Section 7.2, we defined the recursive subsets of N {0}. In the present section we consider the recursively enumerable sets. The recursive sets are computable in the sense that they have computable characteristic functions. The recursively enumerable sets are computably generated in the following sense.

Definition 7.40 Let A be a set of non-negative integers. We say that A is recursively enumerable if there exists a total recursive function f such that A = {f (0), f (1), f (2), f (3), . . .}.

328

Computability and complexity

So a set is recursively enumerable if it is the range of some total recursive function. Recall that every subset of (N {0})k corresponds to a decision problem. Whereas the recursive subsets correspond to decidable decision problems, recursively enumerable subsets correspond to semi-decidable decision problems.

Definition 7.41 Let R be a subset of (N {0})k. The decision problem corresponding to R is semi-decidable if the following k-ary function is computable:

1if x¯ R

hx) =

undefined otherwise.

Example 7.42 Consider the Validity Problem for First-Order Logic (FOVAL). Given a first-order sentence ϕ, we must determine whether or not ϕ is valid. We claim that this problem is semi-decidable. We describe an algorithm that determines the correct answer given valid ϕ. This algorithm lists each of the countably many formal proofs and checks them one-by-one. If a formal proof for ϕ is found, then the algorithm stops and outputs “yes, ϕ is valid.” Otherwise, the algorithm produces no output. Intuitively, this is what is meant by “semi-decidable.” Whereas this algorithm correctly determines whether a given sentence is valid, it will not tell us whether a given sentence is not valid.

Formally, a decision problem is a relation on the non-negative integers. The algorithm from the previous example is stated informally. To prove that FOVAL is semi-decidable but not decidable, we code FOVAL as a subset of N. In Section 8.4, we describe a procedure for coding sentences of first-order logic. That the set of codes for valid sentences is recursively enumerable follows from the completeness of first-order logic.

Examples of recursively enumerable sets that are not recursive are given in the next section. The codes from the previous section are used to define these and other noncomputable subsets of N {0}. In the present section, we discuss some of the numerous equivalent ways to define the concept of recursively enumerable sets.

Proposition 7.43 Let A be a proper subset of the non-negative integers. The following are equivalent:

(1)A is recursively enumerable

(2)A is the domain of a partial recursive function

(3)the decision problem of determining whether or not a given number x is in A is semi-decidable.

Computability and complexity

329

Proof Suppose first that A is recursively enumerable. Then A is the range of a

total recursive function f (x).

 

 

The binary function g(x, y) = (f (x) − y) + (y − f (x)) is also total recursive. This function equals 0 if and only if y = f (x). The set A is the domain of the function ubxg(x, y). Since this function is defined from a recursive function by unbounded search, ubxg(x, y) is recursive. So (1) implies (2).

Suppose now that (2) holds. Suppose that A is the domain of a recursive function f (x). By definition, the decision problem corresponding to A is semidecidable if and only if the following function is computable:

1if x A

h(x) =

undefined otherwise.

Since f (x) is recursive, so is the composition c1(f (x)) $ h(x) (where c1 is the constant function c1(x) = 1). So (2) implies (3).

Finally, suppose that (3) holds. Then h(x) (as defined above) is recursive. So h(x) $ ϕ1e(x) for some e. To compute h(x) we run program Pe with input x in bin B1. Recall the primitive recursive functions bin(e, x, n, 1) and line(e, x, n) from the proof of Theorem 7.33. If we run program Pe with input x, then the computation terminates when pf (e, line(e, x, n)) = 0. Let a be any element of A. Let

g(x, n) =

x if pf (e, line(e, x, n)) = 0 a otherwise.

The range of g(x, n) is A. To prove (1) we must find a unary function having range A. Let

g(n, m) if x = 2n3m

f (x) =

aotherwise.

Clearly f (x) is a unary function having the same range as g(x, y). So A is recursively enumerated by the function f (x) and (1) holds.

The characterization of recursively enumerable sets as the domains of partial recursive functions yields the following characterization of the recursive sets.

¯

Proposition 7.44 A set A is recursive if and only if both A and A are recursively

¯

enumerable (where A is the set of non-negative integers not in A).