home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / progs / turing.icn < prev    next >
Text File  |  2000-07-29  |  5KB  |  176 lines

  1. ############################################################################
  2. #
  3. #    File:     turing.icn
  4. #
  5. #    Subject:  Program to simulate a Turing machine
  6. #
  7. #    Author:   Gregg M. Townsend
  8. #
  9. #    Date:     November 14, 1994
  10. #
  11. ############################################################################
  12. #
  13. #   This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #     This program simulates the operation of an n-state Turing machine,
  18. #  tracing all actions.  The machine starts in state 1 with an empty tape.
  19. #
  20. #     A description of the Turing machine is read from the file given as a
  21. #  command-line argument, or from standard input if none is specified.
  22. #  Comment lines beginning with '#' are allowed, as are empty lines.
  23. #
  24. #     The program states must be numbered from 1 and must appear in order.
  25. #  Each appears on a single line in this form:
  26. #
  27. #      sss.  wdnnn  wdnnn
  28. #
  29. #  sss is the state number in decimal.  The wdnnn fields specify the
  30. #  action to be taken on reading a 0 or 1 respectively:
  31. #
  32. #      w   is the digit to write (0 or 1)
  33. #      d   is the direction to move (L/l/R/r, or H/h to halt)
  34. #      nnn is the next state number (0 if halting)
  35. #
  36. #  Sample input file:
  37. #
  38. #      1. 1r2 1l3
  39. #      2. 1l1 1r2
  40. #      3. 1l2 1h0
  41. #
  42. #     One line is written for each cycle giving the cycle number, current
  43. #  state, and an image of that portion of the tape that has been visited
  44. #  so far.  The current position is indicated by reverse video (using
  45. #  ANSI terminal escape sequences).
  46. #
  47. #     Input errors are reported to standard error output and inhibit
  48. #  execution.
  49. #
  50. #     Bugs:
  51. #
  52. #     Transitions to nonexistent states are not detected.
  53. #  Reverse video should be parameterizable or at least optional.
  54. #  There is no way to limit the number of cycles.
  55. #  Infinite loops are not detected.  (Left as an exercise... :-)
  56. #
  57. #  Reference:
  58. #
  59. #     Scientific American, August 1984, pp. 19-23.  A. K. Dewdney's
  60. #  discussion of "busy beaver" turing machines in his "Computer
  61. #  Recreations" column motivated this program.  The sample above
  62. #  is the three-state busy beaver.
  63. #
  64. ############################################################################
  65. #
  66. #  Links: options
  67. #
  68. ############################################################################
  69.  
  70. link options
  71.  
  72. record action(wrt, mov, nxs)
  73.  
  74. global machine, lns, lno, errs
  75. global cycle, tape, posn, state, video
  76.  
  77. procedure main(args)
  78.    local opts
  79.  
  80.    opts := options(args, "v")
  81.    video := \opts["v"]
  82.  
  83.    rdmach(&input)            # read machine description
  84.    if errs > 0 then stop("[execution suppressed]")
  85.    lns := **machine            # initialize turing machine
  86.    tape := "0"
  87.    posn := 1
  88.    cycle := 0
  89.    state := 1
  90.    while state > 0 do {        # execute
  91.       dumptape()
  92.       transit(machine[state][tape[posn]+1])
  93.       cycle +:= 1
  94.    }
  95.    dumptape()
  96. end
  97.  
  98. #  dumptape - display current tape contents on screen
  99.  
  100. procedure dumptape()
  101.    if cycle < 10 then writes(" ")
  102.    writes(cycle, ". [", right(state, lns), "] ", tape[1:posn])
  103.    if \video then write("\e[7m", tape[posn], "\e[m", tape[posn + 1:0])
  104.    else {
  105.       write(tape[posn:0])
  106.       write(repl(" ", 6 + *state + posn), "^")
  107.       }
  108. end
  109.  
  110.  
  111. #  transit (act) - transit to the next state performing the given action
  112.  
  113. procedure transit(act)
  114.    tape[posn] := act.wrt
  115.    if act.mov == "R" then {
  116.       posn +:= 1
  117.       if posn > *tape then tape ||:= "0"
  118.       }
  119.    else if act.mov == "L" then {
  120.       if posn = 1 then tape := "0" || tape
  121.       else posn -:= 1
  122.       }
  123.    state := act.nxs
  124.    return
  125. end
  126.  
  127. #  rdmach (f) - read machine description from the given file
  128.  
  129. procedure rdmach(f)
  130.    local nstates, line, a0, a1, n
  131.  
  132.    machine := list()
  133.    nstates := 0
  134.    lno := 0
  135.    errs := 0
  136.    while line := trim(read(f), ' \t') do {
  137.       lno +:= 1
  138.       if *line > 0 & line[1] ~== "#"
  139.          then line ? {
  140.             tab(many(' \t'))
  141.             n := tab(many(&digits)) | 0
  142.             if n ~= nstates + 1 then warn("sequence error")
  143.             nstates := n
  144.             tab(many('. \t'))
  145.             a0 := tab(many('01LRHlrh23456789')) | ""
  146.             tab(many(' \t'))
  147.             a1 := tab(many('01LRHlrh23456789')) | ""
  148.             pos(0) | (warn("syntax error") & next)
  149.             put(machine, [mkact(a0), mkact(a1)])
  150.             }
  151.    }
  152.    lno := "<EOF>"
  153.    if *machine = errs = 0 then warn("no machine!")
  154.    return
  155. end
  156.  
  157. #  mkact (a) - construct the action record specified by the given string
  158.  
  159. procedure mkact(a)
  160.    local w, m, n
  161.  
  162.    w := a[1] | "9"
  163.    m := map(a[2], &lcase, &ucase) | "X"
  164.    (any('01', w) & any('LRH', m)) | warn("syntax error")
  165.    n := integer(a[3:0]) | (warn("bad nextstate"), 0)
  166.    return action (w, m, n)
  167. end
  168.  
  169. #  warn (msg) - report an error in the machine description
  170.  
  171. procedure warn(msg)
  172.    write(&errout, "line ", lno, ": ", msg)
  173.    errs +:= 1
  174.    return
  175. end
  176.