Notes on Models of Computation
Chapter 9

H. Conrad Cunningham

06 April 2022

Copyright (C) 2015, 2022, H. Conrad Cunningham
Professor of Computer and Information Science
University of Mississippi
214 Weir Hall
P.O. Box 1848
University, MS 38677
(662) 915-7396 (dept. office)

Browser Advisory: The HTML version of this textbook requires a browser that supports the display of MathML. A good choice as of April 2022 is a recent version of Firefox from Mozilla.

Note: These notes were written primarily to accompany my use of Chapter 1 of the Linz textbook An Introduction to Formal Languages and Automata [[1].

9 Turing Machines

A finite accepter (nfa, dfa)

A pushdown accepter (npda, dpda)

The family of regular languages is a subset of the deterministic context-free languages, which is a subset of the context-free languages.

But, as we saw in Chapter 8, not all languages of interest are context-free. To accept languages like {anbncn:n0}\{ a^{n}b^{n}c^{n} : n \geq 0 \} and {ww:w{a,b}*}\{ ww : w \in \{a,b\}^{*} \}, we need an automaton with a more flexible internal storage mechanism.

What kind of internal storage is needed to allow the machine to accept languages such as these? multiple stacks? a queue? some other mechanism?

More ambitiously, what is the most powerful automaton we can define? What are the limits of mechanical computation?

This chapter introduces the Turing machine to explore these theoretical questions. The Turing machine is a fundamental concept in the theoretical study of computation.

The Turing machine

Although Turing machines are simple mechanisms, the Turing thesis (also known as the Church-Turing thesis) maintains that any computation that can be carried out on present-day computers an be done on a Turing machine.

Note: Much of the work on computability was published in the 1930’s, before the advent of electronic computers a decade later. It included work by Austrian (and later American) logician Kurt Goedel on primitive recursive function theory, American mathematician Alonso Church on lambda calculus (a foundation of functional programming), British mathematician Alan Turing (also later a PhD student of Church’s) on Turing machines, and American mathematician Emil Post on Post machines.

9.1 The Standard Turing Machine

9.1.1 What is a Turing Machine?

9.1.1.1 Schematic Drawing of Turing Machine

Linz Figure 9.1 shows a schematic drawing of a standard Turing machine.

This deviates from the general scheme given in Chapter 1 in that the input file, internal storage, and output mechanism are all represented by a single mechanism, the tape. The input is on the tape at initiation and the output is on that tape at termination.

On each move, the tape’s read-write head reads a symbol from the current tape cell, writes a symbol back to that cell, and moves one cell to the left or right.

Linz Fig. 9.1: Standard Turing Machine

9.1.1.2 Definition of Turing Machine

Turing machines were first defined by British mathematician Alan Turing in 1937, while he was a graduate student at Cambridge University.

Linz Definition 9.1 (Turing Machine): A Turing machine MM is defined by

M=(Q,Σ,Γ,δ,q0,,F)M = (Q, \Sigma, \Gamma, \delta, q_{0}, \Box, F)

where

  1. QQ is the set of internal states
  2. Σ\Sigma is the input alphabet
  3. Γ\Gamma is a finite set of symbols called the tape alphabet
  4. δ\delta is the transition function
  5. Γ\Box \in \Gamma is a special symbol called the blank
  6. q0Qq_{0} \in Q is the initial state
  7. FQF \subseteq Q is the set of final states

We also require

  1. ΣΓ{}\Sigma \subseteq \Gamma - \{\Box\}

and define

  1. δ:Q×ΓQ×Γ×{L,R}\delta : Q \times \Gamma \rightarrow Q \times \Gamma \times \{L, R\}.

Requirement 8 means that the blank symbol \Box cannot be either an input or an output of a Turing machine. It is the default content for any cell that has no meaningful content.

From requirement 9, we see that the arguments of the transition function δ\delta are:

  • the current state of the control unit
  • the current tape symbol

The result of the transition function δ\delta gives:

  • the new state of the control unit
  • the symbol that replaces the current symbol on the tape
  • a move symbol LL or RR, denoting a move of the read-write head to the left or the right on the tape

In general, δ\delta is a partial function. That is, not all configurations have a next move defined.

9.1.1.3 Linz Example 9.1

Consider a Turing machine with a move defined as follows:

δ(q0,a)=(q1,d,R)\delta(q_{0}, a) = (q_{1}, d, R)

Linz Figure 9.2 shows the situation (a) before the move and (b) after the move.

Linz Fig. 9.2: One Move of a Turing Machine

9.1.1.4 A Simple Computer

A Turing machine is a simple computer. It has

  • a processing unit that has a finite memory
  • a tape that provides unlimited secondary storage capacity
  • a limited set of instructions

The Turing machine can

  • sense the symbol under the tape’s read-write head
  • use the result to decide what to do next
  • write a symbol back to the tape
  • change the state of the control
  • move the read-write head one position to the left or right on the tape

The transition function δ\delta determines the behavior of the machine, i.e., it is the machine’s program.

The Turing macine starts in initial state q0q_{0} and then goes through a sequence of moves defined by δ\delta. A cell on the tape may be read and written many times.

Eventually the Turing machine may enter a configuration for which δ\delta is undefined. When it enters such a state, the machine halts. Hence, this state is called a halt state.

Typically, no transitions are defined on any final state.

9.1.1.5 Linz Example 9.2

Consider the Turing machine defined by

Q={q0,q1}Q = \{ q_{0}, q_{1} \},
Σ={a,b}\Sigma = \{ a, b\},
Γ={a,b,}\Gamma = \{a, b, \Box \},
F={q1}F = \{ q_{1} \}

where δ\delta is defined as follows:

  1. δ(q0,a)=(q0,b,R)\delta(q_{0}, a) = (q_{0}, b, R),
  2. δ(q0,b)=(q0,b,R)\delta(q_{0}, b) = (q_{0}, b, R),
  3. δ(q0,)=(q1,,L)\delta(q_{0}, \Box) = (q_{1}, \Box, L).

Linz Figure 9 .3 shows a sequence of moves for this Turing machine:

  • It begins in state q0q_{0} with the input positioned over an aa.
  • When an aa is read, transition rule 1 fires, replaces aa by bb on the tape, moves right, and stays in state q0q_{0}.
  • When a bb is read, transition rule 2 fires, leaves bb on the tape, moves right, and stays in state q0q_{0}.
  • It continues moving right, replacing each aa by a bb and leaving each bb unchanged.
  • When a blank (\Box) is read, transition rule 3 fires, leaves the blank on the tape, moves left, and enters final state q1q_{1}.
Linz Fig. 9.3: A Sequence of Moves of a Turing Machine

9.1.1.6 Transition Graph for Turing Machine

As with finite and pushdown automata, we can use transition graphs to represent Turing machines. We label the edges of the graph with a triple giving (1) the current tape symbol, (2) the symbol that replaces it, and (3) the direction in which the read-write head moves.

Linz Figure 9.4 shows a transition graph for the Turing machine given in Linz Example 9.2.

Linz Fig. 9.4: Transition Graph for Example 9.2

9.1.1.7 Linz Example 9.3 (Infinite Loop)

Consider the Turing machine defined in Linz Figure 9.5.

Linz Fig. 9.5: Infinite Loop

Suppose the tape initially contains aba b \ldots with the read-write head positioned over the aa and in state q0q_{0}. Then the Turing machine executes the following sequence of moves:

  1. The machine reads symbol aa, leaves it unchanged, moves right (now over symbol bb), and enters state q1q_{1}.

  2. The machine reads bb, leaves it unchanged, moves back left (now over aa again), and enters state q0q_{0} again.

  3. The machine then repeats steps 1-3.

Clearly, regardless of the tape configuration, this machine does not halt. It goes into an infinite loop.

9.1.1.8 Standard Turing Machine

Because we can define a Turing machine in several different ways, it is useful to summarize the main features of our model.

A standard Turing machine:

  1. has a tape that is unbounded in both directions, allowing any number of left and right moves

  2. is deterministic in that δ\delta defines at most one move for each configuration

  3. has no special input or output files. At the initial time, the tape has some specified content, some of which is considered input. Whenever the machine halts, some or all of the contents of the tape is considered output.

These definitions are chosen for convenience in this chapter. Chapter 10 (which we do not cover in this course) examines alternative versions of the Turing machine concept.

9.1.1.9 Instantaneous Description of Turing Machine

As with pushdown automata, we use instantaneous descriptions to examine the configurations in a sequence of moves. The notation (using strings)

x1qx2x_{1} q x_{2}

or (using individual symbols)

a1a2ak1qakak+1ana_{1} a_{2} \cdots a_{k-1} q a_{k} a_{k+1} \cdots a_{n}

gives the instantaneous description of a Turing machine in state qq with the tape as shown in Linz Figure 9.5.

By convention, the read-write head is positioned over the symbol to the right of the state (i.e., aka_{k} above).

Linz Fig. 9.6: Tape Configuration a_{1} a_{2} \cdots a_{k-1} q a_{k} a_{k+1} \cdots a_{n}

A tape cell contains \Box if not otherwise defined to have a value.

Example: The diagrams in Linz Figure 9.3 (above) show the instantaneous descriptions q0aaq_{0} a a, bq0ab q_{0} a, bbq0b b q_{0} \Box, and bq1bb q_{1} b.

As with pushdown automata, we use \vdash to denote a move.

Thus, for transition rule

δ(q1,c)=(q2,e,R)\delta(q_{1}, c) = (q_{2}, e, R)

we can have the move

abq1cdabeq2da b q_{1} c d \vdash a b e q_{2} d.

As usual we denote the transitive closure of move (i.e., arbitrary number of moves) using:

*\vdash^*

We also use subscripts to distinguish among machines:

M\vdash_{M}

9.1.1.10 Computation of Turing Machine

Now let’s summarize the above discussion with the following definitions.

Linz Definition 9.2 (Computation): Let M=(Q,Σ,Γ,δ,q0,,F)M = (Q, \Sigma, \Gamma, \delta, q_{0}, \Box, F) be a Turing machine. Then any string a1ak1q1akak+1ana_{1} \cdots a_{k-1} q_{1} a_{k} a_{k+1} \cdots a_{n} with aiΓa_{i} \in \Gamma and q1Qq_{1} \in Q, is an instantaneous description of MM.

A move

a1ak1q1akak+1ana_{1} \cdots a_{k-1} q_{1} a_{k} a_{k+1} \cdots a_{n} \vdash a1ak1bq2ak+1ana_{1} \cdots a_{k-1} b q_{2} a_{k+1} \cdots a_{n}

is possible if and only if

δ(q1,ak)=(q2,b,R)\delta(q_{1}, a_{k}) = (q_{2}, b, R).

A move

a1ak1q1akak+1ana_{1} \cdots a_{k-1} q_{1} a_{k} a_{k+1} \cdots a_{n} \vdash a1q2ak1bak+1ana_{1} \cdots q_{2} a_{k-1} b a_{k+1} \cdots a_{n}

is possible if and only if

δ(q1,ak)=(q2,b,L)\delta(q_{1}, a_{k}) = (q_{2}, b, L).

MM halts starting from some initial configuration x1qix2x_{1} q_{i} x_{2} if

x1qix2*y1qjay2x_{1} q_{i} x_{2} \ \vdash^*\ y_{1} q_{j} a y_{2}

for any qjq_{j} and aa, for which δ(qj,a)\delta(q_{j}, a) is undefined.

The sequence of configurations leading to a halt state is a computation.

If a Turing machine does not halt, we use the following special notation to describe its computation:

x1qx2*x_{1} q x_{2} \vdash^* \infty

9.1.2 Turing Machines as Language Acceptors

Can a Turing machine accept a string ww?

Yes, using the following setup:

  • Write ww on the tape initially.
  • Fill all the unused cells on the tape with blanks \Box.
  • Start the Turing machine with read-write head over leftmost symbol of ww.
  • If the machine halts in a final state, then it accepts string ww.

Linz Definition 9.3 (Language Accepted by Turing Machine): Let M=(Q,Σ,Γ,δ,q0,,F)M = (Q, \Sigma, \Gamma, \delta, q_{0}, \Box, F) be a Turing machine. Then the language accepted by MM is

L(M)={wΣ+:q0w*x1qfx2,qfF,x1,x2Γ*}L(M) = \{ w \in \Sigma^{+} : q_{0} w \vdash^{*} x_{1} q_{f} x_{2}, q_{f} \in F, x_{1}, x_{2} \in \Gamma^{*} \}.

Note: The finite string ww must be written to the tape with blanks on both sides. No blanks can are embedded within the input string ww itself.

Question: What if wL(M)w \not\in L(M)?

The Turing machine might:

  1. halt in nonfinal state
  2. never halt

Any string for which the machine does not halt is, by definition, not in L(M)L(M).

9.1.2.1 Linz Example 9.6

For Σ={0,1}\Sigma = \{ 0, 1 \}, design a Turing machine that accepts the language denoted by the regular expression 00*00^{*}.

We use two internal states Q={q0,q1}Q = \{ q_{0}, q_{1} \}, one final state F={q1}F = \{ q_{1} \}, and transition function:

δ(q0,0)=(q0,0,R)\delta(q_{0}, 0) = (q_{0}, 0, R),
δ(q0,)=(q1,,R)\delta(q_{0}, \Box) = (q_{1}, \Box, R)

The transition graph shown below implements this machine.

  • While a 00 appears under the read-write head, the head moves to the right.
  • If a blank is read, the machine halts in final state q1q_{1}.
  • If a 11 is read, the machine halts in the nonfinal state q0q_{0} because δ(q0,1)\delta(q_{0}, 1) is undefined.

The Turing machine also halts in a final state if started in state q0q_{0} on a blank. We could interpret this as acceptance of λ\lambda, but for technical reasons the empty string is not included in Linz Definition 9.3.

9.1.2.2 Linz Example 9.7

For Σ={a,b}\Sigma = \{ a, b \}, design a Turing machine that accepts

L={anbn:n1}L = \{a^{n} b^{n} : n \geq 1 \}.

We can design a machine that incorporates the following algorithm:

      While both aa’s and bb’s remain
          replace leftmost aa by xx
          replace leftmost bb by yy
      If no aa’s or bb’s remain
          accept
      else
          reject

Filling in the details, we get the following Turing machine for which:

Q={q0,q1,q2,q3,q4}Q = \{ q_{0}, q_{1}, q_{2}, q_{3}, q_{4} \}
F={q4}F = \{q_4\}
Σ={a,b}\Sigma = \{a, b\}
Γ={a,b,x,y,}\Gamma = \{a, b, x, y, \Box\}

The transitions can be broken into several sets.

The first set

  1. δ(q0,a)=(q1,x,R)\delta(q_{0}, a) = (q_{1}, x, R)
  2. δ(q1,a)=(q1,a,R)\delta(q_{1}, a) = (q_{1}, a, R)
  3. δ(q1,y)=(q1,y,R)\delta(q_{1}, y) = (q_{1}, y, R)
  4. δ(q1,b)=(q2,y,L)\delta(q_{1}, b) = (q_{2}, y, L)

replaces the leftmost aa with an xx, then causes the read-write head to travel right to the first bb, replacing it with a yy. The machine then enters a state q2q_{2}, indicating that an aa has been successfully paired with a bb.

The second set

  1. δ(q2,y)=(q2,y,L)\delta(q_{2}, y) = (q_{2}, y, L)
  2. δ(q2,a)=(q2,a,L)\delta(q_{2}, a) = (q_{2}, a, L)
  3. δ(q2,x)=(q0,x,R)\delta(q_{2}, x) = (q_{0}, x, R)

reverses the direction of movement until an xx is encountered, repositions the read-write head over the leftmost aa, and returns control to the initial state.

The machine is now back in the initial state q0q_{0}, ready to process the next aa-bb pair.

After one pass through this part of the computation, the machine has executed the partial computation:

q0aaabbbq_{0} a a \cdots a b b \cdots b *\vdash^{*} xq0aaybbx q_{0} a \cdots a y b \cdots b

So, it has matched a single aa with a single bb.

The machine continues this process until no aa is found on leftward movement.

If all aa’s have been replaced, then state q0q_{0} detects a yy instead of an aa and changes to state q3q_{3}. This state must verify that all bb’s have been processed as well.

  1. δ(q0,y)=(q3,y,R)\delta(q_{0}, y) = (q_{3}, y, R)
  2. δ(q3,y)=(q3,y,R)\delta(q_{3}, y) = (q_{3}, y, R)
  3. δ(q3,)=(q4,,R)\delta(q_{3}, \Box) = (q_{4}, \Box, R)

The input aabbaabb makes the moves shown below. (The bold number in parenthesis gives the rule applied in that step.)

q0aabbq_{0}aabb – start at left end
(1) \vdash xq1abbxq_{1}abb – process 1st a-b pair
(2) \vdash xaq1bbxaq_{1}bb – moving to right
(4) \vdash xq1aybxq_{1}ayb
(6) \vdash q2xaybq_{2}xayb – move back to left
(7) \vdash xq0aybxq_{0}ayb
(1) \vdash xxq1ybxxq_{1}yb – process 2nd a-b pair
(3) \vdash xxyq1bxxyq_{1}b – moving to right
(4) \vdash xxq2yyxxq_{2}yy
(5) \vdash xq2xyyxq_{2}xyy – move back to left
(7) \vdash xxq0yyxxq_{0}yy
(8) \vdash xxyq3yxxyq_{3}y – no a’s
(9) \vdash xxyyq3xxyyq_{3}\Box – check for extra b’s
(10) \vdash xxyyq4xxyy\Box q_{4}\Box – done, move to final

The Turing machine halts in final state q4q_{4}, thus accepting the string aabbaabb.

If the input is not in the language, the Turing machine will halt in a nonfinal state.

For example, consider:

  • anbma^{n} b^{m} for n>mn > m?
    • halts in nonfinal state q1q_{1} when \Box found
  • anbma^{n} b^{m} for 0<n<m0 < n < m?
    • halts in nonfinal state q3q_{3} when bb found
  • abaaba?
    • halts in nonfinal state q3q_{3} when aa found
  • bb?
    • halts in nonfinal state q0q_{0} when bb found

9.1.3 Turing Machines as Transducers

Turing machines are more than just language accepters. They provide a simple abstract model for computers in general. Computers transform data. Hence, Turing machines are transducers (as we defined them in Chapter 1). For a computation, the

  • input consists of all the nonblank symbols on the tape initially

  • output consists of is whatever is on the tape when the machine halts in a final state

Thus, we can view a Turing machine transducer MM as an implementation of a function ff defined by

ŵ=f(w)\hat{w} = f(w)

provided that

q0wM*qfŵq_{0} w \vdash^{*}_{M} q_{f} \hat{w},

for some final state qfq_{f}.

Linz Definition 9.4 (Turing Computable): A function ff with domain DD is said to be Turing-computable, or just computable, if there exists some Turing machine M=(Q,Σ,Γ,δ,q0,,F)M = (Q, \Sigma, \Gamma, \delta, q_{0}, \Box, F) such that

q0wM*qff(w)q_{0} w \vdash^{*}_{M} q_{f} f(w), qfFq_f \in F,

for all wDw \in D.

Note: A transducer Turing machine must start on the leftmost symbol of the input and stop on the leftmost symbol of the output.

9.1.3.1 Linz Example 9.9

Compute x+yx + y for positive integers xx and yy.

We use unary notation to represent the positive integers, i.e., a positive integer is represented by a sequence of 1’s whose length is equal to the value of the integer. For example:

1111=41111 \ =\ 4

The computation is

q0w(x)0w(y)q_{0} w(x) 0 w(y) *\vdash^{*} qfw(x+y)0q_{f} w(x + y) 0

where 00 separates the two numbers at initiation and after the result at termination.

Key idea: Move the separating 00 to the right end.

To achieve this, we construct M=(Q,Σ,Γ,δ,q0,,F)M = (Q, \Sigma, \Gamma, \delta, q_{0}, \Box, F) with

Q={q0,q1,q2,q3,q4}Q = \{ q_{0}, q_{1}, q_{2}, q_{3}, q_{4} \}
F={q4}F = \{ q_{4} \}
δ(q0,1)=(q0,1,R)\delta(q_{0}, 1) = (q_{0}, 1, R)
δ(q0,0)=(q1,1,R)\delta(q_{0}, 0) = (q_{1}, 1, R)
δ(q1,1)=(q1,1,R)\delta(q_{1}, 1) = (q_{1}, 1, R)
δ(q1,)=(q2,,L)\delta(q_{1}, \Box) = (q_{2}, \Box, L)
δ(q2,1)=(q3,0,L)\delta(q_{2}, 1) = (q_{3}, 0, L)
δ(q3,1)=(q3,1,L)\delta(q_{3}, 1) = (q_{3}, 1, L)
δ(q3,)=(q4,,R)\delta(q_{3}, \Box) = (q_{4}, \Box, R)

The sequence of instantaneous descriptions for adding 111 to 11 is shown below.

q0111011q_{0}111011 \;\vdash\; 1q0110111q_{0}11011 \;\vdash\; 11q0101111q_{0}1011 \;\vdash\; 111q0011111q_{0}011
\;\vdash\; 1111q11111111q_{1}111 \;\vdash\; 11111q1111111q_{1}1 \;\vdash\; 111111q1111111q_{1}\Box
\;\vdash\; 11111q2111111q_{2}1 \;\vdash\; 1111q3101111q_{3}10 \;\vdash\; 111q3110111q_{3}110
\;\vdash\; 11q3111011q_{3}1110 \;\vdash\; 1q3111101q_{3}11110 \;\vdash\; q3111110q_{3}111110
\;\vdash\; q3111110q_{3}\Box 111110 \;\vdash\; q4111110q_{4}111110

9.1.3.2 Linz Example 9.10

Construct a Turing machine that copies strings of 11’s. More precisely, find a machine that performs the computation

q0w*qfwwq_{0} w \vdash^{*} q_{f} ww,

for any w{1}+w \in \{1\}^{+}.

To solve the problem, we implement the following procedure:

  1. Replace every 11 by an xx.
  2. Find the rightmost xx and replace it with 11.
  3. Travel to the right end of the current nonblank region and create a 11 there.
  4. Repeat steps 2 and 3 until there are no more xx’s.

A Turing machine transition function for this procedure is as follows:

δ(q0,1)=(q0,x,R)\delta(q_{0}, 1) = (q_{0}, x, R)
δ(q0,)=(q1,L)\delta(q_{0}, \Box) = (q_{1} \Box, L)
δ(q1,x)=(q2,1,R)\delta(q_{1}, x) = (q_{2}, 1, R)
δ(q2,1)=(q2,1,R\delta(q_{2}, 1) = (q_{2}, 1, R
δ(q2,)=(q1,1,L)\delta(q_{2}, \Box) = (q_{1}, 1, L)
δ(q1,1)=(q1,1,L)\delta(q_{1}, 1) = (q_{1}, 1, L)
δ(q1,)=(q3,,R)\delta(q_{1}, \Box) = (q_{3}, \Box, R)

where q3q_{3} is the only final state.

Linz Figure 9.7 shows a transition graph for this Turing machine.

Linz Fig. 9.7: Transition Graph for Example 9.10

This is not easy to follow, so let us trace the program with the string 11. The computation performed is as shown below.

q011q_{0}11 \;\vdash\; xq01xq_{0}1 \;\vdash\; xxq0xxq_{0}\Box \;\vdash\; xq1xxq_{1}x
\;\vdash\; x1q2x1q_{2}\Box \;\vdash\; xq111xq_{1}11 \;\vdash\; q1x11q_{1}x11
\;\vdash\; 1q2111q_{2}11 \;\vdash\; 11q2111q_{2}1 \;\vdash\; 111q2111q_{2}\Box
\;\vdash\; 11q11111q_{1}11 \;\vdash\; 1q11111q_{1}111
\;\vdash\; q11111q_{1}1111 \;\vdash\; q11111q_{1}\Box 1111 \;\vdash\; q31111q_{3}1111

9.1.3.3 Linz Example 9.11

Suppose xx and yy are positive integers represented in unary notation.

Construct a Turing machine that halts in a final state qyq_{y} if xyx \geq y and in a nonfinal state qnq_{n} if x<yx < y.

That is, the machine must perform the computation:

q0w(x)0w(y)q_{0} w(x) 0 w(y) *\vdash^{*} qyw(x)0w(y)q_{y} w(x) 0 w(y), if xyx \geq y
q0w(x)0w(y)q_{0} w(x) 0 w(y) *\vdash^{*} qnw(x)0w(y)q_{n} w(x) 0 w(y), if x<yx < y

We can adapt the approach from Linz Example 9.7. Instead of matching aa’s and bb’s, we match each 1 on the left of the dividing 0 with the 1 on the right. At the end of the matching, we will have on the tape either

xx110xxxx x \cdots 110xx \cdots x \Box

or

xxxx0xxx11x x \cdots xx0xx \cdots x11 \Box,

depending on whether x>yx > y or y>xy > x.

A transition graph for machine is shown below.

9.2 Combining Turing Machines for Complicated Tasks

9.2.1 Introduction

How can we compose simpler operations on Turing machines to form more complex operations?

Techniques discussed in this section include use of:

  • Top-down stepwise refinement, i.e., starting with a high-level description and refining it incrementally until we obtain a description in the actual language

  • Block diagrams or pseudocode to state high-level descriptions

9.2.2 Using Block Diagrams

In the block diagram technique, we define high-level computations in boxes without internal details on how computation is done. The details are filled in on a subsequent refinement.

To explore the use of block diagrams in the design of complex computations, consider Linz Example 9.12, which builds on Linz Examples 9.9 and 9.11 (above).

9.2.2.1 Linz Example 9.12

Design a Turing machine that computes the following function:

f(x,y)=x+yf(x, y) = x + y, if xyx \geq y,
f(x,y)=0f(x, y) = 0, if x<yx < y.

For simplicity, we assume xx and yy are positive integers in unary representation and the value zero is represented by 0, with the rest of the tape blank.

Linz Figure 9.8 shows a high-level block diagram of this computation. This computation consists of a network of three simpler machines:

  • a Comparer CC to determine whether or not xyx \geq y
  • an Adder AA that computes x+yx + y
  • an Eraser EE that changes every 11 to a blank
Linz Fig. 9.8: Block Diagram

We use such high-level diagrams in subsequent discussions of large computations. How can we justify that practice?

We can implement:

  • the Comparer program CC as suggested in Linz Example 9.11, using a Turing machine having states indexed with CC

  • the Adder program AA as suggested in Linz Example 9.9, with states indexed with AA

  • the Eraser program EE by constructing a Turing machine having states indexed with EE

Comparer CC carries out the computations

qC,0w(x)0w(y)*qA,0w(x)0w(y)q_{C,0} w(x) 0 w(y) \vdash^{*} q_{A,0} w(x) 0 w(y), if xyx \geq y,

and

qC,0w(x)0w(y)*qE,0w(x)0w(y)q_{C,0} w(x) 0 w(y) \vdash^{*} q_{E,0} w(x) 0 w(y), if x<yx < y.

If qA,0q_{A,0} and qE,0q_{E, 0} are the initial states of computations AA and EE, respectively, then CC starts either AA or EE.

Adder AA carries out the computation

qA,0w(x)0w(y)*qA,fw(x+y)0q_{A,0} w(x) 0 w(y) \vdash^{*} q_{A,f} w(x + y) 0.

And, Eraser EE carries out the computation

qE,0w(x)0w(y)*qE,f0q_{E,0} w(x) 0 w(y) \vdash^{*} q_{E,f} 0.

The outer diagram in Linz Figure 9.8 thus represents a single Turing machine that combines the actions of machines CC, AA, and EE as shown.

9.2.3 Using Pseudocode

In the pseudocode technique, we outline a computation using high-level descriptive phrases understandable to people. We refine and translate it to lower-level implementations later.

9.2.3.1 Macroinstructions

A simple kind of pseudocode is the macroinstruction. A macroinstruction is a single statement shorthand for a sequence of lower-level statements.

We first define the macroinstructions in terms of the lower-level language. Then we compose macroinstructions into a larger program, assuming the relevant substitutions will be done.

9.2.3.2 Linz Example 9.13

For this example, consider the macroinstruction

if aa then qjq_{j} else qkq_{k}.

This means:

  • If the Turing machine reads an aa, then it, regardless of its current state, transitions into state qjq_{j} without changing the tape content or moving the read-write head.

  • If the symbol read is not an aa, then it transitions into state qkq_{k} without changing anything.

We can implement this macroinstruction with several steps of a Turing machine:

δ(qi,a)=(qj0,a,R)\delta(q_{i}, a) = (q_{j0}, a, R) for all qiQq_{i} \in Q
δ(qj0,c)=(qj,c,L)\delta(q_{j0},c) = (q_{j}, c, L) for all cΓc \in \Gamma

δ(qi,b)=(qk0,b,R)\delta(q_{i}, b) = (q_{k0}, b, R) for all qiQq_{i} \in Q and all bΓ{a}b \in \Gamma - \{a\}
δ(qk0,c)=(qk,c,L)\delta(q_{k0},c) = (q_{k}, c, L) for all cΓc \in \Gamma

States qj0q_{j0} and qk0q_{k0} just back up Turing machine tape position one place.

Macroinstructions are expanded at each occurrence.

9.2.3.3 Subprograms

While each occurrence of a macroinstruction is expanded into actual code, a subprogram is a single piece of code that is invoked repeatedly.

As in higher-level language programs, we must be able to call a subprogram and then, after execution, return to the calling point and resume execution without any unwanted effects.

How can we do this with Turing machines?

We must be able to:

  • preserve information about the calling program’s configuration (state, read-write head position, tape contents), so that it can be restored on return from the subprogram

  • pass information from the calling program to the called subprogram and vice versa

We can do this by partitioning the tape into several regions. Linz Figure 9.9 illustrates this technique for a program AA (a Turing machine) that calls a subprogram BB (another Turing machine).

  1. AA executes in its own workspace.
  2. Before transferring control to BB, AA writes information about its configuration and inputs for BB into some separate region TT.
  3. After transfer, BB finds its input in TT.
  4. BB executes in its own separate workspace.
  5. When BB completes, it writes relevant results into TT.
  6. BB transfers control back to AA, which resumes and gets the needed results from TT.
Linz Fig. 9.9: Tape Regions for Subprograms

Note: This is similar to what happens in an actual computer for a subprogram (function, procedure) call. The region TT is normally a segment pushed onto the program’s runtime stack or dynamically allocated from the heap memory.

9.2.3.4 Linz Example 9.14

Design a Turing machine that multiplies xx and yy, positive integers represented in unary notation.

Assume the initial and final tape configurations are as shown in Linz Figure 9.10.

We can multiply xx by yy by adding yy to itself xx times as described in the algorithm below.

      Repeat until xx contains no more 11’s\
          Find a 11 in xx and replace it with another symbol aa\
          Replace the leftmost 00 by 0y0y\
      Replace all aa’s with 1’s
Linz Fig. 9.10: Multiplication

Although the above description of the pseudocode approach is imprecise, the idea is sufficiently simple that it is clear we can implement it.

We have not proved that the block diagram, macroinstruction, or subprogram approaches will work in all cases. But the discussion in this section shows that it is plausible to use Turing machines to express complex computations.

9.3 Turing’s Thesis

The Turing thesis is an hypothesis that any computation that can be carried out by mechanical means can be performed by some Turing machine.

This is a broad assertion. It is not something we can prove!

The Turing thesis is actually a definition of mechanical computation: a computation is mechanical if and only if it can be performed by some Turing machine.

Some arguments for accepting the Turing thesis as the definition of mechanical computation include:

  1. Anything that can be computed by any existing digital computer can also be computed by a Turing machine.

  2. There are no known problems that are solvable by what we intuitively consider an algorithm for which a Turing machine program cannot be written.

  3. No alternative model for mechanical computation is more powerful than the Turing machine model.

The Turing thesis is to computing science as, for example, classical Newtonian mechanics is to physics. Newton’s “laws” of motion cannot be proved, but they could possibly be invalidated by observation. The “laws” are plausible models that have enabled humans to explain much of the physical world for several centuries.

Similarly, we accept the Turing thesis as a basic “law” of computing science. The conclusions we draw from it agree with what we know about real computers.

The Turing thesis enables us to formalize the concept of algorithm.

Linz Definition 9.5 (Algorithm): An algorithm for a function f:DRf: D \rightarrow R is a Turing machine MM, which given as input any dDd \in D on its tape, eventually halts with the correct answer f(d)Rf(d) \in R on its tape. Specifically, we can require that

q0dM*qff(d),qfFq_{0} d \vdash^{*}_{M} q_{f} f(d), q_{f} \in F,

for all dDd \in D.

To prove that “there exists an algorithm”, we can construct a Turing machine that computes the result.

However, this is difficult in practice for such a low-level machine.

An alternative is, first, to appeal to the Turing thesis, arguing that anything that we can compute with a digital computer we can compute with a Turing machine. Thus a program in suitable high-level language or precise pseudocode can compute the result. If unsure, then we can validate this by actually implementing the computation on a computer.

Note: A higher-level language is Turing-complete if it can express any algorithm that can be expressed with a Turing machine. If we can write a Turing machine simulator in that language, we consider the language Turing complete.

9.4 References

[1]
Peter Linz. 2011. Formal languages and automata (Fifth ed.). Jones & Bartlett, Burlington, Massachusetts, USA.